]> git.immae.eu Git - perso/Immae/Projets/packagist/ludivine-ckeditor-component.git/commitdiff
Validation initiale 4.6.2.1
authorIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 19 Jan 2017 23:55:51 +0000 (00:55 +0100)
committerIsmaël Bouya <ismael.bouya@normalesup.org>
Thu, 19 Jan 2017 23:55:51 +0000 (00:55 +0100)
2237 files changed:
README.md [new file with mode: 0644]
build-config.js [new file with mode: 0644]
component.json [new file with mode: 0644]
composer.json [new file with mode: 0644]
release/CHANGES.md [new file with mode: 0644]
release/LICENSE.md [new file with mode: 0644]
release/README.md [new file with mode: 0644]
release/adapters/jquery.js [new file with mode: 0644]
release/ckeditor.js [new file with mode: 0644]
release/config.js [new file with mode: 0644]
release/contents.css [new file with mode: 0644]
release/lang/en.js [new file with mode: 0644]
release/lang/fr.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/a11yhelp.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/_translationstatus.txt [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/af.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ar.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/az.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/bg.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ca.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/cs.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/cy.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/da.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/de-ch.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/de.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/el.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/en-gb.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/en.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/eo.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/es.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/et.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/eu.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/fa.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/fi.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/fo.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/fr-ca.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/fr.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/gl.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/gu.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/he.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/hi.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/hr.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/hu.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/id.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/it.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ja.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/km.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ko.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ku.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/lt.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/lv.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/mk.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/mn.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/nb.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/nl.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/no.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/oc.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/pl.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/pt-br.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/pt.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ro.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ru.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/si.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sk.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sl.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sq.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sr-latn.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sr.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/sv.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/th.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/tr.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/tt.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/ug.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/uk.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/vi.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/zh-cn.js [new file with mode: 0644]
release/plugins/a11yhelp/dialogs/lang/zh.js [new file with mode: 0644]
release/plugins/clipboard/dialogs/paste.js [new file with mode: 0644]
release/plugins/dialog/dialogDefinition.js [new file with mode: 0644]
release/plugins/icons.png [new file with mode: 0644]
release/plugins/icons_hidpi.png [new file with mode: 0644]
release/plugins/iframe/dialogs/iframe.js [new file with mode: 0644]
release/plugins/iframe/images/placeholder.png [new file with mode: 0644]
release/plugins/image/dialogs/image.js [new file with mode: 0644]
release/plugins/image/images/noimage.png [new file with mode: 0644]
release/plugins/link/dialogs/anchor.js [new file with mode: 0644]
release/plugins/link/dialogs/link.js [new file with mode: 0644]
release/plugins/link/images/anchor.png [new file with mode: 0644]
release/plugins/link/images/hidpi/anchor.png [new file with mode: 0644]
release/plugins/liststyle/dialogs/liststyle.js [new file with mode: 0644]
release/plugins/magicline/images/hidpi/icon-rtl.png [new file with mode: 0644]
release/plugins/magicline/images/hidpi/icon.png [new file with mode: 0644]
release/plugins/magicline/images/icon-rtl.png [new file with mode: 0644]
release/plugins/magicline/images/icon.png [new file with mode: 0644]
release/plugins/oembed/LICENSE.md [new file with mode: 0644]
release/plugins/oembed/README.md [new file with mode: 0644]
release/plugins/oembed/libs/jquery.oembed.min.js [new file with mode: 0644]
release/plugins/widget/images/handle.png [new file with mode: 0644]
release/samples/css/samples.css [new file with mode: 0644]
release/samples/img/github-top.png [new file with mode: 0644]
release/samples/img/header-bg.png [new file with mode: 0644]
release/samples/img/header-separator.png [new file with mode: 0644]
release/samples/img/logo.png [new file with mode: 0644]
release/samples/img/navigation-tip.png [new file with mode: 0644]
release/samples/index.html [new file with mode: 0644]
release/samples/js/sample.js [new file with mode: 0644]
release/samples/js/sf.js [new file with mode: 0644]
release/samples/old/ajax.html [new file with mode: 0644]
release/samples/old/api.html [new file with mode: 0644]
release/samples/old/appendto.html [new file with mode: 0644]
release/samples/old/assets/inlineall/logo.png [new file with mode: 0644]
release/samples/old/assets/outputxhtml/outputxhtml.css [new file with mode: 0644]
release/samples/old/assets/posteddata.php [new file with mode: 0644]
release/samples/old/assets/sample.jpg [new file with mode: 0644]
release/samples/old/assets/uilanguages/languages.js [new file with mode: 0644]
release/samples/old/datafiltering.html [new file with mode: 0644]
release/samples/old/dialog/assets/my_dialog.js [new file with mode: 0644]
release/samples/old/dialog/dialog.html [new file with mode: 0644]
release/samples/old/divreplace.html [new file with mode: 0644]
release/samples/old/enterkey/enterkey.html [new file with mode: 0644]
release/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla [new file with mode: 0644]
release/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf [new file with mode: 0644]
release/samples/old/htmlwriter/assets/outputforflash/swfobject.js [new file with mode: 0644]
release/samples/old/htmlwriter/outputforflash.html [new file with mode: 0644]
release/samples/old/htmlwriter/outputhtml.html [new file with mode: 0644]
release/samples/old/index.html [new file with mode: 0644]
release/samples/old/inlineall.html [new file with mode: 0644]
release/samples/old/inlinebycode.html [new file with mode: 0644]
release/samples/old/inlinetextarea.html [new file with mode: 0644]
release/samples/old/jquery.html [new file with mode: 0644]
release/samples/old/magicline/magicline.html [new file with mode: 0644]
release/samples/old/readonly.html [new file with mode: 0644]
release/samples/old/replacebyclass.html [new file with mode: 0644]
release/samples/old/replacebycode.html [new file with mode: 0644]
release/samples/old/sample.css [new file with mode: 0644]
release/samples/old/sample.js [new file with mode: 0644]
release/samples/old/sample_posteddata.php [new file with mode: 0644]
release/samples/old/tabindex.html [new file with mode: 0644]
release/samples/old/toolbar/toolbar.html [new file with mode: 0644]
release/samples/old/uicolor.html [new file with mode: 0644]
release/samples/old/uilanguages.html [new file with mode: 0644]
release/samples/old/wysiwygarea/fullpage.html [new file with mode: 0644]
release/samples/old/xhtmlstyle.html [new file with mode: 0644]
release/samples/toolbarconfigurator/css/fontello.css [new file with mode: 0644]
release/samples/toolbarconfigurator/font/LICENSE.txt [new file with mode: 0644]
release/samples/toolbarconfigurator/font/config.json [new file with mode: 0644]
release/samples/toolbarconfigurator/font/fontello.eot [new file with mode: 0644]
release/samples/toolbarconfigurator/font/fontello.svg [new file with mode: 0644]
release/samples/toolbarconfigurator/font/fontello.ttf [new file with mode: 0644]
release/samples/toolbarconfigurator/font/fontello.woff [new file with mode: 0644]
release/samples/toolbarconfigurator/index.html [new file with mode: 0644]
release/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js [new file with mode: 0644]
release/samples/toolbarconfigurator/js/fulltoolbareditor.js [new file with mode: 0644]
release/samples/toolbarconfigurator/js/toolbarmodifier.js [new file with mode: 0644]
release/samples/toolbarconfigurator/js/toolbartextmodifier.js [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/LICENSE [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/codemirror.css [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/codemirror.js [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/javascript.js [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/neo.css [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/show-hint.css [new file with mode: 0644]
release/samples/toolbarconfigurator/lib/codemirror/show-hint.js [new file with mode: 0644]
release/skins/moono/dialog.css [new file with mode: 0644]
release/skins/moono/dialog_ie.css [new file with mode: 0644]
release/skins/moono/dialog_ie7.css [new file with mode: 0644]
release/skins/moono/dialog_ie8.css [new file with mode: 0644]
release/skins/moono/dialog_iequirks.css [new file with mode: 0644]
release/skins/moono/editor.css [new file with mode: 0644]
release/skins/moono/editor_gecko.css [new file with mode: 0644]
release/skins/moono/editor_ie.css [new file with mode: 0644]
release/skins/moono/editor_ie7.css [new file with mode: 0644]
release/skins/moono/editor_ie8.css [new file with mode: 0644]
release/skins/moono/editor_iequirks.css [new file with mode: 0644]
release/skins/moono/icons.png [new file with mode: 0644]
release/skins/moono/icons_hidpi.png [new file with mode: 0644]
release/skins/moono/images/anchor.png [new file with mode: 0644]
release/skins/moono/images/arrow.png [new file with mode: 0644]
release/skins/moono/images/close.png [new file with mode: 0644]
release/skins/moono/images/hidpi/anchor.png [new file with mode: 0644]
release/skins/moono/images/hidpi/close.png [new file with mode: 0644]
release/skins/moono/images/hidpi/lock-open.png [new file with mode: 0644]
release/skins/moono/images/hidpi/lock.png [new file with mode: 0644]
release/skins/moono/images/hidpi/refresh.png [new file with mode: 0644]
release/skins/moono/images/lock-open.png [new file with mode: 0644]
release/skins/moono/images/lock.png [new file with mode: 0644]
release/skins/moono/images/refresh.png [new file with mode: 0644]
release/skins/moono/images/spinner.gif [new file with mode: 0644]
release/skins/moono/readme.md [new file with mode: 0644]
release/styles.js [new file with mode: 0644]
sources/CHANGES.md [new file with mode: 0644]
sources/LICENSE.md [new file with mode: 0644]
sources/README.md [new file with mode: 0644]
sources/adapters/jquery.js [new file with mode: 0644]
sources/ckeditor.js [new file with mode: 0644]
sources/config.js [new file with mode: 0644]
sources/contents.css [new file with mode: 0644]
sources/core/_bootstrap.js [new file with mode: 0644]
sources/core/ckeditor.js [new file with mode: 0644]
sources/core/ckeditor_base.js [new file with mode: 0644]
sources/core/ckeditor_basic.js [new file with mode: 0644]
sources/core/command.js [new file with mode: 0644]
sources/core/commanddefinition.js [new file with mode: 0644]
sources/core/config.js [new file with mode: 0644]
sources/core/creators/inline.js [new file with mode: 0644]
sources/core/creators/themedui.js [new file with mode: 0644]
sources/core/dataprocessor.js [new file with mode: 0644]
sources/core/dom.js [new file with mode: 0644]
sources/core/dom/comment.js [new file with mode: 0644]
sources/core/dom/document.js [new file with mode: 0644]
sources/core/dom/documentfragment.js [new file with mode: 0644]
sources/core/dom/domobject.js [new file with mode: 0644]
sources/core/dom/element.js [new file with mode: 0644]
sources/core/dom/elementpath.js [new file with mode: 0644]
sources/core/dom/event.js [new file with mode: 0644]
sources/core/dom/iterator.js [new file with mode: 0644]
sources/core/dom/node.js [new file with mode: 0644]
sources/core/dom/nodelist.js [new file with mode: 0644]
sources/core/dom/range.js [new file with mode: 0644]
sources/core/dom/rangelist.js [new file with mode: 0644]
sources/core/dom/text.js [new file with mode: 0644]
sources/core/dom/walker.js [new file with mode: 0644]
sources/core/dom/window.js [new file with mode: 0644]
sources/core/dtd.js [new file with mode: 0644]
sources/core/editable.js [new file with mode: 0644]
sources/core/editor.js [new file with mode: 0644]
sources/core/editor_basic.js [new file with mode: 0644]
sources/core/env.js [new file with mode: 0644]
sources/core/event.js [new file with mode: 0644]
sources/core/eventInfo.js [new file with mode: 0644]
sources/core/filter.js [new file with mode: 0644]
sources/core/focusmanager.js [new file with mode: 0644]
sources/core/htmldataprocessor.js [new file with mode: 0644]
sources/core/htmlparser.js [new file with mode: 0644]
sources/core/htmlparser/basicwriter.js [new file with mode: 0644]
sources/core/htmlparser/cdata.js [new file with mode: 0644]
sources/core/htmlparser/comment.js [new file with mode: 0644]
sources/core/htmlparser/element.js [new file with mode: 0644]
sources/core/htmlparser/filter.js [new file with mode: 0644]
sources/core/htmlparser/fragment.js [new file with mode: 0644]
sources/core/htmlparser/node.js [new file with mode: 0644]
sources/core/htmlparser/text.js [new file with mode: 0644]
sources/core/keystrokehandler.js [new file with mode: 0644]
sources/core/lang.js [new file with mode: 0644]
sources/core/loader.js [new file with mode: 0644]
sources/core/log.js [new file with mode: 0644]
sources/core/plugindefinition.js [new file with mode: 0644]
sources/core/plugins.js [new file with mode: 0644]
sources/core/resourcemanager.js [new file with mode: 0644]
sources/core/scriptloader.js [new file with mode: 0644]
sources/core/selection.js [new file with mode: 0644]
sources/core/skin.js [new file with mode: 0644]
sources/core/style.js [new file with mode: 0644]
sources/core/template.js [new file with mode: 0644]
sources/core/tools.js [new file with mode: 0644]
sources/core/ui.js [new file with mode: 0644]
sources/lang/_translationstatus.txt [new file with mode: 0644]
sources/lang/af.js [new file with mode: 0644]
sources/lang/ar.js [new file with mode: 0644]
sources/lang/az.js [new file with mode: 0644]
sources/lang/bg.js [new file with mode: 0644]
sources/lang/bn.js [new file with mode: 0644]
sources/lang/bs.js [new file with mode: 0644]
sources/lang/ca.js [new file with mode: 0644]
sources/lang/cs.js [new file with mode: 0644]
sources/lang/cy.js [new file with mode: 0644]
sources/lang/da.js [new file with mode: 0644]
sources/lang/de-ch.js [new file with mode: 0644]
sources/lang/de.js [new file with mode: 0644]
sources/lang/el.js [new file with mode: 0644]
sources/lang/en-au.js [new file with mode: 0644]
sources/lang/en-ca.js [new file with mode: 0644]
sources/lang/en-gb.js [new file with mode: 0644]
sources/lang/en.js [new file with mode: 0644]
sources/lang/eo.js [new file with mode: 0644]
sources/lang/es.js [new file with mode: 0644]
sources/lang/et.js [new file with mode: 0644]
sources/lang/eu.js [new file with mode: 0644]
sources/lang/fa.js [new file with mode: 0644]
sources/lang/fi.js [new file with mode: 0644]
sources/lang/fo.js [new file with mode: 0644]
sources/lang/fr-ca.js [new file with mode: 0644]
sources/lang/fr.js [new file with mode: 0644]
sources/lang/gl.js [new file with mode: 0644]
sources/lang/gu.js [new file with mode: 0644]
sources/lang/he.js [new file with mode: 0644]
sources/lang/hi.js [new file with mode: 0644]
sources/lang/hr.js [new file with mode: 0644]
sources/lang/hu.js [new file with mode: 0644]
sources/lang/id.js [new file with mode: 0644]
sources/lang/is.js [new file with mode: 0644]
sources/lang/it.js [new file with mode: 0644]
sources/lang/ja.js [new file with mode: 0644]
sources/lang/ka.js [new file with mode: 0644]
sources/lang/km.js [new file with mode: 0644]
sources/lang/ko.js [new file with mode: 0644]
sources/lang/ku.js [new file with mode: 0644]
sources/lang/lt.js [new file with mode: 0644]
sources/lang/lv.js [new file with mode: 0644]
sources/lang/mk.js [new file with mode: 0644]
sources/lang/mn.js [new file with mode: 0644]
sources/lang/ms.js [new file with mode: 0644]
sources/lang/nb.js [new file with mode: 0644]
sources/lang/nl.js [new file with mode: 0644]
sources/lang/no.js [new file with mode: 0644]
sources/lang/oc.js [new file with mode: 0644]
sources/lang/pl.js [new file with mode: 0644]
sources/lang/pt-br.js [new file with mode: 0644]
sources/lang/pt.js [new file with mode: 0644]
sources/lang/ro.js [new file with mode: 0644]
sources/lang/ru.js [new file with mode: 0644]
sources/lang/si.js [new file with mode: 0644]
sources/lang/sk.js [new file with mode: 0644]
sources/lang/sl.js [new file with mode: 0644]
sources/lang/sq.js [new file with mode: 0644]
sources/lang/sr-latn.js [new file with mode: 0644]
sources/lang/sr.js [new file with mode: 0644]
sources/lang/sv.js [new file with mode: 0644]
sources/lang/th.js [new file with mode: 0644]
sources/lang/tr.js [new file with mode: 0644]
sources/lang/tt.js [new file with mode: 0644]
sources/lang/ug.js [new file with mode: 0644]
sources/lang/uk.js [new file with mode: 0644]
sources/lang/vi.js [new file with mode: 0644]
sources/lang/zh-cn.js [new file with mode: 0644]
sources/lang/zh.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/a11yhelp.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/_translationstatus.txt [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/af.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ar.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/az.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/bg.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ca.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/cs.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/cy.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/da.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/de-ch.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/de.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/el.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/en-gb.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/en.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/eo.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/es.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/et.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/eu.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/fa.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/fi.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/fo.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/fr.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/gl.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/gu.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/he.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/hi.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/hr.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/hu.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/id.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/it.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ja.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/km.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ko.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ku.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/lt.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/lv.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/mk.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/mn.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/nb.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/nl.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/no.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/oc.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/pl.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/pt-br.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/pt.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ro.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ru.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/si.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sk.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sl.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sq.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sr.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/sv.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/th.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/tr.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/tt.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/ug.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/uk.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/vi.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/a11yhelp/dialogs/lang/zh.js [new file with mode: 0644]
sources/plugins/a11yhelp/plugin.js [new file with mode: 0644]
sources/plugins/basicstyles/icons/bold.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/bold.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/italic.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/strike.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/subscript.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/superscript.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/hidpi/underline.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/italic.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/strike.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/subscript.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/superscript.png [new file with mode: 0644]
sources/plugins/basicstyles/icons/underline.png [new file with mode: 0644]
sources/plugins/basicstyles/lang/af.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ar.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/az.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/bg.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/bn.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/bs.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ca.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/cs.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/cy.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/da.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/de-ch.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/de.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/el.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/en-au.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/en-ca.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/en-gb.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/en.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/eo.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/es.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/et.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/eu.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/fa.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/fi.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/fo.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/fr.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/gl.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/gu.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/he.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/hi.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/hr.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/hu.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/id.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/is.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/it.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ja.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ka.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/km.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ko.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ku.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/lt.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/lv.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/mk.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/mn.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ms.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/nb.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/nl.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/no.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/oc.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/pl.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/pt-br.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/pt.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ro.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ru.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/si.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sk.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sl.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sq.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sr.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/sv.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/th.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/tr.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/tt.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/ug.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/uk.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/vi.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/basicstyles/lang/zh.js [new file with mode: 0644]
sources/plugins/basicstyles/plugin.js [new file with mode: 0644]
sources/plugins/button/lang/af.js [new file with mode: 0644]
sources/plugins/button/lang/ar.js [new file with mode: 0644]
sources/plugins/button/lang/az.js [new file with mode: 0644]
sources/plugins/button/lang/bg.js [new file with mode: 0644]
sources/plugins/button/lang/ca.js [new file with mode: 0644]
sources/plugins/button/lang/cs.js [new file with mode: 0644]
sources/plugins/button/lang/da.js [new file with mode: 0644]
sources/plugins/button/lang/de-ch.js [new file with mode: 0644]
sources/plugins/button/lang/de.js [new file with mode: 0644]
sources/plugins/button/lang/el.js [new file with mode: 0644]
sources/plugins/button/lang/en-gb.js [new file with mode: 0644]
sources/plugins/button/lang/en.js [new file with mode: 0644]
sources/plugins/button/lang/eo.js [new file with mode: 0644]
sources/plugins/button/lang/es.js [new file with mode: 0644]
sources/plugins/button/lang/eu.js [new file with mode: 0644]
sources/plugins/button/lang/fa.js [new file with mode: 0644]
sources/plugins/button/lang/fi.js [new file with mode: 0644]
sources/plugins/button/lang/fr.js [new file with mode: 0644]
sources/plugins/button/lang/gl.js [new file with mode: 0644]
sources/plugins/button/lang/he.js [new file with mode: 0644]
sources/plugins/button/lang/hu.js [new file with mode: 0644]
sources/plugins/button/lang/id.js [new file with mode: 0644]
sources/plugins/button/lang/it.js [new file with mode: 0644]
sources/plugins/button/lang/ja.js [new file with mode: 0644]
sources/plugins/button/lang/km.js [new file with mode: 0644]
sources/plugins/button/lang/ko.js [new file with mode: 0644]
sources/plugins/button/lang/ku.js [new file with mode: 0644]
sources/plugins/button/lang/lt.js [new file with mode: 0644]
sources/plugins/button/lang/nb.js [new file with mode: 0644]
sources/plugins/button/lang/nl.js [new file with mode: 0644]
sources/plugins/button/lang/no.js [new file with mode: 0644]
sources/plugins/button/lang/oc.js [new file with mode: 0644]
sources/plugins/button/lang/pl.js [new file with mode: 0644]
sources/plugins/button/lang/pt-br.js [new file with mode: 0644]
sources/plugins/button/lang/pt.js [new file with mode: 0644]
sources/plugins/button/lang/ro.js [new file with mode: 0644]
sources/plugins/button/lang/ru.js [new file with mode: 0644]
sources/plugins/button/lang/sk.js [new file with mode: 0644]
sources/plugins/button/lang/sl.js [new file with mode: 0644]
sources/plugins/button/lang/sq.js [new file with mode: 0644]
sources/plugins/button/lang/sv.js [new file with mode: 0644]
sources/plugins/button/lang/tr.js [new file with mode: 0644]
sources/plugins/button/lang/tt.js [new file with mode: 0644]
sources/plugins/button/lang/ug.js [new file with mode: 0644]
sources/plugins/button/lang/uk.js [new file with mode: 0644]
sources/plugins/button/lang/vi.js [new file with mode: 0644]
sources/plugins/button/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/button/lang/zh.js [new file with mode: 0644]
sources/plugins/button/plugin.js [new file with mode: 0644]
sources/plugins/clipboard/dev/clipboard.html [new file with mode: 0644]
sources/plugins/clipboard/dev/console.js [new file with mode: 0644]
sources/plugins/clipboard/dev/dnd.html [new file with mode: 0644]
sources/plugins/clipboard/dialogs/paste.js [new file with mode: 0644]
sources/plugins/clipboard/icons/copy-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/copy.png [new file with mode: 0644]
sources/plugins/clipboard/icons/cut-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/cut.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/copy-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/copy.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/cut-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/cut.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/paste-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/hidpi/paste.png [new file with mode: 0644]
sources/plugins/clipboard/icons/paste-rtl.png [new file with mode: 0644]
sources/plugins/clipboard/icons/paste.png [new file with mode: 0644]
sources/plugins/clipboard/lang/af.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ar.js [new file with mode: 0644]
sources/plugins/clipboard/lang/az.js [new file with mode: 0644]
sources/plugins/clipboard/lang/bg.js [new file with mode: 0644]
sources/plugins/clipboard/lang/bn.js [new file with mode: 0644]
sources/plugins/clipboard/lang/bs.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ca.js [new file with mode: 0644]
sources/plugins/clipboard/lang/cs.js [new file with mode: 0644]
sources/plugins/clipboard/lang/cy.js [new file with mode: 0644]
sources/plugins/clipboard/lang/da.js [new file with mode: 0644]
sources/plugins/clipboard/lang/de-ch.js [new file with mode: 0644]
sources/plugins/clipboard/lang/de.js [new file with mode: 0644]
sources/plugins/clipboard/lang/el.js [new file with mode: 0644]
sources/plugins/clipboard/lang/en-au.js [new file with mode: 0644]
sources/plugins/clipboard/lang/en-ca.js [new file with mode: 0644]
sources/plugins/clipboard/lang/en-gb.js [new file with mode: 0644]
sources/plugins/clipboard/lang/en.js [new file with mode: 0644]
sources/plugins/clipboard/lang/eo.js [new file with mode: 0644]
sources/plugins/clipboard/lang/es.js [new file with mode: 0644]
sources/plugins/clipboard/lang/et.js [new file with mode: 0644]
sources/plugins/clipboard/lang/eu.js [new file with mode: 0644]
sources/plugins/clipboard/lang/fa.js [new file with mode: 0644]
sources/plugins/clipboard/lang/fi.js [new file with mode: 0644]
sources/plugins/clipboard/lang/fo.js [new file with mode: 0644]
sources/plugins/clipboard/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/clipboard/lang/fr.js [new file with mode: 0644]
sources/plugins/clipboard/lang/gl.js [new file with mode: 0644]
sources/plugins/clipboard/lang/gu.js [new file with mode: 0644]
sources/plugins/clipboard/lang/he.js [new file with mode: 0644]
sources/plugins/clipboard/lang/hi.js [new file with mode: 0644]
sources/plugins/clipboard/lang/hr.js [new file with mode: 0644]
sources/plugins/clipboard/lang/hu.js [new file with mode: 0644]
sources/plugins/clipboard/lang/id.js [new file with mode: 0644]
sources/plugins/clipboard/lang/is.js [new file with mode: 0644]
sources/plugins/clipboard/lang/it.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ja.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ka.js [new file with mode: 0644]
sources/plugins/clipboard/lang/km.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ko.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ku.js [new file with mode: 0644]
sources/plugins/clipboard/lang/lt.js [new file with mode: 0644]
sources/plugins/clipboard/lang/lv.js [new file with mode: 0644]
sources/plugins/clipboard/lang/mk.js [new file with mode: 0644]
sources/plugins/clipboard/lang/mn.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ms.js [new file with mode: 0644]
sources/plugins/clipboard/lang/nb.js [new file with mode: 0644]
sources/plugins/clipboard/lang/nl.js [new file with mode: 0644]
sources/plugins/clipboard/lang/no.js [new file with mode: 0644]
sources/plugins/clipboard/lang/oc.js [new file with mode: 0644]
sources/plugins/clipboard/lang/pl.js [new file with mode: 0644]
sources/plugins/clipboard/lang/pt-br.js [new file with mode: 0644]
sources/plugins/clipboard/lang/pt.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ro.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ru.js [new file with mode: 0644]
sources/plugins/clipboard/lang/si.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sk.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sl.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sq.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sr.js [new file with mode: 0644]
sources/plugins/clipboard/lang/sv.js [new file with mode: 0644]
sources/plugins/clipboard/lang/th.js [new file with mode: 0644]
sources/plugins/clipboard/lang/tr.js [new file with mode: 0644]
sources/plugins/clipboard/lang/tt.js [new file with mode: 0644]
sources/plugins/clipboard/lang/ug.js [new file with mode: 0644]
sources/plugins/clipboard/lang/uk.js [new file with mode: 0644]
sources/plugins/clipboard/lang/vi.js [new file with mode: 0644]
sources/plugins/clipboard/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/clipboard/lang/zh.js [new file with mode: 0644]
sources/plugins/clipboard/plugin.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/af.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ar.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/az.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/bg.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/bn.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/bs.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ca.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/cs.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/cy.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/da.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/de-ch.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/de.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/el.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/en-au.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/en-ca.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/en-gb.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/en.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/eo.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/es.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/et.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/eu.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/fa.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/fi.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/fo.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/fr.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/gl.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/gu.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/he.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/hi.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/hr.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/hu.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/id.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/is.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/it.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ja.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ka.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/km.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ko.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ku.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/lt.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/lv.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/mk.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/mn.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ms.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/nb.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/nl.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/no.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/oc.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/pl.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/pt-br.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/pt.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ro.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ru.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/si.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sk.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sl.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sq.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sr.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/sv.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/th.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/tr.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/tt.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/ug.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/uk.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/vi.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/contextmenu/lang/zh.js [new file with mode: 0644]
sources/plugins/contextmenu/plugin.js [new file with mode: 0644]
sources/plugins/dialog/dialogDefinition.js [new file with mode: 0644]
sources/plugins/dialog/plugin.js [new file with mode: 0644]
sources/plugins/dialog/samples/assets/my_dialog.js [new file with mode: 0644]
sources/plugins/dialog/samples/dialog.html [new file with mode: 0644]
sources/plugins/dialogadvtab/plugin.js [new file with mode: 0644]
sources/plugins/dialogui/plugin.js [new file with mode: 0644]
sources/plugins/elementspath/lang/af.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ar.js [new file with mode: 0644]
sources/plugins/elementspath/lang/az.js [new file with mode: 0644]
sources/plugins/elementspath/lang/bg.js [new file with mode: 0644]
sources/plugins/elementspath/lang/bn.js [new file with mode: 0644]
sources/plugins/elementspath/lang/bs.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ca.js [new file with mode: 0644]
sources/plugins/elementspath/lang/cs.js [new file with mode: 0644]
sources/plugins/elementspath/lang/cy.js [new file with mode: 0644]
sources/plugins/elementspath/lang/da.js [new file with mode: 0644]
sources/plugins/elementspath/lang/de-ch.js [new file with mode: 0644]
sources/plugins/elementspath/lang/de.js [new file with mode: 0644]
sources/plugins/elementspath/lang/el.js [new file with mode: 0644]
sources/plugins/elementspath/lang/en-au.js [new file with mode: 0644]
sources/plugins/elementspath/lang/en-ca.js [new file with mode: 0644]
sources/plugins/elementspath/lang/en-gb.js [new file with mode: 0644]
sources/plugins/elementspath/lang/en.js [new file with mode: 0644]
sources/plugins/elementspath/lang/eo.js [new file with mode: 0644]
sources/plugins/elementspath/lang/es.js [new file with mode: 0644]
sources/plugins/elementspath/lang/et.js [new file with mode: 0644]
sources/plugins/elementspath/lang/eu.js [new file with mode: 0644]
sources/plugins/elementspath/lang/fa.js [new file with mode: 0644]
sources/plugins/elementspath/lang/fi.js [new file with mode: 0644]
sources/plugins/elementspath/lang/fo.js [new file with mode: 0644]
sources/plugins/elementspath/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/elementspath/lang/fr.js [new file with mode: 0644]
sources/plugins/elementspath/lang/gl.js [new file with mode: 0644]
sources/plugins/elementspath/lang/gu.js [new file with mode: 0644]
sources/plugins/elementspath/lang/he.js [new file with mode: 0644]
sources/plugins/elementspath/lang/hi.js [new file with mode: 0644]
sources/plugins/elementspath/lang/hr.js [new file with mode: 0644]
sources/plugins/elementspath/lang/hu.js [new file with mode: 0644]
sources/plugins/elementspath/lang/is.js [new file with mode: 0644]
sources/plugins/elementspath/lang/it.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ja.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ka.js [new file with mode: 0644]
sources/plugins/elementspath/lang/km.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ko.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ku.js [new file with mode: 0644]
sources/plugins/elementspath/lang/lt.js [new file with mode: 0644]
sources/plugins/elementspath/lang/lv.js [new file with mode: 0644]
sources/plugins/elementspath/lang/mk.js [new file with mode: 0644]
sources/plugins/elementspath/lang/mn.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ms.js [new file with mode: 0644]
sources/plugins/elementspath/lang/nb.js [new file with mode: 0644]
sources/plugins/elementspath/lang/nl.js [new file with mode: 0644]
sources/plugins/elementspath/lang/no.js [new file with mode: 0644]
sources/plugins/elementspath/lang/oc.js [new file with mode: 0644]
sources/plugins/elementspath/lang/pl.js [new file with mode: 0644]
sources/plugins/elementspath/lang/pt-br.js [new file with mode: 0644]
sources/plugins/elementspath/lang/pt.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ro.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ru.js [new file with mode: 0644]
sources/plugins/elementspath/lang/si.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sk.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sl.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sq.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sr.js [new file with mode: 0644]
sources/plugins/elementspath/lang/sv.js [new file with mode: 0644]
sources/plugins/elementspath/lang/th.js [new file with mode: 0644]
sources/plugins/elementspath/lang/tr.js [new file with mode: 0644]
sources/plugins/elementspath/lang/tt.js [new file with mode: 0644]
sources/plugins/elementspath/lang/ug.js [new file with mode: 0644]
sources/plugins/elementspath/lang/uk.js [new file with mode: 0644]
sources/plugins/elementspath/lang/vi.js [new file with mode: 0644]
sources/plugins/elementspath/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/elementspath/lang/zh.js [new file with mode: 0644]
sources/plugins/elementspath/plugin.js [new file with mode: 0644]
sources/plugins/enterkey/plugin.js [new file with mode: 0644]
sources/plugins/enterkey/samples/enterkey.html [new file with mode: 0644]
sources/plugins/entities/plugin.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/af.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ar.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/az.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/bg.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/bn.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/bs.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ca.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/cs.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/cy.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/da.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/de-ch.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/de.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/el.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/en-au.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/en-ca.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/en-gb.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/en.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/eo.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/es.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/et.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/eu.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/fa.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/fi.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/fo.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/fr.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/gl.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/gu.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/he.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/hi.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/hr.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/hu.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/id.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/is.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/it.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ja.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ka.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/km.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ko.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ku.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/lt.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/lv.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/mk.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/mn.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ms.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/nb.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/nl.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/no.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/oc.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/pl.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/pt-br.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/pt.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ro.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ru.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/si.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sk.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sl.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sq.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sr.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/sv.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/th.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/tr.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/tt.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/ug.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/uk.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/vi.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/fakeobjects/lang/zh.js [new file with mode: 0644]
sources/plugins/fakeobjects/plugin.js [new file with mode: 0644]
sources/plugins/filebrowser/plugin.js [new file with mode: 0644]
sources/plugins/floatingspace/plugin.js [new file with mode: 0644]
sources/plugins/floatpanel/plugin.js [new file with mode: 0644]
sources/plugins/format/lang/af.js [new file with mode: 0644]
sources/plugins/format/lang/ar.js [new file with mode: 0644]
sources/plugins/format/lang/az.js [new file with mode: 0644]
sources/plugins/format/lang/bg.js [new file with mode: 0644]
sources/plugins/format/lang/bn.js [new file with mode: 0644]
sources/plugins/format/lang/bs.js [new file with mode: 0644]
sources/plugins/format/lang/ca.js [new file with mode: 0644]
sources/plugins/format/lang/cs.js [new file with mode: 0644]
sources/plugins/format/lang/cy.js [new file with mode: 0644]
sources/plugins/format/lang/da.js [new file with mode: 0644]
sources/plugins/format/lang/de-ch.js [new file with mode: 0644]
sources/plugins/format/lang/de.js [new file with mode: 0644]
sources/plugins/format/lang/el.js [new file with mode: 0644]
sources/plugins/format/lang/en-au.js [new file with mode: 0644]
sources/plugins/format/lang/en-ca.js [new file with mode: 0644]
sources/plugins/format/lang/en-gb.js [new file with mode: 0644]
sources/plugins/format/lang/en.js [new file with mode: 0644]
sources/plugins/format/lang/eo.js [new file with mode: 0644]
sources/plugins/format/lang/es.js [new file with mode: 0644]
sources/plugins/format/lang/et.js [new file with mode: 0644]
sources/plugins/format/lang/eu.js [new file with mode: 0644]
sources/plugins/format/lang/fa.js [new file with mode: 0644]
sources/plugins/format/lang/fi.js [new file with mode: 0644]
sources/plugins/format/lang/fo.js [new file with mode: 0644]
sources/plugins/format/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/format/lang/fr.js [new file with mode: 0644]
sources/plugins/format/lang/gl.js [new file with mode: 0644]
sources/plugins/format/lang/gu.js [new file with mode: 0644]
sources/plugins/format/lang/he.js [new file with mode: 0644]
sources/plugins/format/lang/hi.js [new file with mode: 0644]
sources/plugins/format/lang/hr.js [new file with mode: 0644]
sources/plugins/format/lang/hu.js [new file with mode: 0644]
sources/plugins/format/lang/id.js [new file with mode: 0644]
sources/plugins/format/lang/is.js [new file with mode: 0644]
sources/plugins/format/lang/it.js [new file with mode: 0644]
sources/plugins/format/lang/ja.js [new file with mode: 0644]
sources/plugins/format/lang/ka.js [new file with mode: 0644]
sources/plugins/format/lang/km.js [new file with mode: 0644]
sources/plugins/format/lang/ko.js [new file with mode: 0644]
sources/plugins/format/lang/ku.js [new file with mode: 0644]
sources/plugins/format/lang/lt.js [new file with mode: 0644]
sources/plugins/format/lang/lv.js [new file with mode: 0644]
sources/plugins/format/lang/mk.js [new file with mode: 0644]
sources/plugins/format/lang/mn.js [new file with mode: 0644]
sources/plugins/format/lang/ms.js [new file with mode: 0644]
sources/plugins/format/lang/nb.js [new file with mode: 0644]
sources/plugins/format/lang/nl.js [new file with mode: 0644]
sources/plugins/format/lang/no.js [new file with mode: 0644]
sources/plugins/format/lang/oc.js [new file with mode: 0644]
sources/plugins/format/lang/pl.js [new file with mode: 0644]
sources/plugins/format/lang/pt-br.js [new file with mode: 0644]
sources/plugins/format/lang/pt.js [new file with mode: 0644]
sources/plugins/format/lang/ro.js [new file with mode: 0644]
sources/plugins/format/lang/ru.js [new file with mode: 0644]
sources/plugins/format/lang/si.js [new file with mode: 0644]
sources/plugins/format/lang/sk.js [new file with mode: 0644]
sources/plugins/format/lang/sl.js [new file with mode: 0644]
sources/plugins/format/lang/sq.js [new file with mode: 0644]
sources/plugins/format/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/format/lang/sr.js [new file with mode: 0644]
sources/plugins/format/lang/sv.js [new file with mode: 0644]
sources/plugins/format/lang/th.js [new file with mode: 0644]
sources/plugins/format/lang/tr.js [new file with mode: 0644]
sources/plugins/format/lang/tt.js [new file with mode: 0644]
sources/plugins/format/lang/ug.js [new file with mode: 0644]
sources/plugins/format/lang/uk.js [new file with mode: 0644]
sources/plugins/format/lang/vi.js [new file with mode: 0644]
sources/plugins/format/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/format/lang/zh.js [new file with mode: 0644]
sources/plugins/format/plugin.js [new file with mode: 0644]
sources/plugins/horizontalrule/icons/hidpi/horizontalrule.png [new file with mode: 0644]
sources/plugins/horizontalrule/icons/horizontalrule.png [new file with mode: 0644]
sources/plugins/horizontalrule/lang/af.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ar.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/az.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/bg.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/bn.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/bs.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ca.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/cs.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/cy.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/da.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/de-ch.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/de.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/el.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/en-au.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/en-ca.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/en-gb.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/en.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/eo.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/es.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/et.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/eu.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/fa.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/fi.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/fo.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/fr.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/gl.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/gu.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/he.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/hi.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/hr.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/hu.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/id.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/is.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/it.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ja.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ka.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/km.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ko.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ku.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/lt.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/lv.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/mk.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/mn.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ms.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/nb.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/nl.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/no.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/oc.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/pl.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/pt-br.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/pt.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ro.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ru.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/si.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sk.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sl.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sq.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sr.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/sv.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/th.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/tr.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/tt.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/ug.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/uk.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/vi.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/horizontalrule/lang/zh.js [new file with mode: 0644]
sources/plugins/horizontalrule/plugin.js [new file with mode: 0644]
sources/plugins/htmlwriter/plugin.js [new file with mode: 0644]
sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.fla [new file with mode: 0644]
sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.swf [new file with mode: 0644]
sources/plugins/htmlwriter/samples/assets/outputforflash/swfobject.js [new file with mode: 0644]
sources/plugins/htmlwriter/samples/outputforflash.html [new file with mode: 0644]
sources/plugins/htmlwriter/samples/outputhtml.html [new file with mode: 0644]
sources/plugins/iframe/dialogs/iframe.js [new file with mode: 0644]
sources/plugins/iframe/icons/hidpi/iframe.png [new file with mode: 0644]
sources/plugins/iframe/icons/iframe.png [new file with mode: 0644]
sources/plugins/iframe/images/placeholder.png [new file with mode: 0644]
sources/plugins/iframe/lang/af.js [new file with mode: 0644]
sources/plugins/iframe/lang/ar.js [new file with mode: 0644]
sources/plugins/iframe/lang/az.js [new file with mode: 0644]
sources/plugins/iframe/lang/bg.js [new file with mode: 0644]
sources/plugins/iframe/lang/bn.js [new file with mode: 0644]
sources/plugins/iframe/lang/bs.js [new file with mode: 0644]
sources/plugins/iframe/lang/ca.js [new file with mode: 0644]
sources/plugins/iframe/lang/cs.js [new file with mode: 0644]
sources/plugins/iframe/lang/cy.js [new file with mode: 0644]
sources/plugins/iframe/lang/da.js [new file with mode: 0644]
sources/plugins/iframe/lang/de-ch.js [new file with mode: 0644]
sources/plugins/iframe/lang/de.js [new file with mode: 0644]
sources/plugins/iframe/lang/el.js [new file with mode: 0644]
sources/plugins/iframe/lang/en-au.js [new file with mode: 0644]
sources/plugins/iframe/lang/en-ca.js [new file with mode: 0644]
sources/plugins/iframe/lang/en-gb.js [new file with mode: 0644]
sources/plugins/iframe/lang/en.js [new file with mode: 0644]
sources/plugins/iframe/lang/eo.js [new file with mode: 0644]
sources/plugins/iframe/lang/es.js [new file with mode: 0644]
sources/plugins/iframe/lang/et.js [new file with mode: 0644]
sources/plugins/iframe/lang/eu.js [new file with mode: 0644]
sources/plugins/iframe/lang/fa.js [new file with mode: 0644]
sources/plugins/iframe/lang/fi.js [new file with mode: 0644]
sources/plugins/iframe/lang/fo.js [new file with mode: 0644]
sources/plugins/iframe/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/iframe/lang/fr.js [new file with mode: 0644]
sources/plugins/iframe/lang/gl.js [new file with mode: 0644]
sources/plugins/iframe/lang/gu.js [new file with mode: 0644]
sources/plugins/iframe/lang/he.js [new file with mode: 0644]
sources/plugins/iframe/lang/hi.js [new file with mode: 0644]
sources/plugins/iframe/lang/hr.js [new file with mode: 0644]
sources/plugins/iframe/lang/hu.js [new file with mode: 0644]
sources/plugins/iframe/lang/id.js [new file with mode: 0644]
sources/plugins/iframe/lang/is.js [new file with mode: 0644]
sources/plugins/iframe/lang/it.js [new file with mode: 0644]
sources/plugins/iframe/lang/ja.js [new file with mode: 0644]
sources/plugins/iframe/lang/ka.js [new file with mode: 0644]
sources/plugins/iframe/lang/km.js [new file with mode: 0644]
sources/plugins/iframe/lang/ko.js [new file with mode: 0644]
sources/plugins/iframe/lang/ku.js [new file with mode: 0644]
sources/plugins/iframe/lang/lt.js [new file with mode: 0644]
sources/plugins/iframe/lang/lv.js [new file with mode: 0644]
sources/plugins/iframe/lang/mk.js [new file with mode: 0644]
sources/plugins/iframe/lang/mn.js [new file with mode: 0644]
sources/plugins/iframe/lang/ms.js [new file with mode: 0644]
sources/plugins/iframe/lang/nb.js [new file with mode: 0644]
sources/plugins/iframe/lang/nl.js [new file with mode: 0644]
sources/plugins/iframe/lang/no.js [new file with mode: 0644]
sources/plugins/iframe/lang/oc.js [new file with mode: 0644]
sources/plugins/iframe/lang/pl.js [new file with mode: 0644]
sources/plugins/iframe/lang/pt-br.js [new file with mode: 0644]
sources/plugins/iframe/lang/pt.js [new file with mode: 0644]
sources/plugins/iframe/lang/ro.js [new file with mode: 0644]
sources/plugins/iframe/lang/ru.js [new file with mode: 0644]
sources/plugins/iframe/lang/si.js [new file with mode: 0644]
sources/plugins/iframe/lang/sk.js [new file with mode: 0644]
sources/plugins/iframe/lang/sl.js [new file with mode: 0644]
sources/plugins/iframe/lang/sq.js [new file with mode: 0644]
sources/plugins/iframe/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/iframe/lang/sr.js [new file with mode: 0644]
sources/plugins/iframe/lang/sv.js [new file with mode: 0644]
sources/plugins/iframe/lang/th.js [new file with mode: 0644]
sources/plugins/iframe/lang/tr.js [new file with mode: 0644]
sources/plugins/iframe/lang/tt.js [new file with mode: 0644]
sources/plugins/iframe/lang/ug.js [new file with mode: 0644]
sources/plugins/iframe/lang/uk.js [new file with mode: 0644]
sources/plugins/iframe/lang/vi.js [new file with mode: 0644]
sources/plugins/iframe/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/iframe/lang/zh.js [new file with mode: 0644]
sources/plugins/iframe/plugin.js [new file with mode: 0644]
sources/plugins/image/dialogs/image.js [new file with mode: 0644]
sources/plugins/image/icons/hidpi/image.png [new file with mode: 0644]
sources/plugins/image/icons/image.png [new file with mode: 0644]
sources/plugins/image/images/noimage.png [new file with mode: 0644]
sources/plugins/image/lang/af.js [new file with mode: 0644]
sources/plugins/image/lang/ar.js [new file with mode: 0644]
sources/plugins/image/lang/az.js [new file with mode: 0644]
sources/plugins/image/lang/bg.js [new file with mode: 0644]
sources/plugins/image/lang/bn.js [new file with mode: 0644]
sources/plugins/image/lang/bs.js [new file with mode: 0644]
sources/plugins/image/lang/ca.js [new file with mode: 0644]
sources/plugins/image/lang/cs.js [new file with mode: 0644]
sources/plugins/image/lang/cy.js [new file with mode: 0644]
sources/plugins/image/lang/da.js [new file with mode: 0644]
sources/plugins/image/lang/de-ch.js [new file with mode: 0644]
sources/plugins/image/lang/de.js [new file with mode: 0644]
sources/plugins/image/lang/el.js [new file with mode: 0644]
sources/plugins/image/lang/en-au.js [new file with mode: 0644]
sources/plugins/image/lang/en-ca.js [new file with mode: 0644]
sources/plugins/image/lang/en-gb.js [new file with mode: 0644]
sources/plugins/image/lang/en.js [new file with mode: 0644]
sources/plugins/image/lang/eo.js [new file with mode: 0644]
sources/plugins/image/lang/es.js [new file with mode: 0644]
sources/plugins/image/lang/et.js [new file with mode: 0644]
sources/plugins/image/lang/eu.js [new file with mode: 0644]
sources/plugins/image/lang/fa.js [new file with mode: 0644]
sources/plugins/image/lang/fi.js [new file with mode: 0644]
sources/plugins/image/lang/fo.js [new file with mode: 0644]
sources/plugins/image/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/image/lang/fr.js [new file with mode: 0644]
sources/plugins/image/lang/gl.js [new file with mode: 0644]
sources/plugins/image/lang/gu.js [new file with mode: 0644]
sources/plugins/image/lang/he.js [new file with mode: 0644]
sources/plugins/image/lang/hi.js [new file with mode: 0644]
sources/plugins/image/lang/hr.js [new file with mode: 0644]
sources/plugins/image/lang/hu.js [new file with mode: 0644]
sources/plugins/image/lang/id.js [new file with mode: 0644]
sources/plugins/image/lang/is.js [new file with mode: 0644]
sources/plugins/image/lang/it.js [new file with mode: 0644]
sources/plugins/image/lang/ja.js [new file with mode: 0644]
sources/plugins/image/lang/ka.js [new file with mode: 0644]
sources/plugins/image/lang/km.js [new file with mode: 0644]
sources/plugins/image/lang/ko.js [new file with mode: 0644]
sources/plugins/image/lang/ku.js [new file with mode: 0644]
sources/plugins/image/lang/lt.js [new file with mode: 0644]
sources/plugins/image/lang/lv.js [new file with mode: 0644]
sources/plugins/image/lang/mk.js [new file with mode: 0644]
sources/plugins/image/lang/mn.js [new file with mode: 0644]
sources/plugins/image/lang/ms.js [new file with mode: 0644]
sources/plugins/image/lang/nb.js [new file with mode: 0644]
sources/plugins/image/lang/nl.js [new file with mode: 0644]
sources/plugins/image/lang/no.js [new file with mode: 0644]
sources/plugins/image/lang/oc.js [new file with mode: 0644]
sources/plugins/image/lang/pl.js [new file with mode: 0644]
sources/plugins/image/lang/pt-br.js [new file with mode: 0644]
sources/plugins/image/lang/pt.js [new file with mode: 0644]
sources/plugins/image/lang/ro.js [new file with mode: 0644]
sources/plugins/image/lang/ru.js [new file with mode: 0644]
sources/plugins/image/lang/si.js [new file with mode: 0644]
sources/plugins/image/lang/sk.js [new file with mode: 0644]
sources/plugins/image/lang/sl.js [new file with mode: 0644]
sources/plugins/image/lang/sq.js [new file with mode: 0644]
sources/plugins/image/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/image/lang/sr.js [new file with mode: 0644]
sources/plugins/image/lang/sv.js [new file with mode: 0644]
sources/plugins/image/lang/th.js [new file with mode: 0644]
sources/plugins/image/lang/tr.js [new file with mode: 0644]
sources/plugins/image/lang/tt.js [new file with mode: 0644]
sources/plugins/image/lang/ug.js [new file with mode: 0644]
sources/plugins/image/lang/uk.js [new file with mode: 0644]
sources/plugins/image/lang/vi.js [new file with mode: 0644]
sources/plugins/image/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/image/lang/zh.js [new file with mode: 0644]
sources/plugins/image/plugin.js [new file with mode: 0644]
sources/plugins/indent/dev/indent.html [new file with mode: 0644]
sources/plugins/indent/icons/hidpi/indent-rtl.png [new file with mode: 0644]
sources/plugins/indent/icons/hidpi/indent.png [new file with mode: 0644]
sources/plugins/indent/icons/hidpi/outdent-rtl.png [new file with mode: 0644]
sources/plugins/indent/icons/hidpi/outdent.png [new file with mode: 0644]
sources/plugins/indent/icons/indent-rtl.png [new file with mode: 0644]
sources/plugins/indent/icons/indent.png [new file with mode: 0644]
sources/plugins/indent/icons/outdent-rtl.png [new file with mode: 0644]
sources/plugins/indent/icons/outdent.png [new file with mode: 0644]
sources/plugins/indent/lang/af.js [new file with mode: 0644]
sources/plugins/indent/lang/ar.js [new file with mode: 0644]
sources/plugins/indent/lang/az.js [new file with mode: 0644]
sources/plugins/indent/lang/bg.js [new file with mode: 0644]
sources/plugins/indent/lang/bn.js [new file with mode: 0644]
sources/plugins/indent/lang/bs.js [new file with mode: 0644]
sources/plugins/indent/lang/ca.js [new file with mode: 0644]
sources/plugins/indent/lang/cs.js [new file with mode: 0644]
sources/plugins/indent/lang/cy.js [new file with mode: 0644]
sources/plugins/indent/lang/da.js [new file with mode: 0644]
sources/plugins/indent/lang/de-ch.js [new file with mode: 0644]
sources/plugins/indent/lang/de.js [new file with mode: 0644]
sources/plugins/indent/lang/el.js [new file with mode: 0644]
sources/plugins/indent/lang/en-au.js [new file with mode: 0644]
sources/plugins/indent/lang/en-ca.js [new file with mode: 0644]
sources/plugins/indent/lang/en-gb.js [new file with mode: 0644]
sources/plugins/indent/lang/en.js [new file with mode: 0644]
sources/plugins/indent/lang/eo.js [new file with mode: 0644]
sources/plugins/indent/lang/es.js [new file with mode: 0644]
sources/plugins/indent/lang/et.js [new file with mode: 0644]
sources/plugins/indent/lang/eu.js [new file with mode: 0644]
sources/plugins/indent/lang/fa.js [new file with mode: 0644]
sources/plugins/indent/lang/fi.js [new file with mode: 0644]
sources/plugins/indent/lang/fo.js [new file with mode: 0644]
sources/plugins/indent/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/indent/lang/fr.js [new file with mode: 0644]
sources/plugins/indent/lang/gl.js [new file with mode: 0644]
sources/plugins/indent/lang/gu.js [new file with mode: 0644]
sources/plugins/indent/lang/he.js [new file with mode: 0644]
sources/plugins/indent/lang/hi.js [new file with mode: 0644]
sources/plugins/indent/lang/hr.js [new file with mode: 0644]
sources/plugins/indent/lang/hu.js [new file with mode: 0644]
sources/plugins/indent/lang/id.js [new file with mode: 0644]
sources/plugins/indent/lang/is.js [new file with mode: 0644]
sources/plugins/indent/lang/it.js [new file with mode: 0644]
sources/plugins/indent/lang/ja.js [new file with mode: 0644]
sources/plugins/indent/lang/ka.js [new file with mode: 0644]
sources/plugins/indent/lang/km.js [new file with mode: 0644]
sources/plugins/indent/lang/ko.js [new file with mode: 0644]
sources/plugins/indent/lang/ku.js [new file with mode: 0644]
sources/plugins/indent/lang/lt.js [new file with mode: 0644]
sources/plugins/indent/lang/lv.js [new file with mode: 0644]
sources/plugins/indent/lang/mk.js [new file with mode: 0644]
sources/plugins/indent/lang/mn.js [new file with mode: 0644]
sources/plugins/indent/lang/ms.js [new file with mode: 0644]
sources/plugins/indent/lang/nb.js [new file with mode: 0644]
sources/plugins/indent/lang/nl.js [new file with mode: 0644]
sources/plugins/indent/lang/no.js [new file with mode: 0644]
sources/plugins/indent/lang/oc.js [new file with mode: 0644]
sources/plugins/indent/lang/pl.js [new file with mode: 0644]
sources/plugins/indent/lang/pt-br.js [new file with mode: 0644]
sources/plugins/indent/lang/pt.js [new file with mode: 0644]
sources/plugins/indent/lang/ro.js [new file with mode: 0644]
sources/plugins/indent/lang/ru.js [new file with mode: 0644]
sources/plugins/indent/lang/si.js [new file with mode: 0644]
sources/plugins/indent/lang/sk.js [new file with mode: 0644]
sources/plugins/indent/lang/sl.js [new file with mode: 0644]
sources/plugins/indent/lang/sq.js [new file with mode: 0644]
sources/plugins/indent/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/indent/lang/sr.js [new file with mode: 0644]
sources/plugins/indent/lang/sv.js [new file with mode: 0644]
sources/plugins/indent/lang/th.js [new file with mode: 0644]
sources/plugins/indent/lang/tr.js [new file with mode: 0644]
sources/plugins/indent/lang/tt.js [new file with mode: 0644]
sources/plugins/indent/lang/ug.js [new file with mode: 0644]
sources/plugins/indent/lang/uk.js [new file with mode: 0644]
sources/plugins/indent/lang/vi.js [new file with mode: 0644]
sources/plugins/indent/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/indent/lang/zh.js [new file with mode: 0644]
sources/plugins/indent/plugin.js [new file with mode: 0644]
sources/plugins/indentblock/plugin.js [new file with mode: 0644]
sources/plugins/indentlist/plugin.js [new file with mode: 0644]
sources/plugins/justify/icons/hidpi/justifyblock.png [new file with mode: 0644]
sources/plugins/justify/icons/hidpi/justifycenter.png [new file with mode: 0644]
sources/plugins/justify/icons/hidpi/justifyleft.png [new file with mode: 0644]
sources/plugins/justify/icons/hidpi/justifyright.png [new file with mode: 0644]
sources/plugins/justify/icons/justifyblock.png [new file with mode: 0644]
sources/plugins/justify/icons/justifycenter.png [new file with mode: 0644]
sources/plugins/justify/icons/justifyleft.png [new file with mode: 0644]
sources/plugins/justify/icons/justifyright.png [new file with mode: 0644]
sources/plugins/justify/lang/af.js [new file with mode: 0644]
sources/plugins/justify/lang/ar.js [new file with mode: 0644]
sources/plugins/justify/lang/az.js [new file with mode: 0644]
sources/plugins/justify/lang/bg.js [new file with mode: 0644]
sources/plugins/justify/lang/bn.js [new file with mode: 0644]
sources/plugins/justify/lang/bs.js [new file with mode: 0644]
sources/plugins/justify/lang/ca.js [new file with mode: 0644]
sources/plugins/justify/lang/cs.js [new file with mode: 0644]
sources/plugins/justify/lang/cy.js [new file with mode: 0644]
sources/plugins/justify/lang/da.js [new file with mode: 0644]
sources/plugins/justify/lang/de-ch.js [new file with mode: 0644]
sources/plugins/justify/lang/de.js [new file with mode: 0644]
sources/plugins/justify/lang/el.js [new file with mode: 0644]
sources/plugins/justify/lang/en-au.js [new file with mode: 0644]
sources/plugins/justify/lang/en-ca.js [new file with mode: 0644]
sources/plugins/justify/lang/en-gb.js [new file with mode: 0644]
sources/plugins/justify/lang/en.js [new file with mode: 0644]
sources/plugins/justify/lang/eo.js [new file with mode: 0644]
sources/plugins/justify/lang/es.js [new file with mode: 0644]
sources/plugins/justify/lang/et.js [new file with mode: 0644]
sources/plugins/justify/lang/eu.js [new file with mode: 0644]
sources/plugins/justify/lang/fa.js [new file with mode: 0644]
sources/plugins/justify/lang/fi.js [new file with mode: 0644]
sources/plugins/justify/lang/fo.js [new file with mode: 0644]
sources/plugins/justify/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/justify/lang/fr.js [new file with mode: 0644]
sources/plugins/justify/lang/gl.js [new file with mode: 0644]
sources/plugins/justify/lang/gu.js [new file with mode: 0644]
sources/plugins/justify/lang/he.js [new file with mode: 0644]
sources/plugins/justify/lang/hi.js [new file with mode: 0644]
sources/plugins/justify/lang/hr.js [new file with mode: 0644]
sources/plugins/justify/lang/hu.js [new file with mode: 0644]
sources/plugins/justify/lang/id.js [new file with mode: 0644]
sources/plugins/justify/lang/is.js [new file with mode: 0644]
sources/plugins/justify/lang/it.js [new file with mode: 0644]
sources/plugins/justify/lang/ja.js [new file with mode: 0644]
sources/plugins/justify/lang/ka.js [new file with mode: 0644]
sources/plugins/justify/lang/km.js [new file with mode: 0644]
sources/plugins/justify/lang/ko.js [new file with mode: 0644]
sources/plugins/justify/lang/ku.js [new file with mode: 0644]
sources/plugins/justify/lang/lt.js [new file with mode: 0644]
sources/plugins/justify/lang/lv.js [new file with mode: 0644]
sources/plugins/justify/lang/mk.js [new file with mode: 0644]
sources/plugins/justify/lang/mn.js [new file with mode: 0644]
sources/plugins/justify/lang/ms.js [new file with mode: 0644]
sources/plugins/justify/lang/nb.js [new file with mode: 0644]
sources/plugins/justify/lang/nl.js [new file with mode: 0644]
sources/plugins/justify/lang/no.js [new file with mode: 0644]
sources/plugins/justify/lang/oc.js [new file with mode: 0644]
sources/plugins/justify/lang/pl.js [new file with mode: 0644]
sources/plugins/justify/lang/pt-br.js [new file with mode: 0644]
sources/plugins/justify/lang/pt.js [new file with mode: 0644]
sources/plugins/justify/lang/ro.js [new file with mode: 0644]
sources/plugins/justify/lang/ru.js [new file with mode: 0644]
sources/plugins/justify/lang/si.js [new file with mode: 0644]
sources/plugins/justify/lang/sk.js [new file with mode: 0644]
sources/plugins/justify/lang/sl.js [new file with mode: 0644]
sources/plugins/justify/lang/sq.js [new file with mode: 0644]
sources/plugins/justify/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/justify/lang/sr.js [new file with mode: 0644]
sources/plugins/justify/lang/sv.js [new file with mode: 0644]
sources/plugins/justify/lang/th.js [new file with mode: 0644]
sources/plugins/justify/lang/tr.js [new file with mode: 0644]
sources/plugins/justify/lang/tt.js [new file with mode: 0644]
sources/plugins/justify/lang/ug.js [new file with mode: 0644]
sources/plugins/justify/lang/uk.js [new file with mode: 0644]
sources/plugins/justify/lang/vi.js [new file with mode: 0644]
sources/plugins/justify/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/justify/lang/zh.js [new file with mode: 0644]
sources/plugins/justify/plugin.js [new file with mode: 0644]
sources/plugins/lineutils/dev/dnd.html [new file with mode: 0644]
sources/plugins/lineutils/dev/magicfinger.html [new file with mode: 0644]
sources/plugins/lineutils/plugin.js [new file with mode: 0644]
sources/plugins/link/dialogs/anchor.js [new file with mode: 0644]
sources/plugins/link/dialogs/link.js [new file with mode: 0644]
sources/plugins/link/icons/anchor-rtl.png [new file with mode: 0644]
sources/plugins/link/icons/anchor.png [new file with mode: 0644]
sources/plugins/link/icons/hidpi/anchor-rtl.png [new file with mode: 0644]
sources/plugins/link/icons/hidpi/anchor.png [new file with mode: 0644]
sources/plugins/link/icons/hidpi/link.png [new file with mode: 0644]
sources/plugins/link/icons/hidpi/unlink.png [new file with mode: 0644]
sources/plugins/link/icons/link.png [new file with mode: 0644]
sources/plugins/link/icons/unlink.png [new file with mode: 0644]
sources/plugins/link/images/anchor.png [new file with mode: 0644]
sources/plugins/link/images/hidpi/anchor.png [new file with mode: 0644]
sources/plugins/link/lang/af.js [new file with mode: 0644]
sources/plugins/link/lang/ar.js [new file with mode: 0644]
sources/plugins/link/lang/az.js [new file with mode: 0644]
sources/plugins/link/lang/bg.js [new file with mode: 0644]
sources/plugins/link/lang/bn.js [new file with mode: 0644]
sources/plugins/link/lang/bs.js [new file with mode: 0644]
sources/plugins/link/lang/ca.js [new file with mode: 0644]
sources/plugins/link/lang/cs.js [new file with mode: 0644]
sources/plugins/link/lang/cy.js [new file with mode: 0644]
sources/plugins/link/lang/da.js [new file with mode: 0644]
sources/plugins/link/lang/de-ch.js [new file with mode: 0644]
sources/plugins/link/lang/de.js [new file with mode: 0644]
sources/plugins/link/lang/el.js [new file with mode: 0644]
sources/plugins/link/lang/en-au.js [new file with mode: 0644]
sources/plugins/link/lang/en-ca.js [new file with mode: 0644]
sources/plugins/link/lang/en-gb.js [new file with mode: 0644]
sources/plugins/link/lang/en.js [new file with mode: 0644]
sources/plugins/link/lang/eo.js [new file with mode: 0644]
sources/plugins/link/lang/es.js [new file with mode: 0644]
sources/plugins/link/lang/et.js [new file with mode: 0644]
sources/plugins/link/lang/eu.js [new file with mode: 0644]
sources/plugins/link/lang/fa.js [new file with mode: 0644]
sources/plugins/link/lang/fi.js [new file with mode: 0644]
sources/plugins/link/lang/fo.js [new file with mode: 0644]
sources/plugins/link/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/link/lang/fr.js [new file with mode: 0644]
sources/plugins/link/lang/gl.js [new file with mode: 0644]
sources/plugins/link/lang/gu.js [new file with mode: 0644]
sources/plugins/link/lang/he.js [new file with mode: 0644]
sources/plugins/link/lang/hi.js [new file with mode: 0644]
sources/plugins/link/lang/hr.js [new file with mode: 0644]
sources/plugins/link/lang/hu.js [new file with mode: 0644]
sources/plugins/link/lang/id.js [new file with mode: 0644]
sources/plugins/link/lang/is.js [new file with mode: 0644]
sources/plugins/link/lang/it.js [new file with mode: 0644]
sources/plugins/link/lang/ja.js [new file with mode: 0644]
sources/plugins/link/lang/ka.js [new file with mode: 0644]
sources/plugins/link/lang/km.js [new file with mode: 0644]
sources/plugins/link/lang/ko.js [new file with mode: 0644]
sources/plugins/link/lang/ku.js [new file with mode: 0644]
sources/plugins/link/lang/lt.js [new file with mode: 0644]
sources/plugins/link/lang/lv.js [new file with mode: 0644]
sources/plugins/link/lang/mk.js [new file with mode: 0644]
sources/plugins/link/lang/mn.js [new file with mode: 0644]
sources/plugins/link/lang/ms.js [new file with mode: 0644]
sources/plugins/link/lang/nb.js [new file with mode: 0644]
sources/plugins/link/lang/nl.js [new file with mode: 0644]
sources/plugins/link/lang/no.js [new file with mode: 0644]
sources/plugins/link/lang/oc.js [new file with mode: 0644]
sources/plugins/link/lang/pl.js [new file with mode: 0644]
sources/plugins/link/lang/pt-br.js [new file with mode: 0644]
sources/plugins/link/lang/pt.js [new file with mode: 0644]
sources/plugins/link/lang/ro.js [new file with mode: 0644]
sources/plugins/link/lang/ru.js [new file with mode: 0644]
sources/plugins/link/lang/si.js [new file with mode: 0644]
sources/plugins/link/lang/sk.js [new file with mode: 0644]
sources/plugins/link/lang/sl.js [new file with mode: 0644]
sources/plugins/link/lang/sq.js [new file with mode: 0644]
sources/plugins/link/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/link/lang/sr.js [new file with mode: 0644]
sources/plugins/link/lang/sv.js [new file with mode: 0644]
sources/plugins/link/lang/th.js [new file with mode: 0644]
sources/plugins/link/lang/tr.js [new file with mode: 0644]
sources/plugins/link/lang/tt.js [new file with mode: 0644]
sources/plugins/link/lang/ug.js [new file with mode: 0644]
sources/plugins/link/lang/uk.js [new file with mode: 0644]
sources/plugins/link/lang/vi.js [new file with mode: 0644]
sources/plugins/link/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/link/lang/zh.js [new file with mode: 0644]
sources/plugins/link/plugin.js [new file with mode: 0644]
sources/plugins/list/icons/bulletedlist-rtl.png [new file with mode: 0644]
sources/plugins/list/icons/bulletedlist.png [new file with mode: 0644]
sources/plugins/list/icons/hidpi/bulletedlist-rtl.png [new file with mode: 0644]
sources/plugins/list/icons/hidpi/bulletedlist.png [new file with mode: 0644]
sources/plugins/list/icons/hidpi/numberedlist-rtl.png [new file with mode: 0644]
sources/plugins/list/icons/hidpi/numberedlist.png [new file with mode: 0644]
sources/plugins/list/icons/numberedlist-rtl.png [new file with mode: 0644]
sources/plugins/list/icons/numberedlist.png [new file with mode: 0644]
sources/plugins/list/lang/af.js [new file with mode: 0644]
sources/plugins/list/lang/ar.js [new file with mode: 0644]
sources/plugins/list/lang/az.js [new file with mode: 0644]
sources/plugins/list/lang/bg.js [new file with mode: 0644]
sources/plugins/list/lang/bn.js [new file with mode: 0644]
sources/plugins/list/lang/bs.js [new file with mode: 0644]
sources/plugins/list/lang/ca.js [new file with mode: 0644]
sources/plugins/list/lang/cs.js [new file with mode: 0644]
sources/plugins/list/lang/cy.js [new file with mode: 0644]
sources/plugins/list/lang/da.js [new file with mode: 0644]
sources/plugins/list/lang/de-ch.js [new file with mode: 0644]
sources/plugins/list/lang/de.js [new file with mode: 0644]
sources/plugins/list/lang/el.js [new file with mode: 0644]
sources/plugins/list/lang/en-au.js [new file with mode: 0644]
sources/plugins/list/lang/en-ca.js [new file with mode: 0644]
sources/plugins/list/lang/en-gb.js [new file with mode: 0644]
sources/plugins/list/lang/en.js [new file with mode: 0644]
sources/plugins/list/lang/eo.js [new file with mode: 0644]
sources/plugins/list/lang/es.js [new file with mode: 0644]
sources/plugins/list/lang/et.js [new file with mode: 0644]
sources/plugins/list/lang/eu.js [new file with mode: 0644]
sources/plugins/list/lang/fa.js [new file with mode: 0644]
sources/plugins/list/lang/fi.js [new file with mode: 0644]
sources/plugins/list/lang/fo.js [new file with mode: 0644]
sources/plugins/list/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/list/lang/fr.js [new file with mode: 0644]
sources/plugins/list/lang/gl.js [new file with mode: 0644]
sources/plugins/list/lang/gu.js [new file with mode: 0644]
sources/plugins/list/lang/he.js [new file with mode: 0644]
sources/plugins/list/lang/hi.js [new file with mode: 0644]
sources/plugins/list/lang/hr.js [new file with mode: 0644]
sources/plugins/list/lang/hu.js [new file with mode: 0644]
sources/plugins/list/lang/id.js [new file with mode: 0644]
sources/plugins/list/lang/is.js [new file with mode: 0644]
sources/plugins/list/lang/it.js [new file with mode: 0644]
sources/plugins/list/lang/ja.js [new file with mode: 0644]
sources/plugins/list/lang/ka.js [new file with mode: 0644]
sources/plugins/list/lang/km.js [new file with mode: 0644]
sources/plugins/list/lang/ko.js [new file with mode: 0644]
sources/plugins/list/lang/ku.js [new file with mode: 0644]
sources/plugins/list/lang/lt.js [new file with mode: 0644]
sources/plugins/list/lang/lv.js [new file with mode: 0644]
sources/plugins/list/lang/mk.js [new file with mode: 0644]
sources/plugins/list/lang/mn.js [new file with mode: 0644]
sources/plugins/list/lang/ms.js [new file with mode: 0644]
sources/plugins/list/lang/nb.js [new file with mode: 0644]
sources/plugins/list/lang/nl.js [new file with mode: 0644]
sources/plugins/list/lang/no.js [new file with mode: 0644]
sources/plugins/list/lang/oc.js [new file with mode: 0644]
sources/plugins/list/lang/pl.js [new file with mode: 0644]
sources/plugins/list/lang/pt-br.js [new file with mode: 0644]
sources/plugins/list/lang/pt.js [new file with mode: 0644]
sources/plugins/list/lang/ro.js [new file with mode: 0644]
sources/plugins/list/lang/ru.js [new file with mode: 0644]
sources/plugins/list/lang/si.js [new file with mode: 0644]
sources/plugins/list/lang/sk.js [new file with mode: 0644]
sources/plugins/list/lang/sl.js [new file with mode: 0644]
sources/plugins/list/lang/sq.js [new file with mode: 0644]
sources/plugins/list/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/list/lang/sr.js [new file with mode: 0644]
sources/plugins/list/lang/sv.js [new file with mode: 0644]
sources/plugins/list/lang/th.js [new file with mode: 0644]
sources/plugins/list/lang/tr.js [new file with mode: 0644]
sources/plugins/list/lang/tt.js [new file with mode: 0644]
sources/plugins/list/lang/ug.js [new file with mode: 0644]
sources/plugins/list/lang/uk.js [new file with mode: 0644]
sources/plugins/list/lang/vi.js [new file with mode: 0644]
sources/plugins/list/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/list/lang/zh.js [new file with mode: 0644]
sources/plugins/list/plugin.js [new file with mode: 0644]
sources/plugins/listblock/plugin.js [new file with mode: 0644]
sources/plugins/liststyle/dialogs/liststyle.js [new file with mode: 0644]
sources/plugins/liststyle/lang/af.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ar.js [new file with mode: 0644]
sources/plugins/liststyle/lang/az.js [new file with mode: 0644]
sources/plugins/liststyle/lang/bg.js [new file with mode: 0644]
sources/plugins/liststyle/lang/bn.js [new file with mode: 0644]
sources/plugins/liststyle/lang/bs.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ca.js [new file with mode: 0644]
sources/plugins/liststyle/lang/cs.js [new file with mode: 0644]
sources/plugins/liststyle/lang/cy.js [new file with mode: 0644]
sources/plugins/liststyle/lang/da.js [new file with mode: 0644]
sources/plugins/liststyle/lang/de-ch.js [new file with mode: 0644]
sources/plugins/liststyle/lang/de.js [new file with mode: 0644]
sources/plugins/liststyle/lang/el.js [new file with mode: 0644]
sources/plugins/liststyle/lang/en-au.js [new file with mode: 0644]
sources/plugins/liststyle/lang/en-ca.js [new file with mode: 0644]
sources/plugins/liststyle/lang/en-gb.js [new file with mode: 0644]
sources/plugins/liststyle/lang/en.js [new file with mode: 0644]
sources/plugins/liststyle/lang/eo.js [new file with mode: 0644]
sources/plugins/liststyle/lang/es.js [new file with mode: 0644]
sources/plugins/liststyle/lang/et.js [new file with mode: 0644]
sources/plugins/liststyle/lang/eu.js [new file with mode: 0644]
sources/plugins/liststyle/lang/fa.js [new file with mode: 0644]
sources/plugins/liststyle/lang/fi.js [new file with mode: 0644]
sources/plugins/liststyle/lang/fo.js [new file with mode: 0644]
sources/plugins/liststyle/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/liststyle/lang/fr.js [new file with mode: 0644]
sources/plugins/liststyle/lang/gl.js [new file with mode: 0644]
sources/plugins/liststyle/lang/gu.js [new file with mode: 0644]
sources/plugins/liststyle/lang/he.js [new file with mode: 0644]
sources/plugins/liststyle/lang/hi.js [new file with mode: 0644]
sources/plugins/liststyle/lang/hr.js [new file with mode: 0644]
sources/plugins/liststyle/lang/hu.js [new file with mode: 0644]
sources/plugins/liststyle/lang/id.js [new file with mode: 0644]
sources/plugins/liststyle/lang/is.js [new file with mode: 0644]
sources/plugins/liststyle/lang/it.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ja.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ka.js [new file with mode: 0644]
sources/plugins/liststyle/lang/km.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ko.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ku.js [new file with mode: 0644]
sources/plugins/liststyle/lang/lt.js [new file with mode: 0644]
sources/plugins/liststyle/lang/lv.js [new file with mode: 0644]
sources/plugins/liststyle/lang/mk.js [new file with mode: 0644]
sources/plugins/liststyle/lang/mn.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ms.js [new file with mode: 0644]
sources/plugins/liststyle/lang/nb.js [new file with mode: 0644]
sources/plugins/liststyle/lang/nl.js [new file with mode: 0644]
sources/plugins/liststyle/lang/no.js [new file with mode: 0644]
sources/plugins/liststyle/lang/oc.js [new file with mode: 0644]
sources/plugins/liststyle/lang/pl.js [new file with mode: 0644]
sources/plugins/liststyle/lang/pt-br.js [new file with mode: 0644]
sources/plugins/liststyle/lang/pt.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ro.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ru.js [new file with mode: 0644]
sources/plugins/liststyle/lang/si.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sk.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sl.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sq.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sr.js [new file with mode: 0644]
sources/plugins/liststyle/lang/sv.js [new file with mode: 0644]
sources/plugins/liststyle/lang/th.js [new file with mode: 0644]
sources/plugins/liststyle/lang/tr.js [new file with mode: 0644]
sources/plugins/liststyle/lang/tt.js [new file with mode: 0644]
sources/plugins/liststyle/lang/ug.js [new file with mode: 0644]
sources/plugins/liststyle/lang/uk.js [new file with mode: 0644]
sources/plugins/liststyle/lang/vi.js [new file with mode: 0644]
sources/plugins/liststyle/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/liststyle/lang/zh.js [new file with mode: 0644]
sources/plugins/liststyle/plugin.js [new file with mode: 0644]
sources/plugins/magicline/dev/magicline.html [new file with mode: 0644]
sources/plugins/magicline/images/hidpi/icon-rtl.png [new file with mode: 0644]
sources/plugins/magicline/images/hidpi/icon.png [new file with mode: 0644]
sources/plugins/magicline/images/icon-rtl.png [new file with mode: 0644]
sources/plugins/magicline/images/icon.png [new file with mode: 0644]
sources/plugins/magicline/lang/af.js [new file with mode: 0644]
sources/plugins/magicline/lang/ar.js [new file with mode: 0644]
sources/plugins/magicline/lang/az.js [new file with mode: 0644]
sources/plugins/magicline/lang/bg.js [new file with mode: 0644]
sources/plugins/magicline/lang/ca.js [new file with mode: 0644]
sources/plugins/magicline/lang/cs.js [new file with mode: 0644]
sources/plugins/magicline/lang/cy.js [new file with mode: 0644]
sources/plugins/magicline/lang/da.js [new file with mode: 0644]
sources/plugins/magicline/lang/de-ch.js [new file with mode: 0644]
sources/plugins/magicline/lang/de.js [new file with mode: 0644]
sources/plugins/magicline/lang/el.js [new file with mode: 0644]
sources/plugins/magicline/lang/en-gb.js [new file with mode: 0644]
sources/plugins/magicline/lang/en.js [new file with mode: 0644]
sources/plugins/magicline/lang/eo.js [new file with mode: 0644]
sources/plugins/magicline/lang/es.js [new file with mode: 0644]
sources/plugins/magicline/lang/et.js [new file with mode: 0644]
sources/plugins/magicline/lang/eu.js [new file with mode: 0644]
sources/plugins/magicline/lang/fa.js [new file with mode: 0644]
sources/plugins/magicline/lang/fi.js [new file with mode: 0644]
sources/plugins/magicline/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/magicline/lang/fr.js [new file with mode: 0644]
sources/plugins/magicline/lang/gl.js [new file with mode: 0644]
sources/plugins/magicline/lang/he.js [new file with mode: 0644]
sources/plugins/magicline/lang/hr.js [new file with mode: 0644]
sources/plugins/magicline/lang/hu.js [new file with mode: 0644]
sources/plugins/magicline/lang/id.js [new file with mode: 0644]
sources/plugins/magicline/lang/it.js [new file with mode: 0644]
sources/plugins/magicline/lang/ja.js [new file with mode: 0644]
sources/plugins/magicline/lang/km.js [new file with mode: 0644]
sources/plugins/magicline/lang/ko.js [new file with mode: 0644]
sources/plugins/magicline/lang/ku.js [new file with mode: 0644]
sources/plugins/magicline/lang/lv.js [new file with mode: 0644]
sources/plugins/magicline/lang/nb.js [new file with mode: 0644]
sources/plugins/magicline/lang/nl.js [new file with mode: 0644]
sources/plugins/magicline/lang/no.js [new file with mode: 0644]
sources/plugins/magicline/lang/oc.js [new file with mode: 0644]
sources/plugins/magicline/lang/pl.js [new file with mode: 0644]
sources/plugins/magicline/lang/pt-br.js [new file with mode: 0644]
sources/plugins/magicline/lang/pt.js [new file with mode: 0644]
sources/plugins/magicline/lang/ru.js [new file with mode: 0644]
sources/plugins/magicline/lang/si.js [new file with mode: 0644]
sources/plugins/magicline/lang/sk.js [new file with mode: 0644]
sources/plugins/magicline/lang/sl.js [new file with mode: 0644]
sources/plugins/magicline/lang/sq.js [new file with mode: 0644]
sources/plugins/magicline/lang/sv.js [new file with mode: 0644]
sources/plugins/magicline/lang/tr.js [new file with mode: 0644]
sources/plugins/magicline/lang/tt.js [new file with mode: 0644]
sources/plugins/magicline/lang/ug.js [new file with mode: 0644]
sources/plugins/magicline/lang/uk.js [new file with mode: 0644]
sources/plugins/magicline/lang/vi.js [new file with mode: 0644]
sources/plugins/magicline/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/magicline/lang/zh.js [new file with mode: 0644]
sources/plugins/magicline/plugin.js [new file with mode: 0644]
sources/plugins/magicline/samples/magicline.html [new file with mode: 0644]
sources/plugins/maximize/icons/hidpi/maximize.png [new file with mode: 0644]
sources/plugins/maximize/icons/maximize.png [new file with mode: 0644]
sources/plugins/maximize/lang/af.js [new file with mode: 0644]
sources/plugins/maximize/lang/ar.js [new file with mode: 0644]
sources/plugins/maximize/lang/az.js [new file with mode: 0644]
sources/plugins/maximize/lang/bg.js [new file with mode: 0644]
sources/plugins/maximize/lang/bn.js [new file with mode: 0644]
sources/plugins/maximize/lang/bs.js [new file with mode: 0644]
sources/plugins/maximize/lang/ca.js [new file with mode: 0644]
sources/plugins/maximize/lang/cs.js [new file with mode: 0644]
sources/plugins/maximize/lang/cy.js [new file with mode: 0644]
sources/plugins/maximize/lang/da.js [new file with mode: 0644]
sources/plugins/maximize/lang/de-ch.js [new file with mode: 0644]
sources/plugins/maximize/lang/de.js [new file with mode: 0644]
sources/plugins/maximize/lang/el.js [new file with mode: 0644]
sources/plugins/maximize/lang/en-au.js [new file with mode: 0644]
sources/plugins/maximize/lang/en-ca.js [new file with mode: 0644]
sources/plugins/maximize/lang/en-gb.js [new file with mode: 0644]
sources/plugins/maximize/lang/en.js [new file with mode: 0644]
sources/plugins/maximize/lang/eo.js [new file with mode: 0644]
sources/plugins/maximize/lang/es.js [new file with mode: 0644]
sources/plugins/maximize/lang/et.js [new file with mode: 0644]
sources/plugins/maximize/lang/eu.js [new file with mode: 0644]
sources/plugins/maximize/lang/fa.js [new file with mode: 0644]
sources/plugins/maximize/lang/fi.js [new file with mode: 0644]
sources/plugins/maximize/lang/fo.js [new file with mode: 0644]
sources/plugins/maximize/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/maximize/lang/fr.js [new file with mode: 0644]
sources/plugins/maximize/lang/gl.js [new file with mode: 0644]
sources/plugins/maximize/lang/gu.js [new file with mode: 0644]
sources/plugins/maximize/lang/he.js [new file with mode: 0644]
sources/plugins/maximize/lang/hi.js [new file with mode: 0644]
sources/plugins/maximize/lang/hr.js [new file with mode: 0644]
sources/plugins/maximize/lang/hu.js [new file with mode: 0644]
sources/plugins/maximize/lang/id.js [new file with mode: 0644]
sources/plugins/maximize/lang/is.js [new file with mode: 0644]
sources/plugins/maximize/lang/it.js [new file with mode: 0644]
sources/plugins/maximize/lang/ja.js [new file with mode: 0644]
sources/plugins/maximize/lang/ka.js [new file with mode: 0644]
sources/plugins/maximize/lang/km.js [new file with mode: 0644]
sources/plugins/maximize/lang/ko.js [new file with mode: 0644]
sources/plugins/maximize/lang/ku.js [new file with mode: 0644]
sources/plugins/maximize/lang/lt.js [new file with mode: 0644]
sources/plugins/maximize/lang/lv.js [new file with mode: 0644]
sources/plugins/maximize/lang/mk.js [new file with mode: 0644]
sources/plugins/maximize/lang/mn.js [new file with mode: 0644]
sources/plugins/maximize/lang/ms.js [new file with mode: 0644]
sources/plugins/maximize/lang/nb.js [new file with mode: 0644]
sources/plugins/maximize/lang/nl.js [new file with mode: 0644]
sources/plugins/maximize/lang/no.js [new file with mode: 0644]
sources/plugins/maximize/lang/oc.js [new file with mode: 0644]
sources/plugins/maximize/lang/pl.js [new file with mode: 0644]
sources/plugins/maximize/lang/pt-br.js [new file with mode: 0644]
sources/plugins/maximize/lang/pt.js [new file with mode: 0644]
sources/plugins/maximize/lang/ro.js [new file with mode: 0644]
sources/plugins/maximize/lang/ru.js [new file with mode: 0644]
sources/plugins/maximize/lang/si.js [new file with mode: 0644]
sources/plugins/maximize/lang/sk.js [new file with mode: 0644]
sources/plugins/maximize/lang/sl.js [new file with mode: 0644]
sources/plugins/maximize/lang/sq.js [new file with mode: 0644]
sources/plugins/maximize/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/maximize/lang/sr.js [new file with mode: 0644]
sources/plugins/maximize/lang/sv.js [new file with mode: 0644]
sources/plugins/maximize/lang/th.js [new file with mode: 0644]
sources/plugins/maximize/lang/tr.js [new file with mode: 0644]
sources/plugins/maximize/lang/tt.js [new file with mode: 0644]
sources/plugins/maximize/lang/ug.js [new file with mode: 0644]
sources/plugins/maximize/lang/uk.js [new file with mode: 0644]
sources/plugins/maximize/lang/vi.js [new file with mode: 0644]
sources/plugins/maximize/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/maximize/lang/zh.js [new file with mode: 0644]
sources/plugins/maximize/plugin.js [new file with mode: 0644]
sources/plugins/menu/plugin.js [new file with mode: 0644]
sources/plugins/oembed/LICENSE.md [new file with mode: 0644]
sources/plugins/oembed/README.md [new file with mode: 0644]
sources/plugins/oembed/icons/hidpi/oembed.png [new file with mode: 0644]
sources/plugins/oembed/icons/oembed.png [new file with mode: 0644]
sources/plugins/oembed/lang/de.js [new file with mode: 0644]
sources/plugins/oembed/lang/en.js [new file with mode: 0644]
sources/plugins/oembed/lang/fr.js [new file with mode: 0644]
sources/plugins/oembed/lang/nl.js [new file with mode: 0644]
sources/plugins/oembed/lang/pl.js [new file with mode: 0644]
sources/plugins/oembed/lang/pt-br.js [new file with mode: 0644]
sources/plugins/oembed/lang/ru.js [new file with mode: 0644]
sources/plugins/oembed/lang/tr.js [new file with mode: 0644]
sources/plugins/oembed/libs/jquery.oembed.min.js [new file with mode: 0644]
sources/plugins/oembed/plugin.js [new file with mode: 0644]
sources/plugins/panel/plugin.js [new file with mode: 0644]
sources/plugins/popup/plugin.js [new file with mode: 0644]
sources/plugins/removeformat/icons/hidpi/removeformat.png [new file with mode: 0644]
sources/plugins/removeformat/icons/removeformat.png [new file with mode: 0644]
sources/plugins/removeformat/lang/af.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ar.js [new file with mode: 0644]
sources/plugins/removeformat/lang/az.js [new file with mode: 0644]
sources/plugins/removeformat/lang/bg.js [new file with mode: 0644]
sources/plugins/removeformat/lang/bn.js [new file with mode: 0644]
sources/plugins/removeformat/lang/bs.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ca.js [new file with mode: 0644]
sources/plugins/removeformat/lang/cs.js [new file with mode: 0644]
sources/plugins/removeformat/lang/cy.js [new file with mode: 0644]
sources/plugins/removeformat/lang/da.js [new file with mode: 0644]
sources/plugins/removeformat/lang/de-ch.js [new file with mode: 0644]
sources/plugins/removeformat/lang/de.js [new file with mode: 0644]
sources/plugins/removeformat/lang/el.js [new file with mode: 0644]
sources/plugins/removeformat/lang/en-au.js [new file with mode: 0644]
sources/plugins/removeformat/lang/en-ca.js [new file with mode: 0644]
sources/plugins/removeformat/lang/en-gb.js [new file with mode: 0644]
sources/plugins/removeformat/lang/en.js [new file with mode: 0644]
sources/plugins/removeformat/lang/eo.js [new file with mode: 0644]
sources/plugins/removeformat/lang/es.js [new file with mode: 0644]
sources/plugins/removeformat/lang/et.js [new file with mode: 0644]
sources/plugins/removeformat/lang/eu.js [new file with mode: 0644]
sources/plugins/removeformat/lang/fa.js [new file with mode: 0644]
sources/plugins/removeformat/lang/fi.js [new file with mode: 0644]
sources/plugins/removeformat/lang/fo.js [new file with mode: 0644]
sources/plugins/removeformat/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/removeformat/lang/fr.js [new file with mode: 0644]
sources/plugins/removeformat/lang/gl.js [new file with mode: 0644]
sources/plugins/removeformat/lang/gu.js [new file with mode: 0644]
sources/plugins/removeformat/lang/he.js [new file with mode: 0644]
sources/plugins/removeformat/lang/hi.js [new file with mode: 0644]
sources/plugins/removeformat/lang/hr.js [new file with mode: 0644]
sources/plugins/removeformat/lang/hu.js [new file with mode: 0644]
sources/plugins/removeformat/lang/id.js [new file with mode: 0644]
sources/plugins/removeformat/lang/is.js [new file with mode: 0644]
sources/plugins/removeformat/lang/it.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ja.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ka.js [new file with mode: 0644]
sources/plugins/removeformat/lang/km.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ko.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ku.js [new file with mode: 0644]
sources/plugins/removeformat/lang/lt.js [new file with mode: 0644]
sources/plugins/removeformat/lang/lv.js [new file with mode: 0644]
sources/plugins/removeformat/lang/mk.js [new file with mode: 0644]
sources/plugins/removeformat/lang/mn.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ms.js [new file with mode: 0644]
sources/plugins/removeformat/lang/nb.js [new file with mode: 0644]
sources/plugins/removeformat/lang/nl.js [new file with mode: 0644]
sources/plugins/removeformat/lang/no.js [new file with mode: 0644]
sources/plugins/removeformat/lang/oc.js [new file with mode: 0644]
sources/plugins/removeformat/lang/pl.js [new file with mode: 0644]
sources/plugins/removeformat/lang/pt-br.js [new file with mode: 0644]
sources/plugins/removeformat/lang/pt.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ro.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ru.js [new file with mode: 0644]
sources/plugins/removeformat/lang/si.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sk.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sl.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sq.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sr.js [new file with mode: 0644]
sources/plugins/removeformat/lang/sv.js [new file with mode: 0644]
sources/plugins/removeformat/lang/th.js [new file with mode: 0644]
sources/plugins/removeformat/lang/tr.js [new file with mode: 0644]
sources/plugins/removeformat/lang/tt.js [new file with mode: 0644]
sources/plugins/removeformat/lang/ug.js [new file with mode: 0644]
sources/plugins/removeformat/lang/uk.js [new file with mode: 0644]
sources/plugins/removeformat/lang/vi.js [new file with mode: 0644]
sources/plugins/removeformat/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/removeformat/lang/zh.js [new file with mode: 0644]
sources/plugins/removeformat/plugin.js [new file with mode: 0644]
sources/plugins/resize/plugin.js [new file with mode: 0644]
sources/plugins/richcombo/plugin.js [new file with mode: 0644]
sources/plugins/showborders/plugin.js [new file with mode: 0644]
sources/plugins/sourcearea/icons/hidpi/source-rtl.png [new file with mode: 0644]
sources/plugins/sourcearea/icons/hidpi/source.png [new file with mode: 0644]
sources/plugins/sourcearea/icons/source-rtl.png [new file with mode: 0644]
sources/plugins/sourcearea/icons/source.png [new file with mode: 0644]
sources/plugins/sourcearea/lang/af.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ar.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/az.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/bg.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/bn.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/bs.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ca.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/cs.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/cy.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/da.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/de-ch.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/de.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/el.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/en-au.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/en-ca.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/en-gb.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/en.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/eo.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/es.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/et.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/eu.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/fa.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/fi.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/fo.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/fr.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/gl.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/gu.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/he.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/hi.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/hr.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/hu.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/id.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/is.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/it.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ja.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ka.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/km.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ko.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ku.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/lt.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/lv.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/mk.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/mn.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ms.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/nb.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/nl.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/no.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/oc.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/pl.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/pt-br.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/pt.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ro.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ru.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/si.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sk.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sl.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sq.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sr.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/sv.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/th.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/tr.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/tt.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/ug.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/uk.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/vi.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/sourcearea/lang/zh.js [new file with mode: 0644]
sources/plugins/sourcearea/plugin.js [new file with mode: 0644]
sources/plugins/tab/plugin.js [new file with mode: 0644]
sources/plugins/toolbar/lang/af.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ar.js [new file with mode: 0644]
sources/plugins/toolbar/lang/az.js [new file with mode: 0644]
sources/plugins/toolbar/lang/bg.js [new file with mode: 0644]
sources/plugins/toolbar/lang/bn.js [new file with mode: 0644]
sources/plugins/toolbar/lang/bs.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ca.js [new file with mode: 0644]
sources/plugins/toolbar/lang/cs.js [new file with mode: 0644]
sources/plugins/toolbar/lang/cy.js [new file with mode: 0644]
sources/plugins/toolbar/lang/da.js [new file with mode: 0644]
sources/plugins/toolbar/lang/de-ch.js [new file with mode: 0644]
sources/plugins/toolbar/lang/de.js [new file with mode: 0644]
sources/plugins/toolbar/lang/el.js [new file with mode: 0644]
sources/plugins/toolbar/lang/en-au.js [new file with mode: 0644]
sources/plugins/toolbar/lang/en-ca.js [new file with mode: 0644]
sources/plugins/toolbar/lang/en-gb.js [new file with mode: 0644]
sources/plugins/toolbar/lang/en.js [new file with mode: 0644]
sources/plugins/toolbar/lang/eo.js [new file with mode: 0644]
sources/plugins/toolbar/lang/es.js [new file with mode: 0644]
sources/plugins/toolbar/lang/et.js [new file with mode: 0644]
sources/plugins/toolbar/lang/eu.js [new file with mode: 0644]
sources/plugins/toolbar/lang/fa.js [new file with mode: 0644]
sources/plugins/toolbar/lang/fi.js [new file with mode: 0644]
sources/plugins/toolbar/lang/fo.js [new file with mode: 0644]
sources/plugins/toolbar/lang/fr-ca.js [new file with mode: 0644]
sources/plugins/toolbar/lang/fr.js [new file with mode: 0644]
sources/plugins/toolbar/lang/gl.js [new file with mode: 0644]
sources/plugins/toolbar/lang/gu.js [new file with mode: 0644]
sources/plugins/toolbar/lang/he.js [new file with mode: 0644]
sources/plugins/toolbar/lang/hi.js [new file with mode: 0644]
sources/plugins/toolbar/lang/hr.js [new file with mode: 0644]
sources/plugins/toolbar/lang/hu.js [new file with mode: 0644]
sources/plugins/toolbar/lang/id.js [new file with mode: 0644]
sources/plugins/toolbar/lang/is.js [new file with mode: 0644]
sources/plugins/toolbar/lang/it.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ja.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ka.js [new file with mode: 0644]
sources/plugins/toolbar/lang/km.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ko.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ku.js [new file with mode: 0644]
sources/plugins/toolbar/lang/lt.js [new file with mode: 0644]
sources/plugins/toolbar/lang/lv.js [new file with mode: 0644]
sources/plugins/toolbar/lang/mk.js [new file with mode: 0644]
sources/plugins/toolbar/lang/mn.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ms.js [new file with mode: 0644]
sources/plugins/toolbar/lang/nb.js [new file with mode: 0644]
sources/plugins/toolbar/lang/nl.js [new file with mode: 0644]
sources/plugins/toolbar/lang/no.js [new file with mode: 0644]
sources/plugins/toolbar/lang/oc.js [new file with mode: 0644]
sources/plugins/toolbar/lang/pl.js [new file with mode: 0644]
sources/plugins/toolbar/lang/pt-br.js [new file with mode: 0644]
sources/plugins/toolbar/lang/pt.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ro.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ru.js [new file with mode: 0644]
sources/plugins/toolbar/lang/si.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sk.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sl.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sq.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sr-latn.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sr.js [new file with mode: 0644]
sources/plugins/toolbar/lang/sv.js [new file with mode: 0644]
sources/plugins/toolbar/lang/th.js [new file with mode: 0644]
sources/plugins/toolbar/lang/tr.js [new file with mode: 0644]
sources/plugins/toolbar/lang/tt.js [new file with mode: 0644]
sources/plugins/toolbar/lang/ug.js [new file with mode: 0644]
sources/plugins/toolbar/lang/uk.js [new file with mode: 0644]
sources/plugins/toolbar/lang/vi.js [new file with mode: 0644]
sources/plugins/toolbar/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/toolbar/lang/zh.js [new file with mode: 0644]
sources/plugins/toolbar/plugin.js [new file with mode: 0644]
sources/plugins/toolbar/samples/toolbar.html [new file with mode: 0644]
sources/plugins/widget/dev/assets/contents.css [new file with mode: 0644]
sources/plugins/widget/dev/assets/sample.jpg [new file with mode: 0644]
sources/plugins/widget/dev/assets/simplebox/contents.css [new file with mode: 0644]
sources/plugins/widget/dev/assets/simplebox/dialogs/simplebox.js [new file with mode: 0644]
sources/plugins/widget/dev/assets/simplebox/icons/simplebox.png [new file with mode: 0644]
sources/plugins/widget/dev/assets/simplebox/plugin.js [new file with mode: 0644]
sources/plugins/widget/dev/console.js [new file with mode: 0644]
sources/plugins/widget/dev/nestedwidgets.html [new file with mode: 0644]
sources/plugins/widget/dev/widgetstyles.html [new file with mode: 0644]
sources/plugins/widget/images/handle.png [new file with mode: 0644]
sources/plugins/widget/lang/af.js [new file with mode: 0644]
sources/plugins/widget/lang/ar.js [new file with mode: 0644]
sources/plugins/widget/lang/az.js [new file with mode: 0644]
sources/plugins/widget/lang/bg.js [new file with mode: 0644]
sources/plugins/widget/lang/ca.js [new file with mode: 0644]
sources/plugins/widget/lang/cs.js [new file with mode: 0644]
sources/plugins/widget/lang/cy.js [new file with mode: 0644]
sources/plugins/widget/lang/da.js [new file with mode: 0644]
sources/plugins/widget/lang/de-ch.js [new file with mode: 0644]
sources/plugins/widget/lang/de.js [new file with mode: 0644]
sources/plugins/widget/lang/el.js [new file with mode: 0644]
sources/plugins/widget/lang/en-gb.js [new file with mode: 0644]
sources/plugins/widget/lang/en.js [new file with mode: 0644]
sources/plugins/widget/lang/eo.js [new file with mode: 0644]
sources/plugins/widget/lang/es.js [new file with mode: 0644]
sources/plugins/widget/lang/eu.js [new file with mode: 0644]
sources/plugins/widget/lang/fa.js [new file with mode: 0644]
sources/plugins/widget/lang/fi.js [new file with mode: 0644]
sources/plugins/widget/lang/fr.js [new file with mode: 0644]
sources/plugins/widget/lang/gl.js [new file with mode: 0644]
sources/plugins/widget/lang/he.js [new file with mode: 0644]
sources/plugins/widget/lang/hr.js [new file with mode: 0644]
sources/plugins/widget/lang/hu.js [new file with mode: 0644]
sources/plugins/widget/lang/id.js [new file with mode: 0644]
sources/plugins/widget/lang/it.js [new file with mode: 0644]
sources/plugins/widget/lang/ja.js [new file with mode: 0644]
sources/plugins/widget/lang/km.js [new file with mode: 0644]
sources/plugins/widget/lang/ko.js [new file with mode: 0644]
sources/plugins/widget/lang/ku.js [new file with mode: 0644]
sources/plugins/widget/lang/lv.js [new file with mode: 0644]
sources/plugins/widget/lang/nb.js [new file with mode: 0644]
sources/plugins/widget/lang/nl.js [new file with mode: 0644]
sources/plugins/widget/lang/no.js [new file with mode: 0644]
sources/plugins/widget/lang/oc.js [new file with mode: 0644]
sources/plugins/widget/lang/pl.js [new file with mode: 0644]
sources/plugins/widget/lang/pt-br.js [new file with mode: 0644]
sources/plugins/widget/lang/pt.js [new file with mode: 0644]
sources/plugins/widget/lang/ru.js [new file with mode: 0644]
sources/plugins/widget/lang/sk.js [new file with mode: 0644]
sources/plugins/widget/lang/sl.js [new file with mode: 0644]
sources/plugins/widget/lang/sq.js [new file with mode: 0644]
sources/plugins/widget/lang/sv.js [new file with mode: 0644]
sources/plugins/widget/lang/tr.js [new file with mode: 0644]
sources/plugins/widget/lang/tt.js [new file with mode: 0644]
sources/plugins/widget/lang/ug.js [new file with mode: 0644]
sources/plugins/widget/lang/uk.js [new file with mode: 0644]
sources/plugins/widget/lang/vi.js [new file with mode: 0644]
sources/plugins/widget/lang/zh-cn.js [new file with mode: 0644]
sources/plugins/widget/lang/zh.js [new file with mode: 0644]
sources/plugins/widget/plugin.js [new file with mode: 0644]
sources/plugins/widgetselection/plugin.js [new file with mode: 0644]
sources/plugins/wysiwygarea/plugin.js [new file with mode: 0644]
sources/plugins/wysiwygarea/samples/fullpage.html [new file with mode: 0644]
sources/samples/css/samples.css [new file with mode: 0644]
sources/samples/img/github-top.png [new file with mode: 0644]
sources/samples/img/header-bg.png [new file with mode: 0644]
sources/samples/img/header-separator.png [new file with mode: 0644]
sources/samples/img/logo.png [new file with mode: 0644]
sources/samples/img/navigation-tip.png [new file with mode: 0644]
sources/samples/index.html [new file with mode: 0644]
sources/samples/js/sample.js [new file with mode: 0644]
sources/samples/js/sf.js [new file with mode: 0644]
sources/samples/old/ajax.html [new file with mode: 0644]
sources/samples/old/api.html [new file with mode: 0644]
sources/samples/old/appendto.html [new file with mode: 0644]
sources/samples/old/assets/inlineall/logo.png [new file with mode: 0644]
sources/samples/old/assets/outputxhtml/outputxhtml.css [new file with mode: 0644]
sources/samples/old/assets/posteddata.php [new file with mode: 0644]
sources/samples/old/assets/sample.jpg [new file with mode: 0644]
sources/samples/old/assets/uilanguages/languages.js [new file with mode: 0644]
sources/samples/old/datafiltering.html [new file with mode: 0644]
sources/samples/old/divreplace.html [new file with mode: 0644]
sources/samples/old/index.html [new file with mode: 0644]
sources/samples/old/inlineall.html [new file with mode: 0644]
sources/samples/old/inlinebycode.html [new file with mode: 0644]
sources/samples/old/inlinetextarea.html [new file with mode: 0644]
sources/samples/old/jquery.html [new file with mode: 0644]
sources/samples/old/readonly.html [new file with mode: 0644]
sources/samples/old/replacebyclass.html [new file with mode: 0644]
sources/samples/old/replacebycode.html [new file with mode: 0644]
sources/samples/old/sample.css [new file with mode: 0644]
sources/samples/old/sample.js [new file with mode: 0644]
sources/samples/old/sample_posteddata.php [new file with mode: 0644]
sources/samples/old/tabindex.html [new file with mode: 0644]
sources/samples/old/uicolor.html [new file with mode: 0644]
sources/samples/old/uilanguages.html [new file with mode: 0644]
sources/samples/old/xhtmlstyle.html [new file with mode: 0644]
sources/samples/toolbarconfigurator/bender.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/css/fontello.css [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/LICENSE.txt [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/config.json [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/fontello.eot [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/fontello.svg [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/fontello.ttf [new file with mode: 0644]
sources/samples/toolbarconfigurator/font/fontello.woff [new file with mode: 0644]
sources/samples/toolbarconfigurator/index.html [new file with mode: 0644]
sources/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/js/fulltoolbareditor.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/js/toolbarmodifier.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/js/toolbartextmodifier.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/less/base.less [new file with mode: 0644]
sources/samples/toolbarconfigurator/less/toolbarmodifier.less [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/LICENSE [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/README.md [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/codemirror.css [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/codemirror.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/javascript.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/neo.css [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/show-hint.css [new file with mode: 0644]
sources/samples/toolbarconfigurator/lib/codemirror/show-hint.js [new file with mode: 0644]
sources/samples/toolbarconfigurator/package.json [new file with mode: 0644]
sources/samples/toolbarconfigurator/tests/one.js [new file with mode: 0644]
sources/skins/moono/colorpanel.css [new file with mode: 0644]
sources/skins/moono/dev/icons16.png [new file with mode: 0644]
sources/skins/moono/dev/icons16.svg [new file with mode: 0644]
sources/skins/moono/dev/icons32.png [new file with mode: 0644]
sources/skins/moono/dev/icons32.svg [new file with mode: 0644]
sources/skins/moono/dev/locations.json [new file with mode: 0644]
sources/skins/moono/dialog.css [new file with mode: 0644]
sources/skins/moono/dialog_ie.css [new file with mode: 0644]
sources/skins/moono/dialog_ie7.css [new file with mode: 0644]
sources/skins/moono/dialog_ie8.css [new file with mode: 0644]
sources/skins/moono/dialog_iequirks.css [new file with mode: 0644]
sources/skins/moono/editor.css [new file with mode: 0644]
sources/skins/moono/editor_gecko.css [new file with mode: 0644]
sources/skins/moono/editor_ie.css [new file with mode: 0644]
sources/skins/moono/editor_ie7.css [new file with mode: 0644]
sources/skins/moono/editor_ie8.css [new file with mode: 0644]
sources/skins/moono/editor_iequirks.css [new file with mode: 0644]
sources/skins/moono/elementspath.css [new file with mode: 0644]
sources/skins/moono/icons/about.png [new file with mode: 0644]
sources/skins/moono/icons/anchor-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/anchor.png [new file with mode: 0644]
sources/skins/moono/icons/bgcolor.png [new file with mode: 0644]
sources/skins/moono/icons/bidiltr.png [new file with mode: 0644]
sources/skins/moono/icons/bidirtl.png [new file with mode: 0644]
sources/skins/moono/icons/blockquote.png [new file with mode: 0644]
sources/skins/moono/icons/bold.png [new file with mode: 0644]
sources/skins/moono/icons/bulletedlist-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/bulletedlist.png [new file with mode: 0644]
sources/skins/moono/icons/button.png [new file with mode: 0644]
sources/skins/moono/icons/checkbox.png [new file with mode: 0644]
sources/skins/moono/icons/codesnippet.png [new file with mode: 0644]
sources/skins/moono/icons/copy-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/copy.png [new file with mode: 0644]
sources/skins/moono/icons/copyformatting.png [new file with mode: 0644]
sources/skins/moono/icons/creatediv.png [new file with mode: 0644]
sources/skins/moono/icons/cut-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/cut.png [new file with mode: 0644]
sources/skins/moono/icons/docprops-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/docprops.png [new file with mode: 0644]
sources/skins/moono/icons/find-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/find.png [new file with mode: 0644]
sources/skins/moono/icons/flash.png [new file with mode: 0644]
sources/skins/moono/icons/form.png [new file with mode: 0644]
sources/skins/moono/icons/hiddenfield.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/.DS_Store [new file with mode: 0644]
sources/skins/moono/icons/hidpi/about.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/anchor-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/anchor.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bgcolor.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bidiltr.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bidirtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/blockquote.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bold.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bulletedlist-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/bulletedlist.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/button.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/checkbox.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/codesnippet.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/copy-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/copy.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/copyformatting.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/creatediv.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/cut-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/cut.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/docprops-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/docprops.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/find-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/find.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/flash.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/form.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/hiddenfield.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/horizontalrule.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/iframe.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/image.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/imagebutton.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/indent-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/indent.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/italic.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/justifyblock.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/justifycenter.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/justifyleft.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/justifyright.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/language.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/link.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/maximize.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/newpage-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/newpage.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/numberedlist-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/numberedlist.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/outdent-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/outdent.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pagebreak-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pagebreak.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/paste-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/paste.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pastefromword-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pastefromword.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pastetext-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/pastetext.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/placeholder.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/preview-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/preview.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/print.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/radio.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/redo-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/redo.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/removeformat.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/replace.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/save.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/scayt.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/select-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/select.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/selectall.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/showblocks-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/showblocks.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/smiley.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/source-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/source.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/sourcedialog-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/sourcedialog.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/specialchar.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/spellchecker.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/strike.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/subscript.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/superscript.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/table.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/templates-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/templates.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/textarea-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/textarea.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/textcolor.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/textfield-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/textfield.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/uicolor.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/underline.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/undo-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/undo.png [new file with mode: 0644]
sources/skins/moono/icons/hidpi/unlink.png [new file with mode: 0644]
sources/skins/moono/icons/horizontalrule.png [new file with mode: 0644]
sources/skins/moono/icons/iframe.png [new file with mode: 0644]
sources/skins/moono/icons/image.png [new file with mode: 0644]
sources/skins/moono/icons/imagebutton.png [new file with mode: 0644]
sources/skins/moono/icons/indent-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/indent.png [new file with mode: 0644]
sources/skins/moono/icons/italic.png [new file with mode: 0644]
sources/skins/moono/icons/justifyblock.png [new file with mode: 0644]
sources/skins/moono/icons/justifycenter.png [new file with mode: 0644]
sources/skins/moono/icons/justifyleft.png [new file with mode: 0644]
sources/skins/moono/icons/justifyright.png [new file with mode: 0644]
sources/skins/moono/icons/language.png [new file with mode: 0644]
sources/skins/moono/icons/link.png [new file with mode: 0644]
sources/skins/moono/icons/maximize.png [new file with mode: 0644]
sources/skins/moono/icons/newpage-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/newpage.png [new file with mode: 0644]
sources/skins/moono/icons/numberedlist-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/numberedlist.png [new file with mode: 0644]
sources/skins/moono/icons/outdent-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/outdent.png [new file with mode: 0644]
sources/skins/moono/icons/pagebreak-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/pagebreak.png [new file with mode: 0644]
sources/skins/moono/icons/paste-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/paste.png [new file with mode: 0644]
sources/skins/moono/icons/pastefromword-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/pastefromword.png [new file with mode: 0644]
sources/skins/moono/icons/pastetext-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/pastetext.png [new file with mode: 0644]
sources/skins/moono/icons/placeholder.png [new file with mode: 0644]
sources/skins/moono/icons/preview-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/preview.png [new file with mode: 0644]
sources/skins/moono/icons/print.png [new file with mode: 0644]
sources/skins/moono/icons/radio.png [new file with mode: 0644]
sources/skins/moono/icons/redo-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/redo.png [new file with mode: 0644]
sources/skins/moono/icons/removeformat.png [new file with mode: 0644]
sources/skins/moono/icons/replace.png [new file with mode: 0644]
sources/skins/moono/icons/save.png [new file with mode: 0644]
sources/skins/moono/icons/scayt.png [new file with mode: 0644]
sources/skins/moono/icons/select-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/select.png [new file with mode: 0644]
sources/skins/moono/icons/selectall.png [new file with mode: 0644]
sources/skins/moono/icons/showblocks-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/showblocks.png [new file with mode: 0644]
sources/skins/moono/icons/smiley.png [new file with mode: 0644]
sources/skins/moono/icons/source-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/source.png [new file with mode: 0644]
sources/skins/moono/icons/sourcedialog-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/sourcedialog.png [new file with mode: 0644]
sources/skins/moono/icons/specialchar.png [new file with mode: 0644]
sources/skins/moono/icons/spellchecker.png [new file with mode: 0644]
sources/skins/moono/icons/strike.png [new file with mode: 0644]
sources/skins/moono/icons/subscript.png [new file with mode: 0644]
sources/skins/moono/icons/superscript.png [new file with mode: 0644]
sources/skins/moono/icons/table.png [new file with mode: 0644]
sources/skins/moono/icons/templates-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/templates.png [new file with mode: 0644]
sources/skins/moono/icons/textarea-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/textarea.png [new file with mode: 0644]
sources/skins/moono/icons/textcolor.png [new file with mode: 0644]
sources/skins/moono/icons/textfield-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/textfield.png [new file with mode: 0644]
sources/skins/moono/icons/uicolor.png [new file with mode: 0644]
sources/skins/moono/icons/underline.png [new file with mode: 0644]
sources/skins/moono/icons/undo-rtl.png [new file with mode: 0644]
sources/skins/moono/icons/undo.png [new file with mode: 0644]
sources/skins/moono/icons/unlink.png [new file with mode: 0644]
sources/skins/moono/images/anchor.png [new file with mode: 0644]
sources/skins/moono/images/arrow.png [new file with mode: 0644]
sources/skins/moono/images/close.png [new file with mode: 0644]
sources/skins/moono/images/hidpi/anchor.png [new file with mode: 0644]
sources/skins/moono/images/hidpi/close.png [new file with mode: 0644]
sources/skins/moono/images/hidpi/lock-open.png [new file with mode: 0644]
sources/skins/moono/images/hidpi/lock.png [new file with mode: 0644]
sources/skins/moono/images/hidpi/refresh.png [new file with mode: 0644]
sources/skins/moono/images/lock-open.png [new file with mode: 0644]
sources/skins/moono/images/lock.png [new file with mode: 0644]
sources/skins/moono/images/refresh.png [new file with mode: 0644]
sources/skins/moono/images/spinner.gif [new file with mode: 0644]
sources/skins/moono/mainui.css [new file with mode: 0644]
sources/skins/moono/menu.css [new file with mode: 0644]
sources/skins/moono/notification.css [new file with mode: 0644]
sources/skins/moono/panel.css [new file with mode: 0644]
sources/skins/moono/presets.css [new file with mode: 0644]
sources/skins/moono/readme.md [new file with mode: 0644]
sources/skins/moono/reset.css [new file with mode: 0644]
sources/skins/moono/richcombo.css [new file with mode: 0644]
sources/skins/moono/skin.js [new file with mode: 0644]
sources/skins/moono/toolbar.css [new file with mode: 0644]
sources/styles.js [new file with mode: 0644]

diff --git a/README.md b/README.md
new file mode 100644 (file)
index 0000000..5726a86
--- /dev/null
+++ b/README.md
@@ -0,0 +1,8 @@
+CKeditor Component
+==================
+
+Package Managers
+----------------
+
+* [Component](https://github.com/component/component): `immae/ckeditor`
+* [Composer](http://packagist.org/packages/components/jquery): `immae/ckeditor`
diff --git a/build-config.js b/build-config.js
new file mode 100644 (file)
index 0000000..ae18bab
--- /dev/null
@@ -0,0 +1,88 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * This file was added automatically by CKEditor builder.\r
+ * You may re-use it at any time to build CKEditor again.\r
+ *\r
+ * If you would like to build CKEditor online again\r
+ * (for example to upgrade), visit one the following links:\r
+ *\r
+ * (1) http://ckeditor.com/builder\r
+ *     Visit online builder to build CKEditor from scratch.\r
+ *\r
+ * (2) http://ckeditor.com/builder/1a00d11407d831ab5cdf8a93861cca45\r
+ *     Visit online builder to build CKEditor, starting with the same setup as before.\r
+ *\r
+ * (3) http://ckeditor.com/builder/download/1a00d11407d831ab5cdf8a93861cca45\r
+ *     Straight download link to the latest version of CKEditor (Optimized) with the same setup as before.\r
+ *\r
+ * NOTE:\r
+ *    This file is not used by CKEditor, you may remove it.\r
+ *    Changing this file will not change your CKEditor configuration.\r
+ */\r
+\r
+var CKBUILDER_CONFIG = {\r
+       skin: 'moono',\r
+       preset: 'full',\r
+       ignore: [\r
+               '.bender',\r
+               'bender.js',\r
+               'bender-err.log',\r
+               'bender-out.log',\r
+               'dev',\r
+               '.DS_Store',\r
+               '.editorconfig',\r
+               '.gitattributes',\r
+               '.gitignore',\r
+               'gruntfile.js',\r
+               '.idea',\r
+               '.jscsrc',\r
+               '.jshintignore',\r
+               '.jshintrc',\r
+               'less',\r
+               '.mailmap',\r
+               'node_modules',\r
+               'package.json',\r
+               'README.md',\r
+               'tests'\r
+       ],\r
+       plugins : {
+               'a11yhelp' : 1,
+               'basicstyles' : 1,
+               'contextmenu' : 1,
+               'dialogadvtab' : 1,
+               'elementspath' : 1,
+               'enterkey' : 1,
+               'entities' : 1,
+               'filebrowser' : 1,
+               'floatingspace' : 1,
+               'format' : 1,
+               'horizontalrule' : 1,
+               'htmlwriter' : 1,
+               'iframe' : 1,
+               'image' : 1,
+               'indentblock' : 1,
+               'indentlist' : 1,
+               'justify' : 1,
+               'link' : 1,
+               'list' : 1,
+               'liststyle' : 1,
+               'magicline' : 1,
+               'maximize' : 1,
+               'oembed' : 1,
+               'removeformat' : 1,
+               'resize' : 1,
+               'showborders' : 1,
+               'sourcearea' : 1,
+               'tab' : 1,
+               'toolbar' : 1,
+               'wysiwygarea' : 1
+       },
+       languages : {
+               'en' : 1,
+               'fr' : 1
+       }
+};
\ No newline at end of file
diff --git a/component.json b/component.json
new file mode 100644 (file)
index 0000000..f948599
--- /dev/null
@@ -0,0 +1,24 @@
+{
+  "name": "ckeditor",
+  "repo": "immae/ludivine-ckeditor-component",
+  "version": "4.6.2",
+  "description": "JavaScript WYSIWYG web text editor.",
+  "keywords": [
+    "ckeditor",
+    "fckeditor",
+    "editor",
+    "wysiwyg",
+    "html",
+    "richtext",
+    "text",
+    "javascript"
+  ],
+  "main": "release/ckeditor.js",
+  "scripts": [
+    "release/ckeditor.js"
+  ],
+  "dependencies": {
+    "component/jquery": "*"
+  },
+  "license": [ "GPL-2.0+", "LGPL-2.1+", "MPL-1.1+" ]
+}
diff --git a/composer.json b/composer.json
new file mode 100644 (file)
index 0000000..add204d
--- /dev/null
@@ -0,0 +1,35 @@
+{
+  "name": "immae/ludivine-ckeditor-component",
+  "description": "CKEditor component.",
+  "type": "component",
+  "keywords": [ "ckeditor", "fckeditor", "editor", "wysiwyg", "html", "richtext", "text", "javascript" ],
+  "homepage": "http://ckeditor.com",
+  "license": [ "GPL-2.0+", "LGPL-2.1+", "MPL-1.1+" ],
+  "authors": [
+    {
+      "name":  "CKSource",
+      "homepage": "http://cksource.com"
+    }
+  ],
+  "require": {
+    "robloach/component-installer": "*",
+    "components/jquery": ">=1.11"
+  },
+  "support": {
+    "issues": "http://dev.ckeditor.com",
+    "forum": "http://ckeditor.com/forums",
+    "wiki": "http://docs.ckeditor.com",
+    "source": "http://github.com/ckeditor/ckeditor-dev"
+  },
+  "extra": {
+    "component": {
+      "scripts": [
+        "release/ckeditor.js"
+      ],
+      "files": [
+        "release/**",
+        "sources/**"
+      ]
+    }
+  }
+}
diff --git a/release/CHANGES.md b/release/CHANGES.md
new file mode 100644 (file)
index 0000000..ff58654
--- /dev/null
@@ -0,0 +1,1219 @@
+CKEditor 4 Changelog\r
+====================\r
+\r
+## CKEditor 4.6.2\r
+\r
+New Features:\r
+\r
+* [#16733](http://dev.ckeditor.com/ticket/16733): Added a new pastel color palette for the [Color Button](http://ckeditor.com/addon/colorbutton) plugin and a new [`config.colorButton_colorsPerRow`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_colorsPerRow) configuration option for setting the number of rows in the color selector.\r
+* [#16752](http://dev.ckeditor.com/ticket/16752): Added a new Azerbaijani localization. Thanks to the [Azerbaijani language team](https://www.transifex.com/ckeditor/teams/11143/az/)!\r
+* [#13818](http://dev.ckeditor.com/ticket/13818): It is now possible to group [Widget](http://ckeditor.com/addon/widget) [style definitions](http://docs.ckeditor.com/#!/guide/dev_styles-section-widget-styles), so applying one style disables the other.\r
+\r
+Fixed Issues:\r
+\r
+* [#13446](http://dev.ckeditor.com/ticket/13446): [Chrome] Fixed: It is possible to type in an unfocused inline editor.\r
+* [#14856](http://dev.ckeditor.com/ticket/14856): Fixed: [Font size and font family](http://ckeditor.com/addon/font) reset each other when modified at certain positions.\r
+* [#16745](http://dev.ckeditor.com/ticket/16745): [Edge] Fixed: List items are lost when [pasted from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#16682](http://dev.ckeditor.com/ticket/16682): [Edge] Fixed: A list gets [pasted from Word](http://ckeditor.com/addon/pastefromword) as a set of paragraphs. Added the [`config.pasteFromWord_heuristicsEdgeList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWord_heuristicsEdgeList) configuration option.\r
+* [#10373](http://dev.ckeditor.com/ticket/10373): Fixed: Context menu items can be dragged into the editor.\r
+* [#16728](http://dev.ckeditor.com/ticket/16728): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Quirks Mode.\r
+* [#16795](http://dev.ckeditor.com/ticket/16795): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Compatibility Mode.\r
+* [#16675](http://dev.ckeditor.com/ticket/16675): Fixed: Styles applied with [Copy Formatting](http://ckeditor.com/addon/copyformatting) to a single table cell are applied to the whole table.\r
+* [#16753](http://dev.ckeditor.com/ticket/16753): Fixed: [`element.setSize`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-setSize) sets incorrect editor dimensions if the border width is represented as a fraction of pixels.\r
+* [#16705](http://dev.ckeditor.com/ticket/16705): [Firefox] Fixed: Unable to paste images as Base64 strings when using [Clipboard](http://ckeditor.com/addon/clipboard).\r
+* [#14869](http://dev.ckeditor.com/ticket/14869): Fixed: JavaScript error is thrown when trying to use [Find](http://ckeditor.com/addon/find) in a [`<div>`-based editor](http://ckeditor.com/addon/divarea).\r
+\r
+## CKEditor 4.6.1\r
+\r
+New Features:\r
+\r
+* [#16639](http://dev.ckeditor.com/ticket/16639): The `callback` parameter in the [CKEDITOR.ajax.post](http://docs.ckeditor.com/#!/api/CKEDITOR.ajax-method-post) method became optional.\r
+\r
+Fixed Issues:\r
+\r
+* [#11064](http://dev.ckeditor.com/ticket/11064): [Blink, WebKit] Fixed: Cannot select all editor content when a widget or a non-editable element is the first or last element of the content. Also fixes this issue in the [Select All](http://ckeditor.com/addon/selectall) plugin.\r
+* [#14755](http://dev.ckeditor.com/ticket/14755): [Blink, WebKit, IE8] Fixed: Browser hangs when a table is inserted in the place of a selected list with an empty last item.\r
+* [#16624](http://dev.ckeditor.com/ticket/16624): Fixed: Improved the [Color Button](http://ckeditor.com/addon/colorbutton) plugin which will now normalize the CSS `background` property if it only contains a color value. This fixes missing background colors when using [Paste from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#16600](http://dev.ckeditor.com/ticket/16600): [Blink, WebKit] Fixed: Error thrown occasionally by an uninitialized editable for multiple CKEditor instances on the same page.\r
+\r
+## CKEditor 4.6\r
+\r
+New Features:\r
+\r
+* [#14569](http://dev.ckeditor.com/ticket/14569): Added a new, flat, default CKEditor skin called [Moono-Lisa](http://ckeditor.com/addon/moono-lisa). Refreshed default colors available in the [Color Button](http://ckeditor.com/addon/colorbutton) plugin ([Text Color and Background Color](http://docs.ckeditor.com/#!/guide/dev_colorbutton) feature).\r
+* [#14707](http://dev.ckeditor.com/ticket/14707): Added a new [Copy Formatting](http://ckeditor.com/addon/copyformatting) feature to enable easy copying of styles between your document parts.\r
+* Introduced the completely rewritten [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin:\r
+       * Backward incompatibility: The [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) option now defaults to `false`. This option will be deprecated in the future. Use [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) to replicate the effect of setting it to `true`.\r
+       * Backward incompatibility: The [`config.pasteFromWordNumberedHeadingToList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordNumberedHeadingToList) and [`config.pasteFromWordRemoveStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveStyles) options were dropped and no longer have any effect on pasted content.\r
+       * Major improvements in preservation of list numbering, styling and indentation (nested lists with multiple levels).\r
+       * Major improvements in document structure parsing that fix plenty of issues with distorted or missing content after paste.\r
+* Added new translation: Occitan. Thanks to [Cédric Valmary](https://totenoc.eu/)!\r
+* [#10015](http://dev.ckeditor.com/ticket/10015): Keyboard shortcuts (relevant to the operating system in use) will now be displayed in tooltips and context menus.\r
+* [#13794](http://dev.ckeditor.com/ticket/13794): The [Upload Image](http://ckeditor.com/addon/uploadimage) feature now uses `uploaded.width/height` if set.\r
+* [#12541](http://dev.ckeditor.com/ticket/12541): Added the [Upload File](http://ckeditor.com/addon/uploadfile) plugin that lets you upload a file by drag&amp;dropping it into the editor content.\r
+* [#14449](http://dev.ckeditor.com/ticket/14449): Introduced the [Balloon Panel](http://ckeditor.com/addon/balloonpanel) plugin that lets you create stylish floating UI elements for the editor.\r
+* [#12077](https://dev.ckeditor.com/ticket/12077): Added support for the HTML5 `download` attribute in link (`<a>`) elements. Selecting the "Force Download" checkbox in the [Link](http://ckeditor.com/addon/link) dialog will cause the linked file to be downloaded automatically. Thanks to [sbusse](https://github.com/sbusse)!\r
+* [#13518](http://dev.ckeditor.com/ticket/13518): Introduced the [`additionalRequestParameters`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition-property-additionalRequestParameters) property for file uploads to make it possible to send additional information about the uploaded file to the server.\r
+* [#14889](http://dev.ckeditor.com/ticket/14889): Added the [`config.image2_altRequired`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_altRequired) option for the [Enhanced Image](http://ckeditor.com/addon/image2) plugin to allow making alternative text a mandatory field. Thanks to [Andrey Fedoseev](https://github.com/andreyfedoseev)!\r
+\r
+Fixed Issues:\r
+\r
+* [#9991](http://dev.ckeditor.com/ticket/9991): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) should only normalize input data.\r
+* [#7209](http://dev.ckeditor.com/ticket/7209): Fixed: Lists with 3 levels not [pasted from Word](http://ckeditor.com/addon/pastefromword) correctly.\r
+* [#14335](http://dev.ckeditor.com/ticket/14335): Fixed: Pasting a numbered list starting with a value different from "1" from Microsoft Word does not work correctly.\r
+* [#14542](http://dev.ckeditor.com/ticket/14542): Fixed: Copying a numbered list from Microsoft Word does not preserve list formatting.\r
+* [#14544](http://dev.ckeditor.com/ticket/14544): Fixed: Copying a nested list from Microsoft Word results in an empty list.\r
+* [#14660](http://dev.ckeditor.com/ticket/14660): Fixed: [Pasting text from  Word](http://ckeditor.com/addon/pastefromword) breaks the styling in some cases.\r
+* [#14867](http://dev.ckeditor.com/ticket/14867): [Firefox] Fixed: Text gets stripped when [pasting content from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#2507](http://dev.ckeditor.com/ticket/2507): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) does not detect pasting a part of a paragraph.\r
+* [#3336](http://dev.ckeditor.com/ticket/3336): Fixed: Extra blank row added on top of the content [pasted from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#6115](http://dev.ckeditor.com/ticket/6115): Fixed: When Right-to-Left text direction is applied to a table [pasted from Word](http://ckeditor.com/addon/pastefromword), borders are missing on one side.\r
+* [#6342](http://dev.ckeditor.com/ticket/6342): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filters out a basic text style when it is [configured to use attributes](http://docs.ckeditor.com/#!/guide/dev_basicstyles-section-custom-basic-text-style-definition).\r
+* [#6457](http://dev.ckeditor.com/ticket/6457): [IE] Fixed: [Pasting from Word](http://ckeditor.com/addon/pastefromword) is extremely slow.\r
+* [#6789](http://dev.ckeditor.com/ticket/6789): Fixed: The `mso-list: ignore` style is not handled properly when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#7262](http://dev.ckeditor.com/ticket/7262): Fixed: Lists in preformatted body disappear when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#7662](http://dev.ckeditor.com/ticket/7662): [Opera] Fixed: Extra empty number/bullet shown in the editor body when editing a multi-level list [pasted from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#7807](http://dev.ckeditor.com/ticket/7807): Fixed: Last item in a list not converted to a `<li>` element after [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#7950](http://dev.ckeditor.com/ticket/7950): [IE] Fixed: Content [from Word pasted](http://ckeditor.com/addon/pastefromword) differently than in other browsers.\r
+* [#7982](http://dev.ckeditor.com/ticket/7982): Fixed: Multi-level lists get split into smaller ones when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#8231](http://dev.ckeditor.com/ticket/8231): [WebKit, Opera] Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts empty paragraphs.\r
+* [#8266](http://dev.ckeditor.com/ticket/8266): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts a blank line at the top.\r
+* [#8341](http://dev.ckeditor.com/ticket/8341), [#7646](http://dev.ckeditor.com/ticket/7646): Fixed: Faulty removal of empty `<span>` elements in [Paste from Word](http://ckeditor.com/addon/pastefromword) content cleanup breaking content formatting.\r
+* [#8754](http://dev.ckeditor.com/ticket/8754): [Firefox] Fixed: Incorrect pasting of multiple nested lists in [Paste from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#8983](http://dev.ckeditor.com/ticket/8983): Fixed: Alignment lost when [pasting from Word](http://ckeditor.com/addon/pastefromword) with [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) set to [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).\r
+* [#9331](http://dev.ckeditor.com/ticket/9331): [IE] Fixed: [Pasting text from Word](http://ckeditor.com/addon/pastefromword) creates a simple Caesar cipher.\r
+* [#9422](http://dev.ckeditor.com/ticket/9422): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) leaves an unwanted `color:windowtext` style.\r
+* [#10011](http://dev.ckeditor.com/ticket/10011): [IE9-10] Fixed: [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) is ignored under certain conditions.\r
+* [#10643](http://dev.ckeditor.com/ticket/10643): Fixed: Differences between using <kbd>Ctrl+V</kbd> and pasting from the [Paste from Word](http://ckeditor.com/addon/pastefromword) dialog.\r
+* [#10784](http://dev.ckeditor.com/ticket/10784): Fixed: Lines missing when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#11294](http://dev.ckeditor.com/ticket/11294): [IE10] Fixed: Font size is not preserved when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#11627](http://dev.ckeditor.com/ticket/11627): Fixed: Missing words when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#12784](http://dev.ckeditor.com/ticket/12784): Fixed: Bulleted list with custom bullets gets changed to a numbered list when [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#13174](http://dev.ckeditor.com/ticket/13174): Fixed: Data loss after [pasting from Word](http://ckeditor.com/addon/pastefromword).\r
+* [#13828](http://dev.ckeditor.com/ticket/13828): Fixed: Widget classes should be added to the wrapper rather than the widget element.\r
+* [#13829](http://dev.ckeditor.com/ticket/13829): Fixed: No class in [Widget](http://ckeditor.com/addon/widget) wrapper to identify the widget type.\r
+* [#13519](http://dev.ckeditor.com/ticket/13519): Server response received when uploading files should be more flexible.\r
+\r
+Other Changes:\r
+\r
+* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type) and [WebSpellChecker](http://ckeditor.com/addon/wsc) plugins:\r
+       * Support for the new default Moono-Lisa skin.\r
+       * [#121](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/121): Fixed: [Basic Styles](http://ckeditor.com/addon/basicstyles) do not work when SCAYT is enabled.\r
+       * [#125](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/125): Fixed: Inline styles are not continued when writing multiple lines of styled text with SCAYT enabled.\r
+       * [#127](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/127): Fixed: Uncaught TypeError after enabling SCAYT in the CKEditor `<div>` element.\r
+       * [#128](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/128): Fixed: Error thrown after enabling SCAYT caused by conflicts with RequireJS.\r
+\r
+## CKEditor 4.5.11\r
+\r
+**Security Updates:**\r
+\r
+* [Severity: minor] Fixed the `target="_blank"` vulnerability reported by James Gaskell.\r
+\r
+       Issue summary: If a victim had access to a spoofed version of ckeditor.com via HTTP (e.g. due to DNS spoofing, using a hacked public network or mailicious hotspot), then when using a link to the ckeditor.com website it was possible for the attacker to change the current URL of the opening page, even if the opening page was protected with SSL.\r
+\r
+  An upgrade is recommended.\r
+\r
+New Features:\r
+\r
+* [#14747](http://dev.ckeditor.com/ticket/14747): The [Enhanced Image](http://ckeditor.com/addon/image2) caption now supports the link `target` attribute.\r
+* [#7154](http://dev.ckeditor.com/ticket/7154): Added support for the "Display Text" field to the [Link](http://ckeditor.com/addon/link) dialog. Thanks to [Ryan Guill](https://github.com/ryanguill)!\r
+\r
+Fixed Issues:\r
+\r
+* [#13362](http://dev.ckeditor.com/ticket/13362): [Blink, WebKit] Fixed: Active widget element is not cached when it is losing focus and it is inside an editable element.\r
+* [#13755](http://dev.ckeditor.com/ticket/13755): [Edge] Fixed: Pasting images does not work.\r
+* [#13548](http://dev.ckeditor.com/ticket/13548): [IE] Fixed: Clicking the [elements path](http://ckeditor.com/addon/elementspath) disables Cut and Copy icons.\r
+* [#13812](http://dev.ckeditor.com/ticket/13812): Fixed: When aborting file upload the placeholder for image is left.\r
+* [#14659](http://dev.ckeditor.com/ticket/14659): [Blink] Fixed: Content scrolled to the top after closing the dialog in a [`<div>`-based editor](http://ckeditor.com/addon/divarea).\r
+* [#14825](http://dev.ckeditor.com/ticket/14825): [Edge] Fixed: Focusing the editor causes unwanted scrolling due to dropped support for the `setActive` method.\r
+\r
+## CKEditor 4.5.10\r
+\r
+Fixed Issues:\r
+\r
+* [#10750](http://dev.ckeditor.com/ticket/10750): Fixed: The editor does not escape the `font-style` family property correctly, removing quotes and whitespace from font names.\r
+* [#14413](http://dev.ckeditor.com/ticket/14413): Fixed: The [Auto Grow](http://ckeditor.com/addon/autogrow) plugin with the [`config.autoGrow_onStartup`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoGrow_onStartup) option set to `true` does not work properly for an editor that is not visible.\r
+* [#14451](http://dev.ckeditor.com/ticket/14451): Fixed: Numeric element ID not escaped properly. Thanks to [Jakub Chalupa](https://github.com/chaluja7)!\r
+* [#14590](http://dev.ckeditor.com/ticket/14590): Fixed: Additional line break appearing after inline elements when switching modes. Thanks to [dpidcock](https://github.com/dpidcock)!\r
+* [#14539](https://dev.ckeditor.com/ticket/14539): Fixed: JAWS reads "selected Blank" instead of "selected <widget name>" when selecting a widget.\r
+* [#14701](http://dev.ckeditor.com/ticket/14701): Fixed: More precise labels for [Enhanced Image](http://ckeditor.com/addon/image2) and [Placeholder](http://ckeditor.com/addon/placeholder) widgets.\r
+* [#14667](http://dev.ckeditor.com/ticket/14667): [IE] Fixed: Removing background color from selected text removes background color from the whole paragraph.\r
+* [#14252](http://dev.ckeditor.com/ticket/14252): [IE] Fixed: Styles drop-down list does not always reflect the current style of the text line.\r
+* [#14275](http://dev.ckeditor.com/ticket/14275): [IE9+] Fixed: `onerror` and `onload` events are not used in browsers it could have been used when loading scripts dynamically.\r
+\r
+## CKEditor 4.5.9\r
+\r
+Fixed Issues:\r
+\r
+* [#10685](http://dev.ckeditor.com/ticket/10685): Fixed: Unreadable toolbar icons after updating to the new editor version. Fixed with [6876179](https://github.com/ckeditor/ckeditor-dev/commit/6876179db4ee97e786b07b8fd72e6b4120732185) in [ckeditor-dev](https://github.com/ckeditor/ckeditor-dev) and [6c9189f4](https://github.com/ckeditor/ckeditor-presets/commit/6c9189f46392d2c126854fe8889b820b8c76d291) in [ckeditor-presets](https://github.com/ckeditor/ckeditor-presets).\r
+* [#14573](https://dev.ckeditor.com/ticket/14573): Fixed: Missing [Widget](http://ckeditor.com/addon/widget) drag handler CSS when there are multiple editor instances.\r
+* [#14620](https://dev.ckeditor.com/ticket/14620): Fixed: Setting both the `min-height` style for the `<body>` element and the `height` style for the `<html>` element breaks the [Auto Grow](http://ckeditor.com/addon/autogrow) plugin.\r
+* [#14538](http://dev.ckeditor.com/ticket/14538): Fixed: Keyboard focus goes into an embedded `<iframe>` element.\r
+* [#14602](http://dev.ckeditor.com/ticket/14602): Fixed: The [`dom.element.removeAttribute()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeAttribute) method does not remove all attributes if no parameter is given.\r
+* [#8679](http://dev.ckeditor.com/ticket/8679): Fixed: Better focus indication and ability to style the selected color in the [color picker dialog](http://ckeditor.com/addon/colordialog).\r
+* [#11697](http://dev.ckeditor.com/ticket/11697): Fixed: Content is replaced ignoring the letter case setting in the [Find and Replace](http://ckeditor.com/addon/find) dialog window.\r
+* [#13886](http://dev.ckeditor.com/ticket/13886): Fixed: Invalid handling of the [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) instance with the `styles` property by [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).\r
+* [#14535](http://dev.ckeditor.com/ticket/14535): Fixed: CSS syntax corrections. Thanks to [mdjdenormandie](https://github.com/mdjdenormandie)!\r
+\r
+## CKEditor 4.5.8\r
+\r
+New Features:\r
+\r
+* [#12440](http://dev.ckeditor.com/ticket/12440): Added the [`config.colorButton_enableAutomatic`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_enableAutomatic) option to allow hiding the "Automatic" option in the [color picker](http://ckeditor.com/addon/colorbutton).\r
+\r
+Fixed Issues:\r
+\r
+* [#10448](http://dev.ckeditor.com/ticket/10448): Fixed: Lack of scrollbar in the [right-to-left text direction](http://ckeditor.com/addon/bidi).\r
+* [#12707](http://dev.ckeditor.com/ticket/12707): Fixed: The order of table elements does not comply with the HTML specification.\r
+* [#13756](http://dev.ckeditor.com/ticket/13756): [Edge] Fixed: Context menus are cut-off.\r
+\r
+## CKEditor 4.5.7\r
+\r
+New Features:\r
+\r
+* [#14327](http://dev.ckeditor.com/ticket/14327): Added Swiss German localization. Thanks to [Miro Grenda](https://twitter.com/mirogrenda)!\r
+\r
+Fixed Issues:\r
+\r
+* [#13816](http://dev.ckeditor.com/ticket/13816): Introduced a new strategy for Filling Character handling to avoid changes in DOM. This fixes the following issues:\r
+       * [#12727](http://dev.ckeditor.com/ticket/12727): [Blink] `IndexSizeError` when using the [Div Editing Area](http://ckeditor.com/addon/divarea) and [Content Templates](http://ckeditor.com/addon/templates) plugins.\r
+       * [#13377](http://dev.ckeditor.com/ticket/13377): [Widget](http://ckeditor.com/addon/widget) plugin issue when typing in Korean.\r
+       * [#13389](http://dev.ckeditor.com/ticket/13389): [Blink] [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) fails when the cursor is next to an `<hr>` tag.\r
+       * [#13513](http://dev.ckeditor.com/ticket/13513): [Blink, WebKit] [Div Editing Area](http://ckeditor.com/addon/divarea) and [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) throw an error when an image is the only data in the editor.\r
+* [#13884](http://dev.ckeditor.com/ticket/13884): [Firefox] Fixed: Copying and pasting a table results in just the first cell being pasted.\r
+* [#14234](http://dev.ckeditor.com/ticket/14234): Fixed: URL input field is not marked as required in the [Media Embed](http://ckeditor.com/addon/embed) dialog.\r
+\r
+## CKEditor 4.5.6\r
+\r
+New Features:\r
+\r
+* Introduced the [`CKEDITOR.tools.getCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCookie) and [`CKEDITOR.tools.setCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-setCookie) methods for accessing cookies.\r
+* Introduced the [`CKEDITOR.tools.getCsrfToken()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCsrfToken) method. The CSRF token is now automatically sent by the [File Browser](http://ckeditor.com/addon/filebrowser) and [File Tools](http://ckeditor.com/addon/filetools) plugins during file uploads. The server-side upload handlers may check it and use it to additionally secure the communication.\r
+\r
+Other Changes:\r
+\r
+* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type):\r
+       - New features:\r
+               - CKEditor [Language](http://ckeditor.com/addon/language) plugin support.\r
+               - CKEditor [Placeholder](http://ckeditor.com/addon/placeholder) plugin support.\r
+               - [Drag&Drop](http://sdk.ckeditor.com/samples/fileupload.html) support.\r
+               - **Experimental** [GRAYT](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-grayt_autoStartup) (Grammar As You Type) functionality.\r
+       - Fixed issues:\r
+               * [#98](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/98): SCAYT affects dialog double-click. Fixed in SCAYT core.\r
+               * [#102](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/102): SCAYT core performance enhancements.\r
+               * [#104](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/104): SCAYT's spans leak into the clipboard and after pasting.\r
+               * [#105](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/105): A JavaScript error fired in case of multiple instances of CKEditor on one page.\r
+               * [#107](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/107): SCAYT should not check non-editable parts of content.\r
+               * [#108](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/108): Latest SCAYT copies the ID of the editor element to the iframe.\r
+               * SCAYT stops working when CKEditor [Undo plugin](http://ckeditor.com/addon/undo) not enabled.\r
+               * Issue with pasting SCAYT markup in CKEditor.\r
+               * SCAYT stops working after pressing the *Cancel* button in the WSC dialog.\r
+\r
+## CKEditor 4.5.5\r
+\r
+Fixed Issues:\r
+\r
+* [#13887](https://dev.ckeditor.com/ticket/13887): Fixed: [Link](http://ckeditor.com/addon/link) plugin alters the `target` attribute value. Thanks to [SamZiemer](https://github.com/SamZiemer)!\r
+* [#12189](http://dev.ckeditor.com/ticket/12189): Fixed: The [Link](http://ckeditor.com/addon/link) plugin dialog does not display the subject of email links if the subject parameter is not lowercase.\r
+* [#9192](http://dev.ckeditor.com/ticket/9192): Fixed: An `undefined` string is appended to an email address added with the [Link](http://ckeditor.com/addon/link) plugin if subject and email body are empty and [`config.emailProtection`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-emailProtection) is set to `encode`.\r
+* [#13790](https://dev.ckeditor.com/ticket/13790): Fixed: It is not possible to destroy the editor `<iframe>` after the editor was detached from DOM. Thanks to [Stefan Rijnhart](https://github.com/StefanRijnhart)!\r
+* [#13803](https://dev.ckeditor.com/ticket/13803): Fixed: The editor cannot be destroyed before being fully initialized. Thanks to [Cyril Fluck](https://github.com/cyril-sf)!\r
+* [#13867](http://dev.ckeditor.com/ticket/13867): Fixed: CKEditor does not work when the `classList` polyfill is used.\r
+* [#13885](http://dev.ckeditor.com/ticket/13885): Fixed: [Enhanced Image](http://ckeditor.com/addon/image2) requires the [Link](http://ckeditor.com/addon/link) plugin to link an image.\r
+* [#13883](http://dev.ckeditor.com/ticket/13883): Fixed: Copying a table using the context menu strips off styles.\r
+* [#13872](http://dev.ckeditor.com/ticket/13872): Fixed: Cutting is possible in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode.\r
+* [#12848](http://dev.ckeditor.com/ticket/12848): [Blink] Fixed: Opening the [Find and Replace](http://ckeditor.com/addon/find) dialog window in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode throws an exception.\r
+* [#13879](http://dev.ckeditor.com/ticket/13879): Fixed: It is not possible to prevent the [`editor.drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop) event.\r
+* [#13361](http://dev.ckeditor.com/ticket/13361): Fixed: Skin images fail when the site path includes parentheses because the `background-image` path needs single quotes around the URL value.\r
+* [#13771](http://dev.ckeditor.com/ticket/13771): Fixed: The `contents.css` style is not used if the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin is missing.\r
+* [#13782](http://dev.ckeditor.com/ticket/13782): Fixed: Unclear log messages.\r
+* [#13919](http://dev.ckeditor.com/ticket/13919): [Edge] Fixed: Browser window crashes when accessing the `isContentEditable` property of an `<input>` DOM element.\r
+\r
+Other Changes:\r
+\r
+* [#13859](http://dev.ckeditor.com/ticket/13859): Test cases created with `bender.tools.createTestsForEditors` will also receive editor bot as a second parameter.\r
+\r
+## CKEditor 4.5.4\r
+\r
+New Features:\r
+\r
+* [#13632](http://dev.ckeditor.com/ticket/13632): Introduce error logging mechanism.\r
+* [#13730](http://dev.ckeditor.com/ticket/13730): Switch to the new error logging mechanism.\r
+\r
+Fixed Issues:\r
+\r
+* [#9856](http://dev.ckeditor.com/ticket/9856): Fixed: Cannot use the native context menu together with the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Mark Wade](https://github.com/mark-wade)!\r
+* [#12733](http://dev.ckeditor.com/ticket/12733): [IE9+] Fixed: Radio button `onChange` does not work. Thanks to [Iliya Kostadinov](https://github.com/iliyakostadinov)!\r
+* [#13142](http://dev.ckeditor.com/ticket/13142): [Edge] Fixed: *Ctrl+A* and then *Backspace* result in an empty `<div>` element.\r
+* [#13599](http://dev.ckeditor.com/ticket/13599): Fixed: Cross-editor drag and drop of an inline widget results in error/artifacts.\r
+* [#13640](http://dev.ckeditor.com/ticket/13640): [IE] Fixed: Dropping a widget outside the `<body>` element is not handled correctly.\r
+* [#13533](http://dev.ckeditor.com/ticket/13533): Fixed: No progress during upload.\r
+* [#13680](http://dev.ckeditor.com/ticket/13680): Fixed: The parser should allow the `<h1-6>` element to be a child of the `<summary>` element.\r
+* [#11724](http://dev.ckeditor.com/ticket/11724): [Touch devices] Fixed: Drop-downs often hide right after opening them.\r
+* [#13690](http://dev.ckeditor.com/ticket/13690): Fixed: Copying content from IE to Chrome adds an extra paragraph.\r
+* [#13284](http://dev.ckeditor.com/ticket/13284): Fixed: Cannot drag and drop a widget if the text caret is placed just after the widget instance.\r
+* [#13516](http://dev.ckeditor.com/ticket/13516): Fixed: CKEditor removes empty HTML5 anchors without the `name` attribute.\r
+* [#13765](http://dev.ckeditor.com/ticket/13765): [Safari 9] Fixed: Problems with rendering samples.\r
+\r
+Other Changes:\r
+\r
+* [#11725](http://dev.ckeditor.com/ticket/11725): Marked [`CKEDITOR.env.mobile`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-mobile) as deprecated. The reason is that it is no longer clear what "mobile" means.\r
+* [#13737](http://dev.ckeditor.com/ticket/13737): Upgraded [Bender.js](https://github.com/benderjs/benderjs) to 0.4.1.\r
+\r
+## CKEditor 4.5.3\r
+\r
+New Features:\r
+\r
+* [#13501](http://dev.ckeditor.com/ticket/13501): Added the [`config.fileTools_defaultFileName`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fileTools_defaultFileName) option to allow setting a default file name for paste uploads.\r
+* [#13603](http://dev.ckeditor.com/ticket/13603): Added support for uploading dropped BMP images.\r
+\r
+Fixed Issues:\r
+\r
+* [#13590](http://dev.ckeditor.com/ticket/13590): Fixed: Various issues related to the [Paste from Word](http://ckeditor.com/addon/pastefromword) feature. Fixes also:\r
+  * [#11215](http://dev.ckeditor.com/ticket/11215),\r
+  * [#8780](http://dev.ckeditor.com/ticket/8780),\r
+  * [#12762](http://dev.ckeditor.com/ticket/12762).\r
+* [#13386](http://dev.ckeditor.com/ticket/13386): [Edge] Fixed: Issues with selecting and editing images.\r
+* [#13568](http://dev.ckeditor.com/ticket/13568): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method returns invalid results for entire content selection.\r
+* [#13453](http://dev.ckeditor.com/ticket/13453): Fixed: Drag&drop of entire editor content throws an error.\r
+* [#13465](http://dev.ckeditor.com/ticket/13465): Fixed: Error is thrown and the widget is lost on drag&drop if it is the only content of the editor.\r
+* [#13414](http://dev.ckeditor.com/ticket/13414): Fixed: Content auto paragraphing in a nested editable despite editor configuration.\r
+* [#13429](http://dev.ckeditor.com/ticket/13429): Fixed: Incorrect selection after content insertion by the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.\r
+* [#13388](http://dev.ckeditor.com/ticket/13388): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) integration with [Undo](http://ckeditor.com/addon/undo) is broken.\r
+\r
+Other Changes:\r
+\r
+* [#13637](https://dev.ckeditor.com/ticket/13637): Several icons were refactored.\r
+* Updated [Bender.js](https://github.com/benderjs/benderjs) to 0.3.0 and introduced the ability to run tests via HTTPs ([#13265](https://dev.ckeditor.com/ticket/13265)).\r
+\r
+## CKEditor 4.5.2\r
+\r
+Fixed Issues:\r
+\r
+* [#13609](http://dev.ckeditor.com/ticket/13609): [Edge] Fixed: The browser crashes when switching to the source mode. Thanks to [Andrew Williams and Mark Smeed](http://webxsolution.com/)!\r
+* [PR#201](https://github.com/ckeditor/ckeditor-dev/pull/201): Fixed: Buttons in the toolbar configurator cause form submission. Thanks to [colemanw](https://github.com/colemanw)!\r
+* [#13422](http://dev.ckeditor.com/ticket/13422): Fixed: A monospaced font should be used in the `<textarea>` element storing editor configuration in the toolbar configurator.\r
+* [#13494](http://dev.ckeditor.com/ticket/13494): Fixed: Error thrown in the toolbar configurator if plugin requirements are not met.\r
+* [#13409](http://dev.ckeditor.com/ticket/13409): Fixed: List elements incorrectly merged when pressing *Backspace* or *Delete*.\r
+* [#13434](http://dev.ckeditor.com/ticket/13434): Fixed: Dialog state indicator broken in Right–To–Left environments.\r
+* [#13460](http://dev.ckeditor.com/ticket/13460): [IE8] Fixed: Copying inline widgets is broken when [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) is disabled.\r
+* [#13495](http://dev.ckeditor.com/ticket/13495): [Firefox, IE] Fixed: Text is not word-wrapped in the Paste dialog window.\r
+* [#13528](http://dev.ckeditor.com/ticket/13528): [Firefox@Windows] Fixed: Content copied from Microsoft Word and other external applications is pasted as a plain text. Removed the `CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer` property as the check must be dynamic.\r
+* [#13583](http://dev.ckeditor.com/ticket/13583): Fixed: [`DataTransfer.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer-method-getData) should work consistently in all browsers and should not strip valuable content. Fixed pasting tables from Microsoft Excel on Chrome.\r
+* [#13468](http://dev.ckeditor.com/ticket/13468): [IE] Fixed: Binding drag&drop `dataTransfer` does not work if `text` data was set in the meantime.\r
+* [#13451](http://dev.ckeditor.com/ticket/13451): [IE8-9] Fixed: One drag&drop operation may affect following ones.\r
+* [#13184](http://dev.ckeditor.com/ticket/13184): Fixed: Web page reloaded after a drop on editor UI.\r
+* [#13129](http://dev.ckeditor.com/ticket/13129) Fixed: Block widget blurred after a drop followed by an undo.\r
+* [#13397](http://dev.ckeditor.com/ticket/13397): Fixed: Drag&drop of a widget inside its nested widget crashes the editor.\r
+* [#13385](http://dev.ckeditor.com/ticket/13385): Fixed: [`editor.getSnapshot()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSnapshot) may return a non-string value.\r
+* [#13419](http://dev.ckeditor.com/ticket/13419): Fixed: The [Auto Link](http://ckeditor.com/addon/autolink) plugin does not encode double quotes in URLs.\r
+* [#13420](http://dev.ckeditor.com/ticket/13420): Fixed: The [Auto Embed](http://ckeditor.com/addon/autoembed) plugin ignores encoded characters in URL parameters.\r
+* [#13410](http://dev.ckeditor.com/ticket/13410): Fixed: Error thrown in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin when undoing right after pasting a link.\r
+* [#13566](http://dev.ckeditor.com/ticket/13566): Fixed: Suppressed notifications in the [Media Embed Base](http://ckeditor.com/addon/embedbase) plugin.\r
+* [#11616](http://dev.ckeditor.com/ticket/11616): [Chrome] Fixed: Resizing the editor while it is not displayed breaks the editable. Fixes also [#9160](http://dev.ckeditor.com/ticket/9160) and [#9715](http://dev.ckeditor.com/ticket/9715).\r
+* [#11376](http://dev.ckeditor.com/ticket/11376): [IE11] Fixed: Loss of text when pasting bulleted lists from Microsoft Word.\r
+* [#13143](http://dev.ckeditor.com/ticket/13143): [Edge] Fixed: Focus lost when opening the panel.\r
+* [#13387](http://dev.ckeditor.com/ticket/13387): [Edge] Fixed: "Permission denied" error thrown when loading the editor with developer tools open.\r
+* [#13574](http://dev.ckeditor.com/ticket/13574): [Edge] Fixed: "Permission denied" error thrown when opening editor dialog windows.\r
+* [#13441](http://dev.ckeditor.com/ticket/13441): [Edge] Fixed: The [Clipboard](http://ckeditor.com/addon/clipboard) plugin breaks the state of [Undo](http://ckeditor.com/addon/undo) commands after a paste.\r
+* [#13554](http://dev.ckeditor.com/ticket/13554): [Edge] Fixed: Paste dialog's iframe does not receive focus on show.\r
+* [#13440](http://dev.ckeditor.com/ticket/13440): [Edge] Fixed: Unable to paste a widget.\r
+\r
+Other Changes:\r
+\r
+* [#13421](http://dev.ckeditor.com/ticket/13421): UX improvements to notifications in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.\r
+\r
+## CKEditor 4.5.1\r
+\r
+Fixed Issues:\r
+\r
+* [#13486](http://dev.ckeditor.com/ticket/13486): Fixed: The [Upload Image](http://ckeditor.com/addon/uploadimage) plugin should log an error, not throw an error when upload URL is not set.\r
+\r
+## CKEditor 4.5\r
+\r
+New Features:\r
+\r
+* [#13304](http://dev.ckeditor.com/ticket/13304): Added support for passing DOM elements to [`config.sharedSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-sharedSpaces). Thanks to [Undergrounder](https://github.com/Undergrounder)!\r
+* [#13215](http://dev.ckeditor.com/ticket/13215): Added ability to cancel fetching a resource by the Embed plugins.\r
+* [#13213](http://dev.ckeditor.com/ticket/13213): Added the [`dialog#setState()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-method-setState) method and used it in the [Embed](http://ckeditor.com/addon/embed) dialog to indicate that a resource is being loaded.\r
+* [#13337](http://dev.ckeditor.com/ticket/13337): Added the [`repository.onWidget()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-onWidget) method &mdash; a convenient way to listen to [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) events through the [repository](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository).\r
+* [#13214](http://dev.ckeditor.com/ticket/13214): Added support for pasting links that convert into embeddable resources on the fly.\r
+\r
+Fixed Issues:\r
+\r
+* [#13334](http://dev.ckeditor.com/ticket/13334): Fixed: Error after nesting widgets and playing with undo/redo.\r
+* [#13118](http://dev.ckeditor.com/ticket/13118): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method throws an error when called in the source mode.\r
+* [#13158](http://dev.ckeditor.com/ticket/13158): Fixed: Error after canceling a dialog when creating a widget.\r
+* [#13197](http://dev.ckeditor.com/ticket/13197): Fixed: Linked inline [Enhanced Image](http://ckeditor.com/addon/image2) alignment class is not transferred to the widget wrapper.\r
+* [#13199](http://dev.ckeditor.com/ticket/13199): Fixed: [Semantic Embed](http://ckeditor.com/addon/embedsemantic) does not support widget classes.\r
+* [#13003](http://dev.ckeditor.com/ticket/13003): Fixed: Anchors are uploaded when moving them by drag and drop.\r
+* [#13032](http://dev.ckeditor.com/ticket/13032): Fixed: When upload is done, notification update should be marked as important.\r
+* [#13300](http://dev.ckeditor.com/ticket/13300): Fixed: The `internalCommit` argument in the [Image](http://ckeditor.com/addon/image) dialog seems to be never used.\r
+* [#13036](http://dev.ckeditor.com/ticket/13036): Fixed: Notifications are moved 10px to the right.\r
+* [#13280](http://dev.ckeditor.com/ticket/13280): [IE8] Fixed: Undo after inline widget drag&drop throws an error.\r
+* [#13186](http://dev.ckeditor.com/ticket/13186): Fixed: Content dropped into a nested editable is not filtered by [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf).\r
+* [#13140](http://dev.ckeditor.com/ticket/13140): Fixed: Error thrown when dropping a block widget right after itself.\r
+* [#13176](http://dev.ckeditor.com/ticket/13176): [IE8] Fixed: Errors on drag&drop of embed widgets.\r
+* [#13015](http://dev.ckeditor.com/ticket/13015): Fixed: Dropping an image file on [Enhanced Image](http://ckeditor.com/addon/image2) causes a page reload.\r
+* [#13080](http://dev.ckeditor.com/ticket/13080): Fixed: Ugly notification shown when the response contains HTML content.\r
+* [#13011](http://dev.ckeditor.com/ticket/13011): [IE8] Fixed: Anchors are duplicated on drag&drop in specific locations.\r
+* [#13105](http://dev.ckeditor.com/ticket/13105): Fixed: Various issues related to [`CKEDITOR.tools.htmlEncode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlEncode) and [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode) methods.\r
+* [#11976](http://dev.ckeditor.com/ticket/11976): [Chrome] Fixed: Copy&paste and drag&drop lists from Microsoft Word.\r
+* [#13128](http://dev.ckeditor.com/ticket/13128): Fixed: Various issues with cloning element IDs:\r
+  * Fixed the default behavior of [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) and [`range.extractContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-extractContents) methods which now clone IDs similarly to their native counterparts.\r
+  * Added `cloneId` arguments to the above methods, [`range.splitBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-splitBlock) and [`element.breakParent()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-breakParent). Mind the default values and special behavior in the `extractContents()` method!\r
+  * Fixed issues where IDs were lost on copy&paste and drag&drop.\r
+* Toolbar configurators:\r
+  * [#13185](http://dev.ckeditor.com/ticket/13185): Fixed: Wrong position of the suggestion box if there is not enough space below the caret.\r
+  * [#13138](http://dev.ckeditor.com/ticket/13138): Fixed: The "Toggle empty elements" button label is unclear.\r
+  * [#13136](http://dev.ckeditor.com/ticket/13136): Fixed: Autocompleter is far too intrusive.\r
+  * [#13133](http://dev.ckeditor.com/ticket/13133): Fixed: Tab leaves the editor.\r
+  * [#13173](http://dev.ckeditor.com/ticket/13173): Fixed: [`config.removeButtons`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons) is ignored by the advanced toolbar configurator.\r
+\r
+Other Changes:\r
+\r
+* [#13119](http://dev.ckeditor.com/ticket/13119): Improved compatibility of editor skins ([Moono](http://ckeditor.com/addon/moono) and [Kama](http://ckeditor.com/addon/kama)) with external web page style sheets.\r
+* Toolbar configurators:\r
+  * [#13147](http://dev.ckeditor.com/ticket/13147): Added buttons to the sticky toolbar.\r
+  * [#13207](http://dev.ckeditor.com/ticket/13207): Used modal window to display toolbar configurator help.\r
+* [#13316](http://dev.ckeditor.com/ticket/13316): Made [`CKEDITOR.env.isCompatible`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-isCompatible) a blacklist rather than a whitelist. More about the change in the [Browser Compatibility](http://docs.ckeditor.com/#!/guide/dev_browsers) guide.\r
+* [#13398](http://dev.ckeditor.com/ticket/13398): Renamed `CKEDITOR.fileTools.UploadsRepository` to [`CKEDITOR.fileTools.UploadRepository`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadRepository) and changed all related properties.\r
+* [#13279](http://dev.ckeditor.com/ticket/13279): Reviewed CSS vendor prefixes.\r
+* [#13454](http://dev.ckeditor.com/ticket/13454): Removed unused `lang.image.alertUrl` token from the [Image](http://ckeditor.com/addon/image) plugin.\r
+\r
+## CKEditor 4.5 Beta\r
+\r
+New Features:\r
+\r
+* Clipboard (copy&paste, drag&drop) and file uploading features and improvements ([#11437](http://dev.ckeditor.com/ticket/11437)).\r
+\r
+  * Major features:\r
+    * Support for dropping and pasting files into the editor was introduced. Through a set of new facades for native APIs it is now possible to easily intercept and process inserted files.\r
+    * [File upload tools](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools) were introduced in order to simplify controlling the loading, uploading and handling server response, properly handle [new upload configuration](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uploadUrl) options, etc.\r
+    * [Upload Image](http://ckeditor.com/addon/uploadimage) widget was introduced to upload dropped images. A base class for the [upload widget](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition) was exposed, too, to make it simple to create new types of upload widgets which can handle any type of dropped file, show the upload progress and update the content when the process is done. It also handles editing and undo/redo operations when a file is being uploaded and integrates with the [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) to show progress and success or error.\r
+    * All drag and drop operations were integrated with the editor. All dropped content is passed through the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event and a set of new editor events was introduced &mdash; [`dragstart`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragstart), [`drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop), [`dragend`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragend).\r
+    * The [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) facade was introduced to unify access to data in various types and files. [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) is now always available in the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.\r
+    * Switched from the pastebin to using the native clipboard access whenever possible. This solved many issues related to pastebin such as unnecessary scrolling or data loss. Additionally, on copy and cut from the editor the clipboard data is set. Therefore, on paste the editor has access to clean data, undisturbed by the browsers.\r
+    * Drag and drop of inline and block widgets was integrated with the standard clipboard APIs. By listening to drag events you will thus be notified about widgets, too. This opens a possibility to filter pasted and dropped widgets.\r
+    * The [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event can have the `range` parameter so it is possible to change the paste position in the listener or paste in the not selectable position. Also the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method now accepts `range` as an additional parameter.\r
+    * [#11621](http://dev.ckeditor.com/ticket/11621): A configurable [paste filter](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFilter) was introduced. The filter is by default turned to `'semantic-content'` on Webkit and Blink for all pasted content coming from external sources because of the low quality of HTML that these engines put into the clipboard. Internal and cross-editor paste is safe due to the change explained in the previous point.\r
+\r
+  * Other changes and related fixes:\r
+    * [#12095](http://dev.ckeditor.com/ticket/12095): On drag and copy of widgets [the same method](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) is used to get selected HTML as in the normal case. Thanks to that styles applied to inline widgets are not lost.\r
+    * [#11219](http://dev.ckeditor.com/ticket/11219): Fixed: Dragging a [captioned image](http://ckeditor.com/addon/image2) does not fire the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.\r
+    * [#9554](http://dev.ckeditor.com/ticket/9554): [Webkit Mac] Fixed: Editor scrolls on paste.\r
+    * [#9898](http://dev.ckeditor.com/ticket/9898): [Webkit&Divarea] Fixed: Pasting causes undesirable scrolling.\r
+    * [#11993](http://dev.ckeditor.com/ticket/11993): [Chrome] Fixed: Pasting content scrolls the document.\r
+    * [#12613](http://dev.ckeditor.com/ticket/12613): Show the user that they can not drop on editor UI (toolbar, bottom bar).\r
+    * [#12851](http://dev.ckeditor.com/ticket/12851): [Blink/Webkit] Fixed: Formatting disappears when pasting content into cells.\r
+    * [#12914](http://dev.ckeditor.com/ticket/12914): Fixed: Copy/Paste of table broken in `div`-based editor.\r
+\r
+  * Browser support.<br>Browser support for related features varies significantly (see http://caniuse.com/clipboard).\r
+    * File APIs needed to operate and file upload is not supported in Internet Explorer 9 and below.\r
+    * Only Chrome and Safari on Mac OS support setting custom data items in the clipboard, so currently it is possible to recognize the origin of the copied content in these browsers only. All drag and drop operations can be identified thanks to the new Data Transfer facade.\r
+    * No Internet Explorer browser supports the standard clipboard API which results in small glitches like where only plain text can be dropped from outside the editor. Thanks to the new Data Transfer facade, internal and cross-editor drag and drop supports the full range of data.\r
+    * Direct access to clipboard could only be implemented in Chrome, Safari on Mac OS, Opera and Firefox. In other browsers the pastebin must still be used.\r
+\r
+* [#12875](http://dev.ckeditor.com/ticket/12875): Samples and toolbar configuration tools.\r
+  * The old set of samples shipped with every CKEditor package was replaced with a shiny new single-page sample. This change concluded a long term plan which started from introducing the [CKEditor SDK](http://sdk.ckeditor.com/) and [CKEditor Functionality Overview](http://docs.ckeditor.com/#!/guide/dev_features) section in the documentation which essentially redefined the old samples.\r
+  * Toolbar configurators with live previews were introduced. They will be shipped with every CKEditor package and are meant to help in configuring toolbar layouts.\r
+\r
+* [#10925](http://dev.ckeditor.com/ticket/10925): The [Media Embed](http://ckeditor.com/addon/embed) and [Semantic Media Embed](http://ckeditor.com/addon/embedsemantic) plugins were introduced. Read more about the new features in the [Embedding Content](http://docs.ckeditor.com/#!/guide/dev_media_embed) article.\r
+* [#10931](http://dev.ckeditor.com/ticket/10931): Added support for nesting widgets. It is now possible to insert one widget into another widget's nested editable. Note that unless nested editable's [allowed content](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.nestedEditable.definition-property-allowedContent) is defined precisely, starting from CKEditor 4.5 some widget buttons may become enabled. This feature is not supported in IE8. Included issues:\r
+  * [#12018](http://dev.ckeditor.com/ticket/12018): Fixed and reviewed: Nested widgets garbage collection.\r
+  * [#12024](http://dev.ckeditor.com/ticket/12024): [Firefox] Fixed: Outline is extended to the left by unpositioned drag handlers.\r
+  * [#12006](http://dev.ckeditor.com/ticket/12006): Fixed: Drag and drop of nested block widgets.\r
+  * [#12008](http://dev.ckeditor.com/ticket/12008): Fixed various cases of inserting a single non-editable element using the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method. Fixes pasting a widget with a nested editable inside another widget's nested editable.\r
+\r
+* Notification system:\r
+  * [#11580](http://dev.ckeditor.com/ticket/11580): Introduced the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification).\r
+  * [#12810](http://dev.ckeditor.com/ticket/12810): Introduced a [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) for the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification) which simplifies displaying progress of many concurrent tasks.\r
+* [#11636](http://dev.ckeditor.com/ticket/11636): Introduced new, UX-focused, methods for getting selected HTML and deleting it &mdash; [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) and [`editor.deleteSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml).\r
+* [#12416](http://dev.ckeditor.com/ticket/12416): Added the [`widget.definition.upcastPriority`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-upcastPriority) property which gives more control over widget upcasting order to the widget author.\r
+* [#12036](http://dev.ckeditor.com/ticket/12036): Initialize the editor in [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode when the `<textarea>` element has a `readonly` attribute.\r
+* [#11905](http://dev.ckeditor.com/ticket/11905): The [`resize` event](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-resize) passes the current dimensions in its data.\r
+* [#12126](http://dev.ckeditor.com/ticket/12126): Introduced [`config.image_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image_prefillDimensions) and [`config.image2_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_prefillDimensions) to make pre-filling `width` and `height` configurable for the [Enhanced Image](http://ckeditor.com/addon/image2).\r
+* [#12746](http://dev.ckeditor.com/ticket/12746): Added a new configuration option to hide the [Enhanced Image](http://ckeditor.com/addon/image2) resizer.\r
+* [#12150](http://dev.ckeditor.com/ticket/12150): Exposed the [`getNestedEditable()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-static-method-getNestedEditable) and `is*` [widget helper](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) functions (see the static methods).\r
+* [#12448](http://dev.ckeditor.com/ticket/12448): Introduced the [`editable.insertHtmlIntoRange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertHtmlIntoRange) method.\r
+* [#12143](http://dev.ckeditor.com/ticket/12143): Added the [`config.floatSpacePreferRight`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-floatSpacePreferRight) configuration option that switches the alignment of the floating toolbar. Thanks to [InvisibleBacon](http://github.com/InvisibleBacon)!\r
+* [#10986](http://dev.ckeditor.com/ticket/10986): Added support for changing dialog input and textarea text directions by using the *Shift+Alt+Home/End* keystrokes. The direction is stored in the value of the input by prepending the [`\u202A`](http://unicode.org/cldr/utility/character.jsp?a=202A) or [`\u202B`](http://unicode.org/cldr/utility/character.jsp?a=202B) marker to it. Read more in the [documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition.textInput-property-bidi). Thanks to [edithkk](https://github.com/edithkk)!\r
+* [#12770](http://dev.ckeditor.com/ticket/12770): Added support for passing [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget)'s startup data as a widget command's argument. Thanks to [Rebrov Boris](https://github.com/zipp3r) and [Tieme van Veen](https://github.com/tiemevanveen)!\r
+* [#11583](http://dev.ckeditor.com/ticket/11583): Added support for the HTML5 `required` attribute in various form elements. Thanks to [Steven Busse](https://github.com/sbusse)!\r
+\r
+Changes:\r
+\r
+* [#12858](http://dev.ckeditor.com/ticket/12858): Basic [Spartan](http://blogs.windows.com/bloggingwindows/2015/03/30/introducing-project-spartan-the-new-browser-built-for-windows-10/) browser compatibility. Full compatibility will be introduced later, because at the moment Spartan is still too unstable to be used for tests and we see many changes from version to version.\r
+* [#12948](http://dev.ckeditor.com/ticket/12948): The [`config.mathJaxLibrary`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-mathJaxLib) option does not default to the MathJax CDN any more. It needs to be configured to enable the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin now.\r
+* [#13069](http://dev.ckeditor.com/ticket/13069): Fixed inconsistencies between [`editable.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) and [`editable.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) when the `range` parameter is used. Now, the `editor.insertElement()` method works on a higher level, which means that it saves undo snapshots and sets the selection after insertion. Use the [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange) method directly for the pre 4.5 behavior of `editable.insertElement()`.\r
+* [#12870](http://dev.ckeditor.com/ticket/12870): Use [`editor.showNotification()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-showNotification) instead of `alert()` directly whenever possible. When the [Notification plugin](http://ckeditor.com/addon/notification) is loaded, the notification system is used automatically. Otherwise, the native `alert()` is displayed.\r
+* [#8024](http://dev.ckeditor.com/ticket/8024): Swapped behavior of the Split Cell Vertically and Horizontally features of the [Table Tools](http://ckeditor.com/addon/tabletools) plugin to be more intuitive. Thanks to [kevinisagit](https://github.com/kevinisagit)!\r
+* [#10903](http://dev.ckeditor.com/ticket/10903): Performance improvements for the [`dom.element.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass), [`dom.element.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass) and [`dom.element.hasClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-hasClass) methods. Note: The previous implementation allowed passing multiple classes to `addClass()` although it was only a side effect of that implementation. The new implementation does not allow this.\r
+* [#11856](http://dev.ckeditor.com/ticket/11856): The jQuery adapter throws a meaningful error if CKEditor or jQuery are not loaded.\r
+\r
+Fixed issues:\r
+\r
+* [#11586](http://dev.ckeditor.com/ticket/11586): Fixed: [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) should not change the DOM in order not to affect selection.\r
+* [#12148](http://dev.ckeditor.com/ticket/12148): Fixed: [`dom.element.getChild()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-getChild) should not modify a passed array.\r
+* [#12503](http://dev.ckeditor.com/ticket/12503): [Blink/Webkit] Fixed: Incorrect result of Select All and *Backspace* or *Delete*.\r
+* [#13001](http://dev.ckeditor.com/ticket/13001): [Firefox] Fixed: The `<br />` filler is placed in the wrong position by the [`range.fixBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-fixBlock) method due to quirky Firefox behavior.\r
+* [#13101](http://dev.ckeditor.com/ticket/13101): [IE8] Fixed: Colons are prepended to HTML5 element names when cloning them.\r
+\r
+## CKEditor 4.4.8\r
+\r
+**Security Updates:**\r
+\r
+* Fixed XSS vulnerability in the HTML parser reported by [Dheeraj Joshi](https://twitter.com/dheerajhere) and [Prem Kumar](https://twitter.com/iAmPr3m).\r
+\r
+       Issue summary: It was possible to execute XSS inside CKEditor after persuading the victim to: (i) switch CKEditor to source mode, then (ii) paste a specially crafted HTML code, prepared by the attacker, into the opened CKEditor source area, and (iii) switch back to WYSIWYG mode.\r
+\r
+**An upgrade is highly recommended!**\r
+\r
+Fixed Issues:\r
+\r
+* [#12899](http://dev.ckeditor.com/ticket/12899): Fixed: Corrected wrong tag ending for horizontal box definition in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin. Thanks to [mizafish](https://github.com/mizafish)!\r
+* [#13254](http://dev.ckeditor.com/ticket/13254): Fixed: Cannot outdent block after indent when using the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Jonathan Cottrill](https://github.com/jcttrll)!\r
+* [#13268](http://dev.ckeditor.com/ticket/13268): Fixed: Documentation for [`CKEDITOR.dom.text`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.text) is incorrect. Thanks to [Ben Kiefer](https://github.com/benkiefer)!\r
+* [#12739](http://dev.ckeditor.com/ticket/12739): Fixed: Link loses inline styles when edited without the [Advanced Tab for Dialogs](http://ckeditor.com/addon/dialogadvtab) plugin. Thanks to [Віталій Крутько](https://github.com/asmforce)!\r
+* [#13292](http://dev.ckeditor.com/ticket/13292): Fixed: Protection pattern does not work in attribute in self-closing elements with no space before `/>`. Thanks to [Віталій Крутько](https://github.com/asmforce)!\r
+* [PR#192](https://github.com/ckeditor/ckeditor-dev/pull/192): Fixed: Variable name typo in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin which caused [`CKEDITOR.ui.dialog.radio`](http://docs.ckeditor.com/#!/api/CKEDITOR.ui.dialog.radio) validation to not work. Thanks to [Florian Ludwig](https://github.com/FlorianLudwig)!\r
+* [#13232](http://dev.ckeditor.com/ticket/13232): [Safari] Fixed: The [`element.appendText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-appendText) method does not work properly for empty elements.\r
+* [#13233](http://dev.ckeditor.com/ticket/13233): Fixed: [HTMLDataProcessor](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) can process `foo:href` attributes.\r
+* [#12796](http://dev.ckeditor.com/ticket/12796): Fixed: The [Indent List](http://ckeditor.com/addon/indentlist) plugin unwraps parent `<li>` elements. Thanks to [Andrew Stucki](https://github.com/andrewstucki)!\r
+* [#12885](http://dev.ckeditor.com/ticket/12885): Added missing [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) parameter documentation.\r
+* [#11982](http://dev.ckeditor.com/ticket/11982): Fixed: Bullet added in a wrong position after the *Enter* key is pressed in a nested list.\r
+* [#13027](http://dev.ckeditor.com/ticket/13027): Fixed: Keyboard navigation in dialog windows with multiple tabs not following IBM CI 162 instructions or [ARIA Authoring Practices](http://www.w3.org/TR/2013/WD-wai-aria-practices-20130307/#tabpanel).\r
+* [#12256](http://dev.ckeditor.com/ticket/12256): Fixed: Basic styles classes are lost when pasting from Microsoft Word if [basic styles](http://ckeditor.com/addon/basicstyles) were configured to use classes.\r
+* [#12729](http://dev.ckeditor.com/ticket/12729): Fixed: Incorrect structure created when merging a block into a list item on *Backspace* and *Delete*.\r
+* [#13031](http://dev.ckeditor.com/ticket/13031): [Firefox] Fixed: No more line breaks in source view since Firefox 36.\r
+* [#13131](http://dev.ckeditor.com/ticket/13131): Fixed: The [Code Snippet](http://ckeditor.com/addon/codesnippet) plugin cannot be used without the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin.\r
+* [#9086](http://dev.ckeditor.com/ticket/9086): Fixed: Invalid ARIA property used on paste area `<iframe>`.\r
+* [#13164](http://dev.ckeditor.com/ticket/13164): Fixed: Error when inserting a hidden field.\r
+* [#13155](http://dev.ckeditor.com/ticket/13155): Fixed: Incorrect [Line Utilities](http://ckeditor.com/addon/lineutils) positioning when `<body>` has a margin.\r
+* [#13351](http://dev.ckeditor.com/ticket/13351): Fixed: Link lost when editing a linked image with the Link tab disabled. This also fixed a bug when inserting an image into a fully selected link would throw an error ([#12847](https://dev.ckeditor.com/ticket/12847)).\r
+* [#13344](http://dev.ckeditor.com/ticket/13344): [WebKit/Blink] Fixed: It is possible to remove or change editor content in [read-only mode](http://docs.ckeditor.com/#!/guide/dev_readonly).\r
+\r
+Other Changes:\r
+\r
+* [#12844](http://dev.ckeditor.com/ticket/12844) and [#13103](http://dev.ckeditor.com/ticket/13103): Upgraded the [testing environment](http://docs.ckeditor.com/#!/guide/dev_tests) to [Bender.js](https://github.com/benderjs/benderjs) `0.2.3`.\r
+* [#12930](http://dev.ckeditor.com/ticket/12930): Because of licensing issues, `truncated-mathjax/` is now removed from the `tests/` directory. Now `bender.config.mathJaxLibPath` must be configured manually in order to run [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin tests.\r
+* [#13266](http://dev.ckeditor.com/ticket/13266): Added more shades of gray in the [Color Dialog](http://ckeditor.com/addon/colordialog) window. Thanks to [mizafish](https://github.com/mizafish)!\r
+\r
+\r
+## CKEditor 4.4.7\r
+\r
+Fixed Issues:\r
+\r
+* [#12825](http://dev.ckeditor.com/ticket/12825): Fixed: Preventing the [Table Resize](http://ckeditor.com/addon/tableresize) plugin from operating on elements outside the editor. Thanks to [Paul Martin](https://github.com/Paul-Martin)!\r
+* [#12157](http://dev.ckeditor.com/ticket/12157): Fixed: Lost text formatting on pressing *Tab* when the [`config.tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces) configuration option value was greater than zero.\r
+* [#12777](http://dev.ckeditor.com/ticket/12777): Fixed: The `table-layout` CSS property should be reset by skins. Thanks to [vita10gy](https://github.com/vita10gy)!\r
+* [#12812](http://dev.ckeditor.com/ticket/12812): Fixed: An uncaught security exception is thrown when [Line Utilities](http://ckeditor.com/addon/lineutils) are used in an inline editor loaded in a cross-domain `iframe`. Thanks to [Vitaliy Zurian](https://github.com/thecatontheflat)!\r
+* [#12735](http://dev.ckeditor.com/ticket/12735): Fixed: [`config.fillEmptyBlocks`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fillEmptyBlocks) should only apply when outputting data.\r
+* [#10032](http://dev.ckeditor.com/ticket/10032): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filter is executed for every paste after using the button.\r
+* [#12597](http://dev.ckeditor.com/ticket/12597): [Blink/WebKit] Fixed: Multi-byte Japanese characters entry not working properly after *Shift+Enter*.\r
+* [#12387](http://dev.ckeditor.com/ticket/12387): Fixed: An error is thrown if a skin does not have the [`chameleon`](http://docs.ckeditor.com/#!/api/CKEDITOR.skin-method-chameleon) property defined and [`config.uiColor`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uiColor) is defined.\r
+* [#12747](http://dev.ckeditor.com/ticket/12747): [IE8-10] Fixed: Opening a drop-down for a specific selection when the editor is maximized results in incorrect drop-down panel position.\r
+* [#12850](http://dev.ckeditor.com/ticket/12850): [IEQM] Fixed: An error is thrown after focusing the editor.\r
+\r
+## CKEditor 4.4.6\r
+\r
+**Security Updates:**\r
+\r
+* Fixed XSS vulnerability in the HTML parser reported by [Maco Cortes](https://www.facebook.com/Maaacoooo).\r
+\r
+       Issue summary: It was possible to execute XSS inside CKEditor after persuading the victim to: (i) switch CKEditor to source mode, then (ii) paste a specially crafted HTML code, prepared by the attacker, into the opened CKEditor source area, and (iii) switch back to WYSIWYG mode.\r
+\r
+**An upgrade is highly recommended!**\r
+\r
+New Features:\r
+\r
+* [#12501](http://dev.ckeditor.com/ticket/12501): Allowed dashes in element names in the [string format of allowed content rules](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules-section-string-format).\r
+* [#12550](http://dev.ckeditor.com/ticket/12550): Added the `<main>` element to the [`CKEDITOR.dtd`](http://docs.ckeditor.com/#!/api/CKEDITOR.dtd).\r
+\r
+Fixed Issues:\r
+\r
+* [#12506](http://dev.ckeditor.com/ticket/12506): [Safari] Fixed: Cannot paste into inline editor if the page has `user-select: none` style. Thanks to [shaohua](https://github.com/shaohua)!\r
+* [#12683](http://dev.ckeditor.com/ticket/12683): Fixed: [Filter](http://docs.ckeditor.com/#!/guide/dev_acf) fails to remove custom tags. Thanks to [timselier](https://github.com/timselier)!\r
+* [#12489](http://dev.ckeditor.com/ticket/12489) and [#12491](http://dev.ckeditor.com/ticket/12491): Fixed: Various issues related to restoring the selection after performing operations on filler character. See the [fixed cases](http://dev.ckeditor.com/ticket/12491#comment:4).\r
+* [#12621](http://dev.ckeditor.com/ticket/12621): Fixed: Cannot remove inline styles (bold, italic, etc.) in empty lines.\r
+* [#12630](http://dev.ckeditor.com/ticket/12630): [Chrome] Fixed: Selection is placed outside the paragraph when the [New Page](http://ckeditor.com/addon/newpage) button is clicked. This patch significantly simplified the way how the initial selection (a selection after the content of the editable is overwritten) is being fixed. That might have fixed many related scenarios in all browsers.\r
+* [#11647](http://dev.ckeditor.com/ticket/11647): Fixed: The [`editor.blur`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-blur) event is not fired on first blur after initializing the inline editor on an already focused element.\r
+* [#12601](http://dev.ckeditor.com/ticket/12601): Fixed: [Strikethrough](http://ckeditor.com/addon/basicstyles) button tooltip spelling.\r
+* [#12546](http://dev.ckeditor.com/ticket/12546): Fixed: The Preview tab in the [Document Properties](http://ckeditor.com/addon/docprops) dialog window is always disabled.\r
+* [#12300](http://dev.ckeditor.com/ticket/12300): Fixed: The [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event fired on first navigation key press after typing.\r
+* [#12141](http://dev.ckeditor.com/ticket/12141): Fixed: List items are lost when indenting a list item with content wrapped with a block element.\r
+* [#12515](http://dev.ckeditor.com/ticket/12515): Fixed: Cursor is in the wrong position when undoing after adding an image and typing some text.\r
+* [#12484](http://dev.ckeditor.com/ticket/12484): [Blink/WebKit] Fixed: DOM is changed outside the editor area in a certain case.\r
+* [#12688](http://dev.ckeditor.com/ticket/12688): Improved the tests of the [styles system](http://docs.ckeditor.com/#!/api/CKEDITOR.style) and fixed two minor issues.\r
+* [#12403](http://dev.ckeditor.com/ticket/12403): Fixed: Changing the [font](http://ckeditor.com/addon/font) style should not lead to nesting it in the previous style element.\r
+* [#12609](http://dev.ckeditor.com/ticket/12609): Fixed: Incorrect `config.magicline_putEverywhere` name used for a [Magic Line](http://ckeditor.com/addon/magicline) all-encompassing [`config.magicline_everywhere`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-magicline_everywhere) configuration option.\r
+\r
+\r
+## CKEditor 4.4.5\r
+\r
+New Features:\r
+\r
+* [#12279](http://dev.ckeditor.com/ticket/12279): Added a possibility to pass a custom evaluator to [`node.getAscendant()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.node-method-getAscendant).\r
+\r
+Fixed Issues:\r
+\r
+* [#12423](http://dev.ckeditor.com/ticket/12423): [Safari7.1+] Fixed: *Enter* key moved cursor to a strange position.\r
+* [#12381](http://dev.ckeditor.com/ticket/12381): [iOS] Fixed: Selection issue. Thanks to [Remiremi](https://github.com/Remiremi)!\r
+* [#10804](http://dev.ckeditor.com/ticket/10804): Fixed: `CKEDITOR_GETURL` is not used with some plugins where it should be used. Thanks to [Thomas Andraschko](https://github.com/tandraschko)!\r
+* [#9137](http://dev.ckeditor.com/ticket/9137): Fixed: The `<base>` tag is not created when `<head>` has an attribute. Thanks to [naoki.fujikawa](https://github.com/naoki-fujikawa)!\r
+* [#12377](http://dev.ckeditor.com/ticket/12377): Fixed: Errors thrown in the [Image](http://ckeditor.com/addon/image) plugin when removing preview from the dialog window definition. Thanks to [Axinet](https://github.com/Axinet)!\r
+* [#12162](http://dev.ckeditor.com/ticket/12162): Fixed: Auto paragraphing and *Enter* key in nested editables.\r
+* [#12315](http://dev.ckeditor.com/ticket/12315): Fixed: Marked [`config.autoParagraph`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoParagraph) as deprecated.\r
+* [#12113](http://dev.ckeditor.com/ticket/12113): Fixed: A [code snippet](http://ckeditor.com/addon/codesnippet) should be presented in the [elements path](http://ckeditor.com/addon/elementspath) as "code snippet" (translatable).\r
+* [#12311](http://dev.ckeditor.com/ticket/12311): Fixed: [Remove Format](http://ckeditor.com/addon/removeformat) should also remove `<cite>` elements.\r
+* [#12261](http://dev.ckeditor.com/ticket/12261): Fixed: Filter has to be destroyed and removed from [`CKEDITOR.filter.instances`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-static-property-instances) on editor destroy.\r
+* [#12398](http://dev.ckeditor.com/ticket/12398): Fixed: [Maximize](http://ckeditor.com/addon/maximize) does not work on an instance without a [title](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title).\r
+* [#12097](http://dev.ckeditor.com/ticket/12097): Fixed: JAWS not reading the number of options correctly in the [Text Color and Background Color](http://ckeditor.com/addon/colorbutton) button menu.\r
+* [#12411](http://dev.ckeditor.com/ticket/12411): Fixed: [Page Break](http://ckeditor.com/addon/pagebreak) used directly in the editable breaks the editor.\r
+* [#12354](http://dev.ckeditor.com/ticket/12354): Fixed: Various issues in undo manager when holding keys.\r
+* [#12324](http://dev.ckeditor.com/ticket/12324): [IE8] Fixed: Undo steps are not recorded when changing the caret position by clicking below the body.\r
+* [#12332](http://dev.ckeditor.com/ticket/12332): Fixed: Lowered DOM events listeners' priorities in undo manager in order to avoid ambiguity.\r
+* [#12402](http://dev.ckeditor.com/ticket/12402): [Blink] Fixed: Workaround for Blink bug with `document.title` which breaks updating title in the full HTML mode.\r
+* [#12338](http://dev.ckeditor.com/ticket/12338): Fixed: The CKEditor package contains unoptimized images.\r
+\r
+\r
+## CKEditor 4.4.4\r
+\r
+Fixed Issues:\r
+\r
+* [#12268](http://dev.ckeditor.com/ticket/12268): Cleanup of [UI Color](http://ckeditor.com/addon/uicolor) YUI styles. Thanks to [CasherWest](https://github.com/CasherWest)!\r
+* [#12263](http://dev.ckeditor.com/ticket/12263): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filter does not properly normalize semicolons style text. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!\r
+* [#12243](http://dev.ckeditor.com/ticket/12243): Fixed: Text formatting lost when pasting from Word. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!\r
+* [#111739](http://dev.ckeditor.com/ticket/11739): Fixed: `keypress` listeners should not be used in the undo manager. A complete rewrite of keyboard handling in the undo manager was made. Numerous smaller issues were fixed, among others:\r
+  * [#10926](http://dev.ckeditor.com/ticket/10926): [Chrome@Android] Fixed: Typing does not record snapshots and does not fire the [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.\r
+  * [#11611](http://dev.ckeditor.com/ticket/11611): [Firefox] Fixed: The [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event is fired when pressing Arrow keys.\r
+  * [#12219](http://dev.ckeditor.com/ticket/12219): [Safari] Fixed: Some modifications of the [`UndoManager.locked`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-property-locked) property violate strict mode in the [Undo](http://ckeditor.com/addon/undo) plugin.\r
+* [#10916](http://dev.ckeditor.com/ticket/10916): Fixed: [Magic Line](http://ckeditor.com/addon/magicline) icon in Right-To-Left environments.\r
+* [#11970](http://dev.ckeditor.com/ticket/11970): [IE] Fixed: CKEditor `paste` event is not fired when pasting with *Shift+Ins*.\r
+* [#12111](http://dev.ckeditor.com/ticket/12111): Fixed: Linked image attributes are not read when opening the image dialog window by doubleclicking.\r
+* [#10030](http://dev.ckeditor.com/ticket/10030): [IE] Fixed: Prevented "Unspecified Error" thrown in various cases when IE8-9 does not allow access to `document.activeElement`.\r
+* [#12273](http://dev.ckeditor.com/ticket/12273): Fixed: Applying block style in a description list breaks it.\r
+* [#12218](http://dev.ckeditor.com/ticket/12218): Fixed: Minor syntax issue in CSS files.\r
+* [#12178](http://dev.ckeditor.com/ticket/12178): [Blink/WebKit] Fixed: Iterator does not return the block if the selection is located at the end of it.\r
+* [#12185](http://dev.ckeditor.com/ticket/12185): [IE9QM] Fixed: Error thrown when moving the mouse over focused editor's scrollbar.\r
+* [#12215](http://dev.ckeditor.com/ticket/12215): Fixed: Basepath resolution does not recognize semicolon as a query separator.\r
+* [#12135](http://dev.ckeditor.com/ticket/12135): Fixed: [Remove Format](http://ckeditor.com/addon/removeformat) does not work on widgets.\r
+* [#12298](http://dev.ckeditor.com/ticket/12298): [IE11] Fixed: Clicking below `<body>` in Compatibility Mode will no longer reset selection to the first line.\r
+* [#12204](http://dev.ckeditor.com/ticket/12204): Fixed: Editor's voice label is not affected by [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title).\r
+* [#11915](http://dev.ckeditor.com/ticket/11915): Fixed: With [SCAYT](http://ckeditor.com/addon/scayt) enabled, cursor moves to the beginning of the first highlighted, misspelled word after typing or pasting into the editor.\r
+* [SCAYT](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/69): Fixed: Error thrown in the console after enabling [SCAYT](http://ckeditor.com/addon/scayt) and trying to add a new image.\r
+\r
+\r
+Other Changes:\r
+\r
+* [#12296](http://dev.ckeditor.com/ticket/12296): Merged `benderjs-ckeditor` into the main CKEditor repository.\r
+\r
+## CKEditor 4.4.3\r
+\r
+**Security Updates:**\r
+\r
+* Fixed XSS vulnerability in the Preview plugin reported by Mario Heiderich of [Cure53](https://cure53.de/).\r
+\r
+**An upgrade is highly recommended!**\r
+\r
+New Features:\r
+\r
+* [#12164](http://dev.ckeditor.com/ticket/12164): Added the "Justify" option to the "Horizontal Alignment" drop-down in the Table Cell Properties dialog window.\r
+\r
+Fixed Issues:\r
+\r
+* [#12110](http://dev.ckeditor.com/ticket/12110): Fixed: Editor crash after deleting a table. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!\r
+* [#11897](http://dev.ckeditor.com/ticket/11897): Fixed: *Enter* key used in an empty list item creates a new line instead of breaking the list. Thanks to [noam-si](https://github.com/noam-si)!\r
+* [#12140](http://dev.ckeditor.com/ticket/12140): Fixed: Double-clicking linked widgets opens two dialog windows.\r
+* [#12132](http://dev.ckeditor.com/ticket/12132): Fixed: Image is inserted with `width` and `height` styles even when they are not allowed.\r
+* [#9317](http://dev.ckeditor.com/ticket/9317): [IE] Fixed: [`config.disableObjectResizing`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-disableObjectResizing) does not work on IE. **Note**: We were not able to fix this issue on IE11+ because necessary events stopped working. See a [last resort workaround](http://dev.ckeditor.com/ticket/9317#comment:16) and make sure to [support our complaint to Microsoft](https://connect.microsoft.com/IE/feedback/details/742593/please-respect-execcommand-enableobjectresizing-in-contenteditable-elements).\r
+* [#9638](http://dev.ckeditor.com/ticket/9638): Fixed: There should be no information about accessibility help available under the *Alt+0* keyboard shortcut if the [Accessibility Help](http://ckeditor.com/addon/a11yhelp) plugin is not available.\r
+* [#8117](http://dev.ckeditor.com/ticket/8117) and [#9186](http://dev.ckeditor.com/ticket/9186): Fixed: In HTML5 `<meta>` tags should be allowed everywhere, including inside the `<body>` element.\r
+* [#10422](http://dev.ckeditor.com/ticket/10422): Fixed: [`config.fillEmptyBlocks`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fillEmptyBlocks) not working properly if a function is specified.\r
+\r
+## CKEditor 4.4.2\r
+\r
+Important Notes:\r
+\r
+* The CKEditor testing environment is now publicly available. Read more about how to set up the environment and execute tests in the [CKEditor Testing Environment](http://docs.ckeditor.com/#!/guide/dev_tests) guide.\r
+       Please note that the [`tests/`](https://github.com/ckeditor/ckeditor-dev/tree/master/tests) directory which contains editor tests is not available in release packages. It can only be found in the development version of CKEditor on [GitHub](https://github.com/ckeditor/ckeditor-dev/).\r
+\r
+New Features:\r
+\r
+* [#11909](http://dev.ckeditor.com/ticket/11909): Introduced a parameter to prevent the [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData) method from recording undo snapshots.\r
+\r
+Fixed Issues:\r
+\r
+* [#11757](http://dev.ckeditor.com/ticket/11757): Fixed: Imperfections in the [Moono](http://ckeditor.com/addon/moono) skin. Thanks to [danyaPostfactum](https://github.com/danyaPostfactum)!\r
+* [#10091](http://dev.ckeditor.com/ticket/10091): Blockquote should be treated like an object by the styles system. Thanks to [dan-james-deeson](https://github.com/dan-james-deeson)!\r
+* [#11478](http://dev.ckeditor.com/ticket/11478): Fixed: Issue with passing jQuery objects to [adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) configuration.\r
+* [#10867](http://dev.ckeditor.com/ticket/10867): Fixed: Issue with setting encoded URI as image link.\r
+* [#11983](http://dev.ckeditor.com/ticket/11983): Fixed: Clicking a nested widget does not focus it. Additionally, performance of the [`widget.repository.getByElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-getByElement) method was improved.\r
+* [#12000](http://dev.ckeditor.com/ticket/12000): Fixed: Nested widgets should be initialized on [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData) and [`nestedEditable.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.nestedEditable-method-setData).\r
+* [#12022](http://dev.ckeditor.com/ticket/12022): Fixed: Outer widget's drag handler is not created at all if it has any nested widgets inside.\r
+* [#11960](http://dev.ckeditor.com/ticket/11960): [Blink/WebKit] Fixed: The caret should be scrolled into view on *Backspace* and *Delete* (covers only the merging blocks case).\r
+* [#11306](http://dev.ckeditor.com/ticket/11306): [OSX][Blink/WebKit] Fixed: No widget entries in the context menu on widget right-click.\r
+* [#11957](http://dev.ckeditor.com/ticket/11957): Fixed: Alignment labels in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window are not translated.\r
+* [#11980](http://dev.ckeditor.com/ticket/11980): [Blink/WebKit] Fixed: `<span>` elements created when joining adjacent elements (non-collapsed selection).\r
+* [#12009](http://dev.ckeditor.com/ticket/12009): [Nested widgets] Integration with the [Magic Line](http://ckeditor.com/addon/magicline) plugin.\r
+* [#11387](http://dev.ckeditor.com/ticket/11387): Fixed: `role="radiogroup"` should be applied only to radio inputs' container.\r
+* [#7975](http://dev.ckeditor.com/ticket/7975): [IE8] Fixed: Errors when trying to select an empty table cell.\r
+* [#11947](http://dev.ckeditor.com/ticket/11947): [Firefox+IE11] Fixed: *Shift+Enter* in lists produces two line breaks.\r
+* [#11972](http://dev.ckeditor.com/ticket/11972): Fixed: Feature detection in the [`element.setText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-setText) method should not trigger the layout engine.\r
+* [#7634](http://dev.ckeditor.com/ticket/7634): Fixed: The [Flash Dialog](http://ckeditor.com/addon/flash) plugin omits the `allowFullScreen` parameter in the editor data if set to `true`.\r
+* [#11910](http://dev.ckeditor.com/ticket/11910): Fixed: [Enhanced Image](http://ckeditor.com/addon/image2) does not take [`config.baseHref`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-baseHref) into account when updating image dimensions.\r
+* [#11753](http://dev.ckeditor.com/ticket/11753): Fixed: Wrong [`checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method value after focusing or blurring a widget.\r
+* [#11830](http://dev.ckeditor.com/ticket/11830): Fixed: Impossible to pass some arguments to [CKBuilder](https://github.com/ckeditor/ckbuilder) when using the `/dev/builder/build.sh` script.\r
+* [#11945](http://dev.ckeditor.com/ticket/11945): Fixed: [Form Elements](http://ckeditor.com/addon/forms) plugin should not change a core method.\r
+* [#11384](http://dev.ckeditor.com/ticket/11384): [IE9+] Fixed: `IndexSizeError` thrown when pasting into a non-empty selection anchored in one text node.\r
+\r
+## CKEditor 4.4.1\r
+\r
+New Features:\r
+\r
+* [#9661](http://dev.ckeditor.com/ticket/9661): Added the option to [configure](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-linkJavaScriptLinksAllowed) anchor tags with JavaScript code in the `href` attribute.\r
+\r
+Fixed Issues:\r
+\r
+* [#11861](http://dev.ckeditor.com/ticket/11861): [WebKit/Blink] Fixed: Span elements created while joining adjacent elements. **Note:** This patch only covers cases when *Backspace* or *Delete* is pressed on a collapsed (empty) selection. The remaining case, with a non-empty selection, will be fixed in the next release.\r
+* [#10714](http://dev.ckeditor.com/ticket/10714): [iOS] Fixed: Selection and drop-downs are broken if a touch event listener is used due to a [WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=128924). Thanks to [Arty Gus](https://github.com/artygus)!\r
+* [#11911](http://dev.ckeditor.com/ticket/11911): Fixed setting the `dir` attribute for a preloaded language in [CKEDITOR.lang](http://docs.ckeditor.com/#!/api/CKEDITOR.lang). Thanks to [Akash Mohapatra](https://github.com/akashmohapatra)!\r
+* [#11926](http://dev.ckeditor.com/ticket/11926): Fixed: [Code Snippet](http://ckeditor.com/addon/codesnippet) does not decode HTML entities when loading code from the `<code>` element.\r
+* [#11223](http://dev.ckeditor.com/ticket/11223): Fixed: Issue when [Protected Source](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-protectedSource) was not working in the `<title>` element.\r
+* [#11859](http://dev.ckeditor.com/ticket/11859): Fixed: Removed the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin dependency from the [Code Snippet](http://ckeditor.com/addon/codesnippet) sample.\r
+* [#11754](http://dev.ckeditor.com/ticket/11754): [Chrome] Fixed: Infinite loop when content includes not closed attributes.\r
+* [#11848](http://dev.ckeditor.com/ticket/11848): [IE] Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) throwing an exception when there was no selection in the editor.\r
+* [#11801](http://dev.ckeditor.com/ticket/11801): Fixed: Editor anchors unavailable when linking the [Enhanced Image](http://ckeditor.com/addon/image2) widget.\r
+* [#11626](http://dev.ckeditor.com/ticket/11626): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) sets invalid column width.\r
+* [#11872](http://dev.ckeditor.com/ticket/11872): Made [`element.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass) chainable symmetrically to [`element.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass).\r
+* [#11813](http://dev.ckeditor.com/ticket/11813): Fixed: Link lost while pasting a captioned image and restoring an undo snapshot ([Enhanced Image](http://ckeditor.com/addon/image2)).\r
+* [#11814](http://dev.ckeditor.com/ticket/11814): Fixed: _Link_ and _Unlink_ entries persistently displayed in the [Enhanced Image](http://ckeditor.com/addon/image2) context menu.\r
+* [#11839](http://dev.ckeditor.com/ticket/11839): [IE9] Fixed: The caret jumps out of the editable area when resizing the editor in the source mode.\r
+* [#11822](http://dev.ckeditor.com/ticket/11822): [WebKit] Fixed: Editing anchors by double-click is broken in some cases.\r
+* [#11823](http://dev.ckeditor.com/ticket/11823): [IE8] Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) throws an error over scrollbar.\r
+* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: It is not possible to change the language back to _Not set_ in the [Code Snippet](http://ckeditor.com/addon/codesnippet) dialog window.\r
+* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: [Filter](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied inside elements with the `contenteditable` attribute set to `true`.\r
+* [#11798](http://dev.ckeditor.com/ticket/11798): Fixed: Inserting a non-editable element inside a table cell breaks the table.\r
+* [#11793](http://dev.ckeditor.com/ticket/11793): Fixed: Drop-down is not "on" when clicking it while the editor is blurred.\r
+* [#11850](http://dev.ckeditor.com/ticket/11850): Fixed: Fake objects with the `contenteditable` attribute set to `false` are not downcasted properly.\r
+* [#11811](http://dev.ckeditor.com/ticket/11811): Fixed: Widget's data is not encoded correctly when passed to an attribute.\r
+* [#11777](http://dev.ckeditor.com/ticket/11777): Fixed encoding ampersand in the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin.\r
+* [#11880](http://dev.ckeditor.com/ticket/11880): [IE8-9] Fixed: Linked image has a default thick border.\r
+\r
+Other Changes:\r
+\r
+* [#11807](http://dev.ckeditor.com/ticket/11807): Updated jQuery version used in the sample to 1.11.0 and tested CKEditor jQuery Adapter with version 1.11.0 and 2.1.0.\r
+* [#9504](http://dev.ckeditor.com/ticket/9504): Stopped using deprecated `attribute.specified` in all browsers except Internet Explorer.\r
+* [#11809](http://dev.ckeditor.com/ticket/11809): Changed tab size in `<pre>` to 4 spaces.\r
+\r
+## CKEditor 4.4\r
+\r
+**Important Notes:**\r
+\r
+* Marked the [`editor.beforePaste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-beforePaste) event as deprecated.\r
+* The default class of captioned images has changed to `image` (was: `caption`). Please note that once edited in CKEditor 4.4+, all existing images of the `caption` class (`<figure class="caption">`) will be [filtered out](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) unless the [`config.image2_captionedClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_captionedClass) option is set to `caption`. For backward compatibility (i.e. when upgrading), it is highly recommended to use this setting, which also helps prevent CSS conflicts, etc. This does not apply to new CKEditor integrations.\r
+* Widgets without defined buttons are no longer registered automatically to the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter). Before CKEditor 4.4 widgets were registered to the ACF which was an incorrect behavior ([#11567](http://dev.ckeditor.com/ticket/11567)). This change should not have any impact on standard scenarios, but if your button does not execute the widget command, you need to set [`allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.feature-property-allowedContent) and [`requiredContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.feature-property-requiredContent) properties for it manually, because the editor will not be able to find them.\r
+* The [Show Borders](http://ckeditor.com/addon/showborders) plugin was added to the Standard installation package in order to ensure that unstyled tables are still visible for the user ([#11665](http://dev.ckeditor.com/ticket/11665)).\r
+* Since CKEditor 4.4 the editor instance should be passed to [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) methods to ensure full compatibility with other features (e.g. applying styles to widgets requires that). We ensured backward compatibility though, so the [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) will work even when the editor instance is not provided.\r
+\r
+New Features:\r
+\r
+* [#11297](http://dev.ckeditor.com/ticket/11297): Styles can now be applied to widgets. The definition of a style which can be applied to a specific widget must contain two additional properties &mdash; `type` and `widget`. Read more in the [Widget Styles](http://docs.ckeditor.com/#!/guide/dev_styles-section-widget-styles) section of the "Syles Drop-down" guide. Note that by default, widgets support only classes and no other attributes or styles. Related changes and features:\r
+  * Introduced the [`CKEDITOR.style.addCustomHandler()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-static-method-addCustomHandler) method for registering custom style handlers.\r
+  * The [`CKEDITOR.style.apply()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-apply) and [`CKEDITOR.style.remove()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-remove) methods are now called with an editor instance instead of the document so they can be reused by the [`CKEDITOR.editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) and [`CKEDITOR.editor.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-removeStyle) methods. Backward compatibility was preserved, but from CKEditor 4.4 it is highly recommended to pass an editor instead of a document to these methods.\r
+  * Many new methods and properties were introduced in the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) to make the handling of styles by widgets fully customizable. See: [`widget.definition.styleableElements`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-styleableElements), [`widget.definition.styleToAllowedContentRule`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-styleToAllowedContentRules), [`widget.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-addClass), [`widget.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-removeClass), [`widget.getClasses()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-getClasses), [`widget.hasClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-hasClass), [`widget.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-applyStyle), [`widget.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-removeStyle), [`widget.checkStyleActive()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-checkStyleActive).\r
+  * Integration with the [Allowed Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) required an introduction of the [`CKEDITOR.style.toAllowedContent()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-toAllowedContentRules) method which can be implemented by the custom style handler and if exists, it is used by the [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter) to translate a style to [allowed content rules](http://docs.ckeditor.com/#!/api/CKEDITOR.filter.allowedContentRules).\r
+* [#11300](http://dev.ckeditor.com/ticket/11300): Various changes in the [Enhanced Image](http://ckeditor.com/addon/image2) plugin:\r
+  * Introduced the [`config.image2_captionedClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_captionedClass) option to configure the class of captioned images.\r
+  * Introduced the [`config.image2_alignClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_alignClasses) option to configure the way images are aligned with CSS classes.\r
+  If this setting is defined, the editor produces classes instead of inline styles for aligned images.\r
+  * Default image caption can be translated (customized) with the `editor.lang.image2.captionPlaceholder` string.\r
+* [#11341](http://dev.ckeditor.com/ticket/11341): [Enhanced Image](http://ckeditor.com/addon/image2) plugin: It is now possible to add a link to any image type.\r
+* [#10202](http://dev.ckeditor.com/ticket/10202): Introduced wildcard support in the [Allowed Content Rules](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) format.\r
+* [#10276](http://dev.ckeditor.com/ticket/10276): Introduced blacklisting in the [Allowed Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter).\r
+* [#10480](http://dev.ckeditor.com/ticket/10480): Introduced code snippets with code highlighting. There are two versions available so far &mdash; the default [Code Snippet](http://ckeditor.com/addon/codesnippet) which uses the [highlight.js](http://highlightjs.org) library and the [Code Snippet GeSHi](http://ckeditor.com/addon/codesnippetgeshi) which uses the [GeSHi](http://qbnz.com/highlighter/) library.\r
+* [#11737](http://dev.ckeditor.com/ticket/11737): Introduced an option to prevent [filtering](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) of an element that matches custom criteria (see [`filter.addElementCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-method-addElementCallback)).\r
+* [#11532](http://dev.ckeditor.com/ticket/11532): Introduced the [`editor.addContentsCss()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addContentsCss) method that can be used for [adding custom CSS files](http://docs.ckeditor.com/#!/guide/plugin_sdk_styles).\r
+* [#11536](http://dev.ckeditor.com/ticket/11536): Added the [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode) method for decoding HTML entities.\r
+* [#11225](http://dev.ckeditor.com/ticket/11225): Introduced the [`CKEDITOR.tools.transparentImageData`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-property-transparentImageData) property which contains transparent image data to be used in CSS or as image source.\r
+\r
+Other Changes:\r
+\r
+* [#11377](http://dev.ckeditor.com/ticket/11377): Unified internal representation of empty anchors using the [fake objects](http://ckeditor.com/addon/fakeobjects).\r
+* [#11422](http://dev.ckeditor.com/ticket/11422): Removed Firefox 3.x, Internet Explorer 6 and Opera 12.x leftovers in code.\r
+* [#5217](http://dev.ckeditor.com/ticket/5217): Setting data (including switching between modes) creates a new undo snapshot. Besides that:\r
+  * Introduced the [`editable.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-property-status) property.\r
+  * Introduced a new `forceUpdate` option for the [`editor.lockSnapshot`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-lockSnapshot) event.\r
+  * Fixed: Selection not being unlocked in inline editor after setting data ([#11500](http://dev.ckeditor.com/ticket/11500)).\r
+* The [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin was updated to the latest version.\r
+\r
+Fixed Issues:\r
+\r
+* [#10190](http://dev.ckeditor.com/ticket/10190): Fixed: Removing block style with [`editor.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-removeStyle) should result in a paragraph and not a div.\r
+* [#11727](http://dev.ckeditor.com/ticket/11727): Fixed: The editor tries to select a non-editable image which was clicked.\r
+\r
+## CKEditor 4.3.5\r
+\r
+New Features:\r
+\r
+* Added new translation: Tatar.\r
+\r
+Fixed Issues:\r
+\r
+* [#11677](http://dev.ckeditor.com/ticket/11677): Fixed: Undo/Redo keystrokes are blocked in the source mode.\r
+* [#11717](http://dev.ckeditor.com/ticket/11717): [Document Properties](http://ckeditor.com/addon/docprops) plugin requires the [Color Dialog](http://ckeditor.com/addon/colordialog) plugin to work.\r
+\r
+## CKEditor 4.3.4\r
+\r
+Fixed Issues:\r
+\r
+* [#11597](http://dev.ckeditor.com/ticket/11597): [IE11] Fixed: Error thrown when trying to open the [preview](http://ckeditor.com/addon/preview) using the keyboard.\r
+* [#11544](http://dev.ckeditor.com/ticket/11544): [Placeholders](http://ckeditor.com/addon/placeholder) will no longer be upcasted in parents not accepting `<span>` elements.\r
+* [#8663](http://dev.ckeditor.com/ticket/8663): Fixed [`element.renameNode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-renameNode) not clearing the [`element.getName()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-getName) cache.\r
+* [#11574](http://dev.ckeditor.com/ticket/11574): Fixed: *Backspace* destroying the DOM structure if an inline editable is placed in a list item.\r
+* [#11603](http://dev.ckeditor.com/ticket/11603): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) attaches to tables outside the editable.\r
+* [#9205](http://dev.ckeditor.com/ticket/9205), [#7805](http://dev.ckeditor.com/ticket/7805), [#8216](http://dev.ckeditor.com/ticket/8216): Fixed: `{cke_protected_1}` appearing in data in various cases where HTML comments are placed next to `"` or `'`.\r
+* [#11635](http://dev.ckeditor.com/ticket/11635): Fixed: Some attributes are not protected before the content is passed through the fix bin.\r
+* [#11660](http://dev.ckeditor.com/ticket/11660): [IE] Fixed: Table content is lost when some extra markup is inside the table.\r
+* [#11641](http://dev.ckeditor.com/ticket/11641): Fixed: Switching between modes in the classic editor removes content styles for the inline editor.\r
+* [#11568](http://dev.ckeditor.com/ticket/11568): Fixed: [Styles](http://ckeditor.com/addon/stylescombo) drop-down list is not enabled on selection change.\r
+\r
+## CKEditor 4.3.3\r
+\r
+Fixed Issues:\r
+\r
+* [#11500](http://dev.ckeditor.com/ticket/11500): [WebKit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root).\r
+* [#11104](http://dev.ckeditor.com/ticket/11104): [IE] Fixed: Various issues with scrolling and selection when focusing widgets.\r
+* [#11487](http://dev.ckeditor.com/ticket/11487): Moving mouse over the [Enhanced Image](http://ckeditor.com/addon/image2) widget will no longer change the value returned by the [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method.\r
+* [#8673](http://dev.ckeditor.com/ticket/8673): [WebKit] Fixed: Cannot select and remove the [Page Break](http://ckeditor.com/addon/pagebreak).\r
+* [#11413](http://dev.ckeditor.com/ticket/11413): Fixed: Incorrect [`editor.execCommand()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand) behavior.\r
+* [#11438](http://dev.ckeditor.com/ticket/11438): Splitting table cells vertically is no longer changing table structure.\r
+* [#8899](http://dev.ckeditor.com/ticket/8899): Fixed: Links in the [About CKEditor](http://ckeditor.com/addon/about) dialog window now open in a new browser window or tab.\r
+* [#11490](http://dev.ckeditor.com/ticket/11490): Fixed: [Menu button](http://ckeditor.com/addon/menubutton) panel not showing in the source mode.\r
+* [#11417](http://dev.ckeditor.com/ticket/11417): The [`widget.doubleclick`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-event-doubleclick) event is not canceled anymore after editing was triggered.\r
+* [#11253](http://dev.ckeditor.com/ticket/11253): [IE] Fixed: Clipped upload button in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.\r
+* [#11359](http://dev.ckeditor.com/ticket/11359): Standardized the way anchors are discovered by the [Link](http://ckeditor.com/addon/link) plugin.\r
+* [#11058](http://dev.ckeditor.com/ticket/11058): [IE8] Fixed: Error when deleting a table row.\r
+* [#11508](http://dev.ckeditor.com/ticket/11508): Fixed: [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) discovering protected attributes within other attributes' values.\r
+* [#11533](http://dev.ckeditor.com/ticket/11533): Widgets: Avoid recurring upcasts if the DOM structure was modified during an upcast.\r
+* [#11400](http://dev.ckeditor.com/ticket/11400): Fixed: The [`domObject.removeAllListeners()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.domObject-method-removeAllListeners) method does not remove custom listeners completely.\r
+* [#11493](http://dev.ckeditor.com/ticket/11493): Fixed: The [`selection.getRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getRanges) method does not override cached ranges when used with the `onlyEditables` argument.\r
+* [#11390](http://dev.ckeditor.com/ticket/11390): [IE] All [XML](http://ckeditor.com/addon/xml) plugin [methods](http://docs.ckeditor.com/#!/api/CKEDITOR.xml) now work in IE10+.\r
+* [#11542](http://dev.ckeditor.com/ticket/11542): [IE11] Fixed: Blurry toolbar icons when Right-to-Left UI language is set.\r
+* [#11504](http://dev.ckeditor.com/ticket/11504): Fixed: When [`config.fullPage`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fullPage) is set to `true`, entities are not encoded in editor output.\r
+* [#11004](http://dev.ckeditor.com/ticket/11004): Integrated [Enhanced Image](http://ckeditor.com/addon/image2) dialog window with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter).\r
+* [#11439](http://dev.ckeditor.com/ticket/11439): Fixed: Properties get cloned in the Cell Properties dialog window if multiple cells are selected.\r
+\r
+## CKEditor 4.3.2\r
+\r
+Fixed Issues:\r
+\r
+* [#11331](http://dev.ckeditor.com/ticket/11331): A menu button will have a changed label when selected instead of using the `aria-pressed` attribute.\r
+* [#11177](http://dev.ckeditor.com/ticket/11177): Widget drag handler improvements:\r
+  * [#11176](http://dev.ckeditor.com/ticket/11176): Fixed: Initial position is not updated when the widget data object is empty.\r
+  * [#11001](http://dev.ckeditor.com/ticket/11001): Fixed: Multiple synchronous layout recalculations are caused by initial drag handler positioning causing performance issues.\r
+  * [#11161](http://dev.ckeditor.com/ticket/11161): Fixed: Drag handler is not repositioned in various situations.\r
+  * [#11281](http://dev.ckeditor.com/ticket/11281): Fixed: Drag handler and mask are duplicated after widget reinitialization.\r
+* [#11207](http://dev.ckeditor.com/ticket/11207): [Firefox] Fixed: Misplaced [Enhanced Image](http://ckeditor.com/addon/image2) resizer in the inline editor.\r
+* [#11102](http://dev.ckeditor.com/ticket/11102): `CKEDITOR.template` improvements:\r
+  * [#11102](http://dev.ckeditor.com/ticket/11102): Added newline character support.\r
+  * [#11216](http://dev.ckeditor.com/ticket/11216): Added "\\'" substring support.\r
+* [#11121](http://dev.ckeditor.com/ticket/11121): [Firefox] Fixed: High Contrast mode is enabled when the editor is loaded in a hidden iframe.\r
+* [#11350](http://dev.ckeditor.com/ticket/11350): The default value of [`config.contentsCss`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-contentsCss) is affected by [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl).\r
+* [#11097](http://dev.ckeditor.com/ticket/11097): Improved the [Autogrow](http://ckeditor.com/addon/autogrow) plugin performance when dealing with very big tables.\r
+* [#11290](http://dev.ckeditor.com/ticket/11290): Removed redundant code in the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin.\r
+* [#11133](http://dev.ckeditor.com/ticket/11133): [Page Break](http://ckeditor.com/addon/pagebreak) becomes editable if pasted.\r
+* [#11126](http://dev.ckeditor.com/ticket/11126): Fixed: Native Undo executed once the bottom of the snapshot stack is reached.\r
+* [#11131](http://dev.ckeditor.com/ticket/11131): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Error thrown when switching to source mode if the selection was in widget's nested editable.\r
+* [#11139](http://dev.ckeditor.com/ticket/11139): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Elements Path is not cleared after switching to source mode.\r
+* [#10778](http://dev.ckeditor.com/ticket/10778): Fixed a bug with range enlargement. The range no longer expands to visible whitespace.\r
+* [#11146](http://dev.ckeditor.com/ticket/11146): [IE] Fixed: Preview window switches Internet Explorer to Quirks Mode.\r
+* [#10762](http://dev.ckeditor.com/ticket/10762): [IE] Fixed: JavaScript code displayed in preview window's URL bar.\r
+* [#11186](http://dev.ckeditor.com/ticket/11186): Introduced the [`widgets.repository.addUpcastCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-addUpcastCallback) method that allows to block upcasting given element to a widget.\r
+* [#11307](http://dev.ckeditor.com/ticket/11307): Fixed: Paste as Plain Text conflict with the [MooTools](http://mootools.net) library.\r
+* [#11140](http://dev.ckeditor.com/ticket/11140): [IE11] Fixed: Anchors are not draggable.\r
+* [#11379](http://dev.ckeditor.com/ticket/11379): Changed default contents `line-height` to unitless values to avoid huge text overlapping (like in [#9696](http://dev.ckeditor.com/ticket/9696)).\r
+* [#10787](http://dev.ckeditor.com/ticket/10787): [Firefox] Fixed: Broken replacement of text while pasting into `div`-based editor.\r
+* [#10884](http://dev.ckeditor.com/ticket/10884): Widgets integration with the [Show Blocks](http://ckeditor.com/addon/showblocks) plugin.\r
+* [#11021](http://dev.ckeditor.com/ticket/11021): Fixed: An error thrown when selecting entire editable contents while fake selection is on.\r
+* [#11086](http://dev.ckeditor.com/ticket/11086): [IE8] Re-enable inline widgets drag&drop in Internet Explorer 8.\r
+* [#11372](http://dev.ckeditor.com/ticket/11372): Widgets: Special characters encoded twice in nested editables.\r
+* [#10068](http://dev.ckeditor.com/ticket/10068): Fixed: Support for protocol-relative URLs.\r
+* [#11283](http://dev.ckeditor.com/ticket/11283): [Enhanced Image](http://ckeditor.com/addon/image2): A `<div>` element with `text-align: center` and an image inside is not recognised correctly.\r
+* [#11196](http://dev.ckeditor.com/ticket/11196): [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp): Allowed additional keyboard button labels to be translated in the dialog window.\r
+\r
+## CKEditor 4.3.1\r
+\r
+**Important Notes:**\r
+\r
+* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)).\r
+* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)).\r
+\r
+Fixed Issues:\r
+\r
+* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event.\r
+* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method.\r
+* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder.\r
+* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu.\r
+* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option.\r
+* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor.\r
+* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions.\r
+* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes.\r
+* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image.\r
+* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image.\r
+* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading.\r
+* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget.\r
+* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details.\r
+* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer.\r
+* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode.\r
+* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item.\r
+* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back.\r
+* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more.\r
+* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked.\r
+* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle.\r
+* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements.\r
+* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors.\r
+* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word.\r
+* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the `<textarea>` element are not encoded.\r
+* [#11260](http://dev.ckeditor.com/ticket/11260): Fixed: Initially disabled buttons are not read by JAWS as disabled.\r
+* [#11200](http://dev.ckeditor.com/ticket/11200):  Added [Clipboard](http://ckeditor.com/addon/clipboard) plugin as a dependency for [Widget](http://ckeditor.com/addon/widget) to fix drag and drop.\r
+\r
+## CKEditor 4.3\r
+\r
+New Features:\r
+\r
+* [#10612](http://dev.ckeditor.com/ticket/10612): Internet Explorer 11 support.\r
+* [#10869](http://dev.ckeditor.com/ticket/10869): Widgets: Added better integration with the [Elements Path](http://ckeditor.com/addon/elementspath) plugin.\r
+* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: Added tooltip to the drag handle.\r
+* [#10933](http://dev.ckeditor.com/ticket/10933): Widgets: Introduced drag and drop of block widgets with the [Line Utilities](http://ckeditor.com/addon/lineutils) plugin.\r
+* [#10936](http://dev.ckeditor.com/ticket/10936): Widget System changes for easier integration with other dialog systems.\r
+* [#10895](http://dev.ckeditor.com/ticket/10895): [Enhanced Image](http://ckeditor.com/addon/image2): Added file browser integration.\r
+* [#11002](http://dev.ckeditor.com/ticket/11002): Added the [`draggable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-draggable) option to disable drag and drop support for widgets.\r
+* [#10937](http://dev.ckeditor.com/ticket/10937): [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget improvements:\r
+  * loading indicator ([#10948](http://dev.ckeditor.com/ticket/10948)),\r
+  * applying paragraph changes (like font color change) to iframe ([#10841](http://dev.ckeditor.com/ticket/10841)),\r
+  * Firefox and IE9 clipboard fixes ([#10857](http://dev.ckeditor.com/ticket/10857)),\r
+  * fixing same origin policy issue ([#10840](http://dev.ckeditor.com/ticket/10840)),\r
+  * fixing undo bugs ([#10842](http://dev.ckeditor.com/ticket/10842), [#10930](http://dev.ckeditor.com/ticket/10930)),\r
+  * fixing other minor bugs.\r
+* [#10862](http://dev.ckeditor.com/ticket/10862): [Placeholder](http://ckeditor.com/addon/placeholder) plugin was rewritten as a widget.\r
+* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.\r
+* [#10856](http://dev.ckeditor.com/ticket/10856): Menu buttons will now toggle the visibility of their panels when clicked multiple times. [Language](http://ckeditor.com/addon/language) plugin fixes: Added active language highlighting, added an option to remove the language.\r
+* [#10028](http://dev.ckeditor.com/ticket/10028): New [`config.dialog_noConfirmCancel`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-dialog_noConfirmCancel) configuration option that eliminates the need to confirm closing of a dialog window when the user changed any of its fields.\r
+* [#10848](http://dev.ckeditor.com/ticket/10848): Integrate remaining plugins ([Styles](http://ckeditor.com/addon/stylescombo), [Format](http://ckeditor.com/addon/format), [Font](http://ckeditor.com/addon/font), [Color Button](http://ckeditor.com/addon/colorbutton), [Language](http://ckeditor.com/addon/language) and [Indent](http://ckeditor.com/addon/indent)) with [active filter](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter).\r
+* [#10855](http://dev.ckeditor.com/ticket/10855): Change the extension of emoticons in the [BBCode](http://ckeditor.com/addon/bbcode) sample from GIF to PNG.\r
+\r
+Fixed Issues:\r
+\r
+* [#10831](http://dev.ckeditor.com/ticket/10831): [Enhanced Image](http://ckeditor.com/addon/image2): Merged `image2inline` and `image2block` into one `image2` widget.\r
+* [#10835](http://dev.ckeditor.com/ticket/10835): [Enhanced Image](http://ckeditor.com/addon/image2): Improved visibility of the resize handle.\r
+* [#10836](http://dev.ckeditor.com/ticket/10836): [Enhanced Image](http://ckeditor.com/addon/image2): Preserve custom mouse cursor while resizing the image.\r
+* [#10939](http://dev.ckeditor.com/ticket/10939): [Firefox] [Enhanced Image](http://ckeditor.com/addon/image2): hovering the image causes it to change.\r
+* [#10866](http://dev.ckeditor.com/ticket/10866): Fixed: Broken *Tab* key navigation in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.\r
+* [#10833](http://dev.ckeditor.com/ticket/10833): Fixed: *Lock ratio* option should be on by default in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.\r
+* [#10881](http://dev.ckeditor.com/ticket/10881): Various improvements to *Enter* key behavior in nested editables.\r
+* [#10879](http://dev.ckeditor.com/ticket/10879): [Remove Format](http://ckeditor.com/addon/removeformat) should not leak from a nested editable.\r
+* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [WebSpellChecker](http://ckeditor.com/addon/wsc) fails to apply changes if a nested editable was focused.\r
+* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [SCAYT](http://ckeditor.com/addon/wsc) blocks typing in nested editables.\r
+* [#11079](http://dev.ckeditor.com/ticket/11079): Add button icons to the [Placeholder](http://ckeditor.com/addon/placeholder) sample.\r
+* [#10870](http://dev.ckeditor.com/ticket/10870): The `paste` command is no longer being disabled when the clipboard is empty.\r
+* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.\r
+* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: [Link](http://ckeditor.com/addon/link) plugin does not work with non-editable content.\r
+* [#10828](http://dev.ckeditor.com/ticket/10828): [Magic Line](http://ckeditor.com/addon/magicline) integration with the Widget System.\r
+* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.\r
+* [#11066](http://dev.ckeditor.com/ticket/11066): Widget's private parts use CSS reset.\r
+* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed: Block commands break on widgets; added the [`contentDomInvalidated`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDomInvalidated) event.\r
+* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of the [Image](http://ckeditor.com/addon/image) plugin on the [Form Elements](http://ckeditor.com/addon/forms) plugin.\r
+* [#10911](http://dev.ckeditor.com/ticket/10911): Fixed: Browser *Alt* hotkeys will no longer be blocked while a widget is focused.\r
+* [#11082](http://dev.ckeditor.com/ticket/11082): Fixed: Selected widget is not copied or cut when using toolbar buttons or context menu.\r
+* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed list and div element application to block widgets.\r
+* [#10887](http://dev.ckeditor.com/ticket/10887): Internet Explorer 8 compatibility issues related to the Widget System.\r
+* [#11074](http://dev.ckeditor.com/ticket/11074): Temporarily disabled inline widget drag and drop, because of seriously buggy native `range#moveToPoint` method.\r
+* [#11098](http://dev.ckeditor.com/ticket/11098): Fixed: Wrong selection position after undoing widget drag and drop.\r
+* [#11110](http://dev.ckeditor.com/ticket/11110): Fixed: IFrame and Flash objects are being incorrectly pasted in certain conditions.\r
+* [#11129](http://dev.ckeditor.com/ticket/11129): Page break is lost when loading data.\r
+* [#11123](http://dev.ckeditor.com/ticket/11123): [Firefox] Widget is destroyed after being dragged outside of `<body>`.\r
+* [#11124](http://dev.ckeditor.com/ticket/11124): Fixed the [Elements Path](http://ckeditor.com/addon/elementspath) in an editor using the [Div Editing Area](http://ckeditor.com/addon/divarea).\r
+\r
+## CKEditor 4.3 Beta\r
+\r
+New Features:\r
+\r
+* [#9764](http://dev.ckeditor.com/ticket/9764): Widget System.\r
+  * [Widget plugin](http://ckeditor.com/addon/widget) introducing the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget).\r
+  * New [`editor.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) and [`editor.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-shiftEnterMode) properties &ndash; normalized versions of [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) and [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).\r
+  * Dynamic editor settings. Starting from CKEditor 4.3 Beta, *Enter* mode values and [content filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) instances may be changed dynamically (for example when the caret was placed in an element in which editor features should be adjusted). When you are implementing a new editor feature, you should base its behavior on [dynamic](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) or [static](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) *Enter* mode values depending on whether this feature works in selection context or globally on editor content.\r
+      * Dynamic *Enter* mode values &ndash; [`editor.setActiveEnterMode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveEnterMode) method, [`editor.activeEnterModeChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeEnterModeChange) event, and two properties: [`editor.activeEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) and [`editor.activeShiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeShiftEnterMode).\r
+      * Dynamic content filter instances &ndash; [`editor.setActiveFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveFilter) method, [`editor.activeFilterChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeFilterChange) event, and [`editor.activeFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter) property.\r
+  * "Fake" selection was introduced. It makes it possible to virtually select any element when the real selection remains hidden. See the  [`selection.fake()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-fake) method.\r
+  * Default [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied to non-editable elements (elements with `contenteditable` attribute set to `false` and their descendants) anymore. To add a rule which will be applied to all elements you need to pass an additional argument to the [`filter.addRules()`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter-method-addRules) method.\r
+  * Dozens of new methods were introduced &ndash; most interesting ones:\r
+      * [`document.find()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-find),\r
+      * [`document.findOne()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-findOne),\r
+      * [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange),\r
+      * [`range.moveToClosestEditablePosition()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-moveToClosestEditablePosition),\r
+      * New methods for [`htmlParser.node`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.node) and [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element).\r
+* [#10659](http://dev.ckeditor.com/ticket/10659): New [Enhanced Image](http://ckeditor.com/addon/image2) plugin that introduces a widget with integrated image captions, an option to center images, and dynamic "click and drag" resizing.\r
+* [#10664](http://dev.ckeditor.com/ticket/10664): New [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin that introduces the MathJax widget.\r
+* [#7987](https://dev.ckeditor.com/ticket/7987): New [Language](http://ckeditor.com/addon/language) plugin that implements Language toolbar button to support [WCAG 3.1.2 Language of Parts](http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html).\r
+* [#10708](http://dev.ckeditor.com/ticket/10708): New [smileys](http://ckeditor.com/addon/smiley).\r
+\r
+## CKEditor 4.2.3\r
+\r
+Fixed Issues:\r
+\r
+* [#10994](http://dev.ckeditor.com/ticket/10994): Fixed: Loading external jQuery library when opening the [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) sample directly from file.\r
+* [#10975](http://dev.ckeditor.com/ticket/10975): [IE] Fixed: Error thrown while opening the color palette.\r
+* [#9929](http://dev.ckeditor.com/ticket/9929): [Blink/WebKit] Fixed: A non-breaking space is created once a character is deleted and a regular space is typed.\r
+* [#10963](http://dev.ckeditor.com/ticket/10963): Fixed: JAWS issue with the keyboard shortcut for [Magic Line](http://ckeditor.com/addon/magicline).\r
+* [#11096](http://dev.ckeditor.com/ticket/11096): Fixed: TypeError: Object has no method 'is'.\r
+\r
+## CKEditor 4.2.2\r
+\r
+Fixed Issues:\r
+\r
+* [#9314](http://dev.ckeditor.com/ticket/9314): Fixed: Incorrect error message on closing a dialog window without saving changs.\r
+* [#10308](http://dev.ckeditor.com/ticket/10308): [IE10] Fixed: Unspecified error when deleting a row.\r
+* [#10945](http://dev.ckeditor.com/ticket/10945): [Chrome] Fixed: Clicking with a mouse inside the editor does not show the caret.\r
+* [#10912](http://dev.ckeditor.com/ticket/10912): Prevent default action when content of a non-editable link is clicked.\r
+* [#10913](http://dev.ckeditor.com/ticket/10913): Fixed [`CKEDITOR.plugins.addExternal()`](http://docs.ckeditor.com/#!/api/CKEDITOR.resourceManager-method-addExternal) not handling paths including file name specified.\r
+* [#10666](http://dev.ckeditor.com/ticket/10666): Fixed [`CKEDITOR.tools.isArray()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-isArray) not working cross frame.\r
+* [#10910](http://dev.ckeditor.com/ticket/10910): [IE9] Fixed JavaScript error thrown in Compatibility Mode when clicking and/or typing in the editing area.\r
+* [#10868](http://dev.ckeditor.com/ticket/10868): [IE8] Prevent the browser from crashing when applying the Inline Quotation style.\r
+* [#10915](http://dev.ckeditor.com/ticket/10915): Fixed: Invalid CSS filter in the Kama skin.\r
+* [#10914](http://dev.ckeditor.com/ticket/10914): Plugins [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock) are now included in the build configuration.\r
+* [#10812](http://dev.ckeditor.com/ticket/10812): Fixed [`range.createBookmark2()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-createBookmark2) incorrectly normalizing offsets. This bug was causing many issues: [#10850](http://dev.ckeditor.com/ticket/10850), [#10842](http://dev.ckeditor.com/ticket/10842).\r
+* [#10951](http://dev.ckeditor.com/ticket/10951): Reviewed and optimized focus handling on panels (combo, menu buttons, color buttons, and context menu) to enhance accessibility. Fixed [#10705](http://dev.ckeditor.com/ticket/10705), [#10706](http://dev.ckeditor.com/ticket/10706) and [#10707](http://dev.ckeditor.com/ticket/10707).\r
+* [#10704](http://dev.ckeditor.com/ticket/10704): Fixed a JAWS issue with the Select Color dialog window title not being announced.\r
+* [#10753](http://dev.ckeditor.com/ticket/10753): The floating toolbar in inline instances now has a dedicated accessibility label.\r
+\r
+## CKEditor 4.2.1\r
+\r
+Fixed Issues:\r
+\r
+* [#10301](http://dev.ckeditor.com/ticket/10301): [IE9-10] Undo fails after 3+ consecutive paste actions with a JavaScript error.\r
+* [#10689](http://dev.ckeditor.com/ticket/10689): Save toolbar button saves only the first editor instance.\r
+* [#10368](http://dev.ckeditor.com/ticket/10368): Move language reading direction definition (`dir`) from main language file to core.\r
+* [#9330](http://dev.ckeditor.com/ticket/9330): Fixed pasting anchors from MS Word.\r
+* [#8103](http://dev.ckeditor.com/ticket/8103): Fixed pasting nested lists from MS Word.\r
+* [#9958](http://dev.ckeditor.com/ticket/9958): [IE9] Pressing the "OK" button will trigger the `onbeforeunload` event in the popup dialog.\r
+* [#10662](http://dev.ckeditor.com/ticket/10662): Fixed styles from the Styles drop-down list not registering to the ACF in case when the [Shared Spaces plugin](http://ckeditor.com/addon/sharedspace) is used.\r
+* [#9654](http://dev.ckeditor.com/ticket/9654): Problems with Internet Explorer 10 Quirks Mode.\r
+* [#9816](http://dev.ckeditor.com/ticket/9816): Floating toolbar does not reposition vertically in several cases.\r
+* [#10646](http://dev.ckeditor.com/ticket/10646): Removing a selected sublist or nested table with *Backspace/Delete* removes the parent element.\r
+* [#10623](http://dev.ckeditor.com/ticket/10623): [WebKit] Page is scrolled when opening a drop-down list.\r
+* [#10004](http://dev.ckeditor.com/ticket/10004): [ChromeVox] Button names are not announced.\r
+* [#10731](http://dev.ckeditor.com/ticket/10731): [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin breaks cloning of editor configuration.\r
+* It is now possible to set per instance [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin configuration instead of setting the configuration globally.\r
+\r
+## CKEditor 4.2\r
+\r
+**Important Notes:**\r
+\r
+* Dropped compatibility support for Internet Explorer 7 and Firefox 3.6.\r
+\r
+* Both the Basic and the Standard distribution packages will not contain the new [Indent Block](http://ckeditor.com/addon/indentblock) plugin. Because of this the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) might remove block indentations from existing contents. If you want to prevent this, either [add an appropriate ACF rule to your filter](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) or create a custom build based on the Basic/Standard package and add the Indent Block plugin in [CKBuilder](http://ckeditor.com/builder).\r
+\r
+New Features:\r
+\r
+* [#10027](http://dev.ckeditor.com/ticket/10027): Separated list and block indentation into two plugins: [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock).\r
+* [#8244](http://dev.ckeditor.com/ticket/8244): Use *(Shift+)Tab* to indent and outdent lists.\r
+* [#10281](http://dev.ckeditor.com/ticket/10281): The [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) is now available. Several jQuery-related issues fixed: [#8261](http://dev.ckeditor.com/ticket/8261), [#9077](http://dev.ckeditor.com/ticket/9077), [#8710](http://dev.ckeditor.com/ticket/8710), [#8530](http://dev.ckeditor.com/ticket/8530), [#9019](http://dev.ckeditor.com/ticket/9019), [#6181](http://dev.ckeditor.com/ticket/6181), [#7876](http://dev.ckeditor.com/ticket/7876), [#6906](http://dev.ckeditor.com/ticket/6906).\r
+* [#10042](http://dev.ckeditor.com/ticket/10042): Introduced [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title) setting to change the human-readable title of the editor.\r
+* [#9794](http://dev.ckeditor.com/ticket/9794): Added [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.\r
+* [#9923](http://dev.ckeditor.com/ticket/9923): HiDPI support in the editor UI. HiDPI icons for [Moono skin](http://ckeditor.com/addon/moono) added.\r
+* [#8031](http://dev.ckeditor.com/ticket/8031): Handle `required` attributes on `<textarea>` elements &mdash; introduced [`editor.required`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-required) event.\r
+* [#10280](http://dev.ckeditor.com/ticket/10280): Ability to replace `<textarea>` elements with the inline editor.\r
+\r
+Fixed Issues:\r
+\r
+* [#10599](http://dev.ckeditor.com/ticket/10599): [Indent](http://ckeditor.com/addon/indent) plugin is no longer required by the [List](http://ckeditor.com/addon/list) plugin.\r
+* [#10370](http://dev.ckeditor.com/ticket/10370): Inconsistency in data events between framed and inline editors.\r
+* [#10438](http://dev.ckeditor.com/ticket/10438): [FF, IE] No selection is done on an editable element on executing [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData).\r
+\r
+## CKEditor 4.1.3\r
+\r
+New Features:\r
+\r
+* Added new translation: Indonesian.\r
+\r
+Fixed Issues:\r
+\r
+* [#10644](http://dev.ckeditor.com/ticket/10644): Fixed a critical bug when pasting plain text in Blink-based browsers.\r
+* [#5189](http://dev.ckeditor.com/ticket/5189): [Find/Replace](http://ckeditor.com/addon/find) dialog window: rename "Cancel" button to "Close".\r
+* [#10562](http://dev.ckeditor.com/ticket/10562): [Housekeeping] Unified CSS gradient filter formats in the [Moono](http://ckeditor.com/addon/moono) skin.\r
+* [#10537](http://dev.ckeditor.com/ticket/10537): Advanced Content Filter should register a default rule for [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).\r
+* [#10610](http://dev.ckeditor.com/ticket/10610): [`CKEDITOR.dialog.addIframe()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-static-method-addIframe) incorrectly sets the iframe size in dialog windows.\r
+\r
+## CKEditor 4.1.2\r
+\r
+New Features:\r
+\r
+* Added new translation: Sinhala.\r
+\r
+Fixed Issues:\r
+\r
+* [#10339](http://dev.ckeditor.com/ticket/10339): Fixed: Error thrown when inserted data was totally stripped out after filtering and processing.\r
+* [#10298](http://dev.ckeditor.com/ticket/10298): Fixed: Data processor breaks attributes containing protected parts.\r
+* [#10367](http://dev.ckeditor.com/ticket/10367): Fixed: [`editable.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertText) loses characters when `RegExp` replace controls are being inserted.\r
+* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error when `document.domain` has been altered.\r
+* [#9761](http://dev.ckeditor.com/ticket/9761): Update the *Backspace* key state in [`keystrokeHandler.blockedKeystrokes`](http://docs.ckeditor.com/#!/api/CKEDITOR.keystrokeHandler-property-blockedKeystrokes) when calling [`editor.setReadOnly()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly).\r
+* [#6504](http://dev.ckeditor.com/ticket/6504): Fixed: Race condition while loading several [`config.customConfig`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig) files.\r
+* [#10146](http://dev.ckeditor.com/ticket/10146): [Firefox] Empty lines are being removed while [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).\r
+* [#10360](http://dev.ckeditor.com/ticket/10360): Fixed: ARIA `role="application"` should not be used for dialog windows.\r
+* [#10361](http://dev.ckeditor.com/ticket/10361): Fixed: ARIA `role="application"` should not be used for floating panels.\r
+* [#10510](http://dev.ckeditor.com/ticket/10510): Introduced unique voice labels to differentiate between different editor instances.\r
+* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.\r
+* [#10389](http://dev.ckeditor.com/ticket/10389): Fixed: Invalid HTML in the "Text and Table" template.\r
+* [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin user interface was changed to match CKEditor 4 style.\r
+\r
+## CKEditor 4.1.1\r
+\r
+New Features:\r
+\r
+* Added new translation: Albanian.\r
+\r
+Fixed Issues:\r
+\r
+* [#10172](http://dev.ckeditor.com/ticket/10172): Pressing *Delete* or *Backspace* in an empty table cell moves the cursor to the next/previous cell.\r
+* [#10219](http://dev.ckeditor.com/ticket/10219): Error thrown when destroying an editor instance in parallel with a `mouseup` event.\r
+* [#10265](http://dev.ckeditor.com/ticket/10265): Wrong loop type in the [File Browser](http://ckeditor.com/addon/filebrowser) plugin.\r
+* [#10249](http://dev.ckeditor.com/ticket/10249): Wrong undo/redo states at start.\r
+* [#10268](http://dev.ckeditor.com/ticket/10268): [Show Blocks](http://ckeditor.com/addon/showblocks) does not recover after switching to Source view.\r
+* [#9995](http://dev.ckeditor.com/ticket/9995): HTML code in the `<textarea>` should not be modified by the [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor).\r
+* [#10320](http://dev.ckeditor.com/ticket/10320): [Justify](http://ckeditor.com/addon/justify) plugin should add elements to Advanced Content Filter based on current [Enter mode](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode).\r
+* [#10260](http://dev.ckeditor.com/ticket/10260): Fixed: Advanced Content Filter blocks [`tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces). Unified `data-cke-*` attributes filtering.\r
+* [#10315](http://dev.ckeditor.com/ticket/10315): [WebKit] [Undo manager](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager) should not record snapshots after a filling character was added/removed.\r
+* [#10291](http://dev.ckeditor.com/ticket/10291): [WebKit] Space after a filling character should be secured.\r
+* [#10330](http://dev.ckeditor.com/ticket/10330): [WebKit] The filling character is not removed on `keydown` in specific cases.\r
+* [#10285](http://dev.ckeditor.com/ticket/10285): Fixed: Styled text pasted from MS Word causes an infinite loop.\r
+* [#10131](http://dev.ckeditor.com/ticket/10131): Fixed: [`undoManager.update()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-method-update) does not refresh the command state.\r
+* [#10337](http://dev.ckeditor.com/ticket/10337): Fixed: Unable to remove `<s>` using [Remove Format](http://ckeditor.com/addon/removeformat).\r
+\r
+## CKEditor 4.1\r
+\r
+Fixed Issues:\r
+\r
+* [#10192](http://dev.ckeditor.com/ticket/10192): Closing lists with the *Enter* key does not work with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) in several cases.\r
+* [#10191](http://dev.ckeditor.com/ticket/10191): Fixed allowed content rules unification, so the [`filter.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-allowedContent) property always contains rules in the same format.\r
+* [#10224](http://dev.ckeditor.com/ticket/10224): Advanced Content Filter does not remove non-empty `<a>` elements anymore.\r
+* Minor issues in plugin integration with Advanced Content Filter:\r
+  * [#10166](http://dev.ckeditor.com/ticket/10166): Added transformation from the `align` attribute to `float` style to preserve backward compatibility after the introduction of Advanced Content Filter.\r
+  * [#10195](http://dev.ckeditor.com/ticket/10195): [Image](http://ckeditor.com/addon/image) plugin no longer registers rules for links to Advanced Content Filter.\r
+  * [#10213](http://dev.ckeditor.com/ticket/10213): [Justify](http://ckeditor.com/addon/justify) plugin is now correctly registering rules to Advanced Content Filter when [`config.justifyClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-justifyClasses) is defined.\r
+\r
+## CKEditor 4.1 RC\r
+\r
+New Features:\r
+\r
+* [#9829](http://dev.ckeditor.com/ticket/9829): Advanced Content Filter - data and features activation based on editor configuration.\r
+\r
+  Brand new data filtering system that works in 2 modes:\r
+\r
+  * Based on loaded features (toolbar items, plugins) - the data will be filtered according to what the editor in its\r
+  current configuration can handle.\r
+  * Based on [`config.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent) rules - the data\r
+  will be filtered and the editor features (toolbar items, commands, keystrokes) will be enabled if they are allowed.\r
+\r
+  See the `datafiltering.html` sample, [guides](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) and [`CKEDITOR.filter` API documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).\r
+* [#9387](http://dev.ckeditor.com/ticket/9387): Reintroduced [Shared Spaces](http://ckeditor.com/addon/sharedspace) - the ability to display toolbar and bottom editor space in selected locations and to share them by different editor instances.\r
+* [#9907](http://dev.ckeditor.com/ticket/9907): Added the [`contentPreview`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-contentPreview) event for preview data manipulation.\r
+* [#9713](http://dev.ckeditor.com/ticket/9713): Introduced the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin that brings raw HTML editing for inline editor instances.\r
+* Included in [#9829](http://dev.ckeditor.com/ticket/9829): Introduced new events, [`toHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toHtml) and [`toDataFormat`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toDataFormat), allowing for better integration with data processing.\r
+* [#9981](http://dev.ckeditor.com/ticket/9981): Added ability to filter [`htmlParser.fragment`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.fragment), [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element) etc. by many [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter)s before writing structure to an HTML string.\r
+* Included in [#10103](http://dev.ckeditor.com/ticket/10103):\r
+  * Introduced the [`editor.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-status) property to make it easier to check the current status of the editor.\r
+  * Default [`command`](http://docs.ckeditor.com/#!/api/CKEDITOR.command) state is now [`CKEDITOR.TRISTATE_DISABLE`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-TRISTATE_DISABLED). It will be activated on [`editor.instanceReady`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-instanceReady) or immediately after being added if the editor is already initialized.\r
+* [#9796](http://dev.ckeditor.com/ticket/9796): Introduced `<s>` as a default tag for strikethrough, which replaces obsolete `<strike>` in HTML5.\r
+\r
+## CKEditor 4.0.3\r
+\r
+Fixed Issues:\r
+\r
+* [#10196](http://dev.ckeditor.com/ticket/10196): Fixed context menus not opening with keyboard shortcuts when [Autogrow](http://ckeditor.com/addon/autogrow) is enabled.\r
+* [#10212](http://dev.ckeditor.com/ticket/10212): [IE7-10] Undo command throws errors after multiple switches between Source and WYSIWYG view.\r
+* [#10219](http://dev.ckeditor.com/ticket/10219): [Inline editor] Error thrown after calling [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy).\r
+\r
+## CKEditor 4.0.2\r
+\r
+Fixed Issues:\r
+\r
+* [#9779](http://dev.ckeditor.com/ticket/9779): Fixed overriding [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl) with `CKEDITOR_GETURL`.\r
+* [#9772](http://dev.ckeditor.com/ticket/9772): Custom buttons in the dialog window footer have different look and size ([Moono](http://ckeditor.com/addon/moono), [Kama](http://ckeditor.com/addon/kama) skins).\r
+* [#9029](http://dev.ckeditor.com/ticket/9029): Custom styles added with the [`stylesSet.add()`](http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet-method-add) are displayed in the wrong order.\r
+* [#9887](http://dev.ckeditor.com/ticket/9887): Disable [Magic Line](http://ckeditor.com/addon/magicline) when [`editor.readOnly`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) is set.\r
+* [#9882](http://dev.ckeditor.com/ticket/9882): Fixed empty document title on [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) if set via the Document Properties dialog window.\r
+* [#9773](http://dev.ckeditor.com/ticket/9773): Fixed rendering problems with selection fields in the Kama skin.\r
+* [#9851](http://dev.ckeditor.com/ticket/9851): The [`selectionChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-selectionChange) event is not fired when mouse selection ended outside editable.\r
+* [#9903](http://dev.ckeditor.com/ticket/9903): [Inline editor] Bad positioning of floating space with page horizontal scroll.\r
+* [#9872](http://dev.ckeditor.com/ticket/9872): [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) returns `true` when called onload. Removed the obsolete `editor.mayBeDirty` flag.\r
+* [#9893](http://dev.ckeditor.com/ticket/9893): [IE] Fixed broken toolbar when editing mixed direction content in Quirks mode.\r
+* [#9845](http://dev.ckeditor.com/ticket/9845): Fixed TAB navigation in the [Link](http://ckeditor.com/addon/link) dialog window when the Anchor option is used and no anchors are available.\r
+* [#9883](http://dev.ckeditor.com/ticket/9883): Maximizing was making the entire page editable with [divarea](http://ckeditor.com/addon/divarea)-based editors.\r
+* [#9940](http://dev.ckeditor.com/ticket/9940): [Firefox] Navigating back to a page with the editor was making the entire page editable.\r
+* [#9966](http://dev.ckeditor.com/ticket/9966): Fixed: Unable to type square brackets with French keyboard layout. Changed [Magic Line](http://ckeditor.com/addon/magicline) keystrokes.\r
+* [#9507](http://dev.ckeditor.com/ticket/9507): [Firefox] Selection is moved before editable position when the editor is focused for the first time.\r
+* [#9947](http://dev.ckeditor.com/ticket/9947): [WebKit] Editor overflows parent container in some edge cases.\r
+* [#10105](http://dev.ckeditor.com/ticket/10105): Fixed: Broken [sourcearea](http://ckeditor.com/addon/sourcearea) view when an RTL language is set.\r
+* [#10123](http://dev.ckeditor.com/ticket/10123): [WebKit] Fixed: Several dialog windows have broken layout since the latest WebKit release.\r
+* [#10152](http://dev.ckeditor.com/ticket/10152): Fixed: Invalid ARIA property used on menu items.\r
+\r
+## CKEditor 4.0.1.1\r
+\r
+Fixed Issues:\r
+\r
+* Security update: Added protection against XSS attack and possible path disclosure in the PHP sample.\r
+\r
+## CKEditor 4.0.1\r
+\r
+Fixed Issues:\r
+\r
+* [#9655](http://dev.ckeditor.com/ticket/9655): Support for IE Quirks Mode in the new [Moono skin](http://ckeditor.com/addon/moono).\r
+* Accessibility issues (mainly in inline editor): [#9364](http://dev.ckeditor.com/ticket/9364), [#9368](http://dev.ckeditor.com/ticket/9368), [#9369](http://dev.ckeditor.com/ticket/9369), [#9370](http://dev.ckeditor.com/ticket/9370), [#9541](http://dev.ckeditor.com/ticket/9541), [#9543](http://dev.ckeditor.com/ticket/9543), [#9841](http://dev.ckeditor.com/ticket/9841), [#9844](http://dev.ckeditor.com/ticket/9844).\r
+* [Magic Line](http://ckeditor.com/addon/magicline) plugin:\r
+    * [#9481](http://dev.ckeditor.com/ticket/9481): Added accessibility support for Magic Line.\r
+    * [#9509](http://dev.ckeditor.com/ticket/9509): Added Magic Line support for forms.\r
+    * [#9573](http://dev.ckeditor.com/ticket/9573): Magic Line does not disappear on `mouseout` in a specific case.\r
+* [#9754](http://dev.ckeditor.com/ticket/9754): [WebKit] Cutting & pasting simple unformatted text generates an inline wrapper in WebKit browsers.\r
+* [#9456](http://dev.ckeditor.com/ticket/9456): [Chrome] Properly paste bullet list style from MS Word.\r
+* [#9699](http://dev.ckeditor.com/ticket/9699), [#9758](http://dev.ckeditor.com/ticket/9758): Improved selection locking when selecting by dragging.\r
+* Context menu:\r
+    * [#9712](http://dev.ckeditor.com/ticket/9712): Opening the context menu destroys editor focus.\r
+    * [#9366](http://dev.ckeditor.com/ticket/9366): Context menu should be displayed over the floating toolbar.\r
+    * [#9706](http://dev.ckeditor.com/ticket/9706): Context menu generates a JavaScript error in inline mode when the editor is attached to a header element.\r
+* [#9800](http://dev.ckeditor.com/ticket/9800): Hide float panel when resizing the window.\r
+* [#9721](http://dev.ckeditor.com/ticket/9721): Padding in content of div-based editor puts the editing area under the bottom UI space.\r
+* [#9528](http://dev.ckeditor.com/ticket/9528): Host page `box-sizing` style should not influence the editor UI elements.\r
+* [#9503](http://dev.ckeditor.com/ticket/9503): [Form Elements](http://ckeditor.com/addon/forms) plugin adds context menu listeners only on supported input types. Added support for `tel`, `email`, `search` and `url` input types.\r
+* [#9769](http://dev.ckeditor.com/ticket/9769): Improved floating toolbar positioning in a narrow window.\r
+* [#9875](http://dev.ckeditor.com/ticket/9875): Table dialog window does not populate width correctly.\r
+* [#8675](http://dev.ckeditor.com/ticket/8675): Deleting cells in a nested table removes the outer table cell.\r
+* [#9815](http://dev.ckeditor.com/ticket/9815): Cannot edit dialog window fields in an editor initialized in the jQuery UI modal dialog.\r
+* [#8888](http://dev.ckeditor.com/ticket/8888): CKEditor dialog windows do not show completely in a small window.\r
+* [#9360](http://dev.ckeditor.com/ticket/9360): [Inline editor] Blocks shown for a `<div>` element stay permanently even after the user exits editing the `<div>`.\r
+* [#9531](http://dev.ckeditor.com/ticket/9531): [Firefox & Inline editor] Toolbar is lost when closing the Format drop-down list by clicking its button.\r
+* [#9553](http://dev.ckeditor.com/ticket/9553): Table width incorrectly set when the `border-width` style is specified.\r
+* [#9594](http://dev.ckeditor.com/ticket/9594): Cannot tab past CKEditor when it is in read-only mode.\r
+* [#9658](http://dev.ckeditor.com/ticket/9658): [IE9] Justify not working on selected images.\r
+* [#9686](http://dev.ckeditor.com/ticket/9686): Added missing contents styles for `<pre>` elements.\r
+* [#9709](http://dev.ckeditor.com/ticket/9709): [Paste from Word](http://ckeditor.com/addon/pastefromword) should not depend on configuration from other styles.\r
+* [#9726](http://dev.ckeditor.com/ticket/9726): Removed [Color Dialog](http://ckeditor.com/addon/colordialog) plugin dependency from [Table Tools](http://ckeditor.com/addon/tabletools).\r
+* [#9765](http://dev.ckeditor.com/ticket/9765): Toolbar Collapse command documented incorrectly in the [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp) dialog window.\r
+* [#9771](http://dev.ckeditor.com/ticket/9771): [WebKit & Opera] Fixed scrolling issues when pasting.\r
+* [#9787](http://dev.ckeditor.com/ticket/9787): [IE9] `onChange` is not fired for checkboxes in dialogs.\r
+* [#9842](http://dev.ckeditor.com/ticket/9842): [Firefox 17] When opening a toolbar menu for the first time and pressing the *Down Arrow* key, focus goes to the next toolbar button instead of the menu options.\r
+* [#9847](http://dev.ckeditor.com/ticket/9847): [Elements Path](http://ckeditor.com/addon/elementspath) should not be initialized in the inline editor.\r
+* [#9853](http://dev.ckeditor.com/ticket/9853): [`editor.addRemoveFormatFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addRemoveFormatFilter) is exposed before it really works.\r
+* [#8893](http://dev.ckeditor.com/ticket/8893): Value of the [`pasteFromWordCleanupFile`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordCleanupFile) configuration option is now taken from the instance configuration.\r
+* [#9693](http://dev.ckeditor.com/ticket/9693): Removed "Live Preview" checkbox from UI color picker.\r
+\r
+\r
+## CKEditor 4.0\r
+\r
+The first stable release of the new CKEditor 4 code line.\r
+\r
+The CKEditor JavaScript API has been kept compatible with CKEditor 4, whenever\r
+possible. The list of relevant changes can be found in the [API Changes page of\r
+the CKEditor 4 documentation][1].\r
+\r
+[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes "API Changes"\r
diff --git a/release/LICENSE.md b/release/LICENSE.md
new file mode 100644 (file)
index 0000000..044e7da
--- /dev/null
@@ -0,0 +1,1420 @@
+Software License Agreement\r
+==========================\r
+\r
+CKEditor - The text editor for Internet - http://ckeditor.com\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+\r
+Licensed under the terms of any of the following licenses at your\r
+choice:\r
+\r
+ - GNU General Public License Version 2 or later (the "GPL")\r
+   http://www.gnu.org/licenses/gpl.html\r
+   (See Appendix A)\r
+\r
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")\r
+   http://www.gnu.org/licenses/lgpl.html\r
+   (See Appendix B)\r
+\r
+ - Mozilla Public License Version 1.1 or later (the "MPL")\r
+   http://www.mozilla.org/MPL/MPL-1.1.html\r
+   (See Appendix C)\r
+\r
+You are not required to, but if you want to explicitly declare the\r
+license you have chosen to be bound to when using, reproducing,\r
+modifying and distributing this software, just include a text file\r
+titled "legal.txt" in your version of this software, indicating your\r
+license choice. In any case, your choice will not restrict any\r
+recipient of your version of this software to use, reproduce, modify\r
+and distribute this software under any of the above licenses.\r
+\r
+Sources of Intellectual Property Included in CKEditor\r
+-----------------------------------------------------\r
+\r
+Where not otherwise indicated, all CKEditor content is authored by\r
+CKSource engineers and consists of CKSource-owned intellectual\r
+property. In some specific instances, CKEditor will incorporate work\r
+done by developers outside of CKSource with their express permission.\r
+\r
+The following libraries are included in CKEditor under the MIT license (see Appendix D):\r
+\r
+* CKSource Samples Framework (included in the samples) - Copyright (c) 2014-2017, CKSource - Frederico Knabben.\r
+* PicoModal (included in `samples/js/sf.js`) - Copyright (c) 2012 James Frasca.\r
+* CodeMirror (included in the samples) - Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others.\r
+\r
+Parts of code taken from the following libraries are included in CKEditor under the MIT license (see Appendix D):\r
+\r
+* jQuery (inspired the domReady function, ckeditor_base.js) - Copyright (c) 2011 John Resig, http://jquery.com/\r
+\r
+The following libraries are included in CKEditor under the SIL Open Font License, Version 1.1 (see Appendix E):\r
+\r
+* Font Awesome (included in the toolbar configurator) - Copyright (C) 2012 by Dave Gandy.\r
+\r
+The following libraries are included in CKEditor under the BSD-3 License (see Appendix F):\r
+\r
+* highlight.js (included in the `codesnippet` plugin) - Copyright (c) 2006, Ivan Sagalaev.\r
+* YUI Library (included in the `uicolor` plugin) - Copyright (c) 2009, Yahoo! Inc.\r
+\r
+\r
+Trademarks\r
+----------\r
+\r
+CKEditor is a trademark of CKSource - Frederico Knabben. All other brand\r
+and product names are trademarks, registered trademarks or service\r
+marks of their respective holders.\r
+\r
+---\r
+\r
+Appendix A: The GPL License\r
+---------------------------\r
+\r
+```\r
+GNU GENERAL PUBLIC LICENSE\r
+Version 2, June 1991\r
+\r
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,\r
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+License is intended to guarantee your freedom to share and change free\r
+software-to make sure the software is free for all its users.  This\r
+General Public License applies to most of the Free Software\r
+Foundation's software and to any other program whose authors commit to\r
+using it.  (Some other Free Software Foundation software is covered by\r
+the GNU Lesser General Public License instead.)  You can apply it to\r
+your programs, too.\r
+\r
+  When we speak of free software, we are referring to freedom, not\r
+price.  Our General Public Licenses are designed to make sure that you\r
+have the freedom to distribute copies of free software (and charge for\r
+this service if you wish), that you receive source code or can get it\r
+if you want it, that you can change the software or use pieces of it\r
+in new free programs; and that you know you can do these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+anyone to deny you these rights or to ask you to surrender the rights.\r
+These restrictions translate to certain responsibilities for you if you\r
+distribute copies of the software, or if you modify it.\r
+\r
+  For example, if you distribute copies of such a program, whether\r
+gratis or for a fee, you must give the recipients all the rights that\r
+you have.  You must make sure that they, too, receive or can get the\r
+source code.  And you must show them these terms so they know their\r
+rights.\r
+\r
+  We protect your rights with two steps: (1) copyright the software, and\r
+(2) offer you this license which gives you legal permission to copy,\r
+distribute and/or modify the software.\r
+\r
+  Also, for each author's protection and ours, we want to make certain\r
+that everyone understands that there is no warranty for this free\r
+software.  If the software is modified by someone else and passed on, we\r
+want its recipients to know that what they have is not the original, so\r
+that any problems introduced by others will not reflect on the original\r
+authors' reputations.\r
+\r
+  Finally, any free program is threatened constantly by software\r
+patents.  We wish to avoid the danger that redistributors of a free\r
+program will individually obtain patent licenses, in effect making the\r
+program proprietary.  To prevent this, we have made it clear that any\r
+patent must be licensed for everyone's free use or not licensed at all.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.\r
+\r
+GNU GENERAL PUBLIC LICENSE\r
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License applies to any program or other work which contains\r
+a notice placed by the copyright holder saying it may be distributed\r
+under the terms of this General Public License.  The "Program", below,\r
+refers to any such program or work, and a "work based on the Program"\r
+means either the Program or any derivative work under copyright law:\r
+that is to say, a work containing the Program or a portion of it,\r
+either verbatim or with modifications and/or translated into another\r
+language.  (Hereinafter, translation is included without limitation in\r
+the term "modification".)  Each licensee is addressed as "you".\r
+\r
+Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running the Program is not restricted, and the output from the Program\r
+is covered only if its contents constitute a work based on the\r
+Program (independent of having been made by running the Program).\r
+Whether that is true depends on what the Program does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Program's\r
+source code as you receive it, in any medium, provided that you\r
+conspicuously and appropriately publish on each copy an appropriate\r
+copyright notice and disclaimer of warranty; keep intact all the\r
+notices that refer to this License and to the absence of any warranty;\r
+and give any other recipients of the Program a copy of this License\r
+along with the Program.\r
+\r
+You may charge a fee for the physical act of transferring a copy, and\r
+you may at your option offer warranty protection in exchange for a fee.\r
+\r
+  2. You may modify your copy or copies of the Program or any portion\r
+of it, thus forming a work based on the Program, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) You must cause the modified files to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    b) You must cause any work that you distribute or publish, that in\r
+    whole or in part contains or is derived from the Program or any\r
+    part thereof, to be licensed as a whole at no charge to all third\r
+    parties under the terms of this License.\r
+\r
+    c) If the modified program normally reads commands interactively\r
+    when run, you must cause it, when started running for such\r
+    interactive use in the most ordinary way, to print or display an\r
+    announcement including an appropriate copyright notice and a\r
+    notice that there is no warranty (or else, saying that you provide\r
+    a warranty) and that users may redistribute the program under\r
+    these conditions, and telling the user how to view a copy of this\r
+    License.  (Exception: if the Program itself is interactive but\r
+    does not normally print such an announcement, your work based on\r
+    the Program is not required to print an announcement.)\r
+\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Program,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Program, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Program.\r
+\r
+In addition, mere aggregation of another work not based on the Program\r
+with the Program (or with a work based on the Program) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may copy and distribute the Program (or a work based on it,\r
+under Section 2) in object code or executable form under the terms of\r
+Sections 1 and 2 above provided that you also do one of the following:\r
+\r
+    a) Accompany it with the complete corresponding machine-readable\r
+    source code, which must be distributed under the terms of Sections\r
+    1 and 2 above on a medium customarily used for software interchange; or,\r
+\r
+    b) Accompany it with a written offer, valid for at least three\r
+    years, to give any third party, for a charge no more than your\r
+    cost of physically performing source distribution, a complete\r
+    machine-readable copy of the corresponding source code, to be\r
+    distributed under the terms of Sections 1 and 2 above on a medium\r
+    customarily used for software interchange; or,\r
+\r
+    c) Accompany it with the information you received as to the offer\r
+    to distribute corresponding source code.  (This alternative is\r
+    allowed only for noncommercial distribution and only if you\r
+    received the program in object code or executable form with such\r
+    an offer, in accord with Subsection b above.)\r
+\r
+The source code for a work means the preferred form of the work for\r
+making modifications to it.  For an executable work, complete source\r
+code means all the source code for all modules it contains, plus any\r
+associated interface definition files, plus the scripts used to\r
+control compilation and installation of the executable.  However, as a\r
+special exception, the source code distributed need not include\r
+anything that is normally distributed (in either source or binary\r
+form) with the major components (compiler, kernel, and so on) of the\r
+operating system on which the executable runs, unless that component\r
+itself accompanies the executable.\r
+\r
+If distribution of executable or object code is made by offering\r
+access to copy from a designated place, then offering equivalent\r
+access to copy the source code from the same place counts as\r
+distribution of the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\r
+  4. You may not copy, modify, sublicense, or distribute the Program\r
+except as expressly provided under this License.  Any attempt\r
+otherwise to copy, modify, sublicense or distribute the Program is\r
+void, and will automatically terminate your rights under this License.\r
+However, parties who have received copies, or rights, from you under\r
+this License will not have their licenses terminated so long as such\r
+parties remain in full compliance.\r
+\r
+  5. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Program or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Program (or any work based on the\r
+Program), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Program or works based on it.\r
+\r
+  6. Each time you redistribute the Program (or any work based on the\r
+Program), the recipient automatically receives a license from the\r
+original licensor to copy, distribute or modify the Program subject to\r
+these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties to\r
+this License.\r
+\r
+  7. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Program at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Program by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Program.\r
+\r
+If any portion of this section is held invalid or unenforceable under\r
+any particular circumstance, the balance of the section is intended to\r
+apply and the section as a whole is intended to apply in other\r
+circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system, which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\r
+  8. If the distribution and/or use of the Program is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Program under this License\r
+may add an explicit geographical distribution limitation excluding\r
+those countries, so that distribution is permitted only in or among\r
+countries not thus excluded.  In such case, this License incorporates\r
+the limitation as if written in the body of this License.\r
+\r
+  9. The Free Software Foundation may publish revised and/or new versions\r
+of the General Public License from time to time.  Such new versions will\r
+be similar in spirit to the present version, but may differ in detail to\r
+address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Program\r
+specifies a version number of this License which applies to it and "any\r
+later version", you have the option of following the terms and conditions\r
+either of that version or of any later version published by the Free\r
+Software Foundation.  If the Program does not specify a version number of\r
+this License, you may choose any version ever published by the Free Software\r
+Foundation.\r
+\r
+  10. If you wish to incorporate parts of the Program into other free\r
+programs whose distribution conditions are different, write to the author\r
+to ask for permission.  For software which is copyrighted by the Free\r
+Software Foundation, write to the Free Software Foundation; we sometimes\r
+make exceptions for this.  Our decision will be guided by the two goals\r
+of preserving the free status of all derivatives of our free software and\r
+of promoting the sharing and reuse of software generally.\r
+\r
+NO WARRANTY\r
+\r
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY\r
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN\r
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES\r
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED\r
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF\r
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS\r
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE\r
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,\r
+REPAIR OR CORRECTION.\r
+\r
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING\r
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR\r
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,\r
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING\r
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED\r
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY\r
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER\r
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE\r
+POSSIBILITY OF SUCH DAMAGES.\r
+\r
+END OF TERMS AND CONDITIONS\r
+```\r
+\r
+Appendix B: The LGPL License\r
+----------------------------\r
+\r
+```\r
+GNU LESSER GENERAL PUBLIC LICENSE\r
+Version 2.1, February 1999\r
+\r
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.\r
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\r
+ Everyone is permitted to copy and distribute verbatim copies\r
+ of this license document, but changing it is not allowed.\r
+\r
+[This is the first released version of the Lesser GPL.  It also counts\r
+ as the successor of the GNU Library Public License, version 2, hence\r
+ the version number 2.1.]\r
+\r
+Preamble\r
+\r
+  The licenses for most software are designed to take away your\r
+freedom to share and change it.  By contrast, the GNU General Public\r
+Licenses are intended to guarantee your freedom to share and change\r
+free software-to make sure the software is free for all its users.\r
+\r
+  This license, the Lesser General Public License, applies to some\r
+specially designated software packages-typically libraries-of the\r
+Free Software Foundation and other authors who decide to use it.  You\r
+can use it too, but we suggest you first think carefully about whether\r
+this license or the ordinary General Public License is the better\r
+strategy to use in any particular case, based on the explanations below.\r
+\r
+  When we speak of free software, we are referring to freedom of use,\r
+not price.  Our General Public Licenses are designed to make sure that\r
+you have the freedom to distribute copies of free software (and charge\r
+for this service if you wish); that you receive source code or can get\r
+it if you want it; that you can change the software and use pieces of\r
+it in new free programs; and that you are informed that you can do\r
+these things.\r
+\r
+  To protect your rights, we need to make restrictions that forbid\r
+distributors to deny you these rights or to ask you to surrender these\r
+rights.  These restrictions translate to certain responsibilities for\r
+you if you distribute copies of the library or if you modify it.\r
+\r
+  For example, if you distribute copies of the library, whether gratis\r
+or for a fee, you must give the recipients all the rights that we gave\r
+you.  You must make sure that they, too, receive or can get the source\r
+code.  If you link other code with the library, you must provide\r
+complete object files to the recipients, so that they can relink them\r
+with the library after making changes to the library and recompiling\r
+it.  And you must show them these terms so they know their rights.\r
+\r
+  We protect your rights with a two-step method: (1) we copyright the\r
+library, and (2) we offer you this license, which gives you legal\r
+permission to copy, distribute and/or modify the library.\r
+\r
+  To protect each distributor, we want to make it very clear that\r
+there is no warranty for the free library.  Also, if the library is\r
+modified by someone else and passed on, the recipients should know\r
+that what they have is not the original version, so that the original\r
+author's reputation will not be affected by problems that might be\r
+introduced by others.\r
+\r
+  Finally, software patents pose a constant threat to the existence of\r
+any free program.  We wish to make sure that a company cannot\r
+effectively restrict the users of a free program by obtaining a\r
+restrictive license from a patent holder.  Therefore, we insist that\r
+any patent license obtained for a version of the library must be\r
+consistent with the full freedom of use specified in this license.\r
+\r
+  Most GNU software, including some libraries, is covered by the\r
+ordinary GNU General Public License.  This license, the GNU Lesser\r
+General Public License, applies to certain designated libraries, and\r
+is quite different from the ordinary General Public License.  We use\r
+this license for certain libraries in order to permit linking those\r
+libraries into non-free programs.\r
+\r
+  When a program is linked with a library, whether statically or using\r
+a shared library, the combination of the two is legally speaking a\r
+combined work, a derivative of the original library.  The ordinary\r
+General Public License therefore permits such linking only if the\r
+entire combination fits its criteria of freedom.  The Lesser General\r
+Public License permits more lax criteria for linking other code with\r
+the library.\r
+\r
+  We call this license the "Lesser" General Public License because it\r
+does Less to protect the user's freedom than the ordinary General\r
+Public License.  It also provides other free software developers Less\r
+of an advantage over competing non-free programs.  These disadvantages\r
+are the reason we use the ordinary General Public License for many\r
+libraries.  However, the Lesser license provides advantages in certain\r
+special circumstances.\r
+\r
+  For example, on rare occasions, there may be a special need to\r
+encourage the widest possible use of a certain library, so that it becomes\r
+a de-facto standard.  To achieve this, non-free programs must be\r
+allowed to use the library.  A more frequent case is that a free\r
+library does the same job as widely used non-free libraries.  In this\r
+case, there is little to gain by limiting the free library to free\r
+software only, so we use the Lesser General Public License.\r
+\r
+  In other cases, permission to use a particular library in non-free\r
+programs enables a greater number of people to use a large body of\r
+free software.  For example, permission to use the GNU C Library in\r
+non-free programs enables many more people to use the whole GNU\r
+operating system, as well as its variant, the GNU/Linux operating\r
+system.\r
+\r
+  Although the Lesser General Public License is Less protective of the\r
+users' freedom, it does ensure that the user of a program that is\r
+linked with the Library has the freedom and the wherewithal to run\r
+that program using a modified version of the Library.\r
+\r
+  The precise terms and conditions for copying, distribution and\r
+modification follow.  Pay close attention to the difference between a\r
+"work based on the library" and a "work that uses the library".  The\r
+former contains code derived from the library, whereas the latter must\r
+be combined with the library in order to run.\r
+\r
+GNU LESSER GENERAL PUBLIC LICENSE\r
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION\r
+\r
+  0. This License Agreement applies to any software library or other\r
+program which contains a notice placed by the copyright holder or\r
+other authorized party saying it may be distributed under the terms of\r
+this Lesser General Public License (also called "this License").\r
+Each licensee is addressed as "you".\r
+\r
+  A "library" means a collection of software functions and/or data\r
+prepared so as to be conveniently linked with application programs\r
+(which use some of those functions and data) to form executables.\r
+\r
+  The "Library", below, refers to any such software library or work\r
+which has been distributed under these terms.  A "work based on the\r
+Library" means either the Library or any derivative work under\r
+copyright law: that is to say, a work containing the Library or a\r
+portion of it, either verbatim or with modifications and/or translated\r
+straightforwardly into another language.  (Hereinafter, translation is\r
+included without limitation in the term "modification".)\r
+\r
+  "Source code" for a work means the preferred form of the work for\r
+making modifications to it.  For a library, complete source code means\r
+all the source code for all modules it contains, plus any associated\r
+interface definition files, plus the scripts used to control compilation\r
+and installation of the library.\r
+\r
+  Activities other than copying, distribution and modification are not\r
+covered by this License; they are outside its scope.  The act of\r
+running a program using the Library is not restricted, and output from\r
+such a program is covered only if its contents constitute a work based\r
+on the Library (independent of the use of the Library in a tool for\r
+writing it).  Whether that is true depends on what the Library does\r
+and what the program that uses the Library does.\r
+\r
+  1. You may copy and distribute verbatim copies of the Library's\r
+complete source code as you receive it, in any medium, provided that\r
+you conspicuously and appropriately publish on each copy an\r
+appropriate copyright notice and disclaimer of warranty; keep intact\r
+all the notices that refer to this License and to the absence of any\r
+warranty; and distribute a copy of this License along with the\r
+Library.\r
+\r
+  You may charge a fee for the physical act of transferring a copy,\r
+and you may at your option offer warranty protection in exchange for a\r
+fee.\r
+\r
+  2. You may modify your copy or copies of the Library or any portion\r
+of it, thus forming a work based on the Library, and copy and\r
+distribute such modifications or work under the terms of Section 1\r
+above, provided that you also meet all of these conditions:\r
+\r
+    a) The modified work must itself be a software library.\r
+\r
+    b) You must cause the files modified to carry prominent notices\r
+    stating that you changed the files and the date of any change.\r
+\r
+    c) You must cause the whole of the work to be licensed at no\r
+    charge to all third parties under the terms of this License.\r
+\r
+    d) If a facility in the modified Library refers to a function or a\r
+    table of data to be supplied by an application program that uses\r
+    the facility, other than as an argument passed when the facility\r
+    is invoked, then you must make a good faith effort to ensure that,\r
+    in the event an application does not supply such function or\r
+    table, the facility still operates, and performs whatever part of\r
+    its purpose remains meaningful.\r
+\r
+    (For example, a function in a library to compute square roots has\r
+    a purpose that is entirely well-defined independent of the\r
+    application.  Therefore, Subsection 2d requires that any\r
+    application-supplied function or table used by this function must\r
+    be optional: if the application does not supply it, the square\r
+    root function must still compute square roots.)\r
+\r
+These requirements apply to the modified work as a whole.  If\r
+identifiable sections of that work are not derived from the Library,\r
+and can be reasonably considered independent and separate works in\r
+themselves, then this License, and its terms, do not apply to those\r
+sections when you distribute them as separate works.  But when you\r
+distribute the same sections as part of a whole which is a work based\r
+on the Library, the distribution of the whole must be on the terms of\r
+this License, whose permissions for other licensees extend to the\r
+entire whole, and thus to each and every part regardless of who wrote\r
+it.\r
+\r
+Thus, it is not the intent of this section to claim rights or contest\r
+your rights to work written entirely by you; rather, the intent is to\r
+exercise the right to control the distribution of derivative or\r
+collective works based on the Library.\r
+\r
+In addition, mere aggregation of another work not based on the Library\r
+with the Library (or with a work based on the Library) on a volume of\r
+a storage or distribution medium does not bring the other work under\r
+the scope of this License.\r
+\r
+  3. You may opt to apply the terms of the ordinary GNU General Public\r
+License instead of this License to a given copy of the Library.  To do\r
+this, you must alter all the notices that refer to this License, so\r
+that they refer to the ordinary GNU General Public License, version 2,\r
+instead of to this License.  (If a newer version than version 2 of the\r
+ordinary GNU General Public License has appeared, then you can specify\r
+that version instead if you wish.)  Do not make any other change in\r
+these notices.\r
+\r
+  Once this change is made in a given copy, it is irreversible for\r
+that copy, so the ordinary GNU General Public License applies to all\r
+subsequent copies and derivative works made from that copy.\r
+\r
+  This option is useful when you wish to copy part of the code of\r
+the Library into a program that is not a library.\r
+\r
+  4. You may copy and distribute the Library (or a portion or\r
+derivative of it, under Section 2) in object code or executable form\r
+under the terms of Sections 1 and 2 above provided that you accompany\r
+it with the complete corresponding machine-readable source code, which\r
+must be distributed under the terms of Sections 1 and 2 above on a\r
+medium customarily used for software interchange.\r
+\r
+  If distribution of object code is made by offering access to copy\r
+from a designated place, then offering equivalent access to copy the\r
+source code from the same place satisfies the requirement to\r
+distribute the source code, even though third parties are not\r
+compelled to copy the source along with the object code.\r
+\r
+  5. A program that contains no derivative of any portion of the\r
+Library, but is designed to work with the Library by being compiled or\r
+linked with it, is called a "work that uses the Library".  Such a\r
+work, in isolation, is not a derivative work of the Library, and\r
+therefore falls outside the scope of this License.\r
+\r
+  However, linking a "work that uses the Library" with the Library\r
+creates an executable that is a derivative of the Library (because it\r
+contains portions of the Library), rather than a "work that uses the\r
+library".  The executable is therefore covered by this License.\r
+Section 6 states terms for distribution of such executables.\r
+\r
+  When a "work that uses the Library" uses material from a header file\r
+that is part of the Library, the object code for the work may be a\r
+derivative work of the Library even though the source code is not.\r
+Whether this is true is especially significant if the work can be\r
+linked without the Library, or if the work is itself a library.  The\r
+threshold for this to be true is not precisely defined by law.\r
+\r
+  If such an object file uses only numerical parameters, data\r
+structure layouts and accessors, and small macros and small inline\r
+functions (ten lines or less in length), then the use of the object\r
+file is unrestricted, regardless of whether it is legally a derivative\r
+work.  (Executables containing this object code plus portions of the\r
+Library will still fall under Section 6.)\r
+\r
+  Otherwise, if the work is a derivative of the Library, you may\r
+distribute the object code for the work under the terms of Section 6.\r
+Any executables containing that work also fall under Section 6,\r
+whether or not they are linked directly with the Library itself.\r
+\r
+  6. As an exception to the Sections above, you may also combine or\r
+link a "work that uses the Library" with the Library to produce a\r
+work containing portions of the Library, and distribute that work\r
+under terms of your choice, provided that the terms permit\r
+modification of the work for the customer's own use and reverse\r
+engineering for debugging such modifications.\r
+\r
+  You must give prominent notice with each copy of the work that the\r
+Library is used in it and that the Library and its use are covered by\r
+this License.  You must supply a copy of this License.  If the work\r
+during execution displays copyright notices, you must include the\r
+copyright notice for the Library among them, as well as a reference\r
+directing the user to the copy of this License.  Also, you must do one\r
+of these things:\r
+\r
+    a) Accompany the work with the complete corresponding\r
+    machine-readable source code for the Library including whatever\r
+    changes were used in the work (which must be distributed under\r
+    Sections 1 and 2 above); and, if the work is an executable linked\r
+    with the Library, with the complete machine-readable "work that\r
+    uses the Library", as object code and/or source code, so that the\r
+    user can modify the Library and then relink to produce a modified\r
+    executable containing the modified Library.  (It is understood\r
+    that the user who changes the contents of definitions files in the\r
+    Library will not necessarily be able to recompile the application\r
+    to use the modified definitions.)\r
+\r
+    b) Use a suitable shared library mechanism for linking with the\r
+    Library.  A suitable mechanism is one that (1) uses at run time a\r
+    copy of the library already present on the user's computer system,\r
+    rather than copying library functions into the executable, and (2)\r
+    will operate properly with a modified version of the library, if\r
+    the user installs one, as long as the modified version is\r
+    interface-compatible with the version that the work was made with.\r
+\r
+    c) Accompany the work with a written offer, valid for at\r
+    least three years, to give the same user the materials\r
+    specified in Subsection 6a, above, for a charge no more\r
+    than the cost of performing this distribution.\r
+\r
+    d) If distribution of the work is made by offering access to copy\r
+    from a designated place, offer equivalent access to copy the above\r
+    specified materials from the same place.\r
+\r
+    e) Verify that the user has already received a copy of these\r
+    materials or that you have already sent this user a copy.\r
+\r
+  For an executable, the required form of the "work that uses the\r
+Library" must include any data and utility programs needed for\r
+reproducing the executable from it.  However, as a special exception,\r
+the materials to be distributed need not include anything that is\r
+normally distributed (in either source or binary form) with the major\r
+components (compiler, kernel, and so on) of the operating system on\r
+which the executable runs, unless that component itself accompanies\r
+the executable.\r
+\r
+  It may happen that this requirement contradicts the license\r
+restrictions of other proprietary libraries that do not normally\r
+accompany the operating system.  Such a contradiction means you cannot\r
+use both them and the Library together in an executable that you\r
+distribute.\r
+\r
+  7. You may place library facilities that are a work based on the\r
+Library side-by-side in a single library together with other library\r
+facilities not covered by this License, and distribute such a combined\r
+library, provided that the separate distribution of the work based on\r
+the Library and of the other library facilities is otherwise\r
+permitted, and provided that you do these two things:\r
+\r
+    a) Accompany the combined library with a copy of the same work\r
+    based on the Library, uncombined with any other library\r
+    facilities.  This must be distributed under the terms of the\r
+    Sections above.\r
+\r
+    b) Give prominent notice with the combined library of the fact\r
+    that part of it is a work based on the Library, and explaining\r
+    where to find the accompanying uncombined form of the same work.\r
+\r
+  8. You may not copy, modify, sublicense, link with, or distribute\r
+the Library except as expressly provided under this License.  Any\r
+attempt otherwise to copy, modify, sublicense, link with, or\r
+distribute the Library is void, and will automatically terminate your\r
+rights under this License.  However, parties who have received copies,\r
+or rights, from you under this License will not have their licenses\r
+terminated so long as such parties remain in full compliance.\r
+\r
+  9. You are not required to accept this License, since you have not\r
+signed it.  However, nothing else grants you permission to modify or\r
+distribute the Library or its derivative works.  These actions are\r
+prohibited by law if you do not accept this License.  Therefore, by\r
+modifying or distributing the Library (or any work based on the\r
+Library), you indicate your acceptance of this License to do so, and\r
+all its terms and conditions for copying, distributing or modifying\r
+the Library or works based on it.\r
+\r
+  10. Each time you redistribute the Library (or any work based on the\r
+Library), the recipient automatically receives a license from the\r
+original licensor to copy, distribute, link with or modify the Library\r
+subject to these terms and conditions.  You may not impose any further\r
+restrictions on the recipients' exercise of the rights granted herein.\r
+You are not responsible for enforcing compliance by third parties with\r
+this License.\r
+\r
+  11. If, as a consequence of a court judgment or allegation of patent\r
+infringement or for any other reason (not limited to patent issues),\r
+conditions are imposed on you (whether by court order, agreement or\r
+otherwise) that contradict the conditions of this License, they do not\r
+excuse you from the conditions of this License.  If you cannot\r
+distribute so as to satisfy simultaneously your obligations under this\r
+License and any other pertinent obligations, then as a consequence you\r
+may not distribute the Library at all.  For example, if a patent\r
+license would not permit royalty-free redistribution of the Library by\r
+all those who receive copies directly or indirectly through you, then\r
+the only way you could satisfy both it and this License would be to\r
+refrain entirely from distribution of the Library.\r
+\r
+If any portion of this section is held invalid or unenforceable under any\r
+particular circumstance, the balance of the section is intended to apply,\r
+and the section as a whole is intended to apply in other circumstances.\r
+\r
+It is not the purpose of this section to induce you to infringe any\r
+patents or other property right claims or to contest validity of any\r
+such claims; this section has the sole purpose of protecting the\r
+integrity of the free software distribution system which is\r
+implemented by public license practices.  Many people have made\r
+generous contributions to the wide range of software distributed\r
+through that system in reliance on consistent application of that\r
+system; it is up to the author/donor to decide if he or she is willing\r
+to distribute software through any other system and a licensee cannot\r
+impose that choice.\r
+\r
+This section is intended to make thoroughly clear what is believed to\r
+be a consequence of the rest of this License.\r
+\r
+  12. If the distribution and/or use of the Library is restricted in\r
+certain countries either by patents or by copyrighted interfaces, the\r
+original copyright holder who places the Library under this License may add\r
+an explicit geographical distribution limitation excluding those countries,\r
+so that distribution is permitted only in or among countries not thus\r
+excluded.  In such case, this License incorporates the limitation as if\r
+written in the body of this License.\r
+\r
+  13. The Free Software Foundation may publish revised and/or new\r
+versions of the Lesser General Public License from time to time.\r
+Such new versions will be similar in spirit to the present version,\r
+but may differ in detail to address new problems or concerns.\r
+\r
+Each version is given a distinguishing version number.  If the Library\r
+specifies a version number of this License which applies to it and\r
+"any later version", you have the option of following the terms and\r
+conditions either of that version or of any later version published by\r
+the Free Software Foundation.  If the Library does not specify a\r
+license version number, you may choose any version ever published by\r
+the Free Software Foundation.\r
+\r
+  14. If you wish to incorporate parts of the Library into other free\r
+programs whose distribution conditions are incompatible with these,\r
+write to the author to ask for permission.  For software which is\r
+copyrighted by the Free Software Foundation, write to the Free\r
+Software Foundation; we sometimes make exceptions for this.  Our\r
+decision will be guided by the two goals of preserving the free status\r
+of all derivatives of our free software and of promoting the sharing\r
+and reuse of software generally.\r
+\r
+NO WARRANTY\r
+\r
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO\r
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.\r
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR\r
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY\r
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE\r
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR\r
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE\r
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME\r
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.\r
+\r
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN\r
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY\r
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU\r
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR\r
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE\r
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING\r
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A\r
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF\r
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH\r
+DAMAGES.\r
+\r
+END OF TERMS AND CONDITIONS\r
+```\r
+\r
+Appendix C: The MPL License\r
+---------------------------\r
+\r
+```\r
+MOZILLA PUBLIC LICENSE\r
+Version 1.1\r
+\r
+1. Definitions.\r
+\r
+     1.0.1. "Commercial Use" means distribution or otherwise making the\r
+     Covered Code available to a third party.\r
+\r
+     1.1. "Contributor" means each entity that creates or contributes to\r
+     the creation of Modifications.\r
+\r
+     1.2. "Contributor Version" means the combination of the Original\r
+     Code, prior Modifications used by a Contributor, and the Modifications\r
+     made by that particular Contributor.\r
+\r
+     1.3. "Covered Code" means the Original Code or Modifications or the\r
+     combination of the Original Code and Modifications, in each case\r
+     including portions thereof.\r
+\r
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally\r
+     accepted in the software development community for the electronic\r
+     transfer of data.\r
+\r
+     1.5. "Executable" means Covered Code in any form other than Source\r
+     Code.\r
+\r
+     1.6. "Initial Developer" means the individual or entity identified\r
+     as the Initial Developer in the Source Code notice required by Exhibit\r
+     A.\r
+\r
+     1.7. "Larger Work" means a work which combines Covered Code or\r
+     portions thereof with code not governed by the terms of this License.\r
+\r
+     1.8. "License" means this document.\r
+\r
+     1.8.1. "Licensable" means having the right to grant, to the maximum\r
+     extent possible, whether at the time of the initial grant or\r
+     subsequently acquired, any and all of the rights conveyed herein.\r
+\r
+     1.9. "Modifications" means any addition to or deletion from the\r
+     substance or structure of either the Original Code or any previous\r
+     Modifications. When Covered Code is released as a series of files, a\r
+     Modification is:\r
+          A. Any addition to or deletion from the contents of a file\r
+          containing Original Code or previous Modifications.\r
+\r
+          B. Any new file that contains any part of the Original Code or\r
+          previous Modifications.\r
+\r
+     1.10. "Original Code" means Source Code of computer software code\r
+     which is described in the Source Code notice required by Exhibit A as\r
+     Original Code, and which, at the time of its release under this\r
+     License is not already Covered Code governed by this License.\r
+\r
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or\r
+     hereafter acquired, including without limitation,  method, process,\r
+     and apparatus claims, in any patent Licensable by grantor.\r
+\r
+     1.11. "Source Code" means the preferred form of the Covered Code for\r
+     making modifications to it, including all modules it contains, plus\r
+     any associated interface definition files, scripts used to control\r
+     compilation and installation of an Executable, or source code\r
+     differential comparisons against either the Original Code or another\r
+     well known, available Covered Code of the Contributor's choice. The\r
+     Source Code can be in a compressed or archival form, provided the\r
+     appropriate decompression or de-archiving software is widely available\r
+     for no charge.\r
+\r
+     1.12. "You" (or "Your")  means an individual or a legal entity\r
+     exercising rights under, and complying with all of the terms of, this\r
+     License or a future version of this License issued under Section 6.1.\r
+     For legal entities, "You" includes any entity which controls, is\r
+     controlled by, or is under common control with You. For purposes of\r
+     this definition, "control" means (a) the power, direct or indirect,\r
+     to cause the direction or management of such entity, whether by\r
+     contract or otherwise, or (b) ownership of more than fifty percent\r
+     (50%) of the outstanding shares or beneficial ownership of such\r
+     entity.\r
+\r
+2. Source Code License.\r
+\r
+     2.1. The Initial Developer Grant.\r
+     The Initial Developer hereby grants You a world-wide, royalty-free,\r
+     non-exclusive license, subject to third party intellectual property\r
+     claims:\r
+          (a)  under intellectual property rights (other than patent or\r
+          trademark) Licensable by Initial Developer to use, reproduce,\r
+          modify, display, perform, sublicense and distribute the Original\r
+          Code (or portions thereof) with or without Modifications, and/or\r
+          as part of a Larger Work; and\r
+\r
+          (b) under Patents Claims infringed by the making, using or\r
+          selling of Original Code, to make, have made, use, practice,\r
+          sell, and offer for sale, and/or otherwise dispose of the\r
+          Original Code (or portions thereof).\r
+\r
+          (c) the licenses granted in this Section 2.1(a) and (b) are\r
+          effective on the date Initial Developer first distributes\r
+          Original Code under the terms of this License.\r
+\r
+          (d) Notwithstanding Section 2.1(b) above, no patent license is\r
+          granted: 1) for code that You delete from the Original Code; 2)\r
+          separate from the Original Code;  or 3) for infringements caused\r
+          by: i) the modification of the Original Code or ii) the\r
+          combination of the Original Code with other software or devices.\r
+\r
+     2.2. Contributor Grant.\r
+     Subject to third party intellectual property claims, each Contributor\r
+     hereby grants You a world-wide, royalty-free, non-exclusive license\r
+\r
+          (a)  under intellectual property rights (other than patent or\r
+          trademark) Licensable by Contributor, to use, reproduce, modify,\r
+          display, perform, sublicense and distribute the Modifications\r
+          created by such Contributor (or portions thereof) either on an\r
+          unmodified basis, with other Modifications, as Covered Code\r
+          and/or as part of a Larger Work; and\r
+\r
+          (b) under Patent Claims infringed by the making, using, or\r
+          selling of  Modifications made by that Contributor either alone\r
+          and/or in combination with its Contributor Version (or portions\r
+          of such combination), to make, use, sell, offer for sale, have\r
+          made, and/or otherwise dispose of: 1) Modifications made by that\r
+          Contributor (or portions thereof); and 2) the combination of\r
+          Modifications made by that Contributor with its Contributor\r
+          Version (or portions of such combination).\r
+\r
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are\r
+          effective on the date Contributor first makes Commercial Use of\r
+          the Covered Code.\r
+\r
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is\r
+          granted: 1) for any code that Contributor has deleted from the\r
+          Contributor Version; 2)  separate from the Contributor Version;\r
+          3)  for infringements caused by: i) third party modifications of\r
+          Contributor Version or ii)  the combination of Modifications made\r
+          by that Contributor with other software  (except as part of the\r
+          Contributor Version) or other devices; or 4) under Patent Claims\r
+          infringed by Covered Code in the absence of Modifications made by\r
+          that Contributor.\r
+\r
+3. Distribution Obligations.\r
+\r
+     3.1. Application of License.\r
+     The Modifications which You create or to which You contribute are\r
+     governed by the terms of this License, including without limitation\r
+     Section 2.2. The Source Code version of Covered Code may be\r
+     distributed only under the terms of this License or a future version\r
+     of this License released under Section 6.1, and You must include a\r
+     copy of this License with every copy of the Source Code You\r
+     distribute. You may not offer or impose any terms on any Source Code\r
+     version that alters or restricts the applicable version of this\r
+     License or the recipients' rights hereunder. However, You may include\r
+     an additional document offering the additional rights described in\r
+     Section 3.5.\r
+\r
+     3.2. Availability of Source Code.\r
+     Any Modification which You create or to which You contribute must be\r
+     made available in Source Code form under the terms of this License\r
+     either on the same media as an Executable version or via an accepted\r
+     Electronic Distribution Mechanism to anyone to whom you made an\r
+     Executable version available; and if made available via Electronic\r
+     Distribution Mechanism, must remain available for at least twelve (12)\r
+     months after the date it initially became available, or at least six\r
+     (6) months after a subsequent version of that particular Modification\r
+     has been made available to such recipients. You are responsible for\r
+     ensuring that the Source Code version remains available even if the\r
+     Electronic Distribution Mechanism is maintained by a third party.\r
+\r
+     3.3. Description of Modifications.\r
+     You must cause all Covered Code to which You contribute to contain a\r
+     file documenting the changes You made to create that Covered Code and\r
+     the date of any change. You must include a prominent statement that\r
+     the Modification is derived, directly or indirectly, from Original\r
+     Code provided by the Initial Developer and including the name of the\r
+     Initial Developer in (a) the Source Code, and (b) in any notice in an\r
+     Executable version or related documentation in which You describe the\r
+     origin or ownership of the Covered Code.\r
+\r
+     3.4. Intellectual Property Matters\r
+          (a) Third Party Claims.\r
+          If Contributor has knowledge that a license under a third party's\r
+          intellectual property rights is required to exercise the rights\r
+          granted by such Contributor under Sections 2.1 or 2.2,\r
+          Contributor must include a text file with the Source Code\r
+          distribution titled "LEGAL" which describes the claim and the\r
+          party making the claim in sufficient detail that a recipient will\r
+          know whom to contact. If Contributor obtains such knowledge after\r
+          the Modification is made available as described in Section 3.2,\r
+          Contributor shall promptly modify the LEGAL file in all copies\r
+          Contributor makes available thereafter and shall take other steps\r
+          (such as notifying appropriate mailing lists or newsgroups)\r
+          reasonably calculated to inform those who received the Covered\r
+          Code that new knowledge has been obtained.\r
+\r
+          (b) Contributor APIs.\r
+          If Contributor's Modifications include an application programming\r
+          interface and Contributor has knowledge of patent licenses which\r
+          are reasonably necessary to implement that API, Contributor must\r
+          also include this information in the LEGAL file.\r
+\r
+               (c)    Representations.\r
+          Contributor represents that, except as disclosed pursuant to\r
+          Section 3.4(a) above, Contributor believes that Contributor's\r
+          Modifications are Contributor's original creation(s) and/or\r
+          Contributor has sufficient rights to grant the rights conveyed by\r
+          this License.\r
+\r
+     3.5. Required Notices.\r
+     You must duplicate the notice in Exhibit A in each file of the Source\r
+     Code.  If it is not possible to put such notice in a particular Source\r
+     Code file due to its structure, then You must include such notice in a\r
+     location (such as a relevant directory) where a user would be likely\r
+     to look for such a notice.  If You created one or more Modification(s)\r
+     You may add your name as a Contributor to the notice described in\r
+     Exhibit A.  You must also duplicate this License in any documentation\r
+     for the Source Code where You describe recipients' rights or ownership\r
+     rights relating to Covered Code.  You may choose to offer, and to\r
+     charge a fee for, warranty, support, indemnity or liability\r
+     obligations to one or more recipients of Covered Code. However, You\r
+     may do so only on Your own behalf, and not on behalf of the Initial\r
+     Developer or any Contributor. You must make it absolutely clear than\r
+     any such warranty, support, indemnity or liability obligation is\r
+     offered by You alone, and You hereby agree to indemnify the Initial\r
+     Developer and every Contributor for any liability incurred by the\r
+     Initial Developer or such Contributor as a result of warranty,\r
+     support, indemnity or liability terms You offer.\r
+\r
+     3.6. Distribution of Executable Versions.\r
+     You may distribute Covered Code in Executable form only if the\r
+     requirements of Section 3.1-3.5 have been met for that Covered Code,\r
+     and if You include a notice stating that the Source Code version of\r
+     the Covered Code is available under the terms of this License,\r
+     including a description of how and where You have fulfilled the\r
+     obligations of Section 3.2. The notice must be conspicuously included\r
+     in any notice in an Executable version, related documentation or\r
+     collateral in which You describe recipients' rights relating to the\r
+     Covered Code. You may distribute the Executable version of Covered\r
+     Code or ownership rights under a license of Your choice, which may\r
+     contain terms different from this License, provided that You are in\r
+     compliance with the terms of this License and that the license for the\r
+     Executable version does not attempt to limit or alter the recipient's\r
+     rights in the Source Code version from the rights set forth in this\r
+     License. If You distribute the Executable version under a different\r
+     license You must make it absolutely clear that any terms which differ\r
+     from this License are offered by You alone, not by the Initial\r
+     Developer or any Contributor. You hereby agree to indemnify the\r
+     Initial Developer and every Contributor for any liability incurred by\r
+     the Initial Developer or such Contributor as a result of any such\r
+     terms You offer.\r
+\r
+     3.7. Larger Works.\r
+     You may create a Larger Work by combining Covered Code with other code\r
+     not governed by the terms of this License and distribute the Larger\r
+     Work as a single product. In such a case, You must make sure the\r
+     requirements of this License are fulfilled for the Covered Code.\r
+\r
+4. Inability to Comply Due to Statute or Regulation.\r
+\r
+     If it is impossible for You to comply with any of the terms of this\r
+     License with respect to some or all of the Covered Code due to\r
+     statute, judicial order, or regulation then You must: (a) comply with\r
+     the terms of this License to the maximum extent possible; and (b)\r
+     describe the limitations and the code they affect. Such description\r
+     must be included in the LEGAL file described in Section 3.4 and must\r
+     be included with all distributions of the Source Code. Except to the\r
+     extent prohibited by statute or regulation, such description must be\r
+     sufficiently detailed for a recipient of ordinary skill to be able to\r
+     understand it.\r
+\r
+5. Application of this License.\r
+\r
+     This License applies to code to which the Initial Developer has\r
+     attached the notice in Exhibit A and to related Covered Code.\r
+\r
+6. Versions of the License.\r
+\r
+     6.1. New Versions.\r
+     Netscape Communications Corporation ("Netscape") may publish revised\r
+     and/or new versions of the License from time to time. Each version\r
+     will be given a distinguishing version number.\r
+\r
+     6.2. Effect of New Versions.\r
+     Once Covered Code has been published under a particular version of the\r
+     License, You may always continue to use it under the terms of that\r
+     version. You may also choose to use such Covered Code under the terms\r
+     of any subsequent version of the License published by Netscape. No one\r
+     other than Netscape has the right to modify the terms applicable to\r
+     Covered Code created under this License.\r
+\r
+     6.3. Derivative Works.\r
+     If You create or use a modified version of this License (which you may\r
+     only do in order to apply it to code which is not already Covered Code\r
+     governed by this License), You must (a) rename Your license so that\r
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",\r
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your\r
+     license (except to note that your license differs from this License)\r
+     and (b) otherwise make it clear that Your version of the license\r
+     contains terms which differ from the Mozilla Public License and\r
+     Netscape Public License. (Filling in the name of the Initial\r
+     Developer, Original Code or Contributor in the notice described in\r
+     Exhibit A shall not of themselves be deemed to be modifications of\r
+     this License.)\r
+\r
+7. DISCLAIMER OF WARRANTY.\r
+\r
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,\r
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,\r
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF\r
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.\r
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE\r
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,\r
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE\r
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER\r
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF\r
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.\r
+\r
+8. TERMINATION.\r
+\r
+     8.1.  This License and the rights granted hereunder will terminate\r
+     automatically if You fail to comply with terms herein and fail to cure\r
+     such breach within 30 days of becoming aware of the breach. All\r
+     sublicenses to the Covered Code which are properly granted shall\r
+     survive any termination of this License. Provisions which, by their\r
+     nature, must remain in effect beyond the termination of this License\r
+     shall survive.\r
+\r
+     8.2.  If You initiate litigation by asserting a patent infringement\r
+     claim (excluding declatory judgment actions) against Initial Developer\r
+     or a Contributor (the Initial Developer or Contributor against whom\r
+     You file such action is referred to as "Participant")  alleging that:\r
+\r
+     (a)  such Participant's Contributor Version directly or indirectly\r
+     infringes any patent, then any and all rights granted by such\r
+     Participant to You under Sections 2.1 and/or 2.2 of this License\r
+     shall, upon 60 days notice from Participant terminate prospectively,\r
+     unless if within 60 days after receipt of notice You either: (i)\r
+     agree in writing to pay Participant a mutually agreeable reasonable\r
+     royalty for Your past and future use of Modifications made by such\r
+     Participant, or (ii) withdraw Your litigation claim with respect to\r
+     the Contributor Version against such Participant.  If within 60 days\r
+     of notice, a reasonable royalty and payment arrangement are not\r
+     mutually agreed upon in writing by the parties or the litigation claim\r
+     is not withdrawn, the rights granted by Participant to You under\r
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of\r
+     the 60 day notice period specified above.\r
+\r
+     (b)  any software, hardware, or device, other than such Participant's\r
+     Contributor Version, directly or indirectly infringes any patent, then\r
+     any rights granted to You by such Participant under Sections 2.1(b)\r
+     and 2.2(b) are revoked effective as of the date You first made, used,\r
+     sold, distributed, or had made, Modifications made by that\r
+     Participant.\r
+\r
+     8.3.  If You assert a patent infringement claim against Participant\r
+     alleging that such Participant's Contributor Version directly or\r
+     indirectly infringes any patent where such claim is resolved (such as\r
+     by license or settlement) prior to the initiation of patent\r
+     infringement litigation, then the reasonable value of the licenses\r
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken\r
+     into account in determining the amount or value of any payment or\r
+     license.\r
+\r
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,\r
+     all end user license agreements (excluding distributors and resellers)\r
+     which have been validly granted by You or any distributor hereunder\r
+     prior to termination shall survive termination.\r
+\r
+9. LIMITATION OF LIABILITY.\r
+\r
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT\r
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL\r
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,\r
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR\r
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY\r
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,\r
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER\r
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN\r
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF\r
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY\r
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW\r
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE\r
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO\r
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.\r
+\r
+10. U.S. GOVERNMENT END USERS.\r
+\r
+     The Covered Code is a "commercial item," as that term is defined in\r
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer\r
+     software" and "commercial computer software documentation," as such\r
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48\r
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),\r
+     all U.S. Government End Users acquire Covered Code with only those\r
+     rights set forth herein.\r
+\r
+11. MISCELLANEOUS.\r
+\r
+     This License represents the complete agreement concerning subject\r
+     matter hereof. If any provision of this License is held to be\r
+     unenforceable, such provision shall be reformed only to the extent\r
+     necessary to make it enforceable. This License shall be governed by\r
+     California law provisions (except to the extent applicable law, if\r
+     any, provides otherwise), excluding its conflict-of-law provisions.\r
+     With respect to disputes in which at least one party is a citizen of,\r
+     or an entity chartered or registered to do business in the United\r
+     States of America, any litigation relating to this License shall be\r
+     subject to the jurisdiction of the Federal Courts of the Northern\r
+     District of California, with venue lying in Santa Clara County,\r
+     California, with the losing party responsible for costs, including\r
+     without limitation, court costs and reasonable attorneys' fees and\r
+     expenses. The application of the United Nations Convention on\r
+     Contracts for the International Sale of Goods is expressly excluded.\r
+     Any law or regulation which provides that the language of a contract\r
+     shall be construed against the drafter shall not apply to this\r
+     License.\r
+\r
+12. RESPONSIBILITY FOR CLAIMS.\r
+\r
+     As between Initial Developer and the Contributors, each party is\r
+     responsible for claims and damages arising, directly or indirectly,\r
+     out of its utilization of rights under this License and You agree to\r
+     work with Initial Developer and Contributors to distribute such\r
+     responsibility on an equitable basis. Nothing herein is intended or\r
+     shall be deemed to constitute any admission of liability.\r
+\r
+13. MULTIPLE-LICENSED CODE.\r
+\r
+     Initial Developer may designate portions of the Covered Code as\r
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial\r
+     Developer permits you to utilize portions of the Covered Code under\r
+     Your choice of the NPL or the alternative licenses, if any, specified\r
+     by the Initial Developer in the file described in Exhibit A.\r
+\r
+EXHIBIT A -Mozilla Public License.\r
+\r
+     ``The contents of this file are subject to the Mozilla Public License\r
+     Version 1.1 (the "License"); you may not use this file except in\r
+     compliance with the License. You may obtain a copy of the License at\r
+     http://www.mozilla.org/MPL/\r
+\r
+     Software distributed under the License is distributed on an "AS IS"\r
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the\r
+     License for the specific language governing rights and limitations\r
+     under the License.\r
+\r
+     The Original Code is ______________________________________.\r
+\r
+     The Initial Developer of the Original Code is ________________________.\r
+     Portions created by ______________________ are Copyright (C) ______\r
+     _______________________. All Rights Reserved.\r
+\r
+     Contributor(s): ______________________________________.\r
+\r
+     Alternatively, the contents of this file may be used under the terms\r
+     of the _____ license (the  "[___] License"), in which case the\r
+     provisions of [______] License are applicable instead of those\r
+     above.  If you wish to allow use of your version of this file only\r
+     under the terms of the [____] License and not to allow others to use\r
+     your version of this file under the MPL, indicate your decision by\r
+     deleting  the provisions above and replace  them with the notice and\r
+     other provisions required by the [___] License.  If you do not delete\r
+     the provisions above, a recipient may use your version of this file\r
+     under either the MPL or the [___] License."\r
+\r
+     [NOTE: The text of this Exhibit A may differ slightly from the text of\r
+     the notices in the Source Code files of the Original Code. You should\r
+     use the text of this Exhibit A rather than the text found in the\r
+     Original Code Source Code for Your Modifications.]\r
+```\r
+\r
+Appendix D: The MIT License\r
+---------------------------\r
+\r
+```\r
+The MIT License (MIT)\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in\r
+all copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
+THE SOFTWARE.\r
+```\r
+\r
+Appendix E: The SIL Open Font License Version 1.1\r
+---------------------------------------------\r
+\r
+```\r
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007\r
+-----------------------------------------------------------\r
+\r
+PREAMBLE\r
+The goals of the Open Font License (OFL) are to stimulate worldwide\r
+development of collaborative font projects, to support the font creation\r
+efforts of academic and linguistic communities, and to provide a free and\r
+open framework in which fonts may be shared and improved in partnership\r
+with others.\r
+\r
+The OFL allows the licensed fonts to be used, studied, modified and\r
+redistributed freely as long as they are not sold by themselves. The\r
+fonts, including any derivative works, can be bundled, embedded,\r
+redistributed and/or sold with any software provided that any reserved\r
+names are not used by derivative works. The fonts and derivatives,\r
+however, cannot be released under any other type of license. The\r
+requirement for fonts to remain under this license does not apply\r
+to any document created using the fonts or their derivatives.\r
+\r
+DEFINITIONS\r
+"Font Software" refers to the set of files released by the Copyright\r
+Holder(s) under this license and clearly marked as such. This may\r
+include source files, build scripts and documentation.\r
+\r
+"Reserved Font Name" refers to any names specified as such after the\r
+copyright statement(s).\r
+\r
+"Original Version" refers to the collection of Font Software components as\r
+distributed by the Copyright Holder(s).\r
+\r
+"Modified Version" refers to any derivative made by adding to, deleting,\r
+or substituting -- in part or in whole -- any of the components of the\r
+Original Version, by changing formats or by porting the Font Software to a\r
+new environment.\r
+\r
+"Author" refers to any designer, engineer, programmer, technical\r
+writer or other person who contributed to the Font Software.\r
+\r
+PERMISSION & CONDITIONS\r
+Permission is hereby granted, free of charge, to any person obtaining\r
+a copy of the Font Software, to use, study, copy, merge, embed, modify,\r
+redistribute, and sell modified and unmodified copies of the Font\r
+Software, subject to the following conditions:\r
+\r
+1) Neither the Font Software nor any of its individual components,\r
+in Original or Modified Versions, may be sold by itself.\r
+\r
+2) Original or Modified Versions of the Font Software may be bundled,\r
+redistributed and/or sold with any software, provided that each copy\r
+contains the above copyright notice and this license. These can be\r
+included either as stand-alone text files, human-readable headers or\r
+in the appropriate machine-readable metadata fields within text or\r
+binary files as long as those fields can be easily viewed by the user.\r
+\r
+3) No Modified Version of the Font Software may use the Reserved Font\r
+Name(s) unless explicit written permission is granted by the corresponding\r
+Copyright Holder. This restriction only applies to the primary font name as\r
+presented to the users.\r
+\r
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font\r
+Software shall not be used to promote, endorse or advertise any\r
+Modified Version, except to acknowledge the contribution(s) of the\r
+Copyright Holder(s) and the Author(s) or with their explicit written\r
+permission.\r
+\r
+5) The Font Software, modified or unmodified, in part or in whole,\r
+must be distributed entirely under this license, and must not be\r
+distributed under any other license. The requirement for fonts to\r
+remain under this license does not apply to any document created\r
+using the Font Software.\r
+\r
+TERMINATION\r
+This license becomes null and void if any of the above conditions are\r
+not met.\r
+\r
+DISCLAIMER\r
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF\r
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT\r
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE\r
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\r
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL\r
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING\r
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM\r
+OTHER DEALINGS IN THE FONT SOFTWARE.\r
+```\r
+\r
+Appendix F: The BSD-3 License\r
+-----------------------------\r
+\r
+```\r
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:\r
+\r
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.\r
+\r
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.\r
+\r
+3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.\r
+\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+```\r
+\r
diff --git a/release/README.md b/release/README.md
new file mode 100644 (file)
index 0000000..d18d4a1
--- /dev/null
@@ -0,0 +1,39 @@
+CKEditor 4
+==========
+
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+http://ckeditor.com - See LICENSE.md for license information.
+
+CKEditor is a text editor to be used inside web pages. It's not a replacement
+for desktop text editors like Word or OpenOffice, but a component to be used as
+part of web applications and websites.
+
+## Documentation
+
+The full editor documentation is available online at the following address:
+http://docs.ckeditor.com
+
+## Installation
+
+Installing CKEditor is an easy task. Just follow these simple steps:
+
+ 1. **Download** the latest version from the CKEditor website:
+    http://ckeditor.com. You should have already completed this step, but be
+    sure you have the very latest version.
+ 2. **Extract** (decompress) the downloaded file into the root of your website.
+
+**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
+place the files in whichever you want though.
+
+## Checking Your Installation
+
+The editor comes with a few sample pages that can be used to verify that
+installation proceeded properly. Take a look at the `samples` directory.
+
+To test your installation, just call the following page at your website:
+
+       http://<your site>/<CKEditor installation path>/samples/index.html
+
+For example:
+
+       http://www.example.com/ckeditor/samples/index.html
diff --git a/release/adapters/jquery.js b/release/adapters/jquery.js
new file mode 100644 (file)
index 0000000..86cb458
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(a){if("undefined"==typeof a)throw Error("jQuery should be loaded before CKEditor jQuery adapter.");if("undefined"==typeof CKEDITOR)throw Error("CKEditor should be loaded before CKEditor jQuery adapter.");CKEDITOR.config.jqueryOverrideVal="undefined"==typeof CKEDITOR.config.jqueryOverrideVal?!0:CKEDITOR.config.jqueryOverrideVal;a.extend(a.fn,{ckeditorGet:function(){var a=this.eq(0).data("ckeditorInstance");if(!a)throw"CKEditor is not initialized yet, use ckeditor() with a callback.";return a},
+ckeditor:function(g,d){if(!CKEDITOR.env.isCompatible)throw Error("The environment is incompatible.");if(!a.isFunction(g)){var m=d;d=g;g=m}var k=[];d=d||{};this.each(function(){var b=a(this),c=b.data("ckeditorInstance"),f=b.data("_ckeditorInstanceLock"),h=this,l=new a.Deferred;k.push(l.promise());if(c&&!f)g&&g.apply(c,[this]),l.resolve();else if(f)c.once("instanceReady",function(){setTimeout(function(){c.element?(c.element.$==h&&g&&g.apply(c,[h]),l.resolve()):setTimeout(arguments.callee,100)},0)},
+null,null,9999);else{if(d.autoUpdateElement||"undefined"==typeof d.autoUpdateElement&&CKEDITOR.config.autoUpdateElement)d.autoUpdateElementJquery=!0;d.autoUpdateElement=!1;b.data("_ckeditorInstanceLock",!0);c=a(this).is("textarea")?CKEDITOR.replace(h,d):CKEDITOR.inline(h,d);b.data("ckeditorInstance",c);c.on("instanceReady",function(d){var e=d.editor;setTimeout(function(){if(e.element){d.removeListener();e.on("dataReady",function(){b.trigger("dataReady.ckeditor",[e])});e.on("setData",function(a){b.trigger("setData.ckeditor",
+[e,a.data])});e.on("getData",function(a){b.trigger("getData.ckeditor",[e,a.data])},999);e.on("destroy",function(){b.trigger("destroy.ckeditor",[e])});e.on("save",function(){a(h.form).submit();return!1},null,null,20);if(e.config.autoUpdateElementJquery&&b.is("textarea")&&a(h.form).length){var c=function(){b.ckeditor(function(){e.updateElement()})};a(h.form).submit(c);a(h.form).bind("form-pre-serialize",c);b.bind("destroy.ckeditor",function(){a(h.form).unbind("submit",c);a(h.form).unbind("form-pre-serialize",
+c)})}e.on("destroy",function(){b.removeData("ckeditorInstance")});b.removeData("_ckeditorInstanceLock");b.trigger("instanceReady.ckeditor",[e]);g&&g.apply(e,[h]);l.resolve()}else setTimeout(arguments.callee,100)},0)},null,null,9999)}});var f=new a.Deferred;this.promise=f.promise();a.when.apply(this,k).then(function(){f.resolve()});this.editor=this.eq(0).data("ckeditorInstance");return this}});CKEDITOR.config.jqueryOverrideVal&&(a.fn.val=CKEDITOR.tools.override(a.fn.val,function(g){return function(d){if(arguments.length){var m=
+this,k=[],f=this.each(function(){var b=a(this),c=b.data("ckeditorInstance");if(b.is("textarea")&&c){var f=new a.Deferred;c.setData(d,function(){f.resolve()});k.push(f.promise());return!0}return g.call(b,d)});if(k.length){var b=new a.Deferred;a.when.apply(this,k).done(function(){b.resolveWith(m)});return b.promise()}return f}var f=a(this).eq(0),c=f.data("ckeditorInstance");return f.is("textarea")&&c?c.getData():g.call(f)}}))})(window.jQuery);
\ No newline at end of file
diff --git a/release/ckeditor.js b/release/ckeditor.js
new file mode 100644 (file)
index 0000000..7588b1b
--- /dev/null
@@ -0,0 +1,1042 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(){if(window.CKEDITOR&&window.CKEDITOR.dom)return;window.CKEDITOR||(window.CKEDITOR=function(){var a=/(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i,d={timestamp:"H0CG",version:"4.6.2",revision:"20af917",rnd:Math.floor(900*Math.random())+100,_:{pending:[],basePathSrcPattern:a},status:"unloaded",basePath:function(){var b=window.CKEDITOR_BASEPATH||"";if(!b)for(var c=document.getElementsByTagName("script"),d=0;d<c.length;d++){var h=c[d].src.match(a);if(h){b=h[1];break}}-1==b.indexOf(":/")&&"//"!=b.slice(0,2)&&(b=0===b.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+
+b:location.href.match(/^[^\?]*\/(?:)/)[0]+b);if(!b)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return b}(),getUrl:function(a){-1==a.indexOf(":/")&&0!==a.indexOf("/")&&(a=this.basePath+a);this.timestamp&&"/"!=a.charAt(a.length-1)&&!/[&?]t=/.test(a)&&(a+=(0<=a.indexOf("?")?"\x26":"?")+"t\x3d"+this.timestamp);return a},domReady:function(){function a(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",
+a,!1),b()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",a),b())}catch(c){}}function b(){for(var a;a=c.shift();)a()}var c=[];return function(b){function d(){try{document.documentElement.doScroll("left")}catch(f){setTimeout(d,1);return}a()}c.push(b);"complete"===document.readyState&&setTimeout(a,1);if(1==c.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",a,!1),window.addEventListener("load",a,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",
+a);window.attachEvent("onload",a);b=!1;try{b=!window.frameElement}catch(r){}document.documentElement.doScroll&&b&&d()}}}()},b=window.CKEDITOR_GETURL;if(b){var c=d.getUrl;d.getUrl=function(a){return b.call(d,a)||c.call(d,a)}}return d}());
+CKEDITOR.event||(CKEDITOR.event=function(){},CKEDITOR.event.implementOn=function(a){var d=CKEDITOR.event.prototype,b;for(b in d)null==a[b]&&(a[b]=d[b])},CKEDITOR.event.prototype=function(){function a(a){var e=d(this);return e[a]||(e[a]=new b(a))}var d=function(a){a=a.getPrivate&&a.getPrivate()||a._||(a._={});return a.events||(a.events={})},b=function(a){this.name=a;this.listeners=[]};b.prototype={getListenerIndex:function(a){for(var b=0,d=this.listeners;b<d.length;b++)if(d[b].fn==a)return b;return-1}};
+return{define:function(b,d){var g=a.call(this,b);CKEDITOR.tools.extend(g,d,!0)},on:function(b,d,g,k,h){function p(a,f,B,h){a={name:b,sender:this,editor:a,data:f,listenerData:k,stop:B,cancel:h,removeListener:r};return!1===d.call(g,a)?!1:a.data}function r(){B.removeListener(b,d)}var f=a.call(this,b);if(0>f.getListenerIndex(d)){f=f.listeners;g||(g=this);isNaN(h)&&(h=10);var B=this;p.fn=d;p.priority=h;for(var u=f.length-1;0<=u;u--)if(f[u].priority<=h)return f.splice(u+1,0,p),{removeListener:r};f.unshift(p)}return{removeListener:r}},
+once:function(){var a=Array.prototype.slice.call(arguments),b=a[1];a[1]=function(a){a.removeListener();return b.apply(this,arguments)};return this.on.apply(this,a)},capture:function(){CKEDITOR.event.useCapture=1;var a=this.on.apply(this,arguments);CKEDITOR.event.useCapture=0;return a},fire:function(){var a=0,b=function(){a=1},g=0,k=function(){g=1};return function(h,p,r){var f=d(this)[h];h=a;var B=g;a=g=0;if(f){var u=f.listeners;if(u.length)for(var u=u.slice(0),z,y=0;y<u.length;y++){if(f.errorProof)try{z=
+u[y].call(this,r,p,b,k)}catch(m){}else z=u[y].call(this,r,p,b,k);!1===z?g=1:"undefined"!=typeof z&&(p=z);if(a||g)break}}p=g?!1:"undefined"==typeof p?!0:p;a=h;g=B;return p}}(),fireOnce:function(a,b,g){b=this.fire(a,b,g);delete d(this)[a];return b},removeListener:function(a,b){var g=d(this)[a];if(g){var k=g.getListenerIndex(b);0<=k&&g.listeners.splice(k,1)}},removeAllListeners:function(){var a=d(this),b;for(b in a)delete a[b]},hasListeners:function(a){return(a=d(this)[a])&&0<a.listeners.length}}}());
+CKEDITOR.editor||(CKEDITOR.editor=function(){CKEDITOR._.pending.push([this,arguments]);CKEDITOR.event.call(this)},CKEDITOR.editor.prototype.fire=function(a,d){a in{instanceReady:1,loaded:1}&&(this[a]=!0);return CKEDITOR.event.prototype.fire.call(this,a,d,this)},CKEDITOR.editor.prototype.fireOnce=function(a,d){a in{instanceReady:1,loaded:1}&&(this[a]=!0);return CKEDITOR.event.prototype.fireOnce.call(this,a,d,this)},CKEDITOR.event.implementOn(CKEDITOR.editor.prototype));
+CKEDITOR.env||(CKEDITOR.env=function(){var a=navigator.userAgent.toLowerCase(),d=a.match(/edge[ \/](\d+.?\d*)/),b=-1<a.indexOf("trident/"),b=!(!d&&!b),b={ie:b,edge:!!d,webkit:!b&&-1<a.indexOf(" applewebkit/"),air:-1<a.indexOf(" adobeair/"),mac:-1<a.indexOf("macintosh"),quirks:"BackCompat"==document.compatMode&&(!document.documentMode||10>document.documentMode),mobile:-1<a.indexOf("mobile"),iOS:/(ipad|iphone|ipod)/.test(a),isCustomDomain:function(){if(!this.ie)return!1;var a=document.domain,b=window.location.hostname;
+return a!=b&&a!="["+b+"]"},secure:"https:"==location.protocol};b.gecko="Gecko"==navigator.product&&!b.webkit&&!b.ie;b.webkit&&(-1<a.indexOf("chrome")?b.chrome=!0:b.safari=!0);var c=0;b.ie&&(c=d?parseFloat(d[1]):b.quirks||!document.documentMode?parseFloat(a.match(/msie (\d+)/)[1]):document.documentMode,b.ie9Compat=9==c,b.ie8Compat=8==c,b.ie7Compat=7==c,b.ie6Compat=7>c||b.quirks);b.gecko&&(d=a.match(/rv:([\d\.]+)/))&&(d=d[1].split("."),c=1E4*d[0]+100*(d[1]||0)+1*(d[2]||0));b.air&&(c=parseFloat(a.match(/ adobeair\/(\d+)/)[1]));
+b.webkit&&(c=parseFloat(a.match(/ applewebkit\/(\d+)/)[1]));b.version=c;b.isCompatible=!(b.ie&&7>c)&&!(b.gecko&&4E4>c)&&!(b.webkit&&534>c);b.hidpi=2<=window.devicePixelRatio;b.needsBrFiller=b.gecko||b.webkit||b.ie&&10<c;b.needsNbspFiller=b.ie&&11>c;b.cssClass="cke_browser_"+(b.ie?"ie":b.gecko?"gecko":b.webkit?"webkit":"unknown");b.quirks&&(b.cssClass+=" cke_browser_quirks");b.ie&&(b.cssClass+=" cke_browser_ie"+(b.quirks?"6 cke_browser_iequirks":b.version));b.air&&(b.cssClass+=" cke_browser_air");
+b.iOS&&(b.cssClass+=" cke_browser_ios");b.hidpi&&(b.cssClass+=" cke_hidpi");return b}());
+"unloaded"==CKEDITOR.status&&function(){CKEDITOR.event.implementOn(CKEDITOR);CKEDITOR.loadFullCore=function(){if("basic_ready"!=CKEDITOR.status)CKEDITOR.loadFullCore._load=1;else{delete CKEDITOR.loadFullCore;var a=document.createElement("script");a.type="text/javascript";a.src=CKEDITOR.basePath+"ckeditor.js";document.getElementsByTagName("head")[0].appendChild(a)}};CKEDITOR.loadFullCoreTimeout=0;CKEDITOR.add=function(a){(this._.pending||(this._.pending=[])).push(a)};(function(){CKEDITOR.domReady(function(){var a=
+CKEDITOR.loadFullCore,d=CKEDITOR.loadFullCoreTimeout;a&&(CKEDITOR.status="basic_ready",a&&a._load?a():d&&setTimeout(function(){CKEDITOR.loadFullCore&&CKEDITOR.loadFullCore()},1E3*d))})})();CKEDITOR.status="basic_loaded"}();"use strict";CKEDITOR.VERBOSITY_WARN=1;CKEDITOR.VERBOSITY_ERROR=2;CKEDITOR.verbosity=CKEDITOR.VERBOSITY_WARN|CKEDITOR.VERBOSITY_ERROR;CKEDITOR.warn=function(a,d){CKEDITOR.verbosity&CKEDITOR.VERBOSITY_WARN&&CKEDITOR.fire("log",{type:"warn",errorCode:a,additionalData:d})};
+CKEDITOR.error=function(a,d){CKEDITOR.verbosity&CKEDITOR.VERBOSITY_ERROR&&CKEDITOR.fire("log",{type:"error",errorCode:a,additionalData:d})};
+CKEDITOR.on("log",function(a){if(window.console&&window.console.log){var d=console[a.data.type]?a.data.type:"log",b=a.data.errorCode;if(a=a.data.additionalData)console[d]("[CKEDITOR] Error code: "+b+".",a);else console[d]("[CKEDITOR] Error code: "+b+".");console[d]("[CKEDITOR] For more information about this error go to http://docs.ckeditor.com/#!/guide/dev_errors-section-"+b)}},null,null,999);CKEDITOR.dom={};
+(function(){var a=[],d=CKEDITOR.env.gecko?"-moz-":CKEDITOR.env.webkit?"-webkit-":CKEDITOR.env.ie?"-ms-":"",b=/&/g,c=/>/g,e=/</g,g=/"/g,k=/&(lt|gt|amp|quot|nbsp|shy|#\d{1,5});/g,h={lt:"\x3c",gt:"\x3e",amp:"\x26",quot:'"',nbsp:" ",shy:"­"},p=function(a,f){return"#"==f[0]?String.fromCharCode(parseInt(f.slice(1),10)):h[f]};CKEDITOR.on("reset",function(){a=[]});CKEDITOR.tools={arrayCompare:function(a,f){if(!a&&!f)return!0;if(!a||!f||a.length!=f.length)return!1;for(var b=0;b<a.length;b++)if(a[b]!=f[b])return!1;
+return!0},getIndex:function(a,f){for(var b=0;b<a.length;++b)if(f(a[b]))return b;return-1},clone:function(a){var f;if(a&&a instanceof Array){f=[];for(var b=0;b<a.length;b++)f[b]=CKEDITOR.tools.clone(a[b]);return f}if(null===a||"object"!=typeof a||a instanceof String||a instanceof Number||a instanceof Boolean||a instanceof Date||a instanceof RegExp||a.nodeType||a.window===a)return a;f=new a.constructor;for(b in a)f[b]=CKEDITOR.tools.clone(a[b]);return f},capitalize:function(a,f){return a.charAt(0).toUpperCase()+
+(f?a.slice(1):a.slice(1).toLowerCase())},extend:function(a){var f=arguments.length,b,c;"boolean"==typeof(b=arguments[f-1])?f--:"boolean"==typeof(b=arguments[f-2])&&(c=arguments[f-1],f-=2);for(var h=1;h<f;h++){var d=arguments[h],m;for(m in d)if(!0===b||null==a[m])if(!c||m in c)a[m]=d[m]}return a},prototypedCopy:function(a){var f=function(){};f.prototype=a;return new f},copy:function(a){var f={},b;for(b in a)f[b]=a[b];return f},isArray:function(a){return"[object Array]"==Object.prototype.toString.call(a)},
+isEmpty:function(a){for(var f in a)if(a.hasOwnProperty(f))return!1;return!0},cssVendorPrefix:function(a,f,b){if(b)return d+a+":"+f+";"+a+":"+f;b={};b[a]=f;b[d+a]=f;return b},cssStyleToDomStyle:function(){var a=document.createElement("div").style,f="undefined"!=typeof a.cssFloat?"cssFloat":"undefined"!=typeof a.styleFloat?"styleFloat":"float";return function(a){return"float"==a?f:a.replace(/-./g,function(a){return a.substr(1).toUpperCase()})}}(),buildStyleHtml:function(a){a=[].concat(a);for(var f,
+b=[],c=0;c<a.length;c++)if(f=a[c])/@import|[{}]/.test(f)?b.push("\x3cstyle\x3e"+f+"\x3c/style\x3e"):b.push('\x3clink type\x3d"text/css" rel\x3dstylesheet href\x3d"'+f+'"\x3e');return b.join("")},htmlEncode:function(a){return void 0===a||null===a?"":String(a).replace(b,"\x26amp;").replace(c,"\x26gt;").replace(e,"\x26lt;")},htmlDecode:function(a){return a.replace(k,p)},htmlEncodeAttr:function(a){return CKEDITOR.tools.htmlEncode(a).replace(g,"\x26quot;")},htmlDecodeAttr:function(a){return CKEDITOR.tools.htmlDecode(a)},
+transformPlainTextToHtml:function(a,f){var b=f==CKEDITOR.ENTER_BR,c=this.htmlEncode(a.replace(/\r\n/g,"\n")),c=c.replace(/\t/g,"\x26nbsp;\x26nbsp; \x26nbsp;"),h=f==CKEDITOR.ENTER_P?"p":"div";if(!b){var d=/\n{2}/g;if(d.test(c))var m="\x3c"+h+"\x3e",p="\x3c/"+h+"\x3e",c=m+c.replace(d,function(){return p+m})+p}c=c.replace(/\n/g,"\x3cbr\x3e");b||(c=c.replace(new RegExp("\x3cbr\x3e(?\x3d\x3c/"+h+"\x3e)"),function(a){return CKEDITOR.tools.repeat(a,2)}));c=c.replace(/^ | $/g,"\x26nbsp;");return c=c.replace(/(>|\s) /g,
+function(a,f){return f+"\x26nbsp;"}).replace(/ (?=<)/g,"\x26nbsp;")},getNextNumber:function(){var a=0;return function(){return++a}}(),getNextId:function(){return"cke_"+this.getNextNumber()},getUniqueId:function(){for(var a="e",f=0;8>f;f++)a+=Math.floor(65536*(1+Math.random())).toString(16).substring(1);return a},override:function(a,f){var b=f(a);b.prototype=a.prototype;return b},setTimeout:function(a,f,b,c,h){h||(h=window);b||(b=h);return h.setTimeout(function(){c?a.apply(b,[].concat(c)):a.apply(b)},
+f||0)},trim:function(){var a=/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g;return function(f){return f.replace(a,"")}}(),ltrim:function(){var a=/^[ \t\n\r]+/g;return function(f){return f.replace(a,"")}}(),rtrim:function(){var a=/[ \t\n\r]+$/g;return function(f){return f.replace(a,"")}}(),indexOf:function(a,f){if("function"==typeof f)for(var b=0,c=a.length;b<c;b++){if(f(a[b]))return b}else{if(a.indexOf)return a.indexOf(f);b=0;for(c=a.length;b<c;b++)if(a[b]===f)return b}return-1},search:function(a,f){var b=CKEDITOR.tools.indexOf(a,
+f);return 0<=b?a[b]:null},bind:function(a,f){return function(){return a.apply(f,arguments)}},createClass:function(a){var f=a.$,b=a.base,c=a.privates||a._,h=a.proto;a=a.statics;!f&&(f=function(){b&&this.base.apply(this,arguments)});if(c)var d=f,f=function(){var a=this._||(this._={}),f;for(f in c){var b=c[f];a[f]="function"==typeof b?CKEDITOR.tools.bind(b,this):b}d.apply(this,arguments)};b&&(f.prototype=this.prototypedCopy(b.prototype),f.prototype.constructor=f,f.base=b,f.baseProto=b.prototype,f.prototype.base=
+function(){this.base=b.prototype.base;b.apply(this,arguments);this.base=arguments.callee});h&&this.extend(f.prototype,h,!0);a&&this.extend(f,a,!0);return f},addFunction:function(b,f){return a.push(function(){return b.apply(f||this,arguments)})-1},removeFunction:function(b){a[b]=null},callFunction:function(b){var f=a[b];return f&&f.apply(window,Array.prototype.slice.call(arguments,1))},cssLength:function(){var a=/^-?\d+\.?\d*px$/,f;return function(b){f=CKEDITOR.tools.trim(b+"")+"px";return a.test(f)?
+f:b||""}}(),convertToPx:function(){var a;return function(f){a||(a=CKEDITOR.dom.element.createFromHtml('\x3cdiv style\x3d"position:absolute;left:-9999px;top:-9999px;margin:0px;padding:0px;border:0px;"\x3e\x3c/div\x3e',CKEDITOR.document),CKEDITOR.document.getBody().append(a));return/%$/.test(f)?f:(a.setStyle("width",f),a.$.clientWidth)}}(),repeat:function(a,f){return Array(f+1).join(a)},tryThese:function(){for(var a,f=0,b=arguments.length;f<b;f++){var c=arguments[f];try{a=c();break}catch(h){}}return a},
+genKey:function(){return Array.prototype.slice.call(arguments).join("-")},defer:function(a){return function(){var f=arguments,b=this;window.setTimeout(function(){a.apply(b,f)},0)}},normalizeCssText:function(a,f){var b=[],c,h=CKEDITOR.tools.parseCssText(a,!0,f);for(c in h)b.push(c+":"+h[c]);b.sort();return b.length?b.join(";")+";":""},convertRgbToHex:function(a){return a.replace(/(?:rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\))/gi,function(a,b,c,h){a=[b,c,h];for(b=0;3>b;b++)a[b]=("0"+parseInt(a[b],10).toString(16)).slice(-2);
+return"#"+a.join("")})},normalizeHex:function(a){return a.replace(/#(([0-9a-f]{3}){1,2})($|;|\s+)/gi,function(a,b,c,h){a=b.toLowerCase();3==a.length&&(a=a.split(""),a=[a[0],a[0],a[1],a[1],a[2],a[2]].join(""));return"#"+a+h})},parseCssText:function(a,f,b){var c={};b&&(a=(new CKEDITOR.dom.element("span")).setAttribute("style",a).getAttribute("style")||"");a&&(a=CKEDITOR.tools.normalizeHex(CKEDITOR.tools.convertRgbToHex(a)));if(!a||";"==a)return c;a.replace(/&quot;/g,'"').replace(/\s*([^:;\s]+)\s*:\s*([^;]+)\s*(?=;|$)/g,
+function(a,b,h){f&&(b=b.toLowerCase(),"font-family"==b&&(h=h.replace(/\s*,\s*/g,",")),h=CKEDITOR.tools.trim(h));c[b]=h});return c},writeCssText:function(a,b){var c,h=[];for(c in a)h.push(c+":"+a[c]);b&&h.sort();return h.join("; ")},objectCompare:function(a,b,c){var h;if(!a&&!b)return!0;if(!a||!b)return!1;for(h in a)if(a[h]!=b[h])return!1;if(!c)for(h in b)if(a[h]!=b[h])return!1;return!0},objectKeys:function(a){var b=[],c;for(c in a)b.push(c);return b},convertArrayToObject:function(a,b){var c={};1==
+arguments.length&&(b=!0);for(var h=0,d=a.length;h<d;++h)c[a[h]]=b;return c},fixDomain:function(){for(var a;;)try{a=window.parent.document.domain;break}catch(b){a=a?a.replace(/.+?(?:\.|$)/,""):document.domain;if(!a)break;document.domain=a}return!!a},eventsBuffer:function(a,b,c){function h(){p=(new Date).getTime();d=!1;c?b.call(c):b()}var d,p=0;return{input:function(){if(!d){var b=(new Date).getTime()-p;b<a?d=setTimeout(h,a-b):h()}},reset:function(){d&&clearTimeout(d);d=p=0}}},enableHtml5Elements:function(a,
+b){for(var c="abbr article aside audio bdi canvas data datalist details figcaption figure footer header hgroup main mark meter nav output progress section summary time video".split(" "),h=c.length,d;h--;)d=a.createElement(c[h]),b&&a.appendChild(d)},checkIfAnyArrayItemMatches:function(a,b){for(var c=0,h=a.length;c<h;++c)if(a[c].match(b))return!0;return!1},checkIfAnyObjectPropertyMatches:function(a,b){for(var c in a)if(c.match(b))return!0;return!1},keystrokeToString:function(a,b){var c=b&16711680,h=
+b&65535,d=CKEDITOR.env.mac,p=[],m=[];c&CKEDITOR.CTRL&&(p.push(d?"⌘":a[17]),m.push(d?a[224]:a[17]));c&CKEDITOR.ALT&&(p.push(d?"⌥":a[18]),m.push(a[18]));c&CKEDITOR.SHIFT&&(p.push(d?"⇧":a[16]),m.push(a[16]));h&&(a[h]?(p.push(a[h]),m.push(a[h])):(p.push(String.fromCharCode(h)),m.push(String.fromCharCode(h))));return{display:p.join("+"),aria:m.join("+")}},transparentImageData:"data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw\x3d\x3d",getCookie:function(a){a=a.toLowerCase();
+for(var b=document.cookie.split(";"),c,h,d=0;d<b.length;d++)if(c=b[d].split("\x3d"),h=decodeURIComponent(CKEDITOR.tools.trim(c[0]).toLowerCase()),h===a)return decodeURIComponent(1<c.length?c[1]:"");return null},setCookie:function(a,b){document.cookie=encodeURIComponent(a)+"\x3d"+encodeURIComponent(b)+";path\x3d/"},getCsrfToken:function(){var a=CKEDITOR.tools.getCookie("ckCsrfToken");if(!a||40!=a.length){var a=[],b="";if(window.crypto&&window.crypto.getRandomValues)a=new Uint8Array(40),window.crypto.getRandomValues(a);
+else for(var c=0;40>c;c++)a.push(Math.floor(256*Math.random()));for(c=0;c<a.length;c++)var h="abcdefghijklmnopqrstuvwxyz0123456789".charAt(a[c]%36),b=b+(.5<Math.random()?h.toUpperCase():h);a=b;CKEDITOR.tools.setCookie("ckCsrfToken",a)}return a},escapeCss:function(a){return a?window.CSS&&CSS.escape?CSS.escape(a):isNaN(parseInt(a.charAt(0),10))?a:"\\3"+a.charAt(0)+" "+a.substring(1,a.length):""},style:{parse:{_colors:{aliceblue:"#F0F8FF",antiquewhite:"#FAEBD7",aqua:"#00FFFF",aquamarine:"#7FFFD4",azure:"#F0FFFF",
+beige:"#F5F5DC",bisque:"#FFE4C4",black:"#000000",blanchedalmond:"#FFEBCD",blue:"#0000FF",blueviolet:"#8A2BE2",brown:"#A52A2A",burlywood:"#DEB887",cadetblue:"#5F9EA0",chartreuse:"#7FFF00",chocolate:"#D2691E",coral:"#FF7F50",cornflowerblue:"#6495ED",cornsilk:"#FFF8DC",crimson:"#DC143C",cyan:"#00FFFF",darkblue:"#00008B",darkcyan:"#008B8B",darkgoldenrod:"#B8860B",darkgray:"#A9A9A9",darkgreen:"#006400",darkgrey:"#A9A9A9",darkkhaki:"#BDB76B",darkmagenta:"#8B008B",darkolivegreen:"#556B2F",darkorange:"#FF8C00",
+darkorchid:"#9932CC",darkred:"#8B0000",darksalmon:"#E9967A",darkseagreen:"#8FBC8F",darkslateblue:"#483D8B",darkslategray:"#2F4F4F",darkslategrey:"#2F4F4F",darkturquoise:"#00CED1",darkviolet:"#9400D3",deeppink:"#FF1493",deepskyblue:"#00BFFF",dimgray:"#696969",dimgrey:"#696969",dodgerblue:"#1E90FF",firebrick:"#B22222",floralwhite:"#FFFAF0",forestgreen:"#228B22",fuchsia:"#FF00FF",gainsboro:"#DCDCDC",ghostwhite:"#F8F8FF",gold:"#FFD700",goldenrod:"#DAA520",gray:"#808080",green:"#008000",greenyellow:"#ADFF2F",
+grey:"#808080",honeydew:"#F0FFF0",hotpink:"#FF69B4",indianred:"#CD5C5C",indigo:"#4B0082",ivory:"#FFFFF0",khaki:"#F0E68C",lavender:"#E6E6FA",lavenderblush:"#FFF0F5",lawngreen:"#7CFC00",lemonchiffon:"#FFFACD",lightblue:"#ADD8E6",lightcoral:"#F08080",lightcyan:"#E0FFFF",lightgoldenrodyellow:"#FAFAD2",lightgray:"#D3D3D3",lightgreen:"#90EE90",lightgrey:"#D3D3D3",lightpink:"#FFB6C1",lightsalmon:"#FFA07A",lightseagreen:"#20B2AA",lightskyblue:"#87CEFA",lightslategray:"#778899",lightslategrey:"#778899",lightsteelblue:"#B0C4DE",
+lightyellow:"#FFFFE0",lime:"#00FF00",limegreen:"#32CD32",linen:"#FAF0E6",magenta:"#FF00FF",maroon:"#800000",mediumaquamarine:"#66CDAA",mediumblue:"#0000CD",mediumorchid:"#BA55D3",mediumpurple:"#9370DB",mediumseagreen:"#3CB371",mediumslateblue:"#7B68EE",mediumspringgreen:"#00FA9A",mediumturquoise:"#48D1CC",mediumvioletred:"#C71585",midnightblue:"#191970",mintcream:"#F5FFFA",mistyrose:"#FFE4E1",moccasin:"#FFE4B5",navajowhite:"#FFDEAD",navy:"#000080",oldlace:"#FDF5E6",olive:"#808000",olivedrab:"#6B8E23",
+orange:"#FFA500",orangered:"#FF4500",orchid:"#DA70D6",palegoldenrod:"#EEE8AA",palegreen:"#98FB98",paleturquoise:"#AFEEEE",palevioletred:"#DB7093",papayawhip:"#FFEFD5",peachpuff:"#FFDAB9",peru:"#CD853F",pink:"#FFC0CB",plum:"#DDA0DD",powderblue:"#B0E0E6",purple:"#800080",rebeccapurple:"#663399",red:"#FF0000",rosybrown:"#BC8F8F",royalblue:"#4169E1",saddlebrown:"#8B4513",salmon:"#FA8072",sandybrown:"#F4A460",seagreen:"#2E8B57",seashell:"#FFF5EE",sienna:"#A0522D",silver:"#C0C0C0",skyblue:"#87CEEB",slateblue:"#6A5ACD",
+slategray:"#708090",slategrey:"#708090",snow:"#FFFAFA",springgreen:"#00FF7F",steelblue:"#4682B4",tan:"#D2B48C",teal:"#008080",thistle:"#D8BFD8",tomato:"#FF6347",turquoise:"#40E0D0",violet:"#EE82EE",wheat:"#F5DEB3",white:"#FFFFFF",whitesmoke:"#F5F5F5",yellow:"#FFFF00",yellowgreen:"#9ACD32"},_rgbaRegExp:/rgba?\(\s*\d+%?\s*,\s*\d+%?\s*,\s*\d+%?\s*(?:,\s*[0-9.]+\s*)?\)/gi,_hslaRegExp:/hsla?\(\s*[0-9.]+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[0-9.]+\s*)?\)/gi,background:function(a){var b=[],c=[],c=this._findColor(a);
+c.length&&(b.color=c[0],CKEDITOR.tools.array.forEach(c,function(b){a=a.replace(b,"")}));if(a=CKEDITOR.tools.trim(a))b.unprocessed=a;return b},margin:function(a){function b(a){c.top=h[a[0]];c.right=h[a[1]];c.bottom=h[a[2]];c.left=h[a[3]]}var c={},h=a.match(/(?:\-?[\.\d]+(?:%|\w*)|auto|inherit|initial|unset)/g)||["0px"];switch(h.length){case 1:b([0,0,0,0]);break;case 2:b([0,1,0,1]);break;case 3:b([0,1,2,1]);break;case 4:b([0,1,2,3])}return c},_findColor:function(a){var b=[],c=CKEDITOR.tools.array,b=
+b.concat(a.match(this._rgbaRegExp)||[]),b=b.concat(a.match(this._hslaRegExp)||[]);return b=b.concat(c.filter(a.split(/\s+/),function(a){return a.match(/^\#[a-f0-9]{3}(?:[a-f0-9]{3})?$/gi)?!0:a.toLowerCase()in CKEDITOR.tools.style.parse._colors}))}}},array:{filter:function(a,b,c){var h=[];this.forEach(a,function(d,p){b.call(c,d,p,a)&&h.push(d)});return h},forEach:function(a,b,c){var h=a.length,d;for(d=0;d<h;d++)b.call(c,a[d],d,a)},map:function(a,b,c){for(var h=[],d=0;d<a.length;d++)h.push(b.call(c,
+a[d],d,a));return h},reduce:function(a,b,c,h){for(var d=0;d<a.length;d++)c=b.call(h,c,a[d],d,a);return c}}};CKEDITOR.tools.array.indexOf=CKEDITOR.tools.indexOf;CKEDITOR.tools.array.isArray=CKEDITOR.tools.isArray})();
+CKEDITOR.dtd=function(){var a=CKEDITOR.tools.extend,d=function(a,b){for(var c=CKEDITOR.tools.clone(a),h=1;h<arguments.length;h++){b=arguments[h];for(var d in b)delete c[d]}return c},b={},c={},e={address:1,article:1,aside:1,blockquote:1,details:1,div:1,dl:1,fieldset:1,figure:1,footer:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,header:1,hgroup:1,hr:1,main:1,menu:1,nav:1,ol:1,p:1,pre:1,section:1,table:1,ul:1},g={command:1,link:1,meta:1,noscript:1,script:1,style:1},k={},h={"#":1},p={center:1,dir:1,noframes:1};
+a(b,{a:1,abbr:1,area:1,audio:1,b:1,bdi:1,bdo:1,br:1,button:1,canvas:1,cite:1,code:1,command:1,datalist:1,del:1,dfn:1,em:1,embed:1,i:1,iframe:1,img:1,input:1,ins:1,kbd:1,keygen:1,label:1,map:1,mark:1,meter:1,noscript:1,object:1,output:1,progress:1,q:1,ruby:1,s:1,samp:1,script:1,select:1,small:1,span:1,strong:1,sub:1,sup:1,textarea:1,time:1,u:1,"var":1,video:1,wbr:1},h,{acronym:1,applet:1,basefont:1,big:1,font:1,isindex:1,strike:1,style:1,tt:1});a(c,e,b,p);d={a:d(b,{a:1,button:1}),abbr:b,address:c,
+area:k,article:c,aside:c,audio:a({source:1,track:1},c),b:b,base:k,bdi:b,bdo:b,blockquote:c,body:c,br:k,button:d(b,{a:1,button:1}),canvas:b,caption:c,cite:b,code:b,col:k,colgroup:{col:1},command:k,datalist:a({option:1},b),dd:c,del:b,details:a({summary:1},c),dfn:b,div:c,dl:{dt:1,dd:1},dt:c,em:b,embed:k,fieldset:a({legend:1},c),figcaption:c,figure:a({figcaption:1},c),footer:c,form:c,h1:b,h2:b,h3:b,h4:b,h5:b,h6:b,head:a({title:1,base:1},g),header:c,hgroup:{h1:1,h2:1,h3:1,h4:1,h5:1,h6:1},hr:k,html:a({head:1,
+body:1},c,g),i:b,iframe:h,img:k,input:k,ins:b,kbd:b,keygen:k,label:b,legend:b,li:c,link:k,main:c,map:c,mark:b,menu:a({li:1},c),meta:k,meter:d(b,{meter:1}),nav:c,noscript:a({link:1,meta:1,style:1},b),object:a({param:1},b),ol:{li:1},optgroup:{option:1},option:h,output:b,p:b,param:k,pre:b,progress:d(b,{progress:1}),q:b,rp:b,rt:b,ruby:a({rp:1,rt:1},b),s:b,samp:b,script:h,section:c,select:{optgroup:1,option:1},small:b,source:k,span:b,strong:b,style:h,sub:b,summary:a({h1:1,h2:1,h3:1,h4:1,h5:1,h6:1},b),
+sup:b,table:{caption:1,colgroup:1,thead:1,tfoot:1,tbody:1,tr:1},tbody:{tr:1},td:c,textarea:h,tfoot:{tr:1},th:c,thead:{tr:1},time:d(b,{time:1}),title:h,tr:{th:1,td:1},track:k,u:b,ul:{li:1},"var":b,video:a({source:1,track:1},c),wbr:k,acronym:b,applet:a({param:1},c),basefont:k,big:b,center:c,dialog:k,dir:{li:1},font:b,isindex:k,noframes:c,strike:b,tt:b};a(d,{$block:a({audio:1,dd:1,dt:1,figcaption:1,li:1,video:1},e,p),$blockLimit:{article:1,aside:1,audio:1,body:1,caption:1,details:1,dir:1,div:1,dl:1,
+fieldset:1,figcaption:1,figure:1,footer:1,form:1,header:1,hgroup:1,main:1,menu:1,nav:1,ol:1,section:1,table:1,td:1,th:1,tr:1,ul:1,video:1},$cdata:{script:1,style:1},$editable:{address:1,article:1,aside:1,blockquote:1,body:1,details:1,div:1,fieldset:1,figcaption:1,footer:1,form:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,header:1,hgroup:1,main:1,nav:1,p:1,pre:1,section:1},$empty:{area:1,base:1,basefont:1,br:1,col:1,command:1,dialog:1,embed:1,hr:1,img:1,input:1,isindex:1,keygen:1,link:1,meta:1,param:1,source:1,
+track:1,wbr:1},$inline:b,$list:{dl:1,ol:1,ul:1},$listItem:{dd:1,dt:1,li:1},$nonBodyContent:a({body:1,head:1,html:1},d.head),$nonEditable:{applet:1,audio:1,button:1,embed:1,iframe:1,map:1,object:1,option:1,param:1,script:1,textarea:1,video:1},$object:{applet:1,audio:1,button:1,hr:1,iframe:1,img:1,input:1,object:1,select:1,table:1,textarea:1,video:1},$removeEmpty:{abbr:1,acronym:1,b:1,bdi:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,mark:1,meter:1,output:1,q:1,ruby:1,
+s:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,time:1,tt:1,u:1,"var":1},$tabIndex:{a:1,area:1,button:1,input:1,object:1,select:1,textarea:1},$tableContent:{caption:1,col:1,colgroup:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1},$transparent:{a:1,audio:1,canvas:1,del:1,ins:1,map:1,noscript:1,object:1,video:1},$intermediate:{caption:1,colgroup:1,dd:1,dt:1,figcaption:1,legend:1,li:1,optgroup:1,option:1,rp:1,rt:1,summary:1,tbody:1,td:1,tfoot:1,th:1,thead:1,tr:1}});return d}();
+CKEDITOR.dom.event=function(a){this.$=a};
+CKEDITOR.dom.event.prototype={getKey:function(){return this.$.keyCode||this.$.which},getKeystroke:function(){var a=this.getKey();if(this.$.ctrlKey||this.$.metaKey)a+=CKEDITOR.CTRL;this.$.shiftKey&&(a+=CKEDITOR.SHIFT);this.$.altKey&&(a+=CKEDITOR.ALT);return a},preventDefault:function(a){var d=this.$;d.preventDefault?d.preventDefault():d.returnValue=!1;a&&this.stopPropagation()},stopPropagation:function(){var a=this.$;a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},getTarget:function(){var a=
+this.$.target||this.$.srcElement;return a?new CKEDITOR.dom.node(a):null},getPhase:function(){return this.$.eventPhase||2},getPageOffset:function(){var a=this.getTarget().getDocument().$;return{x:this.$.pageX||this.$.clientX+(a.documentElement.scrollLeft||a.body.scrollLeft),y:this.$.pageY||this.$.clientY+(a.documentElement.scrollTop||a.body.scrollTop)}}};CKEDITOR.CTRL=1114112;CKEDITOR.SHIFT=2228224;CKEDITOR.ALT=4456448;CKEDITOR.EVENT_PHASE_CAPTURING=1;CKEDITOR.EVENT_PHASE_AT_TARGET=2;
+CKEDITOR.EVENT_PHASE_BUBBLING=3;CKEDITOR.dom.domObject=function(a){a&&(this.$=a)};
+CKEDITOR.dom.domObject.prototype=function(){var a=function(a,b){return function(c){"undefined"!=typeof CKEDITOR&&a.fire(b,new CKEDITOR.dom.event(c))}};return{getPrivate:function(){var a;(a=this.getCustomData("_"))||this.setCustomData("_",a={});return a},on:function(d){var b=this.getCustomData("_cke_nativeListeners");b||(b={},this.setCustomData("_cke_nativeListeners",b));b[d]||(b=b[d]=a(this,d),this.$.addEventListener?this.$.addEventListener(d,b,!!CKEDITOR.event.useCapture):this.$.attachEvent&&this.$.attachEvent("on"+
+d,b));return CKEDITOR.event.prototype.on.apply(this,arguments)},removeListener:function(a){CKEDITOR.event.prototype.removeListener.apply(this,arguments);if(!this.hasListeners(a)){var b=this.getCustomData("_cke_nativeListeners"),c=b&&b[a];c&&(this.$.removeEventListener?this.$.removeEventListener(a,c,!1):this.$.detachEvent&&this.$.detachEvent("on"+a,c),delete b[a])}},removeAllListeners:function(){var a=this.getCustomData("_cke_nativeListeners"),b;for(b in a){var c=a[b];this.$.detachEvent?this.$.detachEvent("on"+
+b,c):this.$.removeEventListener&&this.$.removeEventListener(b,c,!1);delete a[b]}CKEDITOR.event.prototype.removeAllListeners.call(this)}}}();
+(function(a){var d={};CKEDITOR.on("reset",function(){d={}});a.equals=function(a){try{return a&&a.$===this.$}catch(c){return!1}};a.setCustomData=function(a,c){var e=this.getUniqueId();(d[e]||(d[e]={}))[a]=c;return this};a.getCustomData=function(a){var c=this.$["data-cke-expando"];return(c=c&&d[c])&&a in c?c[a]:null};a.removeCustomData=function(a){var c=this.$["data-cke-expando"],c=c&&d[c],e,g;c&&(e=c[a],g=a in c,delete c[a]);return g?e:null};a.clearCustomData=function(){this.removeAllListeners();var a=
+this.$["data-cke-expando"];a&&delete d[a]};a.getUniqueId=function(){return this.$["data-cke-expando"]||(this.$["data-cke-expando"]=CKEDITOR.tools.getNextNumber())};CKEDITOR.event.implementOn(a)})(CKEDITOR.dom.domObject.prototype);
+CKEDITOR.dom.node=function(a){return a?new CKEDITOR.dom[a.nodeType==CKEDITOR.NODE_DOCUMENT?"document":a.nodeType==CKEDITOR.NODE_ELEMENT?"element":a.nodeType==CKEDITOR.NODE_TEXT?"text":a.nodeType==CKEDITOR.NODE_COMMENT?"comment":a.nodeType==CKEDITOR.NODE_DOCUMENT_FRAGMENT?"documentFragment":"domObject"](a):this};CKEDITOR.dom.node.prototype=new CKEDITOR.dom.domObject;CKEDITOR.NODE_ELEMENT=1;CKEDITOR.NODE_DOCUMENT=9;CKEDITOR.NODE_TEXT=3;CKEDITOR.NODE_COMMENT=8;CKEDITOR.NODE_DOCUMENT_FRAGMENT=11;
+CKEDITOR.POSITION_IDENTICAL=0;CKEDITOR.POSITION_DISCONNECTED=1;CKEDITOR.POSITION_FOLLOWING=2;CKEDITOR.POSITION_PRECEDING=4;CKEDITOR.POSITION_IS_CONTAINED=8;CKEDITOR.POSITION_CONTAINS=16;
+CKEDITOR.tools.extend(CKEDITOR.dom.node.prototype,{appendTo:function(a,d){a.append(this,d);return a},clone:function(a,d){function b(c){c["data-cke-expando"]&&(c["data-cke-expando"]=!1);if(c.nodeType==CKEDITOR.NODE_ELEMENT||c.nodeType==CKEDITOR.NODE_DOCUMENT_FRAGMENT)if(d||c.nodeType!=CKEDITOR.NODE_ELEMENT||c.removeAttribute("id",!1),a){c=c.childNodes;for(var e=0;e<c.length;e++)b(c[e])}}function c(b){if(b.type==CKEDITOR.NODE_ELEMENT||b.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT){if(b.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT){var d=
+b.getName();":"==d[0]&&b.renameNode(d.substring(1))}if(a)for(d=0;d<b.getChildCount();d++)c(b.getChild(d))}}var e=this.$.cloneNode(a);b(e);e=new CKEDITOR.dom.node(e);CKEDITOR.env.ie&&9>CKEDITOR.env.version&&(this.type==CKEDITOR.NODE_ELEMENT||this.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT)&&c(e);return e},hasPrevious:function(){return!!this.$.previousSibling},hasNext:function(){return!!this.$.nextSibling},insertAfter:function(a){a.$.parentNode.insertBefore(this.$,a.$.nextSibling);return a},insertBefore:function(a){a.$.parentNode.insertBefore(this.$,
+a.$);return a},insertBeforeMe:function(a){this.$.parentNode.insertBefore(a.$,this.$);return a},getAddress:function(a){for(var d=[],b=this.getDocument().$.documentElement,c=this.$;c&&c!=b;){var e=c.parentNode;e&&d.unshift(this.getIndex.call({$:c},a));c=e}return d},getDocument:function(){return new CKEDITOR.dom.document(this.$.ownerDocument||this.$.parentNode.ownerDocument)},getIndex:function(a){function d(a,c){var p=c?a.nextSibling:a.previousSibling;return p&&p.nodeType==CKEDITOR.NODE_TEXT?b(p)?d(p,
+c):p:null}function b(a){return!a.nodeValue||a.nodeValue==CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE}var c=this.$,e=-1,g;if(!this.$.parentNode||a&&c.nodeType==CKEDITOR.NODE_TEXT&&b(c)&&!d(c)&&!d(c,!0))return-1;do a&&c!=this.$&&c.nodeType==CKEDITOR.NODE_TEXT&&(g||b(c))||(e++,g=c.nodeType==CKEDITOR.NODE_TEXT);while(c=c.previousSibling);return e},getNextSourceNode:function(a,d,b){if(b&&!b.call){var c=b;b=function(a){return!a.equals(c)}}a=!a&&this.getFirst&&this.getFirst();var e;if(!a){if(this.type==
+CKEDITOR.NODE_ELEMENT&&b&&!1===b(this,!0))return null;a=this.getNext()}for(;!a&&(e=(e||this).getParent());){if(b&&!1===b(e,!0))return null;a=e.getNext()}return!a||b&&!1===b(a)?null:d&&d!=a.type?a.getNextSourceNode(!1,d,b):a},getPreviousSourceNode:function(a,d,b){if(b&&!b.call){var c=b;b=function(a){return!a.equals(c)}}a=!a&&this.getLast&&this.getLast();var e;if(!a){if(this.type==CKEDITOR.NODE_ELEMENT&&b&&!1===b(this,!0))return null;a=this.getPrevious()}for(;!a&&(e=(e||this).getParent());){if(b&&!1===
+b(e,!0))return null;a=e.getPrevious()}return!a||b&&!1===b(a)?null:d&&a.type!=d?a.getPreviousSourceNode(!1,d,b):a},getPrevious:function(a){var d=this.$,b;do b=(d=d.previousSibling)&&10!=d.nodeType&&new CKEDITOR.dom.node(d);while(b&&a&&!a(b));return b},getNext:function(a){var d=this.$,b;do b=(d=d.nextSibling)&&new CKEDITOR.dom.node(d);while(b&&a&&!a(b));return b},getParent:function(a){var d=this.$.parentNode;return d&&(d.nodeType==CKEDITOR.NODE_ELEMENT||a&&d.nodeType==CKEDITOR.NODE_DOCUMENT_FRAGMENT)?
+new CKEDITOR.dom.node(d):null},getParents:function(a){var d=this,b=[];do b[a?"push":"unshift"](d);while(d=d.getParent());return b},getCommonAncestor:function(a){if(a.equals(this))return this;if(a.contains&&a.contains(this))return a;var d=this.contains?this:this.getParent();do if(d.contains(a))return d;while(d=d.getParent());return null},getPosition:function(a){var d=this.$,b=a.$;if(d.compareDocumentPosition)return d.compareDocumentPosition(b);if(d==b)return CKEDITOR.POSITION_IDENTICAL;if(this.type==
+CKEDITOR.NODE_ELEMENT&&a.type==CKEDITOR.NODE_ELEMENT){if(d.contains){if(d.contains(b))return CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_PRECEDING;if(b.contains(d))return CKEDITOR.POSITION_IS_CONTAINED+CKEDITOR.POSITION_FOLLOWING}if("sourceIndex"in d)return 0>d.sourceIndex||0>b.sourceIndex?CKEDITOR.POSITION_DISCONNECTED:d.sourceIndex<b.sourceIndex?CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_FOLLOWING}d=this.getAddress();a=a.getAddress();for(var b=Math.min(d.length,a.length),c=0;c<b;c++)if(d[c]!=
+a[c])return d[c]<a[c]?CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_FOLLOWING;return d.length<a.length?CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_PRECEDING:CKEDITOR.POSITION_IS_CONTAINED+CKEDITOR.POSITION_FOLLOWING},getAscendant:function(a,d){var b=this.$,c,e;d||(b=b.parentNode);"function"==typeof a?(e=!0,c=a):(e=!1,c=function(b){b="string"==typeof b.nodeName?b.nodeName.toLowerCase():"";return"string"==typeof a?b==a:b in a});for(;b;){if(c(e?new CKEDITOR.dom.node(b):b))return new CKEDITOR.dom.node(b);
+try{b=b.parentNode}catch(g){b=null}}return null},hasAscendant:function(a,d){var b=this.$;d||(b=b.parentNode);for(;b;){if(b.nodeName&&b.nodeName.toLowerCase()==a)return!0;b=b.parentNode}return!1},move:function(a,d){a.append(this.remove(),d)},remove:function(a){var d=this.$,b=d.parentNode;if(b){if(a)for(;a=d.firstChild;)b.insertBefore(d.removeChild(a),d);b.removeChild(d)}return this},replace:function(a){this.insertBefore(a);a.remove()},trim:function(){this.ltrim();this.rtrim()},ltrim:function(){for(var a;this.getFirst&&
+(a=this.getFirst());){if(a.type==CKEDITOR.NODE_TEXT){var d=CKEDITOR.tools.ltrim(a.getText()),b=a.getLength();if(d)d.length<b&&(a.split(b-d.length),this.$.removeChild(this.$.firstChild));else{a.remove();continue}}break}},rtrim:function(){for(var a;this.getLast&&(a=this.getLast());){if(a.type==CKEDITOR.NODE_TEXT){var d=CKEDITOR.tools.rtrim(a.getText()),b=a.getLength();if(d)d.length<b&&(a.split(d.length),this.$.lastChild.parentNode.removeChild(this.$.lastChild));else{a.remove();continue}}break}CKEDITOR.env.needsBrFiller&&
+(a=this.$.lastChild)&&1==a.type&&"br"==a.nodeName.toLowerCase()&&a.parentNode.removeChild(a)},isReadOnly:function(a){var d=this;this.type!=CKEDITOR.NODE_ELEMENT&&(d=this.getParent());CKEDITOR.env.edge&&d&&d.is("textarea","input")&&(a=!0);if(!a&&d&&"undefined"!=typeof d.$.isContentEditable)return!(d.$.isContentEditable||d.data("cke-editable"));for(;d;){if(d.data("cke-editable"))return!1;if(d.hasAttribute("contenteditable"))return"false"==d.getAttribute("contenteditable");d=d.getParent()}return!0}});
+CKEDITOR.dom.window=function(a){CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.window.prototype=new CKEDITOR.dom.domObject;
+CKEDITOR.tools.extend(CKEDITOR.dom.window.prototype,{focus:function(){this.$.focus()},getViewPaneSize:function(){var a=this.$.document,d="CSS1Compat"==a.compatMode;return{width:(d?a.documentElement.clientWidth:a.body.clientWidth)||0,height:(d?a.documentElement.clientHeight:a.body.clientHeight)||0}},getScrollPosition:function(){var a=this.$;if("pageXOffset"in a)return{x:a.pageXOffset||0,y:a.pageYOffset||0};a=a.document;return{x:a.documentElement.scrollLeft||a.body.scrollLeft||0,y:a.documentElement.scrollTop||
+a.body.scrollTop||0}},getFrame:function(){var a=this.$.frameElement;return a?new CKEDITOR.dom.element.get(a):null}});CKEDITOR.dom.document=function(a){CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.document.prototype=new CKEDITOR.dom.domObject;
+CKEDITOR.tools.extend(CKEDITOR.dom.document.prototype,{type:CKEDITOR.NODE_DOCUMENT,appendStyleSheet:function(a){if(this.$.createStyleSheet)this.$.createStyleSheet(a);else{var d=new CKEDITOR.dom.element("link");d.setAttributes({rel:"stylesheet",type:"text/css",href:a});this.getHead().append(d)}},appendStyleText:function(a){if(this.$.createStyleSheet){var d=this.$.createStyleSheet("");d.cssText=a}else{var b=new CKEDITOR.dom.element("style",this);b.append(new CKEDITOR.dom.text(a,this));this.getHead().append(b)}return d||
+b.$.sheet},createElement:function(a,d){var b=new CKEDITOR.dom.element(a,this);d&&(d.attributes&&b.setAttributes(d.attributes),d.styles&&b.setStyles(d.styles));return b},createText:function(a){return new CKEDITOR.dom.text(a,this)},focus:function(){this.getWindow().focus()},getActive:function(){var a;try{a=this.$.activeElement}catch(d){return null}return new CKEDITOR.dom.element(a)},getById:function(a){return(a=this.$.getElementById(a))?new CKEDITOR.dom.element(a):null},getByAddress:function(a,d){for(var b=
+this.$.documentElement,c=0;b&&c<a.length;c++){var e=a[c];if(d)for(var g=-1,k=0;k<b.childNodes.length;k++){var h=b.childNodes[k];if(!0!==d||3!=h.nodeType||!h.previousSibling||3!=h.previousSibling.nodeType)if(g++,g==e){b=h;break}}else b=b.childNodes[e]}return b?new CKEDITOR.dom.node(b):null},getElementsByTag:function(a,d){CKEDITOR.env.ie&&8>=document.documentMode||!d||(a=d+":"+a);return new CKEDITOR.dom.nodeList(this.$.getElementsByTagName(a))},getHead:function(){var a=this.$.getElementsByTagName("head")[0];
+return a=a?new CKEDITOR.dom.element(a):this.getDocumentElement().append(new CKEDITOR.dom.element("head"),!0)},getBody:function(){return new CKEDITOR.dom.element(this.$.body)},getDocumentElement:function(){return new CKEDITOR.dom.element(this.$.documentElement)},getWindow:function(){return new CKEDITOR.dom.window(this.$.parentWindow||this.$.defaultView)},write:function(a){this.$.open("text/html","replace");CKEDITOR.env.ie&&(a=a.replace(/(?:^\s*<!DOCTYPE[^>]*?>)|^/i,'$\x26\n\x3cscript data-cke-temp\x3d"1"\x3e('+
+CKEDITOR.tools.fixDomain+")();\x3c/script\x3e"));this.$.write(a);this.$.close()},find:function(a){return new CKEDITOR.dom.nodeList(this.$.querySelectorAll(a))},findOne:function(a){return(a=this.$.querySelector(a))?new CKEDITOR.dom.element(a):null},_getHtml5ShivFrag:function(){var a=this.getCustomData("html5ShivFrag");a||(a=this.$.createDocumentFragment(),CKEDITOR.tools.enableHtml5Elements(a,!0),this.setCustomData("html5ShivFrag",a));return a}});CKEDITOR.dom.nodeList=function(a){this.$=a};
+CKEDITOR.dom.nodeList.prototype={count:function(){return this.$.length},getItem:function(a){return 0>a||a>=this.$.length?null:(a=this.$[a])?new CKEDITOR.dom.node(a):null}};CKEDITOR.dom.element=function(a,d){"string"==typeof a&&(a=(d?d.$:document).createElement(a));CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.element.get=function(a){return(a="string"==typeof a?document.getElementById(a)||document.getElementsByName(a)[0]:a)&&(a.$?a:new CKEDITOR.dom.element(a))};CKEDITOR.dom.element.prototype=new CKEDITOR.dom.node;
+CKEDITOR.dom.element.createFromHtml=function(a,d){var b=new CKEDITOR.dom.element("div",d);b.setHtml(a);return b.getFirst().remove()};CKEDITOR.dom.element.setMarker=function(a,d,b,c){var e=d.getCustomData("list_marker_id")||d.setCustomData("list_marker_id",CKEDITOR.tools.getNextNumber()).getCustomData("list_marker_id"),g=d.getCustomData("list_marker_names")||d.setCustomData("list_marker_names",{}).getCustomData("list_marker_names");a[e]=d;g[b]=1;return d.setCustomData(b,c)};
+CKEDITOR.dom.element.clearAllMarkers=function(a){for(var d in a)CKEDITOR.dom.element.clearMarkers(a,a[d],1)};CKEDITOR.dom.element.clearMarkers=function(a,d,b){var c=d.getCustomData("list_marker_names"),e=d.getCustomData("list_marker_id"),g;for(g in c)d.removeCustomData(g);d.removeCustomData("list_marker_names");b&&(d.removeCustomData("list_marker_id"),delete a[e])};
+(function(){function a(a,b){return-1<(" "+a+" ").replace(g," ").indexOf(" "+b+" ")}function d(a){var b=!0;a.$.id||(a.$.id="cke_tmp_"+CKEDITOR.tools.getNextNumber(),b=!1);return function(){b||a.removeAttribute("id")}}function b(a,b){var c=CKEDITOR.tools.escapeCss(a.$.id);return"#"+c+" "+b.split(/,\s*/).join(", #"+c+" ")}function c(a){for(var b=0,c=0,f=k[a].length;c<f;c++)b+=parseFloat(this.getComputedStyle(k[a][c])||0,10)||0;return b}var e=document.createElement("_").classList,e="undefined"!==typeof e&&
+null!==String(e.add).match(/\[Native code\]/gi),g=/[\n\t\r]/g;CKEDITOR.tools.extend(CKEDITOR.dom.element.prototype,{type:CKEDITOR.NODE_ELEMENT,addClass:e?function(a){this.$.classList.add(a);return this}:function(b){var c=this.$.className;c&&(a(c,b)||(c+=" "+b));this.$.className=c||b;return this},removeClass:e?function(a){var b=this.$;b.classList.remove(a);b.className||b.removeAttribute("class");return this}:function(b){var c=this.getAttribute("class");c&&a(c,b)&&((c=c.replace(new RegExp("(?:^|\\s+)"+
+b+"(?\x3d\\s|$)"),"").replace(/^\s+/,""))?this.setAttribute("class",c):this.removeAttribute("class"));return this},hasClass:function(b){return a(this.$.className,b)},append:function(a,b){"string"==typeof a&&(a=this.getDocument().createElement(a));b?this.$.insertBefore(a.$,this.$.firstChild):this.$.appendChild(a.$);return a},appendHtml:function(a){if(this.$.childNodes.length){var b=new CKEDITOR.dom.element("div",this.getDocument());b.setHtml(a);b.moveChildren(this)}else this.setHtml(a)},appendText:function(a){null!=
+this.$.text&&CKEDITOR.env.ie&&9>CKEDITOR.env.version?this.$.text+=a:this.append(new CKEDITOR.dom.text(a))},appendBogus:function(a){if(a||CKEDITOR.env.needsBrFiller){for(a=this.getLast();a&&a.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.rtrim(a.getText());)a=a.getPrevious();a&&a.is&&a.is("br")||(a=this.getDocument().createElement("br"),CKEDITOR.env.gecko&&a.setAttribute("type","_moz"),this.append(a))}},breakParent:function(a,b){var c=new CKEDITOR.dom.range(this.getDocument());c.setStartAfter(this);c.setEndAfter(a);
+var f=c.extractContents(!1,b||!1),d;c.insertNode(this.remove());if(CKEDITOR.env.ie&&!CKEDITOR.env.edge){for(c=new CKEDITOR.dom.element("div");d=f.getFirst();)d.$.style.backgroundColor&&(d.$.style.backgroundColor=d.$.style.backgroundColor),c.append(d);c.insertAfter(this);c.remove(!0)}else f.insertAfterNode(this)},contains:document.compareDocumentPosition?function(a){return!!(this.$.compareDocumentPosition(a.$)&16)}:function(a){var b=this.$;return a.type!=CKEDITOR.NODE_ELEMENT?b.contains(a.getParent().$):
+b!=a.$&&b.contains(a.$)},focus:function(){function a(){try{this.$.focus()}catch(b){}}return function(b){b?CKEDITOR.tools.setTimeout(a,100,this):a.call(this)}}(),getHtml:function(){var a=this.$.innerHTML;return CKEDITOR.env.ie?a.replace(/<\?[^>]*>/g,""):a},getOuterHtml:function(){if(this.$.outerHTML)return this.$.outerHTML.replace(/<\?[^>]*>/,"");var a=this.$.ownerDocument.createElement("div");a.appendChild(this.$.cloneNode(!0));return a.innerHTML},getClientRect:function(){var a=CKEDITOR.tools.extend({},
+this.$.getBoundingClientRect());!a.width&&(a.width=a.right-a.left);!a.height&&(a.height=a.bottom-a.top);return a},setHtml:CKEDITOR.env.ie&&9>CKEDITOR.env.version?function(a){try{var b=this.$;if(this.getParent())return b.innerHTML=a;var c=this.getDocument()._getHtml5ShivFrag();c.appendChild(b);b.innerHTML=a;c.removeChild(b);return a}catch(f){this.$.innerHTML="";b=new CKEDITOR.dom.element("body",this.getDocument());b.$.innerHTML=a;for(b=b.getChildren();b.count();)this.append(b.getItem(0));return a}}:
+function(a){return this.$.innerHTML=a},setText:function(){var a=document.createElement("p");a.innerHTML="x";a=a.textContent;return function(b){this.$[a?"textContent":"innerText"]=b}}(),getAttribute:function(){var a=function(a){return this.$.getAttribute(a,2)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.quirks)?function(a){switch(a){case "class":a="className";break;case "http-equiv":a="httpEquiv";break;case "name":return this.$.name;case "tabindex":return a=this.$.getAttribute(a,
+2),0!==a&&0===this.$.tabIndex&&(a=null),a;case "checked":return a=this.$.attributes.getNamedItem(a),(a.specified?a.nodeValue:this.$.checked)?"checked":null;case "hspace":case "value":return this.$[a];case "style":return this.$.style.cssText;case "contenteditable":case "contentEditable":return this.$.attributes.getNamedItem("contentEditable").specified?this.$.getAttribute("contentEditable"):null}return this.$.getAttribute(a,2)}:a}(),getAttributes:function(a){var b={},c=this.$.attributes,f;a=CKEDITOR.tools.isArray(a)?
+a:[];for(f=0;f<c.length;f++)-1===CKEDITOR.tools.indexOf(a,c[f].name)&&(b[c[f].name]=c[f].value);return b},getChildren:function(){return new CKEDITOR.dom.nodeList(this.$.childNodes)},getComputedStyle:document.defaultView&&document.defaultView.getComputedStyle?function(a){var b=this.getWindow().$.getComputedStyle(this.$,null);return b?b.getPropertyValue(a):""}:function(a){return this.$.currentStyle[CKEDITOR.tools.cssStyleToDomStyle(a)]},getDtd:function(){var a=CKEDITOR.dtd[this.getName()];this.getDtd=
+function(){return a};return a},getElementsByTag:CKEDITOR.dom.document.prototype.getElementsByTag,getTabIndex:function(){var a=this.$.tabIndex;return 0!==a||CKEDITOR.dtd.$tabIndex[this.getName()]||0===parseInt(this.getAttribute("tabindex"),10)?a:-1},getText:function(){return this.$.textContent||this.$.innerText||""},getWindow:function(){return this.getDocument().getWindow()},getId:function(){return this.$.id||null},getNameAtt:function(){return this.$.name||null},getName:function(){var a=this.$.nodeName.toLowerCase();
+if(CKEDITOR.env.ie&&8>=document.documentMode){var b=this.$.scopeName;"HTML"!=b&&(a=b.toLowerCase()+":"+a)}this.getName=function(){return a};return this.getName()},getValue:function(){return this.$.value},getFirst:function(a){var b=this.$.firstChild;(b=b&&new CKEDITOR.dom.node(b))&&a&&!a(b)&&(b=b.getNext(a));return b},getLast:function(a){var b=this.$.lastChild;(b=b&&new CKEDITOR.dom.node(b))&&a&&!a(b)&&(b=b.getPrevious(a));return b},getStyle:function(a){return this.$.style[CKEDITOR.tools.cssStyleToDomStyle(a)]},
+is:function(){var a=this.getName();if("object"==typeof arguments[0])return!!arguments[0][a];for(var b=0;b<arguments.length;b++)if(arguments[b]==a)return!0;return!1},isEditable:function(a){var b=this.getName();return this.isReadOnly()||"none"==this.getComputedStyle("display")||"hidden"==this.getComputedStyle("visibility")||CKEDITOR.dtd.$nonEditable[b]||CKEDITOR.dtd.$empty[b]||this.is("a")&&(this.data("cke-saved-name")||this.hasAttribute("name"))&&!this.getChildCount()?!1:!1!==a?(a=CKEDITOR.dtd[b]||
+CKEDITOR.dtd.span,!(!a||!a["#"])):!0},isIdentical:function(a){var b=this.clone(0,1);a=a.clone(0,1);b.removeAttributes(["_moz_dirty","data-cke-expando","data-cke-saved-href","data-cke-saved-name"]);a.removeAttributes(["_moz_dirty","data-cke-expando","data-cke-saved-href","data-cke-saved-name"]);if(b.$.isEqualNode)return b.$.style.cssText=CKEDITOR.tools.normalizeCssText(b.$.style.cssText),a.$.style.cssText=CKEDITOR.tools.normalizeCssText(a.$.style.cssText),b.$.isEqualNode(a.$);b=b.getOuterHtml();a=
+a.getOuterHtml();if(CKEDITOR.env.ie&&9>CKEDITOR.env.version&&this.is("a")){var c=this.getParent();c.type==CKEDITOR.NODE_ELEMENT&&(c=c.clone(),c.setHtml(b),b=c.getHtml(),c.setHtml(a),a=c.getHtml())}return b==a},isVisible:function(){var a=(this.$.offsetHeight||this.$.offsetWidth)&&"hidden"!=this.getComputedStyle("visibility"),b,c;a&&CKEDITOR.env.webkit&&(b=this.getWindow(),!b.equals(CKEDITOR.document.getWindow())&&(c=b.$.frameElement)&&(a=(new CKEDITOR.dom.element(c)).isVisible()));return!!a},isEmptyInlineRemoveable:function(){if(!CKEDITOR.dtd.$removeEmpty[this.getName()])return!1;
+for(var a=this.getChildren(),b=0,c=a.count();b<c;b++){var f=a.getItem(b);if(f.type!=CKEDITOR.NODE_ELEMENT||!f.data("cke-bookmark"))if(f.type==CKEDITOR.NODE_ELEMENT&&!f.isEmptyInlineRemoveable()||f.type==CKEDITOR.NODE_TEXT&&CKEDITOR.tools.trim(f.getText()))return!1}return!0},hasAttributes:CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.quirks)?function(){for(var a=this.$.attributes,b=0;b<a.length;b++){var c=a[b];switch(c.nodeName){case "class":if(this.getAttribute("class"))return!0;case "data-cke-expando":continue;
+default:if(c.specified)return!0}}return!1}:function(){var a=this.$.attributes,b=a.length,c={"data-cke-expando":1,_moz_dirty:1};return 0<b&&(2<b||!c[a[0].nodeName]||2==b&&!c[a[1].nodeName])},hasAttribute:function(){function a(b){var c=this.$.attributes.getNamedItem(b);if("input"==this.getName())switch(b){case "class":return 0<this.$.className.length;case "checked":return!!this.$.checked;case "value":return b=this.getAttribute("type"),"checkbox"==b||"radio"==b?"on"!=this.$.value:!!this.$.value}return c?
+c.specified:!1}return CKEDITOR.env.ie?8>CKEDITOR.env.version?function(b){return"name"==b?!!this.$.name:a.call(this,b)}:a:function(a){return!!this.$.attributes.getNamedItem(a)}}(),hide:function(){this.setStyle("display","none")},moveChildren:function(a,b){var c=this.$;a=a.$;if(c!=a){var f;if(b)for(;f=c.lastChild;)a.insertBefore(c.removeChild(f),a.firstChild);else for(;f=c.firstChild;)a.appendChild(c.removeChild(f))}},mergeSiblings:function(){function a(b,c,f){if(c&&c.type==CKEDITOR.NODE_ELEMENT){for(var d=
+[];c.data("cke-bookmark")||c.isEmptyInlineRemoveable();)if(d.push(c),c=f?c.getNext():c.getPrevious(),!c||c.type!=CKEDITOR.NODE_ELEMENT)return;if(b.isIdentical(c)){for(var h=f?b.getLast():b.getFirst();d.length;)d.shift().move(b,!f);c.moveChildren(b,!f);c.remove();h&&h.type==CKEDITOR.NODE_ELEMENT&&h.mergeSiblings()}}}return function(b){if(!1===b||CKEDITOR.dtd.$removeEmpty[this.getName()]||this.is("a"))a(this,this.getNext(),!0),a(this,this.getPrevious())}}(),show:function(){this.setStyles({display:"",
+visibility:""})},setAttribute:function(){var a=function(a,b){this.$.setAttribute(a,b);return this};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.quirks)?function(b,c){"class"==b?this.$.className=c:"style"==b?this.$.style.cssText=c:"tabindex"==b?this.$.tabIndex=c:"checked"==b?this.$.checked=c:"contenteditable"==b?a.call(this,"contentEditable",c):a.apply(this,arguments);return this}:CKEDITOR.env.ie8Compat&&CKEDITOR.env.secure?function(b,c){if("src"==b&&c.match(/^http:\/\//))try{a.apply(this,
+arguments)}catch(f){}else a.apply(this,arguments);return this}:a}(),setAttributes:function(a){for(var b in a)this.setAttribute(b,a[b]);return this},setValue:function(a){this.$.value=a;return this},removeAttribute:function(){var a=function(a){this.$.removeAttribute(a)};return CKEDITOR.env.ie&&(CKEDITOR.env.ie7Compat||CKEDITOR.env.quirks)?function(a){"class"==a?a="className":"tabindex"==a?a="tabIndex":"contenteditable"==a&&(a="contentEditable");this.$.removeAttribute(a)}:a}(),removeAttributes:function(a){if(CKEDITOR.tools.isArray(a))for(var b=
+0;b<a.length;b++)this.removeAttribute(a[b]);else for(b in a=a||this.getAttributes(),a)a.hasOwnProperty(b)&&this.removeAttribute(b)},removeStyle:function(a){var b=this.$.style;if(b.removeProperty||"border"!=a&&"margin"!=a&&"padding"!=a)b.removeProperty?b.removeProperty(a):b.removeAttribute(CKEDITOR.tools.cssStyleToDomStyle(a)),this.$.style.cssText||this.removeAttribute("style");else{var c=["top","left","right","bottom"],f;"border"==a&&(f=["color","style","width"]);for(var b=[],d=0;d<c.length;d++)if(f)for(var u=
+0;u<f.length;u++)b.push([a,c[d],f[u]].join("-"));else b.push([a,c[d]].join("-"));for(a=0;a<b.length;a++)this.removeStyle(b[a])}},setStyle:function(a,b){this.$.style[CKEDITOR.tools.cssStyleToDomStyle(a)]=b;return this},setStyles:function(a){for(var b in a)this.setStyle(b,a[b]);return this},setOpacity:function(a){CKEDITOR.env.ie&&9>CKEDITOR.env.version?(a=Math.round(100*a),this.setStyle("filter",100<=a?"":"progid:DXImageTransform.Microsoft.Alpha(opacity\x3d"+a+")")):this.setStyle("opacity",a)},unselectable:function(){this.setStyles(CKEDITOR.tools.cssVendorPrefix("user-select",
+"none"));if(CKEDITOR.env.ie){this.setAttribute("unselectable","on");for(var a,b=this.getElementsByTag("*"),c=0,f=b.count();c<f;c++)a=b.getItem(c),a.setAttribute("unselectable","on")}},getPositionedAncestor:function(){for(var a=this;"html"!=a.getName();){if("static"!=a.getComputedStyle("position"))return a;a=a.getParent()}return null},getDocumentPosition:function(a){var b=0,c=0,f=this.getDocument(),d=f.getBody(),u="BackCompat"==f.$.compatMode;if(document.documentElement.getBoundingClientRect&&(CKEDITOR.env.ie?
+8!==CKEDITOR.env.version:1)){var e=this.$.getBoundingClientRect(),g=f.$.documentElement,m=g.clientTop||d.$.clientTop||0,x=g.clientLeft||d.$.clientLeft||0,k=!0;CKEDITOR.env.ie&&(k=f.getDocumentElement().contains(this),f=f.getBody().contains(this),k=u&&f||!u&&k);k&&(CKEDITOR.env.webkit||CKEDITOR.env.ie&&12<=CKEDITOR.env.version?(b=d.$.scrollLeft||g.scrollLeft,c=d.$.scrollTop||g.scrollTop):(c=u?d.$:g,b=c.scrollLeft,c=c.scrollTop),b=e.left+b-x,c=e.top+c-m)}else for(m=this,x=null;m&&"body"!=m.getName()&&
+"html"!=m.getName();){b+=m.$.offsetLeft-m.$.scrollLeft;c+=m.$.offsetTop-m.$.scrollTop;m.equals(this)||(b+=m.$.clientLeft||0,c+=m.$.clientTop||0);for(;x&&!x.equals(m);)b-=x.$.scrollLeft,c-=x.$.scrollTop,x=x.getParent();x=m;m=(e=m.$.offsetParent)?new CKEDITOR.dom.element(e):null}a&&(e=this.getWindow(),m=a.getWindow(),!e.equals(m)&&e.$.frameElement&&(a=(new CKEDITOR.dom.element(e.$.frameElement)).getDocumentPosition(a),b+=a.x,c+=a.y));document.documentElement.getBoundingClientRect||!CKEDITOR.env.gecko||
+u||(b+=this.$.clientLeft?1:0,c+=this.$.clientTop?1:0);return{x:b,y:c}},scrollIntoView:function(a){var b=this.getParent();if(b){do if((b.$.clientWidth&&b.$.clientWidth<b.$.scrollWidth||b.$.clientHeight&&b.$.clientHeight<b.$.scrollHeight)&&!b.is("body")&&this.scrollIntoParent(b,a,1),b.is("html")){var c=b.getWindow();try{var f=c.$.frameElement;f&&(b=new CKEDITOR.dom.element(f))}catch(d){}}while(b=b.getParent())}},scrollIntoParent:function(a,b,c){var f,d,e,z;function g(b,c){/body|html/.test(a.getName())?
+a.getWindow().$.scrollBy(b,c):(a.$.scrollLeft+=b,a.$.scrollTop+=c)}function m(a,b){var c={x:0,y:0};if(!a.is(k?"body":"html")){var f=a.$.getBoundingClientRect();c.x=f.left;c.y=f.top}f=a.getWindow();f.equals(b)||(f=m(CKEDITOR.dom.element.get(f.$.frameElement),b),c.x+=f.x,c.y+=f.y);return c}function x(a,b){return parseInt(a.getComputedStyle("margin-"+b)||0,10)||0}!a&&(a=this.getWindow());e=a.getDocument();var k="BackCompat"==e.$.compatMode;a instanceof CKEDITOR.dom.window&&(a=k?e.getBody():e.getDocumentElement());
+CKEDITOR.env.webkit&&(e=this.getEditor(!1))&&(e._.previousScrollTop=null);e=a.getWindow();d=m(this,e);var w=m(a,e),F=this.$.offsetHeight;f=this.$.offsetWidth;var l=a.$.clientHeight,q=a.$.clientWidth;e=d.x-x(this,"left")-w.x||0;z=d.y-x(this,"top")-w.y||0;f=d.x+f+x(this,"right")-(w.x+q)||0;d=d.y+F+x(this,"bottom")-(w.y+l)||0;(0>z||0<d)&&g(0,!0===b?z:!1===b?d:0>z?z:d);c&&(0>e||0<f)&&g(0>e?e:f,0)},setState:function(a,b,c){b=b||"cke";switch(a){case CKEDITOR.TRISTATE_ON:this.addClass(b+"_on");this.removeClass(b+
+"_off");this.removeClass(b+"_disabled");c&&this.setAttribute("aria-pressed",!0);c&&this.removeAttribute("aria-disabled");break;case CKEDITOR.TRISTATE_DISABLED:this.addClass(b+"_disabled");this.removeClass(b+"_off");this.removeClass(b+"_on");c&&this.setAttribute("aria-disabled",!0);c&&this.removeAttribute("aria-pressed");break;default:this.addClass(b+"_off"),this.removeClass(b+"_on"),this.removeClass(b+"_disabled"),c&&this.removeAttribute("aria-pressed"),c&&this.removeAttribute("aria-disabled")}},
+getFrameDocument:function(){var a=this.$;try{a.contentWindow.document}catch(b){a.src=a.src}return a&&new CKEDITOR.dom.document(a.contentWindow.document)},copyAttributes:function(a,b){var c=this.$.attributes;b=b||{};for(var f=0;f<c.length;f++){var d=c[f],e=d.nodeName.toLowerCase(),g;if(!(e in b))if("checked"==e&&(g=this.getAttribute(e)))a.setAttribute(e,g);else if(!CKEDITOR.env.ie||this.hasAttribute(e))g=this.getAttribute(e),null===g&&(g=d.nodeValue),a.setAttribute(e,g)}""!==this.$.style.cssText&&
+(a.$.style.cssText=this.$.style.cssText)},renameNode:function(a){if(this.getName()!=a){var b=this.getDocument();a=new CKEDITOR.dom.element(a,b);this.copyAttributes(a);this.moveChildren(a);this.getParent(!0)&&this.$.parentNode.replaceChild(a.$,this.$);a.$["data-cke-expando"]=this.$["data-cke-expando"];this.$=a.$;delete this.getName}},getChild:function(){function a(b,c){var f=b.childNodes;if(0<=c&&c<f.length)return f[c]}return function(b){var c=this.$;if(b.slice)for(b=b.slice();0<b.length&&c;)c=a(c,
+b.shift());else c=a(c,b);return c?new CKEDITOR.dom.node(c):null}}(),getChildCount:function(){return this.$.childNodes.length},disableContextMenu:function(){function a(b){return b.type==CKEDITOR.NODE_ELEMENT&&b.hasClass("cke_enable_context_menu")}this.on("contextmenu",function(b){b.data.getTarget().getAscendant(a,!0)||b.data.preventDefault()})},getDirection:function(a){return a?this.getComputedStyle("direction")||this.getDirection()||this.getParent()&&this.getParent().getDirection(1)||this.getDocument().$.dir||
+"ltr":this.getStyle("direction")||this.getAttribute("dir")},data:function(a,b){a="data-"+a;if(void 0===b)return this.getAttribute(a);!1===b?this.removeAttribute(a):this.setAttribute(a,b);return null},getEditor:function(a){var b=CKEDITOR.instances,c,f,d;a=a||void 0===a;for(c in b)if(f=b[c],f.element.equals(this)&&f.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO||!a&&(d=f.editable())&&(d.equals(this)||d.contains(this)))return f;return null},find:function(a){var c=d(this);a=new CKEDITOR.dom.nodeList(this.$.querySelectorAll(b(this,
+a)));c();return a},findOne:function(a){var c=d(this);a=this.$.querySelector(b(this,a));c();return a?new CKEDITOR.dom.element(a):null},forEach:function(a,b,c){if(!(c||b&&this.type!=b))var f=a(this);if(!1!==f){c=this.getChildren();for(var d=0;d<c.count();d++)f=c.getItem(d),f.type==CKEDITOR.NODE_ELEMENT?f.forEach(a,b):b&&f.type!=b||a(f)}}});var k={width:["border-left-width","border-right-width","padding-left","padding-right"],height:["border-top-width","border-bottom-width","padding-top","padding-bottom"]};
+CKEDITOR.dom.element.prototype.setSize=function(a,b,d){"number"==typeof b&&(!d||CKEDITOR.env.ie&&CKEDITOR.env.quirks||(b-=c.call(this,a)),this.setStyle(a,b+"px"))};CKEDITOR.dom.element.prototype.getSize=function(a,b){var d=Math.max(this.$["offset"+CKEDITOR.tools.capitalize(a)],this.$["client"+CKEDITOR.tools.capitalize(a)])||0;b&&(d-=c.call(this,a));return d}})();CKEDITOR.dom.documentFragment=function(a){a=a||CKEDITOR.document;this.$=a.type==CKEDITOR.NODE_DOCUMENT?a.$.createDocumentFragment():a};
+CKEDITOR.tools.extend(CKEDITOR.dom.documentFragment.prototype,CKEDITOR.dom.element.prototype,{type:CKEDITOR.NODE_DOCUMENT_FRAGMENT,insertAfterNode:function(a){a=a.$;a.parentNode.insertBefore(this.$,a.nextSibling)},getHtml:function(){var a=new CKEDITOR.dom.element("div");this.clone(1,1).appendTo(a);return a.getHtml().replace(/\s*data-cke-expando=".*?"/g,"")}},!0,{append:1,appendBogus:1,clone:1,getFirst:1,getHtml:1,getLast:1,getParent:1,getNext:1,getPrevious:1,appendTo:1,moveChildren:1,insertBefore:1,
+insertAfterNode:1,replace:1,trim:1,type:1,ltrim:1,rtrim:1,getDocument:1,getChildCount:1,getChild:1,getChildren:1});
+(function(){function a(a,b){var c=this.range;if(this._.end)return null;if(!this._.start){this._.start=1;if(c.collapsed)return this.end(),null;c.optimize()}var f,d=c.startContainer;f=c.endContainer;var e=c.startOffset,B=c.endOffset,g,l=this.guard,q=this.type,n=a?"getPreviousSourceNode":"getNextSourceNode";if(!a&&!this._.guardLTR){var t=f.type==CKEDITOR.NODE_ELEMENT?f:f.getParent(),A=f.type==CKEDITOR.NODE_ELEMENT?f.getChild(B):f.getNext();this._.guardLTR=function(a,b){return(!b||!t.equals(a))&&(!A||
+!a.equals(A))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}if(a&&!this._.guardRTL){var C=d.type==CKEDITOR.NODE_ELEMENT?d:d.getParent(),h=d.type==CKEDITOR.NODE_ELEMENT?e?d.getChild(e-1):null:d.getPrevious();this._.guardRTL=function(a,b){return(!b||!C.equals(a))&&(!h||!a.equals(h))&&(a.type!=CKEDITOR.NODE_ELEMENT||!b||!a.equals(c.root))}}var k=a?this._.guardRTL:this._.guardLTR;g=l?function(a,b){return!1===k(a,b)?!1:l(a,b)}:k;this.current?f=this.current[n](!1,q,g):(a?f.type==CKEDITOR.NODE_ELEMENT&&
+(f=0<B?f.getChild(B-1):!1===g(f,!0)?null:f.getPreviousSourceNode(!0,q,g)):(f=d,f.type==CKEDITOR.NODE_ELEMENT&&((f=f.getChild(e))||(f=!1===g(d,!0)?null:d.getNextSourceNode(!0,q,g)))),f&&!1===g(f)&&(f=null));for(;f&&!this._.end;){this.current=f;if(!this.evaluator||!1!==this.evaluator(f)){if(!b)return f}else if(b&&this.evaluator)return!1;f=f[n](!1,q,g)}this.end();return this.current=null}function d(b){for(var c,f=null;c=a.call(this,b);)f=c;return f}CKEDITOR.dom.walker=CKEDITOR.tools.createClass({$:function(a){this.range=
+a;this._={}},proto:{end:function(){this._.end=1},next:function(){return a.call(this)},previous:function(){return a.call(this,1)},checkForward:function(){return!1!==a.call(this,0,1)},checkBackward:function(){return!1!==a.call(this,1,1)},lastForward:function(){return d.call(this)},lastBackward:function(){return d.call(this,1)},reset:function(){delete this.current;this._={}}}});var b={block:1,"list-item":1,table:1,"table-row-group":1,"table-header-group":1,"table-footer-group":1,"table-row":1,"table-column-group":1,
+"table-column":1,"table-cell":1,"table-caption":1},c={absolute:1,fixed:1};CKEDITOR.dom.element.prototype.isBlockBoundary=function(a){return"none"!=this.getComputedStyle("float")||this.getComputedStyle("position")in c||!b[this.getComputedStyle("display")]?!!(this.is(CKEDITOR.dtd.$block)||a&&this.is(a)):!0};CKEDITOR.dom.walker.blockBoundary=function(a){return function(b){return!(b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary(a))}};CKEDITOR.dom.walker.listItemBoundary=function(){return this.blockBoundary({br:1})};
+CKEDITOR.dom.walker.bookmark=function(a,b){function c(a){return a&&a.getName&&"span"==a.getName()&&a.data("cke-bookmark")}return function(f){var d,e;d=f&&f.type!=CKEDITOR.NODE_ELEMENT&&(e=f.getParent())&&c(e);d=a?d:d||c(f);return!!(b^d)}};CKEDITOR.dom.walker.whitespaces=function(a){return function(b){var c;b&&b.type==CKEDITOR.NODE_TEXT&&(c=!CKEDITOR.tools.trim(b.getText())||CKEDITOR.env.webkit&&b.getText()==CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE);return!!(a^c)}};CKEDITOR.dom.walker.invisible=
+function(a){var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.env.webkit?1:0;return function(f){b(f)?f=1:(f.type==CKEDITOR.NODE_TEXT&&(f=f.getParent()),f=f.$.offsetWidth<=c);return!!(a^f)}};CKEDITOR.dom.walker.nodeType=function(a,b){return function(c){return!!(b^c.type==a)}};CKEDITOR.dom.walker.bogus=function(a){function b(a){return!g(a)&&!k(a)}return function(c){var f=CKEDITOR.env.needsBrFiller?c.is&&c.is("br"):c.getText&&e.test(c.getText());f&&(f=c.getParent(),c=c.getNext(b),f=f.isBlockBoundary()&&
+(!c||c.type==CKEDITOR.NODE_ELEMENT&&c.isBlockBoundary()));return!!(a^f)}};CKEDITOR.dom.walker.temp=function(a){return function(b){b.type!=CKEDITOR.NODE_ELEMENT&&(b=b.getParent());b=b&&b.hasAttribute("data-cke-temp");return!!(a^b)}};var e=/^[\t\r\n ]*(?:&nbsp;|\xa0)$/,g=CKEDITOR.dom.walker.whitespaces(),k=CKEDITOR.dom.walker.bookmark(),h=CKEDITOR.dom.walker.temp(),p=function(a){return k(a)||g(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.is(CKEDITOR.dtd.$inline)&&!a.is(CKEDITOR.dtd.$empty)};CKEDITOR.dom.walker.ignored=
+function(a){return function(b){b=g(b)||k(b)||h(b);return!!(a^b)}};var r=CKEDITOR.dom.walker.ignored();CKEDITOR.dom.walker.empty=function(a){return function(b){for(var c=0,f=b.getChildCount();c<f;++c)if(!r(b.getChild(c)))return!!a;return!a}};var f=CKEDITOR.dom.walker.empty(),B=CKEDITOR.dom.walker.validEmptyBlockContainers=CKEDITOR.tools.extend(function(a){var b={},c;for(c in a)CKEDITOR.dtd[c]["#"]&&(b[c]=1);return b}(CKEDITOR.dtd.$block),{caption:1,td:1,th:1});CKEDITOR.dom.walker.editable=function(a){return function(b){b=
+r(b)?!1:b.type==CKEDITOR.NODE_TEXT||b.type==CKEDITOR.NODE_ELEMENT&&(b.is(CKEDITOR.dtd.$inline)||b.is("hr")||"false"==b.getAttribute("contenteditable")||!CKEDITOR.env.needsBrFiller&&b.is(B)&&f(b))?!0:!1;return!!(a^b)}};CKEDITOR.dom.element.prototype.getBogus=function(){var a=this;do a=a.getPreviousSourceNode();while(p(a));return a&&(CKEDITOR.env.needsBrFiller?a.is&&a.is("br"):a.getText&&e.test(a.getText()))?a:!1}})();
+CKEDITOR.dom.range=function(a){this.endOffset=this.endContainer=this.startOffset=this.startContainer=null;this.collapsed=!0;var d=a instanceof CKEDITOR.dom.document;this.document=d?a:a.getDocument();this.root=d?a.getBody():a};
+(function(){function a(a){a.collapsed=a.startContainer&&a.endContainer&&a.startContainer.equals(a.endContainer)&&a.startOffset==a.endOffset}function d(a,b,c,d,e){function m(a,b,c,f){var d=c?a.getPrevious():a.getNext();if(f&&k)return d;l||f?b.append(a.clone(!0,e),c):(a.remove(),r&&b.append(a));return d}function g(){var a,b,c,f=Math.min(P.length,v.length);for(a=0;a<f;a++)if(b=P[a],c=v[a],!b.equals(c))return a;return a-1}function h(){var b=G-1,c=M&&H&&!q.equals(n);b<E-1||b<I-1||c?(c?a.moveToPosition(n,
+CKEDITOR.POSITION_BEFORE_START):I==b+1&&D?a.moveToPosition(v[b],CKEDITOR.POSITION_BEFORE_END):a.moveToPosition(v[b+1],CKEDITOR.POSITION_BEFORE_START),d&&(b=P[b+1])&&b.type==CKEDITOR.NODE_ELEMENT&&(c=CKEDITOR.dom.element.createFromHtml('\x3cspan data-cke-bookmark\x3d"1" style\x3d"display:none"\x3e\x26nbsp;\x3c/span\x3e',a.document),c.insertAfter(b),b.mergeSiblings(!1),a.moveToBookmark({startNode:c}))):a.collapse(!0)}a.optimizeBookmark();var k=0===b,r=1==b,l=2==b;b=l||r;var q=a.startContainer,n=a.endContainer,
+t=a.startOffset,A=a.endOffset,C,D,M,H,p,Q;if(l&&n.type==CKEDITOR.NODE_TEXT&&q.equals(n))q=a.document.createText(q.substring(t,A)),c.append(q);else{n.type==CKEDITOR.NODE_TEXT?l?Q=!0:n=n.split(A):0<n.getChildCount()?A>=n.getChildCount()?(n=n.getChild(A-1),D=!0):n=n.getChild(A):H=D=!0;q.type==CKEDITOR.NODE_TEXT?l?p=!0:q.split(t):0<q.getChildCount()?0===t?(q=q.getChild(t),C=!0):q=q.getChild(t-1):M=C=!0;for(var P=q.getParents(),v=n.getParents(),G=g(),E=P.length-1,I=v.length-1,K=c,L,Z,X,fa=-1,S=G;S<=E;S++){Z=
+P[S];X=Z.getNext();for(S!=E||Z.equals(v[S])&&E<I?b&&(L=K.append(Z.clone(0,e))):C?m(Z,K,!1,M):p&&K.append(a.document.createText(Z.substring(t)));X;){if(X.equals(v[S])){fa=S;break}X=m(X,K)}K=L}K=c;for(S=G;S<=I;S++)if(c=v[S],X=c.getPrevious(),c.equals(P[S]))b&&(K=K.getChild(0));else{S!=I||c.equals(P[S])&&I<E?b&&(L=K.append(c.clone(0,e))):D?m(c,K,!1,H):Q&&K.append(a.document.createText(c.substring(0,A)));if(S>fa)for(;X;)X=m(X,K,!0);K=L}l||h()}}function b(){var a=!1,b=CKEDITOR.dom.walker.whitespaces(),
+c=CKEDITOR.dom.walker.bookmark(!0),d=CKEDITOR.dom.walker.bogus();return function(e){return c(e)||b(e)?!0:d(e)&&!a?a=!0:e.type==CKEDITOR.NODE_TEXT&&(e.hasAscendant("pre")||CKEDITOR.tools.trim(e.getText()).length)||e.type==CKEDITOR.NODE_ELEMENT&&!e.is(g)?!1:!0}}function c(a){var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(1);return function(d){return c(d)||b(d)?!0:!a&&k(d)||d.type==CKEDITOR.NODE_ELEMENT&&d.is(CKEDITOR.dtd.$removeEmpty)}}function e(a){return function(){var b;return this[a?
+"getPreviousNode":"getNextNode"](function(a){!b&&r(a)&&(b=a);return p(a)&&!(k(a)&&a.equals(b))})}}var g={abbr:1,acronym:1,b:1,bdo:1,big:1,cite:1,code:1,del:1,dfn:1,em:1,font:1,i:1,ins:1,label:1,kbd:1,q:1,samp:1,small:1,span:1,strike:1,strong:1,sub:1,sup:1,tt:1,u:1,"var":1},k=CKEDITOR.dom.walker.bogus(),h=/^[\t\r\n ]*(?:&nbsp;|\xa0)$/,p=CKEDITOR.dom.walker.editable(),r=CKEDITOR.dom.walker.ignored(!0);CKEDITOR.dom.range.prototype={clone:function(){var a=new CKEDITOR.dom.range(this.root);a._setStartContainer(this.startContainer);
+a.startOffset=this.startOffset;a._setEndContainer(this.endContainer);a.endOffset=this.endOffset;a.collapsed=this.collapsed;return a},collapse:function(a){a?(this._setEndContainer(this.startContainer),this.endOffset=this.startOffset):(this._setStartContainer(this.endContainer),this.startOffset=this.endOffset);this.collapsed=!0},cloneContents:function(a){var b=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||d(this,2,b,!1,"undefined"==typeof a?!0:a);return b},deleteContents:function(a){this.collapsed||
+d(this,0,null,a)},extractContents:function(a,b){var c=new CKEDITOR.dom.documentFragment(this.document);this.collapsed||d(this,1,c,a,"undefined"==typeof b?!0:b);return c},createBookmark:function(a){var b,c,d,e,m=this.collapsed;b=this.document.createElement("span");b.data("cke-bookmark",1);b.setStyle("display","none");b.setHtml("\x26nbsp;");a&&(d="cke_bm_"+CKEDITOR.tools.getNextNumber(),b.setAttribute("id",d+(m?"C":"S")));m||(c=b.clone(),c.setHtml("\x26nbsp;"),a&&c.setAttribute("id",d+"E"),e=this.clone(),
+e.collapse(),e.insertNode(c));e=this.clone();e.collapse(!0);e.insertNode(b);c?(this.setStartAfter(b),this.setEndBefore(c)):this.moveToPosition(b,CKEDITOR.POSITION_AFTER_END);return{startNode:a?d+(m?"C":"S"):b,endNode:a?d+"E":c,serializable:a,collapsed:m}},createBookmark2:function(){function a(b){var f=b.container,d=b.offset,e;e=f;var g=d;e=e.type!=CKEDITOR.NODE_ELEMENT||0===g||g==e.getChildCount()?0:e.getChild(g-1).type==CKEDITOR.NODE_TEXT&&e.getChild(g).type==CKEDITOR.NODE_TEXT;e&&(f=f.getChild(d-
+1),d=f.getLength());if(f.type==CKEDITOR.NODE_ELEMENT&&0<d){a:{for(e=f;d--;)if(g=e.getChild(d).getIndex(!0),0<=g){d=g;break a}d=-1}d+=1}if(f.type==CKEDITOR.NODE_TEXT){e=f;for(g=0;(e=e.getPrevious())&&e.type==CKEDITOR.NODE_TEXT;)g+=e.getText().replace(CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE,"").length;e=g;f.getText()?d+=e:(g=f.getPrevious(c),e?(d=e,f=g?g.getNext():f.getParent().getFirst()):(f=f.getParent(),d=g?g.getIndex(!0)+1:0))}b.container=f;b.offset=d}function b(a,c){var f=c.getCustomData("cke-fillingChar");
+if(f){var d=a.container;f.equals(d)&&(a.offset-=CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE.length,0>=a.offset&&(a.offset=d.getIndex(),a.container=d.getParent()))}}var c=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_TEXT,!0);return function(c){var d=this.collapsed,e={container:this.startContainer,offset:this.startOffset},g={container:this.endContainer,offset:this.endOffset};c&&(a(e),b(e,this.root),d||(a(g),b(g,this.root)));return{start:e.container.getAddress(c),end:d?null:g.container.getAddress(c),
+startOffset:e.offset,endOffset:g.offset,normalized:c,collapsed:d,is2:!0}}}(),moveToBookmark:function(a){if(a.is2){var b=this.document.getByAddress(a.start,a.normalized),c=a.startOffset,d=a.end&&this.document.getByAddress(a.end,a.normalized);a=a.endOffset;this.setStart(b,c);d?this.setEnd(d,a):this.collapse(!0)}else b=(c=a.serializable)?this.document.getById(a.startNode):a.startNode,a=c?this.document.getById(a.endNode):a.endNode,this.setStartBefore(b),b.remove(),a?(this.setEndBefore(a),a.remove()):
+this.collapse(!0)},getBoundaryNodes:function(){var a=this.startContainer,b=this.endContainer,c=this.startOffset,d=this.endOffset,e;if(a.type==CKEDITOR.NODE_ELEMENT)if(e=a.getChildCount(),e>c)a=a.getChild(c);else if(1>e)a=a.getPreviousSourceNode();else{for(a=a.$;a.lastChild;)a=a.lastChild;a=new CKEDITOR.dom.node(a);a=a.getNextSourceNode()||a}if(b.type==CKEDITOR.NODE_ELEMENT)if(e=b.getChildCount(),e>d)b=b.getChild(d).getPreviousSourceNode(!0);else if(1>e)b=b.getPreviousSourceNode();else{for(b=b.$;b.lastChild;)b=
+b.lastChild;b=new CKEDITOR.dom.node(b)}a.getPosition(b)&CKEDITOR.POSITION_FOLLOWING&&(a=b);return{startNode:a,endNode:b}},getCommonAncestor:function(a,b){var c=this.startContainer,d=this.endContainer,c=c.equals(d)?a&&c.type==CKEDITOR.NODE_ELEMENT&&this.startOffset==this.endOffset-1?c.getChild(this.startOffset):c:c.getCommonAncestor(d);return b&&!c.is?c.getParent():c},optimize:function(){var a=this.startContainer,b=this.startOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>=a.getLength()&&this.setStartAfter(a):
+this.setStartBefore(a));a=this.endContainer;b=this.endOffset;a.type!=CKEDITOR.NODE_ELEMENT&&(b?b>=a.getLength()&&this.setEndAfter(a):this.setEndBefore(a))},optimizeBookmark:function(){var a=this.startContainer,b=this.endContainer;a.is&&a.is("span")&&a.data("cke-bookmark")&&this.setStartAt(a,CKEDITOR.POSITION_BEFORE_START);b&&b.is&&b.is("span")&&b.data("cke-bookmark")&&this.setEndAt(b,CKEDITOR.POSITION_AFTER_END)},trim:function(a,b){var c=this.startContainer,d=this.startOffset,e=this.collapsed;if((!a||
+e)&&c&&c.type==CKEDITOR.NODE_TEXT){if(d)if(d>=c.getLength())d=c.getIndex()+1,c=c.getParent();else{var m=c.split(d),d=c.getIndex()+1,c=c.getParent();this.startContainer.equals(this.endContainer)?this.setEnd(m,this.endOffset-this.startOffset):c.equals(this.endContainer)&&(this.endOffset+=1)}else d=c.getIndex(),c=c.getParent();this.setStart(c,d);if(e){this.collapse(!0);return}}c=this.endContainer;d=this.endOffset;b||e||!c||c.type!=CKEDITOR.NODE_TEXT||(d?(d>=c.getLength()||c.split(d),d=c.getIndex()+1):
+d=c.getIndex(),c=c.getParent(),this.setEnd(c,d))},enlarge:function(a,b){function c(a){return a&&a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute("contenteditable")?null:a}var d=new RegExp(/[^\s\ufeff]/);switch(a){case CKEDITOR.ENLARGE_INLINE:var e=1;case CKEDITOR.ENLARGE_ELEMENT:var m=function(a,b){var c=new CKEDITOR.dom.range(h);c.setStart(a,b);c.setEndAt(h,CKEDITOR.POSITION_BEFORE_END);var c=new CKEDITOR.dom.walker(c),f;for(c.guard=function(a){return!(a.type==CKEDITOR.NODE_ELEMENT&&a.isBlockBoundary())};f=
+c.next();){if(f.type!=CKEDITOR.NODE_TEXT)return!1;C=f!=a?f.getText():f.substring(b);if(d.test(C))return!1}return!0};if(this.collapsed)break;var g=this.getCommonAncestor(),h=this.root,k,r,l,q,n,t=!1,A,C;A=this.startContainer;var D=this.startOffset;A.type==CKEDITOR.NODE_TEXT?(D&&(A=!CKEDITOR.tools.trim(A.substring(0,D)).length&&A,t=!!A),A&&((q=A.getPrevious())||(l=A.getParent()))):(D&&(q=A.getChild(D-1)||A.getLast()),q||(l=A));for(l=c(l);l||q;){if(l&&!q){!n&&l.equals(g)&&(n=!0);if(e?l.isBlockBoundary():
+!h.contains(l))break;t&&"inline"==l.getComputedStyle("display")||(t=!1,n?k=l:this.setStartBefore(l));q=l.getPrevious()}for(;q;)if(A=!1,q.type==CKEDITOR.NODE_COMMENT)q=q.getPrevious();else{if(q.type==CKEDITOR.NODE_TEXT)C=q.getText(),d.test(C)&&(q=null),A=/[\s\ufeff]$/.test(C);else if((q.$.offsetWidth>(CKEDITOR.env.webkit?1:0)||b&&q.is("br"))&&!q.data("cke-bookmark"))if(t&&CKEDITOR.dtd.$removeEmpty[q.getName()]){C=q.getText();if(d.test(C))q=null;else for(var D=q.$.getElementsByTagName("*"),M=0,H;H=
+D[M++];)if(!CKEDITOR.dtd.$removeEmpty[H.nodeName.toLowerCase()]){q=null;break}q&&(A=!!C.length)}else q=null;A&&(t?n?k=l:l&&this.setStartBefore(l):t=!0);if(q){A=q.getPrevious();if(!l&&!A){l=q;q=null;break}q=A}else l=null}l&&(l=c(l.getParent()))}A=this.endContainer;D=this.endOffset;l=q=null;n=t=!1;A.type==CKEDITOR.NODE_TEXT?CKEDITOR.tools.trim(A.substring(D)).length?t=!0:(t=!A.getLength(),D==A.getLength()?(q=A.getNext())||(l=A.getParent()):m(A,D)&&(l=A.getParent())):(q=A.getChild(D))||(l=A);for(;l||
+q;){if(l&&!q){!n&&l.equals(g)&&(n=!0);if(e?l.isBlockBoundary():!h.contains(l))break;t&&"inline"==l.getComputedStyle("display")||(t=!1,n?r=l:l&&this.setEndAfter(l));q=l.getNext()}for(;q;){A=!1;if(q.type==CKEDITOR.NODE_TEXT)C=q.getText(),m(q,0)||(q=null),A=/^[\s\ufeff]/.test(C);else if(q.type==CKEDITOR.NODE_ELEMENT){if((0<q.$.offsetWidth||b&&q.is("br"))&&!q.data("cke-bookmark"))if(t&&CKEDITOR.dtd.$removeEmpty[q.getName()]){C=q.getText();if(d.test(C))q=null;else for(D=q.$.getElementsByTagName("*"),M=
+0;H=D[M++];)if(!CKEDITOR.dtd.$removeEmpty[H.nodeName.toLowerCase()]){q=null;break}q&&(A=!!C.length)}else q=null}else A=1;A&&t&&(n?r=l:this.setEndAfter(l));if(q){A=q.getNext();if(!l&&!A){l=q;q=null;break}q=A}else l=null}l&&(l=c(l.getParent()))}k&&r&&(g=k.contains(r)?r:k,this.setStartBefore(g),this.setEndAfter(g));break;case CKEDITOR.ENLARGE_BLOCK_CONTENTS:case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:l=new CKEDITOR.dom.range(this.root);h=this.root;l.setStartAt(h,CKEDITOR.POSITION_AFTER_START);l.setEnd(this.startContainer,
+this.startOffset);l=new CKEDITOR.dom.walker(l);var p,Q,P=CKEDITOR.dom.walker.blockBoundary(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?{br:1}:null),v=null,G=function(a){if(a.type==CKEDITOR.NODE_ELEMENT&&"false"==a.getAttribute("contenteditable"))if(v){if(v.equals(a)){v=null;return}}else v=a;else if(v)return;var b=P(a);b||(p=a);return b},e=function(a){var b=G(a);!b&&a.is&&a.is("br")&&(Q=a);return b};l.guard=G;l=l.lastBackward();p=p||h;this.setStartAt(p,!p.is("br")&&(!l&&this.checkStartOfBlock()||l&&p.contains(l))?
+CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_AFTER_END);if(a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS){l=this.clone();l=new CKEDITOR.dom.walker(l);var E=CKEDITOR.dom.walker.whitespaces(),I=CKEDITOR.dom.walker.bookmark();l.evaluator=function(a){return!E(a)&&!I(a)};if((l=l.previous())&&l.type==CKEDITOR.NODE_ELEMENT&&l.is("br"))break}l=this.clone();l.collapse();l.setEndAt(h,CKEDITOR.POSITION_BEFORE_END);l=new CKEDITOR.dom.walker(l);l.guard=a==CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS?e:G;p=v=Q=null;l=l.lastForward();
+p=p||h;this.setEndAt(p,!l&&this.checkEndOfBlock()||l&&p.contains(l)?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_BEFORE_START);Q&&this.setEndAfter(Q)}},shrink:function(a,b,c){if(!this.collapsed){a=a||CKEDITOR.SHRINK_TEXT;var d=this.clone(),e=this.startContainer,m=this.endContainer,g=this.startOffset,h=this.endOffset,k=1,r=1;e&&e.type==CKEDITOR.NODE_TEXT&&(g?g>=e.getLength()?d.setStartAfter(e):(d.setStartBefore(e),k=0):d.setStartBefore(e));m&&m.type==CKEDITOR.NODE_TEXT&&(h?h>=m.getLength()?d.setEndAfter(m):
+(d.setEndAfter(m),r=0):d.setEndBefore(m));var d=new CKEDITOR.dom.walker(d),l=CKEDITOR.dom.walker.bookmark();d.evaluator=function(b){return b.type==(a==CKEDITOR.SHRINK_ELEMENT?CKEDITOR.NODE_ELEMENT:CKEDITOR.NODE_TEXT)};var q;d.guard=function(b,d){if(l(b))return!0;if(a==CKEDITOR.SHRINK_ELEMENT&&b.type==CKEDITOR.NODE_TEXT||d&&b.equals(q)||!1===c&&b.type==CKEDITOR.NODE_ELEMENT&&b.isBlockBoundary()||b.type==CKEDITOR.NODE_ELEMENT&&b.hasAttribute("contenteditable"))return!1;d||b.type!=CKEDITOR.NODE_ELEMENT||
+(q=b);return!0};k&&(e=d[a==CKEDITOR.SHRINK_ELEMENT?"lastForward":"next"]())&&this.setStartAt(e,b?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_START);r&&(d.reset(),(d=d[a==CKEDITOR.SHRINK_ELEMENT?"lastBackward":"previous"]())&&this.setEndAt(d,b?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_END));return!(!k&&!r)}},insertNode:function(a){this.optimizeBookmark();this.trim(!1,!0);var b=this.startContainer,c=b.getChild(this.startOffset);c?a.insertBefore(c):b.append(a);a.getParent()&&a.getParent().equals(this.endContainer)&&
+this.endOffset++;this.setStartBefore(a)},moveToPosition:function(a,b){this.setStartAt(a,b);this.collapse(!0)},moveToRange:function(a){this.setStart(a.startContainer,a.startOffset);this.setEnd(a.endContainer,a.endOffset)},selectNodeContents:function(a){this.setStart(a,0);this.setEnd(a,a.type==CKEDITOR.NODE_TEXT?a.getLength():a.getChildCount())},setStart:function(b,c){b.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[b.getName()]&&(c=b.getIndex(),b=b.getParent());this._setStartContainer(b);this.startOffset=
+c;this.endContainer||(this._setEndContainer(b),this.endOffset=c);a(this)},setEnd:function(b,c){b.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$empty[b.getName()]&&(c=b.getIndex()+1,b=b.getParent());this._setEndContainer(b);this.endOffset=c;this.startContainer||(this._setStartContainer(b),this.startOffset=c);a(this)},setStartAfter:function(a){this.setStart(a.getParent(),a.getIndex()+1)},setStartBefore:function(a){this.setStart(a.getParent(),a.getIndex())},setEndAfter:function(a){this.setEnd(a.getParent(),
+a.getIndex()+1)},setEndBefore:function(a){this.setEnd(a.getParent(),a.getIndex())},setStartAt:function(b,c){switch(c){case CKEDITOR.POSITION_AFTER_START:this.setStart(b,0);break;case CKEDITOR.POSITION_BEFORE_END:b.type==CKEDITOR.NODE_TEXT?this.setStart(b,b.getLength()):this.setStart(b,b.getChildCount());break;case CKEDITOR.POSITION_BEFORE_START:this.setStartBefore(b);break;case CKEDITOR.POSITION_AFTER_END:this.setStartAfter(b)}a(this)},setEndAt:function(b,c){switch(c){case CKEDITOR.POSITION_AFTER_START:this.setEnd(b,
+0);break;case CKEDITOR.POSITION_BEFORE_END:b.type==CKEDITOR.NODE_TEXT?this.setEnd(b,b.getLength()):this.setEnd(b,b.getChildCount());break;case CKEDITOR.POSITION_BEFORE_START:this.setEndBefore(b);break;case CKEDITOR.POSITION_AFTER_END:this.setEndAfter(b)}a(this)},fixBlock:function(a,b){var c=this.createBookmark(),d=this.document.createElement(b);this.collapse(a);this.enlarge(CKEDITOR.ENLARGE_BLOCK_CONTENTS);this.extractContents().appendTo(d);d.trim();this.insertNode(d);var e=d.getBogus();e&&e.remove();
+d.appendBogus();this.moveToBookmark(c);return d},splitBlock:function(a,b){var c=new CKEDITOR.dom.elementPath(this.startContainer,this.root),d=new CKEDITOR.dom.elementPath(this.endContainer,this.root),e=c.block,m=d.block,g=null;if(!c.blockLimit.equals(d.blockLimit))return null;"br"!=a&&(e||(e=this.fixBlock(!0,a),m=(new CKEDITOR.dom.elementPath(this.endContainer,this.root)).block),m||(m=this.fixBlock(!1,a)));c=e&&this.checkStartOfBlock();d=m&&this.checkEndOfBlock();this.deleteContents();e&&e.equals(m)&&
+(d?(g=new CKEDITOR.dom.elementPath(this.startContainer,this.root),this.moveToPosition(m,CKEDITOR.POSITION_AFTER_END),m=null):c?(g=new CKEDITOR.dom.elementPath(this.startContainer,this.root),this.moveToPosition(e,CKEDITOR.POSITION_BEFORE_START),e=null):(m=this.splitElement(e,b||!1),e.is("ul","ol")||e.appendBogus()));return{previousBlock:e,nextBlock:m,wasStartOfBlock:c,wasEndOfBlock:d,elementPath:g}},splitElement:function(a,b){if(!this.collapsed)return null;this.setEndAt(a,CKEDITOR.POSITION_BEFORE_END);
+var c=this.extractContents(!1,b||!1),d=a.clone(!1,b||!1);c.appendTo(d);d.insertAfter(a);this.moveToPosition(a,CKEDITOR.POSITION_AFTER_END);return d},removeEmptyBlocksAtEnd:function(){function a(d){return function(a){return b(a)||c(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.isEmptyInlineRemoveable()||d.is("table")&&a.is("caption")?!1:!0}}var b=CKEDITOR.dom.walker.whitespaces(),c=CKEDITOR.dom.walker.bookmark(!1);return function(b){for(var c=this.createBookmark(),d=this[b?"endPath":"startPath"](),e=d.block||
+d.blockLimit,g;e&&!e.equals(d.root)&&!e.getFirst(a(e));)g=e.getParent(),this[b?"setEndAt":"setStartAt"](e,CKEDITOR.POSITION_AFTER_END),e.remove(1),e=g;this.moveToBookmark(c)}}(),startPath:function(){return new CKEDITOR.dom.elementPath(this.startContainer,this.root)},endPath:function(){return new CKEDITOR.dom.elementPath(this.endContainer,this.root)},checkBoundaryOfElement:function(a,b){var d=b==CKEDITOR.START,e=this.clone();e.collapse(d);e[d?"setStartAt":"setEndAt"](a,d?CKEDITOR.POSITION_AFTER_START:
+CKEDITOR.POSITION_BEFORE_END);e=new CKEDITOR.dom.walker(e);e.evaluator=c(d);return e[d?"checkBackward":"checkForward"]()},checkStartOfBlock:function(){var a=this.startContainer,c=this.startOffset;CKEDITOR.env.ie&&c&&a.type==CKEDITOR.NODE_TEXT&&(a=CKEDITOR.tools.ltrim(a.substring(0,c)),h.test(a)&&this.trim(0,1));this.trim();a=new CKEDITOR.dom.elementPath(this.startContainer,this.root);c=this.clone();c.collapse(!0);c.setStartAt(a.block||a.blockLimit,CKEDITOR.POSITION_AFTER_START);a=new CKEDITOR.dom.walker(c);
+a.evaluator=b();return a.checkBackward()},checkEndOfBlock:function(){var a=this.endContainer,c=this.endOffset;CKEDITOR.env.ie&&a.type==CKEDITOR.NODE_TEXT&&(a=CKEDITOR.tools.rtrim(a.substring(c)),h.test(a)&&this.trim(1,0));this.trim();a=new CKEDITOR.dom.elementPath(this.endContainer,this.root);c=this.clone();c.collapse(!1);c.setEndAt(a.block||a.blockLimit,CKEDITOR.POSITION_BEFORE_END);a=new CKEDITOR.dom.walker(c);a.evaluator=b();return a.checkForward()},getPreviousNode:function(a,b,c){var d=this.clone();
+d.collapse(1);d.setStartAt(c||this.root,CKEDITOR.POSITION_AFTER_START);c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.previous()},getNextNode:function(a,b,c){var d=this.clone();d.collapse();d.setEndAt(c||this.root,CKEDITOR.POSITION_BEFORE_END);c=new CKEDITOR.dom.walker(d);c.evaluator=a;c.guard=b;return c.next()},checkReadOnly:function(){function a(b,c){for(;b;){if(b.type==CKEDITOR.NODE_ELEMENT){if("false"==b.getAttribute("contentEditable")&&!b.data("cke-editable"))return 0;if(b.is("html")||
+"true"==b.getAttribute("contentEditable")&&(b.contains(c)||b.equals(c)))break}b=b.getParent()}return 1}return function(){var b=this.startContainer,c=this.endContainer;return!(a(b,c)&&a(c,b))}}(),moveToElementEditablePosition:function(a,b){if(a.type==CKEDITOR.NODE_ELEMENT&&!a.isEditable(!1))return this.moveToPosition(a,b?CKEDITOR.POSITION_AFTER_END:CKEDITOR.POSITION_BEFORE_START),!0;for(var c=0;a;){if(a.type==CKEDITOR.NODE_TEXT){b&&this.endContainer&&this.checkEndOfBlock()&&h.test(a.getText())?this.moveToPosition(a,
+CKEDITOR.POSITION_BEFORE_START):this.moveToPosition(a,b?CKEDITOR.POSITION_AFTER_END:CKEDITOR.POSITION_BEFORE_START);c=1;break}if(a.type==CKEDITOR.NODE_ELEMENT)if(a.isEditable())this.moveToPosition(a,b?CKEDITOR.POSITION_BEFORE_END:CKEDITOR.POSITION_AFTER_START),c=1;else if(b&&a.is("br")&&this.endContainer&&this.checkEndOfBlock())this.moveToPosition(a,CKEDITOR.POSITION_BEFORE_START);else if("false"==a.getAttribute("contenteditable")&&a.is(CKEDITOR.dtd.$block))return this.setStartBefore(a),this.setEndAfter(a),
+!0;var d=a,e=c,m=void 0;d.type==CKEDITOR.NODE_ELEMENT&&d.isEditable(!1)&&(m=d[b?"getLast":"getFirst"](r));e||m||(m=d[b?"getPrevious":"getNext"](r));a=m}return!!c},moveToClosestEditablePosition:function(a,b){var c,d=0,e,m,g=[CKEDITOR.POSITION_AFTER_END,CKEDITOR.POSITION_BEFORE_START];a?(c=new CKEDITOR.dom.range(this.root),c.moveToPosition(a,g[b?0:1])):c=this.clone();if(a&&!a.is(CKEDITOR.dtd.$block))d=1;else if(e=c[b?"getNextEditableNode":"getPreviousEditableNode"]())d=1,(m=e.type==CKEDITOR.NODE_ELEMENT)&&
+e.is(CKEDITOR.dtd.$block)&&"false"==e.getAttribute("contenteditable")?(c.setStartAt(e,CKEDITOR.POSITION_BEFORE_START),c.setEndAt(e,CKEDITOR.POSITION_AFTER_END)):!CKEDITOR.env.needsBrFiller&&m&&e.is(CKEDITOR.dom.walker.validEmptyBlockContainers)?(c.setEnd(e,0),c.collapse()):c.moveToPosition(e,g[b?1:0]);d&&this.moveToRange(c);return!!d},moveToElementEditStart:function(a){return this.moveToElementEditablePosition(a)},moveToElementEditEnd:function(a){return this.moveToElementEditablePosition(a,!0)},getEnclosedNode:function(){var a=
+this.clone();a.optimize();if(a.startContainer.type!=CKEDITOR.NODE_ELEMENT||a.endContainer.type!=CKEDITOR.NODE_ELEMENT)return null;var a=new CKEDITOR.dom.walker(a),b=CKEDITOR.dom.walker.bookmark(!1,!0),c=CKEDITOR.dom.walker.whitespaces(!0);a.evaluator=function(a){return c(a)&&b(a)};var d=a.next();a.reset();return d&&d.equals(a.previous())?d:null},getTouchedStartNode:function(){var a=this.startContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.startOffset)||a},getTouchedEndNode:function(){var a=
+this.endContainer;return this.collapsed||a.type!=CKEDITOR.NODE_ELEMENT?a:a.getChild(this.endOffset-1)||a},getNextEditableNode:e(),getPreviousEditableNode:e(1),scrollIntoView:function(){var a=new CKEDITOR.dom.element.createFromHtml("\x3cspan\x3e\x26nbsp;\x3c/span\x3e",this.document),b,c,d,e=this.clone();e.optimize();(d=e.startContainer.type==CKEDITOR.NODE_TEXT)?(c=e.startContainer.getText(),b=e.startContainer.split(e.startOffset),a.insertAfter(e.startContainer)):e.insertNode(a);a.scrollIntoView();
+d&&(e.startContainer.setText(c),b.remove());a.remove()},_setStartContainer:function(a){this.startContainer=a},_setEndContainer:function(a){this.endContainer=a},_find:function(a,b){var c=this.getCommonAncestor(),d=this.getBoundaryNodes(),e=[],m,g,h,k;if(c&&c.find)for(g=c.find(a),m=0;m<g.count();m++)if(c=g.getItem(m),b||!c.isReadOnly())h=c.getPosition(d.startNode)&CKEDITOR.POSITION_FOLLOWING||d.startNode.equals(c),k=c.getPosition(d.endNode)&CKEDITOR.POSITION_PRECEDING+CKEDITOR.POSITION_IS_CONTAINED,
+h&&k&&e.push(c);return e}}})();CKEDITOR.POSITION_AFTER_START=1;CKEDITOR.POSITION_BEFORE_END=2;CKEDITOR.POSITION_BEFORE_START=3;CKEDITOR.POSITION_AFTER_END=4;CKEDITOR.ENLARGE_ELEMENT=1;CKEDITOR.ENLARGE_BLOCK_CONTENTS=2;CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS=3;CKEDITOR.ENLARGE_INLINE=4;CKEDITOR.START=1;CKEDITOR.END=2;CKEDITOR.SHRINK_ELEMENT=1;CKEDITOR.SHRINK_TEXT=2;"use strict";
+(function(){function a(a){1>arguments.length||(this.range=a,this.forceBrBreak=0,this.enlargeBr=1,this.enforceRealBlocks=0,this._||(this._={}))}function d(a){var b=[];a.forEach(function(a){if("true"==a.getAttribute("contenteditable"))return b.push(a),!1},CKEDITOR.NODE_ELEMENT,!0);return b}function b(a,c,e,g){a:{null==g&&(g=d(e));for(var h;h=g.shift();)if(h.getDtd().p){g={element:h,remaining:g};break a}g=null}if(!g)return 0;if((h=CKEDITOR.filter.instances[g.element.data("cke-filter")])&&!h.check(c))return b(a,
+c,e,g.remaining);c=new CKEDITOR.dom.range(g.element);c.selectNodeContents(g.element);c=c.createIterator();c.enlargeBr=a.enlargeBr;c.enforceRealBlocks=a.enforceRealBlocks;c.activeFilter=c.filter=h;a._.nestedEditable={element:g.element,container:e,remaining:g.remaining,iterator:c};return 1}function c(a,b,c){if(!b)return!1;a=a.clone();a.collapse(!c);return a.checkBoundaryOfElement(b,c?CKEDITOR.START:CKEDITOR.END)}var e=/^[\r\n\t ]+$/,g=CKEDITOR.dom.walker.bookmark(!1,!0),k=CKEDITOR.dom.walker.whitespaces(!0),
+h=function(a){return g(a)&&k(a)},p={dd:1,dt:1,li:1};a.prototype={getNextParagraph:function(a){var d,k,u,z,y;a=a||"p";if(this._.nestedEditable){if(d=this._.nestedEditable.iterator.getNextParagraph(a))return this.activeFilter=this._.nestedEditable.iterator.activeFilter,d;this.activeFilter=this.filter;if(b(this,a,this._.nestedEditable.container,this._.nestedEditable.remaining))return this.activeFilter=this._.nestedEditable.iterator.activeFilter,this._.nestedEditable.iterator.getNextParagraph(a);this._.nestedEditable=
+null}if(!this.range.root.getDtd()[a])return null;if(!this._.started){var m=this.range.clone();k=m.startPath();var x=m.endPath(),J=!m.collapsed&&c(m,k.block),w=!m.collapsed&&c(m,x.block,1);m.shrink(CKEDITOR.SHRINK_ELEMENT,!0);J&&m.setStartAt(k.block,CKEDITOR.POSITION_BEFORE_END);w&&m.setEndAt(x.block,CKEDITOR.POSITION_AFTER_START);k=m.endContainer.hasAscendant("pre",!0)||m.startContainer.hasAscendant("pre",!0);m.enlarge(this.forceBrBreak&&!k||!this.enlargeBr?CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:CKEDITOR.ENLARGE_BLOCK_CONTENTS);
+m.collapsed||(k=new CKEDITOR.dom.walker(m.clone()),x=CKEDITOR.dom.walker.bookmark(!0,!0),k.evaluator=x,this._.nextNode=k.next(),k=new CKEDITOR.dom.walker(m.clone()),k.evaluator=x,k=k.previous(),this._.lastNode=k.getNextSourceNode(!0,null,m.root),this._.lastNode&&this._.lastNode.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(this._.lastNode.getText())&&this._.lastNode.getParent().isBlockBoundary()&&(x=this.range.clone(),x.moveToPosition(this._.lastNode,CKEDITOR.POSITION_AFTER_END),x.checkEndOfBlock()&&
+(x=new CKEDITOR.dom.elementPath(x.endContainer,x.root),this._.lastNode=(x.block||x.blockLimit).getNextSourceNode(!0))),this._.lastNode&&m.root.contains(this._.lastNode)||(this._.lastNode=this._.docEndMarker=m.document.createText(""),this._.lastNode.insertAfter(k)),m=null);this._.started=1;k=m}x=this._.nextNode;m=this._.lastNode;for(this._.nextNode=null;x;){var J=0,w=x.hasAscendant("pre"),F=x.type!=CKEDITOR.NODE_ELEMENT,l=0;if(F)x.type==CKEDITOR.NODE_TEXT&&e.test(x.getText())&&(F=0);else{var q=x.getName();
+if(CKEDITOR.dtd.$block[q]&&"false"==x.getAttribute("contenteditable")){d=x;b(this,a,d);break}else if(x.isBlockBoundary(this.forceBrBreak&&!w&&{br:1})){if("br"==q)F=1;else if(!k&&!x.getChildCount()&&"hr"!=q){d=x;u=x.equals(m);break}k&&(k.setEndAt(x,CKEDITOR.POSITION_BEFORE_START),"br"!=q&&(this._.nextNode=x));J=1}else{if(x.getFirst()){k||(k=this.range.clone(),k.setStartAt(x,CKEDITOR.POSITION_BEFORE_START));x=x.getFirst();continue}F=1}}F&&!k&&(k=this.range.clone(),k.setStartAt(x,CKEDITOR.POSITION_BEFORE_START));
+u=(!J||F)&&x.equals(m);if(k&&!J)for(;!x.getNext(h)&&!u;){q=x.getParent();if(q.isBlockBoundary(this.forceBrBreak&&!w&&{br:1})){J=1;F=0;u||q.equals(m);k.setEndAt(q,CKEDITOR.POSITION_BEFORE_END);break}x=q;F=1;u=x.equals(m);l=1}F&&k.setEndAt(x,CKEDITOR.POSITION_AFTER_END);x=this._getNextSourceNode(x,l,m);if((u=!x)||J&&k)break}if(!d){if(!k)return this._.docEndMarker&&this._.docEndMarker.remove(),this._.nextNode=null;d=new CKEDITOR.dom.elementPath(k.startContainer,k.root);x=d.blockLimit;J={div:1,th:1,td:1};
+d=d.block;!d&&x&&!this.enforceRealBlocks&&J[x.getName()]&&k.checkStartOfBlock()&&k.checkEndOfBlock()&&!x.equals(k.root)?d=x:!d||this.enforceRealBlocks&&d.is(p)?(d=this.range.document.createElement(a),k.extractContents().appendTo(d),d.trim(),k.insertNode(d),z=y=!0):"li"!=d.getName()?k.checkStartOfBlock()&&k.checkEndOfBlock()||(d=d.clone(!1),k.extractContents().appendTo(d),d.trim(),y=k.splitBlock(),z=!y.wasStartOfBlock,y=!y.wasEndOfBlock,k.insertNode(d)):u||(this._.nextNode=d.equals(m)?null:this._getNextSourceNode(k.getBoundaryNodes().endNode,
+1,m))}z&&(z=d.getPrevious())&&z.type==CKEDITOR.NODE_ELEMENT&&("br"==z.getName()?z.remove():z.getLast()&&"br"==z.getLast().$.nodeName.toLowerCase()&&z.getLast().remove());y&&(z=d.getLast())&&z.type==CKEDITOR.NODE_ELEMENT&&"br"==z.getName()&&(!CKEDITOR.env.needsBrFiller||z.getPrevious(g)||z.getNext(g))&&z.remove();this._.nextNode||(this._.nextNode=u||d.equals(m)||!m?null:this._getNextSourceNode(d,1,m));return d},_getNextSourceNode:function(a,b,c){function d(a){return!(a.equals(c)||a.equals(e))}var e=
+this.range.root;for(a=a.getNextSourceNode(b,null,d);!g(a);)a=a.getNextSourceNode(b,null,d);return a}};CKEDITOR.dom.range.prototype.createIterator=function(){return new a(this)}})();
+CKEDITOR.command=function(a,d){this.uiItems=[];this.exec=function(b){if(this.state==CKEDITOR.TRISTATE_DISABLED||!this.checkAllowed())return!1;this.editorFocus&&a.focus();return!1===this.fire("exec")?!0:!1!==d.exec.call(this,a,b)};this.refresh=function(a,b){if(!this.readOnly&&a.readOnly)return!0;if(this.context&&!b.isContextFor(this.context)||!this.checkAllowed(!0))return this.disable(),!0;this.startDisabled||this.enable();this.modes&&!this.modes[a.mode]&&this.disable();return!1===this.fire("refresh",
+{editor:a,path:b})?!0:d.refresh&&!1!==d.refresh.apply(this,arguments)};var b;this.checkAllowed=function(c){return c||"boolean"!=typeof b?b=a.activeFilter.checkFeature(this):b};CKEDITOR.tools.extend(this,d,{modes:{wysiwyg:1},editorFocus:1,contextSensitive:!!d.context,state:CKEDITOR.TRISTATE_DISABLED});CKEDITOR.event.call(this)};
+CKEDITOR.command.prototype={enable:function(){this.state==CKEDITOR.TRISTATE_DISABLED&&this.checkAllowed()&&this.setState(this.preserveState&&"undefined"!=typeof this.previousState?this.previousState:CKEDITOR.TRISTATE_OFF)},disable:function(){this.setState(CKEDITOR.TRISTATE_DISABLED)},setState:function(a){if(this.state==a||a!=CKEDITOR.TRISTATE_DISABLED&&!this.checkAllowed())return!1;this.previousState=this.state;this.state=a;this.fire("state");return!0},toggleState:function(){this.state==CKEDITOR.TRISTATE_OFF?
+this.setState(CKEDITOR.TRISTATE_ON):this.state==CKEDITOR.TRISTATE_ON&&this.setState(CKEDITOR.TRISTATE_OFF)}};CKEDITOR.event.implementOn(CKEDITOR.command.prototype);CKEDITOR.ENTER_P=1;CKEDITOR.ENTER_BR=2;CKEDITOR.ENTER_DIV=3;
+CKEDITOR.config={customConfig:"config.js",autoUpdateElement:!0,language:"",defaultLanguage:"en",contentsLangDirection:"",enterMode:CKEDITOR.ENTER_P,forceEnterMode:!1,shiftEnterMode:CKEDITOR.ENTER_BR,docType:"\x3c!DOCTYPE html\x3e",bodyId:"",bodyClass:"",fullPage:!1,height:200,contentsCss:CKEDITOR.getUrl("contents.css"),extraPlugins:"",removePlugins:"",protectedSource:[],tabIndex:0,width:"",baseFloatZIndex:1E4,blockedKeystrokes:[CKEDITOR.CTRL+66,CKEDITOR.CTRL+73,CKEDITOR.CTRL+85]};
+(function(){function a(a,b,c,d,l){var e,q;a=[];for(e in b){q=b[e];q="boolean"==typeof q?{}:"function"==typeof q?{match:q}:M(q);"$"!=e.charAt(0)&&(q.elements=e);c&&(q.featureName=c.toLowerCase());var n=q;n.elements=k(n.elements,/\s+/)||null;n.propertiesOnly=n.propertiesOnly||!0===n.elements;var f=/\s*,\s*/,t=void 0;for(t in Q){n[t]=k(n[t],f)||null;var m=n,g=P[t],E=k(n[P[t]],f),v=n[t],A=[],I=!0,C=void 0;E?I=!1:E={};for(C in v)"!"==C.charAt(0)&&(C=C.slice(1),A.push(C),E[C]=!0,I=!1);for(;C=A.pop();)v[C]=
+v["!"+C],delete v["!"+C];m[g]=(I?!1:E)||null}n.match=n.match||null;d.push(q);a.push(q)}b=l.elements;l=l.generic;var h;c=0;for(d=a.length;c<d;++c){e=M(a[c]);q=!0===e.classes||!0===e.styles||!0===e.attributes;n=e;t=g=f=void 0;for(f in Q)n[f]=J(n[f]);m=!0;for(t in P){f=P[t];g=n[f];E=[];v=void 0;for(v in g)-1<v.indexOf("*")?E.push(new RegExp("^"+v.replace(/\*/g,".*")+"$")):E.push(v);g=E;g.length&&(n[f]=g,m=!1)}n.nothingRequired=m;n.noProperties=!(n.attributes||n.classes||n.styles);if(!0===e.elements||
+null===e.elements)l[q?"unshift":"push"](e);else for(h in n=e.elements,delete e.elements,n)if(b[h])b[h][q?"unshift":"push"](e);else b[h]=[e]}}function d(a,c,d,l){if(!a.match||a.match(c))if(l||h(a,c))if(a.propertiesOnly||(d.valid=!0),d.allAttributes||(d.allAttributes=b(a.attributes,c.attributes,d.validAttributes)),d.allStyles||(d.allStyles=b(a.styles,c.styles,d.validStyles)),!d.allClasses){a=a.classes;c=c.classes;l=d.validClasses;if(a)if(!0===a)a=!0;else{for(var e=0,q=c.length,n;e<q;++e)n=c[e],l[n]||
+(l[n]=a(n));a=!1}else a=!1;d.allClasses=a}}function b(a,b,c){if(!a)return!1;if(!0===a)return!0;for(var d in b)c[d]||(c[d]=a(d));return!1}function c(a,b,c){if(!a.match||a.match(b)){if(a.noProperties)return!1;c.hadInvalidAttribute=e(a.attributes,b.attributes)||c.hadInvalidAttribute;c.hadInvalidStyle=e(a.styles,b.styles)||c.hadInvalidStyle;a=a.classes;b=b.classes;if(a){for(var d=!1,l=!0===a,q=b.length;q--;)if(l||a(b[q]))b.splice(q,1),d=!0;a=d}else a=!1;c.hadInvalidClass=a||c.hadInvalidClass}}function e(a,
+b){if(!a)return!1;var c=!1,d=!0===a,l;for(l in b)if(d||a(l))delete b[l],c=!0;return c}function g(a,b,c){if(a.disabled||a.customConfig&&!c||!b)return!1;a._.cachedChecks={};return!0}function k(a,b){if(!a)return!1;if(!0===a)return a;if("string"==typeof a)return a=H(a),"*"==a?!0:CKEDITOR.tools.convertArrayToObject(a.split(b));if(CKEDITOR.tools.isArray(a))return a.length?CKEDITOR.tools.convertArrayToObject(a):!1;var c={},d=0,l;for(l in a)c[l]=a[l],d++;return d?c:!1}function h(a,b){if(a.nothingRequired)return!0;
+var c,d,l,e;if(l=a.requiredClasses)for(e=b.classes,c=0;c<l.length;++c)if(d=l[c],"string"==typeof d){if(-1==CKEDITOR.tools.indexOf(e,d))return!1}else if(!CKEDITOR.tools.checkIfAnyArrayItemMatches(e,d))return!1;return p(b.styles,a.requiredStyles)&&p(b.attributes,a.requiredAttributes)}function p(a,b){if(!b)return!0;for(var c=0,d;c<b.length;++c)if(d=b[c],"string"==typeof d){if(!(d in a))return!1}else if(!CKEDITOR.tools.checkIfAnyObjectPropertyMatches(a,d))return!1;return!0}function r(a){if(!a)return{};
+a=a.split(/\s*,\s*/).sort();for(var b={};a.length;)b[a.shift()]="cke-test";return b}function f(a){var b,c,d,l,e={},q=1;for(a=H(a);b=a.match(v);)(c=b[2])?(d=B(c,"styles"),l=B(c,"attrs"),c=B(c,"classes")):d=l=c=null,e["$"+q++]={elements:b[1],classes:c,styles:d,attributes:l},a=a.slice(b[0].length);return e}function B(a,b){var c=a.match(G[b]);return c?H(c[1]):null}function u(a){var b=a.styleBackup=a.attributes.style,c=a.classBackup=a.attributes["class"];a.styles||(a.styles=CKEDITOR.tools.parseCssText(b||
+"",1));a.classes||(a.classes=c?c.split(/\s+/):[])}function z(a,b,l,e){var n=0,f;e.toHtml&&(b.name=b.name.replace(E,"$1"));if(e.doCallbacks&&a.elementCallbacks){a:{f=a.elementCallbacks;for(var t=0,g=f.length,v;t<g;++t)if(v=f[t](b)){f=v;break a}f=void 0}if(f)return f}if(e.doTransform&&(f=a._.transformations[b.name])){u(b);for(t=0;t<f.length;++t)q(a,b,f[t]);m(b)}if(e.doFilter){a:{t=b.name;g=a._;a=g.allowedRules.elements[t];f=g.allowedRules.generic;t=g.disallowedRules.elements[t];g=g.disallowedRules.generic;
+v=e.skipRequired;var A={valid:!1,validAttributes:{},validClasses:{},validStyles:{},allAttributes:!1,allClasses:!1,allStyles:!1,hadInvalidAttribute:!1,hadInvalidClass:!1,hadInvalidStyle:!1},k,C;if(a||f){u(b);if(t)for(k=0,C=t.length;k<C;++k)if(!1===c(t[k],b,A)){a=null;break a}if(g)for(k=0,C=g.length;k<C;++k)c(g[k],b,A);if(a)for(k=0,C=a.length;k<C;++k)d(a[k],b,A,v);if(f)for(k=0,C=f.length;k<C;++k)d(f[k],b,A,v);a=A}else a=null}if(!a||!a.valid)return l.push(b),1;C=a.validAttributes;var h=a.validStyles;
+f=a.validClasses;var t=b.attributes,M=b.styles,g=b.classes;v=b.classBackup;var K=b.styleBackup,G,D,p=[],A=[],H=/^data-cke-/;k=!1;delete t.style;delete t["class"];delete b.classBackup;delete b.styleBackup;if(!a.allAttributes)for(G in t)C[G]||(H.test(G)?G==(D=G.replace(/^data-cke-saved-/,""))||C[D]||(delete t[G],k=!0):(delete t[G],k=!0));if(!a.allStyles||a.hadInvalidStyle){for(G in M)a.allStyles||h[G]?p.push(G+":"+M[G]):k=!0;p.length&&(t.style=p.sort().join("; "))}else K&&(t.style=K);if(!a.allClasses||
+a.hadInvalidClass){for(G=0;G<g.length;++G)(a.allClasses||f[g[G]])&&A.push(g[G]);A.length&&(t["class"]=A.sort().join(" "));v&&A.length<v.split(/\s+/).length&&(k=!0)}else v&&(t["class"]=v);k&&(n=1);if(!e.skipFinalValidation&&!x(b))return l.push(b),1}e.toHtml&&(b.name=b.name.replace(I,"cke:$1"));return n}function y(a){var b=[],c;for(c in a)-1<c.indexOf("*")&&b.push(c.replace(/\*/g,".*"));return b.length?new RegExp("^(?:"+b.join("|")+")$"):null}function m(a){var b=a.attributes,c;delete b.style;delete b["class"];
+if(c=CKEDITOR.tools.writeCssText(a.styles,!0))b.style=c;a.classes.length&&(b["class"]=a.classes.sort().join(" "))}function x(a){switch(a.name){case "a":if(!(a.children.length||a.attributes.name||a.attributes.id))return!1;break;case "img":if(!a.attributes.src)return!1}return!0}function J(a){if(!a)return!1;if(!0===a)return!0;var b=y(a);return function(c){return c in a||b&&c.match(b)}}function w(){return new CKEDITOR.htmlParser.element("br")}function F(a){return a.type==CKEDITOR.NODE_ELEMENT&&("br"==
+a.name||D.$block[a.name])}function l(a,b,c){var d=a.name;if(D.$empty[d]||!a.children.length)"hr"==d&&"br"==b?a.replaceWith(w()):(a.parent&&c.push({check:"it",el:a.parent}),a.remove());else if(D.$block[d]||"tr"==d)if("br"==b)a.previous&&!F(a.previous)&&(b=w(),b.insertBefore(a)),a.next&&!F(a.next)&&(b=w(),b.insertAfter(a)),a.replaceWithChildren();else{var d=a.children,l;b:{l=D[b];for(var e=0,q=d.length,n;e<q;++e)if(n=d[e],n.type==CKEDITOR.NODE_ELEMENT&&!l[n.name]){l=!1;break b}l=!0}if(l)a.name=b,a.attributes=
+{},c.push({check:"parent-down",el:a});else{l=a.parent;for(var e=l.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT||"body"==l.name,t,f,q=d.length;0<q;)n=d[--q],e&&(n.type==CKEDITOR.NODE_TEXT||n.type==CKEDITOR.NODE_ELEMENT&&D.$inline[n.name])?(t||(t=new CKEDITOR.htmlParser.element(b),t.insertAfter(a),c.push({check:"parent-down",el:t})),t.add(n,0)):(t=null,f=D[l.name]||D.span,n.insertAfter(a),l.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT||n.type!=CKEDITOR.NODE_ELEMENT||f[n.name]||c.push({check:"el-up",el:n}));a.remove()}}else d in
+{style:1,script:1}?a.remove():(a.parent&&c.push({check:"it",el:a.parent}),a.replaceWithChildren())}function q(a,b,c){var d,l;for(d=0;d<c.length;++d)if(l=c[d],!(l.check&&!a.check(l.check,!1)||l.left&&!l.left(b))){l.right(b,K);break}}function n(a,b){var c=b.getDefinition(),d=c.attributes,l=c.styles,e,q,n,t;if(a.name!=c.element)return!1;for(e in d)if("class"==e)for(c=d[e].split(/\s+/),n=a.classes.join("|");t=c.pop();){if(-1==n.indexOf(t))return!1}else if(a.attributes[e]!=d[e])return!1;for(q in l)if(a.styles[q]!=
+l[q])return!1;return!0}function t(a,b){var c,d;"string"==typeof a?c=a:a instanceof CKEDITOR.style?d=a:(c=a[0],d=a[1]);return[{element:c,left:d,right:function(a,c){c.transform(a,b)}}]}function A(a){return function(b){return n(b,a)}}function C(a){return function(b,c){c[a](b)}}var D=CKEDITOR.dtd,M=CKEDITOR.tools.copy,H=CKEDITOR.tools.trim,R=["","p","br","div"];CKEDITOR.FILTER_SKIP_TREE=2;CKEDITOR.filter=function(a){this.allowedContent=[];this.disallowedContent=[];this.elementCallbacks=null;this.disabled=
+!1;this.editor=null;this.id=CKEDITOR.tools.getNextNumber();this._={allowedRules:{elements:{},generic:[]},disallowedRules:{elements:{},generic:[]},transformations:{},cachedTests:{}};CKEDITOR.filter.instances[this.id]=this;if(a instanceof CKEDITOR.editor){a=this.editor=a;this.customConfig=!0;var b=a.config.allowedContent;!0===b?this.disabled=!0:(b||(this.customConfig=!1),this.allow(b,"config",1),this.allow(a.config.extraAllowedContent,"extra",1),this.allow(R[a.enterMode]+" "+R[a.shiftEnterMode],"default",
+1),this.disallow(a.config.disallowedContent))}else this.customConfig=!1,this.allow(a,"default",1)};CKEDITOR.filter.instances={};CKEDITOR.filter.prototype={allow:function(b,c,d){if(!g(this,b,d))return!1;var l,e;if("string"==typeof b)b=f(b);else if(b instanceof CKEDITOR.style){if(b.toAllowedContentRules)return this.allow(b.toAllowedContentRules(this.editor),c,d);l=b.getDefinition();b={};d=l.attributes;b[l.element]=l={styles:l.styles,requiredStyles:l.styles&&CKEDITOR.tools.objectKeys(l.styles)};d&&(d=
+M(d),l.classes=d["class"]?d["class"].split(/\s+/):null,l.requiredClasses=l.classes,delete d["class"],l.attributes=d,l.requiredAttributes=d&&CKEDITOR.tools.objectKeys(d))}else if(CKEDITOR.tools.isArray(b)){for(l=0;l<b.length;++l)e=this.allow(b[l],c,d);return e}a(this,b,c,this.allowedContent,this._.allowedRules);return!0},applyTo:function(a,b,c,d){if(this.disabled)return!1;var e=this,q=[],n=this.editor&&this.editor.config.protectedSource,t,f=!1,g={doFilter:!c,doTransform:!0,doCallbacks:!0,toHtml:b};
+a.forEach(function(a){if(a.type==CKEDITOR.NODE_ELEMENT){if("off"==a.attributes["data-cke-filter"])return!1;if(!b||"span"!=a.name||!~CKEDITOR.tools.objectKeys(a.attributes).join("|").indexOf("data-cke-"))if(t=z(e,a,q,g),t&1)f=!0;else if(t&2)return!1}else if(a.type==CKEDITOR.NODE_COMMENT&&a.value.match(/^\{cke_protected\}(?!\{C\})/)){var c;a:{var d=decodeURIComponent(a.value.replace(/^\{cke_protected\}/,""));c=[];var l,m,E;if(n)for(m=0;m<n.length;++m)if((E=d.match(n[m]))&&E[0].length==d.length){c=!0;
+break a}d=CKEDITOR.htmlParser.fragment.fromHtml(d);1==d.children.length&&(l=d.children[0]).type==CKEDITOR.NODE_ELEMENT&&z(e,l,c,g);c=!c.length}c||q.push(a)}},null,!0);q.length&&(f=!0);var m;a=[];d=R[d||(this.editor?this.editor.enterMode:CKEDITOR.ENTER_P)];for(var E;c=q.pop();)c.type==CKEDITOR.NODE_ELEMENT?l(c,d,a):c.remove();for(;m=a.pop();)if(c=m.el,c.parent)switch(E=D[c.parent.name]||D.span,m.check){case "it":D.$removeEmpty[c.name]&&!c.children.length?l(c,d,a):x(c)||l(c,d,a);break;case "el-up":c.parent.type==
+CKEDITOR.NODE_DOCUMENT_FRAGMENT||E[c.name]||l(c,d,a);break;case "parent-down":c.parent.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT||E[c.name]||l(c.parent,d,a)}return f},checkFeature:function(a){if(this.disabled||!a)return!0;a.toFeature&&(a=a.toFeature(this.editor));return!a.requiredContent||this.check(a.requiredContent)},disable:function(){this.disabled=!0},disallow:function(b){if(!g(this,b,!0))return!1;"string"==typeof b&&(b=f(b));a(this,b,null,this.disallowedContent,this._.disallowedRules);return!0},
+addContentForms:function(a){if(!this.disabled&&a){var b,c,d=[],l;for(b=0;b<a.length&&!l;++b)c=a[b],("string"==typeof c||c instanceof CKEDITOR.style)&&this.check(c)&&(l=c);if(l){for(b=0;b<a.length;++b)d.push(t(a[b],l));this.addTransformations(d)}}},addElementCallback:function(a){this.elementCallbacks||(this.elementCallbacks=[]);this.elementCallbacks.push(a)},addFeature:function(a){if(this.disabled||!a)return!0;a.toFeature&&(a=a.toFeature(this.editor));this.allow(a.allowedContent,a.name);this.addTransformations(a.contentTransformations);
+this.addContentForms(a.contentForms);return a.requiredContent&&(this.customConfig||this.disallowedContent.length)?this.check(a.requiredContent):!0},addTransformations:function(a){var b,c;if(!this.disabled&&a){var d=this._.transformations,l;for(l=0;l<a.length;++l){b=a[l];var e=void 0,q=void 0,n=void 0,t=void 0,f=void 0,g=void 0;c=[];for(q=0;q<b.length;++q)n=b[q],"string"==typeof n?(n=n.split(/\s*:\s*/),t=n[0],f=null,g=n[1]):(t=n.check,f=n.left,g=n.right),e||(e=n,e=e.element?e.element:t?t.match(/^([a-z0-9]+)/i)[0]:
+e.left.getDefinition().element),f instanceof CKEDITOR.style&&(f=A(f)),c.push({check:t==e?null:t,left:f,right:"string"==typeof g?C(g):g});b=e;d[b]||(d[b]=[]);d[b].push(c)}}},check:function(a,b,c){if(this.disabled)return!0;if(CKEDITOR.tools.isArray(a)){for(var d=a.length;d--;)if(this.check(a[d],b,c))return!0;return!1}var l,e;if("string"==typeof a){e=a+"\x3c"+(!1===b?"0":"1")+(c?"1":"0")+"\x3e";if(e in this._.cachedChecks)return this._.cachedChecks[e];d=f(a).$1;l=d.styles;var n=d.classes;d.name=d.elements;
+d.classes=n=n?n.split(/\s*,\s*/):[];d.styles=r(l);d.attributes=r(d.attributes);d.children=[];n.length&&(d.attributes["class"]=n.join(" "));l&&(d.attributes.style=CKEDITOR.tools.writeCssText(d.styles));l=d}else d=a.getDefinition(),l=d.styles,n=d.attributes||{},l&&!CKEDITOR.tools.isEmpty(l)?(l=M(l),n.style=CKEDITOR.tools.writeCssText(l,!0)):l={},l={name:d.element,attributes:n,classes:n["class"]?n["class"].split(/\s+/):[],styles:l,children:[]};var n=CKEDITOR.tools.clone(l),t=[],g;if(!1!==b&&(g=this._.transformations[l.name])){for(d=
+0;d<g.length;++d)q(this,l,g[d]);m(l)}z(this,n,t,{doFilter:!0,doTransform:!1!==b,skipRequired:!c,skipFinalValidation:!c});b=0<t.length?!1:CKEDITOR.tools.objectCompare(l.attributes,n.attributes,!0)?!0:!1;"string"==typeof a&&(this._.cachedChecks[e]=b);return b},getAllowedEnterMode:function(){var a=["p","div","br"],b={p:CKEDITOR.ENTER_P,div:CKEDITOR.ENTER_DIV,br:CKEDITOR.ENTER_BR};return function(c,d){var l=a.slice(),e;if(this.check(R[c]))return c;for(d||(l=l.reverse());e=l.pop();)if(this.check(e))return b[e];
+return CKEDITOR.ENTER_BR}}(),destroy:function(){delete CKEDITOR.filter.instances[this.id];delete this._;delete this.allowedContent;delete this.disallowedContent}};var Q={styles:1,attributes:1,classes:1},P={styles:"requiredStyles",attributes:"requiredAttributes",classes:"requiredClasses"},v=/^([a-z0-9\-*\s]+)((?:\s*\{[!\w\-,\s\*]+\}\s*|\s*\[[!\w\-,\s\*]+\]\s*|\s*\([!\w\-,\s\*]+\)\s*){0,3})(?:;\s*|$)/i,G={styles:/{([^}]+)}/,attrs:/\[([^\]]+)\]/,classes:/\(([^\)]+)\)/},E=/^cke:(object|embed|param)$/,
+I=/^(object|embed|param)$/,K;K=CKEDITOR.filter.transformationsTools={sizeToStyle:function(a){this.lengthToStyle(a,"width");this.lengthToStyle(a,"height")},sizeToAttribute:function(a){this.lengthToAttribute(a,"width");this.lengthToAttribute(a,"height")},lengthToStyle:function(a,b,c){c=c||b;if(!(c in a.styles)){var d=a.attributes[b];d&&(/^\d+$/.test(d)&&(d+="px"),a.styles[c]=d)}delete a.attributes[b]},lengthToAttribute:function(a,b,c){c=c||b;if(!(c in a.attributes)){var d=a.styles[b],l=d&&d.match(/^(\d+)(?:\.\d*)?px$/);
+l?a.attributes[c]=l[1]:"cke-test"==d&&(a.attributes[c]="cke-test")}delete a.styles[b]},alignmentToStyle:function(a){if(!("float"in a.styles)){var b=a.attributes.align;if("left"==b||"right"==b)a.styles["float"]=b}delete a.attributes.align},alignmentToAttribute:function(a){if(!("align"in a.attributes)){var b=a.styles["float"];if("left"==b||"right"==b)a.attributes.align=b}delete a.styles["float"]},splitBorderShorthand:function(a){function b(d){a.styles["border-top-width"]=c[d[0]];a.styles["border-right-width"]=
+c[d[1]];a.styles["border-bottom-width"]=c[d[2]];a.styles["border-left-width"]=c[d[3]]}if(a.styles.border){var c=a.styles.border.match(/([\.\d]+\w+)/g)||["0px"];switch(c.length){case 1:a.styles["border-width"]=c[0];break;case 2:b([0,1,0,1]);break;case 3:b([0,1,2,1]);break;case 4:b([0,1,2,3])}a.styles["border-style"]=a.styles["border-style"]||(a.styles.border.match(/(none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|initial|inherit)/)||[])[0];a.styles["border-style"]||delete a.styles["border-style"];
+delete a.styles.border}},listTypeToStyle:function(a){if(a.attributes.type)switch(a.attributes.type){case "a":a.styles["list-style-type"]="lower-alpha";break;case "A":a.styles["list-style-type"]="upper-alpha";break;case "i":a.styles["list-style-type"]="lower-roman";break;case "I":a.styles["list-style-type"]="upper-roman";break;case "1":a.styles["list-style-type"]="decimal";break;default:a.styles["list-style-type"]=a.attributes.type}},splitMarginShorthand:function(a){function b(d){a.styles["margin-top"]=
+c[d[0]];a.styles["margin-right"]=c[d[1]];a.styles["margin-bottom"]=c[d[2]];a.styles["margin-left"]=c[d[3]]}if(a.styles.margin){var c=a.styles.margin.match(/(\-?[\.\d]+\w+)/g)||["0px"];switch(c.length){case 1:a.styles.margin=c[0];break;case 2:b([0,1,0,1]);break;case 3:b([0,1,2,1]);break;case 4:b([0,1,2,3])}delete a.styles.margin}},matchesStyle:n,transform:function(a,b){if("string"==typeof b)a.name=b;else{var c=b.getDefinition(),d=c.styles,l=c.attributes,e,q,n,t;a.name=c.element;for(e in l)if("class"==
+e)for(c=a.classes.join("|"),n=l[e].split(/\s+/);t=n.pop();)-1==c.indexOf(t)&&a.classes.push(t);else a.attributes[e]=l[e];for(q in d)a.styles[q]=d[q]}}}})();
+(function(){CKEDITOR.focusManager=function(a){if(a.focusManager)return a.focusManager;this.hasFocus=!1;this.currentActive=null;this._={editor:a};return this};CKEDITOR.focusManager._={blurDelay:200};CKEDITOR.focusManager.prototype={focus:function(a){this._.timer&&clearTimeout(this._.timer);a&&(this.currentActive=a);this.hasFocus||this._.locked||((a=CKEDITOR.currentInstance)&&a.focusManager.blur(1),this.hasFocus=!0,(a=this._.editor.container)&&a.addClass("cke_focus"),this._.editor.fire("focus"))},lock:function(){this._.locked=
+1},unlock:function(){delete this._.locked},blur:function(a){function d(){var a=this._.editor;this.hasFocus&&(this.hasFocus=!1,CKEDITOR.env.chrome&&a.editable().isInline()&&a.window.$.getSelection().removeAllRanges(),(a=this._.editor.container)&&a.removeClass("cke_focus"),this._.editor.fire("blur"))}if(!this._.locked){this._.timer&&clearTimeout(this._.timer);var b=CKEDITOR.focusManager._.blurDelay;a||!b?d.call(this):this._.timer=CKEDITOR.tools.setTimeout(function(){delete this._.timer;d.call(this)},
+b,this)}},add:function(a,d){var b=a.getCustomData("focusmanager");if(!b||b!=this){b&&b.remove(a);var b="focus",c="blur";d&&(CKEDITOR.env.ie?(b="focusin",c="focusout"):CKEDITOR.event.useCapture=1);var e={blur:function(){a.equals(this.currentActive)&&this.blur()},focus:function(){this.focus(a)}};a.on(b,e.focus,this);a.on(c,e.blur,this);d&&(CKEDITOR.event.useCapture=0);a.setCustomData("focusmanager",this);a.setCustomData("focusmanager_handlers",e)}},remove:function(a){a.removeCustomData("focusmanager");
+var d=a.removeCustomData("focusmanager_handlers");a.removeListener("blur",d.blur);a.removeListener("focus",d.focus)}}})();CKEDITOR.keystrokeHandler=function(a){if(a.keystrokeHandler)return a.keystrokeHandler;this.keystrokes={};this.blockedKeystrokes={};this._={editor:a};return this};
+(function(){var a,d=function(b){b=b.data;var d=b.getKeystroke(),g=this.keystrokes[d],k=this._.editor;a=!1===k.fire("key",{keyCode:d,domEvent:b});a||(g&&(a=!1!==k.execCommand(g,{from:"keystrokeHandler"})),a||(a=!!this.blockedKeystrokes[d]));a&&b.preventDefault(!0);return!a},b=function(b){a&&(a=!1,b.data.preventDefault(!0))};CKEDITOR.keystrokeHandler.prototype={attach:function(a){a.on("keydown",d,this);if(CKEDITOR.env.gecko&&CKEDITOR.env.mac)a.on("keypress",b,this)}}})();
+(function(){CKEDITOR.lang={languages:{af:1,ar:1,az:1,bg:1,bn:1,bs:1,ca:1,cs:1,cy:1,da:1,de:1,"de-ch":1,el:1,"en-au":1,"en-ca":1,"en-gb":1,en:1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,"fr-ca":1,fr:1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,is:1,it:1,ja:1,ka:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,ms:1,nb:1,nl:1,no:1,oc:1,pl:1,"pt-br":1,pt:1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,"sr-latn":1,sr:1,sv:1,th:1,tr:1,tt:1,ug:1,uk:1,vi:1,"zh-cn":1,zh:1},rtl:{ar:1,fa:1,he:1,ku:1,ug:1},load:function(a,d,b){a&&CKEDITOR.lang.languages[a]||
+(a=this.detect(d,a));var c=this;d=function(){c[a].dir=c.rtl[a]?"rtl":"ltr";b(a,c[a])};this[a]?d():CKEDITOR.scriptLoader.load(CKEDITOR.getUrl("lang/"+a+".js"),d,this)},detect:function(a,d){var b=this.languages;d=d||navigator.userLanguage||navigator.language||a;var c=d.toLowerCase().match(/([a-z]+)(?:-([a-z]+))?/),e=c[1],c=c[2];b[e+"-"+c]?e=e+"-"+c:b[e]||(e=null);CKEDITOR.lang.detect=e?function(){return e}:function(a){return a};return e||a}}})();
+CKEDITOR.scriptLoader=function(){var a={},d={};return{load:function(b,c,e,g){var k="string"==typeof b;k&&(b=[b]);e||(e=CKEDITOR);var h=b.length,p=[],r=[],f=function(a){c&&(k?c.call(e,a):c.call(e,p,r))};if(0===h)f(!0);else{var B=function(a,b){(b?p:r).push(a);0>=--h&&(g&&CKEDITOR.document.getDocumentElement().removeStyle("cursor"),f(b))},u=function(b,c){a[b]=1;var e=d[b];delete d[b];for(var f=0;f<e.length;f++)e[f](b,c)},z=function(b){if(a[b])B(b,!0);else{var e=d[b]||(d[b]=[]);e.push(B);if(!(1<e.length)){var f=
+new CKEDITOR.dom.element("script");f.setAttributes({type:"text/javascript",src:b});c&&(CKEDITOR.env.ie&&(8>=CKEDITOR.env.version||CKEDITOR.env.ie9Compat)?f.$.onreadystatechange=function(){if("loaded"==f.$.readyState||"complete"==f.$.readyState)f.$.onreadystatechange=null,u(b,!0)}:(f.$.onload=function(){setTimeout(function(){u(b,!0)},0)},f.$.onerror=function(){u(b,!1)}));f.appendTo(CKEDITOR.document.getHead())}}};g&&CKEDITOR.document.getDocumentElement().setStyle("cursor","wait");for(var y=0;y<h;y++)z(b[y])}},
+queue:function(){function a(){var b;(b=c[0])&&this.load(b.scriptUrl,b.callback,CKEDITOR,0)}var c=[];return function(d,g){var k=this;c.push({scriptUrl:d,callback:function(){g&&g.apply(this,arguments);c.shift();a.call(k)}});1==c.length&&a.call(this)}}()}}();CKEDITOR.resourceManager=function(a,d){this.basePath=a;this.fileName=d;this.registered={};this.loaded={};this.externals={};this._={waitingList:{}}};
+CKEDITOR.resourceManager.prototype={add:function(a,d){if(this.registered[a])throw Error('[CKEDITOR.resourceManager.add] The resource name "'+a+'" is already registered.');var b=this.registered[a]=d||{};b.name=a;b.path=this.getPath(a);CKEDITOR.fire(a+CKEDITOR.tools.capitalize(this.fileName)+"Ready",b);return this.get(a)},get:function(a){return this.registered[a]||null},getPath:function(a){var d=this.externals[a];return CKEDITOR.getUrl(d&&d.dir||this.basePath+a+"/")},getFilePath:function(a){var d=this.externals[a];
+return CKEDITOR.getUrl(this.getPath(a)+(d?d.file:this.fileName+".js"))},addExternal:function(a,d,b){a=a.split(",");for(var c=0;c<a.length;c++){var e=a[c];b||(d=d.replace(/[^\/]+$/,function(a){b=a;return""}));this.externals[e]={dir:d,file:b||this.fileName+".js"}}},load:function(a,d,b){CKEDITOR.tools.isArray(a)||(a=a?[a]:[]);for(var c=this.loaded,e=this.registered,g=[],k={},h={},p=0;p<a.length;p++){var r=a[p];if(r)if(c[r]||e[r])h[r]=this.get(r);else{var f=this.getFilePath(r);g.push(f);f in k||(k[f]=
+[]);k[f].push(r)}}CKEDITOR.scriptLoader.load(g,function(a,e){if(e.length)throw Error('[CKEDITOR.resourceManager.load] Resource name "'+k[e[0]].join(",")+'" was not found at "'+e[0]+'".');for(var f=0;f<a.length;f++)for(var g=k[a[f]],m=0;m<g.length;m++){var x=g[m];h[x]=this.get(x);c[x]=1}d.call(b,h)},this)}};CKEDITOR.plugins=new CKEDITOR.resourceManager("plugins/","plugin");
+CKEDITOR.plugins.load=CKEDITOR.tools.override(CKEDITOR.plugins.load,function(a){var d={};return function(b,c,e){var g={},k=function(b){a.call(this,b,function(a){CKEDITOR.tools.extend(g,a);var b=[],f;for(f in a){var h=a[f],u=h&&h.requires;if(!d[f]){if(h.icons)for(var z=h.icons.split(","),y=z.length;y--;)CKEDITOR.skin.addIcon(z[y],h.path+"icons/"+(CKEDITOR.env.hidpi&&h.hidpi?"hidpi/":"")+z[y]+".png");d[f]=1}if(u)for(u.split&&(u=u.split(",")),h=0;h<u.length;h++)g[u[h]]||b.push(u[h])}if(b.length)k.call(this,
+b);else{for(f in g)h=g[f],h.onLoad&&!h.onLoad._called&&(!1===h.onLoad()&&delete g[f],h.onLoad._called=1);c&&c.call(e||window,g)}},this)};k.call(this,b)}});CKEDITOR.plugins.setLang=function(a,d,b){var c=this.get(a);a=c.langEntries||(c.langEntries={});c=c.lang||(c.lang=[]);c.split&&(c=c.split(","));-1==CKEDITOR.tools.indexOf(c,d)&&c.push(d);a[d]=b};CKEDITOR.ui=function(a){if(a.ui)return a.ui;this.items={};this.instances={};this.editor=a;this._={handlers:{}};return this};
+CKEDITOR.ui.prototype={add:function(a,d,b){b.name=a.toLowerCase();var c=this.items[a]={type:d,command:b.command||null,args:Array.prototype.slice.call(arguments,2)};CKEDITOR.tools.extend(c,b)},get:function(a){return this.instances[a]},create:function(a){var d=this.items[a],b=d&&this._.handlers[d.type],c=d&&d.command&&this.editor.getCommand(d.command),b=b&&b.create.apply(this,d.args);this.instances[a]=b;c&&c.uiItems.push(b);b&&!b.type&&(b.type=d.type);return b},addHandler:function(a,d){this._.handlers[a]=
+d},space:function(a){return CKEDITOR.document.getById(this.spaceId(a))},spaceId:function(a){return this.editor.id+"_"+a}};CKEDITOR.event.implementOn(CKEDITOR.ui);
+(function(){function a(a,e,f){CKEDITOR.event.call(this);a=a&&CKEDITOR.tools.clone(a);if(void 0!==e){if(!(e instanceof CKEDITOR.dom.element))throw Error("Expect element of type CKEDITOR.dom.element.");if(!f)throw Error("One of the element modes must be specified.");if(CKEDITOR.env.ie&&CKEDITOR.env.quirks&&f==CKEDITOR.ELEMENT_MODE_INLINE)throw Error("Inline element mode is not supported on IE quirks.");if(!b(e,f))throw Error('The specified element mode is not supported on element: "'+e.getName()+'".');
+this.element=e;this.elementMode=f;this.name=this.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO&&(e.getId()||e.getNameAtt())}else this.elementMode=CKEDITOR.ELEMENT_MODE_NONE;this._={};this.commands={};this.templates={};this.name=this.name||d();this.id=CKEDITOR.tools.getNextId();this.status="unloaded";this.config=CKEDITOR.tools.prototypedCopy(CKEDITOR.config);this.ui=new CKEDITOR.ui(this);this.focusManager=new CKEDITOR.focusManager(this);this.keystrokeHandler=new CKEDITOR.keystrokeHandler(this);this.on("readOnly",
+c);this.on("selectionChange",function(a){g(this,a.data.path)});this.on("activeFilterChange",function(){g(this,this.elementPath(),!0)});this.on("mode",c);this.on("instanceReady",function(){this.config.startupFocus&&this.focus()});CKEDITOR.fire("instanceCreated",null,this);CKEDITOR.add(this);CKEDITOR.tools.setTimeout(function(){"destroyed"!==this.status?h(this,a):CKEDITOR.warn("editor-incorrect-destroy")},0,this)}function d(){do var a="editor"+ ++z;while(CKEDITOR.instances[a]);return a}function b(a,
+b){return b==CKEDITOR.ELEMENT_MODE_INLINE?a.is(CKEDITOR.dtd.$editable)||a.is("textarea"):b==CKEDITOR.ELEMENT_MODE_REPLACE?!a.is(CKEDITOR.dtd.$nonBodyContent):1}function c(){var a=this.commands,b;for(b in a)e(this,a[b])}function e(a,b){b[b.startDisabled?"disable":a.readOnly&&!b.readOnly?"disable":b.modes[a.mode]?"enable":"disable"]()}function g(a,b,c){if(b){var d,e,l=a.commands;for(e in l)d=l[e],(c||d.contextSensitive)&&d.refresh(a,b)}}function k(a){var b=a.config.customConfig;if(!b)return!1;var b=
+CKEDITOR.getUrl(b),c=y[b]||(y[b]={});c.fn?(c.fn.call(a,a.config),CKEDITOR.getUrl(a.config.customConfig)!=b&&k(a)||a.fireOnce("customConfigLoaded")):CKEDITOR.scriptLoader.queue(b,function(){c.fn=CKEDITOR.editorConfig?CKEDITOR.editorConfig:function(){};k(a)});return!0}function h(a,b){a.on("customConfigLoaded",function(){if(b){if(b.on)for(var c in b.on)a.on(c,b.on[c]);CKEDITOR.tools.extend(a.config,b,!0);delete a.config.on}c=a.config;a.readOnly=c.readOnly?!0:a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?
+a.element.is("textarea")?a.element.hasAttribute("disabled")||a.element.hasAttribute("readonly"):a.element.isReadOnly():a.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE?a.element.hasAttribute("disabled")||a.element.hasAttribute("readonly"):!1;a.blockless=a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?!(a.element.is("textarea")||CKEDITOR.dtd[a.element.getName()].p):!1;a.tabIndex=c.tabIndex||a.element&&a.element.getAttribute("tabindex")||0;a.activeEnterMode=a.enterMode=a.blockless?CKEDITOR.ENTER_BR:c.enterMode;
+a.activeShiftEnterMode=a.shiftEnterMode=a.blockless?CKEDITOR.ENTER_BR:c.shiftEnterMode;c.skin&&(CKEDITOR.skinName=c.skin);a.fireOnce("configLoaded");a.dataProcessor=new CKEDITOR.htmlDataProcessor(a);a.filter=a.activeFilter=new CKEDITOR.filter(a);p(a)});b&&null!=b.customConfig&&(a.config.customConfig=b.customConfig);k(a)||a.fireOnce("customConfigLoaded")}function p(a){CKEDITOR.skin.loadPart("editor",function(){r(a)})}function r(a){CKEDITOR.lang.load(a.config.language,a.config.defaultLanguage,function(b,
+c){var d=a.config.title;a.langCode=b;a.lang=CKEDITOR.tools.prototypedCopy(c);a.title="string"==typeof d||!1===d?d:[a.lang.editor,a.name].join(", ");a.config.contentsLangDirection||(a.config.contentsLangDirection=a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?a.element.getDirection(1):a.lang.dir);a.fire("langLoaded");f(a)})}function f(a){a.getStylesSet(function(b){a.once("loaded",function(){a.fire("stylesSet",{styles:b})},null,null,1);B(a)})}function B(a){var b=a.config,c=b.plugins,d=b.extraPlugins,e=
+b.removePlugins;if(d)var l=new RegExp("(?:^|,)(?:"+d.replace(/\s*,\s*/g,"|")+")(?\x3d,|$)","g"),c=c.replace(l,""),c=c+(","+d);if(e)var q=new RegExp("(?:^|,)(?:"+e.replace(/\s*,\s*/g,"|")+")(?\x3d,|$)","g"),c=c.replace(q,"");CKEDITOR.env.air&&(c+=",adobeair");CKEDITOR.plugins.load(c.split(","),function(c){var d=[],l=[],e=[];a.plugins=c;for(var f in c){var g=c[f],k=g.lang,h=null,p=g.requires,r;CKEDITOR.tools.isArray(p)&&(p=p.join(","));if(p&&(r=p.match(q)))for(;p=r.pop();)CKEDITOR.error("editor-plugin-required",
+{plugin:p.replace(",",""),requiredBy:f});k&&!a.lang[f]&&(k.split&&(k=k.split(",")),0<=CKEDITOR.tools.indexOf(k,a.langCode)?h=a.langCode:(h=a.langCode.replace(/-.*/,""),h=h!=a.langCode&&0<=CKEDITOR.tools.indexOf(k,h)?h:0<=CKEDITOR.tools.indexOf(k,"en")?"en":k[0]),g.langEntries&&g.langEntries[h]?(a.lang[f]=g.langEntries[h],h=null):e.push(CKEDITOR.getUrl(g.path+"lang/"+h+".js")));l.push(h);d.push(g)}CKEDITOR.scriptLoader.load(e,function(){for(var c=["beforeInit","init","afterInit"],e=0;e<c.length;e++)for(var q=
+0;q<d.length;q++){var n=d[q];0===e&&l[q]&&n.lang&&n.langEntries&&(a.lang[n.name]=n.langEntries[l[q]]);if(n[c[e]])n[c[e]](a)}a.fireOnce("pluginsLoaded");b.keystrokes&&a.setKeystroke(a.config.keystrokes);for(q=0;q<a.config.blockedKeystrokes.length;q++)a.keystrokeHandler.blockedKeystrokes[a.config.blockedKeystrokes[q]]=1;a.status="loaded";a.fireOnce("loaded");CKEDITOR.fire("instanceLoaded",null,a)})})}function u(){var a=this.element;if(a&&this.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO){var b=this.getData();
+this.config.htmlEncodeOutput&&(b=CKEDITOR.tools.htmlEncode(b));a.is("textarea")?a.setValue(b):a.setHtml(b);return!0}return!1}a.prototype=CKEDITOR.editor.prototype;CKEDITOR.editor=a;var z=0,y={};CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{addCommand:function(a,b){b.name=a.toLowerCase();var c=new CKEDITOR.command(this,b);this.mode&&e(this,c);return this.commands[a]=c},_attachToForm:function(){function a(b){c.updateElement();c._.required&&!d.getValue()&&!1===c.fire("required")&&b.data.preventDefault()}
+function b(a){return!!(a&&a.call&&a.apply)}var c=this,d=c.element,e=new CKEDITOR.dom.element(d.$.form);d.is("textarea")&&e&&(e.on("submit",a),b(e.$.submit)&&(e.$.submit=CKEDITOR.tools.override(e.$.submit,function(b){return function(){a();b.apply?b.apply(this):b()}})),c.on("destroy",function(){e.removeListener("submit",a)}))},destroy:function(a){this.fire("beforeDestroy");!a&&u.call(this);this.editable(null);this.filter&&(this.filter.destroy(),delete this.filter);delete this.activeFilter;this.status=
+"destroyed";this.fire("destroy");this.removeAllListeners();CKEDITOR.remove(this);CKEDITOR.fire("instanceDestroyed",null,this)},elementPath:function(a){if(!a){a=this.getSelection();if(!a)return null;a=a.getStartElement()}return a?new CKEDITOR.dom.elementPath(a,this.editable()):null},createRange:function(){var a=this.editable();return a?new CKEDITOR.dom.range(a):null},execCommand:function(a,b){var c=this.getCommand(a),d={name:a,commandData:b,command:c};return c&&c.state!=CKEDITOR.TRISTATE_DISABLED&&
+!1!==this.fire("beforeCommandExec",d)&&(d.returnValue=c.exec(d.commandData),!c.async&&!1!==this.fire("afterCommandExec",d))?d.returnValue:!1},getCommand:function(a){return this.commands[a]},getData:function(a){!a&&this.fire("beforeGetData");var b=this._.data;"string"!=typeof b&&(b=(b=this.element)&&this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE?b.is("textarea")?b.getValue():b.getHtml():"");b={dataValue:b};!a&&this.fire("getData",b);return b.dataValue},getSnapshot:function(){var a=this.fire("getSnapshot");
+"string"!=typeof a&&(a=(a=this.element)&&this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE?a.is("textarea")?a.getValue():a.getHtml():"");return a},loadSnapshot:function(a){this.fire("loadSnapshot",a)},setData:function(a,b,c){var d=!0,e=b;b&&"object"==typeof b&&(c=b.internal,e=b.callback,d=!b.noSnapshot);!c&&d&&this.fire("saveSnapshot");if(e||!c)this.once("dataReady",function(a){!c&&d&&this.fire("saveSnapshot");e&&e.call(a.editor)});a={dataValue:a};!c&&this.fire("setData",a);this._.data=a.dataValue;
+!c&&this.fire("afterSetData",a)},setReadOnly:function(a){a=null==a||a;this.readOnly!=a&&(this.readOnly=a,this.keystrokeHandler.blockedKeystrokes[8]=+a,this.editable().setReadOnly(a),this.fire("readOnly"))},insertHtml:function(a,b,c){this.fire("insertHtml",{dataValue:a,mode:b,range:c})},insertText:function(a){this.fire("insertText",a)},insertElement:function(a){this.fire("insertElement",a)},getSelectedHtml:function(a){var b=this.editable(),c=this.getSelection(),c=c&&c.getRanges();if(!b||!c||0===c.length)return null;
+for(var d=new CKEDITOR.dom.documentFragment,e,l,q,n=0;n<c.length;n++){var f=c[n],g=f.startContainer;g.getName&&"tr"==g.getName()?(e||(e=g.getAscendant("table").clone(),e.append(g.getAscendant("tbody").clone()),d.append(e),e=e.findOne("tbody")),l&&l.equals(g)||(l=g,q=g.clone(),e.append(q)),q.append(f.cloneContents())):d.append(f.cloneContents())}b=e?d:b.getHtmlFromRange(c[0]);return a?b.getHtml():b},extractSelectedHtml:function(a,b){var c=this.editable(),d=this.getSelection().getRanges();if(!c||0===
+d.length)return null;d=d[0];c=c.extractHtmlFromRange(d,b);b||this.getSelection().selectRanges([d]);return a?c.getHtml():c},focus:function(){this.fire("beforeFocus")},checkDirty:function(){return"ready"==this.status&&this._.previousValue!==this.getSnapshot()},resetDirty:function(){this._.previousValue=this.getSnapshot()},updateElement:function(){return u.call(this)},setKeystroke:function(){for(var a=this.keystrokeHandler.keystrokes,b=CKEDITOR.tools.isArray(arguments[0])?arguments[0]:[[].slice.call(arguments,
+0)],c,d,e=b.length;e--;)c=b[e],d=0,CKEDITOR.tools.isArray(c)&&(d=c[1],c=c[0]),d?a[c]=d:delete a[c]},getCommandKeystroke:function(a){var b=a.name,c=this.keystrokeHandler.keystrokes,d;if(a.fakeKeystroke)return a.fakeKeystroke;for(d in c)if(c.hasOwnProperty(d)&&c[d]==b)return d;return null},addFeature:function(a){return this.filter.addFeature(a)},setActiveFilter:function(a){a||(a=this.filter);this.activeFilter!==a&&(this.activeFilter=a,this.fire("activeFilterChange"),a===this.filter?this.setActiveEnterMode(null,
+null):this.setActiveEnterMode(a.getAllowedEnterMode(this.enterMode),a.getAllowedEnterMode(this.shiftEnterMode,!0)))},setActiveEnterMode:function(a,b){a=a?this.blockless?CKEDITOR.ENTER_BR:a:this.enterMode;b=b?this.blockless?CKEDITOR.ENTER_BR:b:this.shiftEnterMode;if(this.activeEnterMode!=a||this.activeShiftEnterMode!=b)this.activeEnterMode=a,this.activeShiftEnterMode=b,this.fire("activeEnterModeChange")},showNotification:function(a){alert(a)}})})();CKEDITOR.ELEMENT_MODE_NONE=0;
+CKEDITOR.ELEMENT_MODE_REPLACE=1;CKEDITOR.ELEMENT_MODE_APPENDTO=2;CKEDITOR.ELEMENT_MODE_INLINE=3;CKEDITOR.htmlParser=function(){this._={htmlPartsRegex:/<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)--\x3e)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/g}};
+(function(){var a=/([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,d={checked:1,compact:1,declare:1,defer:1,disabled:1,ismap:1,multiple:1,nohref:1,noresize:1,noshade:1,nowrap:1,readonly:1,selected:1};CKEDITOR.htmlParser.prototype={onTagOpen:function(){},onTagClose:function(){},onText:function(){},onCDATA:function(){},onComment:function(){},parse:function(b){for(var c,e,g=0,k;c=this._.htmlPartsRegex.exec(b);){e=c.index;if(e>g)if(g=b.substring(g,e),k)k.push(g);else this.onText(g);
+g=this._.htmlPartsRegex.lastIndex;if(e=c[1])if(e=e.toLowerCase(),k&&CKEDITOR.dtd.$cdata[e]&&(this.onCDATA(k.join("")),k=null),!k){this.onTagClose(e);continue}if(k)k.push(c[0]);else if(e=c[3]){if(e=e.toLowerCase(),!/="/.test(e)){var h={},p,r=c[4];c=!!c[5];if(r)for(;p=a.exec(r);){var f=p[1].toLowerCase();p=p[2]||p[3]||p[4]||"";h[f]=!p&&d[f]?f:CKEDITOR.tools.htmlDecodeAttr(p)}this.onTagOpen(e,h,c);!k&&CKEDITOR.dtd.$cdata[e]&&(k=[])}}else if(e=c[2])this.onComment(e)}if(b.length>g)this.onText(b.substring(g,
+b.length))}}})();
+CKEDITOR.htmlParser.basicWriter=CKEDITOR.tools.createClass({$:function(){this._={output:[]}},proto:{openTag:function(a){this._.output.push("\x3c",a)},openTagClose:function(a,d){d?this._.output.push(" /\x3e"):this._.output.push("\x3e")},attribute:function(a,d){"string"==typeof d&&(d=CKEDITOR.tools.htmlEncodeAttr(d));this._.output.push(" ",a,'\x3d"',d,'"')},closeTag:function(a){this._.output.push("\x3c/",a,"\x3e")},text:function(a){this._.output.push(a)},comment:function(a){this._.output.push("\x3c!--",a,
+"--\x3e")},write:function(a){this._.output.push(a)},reset:function(){this._.output=[];this._.indent=!1},getHtml:function(a){var d=this._.output.join("");a&&this.reset();return d}}});"use strict";
+(function(){CKEDITOR.htmlParser.node=function(){};CKEDITOR.htmlParser.node.prototype={remove:function(){var a=this.parent.children,d=CKEDITOR.tools.indexOf(a,this),b=this.previous,c=this.next;b&&(b.next=c);c&&(c.previous=b);a.splice(d,1);this.parent=null},replaceWith:function(a){var d=this.parent.children,b=CKEDITOR.tools.indexOf(d,this),c=a.previous=this.previous,e=a.next=this.next;c&&(c.next=a);e&&(e.previous=a);d[b]=a;a.parent=this.parent;this.parent=null},insertAfter:function(a){var d=a.parent.children,
+b=CKEDITOR.tools.indexOf(d,a),c=a.next;d.splice(b+1,0,this);this.next=a.next;this.previous=a;a.next=this;c&&(c.previous=this);this.parent=a.parent},insertBefore:function(a){var d=a.parent.children,b=CKEDITOR.tools.indexOf(d,a);d.splice(b,0,this);this.next=a;(this.previous=a.previous)&&(a.previous.next=this);a.previous=this;this.parent=a.parent},getAscendant:function(a){var d="function"==typeof a?a:"string"==typeof a?function(b){return b.name==a}:function(b){return b.name in a},b=this.parent;for(;b&&
+b.type==CKEDITOR.NODE_ELEMENT;){if(d(b))return b;b=b.parent}return null},wrapWith:function(a){this.replaceWith(a);a.add(this);return a},getIndex:function(){return CKEDITOR.tools.indexOf(this.parent.children,this)},getFilterContext:function(a){return a||{}}}})();"use strict";CKEDITOR.htmlParser.comment=function(a){this.value=a;this._={isBlockLike:!1}};
+CKEDITOR.htmlParser.comment.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_COMMENT,filter:function(a,d){var b=this.value;if(!(b=a.onComment(d,b,this)))return this.remove(),!1;if("string"!=typeof b)return this.replaceWith(b),!1;this.value=b;return!0},writeHtml:function(a,d){d&&this.filter(d);a.comment(this.value)}});"use strict";
+(function(){CKEDITOR.htmlParser.text=function(a){this.value=a;this._={isBlockLike:!1}};CKEDITOR.htmlParser.text.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(a,d){if(!(this.value=a.onText(d,this.value,this)))return this.remove(),!1},writeHtml:function(a,d){d&&this.filter(d);a.text(this.value)}})})();"use strict";
+(function(){CKEDITOR.htmlParser.cdata=function(a){this.value=a};CKEDITOR.htmlParser.cdata.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_TEXT,filter:function(){},writeHtml:function(a){a.write(this.value)}})})();"use strict";CKEDITOR.htmlParser.fragment=function(){this.children=[];this.parent=null;this._={isBlockLike:!0,hasInlineStarted:!1}};
+(function(){function a(a){return a.attributes["data-cke-survive"]?!1:"a"==a.name&&a.attributes.href||CKEDITOR.dtd.$removeEmpty[a.name]}var d=CKEDITOR.tools.extend({table:1,ul:1,ol:1,dl:1},CKEDITOR.dtd.table,CKEDITOR.dtd.ul,CKEDITOR.dtd.ol,CKEDITOR.dtd.dl),b={ol:1,ul:1},c=CKEDITOR.tools.extend({},{html:1},CKEDITOR.dtd.html,CKEDITOR.dtd.body,CKEDITOR.dtd.head,{style:1,script:1}),e={ul:"li",ol:"li",dl:"dd",table:"tbody",tbody:"tr",thead:"tr",tfoot:"tr",tr:"td"};CKEDITOR.htmlParser.fragment.fromHtml=
+function(g,k,h){function p(a){var b;if(0<x.length)for(var c=0;c<x.length;c++){var d=x[c],l=d.name,e=CKEDITOR.dtd[l],f=w.name&&CKEDITOR.dtd[w.name];f&&!f[l]||a&&e&&!e[a]&&CKEDITOR.dtd[a]?l==w.name&&(B(w,w.parent,1),c--):(b||(r(),b=1),d=d.clone(),d.parent=w,w=d,x.splice(c,1),c--)}}function r(){for(;J.length;)B(J.shift(),w)}function f(a){if(a._.isBlockLike&&"pre"!=a.name&&"textarea"!=a.name){var b=a.children.length,c=a.children[b-1],d;c&&c.type==CKEDITOR.NODE_TEXT&&((d=CKEDITOR.tools.rtrim(c.value))?
+c.value=d:a.children.length=b-1)}}function B(b,c,d){c=c||w||m;var e=w;void 0===b.previous&&(u(c,b)&&(w=c,y.onTagOpen(h,{}),b.returnPoint=c=w),f(b),a(b)&&!b.children.length||c.add(b),"pre"==b.name&&(l=!1),"textarea"==b.name&&(F=!1));b.returnPoint?(w=b.returnPoint,delete b.returnPoint):w=d?c:e}function u(a,b){if((a==m||"body"==a.name)&&h&&(!a.name||CKEDITOR.dtd[a.name][h])){var c,d;return(c=b.attributes&&(d=b.attributes["data-cke-real-element-type"])?d:b.name)&&c in CKEDITOR.dtd.$inline&&!(c in CKEDITOR.dtd.head)&&
+!b.isOrphan||b.type==CKEDITOR.NODE_TEXT}}function z(a,b){return a in CKEDITOR.dtd.$listItem||a in CKEDITOR.dtd.$tableContent?a==b||"dt"==a&&"dd"==b||"dd"==a&&"dt"==b:!1}var y=new CKEDITOR.htmlParser,m=k instanceof CKEDITOR.htmlParser.element?k:"string"==typeof k?new CKEDITOR.htmlParser.element(k):new CKEDITOR.htmlParser.fragment,x=[],J=[],w=m,F="textarea"==m.name,l="pre"==m.name;y.onTagOpen=function(e,n,f,g){n=new CKEDITOR.htmlParser.element(e,n);n.isUnknown&&f&&(n.isEmpty=!0);n.isOptionalClose=g;
+if(a(n))x.push(n);else{if("pre"==e)l=!0;else{if("br"==e&&l){w.add(new CKEDITOR.htmlParser.text("\n"));return}"textarea"==e&&(F=!0)}if("br"==e)J.push(n);else{for(;!(g=(f=w.name)?CKEDITOR.dtd[f]||(w._.isBlockLike?CKEDITOR.dtd.div:CKEDITOR.dtd.span):c,n.isUnknown||w.isUnknown||g[e]);)if(w.isOptionalClose)y.onTagClose(f);else if(e in b&&f in b)f=w.children,(f=f[f.length-1])&&"li"==f.name||B(f=new CKEDITOR.htmlParser.element("li"),w),!n.returnPoint&&(n.returnPoint=w),w=f;else if(e in CKEDITOR.dtd.$listItem&&
+!z(e,f))y.onTagOpen("li"==e?"ul":"dl",{},0,1);else if(f in d&&!z(e,f))!n.returnPoint&&(n.returnPoint=w),w=w.parent;else if(f in CKEDITOR.dtd.$inline&&x.unshift(w),w.parent)B(w,w.parent,1);else{n.isOrphan=1;break}p(e);r();n.parent=w;n.isEmpty?B(n):w=n}}};y.onTagClose=function(a){for(var b=x.length-1;0<=b;b--)if(a==x[b].name){x.splice(b,1);return}for(var c=[],d=[],l=w;l!=m&&l.name!=a;)l._.isBlockLike||d.unshift(l),c.push(l),l=l.returnPoint||l.parent;if(l!=m){for(b=0;b<c.length;b++){var e=c[b];B(e,e.parent)}w=
+l;l._.isBlockLike&&r();B(l,l.parent);l==w&&(w=w.parent);x=x.concat(d)}"body"==a&&(h=!1)};y.onText=function(a){if(!(w._.hasInlineStarted&&!J.length||l||F)&&(a=CKEDITOR.tools.ltrim(a),0===a.length))return;var b=w.name,f=b?CKEDITOR.dtd[b]||(w._.isBlockLike?CKEDITOR.dtd.div:CKEDITOR.dtd.span):c;if(!F&&!f["#"]&&b in d)y.onTagOpen(e[b]||""),y.onText(a);else{r();p();l||F||(a=a.replace(/[\t\r\n ]{2,}|[\t\r\n]/g," "));a=new CKEDITOR.htmlParser.text(a);if(u(w,a))this.onTagOpen(h,{},0,1);w.add(a)}};y.onCDATA=
+function(a){w.add(new CKEDITOR.htmlParser.cdata(a))};y.onComment=function(a){r();p();w.add(new CKEDITOR.htmlParser.comment(a))};y.parse(g);for(r();w!=m;)B(w,w.parent,1);f(m);return m};CKEDITOR.htmlParser.fragment.prototype={type:CKEDITOR.NODE_DOCUMENT_FRAGMENT,add:function(a,b){isNaN(b)&&(b=this.children.length);var c=0<b?this.children[b-1]:null;if(c){if(a._.isBlockLike&&c.type==CKEDITOR.NODE_TEXT&&(c.value=CKEDITOR.tools.rtrim(c.value),0===c.value.length)){this.children.pop();this.add(a);return}c.next=
+a}a.previous=c;a.parent=this;this.children.splice(b,0,a);this._.hasInlineStarted||(this._.hasInlineStarted=a.type==CKEDITOR.NODE_TEXT||a.type==CKEDITOR.NODE_ELEMENT&&!a._.isBlockLike)},filter:function(a,b){b=this.getFilterContext(b);a.onRoot(b,this);this.filterChildren(a,!1,b)},filterChildren:function(a,b,c){if(this.childrenFilteredBy!=a.id){c=this.getFilterContext(c);if(b&&!this.parent)a.onRoot(c,this);this.childrenFilteredBy=a.id;for(b=0;b<this.children.length;b++)!1===this.children[b].filter(a,
+c)&&b--}},writeHtml:function(a,b){b&&this.filter(b);this.writeChildrenHtml(a)},writeChildrenHtml:function(a,b,c){var d=this.getFilterContext();if(c&&!this.parent&&b)b.onRoot(d,this);b&&this.filterChildren(b,!1,d);b=0;c=this.children;for(d=c.length;b<d;b++)c[b].writeHtml(a)},forEach:function(a,b,c){if(!(c||b&&this.type!=b))var d=a(this);if(!1!==d){c=this.children;for(var e=0;e<c.length;e++)d=c[e],d.type==CKEDITOR.NODE_ELEMENT?d.forEach(a,b):b&&d.type!=b||a(d)}},getFilterContext:function(a){return a||
+{}}}})();"use strict";
+(function(){function a(){this.rules=[]}function d(b,c,d,g){var k,h;for(k in c)(h=b[k])||(h=b[k]=new a),h.add(c[k],d,g)}CKEDITOR.htmlParser.filter=CKEDITOR.tools.createClass({$:function(b){this.id=CKEDITOR.tools.getNextNumber();this.elementNameRules=new a;this.attributeNameRules=new a;this.elementsRules={};this.attributesRules={};this.textRules=new a;this.commentRules=new a;this.rootRules=new a;b&&this.addRules(b,10)},proto:{addRules:function(a,c){var e;"number"==typeof c?e=c:c&&"priority"in c&&(e=
+c.priority);"number"!=typeof e&&(e=10);"object"!=typeof c&&(c={});a.elementNames&&this.elementNameRules.addMany(a.elementNames,e,c);a.attributeNames&&this.attributeNameRules.addMany(a.attributeNames,e,c);a.elements&&d(this.elementsRules,a.elements,e,c);a.attributes&&d(this.attributesRules,a.attributes,e,c);a.text&&this.textRules.add(a.text,e,c);a.comment&&this.commentRules.add(a.comment,e,c);a.root&&this.rootRules.add(a.root,e,c)},applyTo:function(a){a.filter(this)},onElementName:function(a,c){return this.elementNameRules.execOnName(a,
+c)},onAttributeName:function(a,c){return this.attributeNameRules.execOnName(a,c)},onText:function(a,c,d){return this.textRules.exec(a,c,d)},onComment:function(a,c,d){return this.commentRules.exec(a,c,d)},onRoot:function(a,c){return this.rootRules.exec(a,c)},onElement:function(a,c){for(var d=[this.elementsRules["^"],this.elementsRules[c.name],this.elementsRules.$],g,k=0;3>k;k++)if(g=d[k]){g=g.exec(a,c,this);if(!1===g)return null;if(g&&g!=c)return this.onNode(a,g);if(c.parent&&!c.name)break}return c},
+onNode:function(a,c){var d=c.type;return d==CKEDITOR.NODE_ELEMENT?this.onElement(a,c):d==CKEDITOR.NODE_TEXT?new CKEDITOR.htmlParser.text(this.onText(a,c.value)):d==CKEDITOR.NODE_COMMENT?new CKEDITOR.htmlParser.comment(this.onComment(a,c.value)):null},onAttribute:function(a,c,d,g){return(d=this.attributesRules[d])?d.exec(a,g,c,this):g}}});CKEDITOR.htmlParser.filterRulesGroup=a;a.prototype={add:function(a,c,d){this.rules.splice(this.findIndex(c),0,{value:a,priority:c,options:d})},addMany:function(a,
+c,d){for(var g=[this.findIndex(c),0],k=0,h=a.length;k<h;k++)g.push({value:a[k],priority:c,options:d});this.rules.splice.apply(this.rules,g)},findIndex:function(a){for(var c=this.rules,d=c.length-1;0<=d&&a<c[d].priority;)d--;return d+1},exec:function(a,c){var d=c instanceof CKEDITOR.htmlParser.node||c instanceof CKEDITOR.htmlParser.fragment,g=Array.prototype.slice.call(arguments,1),k=this.rules,h=k.length,p,r,f,B;for(B=0;B<h;B++)if(d&&(p=c.type,r=c.name),f=k[B],!(a.nonEditable&&!f.options.applyToAll||
+a.nestedEditable&&f.options.excludeNestedEditable)){f=f.value.apply(null,g);if(!1===f||d&&f&&(f.name!=r||f.type!=p))return f;null!=f&&(g[0]=c=f)}return c},execOnName:function(a,c){for(var d=0,g=this.rules,k=g.length,h;c&&d<k;d++)h=g[d],a.nonEditable&&!h.options.applyToAll||a.nestedEditable&&h.options.excludeNestedEditable||(c=c.replace(h.value[0],h.value[1]));return c}}})();
+(function(){function a(a,d){function f(a){return a||CKEDITOR.env.needsNbspFiller?new CKEDITOR.htmlParser.text(" "):new CKEDITOR.htmlParser.element("br",{"data-cke-bogus":1})}function n(a,d){return function(l){if(l.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT){var e=[],n=b(l),t,E;if(n)for(q(n,1)&&e.push(n);n;)g(n)&&(t=c(n))&&q(t)&&((E=c(t))&&!g(E)?e.push(t):(f(v).insertAfter(t),t.remove())),n=n.previous;for(n=0;n<e.length;n++)e[n].remove();if(e=!a||!1!==("function"==typeof d?d(l):d))v||CKEDITOR.env.needsBrFiller||
+l.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT?v||CKEDITOR.env.needsBrFiller||!(7<document.documentMode||l.name in CKEDITOR.dtd.tr||l.name in CKEDITOR.dtd.$listItem)?(e=b(l),e=!e||"form"==l.name&&"input"==e.name):e=!1:e=!1;e&&l.add(f(a))}}}function q(a,b){if((!v||CKEDITOR.env.needsBrFiller)&&a.type==CKEDITOR.NODE_ELEMENT&&"br"==a.name&&!a.attributes["data-cke-eol"])return!0;var c;return a.type==CKEDITOR.NODE_TEXT&&(c=a.value.match(x))&&(c.index&&((new CKEDITOR.htmlParser.text(a.value.substring(0,c.index))).insertBefore(a),
+a.value=c[0]),!CKEDITOR.env.needsBrFiller&&v&&(!b||a.parent.name in h)||!v&&((c=a.previous)&&"br"==c.name||!c||g(c)))?!0:!1}var t={elements:{}},v="html"==d,h=CKEDITOR.tools.extend({},l),A;for(A in h)"#"in w[A]||delete h[A];for(A in h)t.elements[A]=n(v,a.config.fillEmptyBlocks);t.root=n(v,!1);t.elements.br=function(a){return function(b){if(b.parent.type!=CKEDITOR.NODE_DOCUMENT_FRAGMENT){var d=b.attributes;if("data-cke-bogus"in d||"data-cke-eol"in d)delete d["data-cke-bogus"];else{for(d=b.next;d&&e(d);)d=
+d.next;var l=c(b);!d&&g(b.parent)?k(b.parent,f(a)):g(d)&&l&&!g(l)&&f(a).insertBefore(d)}}}}(v);return t}function d(a,b){return a!=CKEDITOR.ENTER_BR&&!1!==b?a==CKEDITOR.ENTER_DIV?"div":"p":!1}function b(a){for(a=a.children[a.children.length-1];a&&e(a);)a=a.previous;return a}function c(a){for(a=a.previous;a&&e(a);)a=a.previous;return a}function e(a){return a.type==CKEDITOR.NODE_TEXT&&!CKEDITOR.tools.trim(a.value)||a.type==CKEDITOR.NODE_ELEMENT&&a.attributes["data-cke-bookmark"]}function g(a){return a&&
+(a.type==CKEDITOR.NODE_ELEMENT&&a.name in l||a.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT)}function k(a,b){var c=a.children[a.children.length-1];a.children.push(b);b.parent=a;c&&(c.next=b,b.previous=c)}function h(a){a=a.attributes;"false"!=a.contenteditable&&(a["data-cke-editable"]=a.contenteditable?"true":1);a.contenteditable="false"}function p(a){a=a.attributes;switch(a["data-cke-editable"]){case "true":a.contenteditable="true";break;case "1":delete a.contenteditable}}function r(a){return a.replace(C,
+function(a,b,c){return"\x3c"+b+c.replace(D,function(a,b){return M.test(b)&&-1==c.indexOf("data-cke-saved-"+b)?" data-cke-saved-"+a+" data-cke-"+CKEDITOR.rnd+"-"+a:a})+"\x3e"})}function f(a,b){return a.replace(b,function(a,b,c){0===a.indexOf("\x3ctextarea")&&(a=b+z(c).replace(/</g,"\x26lt;").replace(/>/g,"\x26gt;")+"\x3c/textarea\x3e");return"\x3ccke:encoded\x3e"+encodeURIComponent(a)+"\x3c/cke:encoded\x3e"})}function B(a){return a.replace(Q,function(a,b){return decodeURIComponent(b)})}function u(a){return a.replace(/\x3c!--(?!{cke_protected})[\s\S]+?--\x3e/g,
+function(a){return"\x3c!--"+J+"{C}"+encodeURIComponent(a).replace(/--/g,"%2D%2D")+"--\x3e"})}function z(a){return a.replace(/\x3c!--\{cke_protected\}\{C\}([\s\S]+?)--\x3e/g,function(a,b){return decodeURIComponent(b)})}function y(a,b){var c=b._.dataStore;return a.replace(/\x3c!--\{cke_protected\}([\s\S]+?)--\x3e/g,function(a,b){return decodeURIComponent(b)}).replace(/\{cke_protected_(\d+)\}/g,function(a,b){return c&&c[b]||""})}function m(a,b){var c=[],d=b.config.protectedSource,l=b._.dataStore||(b._.dataStore=
+{id:1}),e=/<\!--\{cke_temp(comment)?\}(\d*?)--\x3e/g,d=[/<script[\s\S]*?(<\/script>|$)/gi,/<noscript[\s\S]*?<\/noscript>/gi,/<meta[\s\S]*?\/?>/gi].concat(d);a=a.replace(/\x3c!--[\s\S]*?--\x3e/g,function(a){return"\x3c!--{cke_tempcomment}"+(c.push(a)-1)+"--\x3e"});for(var f=0;f<d.length;f++)a=a.replace(d[f],function(a){a=a.replace(e,function(a,b,d){return c[d]});return/cke_temp(comment)?/.test(a)?a:"\x3c!--{cke_temp}"+(c.push(a)-1)+"--\x3e"});a=a.replace(e,function(a,b,d){return"\x3c!--"+J+(b?"{C}":
+"")+encodeURIComponent(c[d]).replace(/--/g,"%2D%2D")+"--\x3e"});a=a.replace(/<\w+(?:\s+(?:(?:[^\s=>]+\s*=\s*(?:[^'"\s>]+|'[^']*'|"[^"]*"))|[^\s=\/>]+))+\s*\/?>/g,function(a){return a.replace(/\x3c!--\{cke_protected\}([^>]*)--\x3e/g,function(a,b){l[l.id]=decodeURIComponent(b);return"{cke_protected_"+l.id++ +"}"})});return a=a.replace(/<(title|iframe|textarea)([^>]*)>([\s\S]*?)<\/\1>/g,function(a,c,d,l){return"\x3c"+c+d+"\x3e"+y(z(l),b)+"\x3c/"+c+"\x3e"})}CKEDITOR.htmlDataProcessor=function(b){var c,
+l,e=this;this.editor=b;this.dataFilter=c=new CKEDITOR.htmlParser.filter;this.htmlFilter=l=new CKEDITOR.htmlParser.filter;this.writer=new CKEDITOR.htmlParser.basicWriter;c.addRules(q);c.addRules(n,{applyToAll:!0});c.addRules(a(b,"data"),{applyToAll:!0});l.addRules(t);l.addRules(A,{applyToAll:!0});l.addRules(a(b,"html"),{applyToAll:!0});b.on("toHtml",function(a){a=a.data;var c=a.dataValue,l,c=m(c,b),c=f(c,R),c=r(c),c=f(c,H),c=c.replace(P,"$1cke:$2"),c=c.replace(G,"\x3ccke:$1$2\x3e\x3c/cke:$1\x3e"),
+c=c.replace(/(<pre\b[^>]*>)(\r\n|\n)/g,"$1$2$2"),c=c.replace(/([^a-z0-9<\-])(on\w{3,})(?!>)/gi,"$1data-cke-"+CKEDITOR.rnd+"-$2");l=a.context||b.editable().getName();var e;CKEDITOR.env.ie&&9>CKEDITOR.env.version&&"pre"==l&&(l="div",c="\x3cpre\x3e"+c+"\x3c/pre\x3e",e=1);l=b.document.createElement(l);l.setHtml("a"+c);c=l.getHtml().substr(1);c=c.replace(new RegExp("data-cke-"+CKEDITOR.rnd+"-","ig"),"");e&&(c=c.replace(/^<pre>|<\/pre>$/gi,""));c=c.replace(v,"$1$2");c=B(c);c=z(c);l=!1===a.fixForBody?!1:
+d(a.enterMode,b.config.autoParagraph);c=CKEDITOR.htmlParser.fragment.fromHtml(c,a.context,l);l&&(e=c,!e.children.length&&CKEDITOR.dtd[e.name][l]&&(l=new CKEDITOR.htmlParser.element(l),e.add(l)));a.dataValue=c},null,null,5);b.on("toHtml",function(a){a.data.filter.applyTo(a.data.dataValue,!0,a.data.dontFilter,a.data.enterMode)&&b.fire("dataFiltered")},null,null,6);b.on("toHtml",function(a){a.data.dataValue.filterChildren(e.dataFilter,!0)},null,null,10);b.on("toHtml",function(a){a=a.data;var b=a.dataValue,
+c=new CKEDITOR.htmlParser.basicWriter;b.writeChildrenHtml(c);b=c.getHtml(!0);a.dataValue=u(b)},null,null,15);b.on("toDataFormat",function(a){var c=a.data.dataValue;a.data.enterMode!=CKEDITOR.ENTER_BR&&(c=c.replace(/^<br *\/?>/i,""));a.data.dataValue=CKEDITOR.htmlParser.fragment.fromHtml(c,a.data.context,d(a.data.enterMode,b.config.autoParagraph))},null,null,5);b.on("toDataFormat",function(a){a.data.dataValue.filterChildren(e.htmlFilter,!0)},null,null,10);b.on("toDataFormat",function(a){a.data.filter.applyTo(a.data.dataValue,
+!1,!0)},null,null,11);b.on("toDataFormat",function(a){var c=a.data.dataValue,d=e.writer;d.reset();c.writeChildrenHtml(d);c=d.getHtml(!0);c=z(c);c=y(c,b);a.data.dataValue=c},null,null,15)};CKEDITOR.htmlDataProcessor.prototype={toHtml:function(a,b,c,d){var l=this.editor,e,f,n,q;b&&"object"==typeof b?(e=b.context,c=b.fixForBody,d=b.dontFilter,f=b.filter,n=b.enterMode,q=b.protectedWhitespaces):e=b;e||null===e||(e=l.editable().getName());return l.fire("toHtml",{dataValue:a,context:e,fixForBody:c,dontFilter:d,
+filter:f||l.filter,enterMode:n||l.enterMode,protectedWhitespaces:q}).dataValue},toDataFormat:function(a,b){var c,d,l;b&&(c=b.context,d=b.filter,l=b.enterMode);c||null===c||(c=this.editor.editable().getName());return this.editor.fire("toDataFormat",{dataValue:a,filter:d||this.editor.filter,context:c,enterMode:l||this.editor.enterMode}).dataValue}};var x=/(?:&nbsp;|\xa0)$/,J="{cke_protected}",w=CKEDITOR.dtd,F="caption colgroup col thead tfoot tbody".split(" "),l=CKEDITOR.tools.extend({},w.$blockLimit,
+w.$block),q={elements:{input:h,textarea:h}},n={attributeNames:[[/^on/,"data-cke-pa-on"],[/^data-cke-expando$/,""]]},t={elements:{embed:function(a){var b=a.parent;if(b&&"object"==b.name){var c=b.attributes.width,b=b.attributes.height;c&&(a.attributes.width=c);b&&(a.attributes.height=b)}},a:function(a){var b=a.attributes;if(!(a.children.length||b.name||b.id||a.attributes["data-cke-saved-name"]))return!1}}},A={elementNames:[[/^cke:/,""],[/^\?xml:namespace$/,""]],attributeNames:[[/^data-cke-(saved|pa)-/,
+""],[/^data-cke-.*/,""],["hidefocus",""]],elements:{$:function(a){var b=a.attributes;if(b){if(b["data-cke-temp"])return!1;for(var c=["name","href","src"],d,l=0;l<c.length;l++)d="data-cke-saved-"+c[l],d in b&&delete b[c[l]]}return a},table:function(a){a.children.slice(0).sort(function(a,b){var c,d;a.type==CKEDITOR.NODE_ELEMENT&&b.type==a.type&&(c=CKEDITOR.tools.indexOf(F,a.name),d=CKEDITOR.tools.indexOf(F,b.name));-1<c&&-1<d&&c!=d||(c=a.parent?a.getIndex():-1,d=b.parent?b.getIndex():-1);return c>d?
+1:-1})},param:function(a){a.children=[];a.isEmpty=!0;return a},span:function(a){"Apple-style-span"==a.attributes["class"]&&delete a.name},html:function(a){delete a.attributes.contenteditable;delete a.attributes["class"]},body:function(a){delete a.attributes.spellcheck;delete a.attributes.contenteditable},style:function(a){var b=a.children[0];b&&b.value&&(b.value=CKEDITOR.tools.trim(b.value));a.attributes.type||(a.attributes.type="text/css")},title:function(a){var b=a.children[0];!b&&k(a,b=new CKEDITOR.htmlParser.text);
+b.value=a.attributes["data-cke-title"]||""},input:p,textarea:p},attributes:{"class":function(a){return CKEDITOR.tools.ltrim(a.replace(/(?:^|\s+)cke_[^\s]*/g,""))||!1}}};CKEDITOR.env.ie&&(A.attributes.style=function(a){return a.replace(/(^|;)([^\:]+)/g,function(a){return a.toLowerCase()})});var C=/<(a|area|img|input|source)\b([^>]*)>/gi,D=/([\w-:]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,M=/^(href|src|name)$/i,H=/(?:<style(?=[ >])[^>]*>[\s\S]*?<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,
+R=/(<textarea(?=[ >])[^>]*>)([\s\S]*?)(?:<\/textarea>)/gi,Q=/<cke:encoded>([^<]*)<\/cke:encoded>/gi,P=/(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,v=/(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi,G=/<cke:(param|embed)([^>]*?)\/?>(?!\s*<\/cke:\1)/gi})();"use strict";
+CKEDITOR.htmlParser.element=function(a,d){this.name=a;this.attributes=d||{};this.children=[];var b=a||"",c=b.match(/^cke:(.*)/);c&&(b=c[1]);b=!!(CKEDITOR.dtd.$nonBodyContent[b]||CKEDITOR.dtd.$block[b]||CKEDITOR.dtd.$listItem[b]||CKEDITOR.dtd.$tableContent[b]||CKEDITOR.dtd.$nonEditable[b]||"br"==b);this.isEmpty=!!CKEDITOR.dtd.$empty[a];this.isUnknown=!CKEDITOR.dtd[a];this._={isBlockLike:b,hasInlineStarted:this.isEmpty||!b}};
+CKEDITOR.htmlParser.cssStyle=function(a){var d={};((a instanceof CKEDITOR.htmlParser.element?a.attributes.style:a)||"").replace(/&quot;/g,'"').replace(/\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g,function(a,c,e){"font-family"==c&&(e=e.replace(/["']/g,""));d[c.toLowerCase()]=e});return{rules:d,populate:function(a){var c=this.toString();c&&(a instanceof CKEDITOR.dom.element?a.setAttribute("style",c):a instanceof CKEDITOR.htmlParser.element?a.attributes.style=c:a.style=c)},toString:function(){var a=[],c;
+for(c in d)d[c]&&a.push(c,":",d[c],";");return a.join("")}}};
+(function(){function a(a){return function(b){return b.type==CKEDITOR.NODE_ELEMENT&&("string"==typeof a?b.name==a:b.name in a)}}var d=function(a,b){a=a[0];b=b[0];return a<b?-1:a>b?1:0},b=CKEDITOR.htmlParser.fragment.prototype;CKEDITOR.htmlParser.element.prototype=CKEDITOR.tools.extend(new CKEDITOR.htmlParser.node,{type:CKEDITOR.NODE_ELEMENT,add:b.add,clone:function(){return new CKEDITOR.htmlParser.element(this.name,this.attributes)},filter:function(a,b){var d=this,k,h;b=d.getFilterContext(b);if(b.off)return!0;
+if(!d.parent)a.onRoot(b,d);for(;;){k=d.name;if(!(h=a.onElementName(b,k)))return this.remove(),!1;d.name=h;if(!(d=a.onElement(b,d)))return this.remove(),!1;if(d!==this)return this.replaceWith(d),!1;if(d.name==k)break;if(d.type!=CKEDITOR.NODE_ELEMENT)return this.replaceWith(d),!1;if(!d.name)return this.replaceWithChildren(),!1}k=d.attributes;var p,r;for(p in k){for(h=k[p];;)if(r=a.onAttributeName(b,p))if(r!=p)delete k[p],p=r;else break;else{delete k[p];break}r&&(!1===(h=a.onAttribute(b,d,r,h))?delete k[r]:
+k[r]=h)}d.isEmpty||this.filterChildren(a,!1,b);return!0},filterChildren:b.filterChildren,writeHtml:function(a,b){b&&this.filter(b);var g=this.name,k=[],h=this.attributes,p,r;a.openTag(g,h);for(p in h)k.push([p,h[p]]);a.sortAttributes&&k.sort(d);p=0;for(r=k.length;p<r;p++)h=k[p],a.attribute(h[0],h[1]);a.openTagClose(g,this.isEmpty);this.writeChildrenHtml(a);this.isEmpty||a.closeTag(g)},writeChildrenHtml:b.writeChildrenHtml,replaceWithChildren:function(){for(var a=this.children,b=a.length;b;)a[--b].insertAfter(this);
+this.remove()},forEach:b.forEach,getFirst:function(b){if(!b)return this.children.length?this.children[0]:null;"function"!=typeof b&&(b=a(b));for(var d=0,g=this.children.length;d<g;++d)if(b(this.children[d]))return this.children[d];return null},getHtml:function(){var a=new CKEDITOR.htmlParser.basicWriter;this.writeChildrenHtml(a);return a.getHtml()},setHtml:function(a){a=this.children=CKEDITOR.htmlParser.fragment.fromHtml(a).children;for(var b=0,d=a.length;b<d;++b)a[b].parent=this},getOuterHtml:function(){var a=
+new CKEDITOR.htmlParser.basicWriter;this.writeHtml(a);return a.getHtml()},split:function(a){for(var b=this.children.splice(a,this.children.length-a),d=this.clone(),k=0;k<b.length;++k)b[k].parent=d;d.children=b;b[0]&&(b[0].previous=null);0<a&&(this.children[a-1].next=null);this.parent.add(d,this.getIndex()+1);return d},find:function(a,b){void 0===b&&(b=!1);var d=[],k;for(k=0;k<this.children.length;k++){var h=this.children[k];"function"==typeof a&&a(h)?d.push(h):"string"==typeof a&&h.name===a&&d.push(h);
+b&&h.find&&(d=d.concat(h.find(a,b)))}return d},addClass:function(a){if(!this.hasClass(a)){var b=this.attributes["class"]||"";this.attributes["class"]=b+(b?" ":"")+a}},removeClass:function(a){var b=this.attributes["class"];b&&((b=CKEDITOR.tools.trim(b.replace(new RegExp("(?:\\s+|^)"+a+"(?:\\s+|$)")," ")))?this.attributes["class"]=b:delete this.attributes["class"])},hasClass:function(a){var b=this.attributes["class"];return b?(new RegExp("(?:^|\\s)"+a+"(?\x3d\\s|$)")).test(b):!1},getFilterContext:function(a){var b=
+[];a||(a={off:!1,nonEditable:!1,nestedEditable:!1});a.off||"off"!=this.attributes["data-cke-processor"]||b.push("off",!0);a.nonEditable||"false"!=this.attributes.contenteditable?a.nonEditable&&!a.nestedEditable&&"true"==this.attributes.contenteditable&&b.push("nestedEditable",!0):b.push("nonEditable",!0);if(b.length){a=CKEDITOR.tools.copy(a);for(var d=0;d<b.length;d+=2)a[b[d]]=b[d+1]}return a}},!0)})();
+(function(){var a={},d=/{([^}]+)}/g,b=/([\\'])/g,c=/\n/g,e=/\r/g;CKEDITOR.template=function(g){if(a[g])this.output=a[g];else{var k=g.replace(b,"\\$1").replace(c,"\\n").replace(e,"\\r").replace(d,function(a,b){return"',data['"+b+"']\x3d\x3dundefined?'{"+b+"}':data['"+b+"'],'"});this.output=a[g]=Function("data","buffer","return buffer?buffer.push('"+k+"'):['"+k+"'].join('');")}}})();delete CKEDITOR.loadFullCore;CKEDITOR.instances={};CKEDITOR.document=new CKEDITOR.dom.document(document);
+CKEDITOR.add=function(a){CKEDITOR.instances[a.name]=a;a.on("focus",function(){CKEDITOR.currentInstance!=a&&(CKEDITOR.currentInstance=a,CKEDITOR.fire("currentInstance"))});a.on("blur",function(){CKEDITOR.currentInstance==a&&(CKEDITOR.currentInstance=null,CKEDITOR.fire("currentInstance"))});CKEDITOR.fire("instance",null,a)};CKEDITOR.remove=function(a){delete CKEDITOR.instances[a.name]};
+(function(){var a={};CKEDITOR.addTemplate=function(d,b){var c=a[d];if(c)return c;c={name:d,source:b};CKEDITOR.fire("template",c);return a[d]=new CKEDITOR.template(c.source)};CKEDITOR.getTemplate=function(d){return a[d]}})();(function(){var a=[];CKEDITOR.addCss=function(d){a.push(d)};CKEDITOR.getCss=function(){return a.join("\n")}})();CKEDITOR.on("instanceDestroyed",function(){CKEDITOR.tools.isEmpty(this.instances)&&CKEDITOR.fire("reset")});CKEDITOR.TRISTATE_ON=1;CKEDITOR.TRISTATE_OFF=2;
+CKEDITOR.TRISTATE_DISABLED=0;
+(function(){CKEDITOR.inline=function(a,d){if(!CKEDITOR.env.isCompatible)return null;a=CKEDITOR.dom.element.get(a);if(a.getEditor())throw'The editor instance "'+a.getEditor().name+'" is already attached to the provided element.';var b=new CKEDITOR.editor(d,a,CKEDITOR.ELEMENT_MODE_INLINE),c=a.is("textarea")?a:null;c?(b.setData(c.getValue(),null,!0),a=CKEDITOR.dom.element.createFromHtml('\x3cdiv contenteditable\x3d"'+!!b.readOnly+'" class\x3d"cke_textarea_inline"\x3e'+c.getValue()+"\x3c/div\x3e",CKEDITOR.document),
+a.insertAfter(c),c.hide(),c.$.form&&b._attachToForm()):b.setData(a.getHtml(),null,!0);b.on("loaded",function(){b.fire("uiReady");b.editable(a);b.container=a;b.ui.contentsElement=a;b.setData(b.getData(1));b.resetDirty();b.fire("contentDom");b.mode="wysiwyg";b.fire("mode");b.status="ready";b.fireOnce("instanceReady");CKEDITOR.fire("instanceReady",null,b)},null,null,1E4);b.on("destroy",function(){c&&(b.container.clearCustomData(),b.container.remove(),c.show());b.element.clearCustomData();delete b.element});
+return b};CKEDITOR.inlineAll=function(){var a,d,b;for(b in CKEDITOR.dtd.$editable)for(var c=CKEDITOR.document.getElementsByTag(b),e=0,g=c.count();e<g;e++)a=c.getItem(e),"true"==a.getAttribute("contenteditable")&&(d={element:a,config:{}},!1!==CKEDITOR.fire("inline",d)&&CKEDITOR.inline(a,d.config))};CKEDITOR.domReady(function(){!CKEDITOR.disableAutoInline&&CKEDITOR.inlineAll()})})();CKEDITOR.replaceClass="ckeditor";
+(function(){function a(a,e,g,k){if(!CKEDITOR.env.isCompatible)return null;a=CKEDITOR.dom.element.get(a);if(a.getEditor())throw'The editor instance "'+a.getEditor().name+'" is already attached to the provided element.';var h=new CKEDITOR.editor(e,a,k);k==CKEDITOR.ELEMENT_MODE_REPLACE&&(a.setStyle("visibility","hidden"),h._.required=a.hasAttribute("required"),a.removeAttribute("required"));g&&h.setData(g,null,!0);h.on("loaded",function(){b(h);k==CKEDITOR.ELEMENT_MODE_REPLACE&&h.config.autoUpdateElement&&
+a.$.form&&h._attachToForm();h.setMode(h.config.startupMode,function(){h.resetDirty();h.status="ready";h.fireOnce("instanceReady");CKEDITOR.fire("instanceReady",null,h)})});h.on("destroy",d);return h}function d(){var a=this.container,b=this.element;a&&(a.clearCustomData(),a.remove());b&&(b.clearCustomData(),this.elementMode==CKEDITOR.ELEMENT_MODE_REPLACE&&(b.show(),this._.required&&b.setAttribute("required","required")),delete this.element)}function b(a){var b=a.name,d=a.element,k=a.elementMode,h=
+a.fire("uiSpace",{space:"top",html:""}).html,p=a.fire("uiSpace",{space:"bottom",html:""}).html,r=new CKEDITOR.template('\x3c{outerEl} id\x3d"cke_{name}" class\x3d"{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} '+CKEDITOR.env.cssClass+'"  dir\x3d"{langDir}" lang\x3d"{langCode}" role\x3d"application"'+(a.title?' aria-labelledby\x3d"cke_{name}_arialbl"':"")+"\x3e"+(a.title?'\x3cspan id\x3d"cke_{name}_arialbl" class\x3d"cke_voice_label"\x3e{voiceLabel}\x3c/span\x3e':"")+'\x3c{outerEl} class\x3d"cke_inner cke_reset" role\x3d"presentation"\x3e{topHtml}\x3c{outerEl} id\x3d"{contentId}" class\x3d"cke_contents cke_reset" role\x3d"presentation"\x3e\x3c/{outerEl}\x3e{bottomHtml}\x3c/{outerEl}\x3e\x3c/{outerEl}\x3e'),
+b=CKEDITOR.dom.element.createFromHtml(r.output({id:a.id,name:b,langDir:a.lang.dir,langCode:a.langCode,voiceLabel:a.title,topHtml:h?'\x3cspan id\x3d"'+a.ui.spaceId("top")+'" class\x3d"cke_top cke_reset_all" role\x3d"presentation" style\x3d"height:auto"\x3e'+h+"\x3c/span\x3e":"",contentId:a.ui.spaceId("contents"),bottomHtml:p?'\x3cspan id\x3d"'+a.ui.spaceId("bottom")+'" class\x3d"cke_bottom cke_reset_all" role\x3d"presentation"\x3e'+p+"\x3c/span\x3e":"",outerEl:CKEDITOR.env.ie?"span":"div"}));k==CKEDITOR.ELEMENT_MODE_REPLACE?
+(d.hide(),b.insertAfter(d)):d.append(b);a.container=b;a.ui.contentsElement=a.ui.space("contents");h&&a.ui.space("top").unselectable();p&&a.ui.space("bottom").unselectable();d=a.config.width;k=a.config.height;d&&b.setStyle("width",CKEDITOR.tools.cssLength(d));k&&a.ui.space("contents").setStyle("height",CKEDITOR.tools.cssLength(k));b.disableContextMenu();CKEDITOR.env.webkit&&b.on("focus",function(){a.focus()});a.fireOnce("uiReady")}CKEDITOR.replace=function(b,d){return a(b,d,null,CKEDITOR.ELEMENT_MODE_REPLACE)};
+CKEDITOR.appendTo=function(b,d,g){return a(b,d,g,CKEDITOR.ELEMENT_MODE_APPENDTO)};CKEDITOR.replaceAll=function(){for(var a=document.getElementsByTagName("textarea"),b=0;b<a.length;b++){var d=null,k=a[b];if(k.name||k.id){if("string"==typeof arguments[0]){if(!(new RegExp("(?:^|\\s)"+arguments[0]+"(?:$|\\s)")).test(k.className))continue}else if("function"==typeof arguments[0]&&(d={},!1===arguments[0](k,d)))continue;this.replace(k,d)}}};CKEDITOR.editor.prototype.addMode=function(a,b){(this._.modes||(this._.modes=
+{}))[a]=b};CKEDITOR.editor.prototype.setMode=function(a,b){var d=this,k=this._.modes;if(a!=d.mode&&k&&k[a]){d.fire("beforeSetMode",a);if(d.mode){var h=d.checkDirty(),k=d._.previousModeData,p,r=0;d.fire("beforeModeUnload");d.editable(0);d._.previousMode=d.mode;d._.previousModeData=p=d.getData(1);"source"==d.mode&&k==p&&(d.fire("lockSnapshot",{forceUpdate:!0}),r=1);d.ui.space("contents").setHtml("");d.mode=""}else d._.previousModeData=d.getData(1);this._.modes[a](function(){d.mode=a;void 0!==h&&!h&&
+d.resetDirty();r?d.fire("unlockSnapshot"):"wysiwyg"==a&&d.fire("saveSnapshot");setTimeout(function(){d.fire("mode");b&&b.call(d)},0)})}};CKEDITOR.editor.prototype.resize=function(a,b,d,k){var h=this.container,p=this.ui.space("contents"),r=CKEDITOR.env.webkit&&this.document&&this.document.getWindow().$.frameElement;k=k?this.container.getFirst(function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasClass("cke_inner")}):h;k.setSize("width",a,!0);r&&(r.style.width="1%");var f=(k.$.offsetHeight||0)-(p.$.clientHeight||
+0),h=Math.max(b-(d?0:f),0);b=d?b+f:b;p.setStyle("height",h+"px");r&&(r.style.width="100%");this.fire("resize",{outerHeight:b,contentsHeight:h,outerWidth:a||k.getSize("width")})};CKEDITOR.editor.prototype.getResizable=function(a){return a?this.ui.space("contents"):this.container};CKEDITOR.domReady(function(){CKEDITOR.replaceClass&&CKEDITOR.replaceAll(CKEDITOR.replaceClass)})})();CKEDITOR.config.startupMode="wysiwyg";
+(function(){function a(a){var b=a.editor,e=a.data.path,f=e.blockLimit,g=a.data.selection,h=g.getRanges()[0],D;if(CKEDITOR.env.gecko||CKEDITOR.env.ie&&CKEDITOR.env.needsBrFiller)if(g=d(g,e))g.appendBogus(),D=CKEDITOR.env.ie;k(b,e.block,f)&&h.collapsed&&!h.getCommonAncestor().isReadOnly()&&(e=h.clone(),e.enlarge(CKEDITOR.ENLARGE_BLOCK_CONTENTS),f=new CKEDITOR.dom.walker(e),f.guard=function(a){return!c(a)||a.type==CKEDITOR.NODE_COMMENT||a.isReadOnly()},!f.checkForward()||e.checkStartOfBlock()&&e.checkEndOfBlock())&&
+(b=h.fixBlock(!0,b.activeEnterMode==CKEDITOR.ENTER_DIV?"div":"p"),CKEDITOR.env.needsBrFiller||(b=b.getFirst(c))&&b.type==CKEDITOR.NODE_TEXT&&CKEDITOR.tools.trim(b.getText()).match(/^(?:&nbsp;|\xa0)$/)&&b.remove(),D=1,a.cancel());D&&h.select()}function d(a,b){if(a.isFake)return 0;var d=b.block||b.blockLimit,e=d&&d.getLast(c);if(!(!d||!d.isBlockBoundary()||e&&e.type==CKEDITOR.NODE_ELEMENT&&e.isBlockBoundary()||d.is("pre")||d.getBogus()))return d}function b(a){var b=a.data.getTarget();b.is("input")&&
+(b=b.getAttribute("type"),"submit"!=b&&"reset"!=b||a.data.preventDefault())}function c(a){return f(a)&&B(a)}function e(a,b){return function(c){var d=c.data.$.toElement||c.data.$.fromElement||c.data.$.relatedTarget;(d=d&&d.nodeType==CKEDITOR.NODE_ELEMENT?new CKEDITOR.dom.element(d):null)&&(b.equals(d)||b.contains(d))||a.call(this,c)}}function g(a){function b(a){return function(b,l){l&&b.type==CKEDITOR.NODE_ELEMENT&&b.is(f)&&(d=b);if(!(l||!c(b)||a&&z(b)))return!1}}var d,e=a.getRanges()[0];a=a.root;
+var f={table:1,ul:1,ol:1,dl:1};if(e.startPath().contains(f)){var g=e.clone();g.collapse(1);g.setStartAt(a,CKEDITOR.POSITION_AFTER_START);a=new CKEDITOR.dom.walker(g);a.guard=b();a.checkBackward();if(d)return g=e.clone(),g.collapse(),g.setEndAt(d,CKEDITOR.POSITION_AFTER_END),a=new CKEDITOR.dom.walker(g),a.guard=b(!0),d=!1,a.checkForward(),d}return null}function k(a,b,c){return!1!==a.config.autoParagraph&&a.activeEnterMode!=CKEDITOR.ENTER_BR&&(a.editable().equals(c)&&!b||b&&"true"==b.getAttribute("contenteditable"))}
+function h(a){return a.activeEnterMode!=CKEDITOR.ENTER_BR&&!1!==a.config.autoParagraph?a.activeEnterMode==CKEDITOR.ENTER_DIV?"div":"p":!1}function p(a){var b=a.editor;b.getSelection().scrollIntoView();setTimeout(function(){b.fire("saveSnapshot")},0)}function r(a,b,c){var d=a.getCommonAncestor(b);for(b=a=c?b:a;(a=a.getParent())&&!d.equals(a)&&1==a.getChildCount();)b=a;b.remove()}var f,B,u,z,y,m,x,J,w,F;CKEDITOR.editable=CKEDITOR.tools.createClass({base:CKEDITOR.dom.element,$:function(a,b){this.base(b.$||
+b);this.editor=a;this.status="unloaded";this.hasFocus=!1;this.setup()},proto:{focus:function(){var a;if(CKEDITOR.env.webkit&&!this.hasFocus&&(a=this.editor._.previousActive||this.getDocument().getActive(),this.contains(a))){a.focus();return}CKEDITOR.env.edge&&14<CKEDITOR.env.version&&!this.hasFocus&&this.getDocument().equals(CKEDITOR.document)&&(this.editor._.previousScrollTop=this.$.scrollTop);try{!CKEDITOR.env.ie||CKEDITOR.env.edge&&14<CKEDITOR.env.version||!this.getDocument().equals(CKEDITOR.document)?
+this.$.focus():this.$.setActive()}catch(b){if(!CKEDITOR.env.ie)throw b;}CKEDITOR.env.safari&&!this.isInline()&&(a=CKEDITOR.document.getActive(),a.equals(this.getWindow().getFrame())||this.getWindow().focus())},on:function(a,b){var c=Array.prototype.slice.call(arguments,0);CKEDITOR.env.ie&&/^focus|blur$/.exec(a)&&(a="focus"==a?"focusin":"focusout",b=e(b,this),c[0]=a,c[1]=b);return CKEDITOR.dom.element.prototype.on.apply(this,c)},attachListener:function(a){!this._.listeners&&(this._.listeners=[]);var b=
+Array.prototype.slice.call(arguments,1),b=a.on.apply(a,b);this._.listeners.push(b);return b},clearListeners:function(){var a=this._.listeners;try{for(;a.length;)a.pop().removeListener()}catch(b){}},restoreAttrs:function(){var a=this._.attrChanges,b,c;for(c in a)a.hasOwnProperty(c)&&(b=a[c],null!==b?this.setAttribute(c,b):this.removeAttribute(c))},attachClass:function(a){var b=this.getCustomData("classes");this.hasClass(a)||(!b&&(b=[]),b.push(a),this.setCustomData("classes",b),this.addClass(a))},changeAttr:function(a,
+b){var c=this.getAttribute(a);b!==c&&(!this._.attrChanges&&(this._.attrChanges={}),a in this._.attrChanges||(this._.attrChanges[a]=c),this.setAttribute(a,b))},insertText:function(a){this.editor.focus();this.insertHtml(this.transformPlainTextToHtml(a),"text")},transformPlainTextToHtml:function(a){var b=this.editor.getSelection().getStartElement().hasAscendant("pre",!0)?CKEDITOR.ENTER_BR:this.editor.activeEnterMode;return CKEDITOR.tools.transformPlainTextToHtml(a,b)},insertHtml:function(a,b,c){var d=
+this.editor;d.focus();d.fire("saveSnapshot");c||(c=d.getSelection().getRanges()[0]);m(this,b||"html",a,c);c.select();p(this);this.editor.fire("afterInsertHtml",{})},insertHtmlIntoRange:function(a,b,c){m(this,c||"html",a,b);this.editor.fire("afterInsertHtml",{intoRange:b})},insertElement:function(a,b){var d=this.editor;d.focus();d.fire("saveSnapshot");var e=d.activeEnterMode,d=d.getSelection(),f=a.getName(),f=CKEDITOR.dtd.$block[f];b||(b=d.getRanges()[0]);this.insertElementIntoRange(a,b)&&(b.moveToPosition(a,
+CKEDITOR.POSITION_AFTER_END),f&&((f=a.getNext(function(a){return c(a)&&!z(a)}))&&f.type==CKEDITOR.NODE_ELEMENT&&f.is(CKEDITOR.dtd.$block)?f.getDtd()["#"]?b.moveToElementEditStart(f):b.moveToElementEditEnd(a):f||e==CKEDITOR.ENTER_BR||(f=b.fixBlock(!0,e==CKEDITOR.ENTER_DIV?"div":"p"),b.moveToElementEditStart(f))));d.selectRanges([b]);p(this)},insertElementIntoSelection:function(a){this.insertElement(a)},insertElementIntoRange:function(a,b){var c=this.editor,d=c.config.enterMode,e=a.getName(),f=CKEDITOR.dtd.$block[e];
+if(b.checkReadOnly())return!1;b.deleteContents(1);b.startContainer.type==CKEDITOR.NODE_ELEMENT&&(b.startContainer.is({tr:1,table:1,tbody:1,thead:1,tfoot:1})?x(b):b.startContainer.is(CKEDITOR.dtd.$list)&&J(b));var g,k;if(f)for(;(g=b.getCommonAncestor(0,1))&&(k=CKEDITOR.dtd[g.getName()])&&(!k||!k[e]);)g.getName()in CKEDITOR.dtd.span?b.splitElement(g):b.checkStartOfBlock()&&b.checkEndOfBlock()?(b.setStartBefore(g),b.collapse(!0),g.remove()):b.splitBlock(d==CKEDITOR.ENTER_DIV?"div":"p",c.editable());
+b.insertNode(a);return!0},setData:function(a,b){b||(a=this.editor.dataProcessor.toHtml(a));this.setHtml(a);this.fixInitialSelection();"unloaded"==this.status&&(this.status="ready");this.editor.fire("dataReady")},getData:function(a){var b=this.getHtml();a||(b=this.editor.dataProcessor.toDataFormat(b));return b},setReadOnly:function(a){this.setAttribute("contenteditable",!a)},detach:function(){this.removeClass("cke_editable");this.status="detached";var a=this.editor;this._.detach();delete a.document;
+delete a.window},isInline:function(){return this.getDocument().equals(CKEDITOR.document)},fixInitialSelection:function(){function a(){var b=c.getDocument().$,d=b.getSelection(),l;a:if(d.anchorNode&&d.anchorNode==c.$)l=!0;else{if(CKEDITOR.env.webkit&&(l=c.getDocument().getActive())&&l.equals(c)&&!d.anchorNode){l=!0;break a}l=void 0}l&&(l=new CKEDITOR.dom.range(c),l.moveToElementEditStart(c),b=b.createRange(),b.setStart(l.startContainer.$,l.startOffset),b.collapse(!0),d.removeAllRanges(),d.addRange(b))}
+function b(){var a=c.getDocument().$,d=a.selection,l=c.getDocument().getActive();"None"==d.type&&l.equals(c)&&(d=new CKEDITOR.dom.range(c),a=a.body.createTextRange(),d.moveToElementEditStart(c),d=d.startContainer,d.type!=CKEDITOR.NODE_ELEMENT&&(d=d.getParent()),a.moveToElementText(d.$),a.collapse(!0),a.select())}var c=this;if(CKEDITOR.env.ie&&(9>CKEDITOR.env.version||CKEDITOR.env.quirks))this.hasFocus&&(this.focus(),b());else if(this.hasFocus)this.focus(),a();else this.once("focus",function(){a()},
+null,null,-999)},getHtmlFromRange:function(a){if(a.collapsed)return new CKEDITOR.dom.documentFragment(a.document);a={doc:this.getDocument(),range:a.clone()};w.eol.detect(a,this);w.bogus.exclude(a);w.cell.shrink(a);a.fragment=a.range.cloneContents();w.tree.rebuild(a,this);w.eol.fix(a,this);return new CKEDITOR.dom.documentFragment(a.fragment.$)},extractHtmlFromRange:function(a,b){var c=F,d={range:a,doc:a.document},e=this.getHtmlFromRange(a);if(a.collapsed)return a.optimize(),e;a.enlarge(CKEDITOR.ENLARGE_INLINE,
+1);c.table.detectPurge(d);d.bookmark=a.createBookmark();delete d.range;var f=this.editor.createRange();f.moveToPosition(d.bookmark.startNode,CKEDITOR.POSITION_BEFORE_START);d.targetBookmark=f.createBookmark();c.list.detectMerge(d,this);c.table.detectRanges(d,this);c.block.detectMerge(d,this);d.tableContentsRanges?(c.table.deleteRanges(d),a.moveToBookmark(d.bookmark),d.range=a):(a.moveToBookmark(d.bookmark),d.range=a,a.extractContents(c.detectExtractMerge(d)));a.moveToBookmark(d.targetBookmark);a.optimize();
+c.fixUneditableRangePosition(a);c.list.merge(d,this);c.table.purge(d,this);c.block.merge(d,this);if(b){c=a.startPath();if(d=a.checkStartOfBlock()&&a.checkEndOfBlock()&&c.block&&!a.root.equals(c.block)){a:{var d=c.block.getElementsByTag("span"),f=0,g;if(d)for(;g=d.getItem(f++);)if(!B(g)){d=!0;break a}d=!1}d=!d}d&&(a.moveToPosition(c.block,CKEDITOR.POSITION_BEFORE_START),c.block.remove())}else c.autoParagraph(this.editor,a),u(a.startContainer)&&a.startContainer.appendBogus();a.startContainer.mergeSiblings();
+return e},setup:function(){var a=this.editor;this.attachListener(a,"beforeGetData",function(){var b=this.getData();this.is("textarea")||!1!==a.config.ignoreEmptyParagraph&&(b=b.replace(y,function(a,b){return b}));a.setData(b,null,1)},this);this.attachListener(a,"getSnapshot",function(a){a.data=this.getData(1)},this);this.attachListener(a,"afterSetData",function(){this.setData(a.getData(1))},this);this.attachListener(a,"loadSnapshot",function(a){this.setData(a.data,1)},this);this.attachListener(a,
+"beforeFocus",function(){var b=a.getSelection();(b=b&&b.getNative())&&"Control"==b.type||this.focus()},this);this.attachListener(a,"insertHtml",function(a){this.insertHtml(a.data.dataValue,a.data.mode,a.data.range)},this);this.attachListener(a,"insertElement",function(a){this.insertElement(a.data)},this);this.attachListener(a,"insertText",function(a){this.insertText(a.data)},this);this.setReadOnly(a.readOnly);this.attachClass("cke_editable");a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?this.attachClass("cke_editable_inline"):
+a.elementMode!=CKEDITOR.ELEMENT_MODE_REPLACE&&a.elementMode!=CKEDITOR.ELEMENT_MODE_APPENDTO||this.attachClass("cke_editable_themed");this.attachClass("cke_contents_"+a.config.contentsLangDirection);a.keystrokeHandler.blockedKeystrokes[8]=+a.readOnly;a.keystrokeHandler.attach(this);this.on("blur",function(){this.hasFocus=!1},null,null,-1);this.on("focus",function(){this.hasFocus=!0},null,null,-1);if(CKEDITOR.env.webkit)this.on("scroll",function(){a._.previousScrollTop=a.editable().$.scrollTop},null,
+null,-1);if(CKEDITOR.env.edge&&14<CKEDITOR.env.version){var d=function(){var b=a.editable();null!=a._.previousScrollTop&&b.getDocument().equals(CKEDITOR.document)&&(b.$.scrollTop=a._.previousScrollTop,a._.previousScrollTop=null,this.removeListener("scroll",d))};this.on("scroll",d)}a.focusManager.add(this);this.equals(CKEDITOR.document.getActive())&&(this.hasFocus=!0,a.once("contentDom",function(){a.focusManager.focus(this)},this));this.isInline()&&this.changeAttr("tabindex",a.tabIndex);if(!this.is("textarea")){a.document=
+this.getDocument();a.window=this.getWindow();var e=a.document;this.changeAttr("spellcheck",!a.config.disableNativeSpellChecker);var t=a.config.contentsLangDirection;this.getDirection(1)!=t&&this.changeAttr("dir",t);var k=CKEDITOR.getCss();if(k){var t=e.getHead(),h=t.getCustomData("stylesheet");h?k!=h.getText()&&(CKEDITOR.env.ie&&9>CKEDITOR.env.version?h.$.styleSheet.cssText=k:h.setText(k)):(k=e.appendStyleText(k),k=new CKEDITOR.dom.element(k.ownerNode||k.owningElement),t.setCustomData("stylesheet",
+k),k.data("cke-temp",1))}t=e.getCustomData("stylesheet_ref")||0;e.setCustomData("stylesheet_ref",t+1);this.setCustomData("cke_includeReadonly",!a.config.disableReadonlyStyling);this.attachListener(this,"click",function(a){a=a.data;var b=(new CKEDITOR.dom.elementPath(a.getTarget(),this)).contains("a");b&&2!=a.$.button&&b.isReadOnly()&&a.preventDefault()});var D={8:1,46:1};this.attachListener(a,"key",function(b){if(a.readOnly)return!0;var c=b.data.domEvent.getKey(),d;if(c in D){b=a.getSelection();var e,
+n=b.getRanges()[0],q=n.startPath(),t,k,h,c=8==c;CKEDITOR.env.ie&&11>CKEDITOR.env.version&&(e=b.getSelectedElement())||(e=g(b))?(a.fire("saveSnapshot"),n.moveToPosition(e,CKEDITOR.POSITION_BEFORE_START),e.remove(),n.select(),a.fire("saveSnapshot"),d=1):n.collapsed&&((t=q.block)&&(h=t[c?"getPrevious":"getNext"](f))&&h.type==CKEDITOR.NODE_ELEMENT&&h.is("table")&&n[c?"checkStartOfBlock":"checkEndOfBlock"]()?(a.fire("saveSnapshot"),n[c?"checkEndOfBlock":"checkStartOfBlock"]()&&t.remove(),n["moveToElementEdit"+
+(c?"End":"Start")](h),n.select(),a.fire("saveSnapshot"),d=1):q.blockLimit&&q.blockLimit.is("td")&&(k=q.blockLimit.getAscendant("table"))&&n.checkBoundaryOfElement(k,c?CKEDITOR.START:CKEDITOR.END)&&(h=k[c?"getPrevious":"getNext"](f))?(a.fire("saveSnapshot"),n["moveToElementEdit"+(c?"End":"Start")](h),n.checkStartOfBlock()&&n.checkEndOfBlock()?h.remove():n.select(),a.fire("saveSnapshot"),d=1):(k=q.contains(["td","th","caption"]))&&n.checkBoundaryOfElement(k,c?CKEDITOR.START:CKEDITOR.END)&&(d=1))}return!d});
+a.blockless&&CKEDITOR.env.ie&&CKEDITOR.env.needsBrFiller&&this.attachListener(this,"keyup",function(b){b.data.getKeystroke()in D&&!this.getFirst(c)&&(this.appendBogus(),b=a.createRange(),b.moveToPosition(this,CKEDITOR.POSITION_AFTER_START),b.select())});this.attachListener(this,"dblclick",function(b){if(a.readOnly)return!1;b={element:b.data.getTarget()};a.fire("doubleclick",b)});CKEDITOR.env.ie&&this.attachListener(this,"click",b);CKEDITOR.env.ie&&!CKEDITOR.env.edge||this.attachListener(this,"mousedown",
+function(b){var c=b.data.getTarget();c.is("img","hr","input","textarea","select")&&!c.isReadOnly()&&(a.getSelection().selectElement(c),c.is("input","textarea","select")&&b.data.preventDefault())});CKEDITOR.env.edge&&this.attachListener(this,"mouseup",function(b){(b=b.data.getTarget())&&b.is("img")&&a.getSelection().selectElement(b)});CKEDITOR.env.gecko&&this.attachListener(this,"mouseup",function(b){if(2==b.data.$.button&&(b=b.data.getTarget(),!b.getOuterHtml().replace(y,""))){var c=a.createRange();
+c.moveToElementEditStart(b);c.select(!0)}});CKEDITOR.env.webkit&&(this.attachListener(this,"click",function(a){a.data.getTarget().is("input","select")&&a.data.preventDefault()}),this.attachListener(this,"mouseup",function(a){a.data.getTarget().is("input","textarea")&&a.data.preventDefault()}));CKEDITOR.env.webkit&&this.attachListener(a,"key",function(b){if(a.readOnly)return!0;b=b.data.domEvent.getKey();if(b in D){var c=8==b,d=a.getSelection().getRanges()[0];b=d.startPath();if(d.collapsed)a:{var e=
+b.block;if(e&&d[c?"checkStartOfBlock":"checkEndOfBlock"]()&&d.moveToClosestEditablePosition(e,!c)&&d.collapsed){if(d.startContainer.type==CKEDITOR.NODE_ELEMENT){var f=d.startContainer.getChild(d.startOffset-(c?1:0));if(f&&f.type==CKEDITOR.NODE_ELEMENT&&f.is("hr")){a.fire("saveSnapshot");f.remove();b=!0;break a}}d=d.startPath().block;if(!d||d&&d.contains(e))b=void 0;else{a.fire("saveSnapshot");var n;(n=(c?d:e).getBogus())&&n.remove();n=a.getSelection();f=n.createBookmarks();(c?e:d).moveChildren(c?
+d:e,!1);b.lastElement.mergeSiblings();r(e,d,!c);n.selectBookmarks(f);b=!0}}else b=!1}else c=d,n=b.block,d=c.endPath().block,n&&d&&!n.equals(d)?(a.fire("saveSnapshot"),(e=n.getBogus())&&e.remove(),c.enlarge(CKEDITOR.ENLARGE_INLINE),c.deleteContents(),d.getParent()&&(d.moveChildren(n,!1),b.lastElement.mergeSiblings(),r(n,d,!0)),c=a.getSelection().getRanges()[0],c.collapse(1),c.optimize(),""===c.startContainer.getHtml()&&c.startContainer.appendBogus(),c.select(),b=!0):b=!1;if(!b)return;a.getSelection().scrollIntoView();
+a.fire("saveSnapshot");return!1}},this,null,100)}}},_:{detach:function(){this.editor.setData(this.editor.getData(),0,1);this.clearListeners();this.restoreAttrs();var a;if(a=this.removeCustomData("classes"))for(;a.length;)this.removeClass(a.pop());if(!this.is("textarea")){a=this.getDocument();var b=a.getHead();if(b.getCustomData("stylesheet")){var c=a.getCustomData("stylesheet_ref");--c?a.setCustomData("stylesheet_ref",c):(a.removeCustomData("stylesheet_ref"),b.removeCustomData("stylesheet").remove())}}this.editor.fire("contentDomUnload");
+delete this.editor}}});CKEDITOR.editor.prototype.editable=function(a){var b=this._.editable;if(b&&a)return 0;arguments.length&&(b=this._.editable=a?a instanceof CKEDITOR.editable?a:new CKEDITOR.editable(this,a):(b&&b.detach(),null));return b};CKEDITOR.on("instanceLoaded",function(b){var c=b.editor;c.on("insertElement",function(a){a=a.data;a.type==CKEDITOR.NODE_ELEMENT&&(a.is("input")||a.is("textarea"))&&("false"!=a.getAttribute("contentEditable")&&a.data("cke-editable",a.hasAttribute("contenteditable")?
+"true":"1"),a.setAttribute("contentEditable",!1))});c.on("selectionChange",function(b){if(!c.readOnly){var d=c.getSelection();d&&!d.isLocked&&(d=c.checkDirty(),c.fire("lockSnapshot"),a(b),c.fire("unlockSnapshot"),!d&&c.resetDirty())}})});CKEDITOR.on("instanceCreated",function(a){var b=a.editor;b.on("mode",function(){var a=b.editable();if(a&&a.isInline()){var c=b.title;a.changeAttr("role","textbox");a.changeAttr("aria-label",c);c&&a.changeAttr("title",c);var d=b.fire("ariaEditorHelpLabel",{}).label;
+if(d&&(c=this.ui.space(this.elementMode==CKEDITOR.ELEMENT_MODE_INLINE?"top":"contents"))){var e=CKEDITOR.tools.getNextId(),d=CKEDITOR.dom.element.createFromHtml('\x3cspan id\x3d"'+e+'" class\x3d"cke_voice_label"\x3e'+d+"\x3c/span\x3e");c.append(d);a.changeAttr("aria-describedby",e)}}})});CKEDITOR.addCss(".cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}");f=CKEDITOR.dom.walker.whitespaces(!0);B=CKEDITOR.dom.walker.bookmark(!1,!0);u=CKEDITOR.dom.walker.empty();
+z=CKEDITOR.dom.walker.bogus();y=/(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;m=function(){function a(b){return b.type==CKEDITOR.NODE_ELEMENT}function b(c,d){var e,f,n,t,g=[],k=d.range.startContainer;e=d.range.startPath();for(var k=p[k.getName()],h=0,C=c.getChildren(),A=C.count(),D=-1,m=-1,r=0,H=e.contains(p.$list);h<A;++h)e=C.getItem(h),a(e)?(n=e.getName(),H&&n in CKEDITOR.dtd.$list?g=g.concat(b(e,d)):(t=!!k[n],
+"br"!=n||!e.data("cke-eol")||h&&h!=A-1||(r=(f=h?g[h-1].node:C.getItem(h+1))&&(!a(f)||!f.is("br")),f=f&&a(f)&&p.$block[f.getName()]),-1!=D||t||(D=h),t||(m=h),g.push({isElement:1,isLineBreak:r,isBlock:e.isBlockBoundary(),hasBlockSibling:f,node:e,name:n,allowed:t}),f=r=0)):g.push({isElement:0,node:e,allowed:1});-1<D&&(g[D].firstNotAllowed=1);-1<m&&(g[m].lastNotAllowed=1);return g}function d(b,c){var e=[],f=b.getChildren(),q=f.count(),g,t=0,k=p[c],h=!b.is(p.$inline)||b.is("br");for(h&&e.push(" ");t<q;t++)g=
+f.getItem(t),a(g)&&!g.is(k)?e=e.concat(d(g,c)):e.push(g);h&&e.push(" ");return e}function e(b){return a(b.startContainer)&&b.startContainer.getChild(b.startOffset-1)}function f(b){return b&&a(b)&&(b.is(p.$removeEmpty)||b.is("a")&&!b.isBlockBoundary())}function g(b,c,d,e){var f=b.clone(),n,q;f.setEndAt(c,CKEDITOR.POSITION_BEFORE_END);(n=(new CKEDITOR.dom.walker(f)).next())&&a(n)&&m[n.getName()]&&(q=n.getPrevious())&&a(q)&&!q.getParent().equals(b.startContainer)&&d.contains(q)&&e.contains(n)&&n.isIdentical(q)&&
+(n.moveChildren(q),n.remove(),g(b,c,d,e))}function D(b,c){function d(b,c){if(c.isBlock&&c.isElement&&!c.node.is("br")&&a(b)&&b.is("br"))return b.remove(),1}var e=c.endContainer.getChild(c.endOffset),f=c.endContainer.getChild(c.endOffset-1);e&&d(e,b[b.length-1]);f&&d(f,b[0])&&(c.setEnd(c.endContainer,c.endOffset-1),c.collapse())}var p=CKEDITOR.dtd,m={p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,ul:1,ol:1,li:1,pre:1,dl:1,blockquote:1},r={p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1},x=CKEDITOR.tools.extend({},
+p.$inline);delete x.br;return function(m,v,G,E){var I=m.editor,K=!1;"unfiltered_html"==v&&(v="html",K=!0);if(!E.checkReadOnly()){var L=(new CKEDITOR.dom.elementPath(E.startContainer,E.root)).blockLimit||E.root;m={type:v,dontFilter:K,editable:m,editor:I,range:E,blockLimit:L,mergeCandidates:[],zombies:[]};v=m.range;E=m.mergeCandidates;var H,u;"text"==m.type&&v.shrink(CKEDITOR.SHRINK_ELEMENT,!0,!1)&&(H=CKEDITOR.dom.element.createFromHtml("\x3cspan\x3e\x26nbsp;\x3c/span\x3e",v.document),v.insertNode(H),
+v.setStartAfter(H));K=new CKEDITOR.dom.elementPath(v.startContainer);m.endPath=L=new CKEDITOR.dom.elementPath(v.endContainer);if(!v.collapsed){var I=L.block||L.blockLimit,B=v.getCommonAncestor();I&&!I.equals(B)&&!I.contains(B)&&v.checkEndOfBlock()&&m.zombies.push(I);v.deleteContents()}for(;(u=e(v))&&a(u)&&u.isBlockBoundary()&&K.contains(u);)v.moveToPosition(u,CKEDITOR.POSITION_BEFORE_END);g(v,m.blockLimit,K,L);H&&(v.setEndBefore(H),v.collapse(),H.remove());H=v.startPath();if(I=H.contains(f,!1,1))v.splitElement(I),
+m.inlineStylesRoot=I,m.inlineStylesPeak=H.lastElement;H=v.createBookmark();(I=H.startNode.getPrevious(c))&&a(I)&&f(I)&&E.push(I);(I=H.startNode.getNext(c))&&a(I)&&f(I)&&E.push(I);for(I=H.startNode;(I=I.getParent())&&f(I);)E.push(I);v.moveToBookmark(H);if(H=G){H=m.range;if("text"==m.type&&m.inlineStylesRoot){u=m.inlineStylesPeak;v=u.getDocument().createText("{cke-peak}");for(E=m.inlineStylesRoot.getParent();!u.equals(E);)v=v.appendTo(u.clone()),u=u.getParent();G=v.getOuterHtml().split("{cke-peak}").join(G)}u=
+m.blockLimit.getName();if(/^\s+|\s+$/.test(G)&&"span"in CKEDITOR.dtd[u]){var z='\x3cspan data-cke-marker\x3d"1"\x3e\x26nbsp;\x3c/span\x3e';G=z+G+z}G=m.editor.dataProcessor.toHtml(G,{context:null,fixForBody:!1,protectedWhitespaces:!!z,dontFilter:m.dontFilter,filter:m.editor.activeFilter,enterMode:m.editor.activeEnterMode});u=H.document.createElement("body");u.setHtml(G);z&&(u.getFirst().remove(),u.getLast().remove());if((z=H.startPath().block)&&(1!=z.getChildCount()||!z.getBogus()))a:{var w;if(1==
+u.getChildCount()&&a(w=u.getFirst())&&w.is(r)&&!w.hasAttribute("contenteditable")){z=w.getElementsByTag("*");H=0;for(E=z.count();H<E;H++)if(v=z.getItem(H),!v.is(x))break a;w.moveChildren(w.getParent(1));w.remove()}}m.dataWrapper=u;H=G}if(H){w=m.range;H=w.document;var y;u=m.blockLimit;E=0;var O,z=[],N,V;G=I=0;var F,J;v=w.startContainer;var K=m.endPath.elements[0],Y,L=K.getPosition(v),B=!!K.getCommonAncestor(v)&&L!=CKEDITOR.POSITION_IDENTICAL&&!(L&CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_IS_CONTAINED);
+v=b(m.dataWrapper,m);for(D(v,w);E<v.length;E++){L=v[E];if(y=L.isLineBreak){y=w;F=u;var U=void 0,aa=void 0;L.hasBlockSibling?y=1:(U=y.startContainer.getAscendant(p.$block,1))&&U.is({div:1,p:1})?(aa=U.getPosition(F),aa==CKEDITOR.POSITION_IDENTICAL||aa==CKEDITOR.POSITION_CONTAINS?y=0:(F=y.splitElement(U),y.moveToPosition(F,CKEDITOR.POSITION_AFTER_START),y=1)):y=0}if(y)G=0<E;else{y=w.startPath();!L.isBlock&&k(m.editor,y.block,y.blockLimit)&&(V=h(m.editor))&&(V=H.createElement(V),V.appendBogus(),w.insertNode(V),
+CKEDITOR.env.needsBrFiller&&(O=V.getBogus())&&O.remove(),w.moveToPosition(V,CKEDITOR.POSITION_BEFORE_END));if((y=w.startPath().block)&&!y.equals(N)){if(O=y.getBogus())O.remove(),z.push(y);N=y}L.firstNotAllowed&&(I=1);if(I&&L.isElement){y=w.startContainer;for(F=null;y&&!p[y.getName()][L.name];){if(y.equals(u)){y=null;break}F=y;y=y.getParent()}if(y)F&&(J=w.splitElement(F),m.zombies.push(J),m.zombies.push(F));else{F=u.getName();Y=!E;y=E==v.length-1;F=d(L.node,F);for(var U=[],aa=F.length,ba=0,da=void 0,
+ea=0,W=-1;ba<aa;ba++)da=F[ba]," "==da?(ea||Y&&!ba||(U.push(new CKEDITOR.dom.text(" ")),W=U.length),ea=1):(U.push(da),ea=0);y&&W==U.length&&U.pop();Y=U}}if(Y){for(;y=Y.pop();)w.insertNode(y);Y=0}else w.insertNode(L.node);L.lastNotAllowed&&E<v.length-1&&((J=B?K:J)&&w.setEndAt(J,CKEDITOR.POSITION_AFTER_START),I=0);w.collapse()}}1!=v.length?O=!1:(O=v[0],O=O.isElement&&"false"==O.node.getAttribute("contenteditable"));O&&(G=!0,y=v[0].node,w.setStartAt(y,CKEDITOR.POSITION_BEFORE_START),w.setEndAt(y,CKEDITOR.POSITION_AFTER_END));
+m.dontMoveCaret=G;m.bogusNeededBlocks=z}O=m.range;var T;J=m.bogusNeededBlocks;for(Y=O.createBookmark();N=m.zombies.pop();)N.getParent()&&(V=O.clone(),V.moveToElementEditStart(N),V.removeEmptyBlocksAtEnd());if(J)for(;N=J.pop();)CKEDITOR.env.needsBrFiller?N.appendBogus():N.append(O.document.createText(" "));for(;N=m.mergeCandidates.pop();)N.mergeSiblings();O.moveToBookmark(Y);if(!m.dontMoveCaret){for(N=e(O);N&&a(N)&&!N.is(p.$empty);){if(N.isBlockBoundary())O.moveToPosition(N,CKEDITOR.POSITION_BEFORE_END);
+else{if(f(N)&&N.getHtml().match(/(\s|&nbsp;)$/g)){T=null;break}T=O.clone();T.moveToPosition(N,CKEDITOR.POSITION_BEFORE_END)}N=N.getLast(c)}T&&O.moveToRange(T)}}}}();x=function(){function a(b){b=new CKEDITOR.dom.walker(b);b.guard=function(a,b){if(b)return!1;if(a.type==CKEDITOR.NODE_ELEMENT)return a.is(CKEDITOR.dtd.$tableContent)};b.evaluator=function(a){return a.type==CKEDITOR.NODE_ELEMENT};return b}function b(a,c,d){c=a.getDocument().createElement(c);a.append(c,d);return c}function c(a){var b=a.count(),
+d;for(b;0<b--;)d=a.getItem(b),CKEDITOR.tools.trim(d.getHtml())||(d.appendBogus(),CKEDITOR.env.ie&&9>CKEDITOR.env.version&&d.getChildCount()&&d.getFirst().remove())}return function(d){var e=d.startContainer,f=e.getAscendant("table",1),g=!1;c(f.getElementsByTag("td"));c(f.getElementsByTag("th"));f=d.clone();f.setStart(e,0);f=a(f).lastBackward();f||(f=d.clone(),f.setEndAt(e,CKEDITOR.POSITION_BEFORE_END),f=a(f).lastForward(),g=!0);f||(f=e);f.is("table")?(d.setStartAt(f,CKEDITOR.POSITION_BEFORE_START),
+d.collapse(!0),f.remove()):(f.is({tbody:1,thead:1,tfoot:1})&&(f=b(f,"tr",g)),f.is("tr")&&(f=b(f,f.getParent().is("thead")?"th":"td",g)),(e=f.getBogus())&&e.remove(),d.moveToPosition(f,g?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_END))}}();J=function(){function a(b){b=new CKEDITOR.dom.walker(b);b.guard=function(a,b){if(b)return!1;if(a.type==CKEDITOR.NODE_ELEMENT)return a.is(CKEDITOR.dtd.$list)||a.is(CKEDITOR.dtd.$listItem)};b.evaluator=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&
+a.is(CKEDITOR.dtd.$listItem)};return b}return function(b){var c=b.startContainer,d=!1,e;e=b.clone();e.setStart(c,0);e=a(e).lastBackward();e||(e=b.clone(),e.setEndAt(c,CKEDITOR.POSITION_BEFORE_END),e=a(e).lastForward(),d=!0);e||(e=c);e.is(CKEDITOR.dtd.$list)?(b.setStartAt(e,CKEDITOR.POSITION_BEFORE_START),b.collapse(!0),e.remove()):((c=e.getBogus())&&c.remove(),b.moveToPosition(e,d?CKEDITOR.POSITION_AFTER_START:CKEDITOR.POSITION_BEFORE_END),b.select())}}();w={eol:{detect:function(a,b){var c=a.range,
+d=c.clone(),e=c.clone(),f=new CKEDITOR.dom.elementPath(c.startContainer,b),g=new CKEDITOR.dom.elementPath(c.endContainer,b);d.collapse(1);e.collapse();f.block&&d.checkBoundaryOfElement(f.block,CKEDITOR.END)&&(c.setStartAfter(f.block),a.prependEolBr=1);g.block&&e.checkBoundaryOfElement(g.block,CKEDITOR.START)&&(c.setEndBefore(g.block),a.appendEolBr=1)},fix:function(a,b){var c=b.getDocument(),d;a.appendEolBr&&(d=this.createEolBr(c),a.fragment.append(d));!a.prependEolBr||d&&!d.getPrevious()||a.fragment.append(this.createEolBr(c),
+1)},createEolBr:function(a){return a.createElement("br",{attributes:{"data-cke-eol":1}})}},bogus:{exclude:function(a){var b=a.range.getBoundaryNodes(),c=b.startNode,b=b.endNode;!b||!z(b)||c&&c.equals(b)||a.range.setEndBefore(b)}},tree:{rebuild:function(a,b){var c=a.range,d=c.getCommonAncestor(),e=new CKEDITOR.dom.elementPath(d,b),f=new CKEDITOR.dom.elementPath(c.startContainer,b),c=new CKEDITOR.dom.elementPath(c.endContainer,b),g;d.type==CKEDITOR.NODE_TEXT&&(d=d.getParent());if(e.blockLimit.is({tr:1,
+table:1})){var k=e.contains("table").getParent();g=function(a){return!a.equals(k)}}else if(e.block&&e.block.is(CKEDITOR.dtd.$listItem)&&(f=f.contains(CKEDITOR.dtd.$list),c=c.contains(CKEDITOR.dtd.$list),!f.equals(c))){var h=e.contains(CKEDITOR.dtd.$list).getParent();g=function(a){return!a.equals(h)}}g||(g=function(a){return!a.equals(e.block)&&!a.equals(e.blockLimit)});this.rebuildFragment(a,b,d,g)},rebuildFragment:function(a,b,c,d){for(var e;c&&!c.equals(b)&&d(c);)e=c.clone(0,1),a.fragment.appendTo(e),
+a.fragment=e,c=c.getParent()}},cell:{shrink:function(a){a=a.range;var b=a.startContainer,c=a.endContainer,d=a.startOffset,e=a.endOffset;b.type==CKEDITOR.NODE_ELEMENT&&b.equals(c)&&b.is("tr")&&++d==e&&a.shrink(CKEDITOR.SHRINK_TEXT)}}};F=function(){function a(b,c){var d=b.getParent();if(d.is(CKEDITOR.dtd.$inline))b[c?"insertBefore":"insertAfter"](d)}function b(c,d,e){a(d);a(e,1);for(var f;f=e.getNext();)f.insertAfter(d),d=f;u(c)&&c.remove()}function c(a,b){var d=new CKEDITOR.dom.range(a);d.setStartAfter(b.startNode);
+d.setEndBefore(b.endNode);return d}return{list:{detectMerge:function(a,b){var d=c(b,a.bookmark),e=d.startPath(),f=d.endPath(),l=e.contains(CKEDITOR.dtd.$list),g=f.contains(CKEDITOR.dtd.$list);a.mergeList=l&&g&&l.getParent().equals(g.getParent())&&!l.equals(g);a.mergeListItems=e.block&&f.block&&e.block.is(CKEDITOR.dtd.$listItem)&&f.block.is(CKEDITOR.dtd.$listItem);if(a.mergeList||a.mergeListItems)d=d.clone(),d.setStartBefore(a.bookmark.startNode),d.setEndAfter(a.bookmark.endNode),a.mergeListBookmark=
+d.createBookmark()},merge:function(a,c){if(a.mergeListBookmark){var d=a.mergeListBookmark.startNode,e=a.mergeListBookmark.endNode,f=new CKEDITOR.dom.elementPath(d,c),l=new CKEDITOR.dom.elementPath(e,c);if(a.mergeList){var g=f.contains(CKEDITOR.dtd.$list),n=l.contains(CKEDITOR.dtd.$list);g.equals(n)||(n.moveChildren(g),n.remove())}a.mergeListItems&&(f=f.contains(CKEDITOR.dtd.$listItem),l=l.contains(CKEDITOR.dtd.$listItem),f.equals(l)||b(l,d,e));d.remove();e.remove()}}},block:{detectMerge:function(a,
+b){if(!a.tableContentsRanges&&!a.mergeListBookmark){var c=new CKEDITOR.dom.range(b);c.setStartBefore(a.bookmark.startNode);c.setEndAfter(a.bookmark.endNode);a.mergeBlockBookmark=c.createBookmark()}},merge:function(a,c){if(a.mergeBlockBookmark&&!a.purgeTableBookmark){var d=a.mergeBlockBookmark.startNode,e=a.mergeBlockBookmark.endNode,f=new CKEDITOR.dom.elementPath(d,c),l=new CKEDITOR.dom.elementPath(e,c),f=f.block,l=l.block;f&&l&&!f.equals(l)&&b(l,d,e);d.remove();e.remove()}}},table:function(){function a(c){var e=
+[],f,l=new CKEDITOR.dom.walker(c),g=c.startPath().contains(d),n=c.endPath().contains(d),k={};l.guard=function(a,l){if(a.type==CKEDITOR.NODE_ELEMENT){var h="visited_"+(l?"out":"in");if(a.getCustomData(h))return;CKEDITOR.dom.element.setMarker(k,a,h,1)}if(l&&g&&a.equals(g))f=c.clone(),f.setEndAt(g,CKEDITOR.POSITION_BEFORE_END),e.push(f);else if(!l&&n&&a.equals(n))f=c.clone(),f.setStartAt(n,CKEDITOR.POSITION_AFTER_START),e.push(f);else{if(h=!l)h=a.type==CKEDITOR.NODE_ELEMENT&&a.is(d)&&(!g||b(a,g))&&(!n||
+b(a,n));h&&(f=c.clone(),f.selectNodeContents(a),e.push(f))}};l.lastForward();CKEDITOR.dom.element.clearAllMarkers(k);return e}function b(a,c){var d=CKEDITOR.POSITION_CONTAINS+CKEDITOR.POSITION_IS_CONTAINED,e=a.getPosition(c);return e===CKEDITOR.POSITION_IDENTICAL?!1:0===(e&d)}var d={td:1,th:1,caption:1};return{detectPurge:function(a){var b=a.range,c=b.clone();c.enlarge(CKEDITOR.ENLARGE_ELEMENT);var c=new CKEDITOR.dom.walker(c),e=0;c.evaluator=function(a){a.type==CKEDITOR.NODE_ELEMENT&&a.is(d)&&++e};
+c.checkForward();if(1<e){var c=b.startPath().contains("table"),f=b.endPath().contains("table");c&&f&&b.checkBoundaryOfElement(c,CKEDITOR.START)&&b.checkBoundaryOfElement(f,CKEDITOR.END)&&(b=a.range.clone(),b.setStartBefore(c),b.setEndAfter(f),a.purgeTableBookmark=b.createBookmark())}},detectRanges:function(e,f){var l=c(f,e.bookmark),g=l.clone(),k,h,v=l.getCommonAncestor();v.is(CKEDITOR.dtd.$tableContent)&&!v.is(d)&&(v=v.getAscendant("table",!0));h=v;v=new CKEDITOR.dom.elementPath(l.startContainer,
+h);h=new CKEDITOR.dom.elementPath(l.endContainer,h);v=v.contains("table");h=h.contains("table");if(v||h)v&&h&&b(v,h)?(e.tableSurroundingRange=g,g.setStartAt(v,CKEDITOR.POSITION_AFTER_END),g.setEndAt(h,CKEDITOR.POSITION_BEFORE_START),g=l.clone(),g.setEndAt(v,CKEDITOR.POSITION_AFTER_END),k=l.clone(),k.setStartAt(h,CKEDITOR.POSITION_BEFORE_START),k=a(g).concat(a(k))):v?h||(e.tableSurroundingRange=g,g.setStartAt(v,CKEDITOR.POSITION_AFTER_END),l.setEndAt(v,CKEDITOR.POSITION_AFTER_END)):(e.tableSurroundingRange=
+g,g.setEndAt(h,CKEDITOR.POSITION_BEFORE_START),l.setStartAt(h,CKEDITOR.POSITION_AFTER_START)),e.tableContentsRanges=k?k:a(l)},deleteRanges:function(a){for(var b;b=a.tableContentsRanges.pop();)b.extractContents(),u(b.startContainer)&&b.startContainer.appendBogus();a.tableSurroundingRange&&a.tableSurroundingRange.extractContents()},purge:function(a){if(a.purgeTableBookmark){var b=a.doc,c=a.range.clone(),b=b.createElement("p");b.insertBefore(a.purgeTableBookmark.startNode);c.moveToBookmark(a.purgeTableBookmark);
+c.deleteContents();a.range.moveToPosition(b,CKEDITOR.POSITION_AFTER_START)}}}}(),detectExtractMerge:function(a){return!(a.range.startPath().contains(CKEDITOR.dtd.$listItem)&&a.range.endPath().contains(CKEDITOR.dtd.$listItem))},fixUneditableRangePosition:function(a){a.startContainer.getDtd()["#"]||a.moveToClosestEditablePosition(null,!0)},autoParagraph:function(a,b){var c=b.startPath(),d;k(a,c.block,c.blockLimit)&&(d=h(a))&&(d=b.document.createElement(d),d.appendBogus(),b.insertNode(d),b.moveToPosition(d,
+CKEDITOR.POSITION_AFTER_START))}}}()})();
+(function(){function a(){var a=this._.fakeSelection,b;a&&(b=this.getSelection(1),b&&b.isHidden()||(a.reset(),a=0));if(!a&&(a=b||this.getSelection(1),!a||a.getType()==CKEDITOR.SELECTION_NONE))return;this.fire("selectionCheck",a);b=this.elementPath();if(!b.compare(this._.selectionPreviousPath)){var c=this._.selectionPreviousPath&&this._.selectionPreviousPath.blockLimit.equals(b.blockLimit);CKEDITOR.env.webkit&&!c&&(this._.previousActive=this.document.getActive());this._.selectionPreviousPath=b;this.fire("selectionChange",
+{selection:a,path:b})}}function d(){x=!0;m||(b.call(this),m=CKEDITOR.tools.setTimeout(b,200,this))}function b(){m=null;x&&(CKEDITOR.tools.setTimeout(a,0,this),x=!1)}function c(a){return J(a)||a.type==CKEDITOR.NODE_ELEMENT&&!a.is(CKEDITOR.dtd.$empty)?!0:!1}function e(a){function b(c,d){return c&&c.type!=CKEDITOR.NODE_TEXT?a.clone()["moveToElementEdit"+(d?"End":"Start")](c):!1}if(!(a.root instanceof CKEDITOR.editable))return!1;var d=a.startContainer,e=a.getPreviousNode(c,null,d),f=a.getNextNode(c,null,
+d);return b(e)||b(f,1)||!(e||f||d.type==CKEDITOR.NODE_ELEMENT&&d.isBlockBoundary()&&d.getBogus())?!0:!1}function g(a){k(a,!1);var b=a.getDocument().createText(z);a.setCustomData("cke-fillingChar",b);return b}function k(a,b){var c=a&&a.removeCustomData("cke-fillingChar");if(c){if(!1!==b){var d=a.getDocument().getSelection().getNative(),e=d&&"None"!=d.type&&d.getRangeAt(0),f=z.length;if(c.getLength()>f&&e&&e.intersectsNode(c.$)){var g=[{node:d.anchorNode,offset:d.anchorOffset},{node:d.focusNode,offset:d.focusOffset}];
+d.anchorNode==c.$&&d.anchorOffset>f&&(g[0].offset-=f);d.focusNode==c.$&&d.focusOffset>f&&(g[1].offset-=f)}}c.setText(h(c.getText(),1));g&&(c=a.getDocument().$,d=c.getSelection(),c=c.createRange(),c.setStart(g[0].node,g[0].offset),c.collapse(!0),d.removeAllRanges(),d.addRange(c),d.extend(g[1].node,g[1].offset))}}function h(a,b){return b?a.replace(y,function(a,b){return b?" ":""}):a.replace(z,"")}function p(a,b){var c=CKEDITOR.dom.element.createFromHtml('\x3cdiv data-cke-hidden-sel\x3d"1" data-cke-temp\x3d"1" style\x3d"'+
+(CKEDITOR.env.ie&&14>CKEDITOR.env.version?"display:none":"position:fixed;top:0;left:-1000px")+'"\x3e'+(b||"\x26nbsp;")+"\x3c/div\x3e",a.document);a.fire("lockSnapshot");a.editable().append(c);var d=a.getSelection(1),e=a.createRange(),f=d.root.on("selectionchange",function(a){a.cancel()},null,null,0);e.setStartAt(c,CKEDITOR.POSITION_AFTER_START);e.setEndAt(c,CKEDITOR.POSITION_BEFORE_END);d.selectRanges([e]);f.removeListener();a.fire("unlockSnapshot");a._.hiddenSelectionContainer=c}function r(a){var b=
+{37:1,39:1,8:1,46:1};return function(c){var d=c.data.getKeystroke();if(b[d]){var e=a.getSelection().getRanges(),f=e[0];1==e.length&&f.collapsed&&(d=f[38>d?"getPreviousEditableNode":"getNextEditableNode"]())&&d.type==CKEDITOR.NODE_ELEMENT&&"false"==d.getAttribute("contenteditable")&&(a.getSelection().fake(d),c.data.preventDefault(),c.cancel())}}}function f(a){for(var b=0;b<a.length;b++){var c=a[b];c.getCommonAncestor().isReadOnly()&&a.splice(b,1);if(!c.collapsed){if(c.startContainer.isReadOnly())for(var d=
+c.startContainer,e;d&&!((e=d.type==CKEDITOR.NODE_ELEMENT)&&d.is("body")||!d.isReadOnly());)e&&"false"==d.getAttribute("contentEditable")&&c.setStartAfter(d),d=d.getParent();d=c.startContainer;e=c.endContainer;var f=c.startOffset,g=c.endOffset,h=c.clone();d&&d.type==CKEDITOR.NODE_TEXT&&(f>=d.getLength()?h.setStartAfter(d):h.setStartBefore(d));e&&e.type==CKEDITOR.NODE_TEXT&&(g?h.setEndAfter(e):h.setEndBefore(e));d=new CKEDITOR.dom.walker(h);d.evaluator=function(d){if(d.type==CKEDITOR.NODE_ELEMENT&&
+d.isReadOnly()){var e=c.clone();c.setEndBefore(d);c.collapsed&&a.splice(b--,1);d.getPosition(h.endContainer)&CKEDITOR.POSITION_CONTAINS||(e.setStartAfter(d),e.collapsed||a.splice(b+1,0,e));return!0}return!1};d.next()}}return a}var B="function"!=typeof window.getSelection,u=1,z=CKEDITOR.tools.repeat("​",7),y=new RegExp(z+"( )?","g"),m,x,J=CKEDITOR.dom.walker.invisible(1),w=function(){function a(b){return function(a){var c=a.editor.createRange();c.moveToClosestEditablePosition(a.selected,b)&&a.editor.getSelection().selectRanges([c]);
+return!1}}function b(a){return function(b){var c=b.editor,d=c.createRange(),e;(e=d.moveToClosestEditablePosition(b.selected,a))||(e=d.moveToClosestEditablePosition(b.selected,!a));e&&c.getSelection().selectRanges([d]);c.fire("saveSnapshot");b.selected.remove();e||(d.moveToElementEditablePosition(c.editable()),c.getSelection().selectRanges([d]));c.fire("saveSnapshot");return!1}}var c=a(),d=a(1);return{37:c,38:c,39:d,40:d,8:b(),46:b(1)}}();CKEDITOR.on("instanceCreated",function(b){function c(){var a=
+e.getSelection();a&&a.removeAllRanges()}var e=b.editor;e.on("contentDom",function(){function b(){v=new CKEDITOR.dom.selection(e.getSelection());v.lock()}function c(){l.removeListener("mouseup",c);q.removeListener("mouseup",c);var a=CKEDITOR.document.$.selection,b=a.createRange();"None"!=a.type&&b.parentElement().ownerDocument==f.$&&b.select()}var f=e.document,l=CKEDITOR.document,g=e.editable(),h=f.getBody(),q=f.getDocumentElement(),m=g.isInline(),p,v;CKEDITOR.env.gecko&&g.attachListener(g,"focus",
+function(a){a.removeListener();0!==p&&(a=e.getSelection().getNative())&&a.isCollapsed&&a.anchorNode==g.$&&(a=e.createRange(),a.moveToElementEditStart(g),a.select())},null,null,-2);g.attachListener(g,CKEDITOR.env.webkit?"DOMFocusIn":"focus",function(){p&&CKEDITOR.env.webkit&&(p=e._.previousActive&&e._.previousActive.equals(f.getActive()))&&null!=e._.previousScrollTop&&e._.previousScrollTop!=g.$.scrollTop&&(g.$.scrollTop=e._.previousScrollTop);e.unlockSelection(p);p=0},null,null,-1);g.attachListener(g,
+"mousedown",function(){p=0});if(CKEDITOR.env.ie||m)B?g.attachListener(g,"beforedeactivate",b,null,null,-1):g.attachListener(e,"selectionCheck",b,null,null,-1),g.attachListener(g,CKEDITOR.env.webkit?"DOMFocusOut":"blur",function(){e.lockSelection(v);p=1},null,null,-1),g.attachListener(g,"mousedown",function(){p=0});if(CKEDITOR.env.ie&&!m){var G;g.attachListener(g,"mousedown",function(a){2==a.data.$.button&&((a=e.document.getSelection())&&a.getType()!=CKEDITOR.SELECTION_NONE||(G=e.window.getScrollPosition()))});
+g.attachListener(g,"mouseup",function(a){2==a.data.$.button&&G&&(e.document.$.documentElement.scrollLeft=G.x,e.document.$.documentElement.scrollTop=G.y);G=null});if("BackCompat"!=f.$.compatMode){if(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat){var E,I;q.on("mousedown",function(a){function b(a){a=a.data.$;if(E){var c=h.$.createTextRange();try{c.moveToPoint(a.clientX,a.clientY)}catch(d){}E.setEndPoint(0>I.compareEndPoints("StartToStart",c)?"EndToEnd":"StartToStart",c);E.select()}}function c(){q.removeListener("mousemove",
+b);l.removeListener("mouseup",c);q.removeListener("mouseup",c);E.select()}a=a.data;if(a.getTarget().is("html")&&a.$.y<q.$.clientHeight&&a.$.x<q.$.clientWidth){E=h.$.createTextRange();try{E.moveToPoint(a.$.clientX,a.$.clientY)}catch(d){}I=E.duplicate();q.on("mousemove",b);l.on("mouseup",c);q.on("mouseup",c)}})}if(7<CKEDITOR.env.version&&11>CKEDITOR.env.version)q.on("mousedown",function(a){a.data.getTarget().is("html")&&(l.on("mouseup",c),q.on("mouseup",c))})}}g.attachListener(g,"selectionchange",a,
+e);g.attachListener(g,"keyup",d,e);g.attachListener(g,CKEDITOR.env.webkit?"DOMFocusIn":"focus",function(){e.forceNextSelectionCheck();e.selectionChange(1)});if(m&&(CKEDITOR.env.webkit||CKEDITOR.env.gecko)){var K;g.attachListener(g,"mousedown",function(){K=1});g.attachListener(f.getDocumentElement(),"mouseup",function(){K&&d.call(e);K=0})}else g.attachListener(CKEDITOR.env.ie?g:f.getDocumentElement(),"mouseup",d,e);CKEDITOR.env.webkit&&g.attachListener(f,"keydown",function(a){switch(a.data.getKey()){case 13:case 33:case 34:case 35:case 36:case 37:case 39:case 8:case 45:case 46:k(g)}},
+null,null,-1);g.attachListener(g,"keydown",r(e),null,null,-1)});e.on("setData",function(){e.unlockSelection();CKEDITOR.env.webkit&&c()});e.on("contentDomUnload",function(){e.unlockSelection()});if(CKEDITOR.env.ie9Compat)e.on("beforeDestroy",c,null,null,9);e.on("dataReady",function(){delete e._.fakeSelection;delete e._.hiddenSelectionContainer;e.selectionChange(1)});e.on("loadSnapshot",function(){var a=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_ELEMENT),b=e.editable().getLast(a);b&&b.hasAttribute("data-cke-hidden-sel")&&
+(b.remove(),CKEDITOR.env.gecko&&(a=e.editable().getFirst(a))&&a.is("br")&&a.getAttribute("_moz_editor_bogus_node")&&a.remove())},null,null,100);e.on("key",function(a){if("wysiwyg"==e.mode){var b=e.getSelection();if(b.isFake){var c=w[a.data.keyCode];if(c)return c({editor:e,selected:b.getSelectedElement(),selection:b,keyEvent:a})}}})});if(CKEDITOR.env.webkit)CKEDITOR.on("instanceReady",function(a){var b=a.editor;b.on("selectionChange",function(){var a=b.editable(),c=a.getCustomData("cke-fillingChar");
+c&&(c.getCustomData("ready")?k(a):c.setCustomData("ready",1))},null,null,-1);b.on("beforeSetMode",function(){k(b.editable())},null,null,-1);b.on("getSnapshot",function(a){a.data&&(a.data=h(a.data))},b,null,20);b.on("toDataFormat",function(a){a.data.dataValue=h(a.data.dataValue)},null,null,0)});CKEDITOR.editor.prototype.selectionChange=function(b){(b?a:d).call(this)};CKEDITOR.editor.prototype.getSelection=function(a){return!this._.savedSelection&&!this._.fakeSelection||a?(a=this.editable())&&"wysiwyg"==
+this.mode?new CKEDITOR.dom.selection(a):null:this._.savedSelection||this._.fakeSelection};CKEDITOR.editor.prototype.lockSelection=function(a){a=a||this.getSelection(1);return a.getType()!=CKEDITOR.SELECTION_NONE?(!a.isLocked&&a.lock(),this._.savedSelection=a,!0):!1};CKEDITOR.editor.prototype.unlockSelection=function(a){var b=this._.savedSelection;return b?(b.unlock(a),delete this._.savedSelection,!0):!1};CKEDITOR.editor.prototype.forceNextSelectionCheck=function(){delete this._.selectionPreviousPath};
+CKEDITOR.dom.document.prototype.getSelection=function(){return new CKEDITOR.dom.selection(this)};CKEDITOR.dom.range.prototype.select=function(){var a=this.root instanceof CKEDITOR.editable?this.root.editor.getSelection():new CKEDITOR.dom.selection(this.root);a.selectRanges([this]);return a};CKEDITOR.SELECTION_NONE=1;CKEDITOR.SELECTION_TEXT=2;CKEDITOR.SELECTION_ELEMENT=3;CKEDITOR.dom.selection=function(a){if(a instanceof CKEDITOR.dom.selection){var b=a;a=a.root}var c=a instanceof CKEDITOR.dom.element;
+this.rev=b?b.rev:u++;this.document=a instanceof CKEDITOR.dom.document?a:a.getDocument();this.root=c?a:this.document.getBody();this.isLocked=0;this._={cache:{}};if(b)return CKEDITOR.tools.extend(this._.cache,b._.cache),this.isFake=b.isFake,this.isLocked=b.isLocked,this;a=this.getNative();var d,e;if(a)if(a.getRangeAt)d=(e=a.rangeCount&&a.getRangeAt(0))&&new CKEDITOR.dom.node(e.commonAncestorContainer);else{try{e=a.createRange()}catch(f){}d=e&&CKEDITOR.dom.element.get(e.item&&e.item(0)||e.parentElement())}if(!d||
+d.type!=CKEDITOR.NODE_ELEMENT&&d.type!=CKEDITOR.NODE_TEXT||!this.root.equals(d)&&!this.root.contains(d))this._.cache.type=CKEDITOR.SELECTION_NONE,this._.cache.startElement=null,this._.cache.selectedElement=null,this._.cache.selectedText="",this._.cache.ranges=new CKEDITOR.dom.rangeList;return this};var F={img:1,hr:1,li:1,table:1,tr:1,td:1,th:1,embed:1,object:1,ol:1,ul:1,a:1,input:1,form:1,select:1,textarea:1,button:1,fieldset:1,thead:1,tfoot:1};CKEDITOR.tools.extend(CKEDITOR.dom.selection,{_removeFillingCharSequenceString:h,
+_createFillingCharSequenceNode:g,FILLING_CHAR_SEQUENCE:z});CKEDITOR.dom.selection.prototype={getNative:function(){return void 0!==this._.cache.nativeSel?this._.cache.nativeSel:this._.cache.nativeSel=B?this.document.$.selection:this.document.getWindow().$.getSelection()},getType:B?function(){var a=this._.cache;if(a.type)return a.type;var b=CKEDITOR.SELECTION_NONE;try{var c=this.getNative(),d=c.type;"Text"==d&&(b=CKEDITOR.SELECTION_TEXT);"Control"==d&&(b=CKEDITOR.SELECTION_ELEMENT);c.createRange().parentElement()&&
+(b=CKEDITOR.SELECTION_TEXT)}catch(e){}return a.type=b}:function(){var a=this._.cache;if(a.type)return a.type;var b=CKEDITOR.SELECTION_TEXT,c=this.getNative();if(!c||!c.rangeCount)b=CKEDITOR.SELECTION_NONE;else if(1==c.rangeCount){var c=c.getRangeAt(0),d=c.startContainer;d==c.endContainer&&1==d.nodeType&&1==c.endOffset-c.startOffset&&F[d.childNodes[c.startOffset].nodeName.toLowerCase()]&&(b=CKEDITOR.SELECTION_ELEMENT)}return a.type=b},getRanges:function(){var a=B?function(){function a(b){return(new CKEDITOR.dom.node(b)).getIndex()}
+var b=function(b,c){b=b.duplicate();b.collapse(c);var d=b.parentElement();if(!d.hasChildNodes())return{container:d,offset:0};for(var e=d.children,f,l,g=b.duplicate(),h=0,k=e.length-1,v=-1,n,m;h<=k;)if(v=Math.floor((h+k)/2),f=e[v],g.moveToElementText(f),n=g.compareEndPoints("StartToStart",b),0<n)k=v-1;else if(0>n)h=v+1;else return{container:d,offset:a(f)};if(-1==v||v==e.length-1&&0>n){g.moveToElementText(d);g.setEndPoint("StartToStart",b);g=g.text.replace(/(\r\n|\r)/g,"\n").length;e=d.childNodes;if(!g)return f=
+e[e.length-1],f.nodeType!=CKEDITOR.NODE_TEXT?{container:d,offset:e.length}:{container:f,offset:f.nodeValue.length};for(d=e.length;0<g&&0<d;)l=e[--d],l.nodeType==CKEDITOR.NODE_TEXT&&(m=l,g-=l.nodeValue.length);return{container:m,offset:-g}}g.collapse(0<n?!0:!1);g.setEndPoint(0<n?"StartToStart":"EndToStart",b);g=g.text.replace(/(\r\n|\r)/g,"\n").length;if(!g)return{container:d,offset:a(f)+(0<n?0:1)};for(;0<g;)try{l=f[0<n?"previousSibling":"nextSibling"],l.nodeType==CKEDITOR.NODE_TEXT&&(g-=l.nodeValue.length,
+m=l),f=l}catch(p){return{container:d,offset:a(f)}}return{container:m,offset:0<n?-g:m.nodeValue.length+g}};return function(){var a=this.getNative(),c=a&&a.createRange(),d=this.getType();if(!a)return[];if(d==CKEDITOR.SELECTION_TEXT)return a=new CKEDITOR.dom.range(this.root),d=b(c,!0),a.setStart(new CKEDITOR.dom.node(d.container),d.offset),d=b(c),a.setEnd(new CKEDITOR.dom.node(d.container),d.offset),a.endContainer.getPosition(a.startContainer)&CKEDITOR.POSITION_PRECEDING&&a.endOffset<=a.startContainer.getIndex()&&
+a.collapse(),[a];if(d==CKEDITOR.SELECTION_ELEMENT){for(var d=[],e=0;e<c.length;e++){for(var f=c.item(e),g=f.parentNode,l=0,a=new CKEDITOR.dom.range(this.root);l<g.childNodes.length&&g.childNodes[l]!=f;l++);a.setStart(new CKEDITOR.dom.node(g),l);a.setEnd(new CKEDITOR.dom.node(g),l+1);d.push(a)}return d}return[]}}():function(){var a=[],b,c=this.getNative();if(!c)return a;for(var d=0;d<c.rangeCount;d++){var e=c.getRangeAt(d);b=new CKEDITOR.dom.range(this.root);b.setStart(new CKEDITOR.dom.node(e.startContainer),
+e.startOffset);b.setEnd(new CKEDITOR.dom.node(e.endContainer),e.endOffset);a.push(b)}return a};return function(b){var c=this._.cache,d=c.ranges;d||(c.ranges=d=new CKEDITOR.dom.rangeList(a.call(this)));return b?f(new CKEDITOR.dom.rangeList(d.slice())):d}}(),getStartElement:function(){var a=this._.cache;if(void 0!==a.startElement)return a.startElement;var b;switch(this.getType()){case CKEDITOR.SELECTION_ELEMENT:return this.getSelectedElement();case CKEDITOR.SELECTION_TEXT:var c=this.getRanges()[0];
+if(c){if(c.collapsed)b=c.startContainer,b.type!=CKEDITOR.NODE_ELEMENT&&(b=b.getParent());else{for(c.optimize();b=c.startContainer,c.startOffset==(b.getChildCount?b.getChildCount():b.getLength())&&!b.isBlockBoundary();)c.setStartAfter(b);b=c.startContainer;if(b.type!=CKEDITOR.NODE_ELEMENT)return b.getParent();if((b=b.getChild(c.startOffset))&&b.type==CKEDITOR.NODE_ELEMENT)for(c=b.getFirst();c&&c.type==CKEDITOR.NODE_ELEMENT;)b=c,c=c.getFirst();else b=c.startContainer}b=b.$}}return a.startElement=b?
+new CKEDITOR.dom.element(b):null},getSelectedElement:function(){var a=this._.cache;if(void 0!==a.selectedElement)return a.selectedElement;var b=this,c=CKEDITOR.tools.tryThese(function(){return b.getNative().createRange().item(0)},function(){for(var a=b.getRanges()[0].clone(),c,d,e=2;e&&!((c=a.getEnclosedNode())&&c.type==CKEDITOR.NODE_ELEMENT&&F[c.getName()]&&(d=c));e--)a.shrink(CKEDITOR.SHRINK_ELEMENT);return d&&d.$});return a.selectedElement=c?new CKEDITOR.dom.element(c):null},getSelectedText:function(){var a=
+this._.cache;if(void 0!==a.selectedText)return a.selectedText;var b=this.getNative(),b=B?"Control"==b.type?"":b.createRange().text:b.toString();return a.selectedText=b},lock:function(){this.getRanges();this.getStartElement();this.getSelectedElement();this.getSelectedText();this._.cache.nativeSel=null;this.isLocked=1},unlock:function(a){if(this.isLocked){if(a)var b=this.getSelectedElement(),c=!b&&this.getRanges(),d=this.isFake;this.isLocked=0;this.reset();a&&(a=b||c[0]&&c[0].getCommonAncestor())&&
+a.getAscendant("body",1)&&(d?this.fake(b):b?this.selectElement(b):this.selectRanges(c))}},reset:function(){this._.cache={};this.isFake=0;var a=this.root.editor;if(a&&a._.fakeSelection)if(this.rev==a._.fakeSelection.rev){delete a._.fakeSelection;var b=a._.hiddenSelectionContainer;if(b){var c=a.checkDirty();a.fire("lockSnapshot");b.remove();a.fire("unlockSnapshot");!c&&a.resetDirty()}delete a._.hiddenSelectionContainer}else CKEDITOR.warn("selection-fake-reset");this.rev=u++},selectElement:function(a){var b=
+new CKEDITOR.dom.range(this.root);b.setStartBefore(a);b.setEndAfter(a);this.selectRanges([b])},selectRanges:function(a){var b=this.root.editor,b=b&&b._.hiddenSelectionContainer;this.reset();if(b)for(var b=this.root,c,d=0;d<a.length;++d)c=a[d],c.endContainer.equals(b)&&(c.endOffset=Math.min(c.endOffset,b.getChildCount()));if(a.length)if(this.isLocked){var f=CKEDITOR.document.getActive();this.unlock();this.selectRanges(a);this.lock();f&&!f.equals(this.root)&&f.focus()}else{var h;a:{var m,p;if(1==a.length&&
+!(p=a[0]).collapsed&&(h=p.getEnclosedNode())&&h.type==CKEDITOR.NODE_ELEMENT&&(p=p.clone(),p.shrink(CKEDITOR.SHRINK_ELEMENT,!0),(m=p.getEnclosedNode())&&m.type==CKEDITOR.NODE_ELEMENT&&(h=m),"false"==h.getAttribute("contenteditable")))break a;h=void 0}if(h)this.fake(h);else{if(B){p=CKEDITOR.dom.walker.whitespaces(!0);m=/\ufeff|\u00a0/;b={table:1,tbody:1,tr:1};1<a.length&&(h=a[a.length-1],a[0].setEnd(h.endContainer,h.endOffset));h=a[0];a=h.collapsed;var r,u,y;if((c=h.getEnclosedNode())&&c.type==CKEDITOR.NODE_ELEMENT&&
+c.getName()in F&&(!c.is("a")||!c.getText()))try{y=c.$.createControlRange();y.addElement(c.$);y.select();return}catch(w){}if(h.startContainer.type==CKEDITOR.NODE_ELEMENT&&h.startContainer.getName()in b||h.endContainer.type==CKEDITOR.NODE_ELEMENT&&h.endContainer.getName()in b)h.shrink(CKEDITOR.NODE_ELEMENT,!0),a=h.collapsed;y=h.createBookmark();b=y.startNode;a||(f=y.endNode);y=h.document.$.body.createTextRange();y.moveToElementText(b.$);y.moveStart("character",1);f?(m=h.document.$.body.createTextRange(),
+m.moveToElementText(f.$),y.setEndPoint("EndToEnd",m),y.moveEnd("character",-1)):(r=b.getNext(p),u=b.hasAscendant("pre"),r=!(r&&r.getText&&r.getText().match(m))&&(u||!b.hasPrevious()||b.getPrevious().is&&b.getPrevious().is("br")),u=h.document.createElement("span"),u.setHtml("\x26#65279;"),u.insertBefore(b),r&&h.document.createText("").insertBefore(b));h.setStartBefore(b);b.remove();a?(r?(y.moveStart("character",-1),y.select(),h.document.$.selection.clear()):y.select(),h.moveToPosition(u,CKEDITOR.POSITION_BEFORE_START),
+u.remove()):(h.setEndBefore(f),f.remove(),y.select())}else{f=this.getNative();if(!f)return;this.removeAllRanges();for(y=0;y<a.length;y++){if(y<a.length-1&&(r=a[y],u=a[y+1],m=r.clone(),m.setStart(r.endContainer,r.endOffset),m.setEnd(u.startContainer,u.startOffset),!m.collapsed&&(m.shrink(CKEDITOR.NODE_ELEMENT,!0),h=m.getCommonAncestor(),m=m.getEnclosedNode(),h.isReadOnly()||m&&m.isReadOnly()))){u.setStart(r.startContainer,r.startOffset);a.splice(y--,1);continue}h=a[y];u=this.document.$.createRange();
+h.collapsed&&CKEDITOR.env.webkit&&e(h)&&(m=g(this.root),h.insertNode(m),(r=m.getNext())&&!m.getPrevious()&&r.type==CKEDITOR.NODE_ELEMENT&&"br"==r.getName()?(k(this.root),h.moveToPosition(r,CKEDITOR.POSITION_BEFORE_START)):h.moveToPosition(m,CKEDITOR.POSITION_AFTER_END));u.setStart(h.startContainer.$,h.startOffset);try{u.setEnd(h.endContainer.$,h.endOffset)}catch(v){if(0<=v.toString().indexOf("NS_ERROR_ILLEGAL_VALUE"))h.collapse(1),u.setEnd(h.endContainer.$,h.endOffset);else throw v;}f.addRange(u)}}this.reset();
+this.root.fire("selectionchange")}}},fake:function(a,b){var c=this.root.editor;void 0===b&&a.hasAttribute("aria-label")&&(b=a.getAttribute("aria-label"));this.reset();p(c,b);var d=this._.cache,e=new CKEDITOR.dom.range(this.root);e.setStartBefore(a);e.setEndAfter(a);d.ranges=new CKEDITOR.dom.rangeList(e);d.selectedElement=d.startElement=a;d.type=CKEDITOR.SELECTION_ELEMENT;d.selectedText=d.nativeSel=null;this.isFake=1;this.rev=u++;c._.fakeSelection=this;this.root.fire("selectionchange")},isHidden:function(){var a=
+this.getCommonAncestor();a&&a.type==CKEDITOR.NODE_TEXT&&(a=a.getParent());return!(!a||!a.data("cke-hidden-sel"))},createBookmarks:function(a){a=this.getRanges().createBookmarks(a);this.isFake&&(a.isFake=1);return a},createBookmarks2:function(a){a=this.getRanges().createBookmarks2(a);this.isFake&&(a.isFake=1);return a},selectBookmarks:function(a){for(var b=[],c,d=0;d<a.length;d++){var e=new CKEDITOR.dom.range(this.root);e.moveToBookmark(a[d]);b.push(e)}a.isFake&&(c=b[0].getEnclosedNode(),c&&c.type==
+CKEDITOR.NODE_ELEMENT||(CKEDITOR.warn("selection-not-fake"),a.isFake=0));a.isFake?this.fake(c):this.selectRanges(b);return this},getCommonAncestor:function(){var a=this.getRanges();return a.length?a[0].startContainer.getCommonAncestor(a[a.length-1].endContainer):null},scrollIntoView:function(){this.type!=CKEDITOR.SELECTION_NONE&&this.getRanges()[0].scrollIntoView()},removeAllRanges:function(){if(this.getType()!=CKEDITOR.SELECTION_NONE){var a=this.getNative();try{a&&a[B?"empty":"removeAllRanges"]()}catch(b){}this.reset()}}}})();
+"use strict";CKEDITOR.STYLE_BLOCK=1;CKEDITOR.STYLE_INLINE=2;CKEDITOR.STYLE_OBJECT=3;
+(function(){function a(a,b){for(var c,d;(a=a.getParent())&&!a.equals(b);)if(a.getAttribute("data-nostyle"))c=a;else if(!d){var e=a.getAttribute("contentEditable");"false"==e?c=a:"true"==e&&(d=1)}return c}function d(a,b,c,d){return(a.getPosition(b)|d)==d&&(!c.childRule||c.childRule(a))}function b(c){var f=c.document;if(c.collapsed)f=J(this,f),c.insertNode(f),c.moveToPosition(f,CKEDITOR.POSITION_BEFORE_END);else{var g=this.element,h=this._.definition,l,k=h.ignoreReadonly,m=k||h.includeReadonly;null==
+m&&(m=c.root.getCustomData("cke_includeReadonly"));var n=CKEDITOR.dtd[g];n||(l=!0,n=CKEDITOR.dtd.span);c.enlarge(CKEDITOR.ENLARGE_INLINE,1);c.trim();var p=c.createBookmark(),q=p.startNode,r=p.endNode,u=q,t;if(!k){var w=c.getCommonAncestor(),k=a(q,w),w=a(r,w);k&&(u=k.getNextSourceNode(!0));w&&(r=w)}for(u.getPosition(r)==CKEDITOR.POSITION_FOLLOWING&&(u=0);u;){k=!1;if(u.equals(r))u=null,k=!0;else{var z=u.type==CKEDITOR.NODE_ELEMENT?u.getName():null,w=z&&"false"==u.getAttribute("contentEditable"),x=z&&
+u.getAttribute("data-nostyle");if(z&&u.data("cke-bookmark")){u=u.getNextSourceNode(!0);continue}if(w&&m&&CKEDITOR.dtd.$block[z])for(var B=u,A=e(B),C=void 0,D=A.length,F=0,B=D&&new CKEDITOR.dom.range(B.getDocument());F<D;++F){var C=A[F],M=CKEDITOR.filter.instances[C.data("cke-filter")];if(M?M.check(this):1)B.selectNodeContents(C),b.call(this,B)}A=z?!n[z]||x?0:w&&!m?0:d(u,r,h,Q):1;if(A)if(C=u.getParent(),A=h,D=g,F=l,!C||!(C.getDtd()||CKEDITOR.dtd.span)[D]&&!F||A.parentRule&&!A.parentRule(C))k=!0;else{if(t||
+z&&CKEDITOR.dtd.$removeEmpty[z]&&(u.getPosition(r)|Q)!=Q||(t=c.clone(),t.setStartBefore(u)),z=u.type,z==CKEDITOR.NODE_TEXT||w||z==CKEDITOR.NODE_ELEMENT&&!u.getChildCount()){for(var z=u,R;(k=!z.getNext(H))&&(R=z.getParent(),n[R.getName()])&&d(R,q,h,P);)z=R;t.setEndAfter(z)}}else k=!0;u=u.getNextSourceNode(x||w)}if(k&&t&&!t.collapsed){for(var k=J(this,f),w=k.hasAttributes(),x=t.getCommonAncestor(),z={},A={},C={},D={},W,T,ca;k&&x;){if(x.getName()==g){for(W in h.attributes)!D[W]&&(ca=x.getAttribute(T))&&
+(k.getAttribute(W)==ca?A[W]=1:D[W]=1);for(T in h.styles)!C[T]&&(ca=x.getStyle(T))&&(k.getStyle(T)==ca?z[T]=1:C[T]=1)}x=x.getParent()}for(W in A)k.removeAttribute(W);for(T in z)k.removeStyle(T);w&&!k.hasAttributes()&&(k=null);k?(t.extractContents().appendTo(k),t.insertNode(k),y.call(this,k),k.mergeSiblings(),CKEDITOR.env.ie||k.$.normalize()):(k=new CKEDITOR.dom.element("span"),t.extractContents().appendTo(k),t.insertNode(k),y.call(this,k),k.remove(!0));t=null}}c.moveToBookmark(p);c.shrink(CKEDITOR.SHRINK_TEXT);
+c.shrink(CKEDITOR.NODE_ELEMENT,!0)}}function c(a){function b(){for(var a=new CKEDITOR.dom.elementPath(d.getParent()),c=new CKEDITOR.dom.elementPath(n.getParent()),e=null,f=null,g=0;g<a.elements.length;g++){var h=a.elements[g];if(h==a.block||h==a.blockLimit)break;p.checkElementRemovable(h,!0)&&(e=h)}for(g=0;g<c.elements.length;g++){h=c.elements[g];if(h==c.block||h==c.blockLimit)break;p.checkElementRemovable(h,!0)&&(f=h)}f&&n.breakParent(f);e&&d.breakParent(e)}a.enlarge(CKEDITOR.ENLARGE_INLINE,1);var c=
+a.createBookmark(),d=c.startNode;if(a.collapsed){for(var e=new CKEDITOR.dom.elementPath(d.getParent(),a.root),f,g=0,h;g<e.elements.length&&(h=e.elements[g])&&h!=e.block&&h!=e.blockLimit;g++)if(this.checkElementRemovable(h)){var k;a.collapsed&&(a.checkBoundaryOfElement(h,CKEDITOR.END)||(k=a.checkBoundaryOfElement(h,CKEDITOR.START)))?(f=h,f.match=k?"start":"end"):(h.mergeSiblings(),h.is(this.element)?z.call(this,h):m(h,l(this)[h.getName()]))}if(f){h=d;for(g=0;;g++){k=e.elements[g];if(k.equals(f))break;
+else if(k.match)continue;else k=k.clone();k.append(h);h=k}h["start"==f.match?"insertBefore":"insertAfter"](f)}}else{var n=c.endNode,p=this;b();for(e=d;!e.equals(n);)f=e.getNextSourceNode(),e.type==CKEDITOR.NODE_ELEMENT&&this.checkElementRemovable(e)&&(e.getName()==this.element?z.call(this,e):m(e,l(this)[e.getName()]),f.type==CKEDITOR.NODE_ELEMENT&&f.contains(d)&&(b(),f=d.getNext())),e=f}a.moveToBookmark(c);a.shrink(CKEDITOR.NODE_ELEMENT,!0)}function e(a){var b=[];a.forEach(function(a){if("true"==
+a.getAttribute("contenteditable"))return b.push(a),!1},CKEDITOR.NODE_ELEMENT,!0);return b}function g(a){var b=a.getEnclosedNode()||a.getCommonAncestor(!1,!0);(a=(new CKEDITOR.dom.elementPath(b,a.root)).contains(this.element,1))&&!a.isReadOnly()&&w(a,this)}function k(a){var b=a.getCommonAncestor(!0,!0);if(a=(new CKEDITOR.dom.elementPath(b,a.root)).contains(this.element,1)){var b=this._.definition,c=b.attributes;if(c)for(var d in c)a.removeAttribute(d,c[d]);if(b.styles)for(var e in b.styles)b.styles.hasOwnProperty(e)&&
+a.removeStyle(e)}}function h(a){var b=a.createBookmark(!0),c=a.createIterator();c.enforceRealBlocks=!0;this._.enterMode&&(c.enlargeBr=this._.enterMode!=CKEDITOR.ENTER_BR);for(var d,e=a.document,f;d=c.getNextParagraph();)!d.isReadOnly()&&(c.activeFilter?c.activeFilter.check(this):1)&&(f=J(this,e,d),r(d,f));a.moveToBookmark(b)}function p(a){var b=a.createBookmark(1),c=a.createIterator();c.enforceRealBlocks=!0;c.enlargeBr=this._.enterMode!=CKEDITOR.ENTER_BR;for(var d,e;d=c.getNextParagraph();)this.checkElementRemovable(d)&&
+(d.is("pre")?((e=this._.enterMode==CKEDITOR.ENTER_BR?null:a.document.createElement(this._.enterMode==CKEDITOR.ENTER_P?"p":"div"))&&d.copyAttributes(e),r(d,e)):z.call(this,d));a.moveToBookmark(b)}function r(a,b){var c=!b;c&&(b=a.getDocument().createElement("div"),a.copyAttributes(b));var d=b&&b.is("pre"),e=a.is("pre"),g=!d&&e;if(d&&!e){e=b;(g=a.getBogus())&&g.remove();g=a.getHtml();g=B(g,/(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g,"");g=g.replace(/[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi,"$1");g=g.replace(/([ \t\n\r]+|&nbsp;)/g,
+" ");g=g.replace(/<br\b[^>]*>/gi,"\n");if(CKEDITOR.env.ie){var h=a.getDocument().createElement("div");h.append(e);e.$.outerHTML="\x3cpre\x3e"+g+"\x3c/pre\x3e";e.copyAttributes(h.getFirst());e=h.getFirst().remove()}else e.setHtml(g);b=e}else g?b=u(c?[a.getHtml()]:f(a),b):a.moveChildren(b);b.replace(a);if(d){var c=b,k;(k=c.getPrevious(R))&&k.type==CKEDITOR.NODE_ELEMENT&&k.is("pre")&&(d=B(k.getHtml(),/\n$/,"")+"\n\n"+B(c.getHtml(),/^\n/,""),CKEDITOR.env.ie?c.$.outerHTML="\x3cpre\x3e"+d+"\x3c/pre\x3e":
+c.setHtml(d),k.remove())}else c&&x(b)}function f(a){var b=[];B(a.getOuterHtml(),/(\S\s*)\n(?:\s|(<span[^>]+data-cke-bookmark.*?\/span>))*\n(?!$)/gi,function(a,b,c){return b+"\x3c/pre\x3e"+c+"\x3cpre\x3e"}).replace(/<pre\b.*?>([\s\S]*?)<\/pre>/gi,function(a,c){b.push(c)});return b}function B(a,b,c){var d="",e="";a=a.replace(/(^<span[^>]+data-cke-bookmark.*?\/span>)|(<span[^>]+data-cke-bookmark.*?\/span>$)/gi,function(a,b,c){b&&(d=b);c&&(e=c);return""});return d+a.replace(b,c)+e}function u(a,b){var c;
+1<a.length&&(c=new CKEDITOR.dom.documentFragment(b.getDocument()));for(var d=0;d<a.length;d++){var e=a[d],e=e.replace(/(\r\n|\r)/g,"\n"),e=B(e,/^[ \t]*\n/,""),e=B(e,/\n$/,""),e=B(e,/^[ \t]+|[ \t]+$/g,function(a,b){return 1==a.length?"\x26nbsp;":b?" "+CKEDITOR.tools.repeat("\x26nbsp;",a.length-1):CKEDITOR.tools.repeat("\x26nbsp;",a.length-1)+" "}),e=e.replace(/\n/g,"\x3cbr\x3e"),e=e.replace(/[ \t]{2,}/g,function(a){return CKEDITOR.tools.repeat("\x26nbsp;",a.length-1)+" "});if(c){var f=b.clone();f.setHtml(e);
+c.append(f)}else b.setHtml(e)}return c||b}function z(a,b){var c=this._.definition,d=c.attributes,c=c.styles,e=l(this)[a.getName()],f=CKEDITOR.tools.isEmpty(d)&&CKEDITOR.tools.isEmpty(c),g;for(g in d)if("class"!=g&&!this._.definition.fullMatch||a.getAttribute(g)==q(g,d[g]))b&&"data-"==g.slice(0,5)||(f=a.hasAttribute(g),a.removeAttribute(g));for(var h in c)this._.definition.fullMatch&&a.getStyle(h)!=q(h,c[h],!0)||(f=f||!!a.getStyle(h),a.removeStyle(h));m(a,e,A[a.getName()]);f&&(this._.definition.alwaysRemoveElement?
+x(a,1):!CKEDITOR.dtd.$block[a.getName()]||this._.enterMode==CKEDITOR.ENTER_BR&&!a.hasAttributes()?x(a):a.renameNode(this._.enterMode==CKEDITOR.ENTER_P?"p":"div"))}function y(a){for(var b=l(this),c=a.getElementsByTag(this.element),d,e=c.count();0<=--e;)d=c.getItem(e),d.isReadOnly()||z.call(this,d,!0);for(var f in b)if(f!=this.element)for(c=a.getElementsByTag(f),e=c.count()-1;0<=e;e--)d=c.getItem(e),d.isReadOnly()||m(d,b[f])}function m(a,b,c){if(b=b&&b.attributes)for(var d=0;d<b.length;d++){var e=b[d][0],
+f;if(f=a.getAttribute(e)){var g=b[d][1];(null===g||g.test&&g.test(f)||"string"==typeof g&&f==g)&&a.removeAttribute(e)}}c||x(a)}function x(a,b){if(!a.hasAttributes()||b)if(CKEDITOR.dtd.$block[a.getName()]){var c=a.getPrevious(R),d=a.getNext(R);!c||c.type!=CKEDITOR.NODE_TEXT&&c.isBlockBoundary({br:1})||a.append("br",1);!d||d.type!=CKEDITOR.NODE_TEXT&&d.isBlockBoundary({br:1})||a.append("br");a.remove(!0)}else c=a.getFirst(),d=a.getLast(),a.remove(!0),c&&(c.type==CKEDITOR.NODE_ELEMENT&&c.mergeSiblings(),
+d&&!c.equals(d)&&d.type==CKEDITOR.NODE_ELEMENT&&d.mergeSiblings())}function J(a,b,c){var d;d=a.element;"*"==d&&(d="span");d=new CKEDITOR.dom.element(d,b);c&&c.copyAttributes(d);d=w(d,a);b.getCustomData("doc_processing_style")&&d.hasAttribute("id")?d.removeAttribute("id"):b.setCustomData("doc_processing_style",1);return d}function w(a,b){var c=b._.definition,d=c.attributes,c=CKEDITOR.style.getStyleText(c);if(d)for(var e in d)a.setAttribute(e,d[e]);c&&a.setAttribute("style",c);return a}function F(a,
+b){for(var c in a)a[c]=a[c].replace(M,function(a,c){return b[c]})}function l(a){if(a._.overrides)return a._.overrides;var b=a._.overrides={},c=a._.definition.overrides;if(c){CKEDITOR.tools.isArray(c)||(c=[c]);for(var d=0;d<c.length;d++){var e=c[d],f,g;"string"==typeof e?f=e.toLowerCase():(f=e.element?e.element.toLowerCase():a.element,g=e.attributes);e=b[f]||(b[f]={});if(g){var e=e.attributes=e.attributes||[],h;for(h in g)e.push([h.toLowerCase(),g[h]])}}}return b}function q(a,b,c){var d=new CKEDITOR.dom.element("span");
+d[c?"setStyle":"setAttribute"](a,b);return d[c?"getStyle":"getAttribute"](a)}function n(a,b){function c(a,b){return"font-family"==b.toLowerCase()?a.replace(/["']/g,""):a}"string"==typeof a&&(a=CKEDITOR.tools.parseCssText(a));"string"==typeof b&&(b=CKEDITOR.tools.parseCssText(b,!0));for(var d in a)if(!(d in b)||c(b[d],d)!=c(a[d],d)&&"inherit"!=a[d]&&"inherit"!=b[d])return!1;return!0}function t(a,b,c){var d=a.document,e=a.getRanges();b=b?this.removeFromRange:this.applyToRange;for(var f,g=e.createIterator();f=
+g.getNextRange();)b.call(this,f,c);a.selectRanges(e);d.removeCustomData("doc_processing_style")}var A={address:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,p:1,pre:1,section:1,header:1,footer:1,nav:1,article:1,aside:1,figure:1,dialog:1,hgroup:1,time:1,meter:1,menu:1,command:1,keygen:1,output:1,progress:1,details:1,datagrid:1,datalist:1},C={a:1,blockquote:1,embed:1,hr:1,img:1,li:1,object:1,ol:1,table:1,td:1,tr:1,th:1,ul:1,dl:1,dt:1,dd:1,form:1,audio:1,video:1},D=/\s*(?:;\s*|$)/,M=/#\((.+?)\)/g,H=CKEDITOR.dom.walker.bookmark(0,
+1),R=CKEDITOR.dom.walker.whitespaces(1);CKEDITOR.style=function(a,b){if("string"==typeof a.type)return new CKEDITOR.style.customHandlers[a.type](a);var c=a.attributes;c&&c.style&&(a.styles=CKEDITOR.tools.extend({},a.styles,CKEDITOR.tools.parseCssText(c.style)),delete c.style);b&&(a=CKEDITOR.tools.clone(a),F(a.attributes,b),F(a.styles,b));c=this.element=a.element?"string"==typeof a.element?a.element.toLowerCase():a.element:"*";this.type=a.type||(A[c]?CKEDITOR.STYLE_BLOCK:C[c]?CKEDITOR.STYLE_OBJECT:
+CKEDITOR.STYLE_INLINE);"object"==typeof this.element&&(this.type=CKEDITOR.STYLE_OBJECT);this._={definition:a}};CKEDITOR.style.prototype={apply:function(a){if(a instanceof CKEDITOR.dom.document)return t.call(this,a.getSelection());if(this.checkApplicable(a.elementPath(),a)){var b=this._.enterMode;b||(this._.enterMode=a.activeEnterMode);t.call(this,a.getSelection(),0,a);this._.enterMode=b}},remove:function(a){if(a instanceof CKEDITOR.dom.document)return t.call(this,a.getSelection(),1);if(this.checkApplicable(a.elementPath(),
+a)){var b=this._.enterMode;b||(this._.enterMode=a.activeEnterMode);t.call(this,a.getSelection(),1,a);this._.enterMode=b}},applyToRange:function(a){this.applyToRange=this.type==CKEDITOR.STYLE_INLINE?b:this.type==CKEDITOR.STYLE_BLOCK?h:this.type==CKEDITOR.STYLE_OBJECT?g:null;return this.applyToRange(a)},removeFromRange:function(a){this.removeFromRange=this.type==CKEDITOR.STYLE_INLINE?c:this.type==CKEDITOR.STYLE_BLOCK?p:this.type==CKEDITOR.STYLE_OBJECT?k:null;return this.removeFromRange(a)},applyToObject:function(a){w(a,
+this)},checkActive:function(a,b){switch(this.type){case CKEDITOR.STYLE_BLOCK:return this.checkElementRemovable(a.block||a.blockLimit,!0,b);case CKEDITOR.STYLE_OBJECT:case CKEDITOR.STYLE_INLINE:for(var c=a.elements,d=0,e;d<c.length;d++)if(e=c[d],this.type!=CKEDITOR.STYLE_INLINE||e!=a.block&&e!=a.blockLimit){if(this.type==CKEDITOR.STYLE_OBJECT){var f=e.getName();if(!("string"==typeof this.element?f==this.element:f in this.element))continue}if(this.checkElementRemovable(e,!0,b))return!0}}return!1},checkApplicable:function(a,
+b,c){b&&b instanceof CKEDITOR.filter&&(c=b);if(c&&!c.check(this))return!1;switch(this.type){case CKEDITOR.STYLE_OBJECT:return!!a.contains(this.element);case CKEDITOR.STYLE_BLOCK:return!!a.blockLimit.getDtd()[this.element]}return!0},checkElementMatch:function(a,b){var c=this._.definition;if(!a||!c.ignoreReadonly&&a.isReadOnly())return!1;var d=a.getName();if("string"==typeof this.element?d==this.element:d in this.element){if(!b&&!a.hasAttributes())return!0;if(d=c._AC)c=d;else{var d={},e=0,f=c.attributes;
+if(f)for(var g in f)e++,d[g]=f[g];if(g=CKEDITOR.style.getStyleText(c))d.style||e++,d.style=g;d._length=e;c=c._AC=d}if(c._length){for(var h in c)if("_length"!=h)if(d=a.getAttribute(h)||"","style"==h?n(c[h],d):c[h]==d){if(!b)return!0}else if(b)return!1;if(b)return!0}else return!0}return!1},checkElementRemovable:function(a,b,c){if(this.checkElementMatch(a,b,c))return!0;if(b=l(this)[a.getName()]){var d;if(!(b=b.attributes))return!0;for(c=0;c<b.length;c++)if(d=b[c][0],d=a.getAttribute(d)){var e=b[c][1];
+if(null===e)return!0;if("string"==typeof e){if(d==e)return!0}else if(e.test(d))return!0}}return!1},buildPreview:function(a){var b=this._.definition,c=[],d=b.element;"bdo"==d&&(d="span");var c=["\x3c",d],e=b.attributes;if(e)for(var f in e)c.push(" ",f,'\x3d"',e[f],'"');(e=CKEDITOR.style.getStyleText(b))&&c.push(' style\x3d"',e,'"');c.push("\x3e",a||b.name,"\x3c/",d,"\x3e");return c.join("")},getDefinition:function(){return this._.definition}};CKEDITOR.style.getStyleText=function(a){var b=a._ST;if(b)return b;
+var b=a.styles,c=a.attributes&&a.attributes.style||"",d="";c.length&&(c=c.replace(D,";"));for(var e in b){var f=b[e],g=(e+":"+f).replace(D,";");"inherit"==f?d+=g:c+=g}c.length&&(c=CKEDITOR.tools.normalizeCssText(c,!0));return a._ST=c+d};CKEDITOR.style.customHandlers={};CKEDITOR.style.addCustomHandler=function(a){var b=function(a){this._={definition:a};this.setup&&this.setup(a)};b.prototype=CKEDITOR.tools.extend(CKEDITOR.tools.prototypedCopy(CKEDITOR.style.prototype),{assignedTo:CKEDITOR.STYLE_OBJECT},
+a,!0);return this.customHandlers[a.type]=b};var Q=CKEDITOR.POSITION_PRECEDING|CKEDITOR.POSITION_IDENTICAL|CKEDITOR.POSITION_IS_CONTAINED,P=CKEDITOR.POSITION_FOLLOWING|CKEDITOR.POSITION_IDENTICAL|CKEDITOR.POSITION_IS_CONTAINED})();CKEDITOR.styleCommand=function(a,d){this.requiredContent=this.allowedContent=this.style=a;CKEDITOR.tools.extend(this,d,!0)};
+CKEDITOR.styleCommand.prototype.exec=function(a){a.focus();this.state==CKEDITOR.TRISTATE_OFF?a.applyStyle(this.style):this.state==CKEDITOR.TRISTATE_ON&&a.removeStyle(this.style)};CKEDITOR.stylesSet=new CKEDITOR.resourceManager("","stylesSet");CKEDITOR.addStylesSet=CKEDITOR.tools.bind(CKEDITOR.stylesSet.add,CKEDITOR.stylesSet);CKEDITOR.loadStylesSet=function(a,d,b){CKEDITOR.stylesSet.addExternal(a,d,"");CKEDITOR.stylesSet.load(a,b)};
+CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{attachStyleStateChange:function(a,d){var b=this._.styleStateChangeCallbacks;b||(b=this._.styleStateChangeCallbacks=[],this.on("selectionChange",function(a){for(var d=0;d<b.length;d++){var g=b[d],k=g.style.checkActive(a.data.path,this)?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF;g.fn.call(this,k)}}));b.push({style:a,fn:d})},applyStyle:function(a){a.apply(this)},removeStyle:function(a){a.remove(this)},getStylesSet:function(a){if(this._.stylesDefinitions)a(this._.stylesDefinitions);
+else{var d=this,b=d.config.stylesCombo_stylesSet||d.config.stylesSet;if(!1===b)a(null);else if(b instanceof Array)d._.stylesDefinitions=b,a(b);else{b||(b="default");var b=b.split(":"),c=b[0];CKEDITOR.stylesSet.addExternal(c,b[1]?b.slice(1).join(":"):CKEDITOR.getUrl("styles.js"),"");CKEDITOR.stylesSet.load(c,function(b){d._.stylesDefinitions=b[c];a(d._.stylesDefinitions)})}}}});
+CKEDITOR.dom.comment=function(a,d){"string"==typeof a&&(a=(d?d.$:document).createComment(a));CKEDITOR.dom.domObject.call(this,a)};CKEDITOR.dom.comment.prototype=new CKEDITOR.dom.node;CKEDITOR.tools.extend(CKEDITOR.dom.comment.prototype,{type:CKEDITOR.NODE_COMMENT,getOuterHtml:function(){return"\x3c!--"+this.$.nodeValue+"--\x3e"}});"use strict";
+(function(){var a={},d={},b;for(b in CKEDITOR.dtd.$blockLimit)b in CKEDITOR.dtd.$list||(a[b]=1);for(b in CKEDITOR.dtd.$block)b in CKEDITOR.dtd.$blockLimit||b in CKEDITOR.dtd.$empty||(d[b]=1);CKEDITOR.dom.elementPath=function(b,e){var g=null,k=null,h=[],p=b,r;e=e||b.getDocument().getBody();do if(p.type==CKEDITOR.NODE_ELEMENT){h.push(p);if(!this.lastElement&&(this.lastElement=p,p.is(CKEDITOR.dtd.$object)||"false"==p.getAttribute("contenteditable")))continue;if(p.equals(e))break;if(!k&&(r=p.getName(),
+"true"==p.getAttribute("contenteditable")?k=p:!g&&d[r]&&(g=p),a[r])){if(r=!g&&"div"==r){a:{r=p.getChildren();for(var f=0,B=r.count();f<B;f++){var u=r.getItem(f);if(u.type==CKEDITOR.NODE_ELEMENT&&CKEDITOR.dtd.$block[u.getName()]){r=!0;break a}}r=!1}r=!r}r?g=p:k=p}}while(p=p.getParent());k||(k=e);this.block=g;this.blockLimit=k;this.root=e;this.elements=h}})();
+CKEDITOR.dom.elementPath.prototype={compare:function(a){var d=this.elements;a=a&&a.elements;if(!a||d.length!=a.length)return!1;for(var b=0;b<d.length;b++)if(!d[b].equals(a[b]))return!1;return!0},contains:function(a,d,b){var c;"string"==typeof a&&(c=function(b){return b.getName()==a});a instanceof CKEDITOR.dom.element?c=function(b){return b.equals(a)}:CKEDITOR.tools.isArray(a)?c=function(b){return-1<CKEDITOR.tools.indexOf(a,b.getName())}:"function"==typeof a?c=a:"object"==typeof a&&(c=function(b){return b.getName()in
+a});var e=this.elements,g=e.length;d&&g--;b&&(e=Array.prototype.slice.call(e,0),e.reverse());for(d=0;d<g;d++)if(c(e[d]))return e[d];return null},isContextFor:function(a){var d;return a in CKEDITOR.dtd.$block?(d=this.contains(CKEDITOR.dtd.$intermediate)||this.root.equals(this.block)&&this.block||this.blockLimit,!!d.getDtd()[a]):!0},direction:function(){return(this.block||this.blockLimit||this.root).getDirection(1)}};
+CKEDITOR.dom.text=function(a,d){"string"==typeof a&&(a=(d?d.$:document).createTextNode(a));this.$=a};CKEDITOR.dom.text.prototype=new CKEDITOR.dom.node;
+CKEDITOR.tools.extend(CKEDITOR.dom.text.prototype,{type:CKEDITOR.NODE_TEXT,getLength:function(){return this.$.nodeValue.length},getText:function(){return this.$.nodeValue},setText:function(a){this.$.nodeValue=a},split:function(a){var d=this.$.parentNode,b=d.childNodes.length,c=this.getLength(),e=this.getDocument(),g=new CKEDITOR.dom.text(this.$.splitText(a),e);d.childNodes.length==b&&(a>=c?(g=e.createText(""),g.insertAfter(this)):(a=e.createText(""),a.insertAfter(g),a.remove()));return g},substring:function(a,
+d){return"number"!=typeof d?this.$.nodeValue.substr(a):this.$.nodeValue.substring(a,d)}});
+(function(){function a(a,c,d){var g=a.serializable,k=c[d?"endContainer":"startContainer"],h=d?"endOffset":"startOffset",p=g?c.document.getById(a.startNode):a.startNode;a=g?c.document.getById(a.endNode):a.endNode;k.equals(p.getPrevious())?(c.startOffset=c.startOffset-k.getLength()-a.getPrevious().getLength(),k=a.getNext()):k.equals(a.getPrevious())&&(c.startOffset-=k.getLength(),k=a.getNext());k.equals(p.getParent())&&c[h]++;k.equals(a.getParent())&&c[h]++;c[d?"endContainer":"startContainer"]=k;return c}
+CKEDITOR.dom.rangeList=function(a){if(a instanceof CKEDITOR.dom.rangeList)return a;a?a instanceof CKEDITOR.dom.range&&(a=[a]):a=[];return CKEDITOR.tools.extend(a,d)};var d={createIterator:function(){var a=this,c=CKEDITOR.dom.walker.bookmark(),d=[],g;return{getNextRange:function(k){g=void 0===g?0:g+1;var h=a[g];if(h&&1<a.length){if(!g)for(var p=a.length-1;0<=p;p--)d.unshift(a[p].createBookmark(!0));if(k)for(var r=0;a[g+r+1];){var f=h.document;k=0;p=f.getById(d[r].endNode);for(f=f.getById(d[r+1].startNode);;){p=
+p.getNextSourceNode(!1);if(f.equals(p))k=1;else if(c(p)||p.type==CKEDITOR.NODE_ELEMENT&&p.isBlockBoundary())continue;break}if(!k)break;r++}for(h.moveToBookmark(d.shift());r--;)p=a[++g],p.moveToBookmark(d.shift()),h.setEnd(p.endContainer,p.endOffset)}return h}}},createBookmarks:function(b){for(var c=[],d,g=0;g<this.length;g++){c.push(d=this[g].createBookmark(b,!0));for(var k=g+1;k<this.length;k++)this[k]=a(d,this[k]),this[k]=a(d,this[k],!0)}return c},createBookmarks2:function(a){for(var c=[],d=0;d<
+this.length;d++)c.push(this[d].createBookmark2(a));return c},moveToBookmarks:function(a){for(var c=0;c<this.length;c++)this[c].moveToBookmark(a[c])}}})();
+(function(){function a(){return CKEDITOR.getUrl(CKEDITOR.skinName.split(",")[1]||"skins/"+CKEDITOR.skinName.split(",")[0]+"/")}function d(b){var c=CKEDITOR.skin["ua_"+b],d=CKEDITOR.env;if(c)for(var c=c.split(",").sort(function(a,b){return a>b?-1:1}),e=0,g;e<c.length;e++)if(g=c[e],d.ie&&(g.replace(/^ie/,"")==d.version||d.quirks&&"iequirks"==g)&&(g="ie"),d[g]){b+="_"+c[e];break}return CKEDITOR.getUrl(a()+b+".css")}function b(a,b){g[a]||(CKEDITOR.document.appendStyleSheet(d(a)),g[a]=1);b&&b()}function c(a){var b=
+a.getById(k);b||(b=a.getHead().append("style"),b.setAttribute("id",k),b.setAttribute("type","text/css"));return b}function e(a,b,c){var d,e,g;if(CKEDITOR.env.webkit)for(b=b.split("}").slice(0,-1),e=0;e<b.length;e++)b[e]=b[e].split("{");for(var h=0;h<a.length;h++)if(CKEDITOR.env.webkit)for(e=0;e<b.length;e++){g=b[e][1];for(d=0;d<c.length;d++)g=g.replace(c[d][0],c[d][1]);a[h].$.sheet.addRule(b[e][0],g)}else{g=b;for(d=0;d<c.length;d++)g=g.replace(c[d][0],c[d][1]);CKEDITOR.env.ie&&11>CKEDITOR.env.version?
+a[h].$.styleSheet.cssText+=g:a[h].$.innerHTML+=g}}var g={};CKEDITOR.skin={path:a,loadPart:function(c,d){CKEDITOR.skin.name!=CKEDITOR.skinName.split(",")[0]?CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(a()+"skin.js"),function(){b(c,d)}):b(c,d)},getPath:function(a){return CKEDITOR.getUrl(d(a))},icons:{},addIcon:function(a,b,c,d){a=a.toLowerCase();this.icons[a]||(this.icons[a]={path:b,offset:c||0,bgsize:d||"16px"})},getIconStyle:function(a,b,c,d,e){var g;a&&(a=a.toLowerCase(),b&&(g=this.icons[a+"-rtl"]),
+g||(g=this.icons[a]));a=c||g&&g.path||"";d=d||g&&g.offset;e=e||g&&g.bgsize||"16px";a&&(a=a.replace(/'/g,"\\'"));return a&&"background-image:url('"+CKEDITOR.getUrl(a)+"');background-position:0 "+d+"px;background-size:"+e+";"}};CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{getUiColor:function(){return this.uiColor},setUiColor:function(a){var b=c(CKEDITOR.document);return(this.setUiColor=function(a){this.uiColor=a;var c=CKEDITOR.skin.chameleon,d="",g="";"function"==typeof c&&(d=c(this,"editor"),g=
+c(this,"panel"));a=[[p,a]];e([b],d,a);e(h,g,a)}).call(this,a)}});var k="cke_ui_color",h=[],p=/\$color/g;CKEDITOR.on("instanceLoaded",function(a){if(!CKEDITOR.env.ie||!CKEDITOR.env.quirks){var b=a.editor;a=function(a){a=(a.data[0]||a.data).element.getElementsByTag("iframe").getItem(0).getFrameDocument();if(!a.getById("cke_ui_color")){a=c(a);h.push(a);var d=b.getUiColor();d&&e([a],CKEDITOR.skin.chameleon(b,"panel"),[[p,d]])}};b.on("panelShow",a);b.on("menuShow",a);b.config.uiColor&&b.setUiColor(b.config.uiColor)}})})();
+(function(){if(CKEDITOR.env.webkit)CKEDITOR.env.hc=!1;else{var a=CKEDITOR.dom.element.createFromHtml('\x3cdiv style\x3d"width:0;height:0;position:absolute;left:-10000px;border:1px solid;border-color:red blue"\x3e\x3c/div\x3e',CKEDITOR.document);a.appendTo(CKEDITOR.document.getHead());try{var d=a.getComputedStyle("border-top-color"),b=a.getComputedStyle("border-right-color");CKEDITOR.env.hc=!(!d||d!=b)}catch(c){CKEDITOR.env.hc=!1}a.remove()}CKEDITOR.env.hc&&(CKEDITOR.env.cssClass+=" cke_hc");CKEDITOR.document.appendStyleText(".cke{visibility:hidden;}");
+CKEDITOR.status="loaded";CKEDITOR.fireOnce("loaded");if(a=CKEDITOR._.pending)for(delete CKEDITOR._.pending,d=0;d<a.length;d++)CKEDITOR.editor.prototype.constructor.apply(a[d][0],a[d][1]),CKEDITOR.add(a[d][0])})();/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.skin.name="moono";CKEDITOR.skin.ua_editor="ie,iequirks,ie7,ie8,gecko";CKEDITOR.skin.ua_dialog="ie,iequirks,ie7,ie8";
+CKEDITOR.skin.chameleon=function(){var b=function(){return function(b,e){for(var a=b.match(/[^#]./g),c=0;3>c;c++){var f=c,d;d=parseInt(a[c],16);d=("0"+(0>e?0|d*(1+e):0|d+(255-d)*e).toString(16)).slice(-2);a[f]=d}return"#"+a.join("")}}(),c=function(){var b=new CKEDITOR.template("background:#{to};background-image:linear-gradient(to bottom,{from},{to});filter:progid:DXImageTransform.Microsoft.gradient(gradientType\x3d0,startColorstr\x3d'{from}',endColorstr\x3d'{to}');");return function(c,a){return b.output({from:c,
+to:a})}}(),f={editor:new CKEDITOR.template("{id}.cke_chrome [border-color:{defaultBorder};] {id} .cke_top [ {defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_bottom [{defaultGradient}border-top-color:{defaultBorder};] {id} .cke_resizer [border-right-color:{ckeResizer}] {id} .cke_dialog_title [{defaultGradient}border-bottom-color:{defaultBorder};] {id} .cke_dialog_footer [{defaultGradient}outline-color:{defaultBorder};border-top-color:{defaultBorder};] {id} .cke_dialog_tab [{lightGradient}border-color:{defaultBorder};] {id} .cke_dialog_tab:hover [{mediumGradient}] {id} .cke_dialog_contents [border-top-color:{defaultBorder};] {id} .cke_dialog_tab_selected, {id} .cke_dialog_tab_selected:hover [background:{dialogTabSelected};border-bottom-color:{dialogTabSelectedBorder};] {id} .cke_dialog_body [background:{dialogBody};border-color:{defaultBorder};] {id} .cke_toolgroup [{lightGradient}border-color:{defaultBorder};] {id} a.cke_button_off:hover, {id} a.cke_button_off:focus, {id} a.cke_button_off:active [{mediumGradient}] {id} .cke_button_on [{ckeButtonOn}] {id} .cke_toolbar_separator [background-color: {ckeToolbarSeparator};] {id} .cke_combo_button [border-color:{defaultBorder};{lightGradient}] {id} a.cke_combo_button:hover, {id} a.cke_combo_button:focus, {id} .cke_combo_on a.cke_combo_button [border-color:{defaultBorder};{mediumGradient}] {id} .cke_path_item [color:{elementsPathColor};] {id} a.cke_path_item:hover, {id} a.cke_path_item:focus, {id} a.cke_path_item:active [background-color:{elementsPathBg};] {id}.cke_panel [border-color:{defaultBorder};] "),
+panel:new CKEDITOR.template(".cke_panel_grouptitle [{lightGradient}border-color:{defaultBorder};] .cke_menubutton_icon [background-color:{menubuttonIcon};] .cke_menubutton:hover .cke_menubutton_icon, .cke_menubutton:focus .cke_menubutton_icon, .cke_menubutton:active .cke_menubutton_icon [background-color:{menubuttonIconHover};] .cke_menuseparator [background-color:{menubuttonIcon};] a:hover.cke_colorbox, a:focus.cke_colorbox, a:active.cke_colorbox [border-color:{defaultBorder};] a:hover.cke_colorauto, a:hover.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:active.cke_colorauto, a:active.cke_colormore [background-color:{ckeColorauto};border-color:{defaultBorder};] ")};
+return function(g,e){var a=g.uiColor,a={id:"."+g.id,defaultBorder:b(a,-.1),defaultGradient:c(b(a,.9),a),lightGradient:c(b(a,1),b(a,.7)),mediumGradient:c(b(a,.8),b(a,.5)),ckeButtonOn:c(b(a,.6),b(a,.7)),ckeResizer:b(a,-.4),ckeToolbarSeparator:b(a,.5),ckeColorauto:b(a,.8),dialogBody:b(a,.7),dialogTabSelected:c("#FFFFFF","#FFFFFF"),dialogTabSelectedBorder:"#FFF",elementsPathColor:b(a,-.6),elementsPathBg:a,menubuttonIcon:b(a,.5),menubuttonIconHover:b(a,.3)};return f[e].output(a).replace(/\[/g,"{").replace(/\]/g,
+"}")}}();CKEDITOR.plugins.add("dialogui",{onLoad:function(){var h=function(b){this._||(this._={});this._["default"]=this._.initValue=b["default"]||"";this._.required=b.required||!1;for(var a=[this._],d=1;d<arguments.length;d++)a.push(arguments[d]);a.push(!0);CKEDITOR.tools.extend.apply(CKEDITOR.tools,a);return this._},v={build:function(b,a,d){return new CKEDITOR.ui.dialog.textInput(b,a,d)}},n={build:function(b,a,d){return new CKEDITOR.ui.dialog[a.type](b,a,d)}},q={isChanged:function(){return this.getValue()!=
+this.getInitValue()},reset:function(b){this.setValue(this.getInitValue(),b)},setInitValue:function(){this._.initValue=this.getValue()},resetInitValue:function(){this._.initValue=this._["default"]},getInitValue:function(){return this._.initValue}},r=CKEDITOR.tools.extend({},CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,{onChange:function(b,a){this._.domOnChangeRegistered||(b.on("load",function(){this.getInputElement().on("change",function(){b.parts.dialog.isVisible()&&this.fire("change",{value:this.getValue()})},
+this)},this),this._.domOnChangeRegistered=!0);this.on("change",a)}},!0),x=/^on([A-Z]\w+)/,t=function(b){for(var a in b)(x.test(a)||"title"==a||"type"==a)&&delete b[a];return b},w=function(b){b=b.data.getKeystroke();b==CKEDITOR.SHIFT+CKEDITOR.ALT+36?this.setDirectionMarker("ltr"):b==CKEDITOR.SHIFT+CKEDITOR.ALT+35&&this.setDirectionMarker("rtl")};CKEDITOR.tools.extend(CKEDITOR.ui.dialog,{labeledElement:function(b,a,d,f){if(!(4>arguments.length)){var c=h.call(this,a);c.labelId=CKEDITOR.tools.getNextId()+
+"_label";this._.children=[];var e={role:a.role||"presentation"};a.includeLabel&&(e["aria-labelledby"]=c.labelId);CKEDITOR.ui.dialog.uiElement.call(this,b,a,d,"div",null,e,function(){var e=[],g=a.required?" cke_required":"";"horizontal"!=a.labelLayout?e.push('\x3clabel class\x3d"cke_dialog_ui_labeled_label'+g+'" ',' id\x3d"'+c.labelId+'"',c.inputId?' for\x3d"'+c.inputId+'"':"",(a.labelStyle?' style\x3d"'+a.labelStyle+'"':"")+"\x3e",a.label,"\x3c/label\x3e",'\x3cdiv class\x3d"cke_dialog_ui_labeled_content"',
+a.controlStyle?' style\x3d"'+a.controlStyle+'"':"",' role\x3d"presentation"\x3e',f.call(this,b,a),"\x3c/div\x3e"):(g={type:"hbox",widths:a.widths,padding:0,children:[{type:"html",html:'\x3clabel class\x3d"cke_dialog_ui_labeled_label'+g+'" id\x3d"'+c.labelId+'" for\x3d"'+c.inputId+'"'+(a.labelStyle?' style\x3d"'+a.labelStyle+'"':"")+"\x3e"+CKEDITOR.tools.htmlEncode(a.label)+"\x3c/label\x3e"},{type:"html",html:'\x3cspan class\x3d"cke_dialog_ui_labeled_content"'+(a.controlStyle?' style\x3d"'+a.controlStyle+
+'"':"")+"\x3e"+f.call(this,b,a)+"\x3c/span\x3e"}]},CKEDITOR.dialog._.uiElementBuilders.hbox.build(b,g,e));return e.join("")})}},textInput:function(b,a,d){if(!(3>arguments.length)){h.call(this,a);var f=this._.inputId=CKEDITOR.tools.getNextId()+"_textInput",c={"class":"cke_dialog_ui_input_"+a.type,id:f,type:a.type};a.validate&&(this.validate=a.validate);a.maxLength&&(c.maxlength=a.maxLength);a.size&&(c.size=a.size);a.inputStyle&&(c.style=a.inputStyle);var e=this,m=!1;b.on("load",function(){e.getInputElement().on("keydown",
+function(a){13==a.data.getKeystroke()&&(m=!0)});e.getInputElement().on("keyup",function(a){13==a.data.getKeystroke()&&m&&(b.getButton("ok")&&setTimeout(function(){b.getButton("ok").click()},0),m=!1);e.bidi&&w.call(e,a)},null,null,1E3)});CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){var b=['\x3cdiv class\x3d"cke_dialog_ui_input_',a.type,'" role\x3d"presentation"'];a.width&&b.push('style\x3d"width:'+a.width+'" ');b.push("\x3e\x3cinput ");c["aria-labelledby"]=this._.labelId;this._.required&&
+(c["aria-required"]=this._.required);for(var e in c)b.push(e+'\x3d"'+c[e]+'" ');b.push(" /\x3e\x3c/div\x3e");return b.join("")})}},textarea:function(b,a,d){if(!(3>arguments.length)){h.call(this,a);var f=this,c=this._.inputId=CKEDITOR.tools.getNextId()+"_textarea",e={};a.validate&&(this.validate=a.validate);e.rows=a.rows||5;e.cols=a.cols||20;e["class"]="cke_dialog_ui_input_textarea "+(a["class"]||"");"undefined"!=typeof a.inputStyle&&(e.style=a.inputStyle);a.dir&&(e.dir=a.dir);if(f.bidi)b.on("load",
+function(){f.getInputElement().on("keyup",w)},f);CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){e["aria-labelledby"]=this._.labelId;this._.required&&(e["aria-required"]=this._.required);var a=['\x3cdiv class\x3d"cke_dialog_ui_input_textarea" role\x3d"presentation"\x3e\x3ctextarea id\x3d"',c,'" '],b;for(b in e)a.push(b+'\x3d"'+CKEDITOR.tools.htmlEncode(e[b])+'" ');a.push("\x3e",CKEDITOR.tools.htmlEncode(f._["default"]),"\x3c/textarea\x3e\x3c/div\x3e");return a.join("")})}},checkbox:function(b,
+a,d){if(!(3>arguments.length)){var f=h.call(this,a,{"default":!!a["default"]});a.validate&&(this.validate=a.validate);CKEDITOR.ui.dialog.uiElement.call(this,b,a,d,"span",null,null,function(){var c=CKEDITOR.tools.extend({},a,{id:a.id?a.id+"_checkbox":CKEDITOR.tools.getNextId()+"_checkbox"},!0),e=[],d=CKEDITOR.tools.getNextId()+"_label",g={"class":"cke_dialog_ui_checkbox_input",type:"checkbox","aria-labelledby":d};t(c);a["default"]&&(g.checked="checked");"undefined"!=typeof c.inputStyle&&(c.style=c.inputStyle);
+f.checkbox=new CKEDITOR.ui.dialog.uiElement(b,c,e,"input",null,g);e.push(' \x3clabel id\x3d"',d,'" for\x3d"',g.id,'"'+(a.labelStyle?' style\x3d"'+a.labelStyle+'"':"")+"\x3e",CKEDITOR.tools.htmlEncode(a.label),"\x3c/label\x3e");return e.join("")})}},radio:function(b,a,d){if(!(3>arguments.length)){h.call(this,a);this._["default"]||(this._["default"]=this._.initValue=a.items[0][1]);a.validate&&(this.validate=a.validate);var f=[],c=this;a.role="radiogroup";a.includeLabel=!0;CKEDITOR.ui.dialog.labeledElement.call(this,
+b,a,d,function(){for(var e=[],d=[],g=(a.id?a.id:CKEDITOR.tools.getNextId())+"_radio",k=0;k<a.items.length;k++){var l=a.items[k],h=void 0!==l[2]?l[2]:l[0],n=void 0!==l[1]?l[1]:l[0],p=CKEDITOR.tools.getNextId()+"_radio_input",q=p+"_label",p=CKEDITOR.tools.extend({},a,{id:p,title:null,type:null},!0),h=CKEDITOR.tools.extend({},p,{title:h},!0),r={type:"radio","class":"cke_dialog_ui_radio_input",name:g,value:n,"aria-labelledby":q},u=[];c._["default"]==n&&(r.checked="checked");t(p);t(h);"undefined"!=typeof p.inputStyle&&
+(p.style=p.inputStyle);p.keyboardFocusable=!0;f.push(new CKEDITOR.ui.dialog.uiElement(b,p,u,"input",null,r));u.push(" ");new CKEDITOR.ui.dialog.uiElement(b,h,u,"label",null,{id:q,"for":r.id},l[0]);e.push(u.join(""))}new CKEDITOR.ui.dialog.hbox(b,f,e,d);return d.join("")});this._.children=f}},button:function(b,a,d){if(arguments.length){"function"==typeof a&&(a=a(b.getParentEditor()));h.call(this,a,{disabled:a.disabled||!1});CKEDITOR.event.implementOn(this);var f=this;b.on("load",function(){var a=this.getElement();
+(function(){a.on("click",function(a){f.click();a.data.preventDefault()});a.on("keydown",function(a){a.data.getKeystroke()in{32:1}&&(f.click(),a.data.preventDefault())})})();a.unselectable()},this);var c=CKEDITOR.tools.extend({},a);delete c.style;var e=CKEDITOR.tools.getNextId()+"_label";CKEDITOR.ui.dialog.uiElement.call(this,b,c,d,"a",null,{style:a.style,href:"javascript:void(0)",title:a.label,hidefocus:"true","class":a["class"],role:"button","aria-labelledby":e},'\x3cspan id\x3d"'+e+'" class\x3d"cke_dialog_ui_button"\x3e'+
+CKEDITOR.tools.htmlEncode(a.label)+"\x3c/span\x3e")}},select:function(b,a,d){if(!(3>arguments.length)){var f=h.call(this,a);a.validate&&(this.validate=a.validate);f.inputId=CKEDITOR.tools.getNextId()+"_select";CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){var c=CKEDITOR.tools.extend({},a,{id:a.id?a.id+"_select":CKEDITOR.tools.getNextId()+"_select"},!0),e=[],d=[],g={id:f.inputId,"class":"cke_dialog_ui_input_select","aria-labelledby":this._.labelId};e.push('\x3cdiv class\x3d"cke_dialog_ui_input_',
+a.type,'" role\x3d"presentation"');a.width&&e.push('style\x3d"width:'+a.width+'" ');e.push("\x3e");void 0!==a.size&&(g.size=a.size);void 0!==a.multiple&&(g.multiple=a.multiple);t(c);for(var k=0,l;k<a.items.length&&(l=a.items[k]);k++)d.push('\x3coption value\x3d"',CKEDITOR.tools.htmlEncode(void 0!==l[1]?l[1]:l[0]).replace(/"/g,"\x26quot;"),'" /\x3e ',CKEDITOR.tools.htmlEncode(l[0]));"undefined"!=typeof c.inputStyle&&(c.style=c.inputStyle);f.select=new CKEDITOR.ui.dialog.uiElement(b,c,e,"select",null,
+g,d.join(""));e.push("\x3c/div\x3e");return e.join("")})}},file:function(b,a,d){if(!(3>arguments.length)){void 0===a["default"]&&(a["default"]="");var f=CKEDITOR.tools.extend(h.call(this,a),{definition:a,buttons:[]});a.validate&&(this.validate=a.validate);b.on("load",function(){CKEDITOR.document.getById(f.frameId).getParent().addClass("cke_dialog_ui_input_file")});CKEDITOR.ui.dialog.labeledElement.call(this,b,a,d,function(){f.frameId=CKEDITOR.tools.getNextId()+"_fileInput";var b=['\x3ciframe frameborder\x3d"0" allowtransparency\x3d"0" class\x3d"cke_dialog_ui_input_file" role\x3d"presentation" id\x3d"',
+f.frameId,'" title\x3d"',a.label,'" src\x3d"javascript:void('];b.push(CKEDITOR.env.ie?"(function(){"+encodeURIComponent("document.open();("+CKEDITOR.tools.fixDomain+")();document.close();")+"})()":"0");b.push(')"\x3e\x3c/iframe\x3e');return b.join("")})}},fileButton:function(b,a,d){var f=this;if(!(3>arguments.length)){h.call(this,a);a.validate&&(this.validate=a.validate);var c=CKEDITOR.tools.extend({},a),e=c.onClick;c.className=(c.className?c.className+" ":"")+"cke_dialog_ui_button";c.onClick=function(c){var d=
+a["for"];e&&!1===e.call(this,c)||(b.getContentElement(d[0],d[1]).submit(),this.disable())};b.on("load",function(){b.getContentElement(a["for"][0],a["for"][1])._.buttons.push(f)});CKEDITOR.ui.dialog.button.call(this,b,c,d)}},html:function(){var b=/^\s*<[\w:]+\s+([^>]*)?>/,a=/^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/,d=/\/$/;return function(f,c,e){if(!(3>arguments.length)){var m=[],g=c.html;"\x3c"!=g.charAt(0)&&(g="\x3cspan\x3e"+g+"\x3c/span\x3e");var k=c.focus;if(k){var l=this.focus;this.focus=function(){("function"==
+typeof k?k:l).call(this);this.fire("focus")};c.isFocusable&&(this.isFocusable=this.isFocusable);this.keyboardFocusable=!0}CKEDITOR.ui.dialog.uiElement.call(this,f,c,m,"span",null,null,"");m=m.join("").match(b);g=g.match(a)||["","",""];d.test(g[1])&&(g[1]=g[1].slice(0,-1),g[2]="/"+g[2]);e.push([g[1]," ",m[1]||"",g[2]].join(""))}}}(),fieldset:function(b,a,d,f,c){var e=c.label;this._={children:a};CKEDITOR.ui.dialog.uiElement.call(this,b,c,f,"fieldset",null,null,function(){var a=[];e&&a.push("\x3clegend"+
+(c.labelStyle?' style\x3d"'+c.labelStyle+'"':"")+"\x3e"+e+"\x3c/legend\x3e");for(var b=0;b<d.length;b++)a.push(d[b]);return a.join("")})}},!0);CKEDITOR.ui.dialog.html.prototype=new CKEDITOR.ui.dialog.uiElement;CKEDITOR.ui.dialog.labeledElement.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{setLabel:function(b){var a=CKEDITOR.document.getById(this._.labelId);1>a.getChildCount()?(new CKEDITOR.dom.text(b,CKEDITOR.document)).appendTo(a):a.getChild(0).$.nodeValue=b;return this},getLabel:function(){var b=
+CKEDITOR.document.getById(this._.labelId);return!b||1>b.getChildCount()?"":b.getChild(0).getText()},eventProcessors:r},!0);CKEDITOR.ui.dialog.button.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{click:function(){return this._.disabled?!1:this.fire("click",{dialog:this._.dialog})},enable:function(){this._.disabled=!1;var b=this.getElement();b&&b.removeClass("cke_disabled")},disable:function(){this._.disabled=!0;this.getElement().addClass("cke_disabled")},isVisible:function(){return this.getElement().getFirst().isVisible()},
+isEnabled:function(){return!this._.disabled},eventProcessors:CKEDITOR.tools.extend({},CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,{onClick:function(b,a){this.on("click",function(){a.apply(this,arguments)})}},!0),accessKeyUp:function(){this.click()},accessKeyDown:function(){this.focus()},keyboardFocusable:!0},!0);CKEDITOR.ui.dialog.textInput.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return CKEDITOR.document.getById(this._.inputId)},
+focus:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&a.$.focus()},0)},select:function(){var b=this.selectParentTab();setTimeout(function(){var a=b.getInputElement();a&&(a.$.focus(),a.$.select())},0)},accessKeyUp:function(){this.select()},setValue:function(b){if(this.bidi){var a=b&&b.charAt(0);(a="‪"==a?"ltr":"‫"==a?"rtl":null)&&(b=b.slice(1));this.setDirectionMarker(a)}b||(b="");return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply(this,arguments)},
+getValue:function(){var b=CKEDITOR.ui.dialog.uiElement.prototype.getValue.call(this);if(this.bidi&&b){var a=this.getDirectionMarker();a&&(b=("ltr"==a?"‪":"‫")+b)}return b},setDirectionMarker:function(b){var a=this.getInputElement();b?a.setAttributes({dir:b,"data-cke-dir-marker":b}):this.getDirectionMarker()&&a.removeAttributes(["dir","data-cke-dir-marker"])},getDirectionMarker:function(){return this.getInputElement().data("cke-dir-marker")},keyboardFocusable:!0},q,!0);CKEDITOR.ui.dialog.textarea.prototype=
+new CKEDITOR.ui.dialog.textInput;CKEDITOR.ui.dialog.select.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,{getInputElement:function(){return this._.select.getElement()},add:function(b,a,d){var f=new CKEDITOR.dom.element("option",this.getDialog().getParentEditor().document),c=this.getInputElement().$;f.$.text=b;f.$.value=void 0===a||null===a?b:a;void 0===d||null===d?CKEDITOR.env.ie?c.add(f.$):c.add(f.$,null):c.add(f.$,d);return this},remove:function(b){this.getInputElement().$.remove(b);
+return this},clear:function(){for(var b=this.getInputElement().$;0<b.length;)b.remove(0);return this},keyboardFocusable:!0},q,!0);CKEDITOR.ui.dialog.checkbox.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{getInputElement:function(){return this._.checkbox.getElement()},setValue:function(b,a){this.getInputElement().$.checked=b;!a&&this.fire("change",{value:b})},getValue:function(){return this.getInputElement().$.checked},accessKeyUp:function(){this.setValue(!this.getValue())},eventProcessors:{onChange:function(b,
+a){if(!CKEDITOR.env.ie||8<CKEDITOR.env.version)return r.onChange.apply(this,arguments);b.on("load",function(){var a=this._.checkbox.getElement();a.on("propertychange",function(b){b=b.data.$;"checked"==b.propertyName&&this.fire("change",{value:a.$.checked})},this)},this);this.on("change",a);return null}},keyboardFocusable:!0},q,!0);CKEDITOR.ui.dialog.radio.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{setValue:function(b,a){for(var d=this._.children,f,c=0;c<d.length&&(f=d[c]);c++)f.getElement().$.checked=
+f.getValue()==b;!a&&this.fire("change",{value:b})},getValue:function(){for(var b=this._.children,a=0;a<b.length;a++)if(b[a].getElement().$.checked)return b[a].getValue();return null},accessKeyUp:function(){var b=this._.children,a;for(a=0;a<b.length;a++)if(b[a].getElement().$.checked){b[a].getElement().focus();return}b[0].getElement().focus()},eventProcessors:{onChange:function(b,a){if(!CKEDITOR.env.ie||8<CKEDITOR.env.version)return r.onChange.apply(this,arguments);b.on("load",function(){for(var a=
+this._.children,b=this,c=0;c<a.length;c++)a[c].getElement().on("propertychange",function(a){a=a.data.$;"checked"==a.propertyName&&this.$.checked&&b.fire("change",{value:this.getAttribute("value")})})},this);this.on("change",a);return null}}},q,!0);CKEDITOR.ui.dialog.file.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.labeledElement,q,{getInputElement:function(){var b=CKEDITOR.document.getById(this._.frameId).getFrameDocument();return 0<b.$.forms.length?new CKEDITOR.dom.element(b.$.forms[0].elements[0]):
+this.getElement()},submit:function(){this.getInputElement().getParent().$.submit();return this},getAction:function(){return this.getInputElement().getParent().$.action},registerEvents:function(b){var a=/^on([A-Z]\w+)/,d,f=function(a,b,c,d){a.on("formLoaded",function(){a.getInputElement().on(c,d,a)})},c;for(c in b)if(d=c.match(a))this.eventProcessors[c]?this.eventProcessors[c].call(this,this._.dialog,b[c]):f(this,this._.dialog,d[1].toLowerCase(),b[c]);return this},reset:function(){function b(){d.$.open();
+var b="";f.size&&(b=f.size-(CKEDITOR.env.ie?7:0));var h=a.frameId+"_input";d.$.write(['\x3chtml dir\x3d"'+g+'" lang\x3d"'+k+'"\x3e\x3chead\x3e\x3ctitle\x3e\x3c/title\x3e\x3c/head\x3e\x3cbody style\x3d"margin: 0; overflow: hidden; background: transparent;"\x3e','\x3cform enctype\x3d"multipart/form-data" method\x3d"POST" dir\x3d"'+g+'" lang\x3d"'+k+'" action\x3d"',CKEDITOR.tools.htmlEncode(f.action),'"\x3e\x3clabel id\x3d"',a.labelId,'" for\x3d"',h,'" style\x3d"display:none"\x3e',CKEDITOR.tools.htmlEncode(f.label),
+'\x3c/label\x3e\x3cinput style\x3d"width:100%" id\x3d"',h,'" aria-labelledby\x3d"',a.labelId,'" type\x3d"file" name\x3d"',CKEDITOR.tools.htmlEncode(f.id||"cke_upload"),'" size\x3d"',CKEDITOR.tools.htmlEncode(0<b?b:""),'" /\x3e\x3c/form\x3e\x3c/body\x3e\x3c/html\x3e\x3cscript\x3e',CKEDITOR.env.ie?"("+CKEDITOR.tools.fixDomain+")();":"","window.parent.CKEDITOR.tools.callFunction("+e+");","window.onbeforeunload \x3d function() {window.parent.CKEDITOR.tools.callFunction("+m+")}","\x3c/script\x3e"].join(""));
+d.$.close();for(b=0;b<c.length;b++)c[b].enable()}var a=this._,d=CKEDITOR.document.getById(a.frameId).getFrameDocument(),f=a.definition,c=a.buttons,e=this.formLoadedNumber,m=this.formUnloadNumber,g=a.dialog._.editor.lang.dir,k=a.dialog._.editor.langCode;e||(e=this.formLoadedNumber=CKEDITOR.tools.addFunction(function(){this.fire("formLoaded")},this),m=this.formUnloadNumber=CKEDITOR.tools.addFunction(function(){this.getInputElement().clearCustomData()},this),this.getDialog()._.editor.on("destroy",function(){CKEDITOR.tools.removeFunction(e);
+CKEDITOR.tools.removeFunction(m)}));CKEDITOR.env.gecko?setTimeout(b,500):b()},getValue:function(){return this.getInputElement().$.value||""},setInitValue:function(){this._.initValue=""},eventProcessors:{onChange:function(b,a){this._.domOnChangeRegistered||(this.on("formLoaded",function(){this.getInputElement().on("change",function(){this.fire("change",{value:this.getValue()})},this)},this),this._.domOnChangeRegistered=!0);this.on("change",a)}},keyboardFocusable:!0},!0);CKEDITOR.ui.dialog.fileButton.prototype=
+new CKEDITOR.ui.dialog.button;CKEDITOR.ui.dialog.fieldset.prototype=CKEDITOR.tools.clone(CKEDITOR.ui.dialog.hbox.prototype);CKEDITOR.dialog.addUIElement("text",v);CKEDITOR.dialog.addUIElement("password",v);CKEDITOR.dialog.addUIElement("textarea",n);CKEDITOR.dialog.addUIElement("checkbox",n);CKEDITOR.dialog.addUIElement("radio",n);CKEDITOR.dialog.addUIElement("button",n);CKEDITOR.dialog.addUIElement("select",n);CKEDITOR.dialog.addUIElement("file",n);CKEDITOR.dialog.addUIElement("fileButton",n);CKEDITOR.dialog.addUIElement("html",
+n);CKEDITOR.dialog.addUIElement("fieldset",{build:function(b,a,d){for(var f=a.children,c,e=[],h=[],g=0;g<f.length&&(c=f[g]);g++){var k=[];e.push(k);h.push(CKEDITOR.dialog._.uiElementBuilders[c.type].build(b,c,k))}return new CKEDITOR.ui.dialog[a.type](b,h,e,d,a)}})}});CKEDITOR.DIALOG_RESIZE_NONE=0;CKEDITOR.DIALOG_RESIZE_WIDTH=1;CKEDITOR.DIALOG_RESIZE_HEIGHT=2;CKEDITOR.DIALOG_RESIZE_BOTH=3;CKEDITOR.DIALOG_STATE_IDLE=1;CKEDITOR.DIALOG_STATE_BUSY=2;
+(function(){function x(){for(var a=this._.tabIdList.length,b=CKEDITOR.tools.indexOf(this._.tabIdList,this._.currentTabId)+a,c=b-1;c>b-a;c--)if(this._.tabs[this._.tabIdList[c%a]][0].$.offsetHeight)return this._.tabIdList[c%a];return null}function A(){for(var a=this._.tabIdList.length,b=CKEDITOR.tools.indexOf(this._.tabIdList,this._.currentTabId),c=b+1;c<b+a;c++)if(this._.tabs[this._.tabIdList[c%a]][0].$.offsetHeight)return this._.tabIdList[c%a];return null}function K(a,b){for(var c=a.$.getElementsByTagName("input"),
+e=0,d=c.length;e<d;e++){var f=new CKEDITOR.dom.element(c[e]);"text"==f.getAttribute("type").toLowerCase()&&(b?(f.setAttribute("value",f.getCustomData("fake_value")||""),f.removeCustomData("fake_value")):(f.setCustomData("fake_value",f.getAttribute("value")),f.setAttribute("value","")))}}function T(a,b){var c=this.getInputElement();c&&(a?c.removeAttribute("aria-invalid"):c.setAttribute("aria-invalid",!0));a||(this.select?this.select():this.focus());b&&alert(b);this.fire("validated",{valid:a,msg:b})}
+function U(){var a=this.getInputElement();a&&a.removeAttribute("aria-invalid")}function V(a){var b=CKEDITOR.dom.element.createFromHtml(CKEDITOR.addTemplate("dialog",W).output({id:CKEDITOR.tools.getNextNumber(),editorId:a.id,langDir:a.lang.dir,langCode:a.langCode,editorDialogClass:"cke_editor_"+a.name.replace(/\./g,"\\.")+"_dialog",closeTitle:a.lang.common.close,hidpi:CKEDITOR.env.hidpi?"cke_hidpi":""})),c=b.getChild([0,0,0,0,0]),e=c.getChild(0),d=c.getChild(1);a.plugins.clipboard&&CKEDITOR.plugins.clipboard.preventDefaultDropOnElement(c);
+!CKEDITOR.env.ie||CKEDITOR.env.quirks||CKEDITOR.env.edge||(a="javascript:void(function(){"+encodeURIComponent("document.open();("+CKEDITOR.tools.fixDomain+")();document.close();")+"}())",CKEDITOR.dom.element.createFromHtml('\x3ciframe frameBorder\x3d"0" class\x3d"cke_iframe_shim" src\x3d"'+a+'" tabIndex\x3d"-1"\x3e\x3c/iframe\x3e').appendTo(c.getParent()));e.unselectable();d.unselectable();return{element:b,parts:{dialog:b.getChild(0),title:e,close:d,tabs:c.getChild(2),contents:c.getChild([3,0,0,0]),
+footer:c.getChild([3,0,1,0])}}}function L(a,b,c){this.element=b;this.focusIndex=c;this.tabIndex=0;this.isFocusable=function(){return!b.getAttribute("disabled")&&b.isVisible()};this.focus=function(){a._.currentFocusIndex=this.focusIndex;this.element.focus()};b.on("keydown",function(a){a.data.getKeystroke()in{32:1,13:1}&&this.fire("click")});b.on("focus",function(){this.fire("mouseover")});b.on("blur",function(){this.fire("mouseout")})}function X(a){function b(){a.layout()}var c=CKEDITOR.document.getWindow();
+c.on("resize",b);a.on("hide",function(){c.removeListener("resize",b)})}function M(a,b){this._={dialog:a};CKEDITOR.tools.extend(this,b)}function Y(a){function b(b){var c=a.getSize(),k=CKEDITOR.document.getWindow().getViewPaneSize(),q=b.data.$.screenX,n=b.data.$.screenY,r=q-e.x,l=n-e.y;e={x:q,y:n};d.x+=r;d.y+=l;a.move(d.x+h[3]<g?-h[3]:d.x-h[1]>k.width-c.width-g?k.width-c.width+("rtl"==f.lang.dir?0:h[1]):d.x,d.y+h[0]<g?-h[0]:d.y-h[2]>k.height-c.height-g?k.height-c.height+h[2]:d.y,1);b.data.preventDefault()}
+function c(){CKEDITOR.document.removeListener("mousemove",b);CKEDITOR.document.removeListener("mouseup",c);if(CKEDITOR.env.ie6Compat){var a=u.getChild(0).getFrameDocument();a.removeListener("mousemove",b);a.removeListener("mouseup",c)}}var e=null,d=null,f=a.getParentEditor(),g=f.config.dialog_magnetDistance,h=CKEDITOR.skin.margins||[0,0,0,0];"undefined"==typeof g&&(g=20);a.parts.title.on("mousedown",function(g){e={x:g.data.$.screenX,y:g.data.$.screenY};CKEDITOR.document.on("mousemove",b);CKEDITOR.document.on("mouseup",
+c);d=a.getPosition();if(CKEDITOR.env.ie6Compat){var f=u.getChild(0).getFrameDocument();f.on("mousemove",b);f.on("mouseup",c)}g.data.preventDefault()},a)}function Z(a){function b(b){var c="rtl"==f.lang.dir,n=k.width,q=k.height,G=n+(b.data.$.screenX-m.x)*(c?-1:1)*(a._.moved?1:2),H=q+(b.data.$.screenY-m.y)*(a._.moved?1:2),B=a._.element.getFirst(),B=c&&B.getComputedStyle("right"),C=a.getPosition();C.y+H>p.height&&(H=p.height-C.y);(c?B:C.x)+G>p.width&&(G=p.width-(c?B:C.x));if(d==CKEDITOR.DIALOG_RESIZE_WIDTH||
+d==CKEDITOR.DIALOG_RESIZE_BOTH)n=Math.max(e.minWidth||0,G-g);if(d==CKEDITOR.DIALOG_RESIZE_HEIGHT||d==CKEDITOR.DIALOG_RESIZE_BOTH)q=Math.max(e.minHeight||0,H-h);a.resize(n,q);a._.moved||a.layout();b.data.preventDefault()}function c(){CKEDITOR.document.removeListener("mouseup",c);CKEDITOR.document.removeListener("mousemove",b);q&&(q.remove(),q=null);if(CKEDITOR.env.ie6Compat){var a=u.getChild(0).getFrameDocument();a.removeListener("mouseup",c);a.removeListener("mousemove",b)}}var e=a.definition,d=e.resizable;
+if(d!=CKEDITOR.DIALOG_RESIZE_NONE){var f=a.getParentEditor(),g,h,p,m,k,q,n=CKEDITOR.tools.addFunction(function(d){k=a.getSize();var e=a.parts.contents;e.$.getElementsByTagName("iframe").length&&(q=CKEDITOR.dom.element.createFromHtml('\x3cdiv class\x3d"cke_dialog_resize_cover" style\x3d"height: 100%; position: absolute; width: 100%;"\x3e\x3c/div\x3e'),e.append(q));h=k.height-a.parts.contents.getSize("height",!(CKEDITOR.env.gecko||CKEDITOR.env.ie&&CKEDITOR.env.quirks));g=k.width-a.parts.contents.getSize("width",
+1);m={x:d.screenX,y:d.screenY};p=CKEDITOR.document.getWindow().getViewPaneSize();CKEDITOR.document.on("mousemove",b);CKEDITOR.document.on("mouseup",c);CKEDITOR.env.ie6Compat&&(e=u.getChild(0).getFrameDocument(),e.on("mousemove",b),e.on("mouseup",c));d.preventDefault&&d.preventDefault()});a.on("load",function(){var b="";d==CKEDITOR.DIALOG_RESIZE_WIDTH?b=" cke_resizer_horizontal":d==CKEDITOR.DIALOG_RESIZE_HEIGHT&&(b=" cke_resizer_vertical");b=CKEDITOR.dom.element.createFromHtml('\x3cdiv class\x3d"cke_resizer'+
+b+" cke_resizer_"+f.lang.dir+'" title\x3d"'+CKEDITOR.tools.htmlEncode(f.lang.common.resize)+'" onmousedown\x3d"CKEDITOR.tools.callFunction('+n+', event )"\x3e'+("ltr"==f.lang.dir?"◢":"◣")+"\x3c/div\x3e");a.parts.footer.append(b,1)});f.on("destroy",function(){CKEDITOR.tools.removeFunction(n)})}}function I(a){a.data.preventDefault(1)}function N(a){var b=CKEDITOR.document.getWindow(),c=a.config,e=CKEDITOR.skinName||a.config.skin,d=c.dialog_backgroundCoverColor||("moono-lisa"==e?"black":"white"),e=c.dialog_backgroundCoverOpacity,
+f=c.baseFloatZIndex,c=CKEDITOR.tools.genKey(d,e,f),g=z[c];g?g.show():(f=['\x3cdiv tabIndex\x3d"-1" style\x3d"position: ',CKEDITOR.env.ie6Compat?"absolute":"fixed","; z-index: ",f,"; top: 0px; left: 0px; ",CKEDITOR.env.ie6Compat?"":"background-color: "+d,'" class\x3d"cke_dialog_background_cover"\x3e'],CKEDITOR.env.ie6Compat&&(d="\x3chtml\x3e\x3cbody style\x3d\\'background-color:"+d+";\\'\x3e\x3c/body\x3e\x3c/html\x3e",f.push('\x3ciframe hidefocus\x3d"true" frameborder\x3d"0" id\x3d"cke_dialog_background_iframe" src\x3d"javascript:'),
+f.push("void((function(){"+encodeURIComponent("document.open();("+CKEDITOR.tools.fixDomain+")();document.write( '"+d+"' );document.close();")+"})())"),f.push('" style\x3d"position:absolute;left:0;top:0;width:100%;height: 100%;filter: progid:DXImageTransform.Microsoft.Alpha(opacity\x3d0)"\x3e\x3c/iframe\x3e')),f.push("\x3c/div\x3e"),g=CKEDITOR.dom.element.createFromHtml(f.join("")),g.setOpacity(void 0!==e?e:.5),g.on("keydown",I),g.on("keypress",I),g.on("keyup",I),g.appendTo(CKEDITOR.document.getBody()),
+z[c]=g);a.focusManager.add(g);u=g;a=function(){var a=b.getViewPaneSize();g.setStyles({width:a.width+"px",height:a.height+"px"})};var h=function(){var a=b.getScrollPosition(),c=CKEDITOR.dialog._.currentTop;g.setStyles({left:a.x+"px",top:a.y+"px"});if(c){do a=c.getPosition(),c.move(a.x,a.y);while(c=c._.parentDialog)}};J=a;b.on("resize",a);a();CKEDITOR.env.mac&&CKEDITOR.env.webkit||g.focus();if(CKEDITOR.env.ie6Compat){var p=function(){h();arguments.callee.prevScrollHandler.apply(this,arguments)};b.$.setTimeout(function(){p.prevScrollHandler=
+window.onscroll||function(){};window.onscroll=p},0);h()}}function O(a){u&&(a.focusManager.remove(u),a=CKEDITOR.document.getWindow(),u.hide(),a.removeListener("resize",J),CKEDITOR.env.ie6Compat&&a.$.setTimeout(function(){window.onscroll=window.onscroll&&window.onscroll.prevScrollHandler||null},0),J=null)}var v=CKEDITOR.tools.cssLength,W='\x3cdiv class\x3d"cke_reset_all {editorId} {editorDialogClass} {hidpi}" dir\x3d"{langDir}" lang\x3d"{langCode}" role\x3d"dialog" aria-labelledby\x3d"cke_dialog_title_{id}"\x3e\x3ctable class\x3d"cke_dialog '+
+CKEDITOR.env.cssClass+' cke_{langDir}" style\x3d"position:absolute" role\x3d"presentation"\x3e\x3ctr\x3e\x3ctd role\x3d"presentation"\x3e\x3cdiv class\x3d"cke_dialog_body" role\x3d"presentation"\x3e\x3cdiv id\x3d"cke_dialog_title_{id}" class\x3d"cke_dialog_title" role\x3d"presentation"\x3e\x3c/div\x3e\x3ca id\x3d"cke_dialog_close_button_{id}" class\x3d"cke_dialog_close_button" href\x3d"javascript:void(0)" title\x3d"{closeTitle}" role\x3d"button"\x3e\x3cspan class\x3d"cke_label"\x3eX\x3c/span\x3e\x3c/a\x3e\x3cdiv id\x3d"cke_dialog_tabs_{id}" class\x3d"cke_dialog_tabs" role\x3d"tablist"\x3e\x3c/div\x3e\x3ctable class\x3d"cke_dialog_contents" role\x3d"presentation"\x3e\x3ctr\x3e\x3ctd id\x3d"cke_dialog_contents_{id}" class\x3d"cke_dialog_contents_body" role\x3d"presentation"\x3e\x3c/td\x3e\x3c/tr\x3e\x3ctr\x3e\x3ctd id\x3d"cke_dialog_footer_{id}" class\x3d"cke_dialog_footer" role\x3d"presentation"\x3e\x3c/td\x3e\x3c/tr\x3e\x3c/table\x3e\x3c/div\x3e\x3c/td\x3e\x3c/tr\x3e\x3c/table\x3e\x3c/div\x3e';
+CKEDITOR.dialog=function(a,b){function c(){var a=l._.focusList;a.sort(function(a,b){return a.tabIndex!=b.tabIndex?b.tabIndex-a.tabIndex:a.focusIndex-b.focusIndex});for(var b=a.length,c=0;c<b;c++)a[c].focusIndex=c}function e(a){var b=l._.focusList;a=a||0;if(!(1>b.length)){var c=l._.currentFocusIndex;l._.tabBarMode&&0>a&&(c=0);try{b[c].getInputElement().$.blur()}catch(d){}var e=c,g=1<l._.pageCount;do{e+=a;if(g&&!l._.tabBarMode&&(e==b.length||-1==e)){l._.tabBarMode=!0;l._.tabs[l._.currentTabId][0].focus();
+l._.currentFocusIndex=-1;return}e=(e+b.length)%b.length;if(e==c)break}while(a&&!b[e].isFocusable());b[e].focus();"text"==b[e].type&&b[e].select()}}function d(b){if(l==CKEDITOR.dialog._.currentTop){var c=b.data.getKeystroke(),d="rtl"==a.lang.dir,g=[37,38,39,40];q=n=0;if(9==c||c==CKEDITOR.SHIFT+9)e(c==CKEDITOR.SHIFT+9?-1:1),q=1;else if(c==CKEDITOR.ALT+121&&!l._.tabBarMode&&1<l.getPageCount())l._.tabBarMode=!0,l._.tabs[l._.currentTabId][0].focus(),l._.currentFocusIndex=-1,q=1;else if(-1!=CKEDITOR.tools.indexOf(g,
+c)&&l._.tabBarMode)c=-1!=CKEDITOR.tools.indexOf([d?39:37,38],c)?x.call(l):A.call(l),l.selectPage(c),l._.tabs[c][0].focus(),q=1;else if(13!=c&&32!=c||!l._.tabBarMode)if(13==c)c=b.data.getTarget(),c.is("a","button","select","textarea")||c.is("input")&&"button"==c.$.type||((c=this.getButton("ok"))&&CKEDITOR.tools.setTimeout(c.click,0,c),q=1),n=1;else if(27==c)(c=this.getButton("cancel"))?CKEDITOR.tools.setTimeout(c.click,0,c):!1!==this.fire("cancel",{hide:!0}).hide&&this.hide(),n=1;else return;else this.selectPage(this._.currentTabId),
+this._.tabBarMode=!1,this._.currentFocusIndex=-1,e(1),q=1;f(b)}}function f(a){q?a.data.preventDefault(1):n&&a.data.stopPropagation()}var g=CKEDITOR.dialog._.dialogDefinitions[b],h=CKEDITOR.tools.clone(aa),p=a.config.dialog_buttonsOrder||"OS",m=a.lang.dir,k={},q,n;("OS"==p&&CKEDITOR.env.mac||"rtl"==p&&"ltr"==m||"ltr"==p&&"rtl"==m)&&h.buttons.reverse();g=CKEDITOR.tools.extend(g(a),h);g=CKEDITOR.tools.clone(g);g=new P(this,g);h=V(a);this._={editor:a,element:h.element,name:b,contentSize:{width:0,height:0},
+size:{width:0,height:0},contents:{},buttons:{},accessKeyMap:{},tabs:{},tabIdList:[],currentTabId:null,currentTabIndex:null,pageCount:0,lastTab:null,tabBarMode:!1,focusList:[],currentFocusIndex:0,hasFocus:!1};this.parts=h.parts;CKEDITOR.tools.setTimeout(function(){a.fire("ariaWidget",this.parts.contents)},0,this);h={position:CKEDITOR.env.ie6Compat?"absolute":"fixed",top:0,visibility:"hidden"};h["rtl"==m?"right":"left"]=0;this.parts.dialog.setStyles(h);CKEDITOR.event.call(this);this.definition=g=CKEDITOR.fire("dialogDefinition",
+{name:b,definition:g},a).definition;if(!("removeDialogTabs"in a._)&&a.config.removeDialogTabs){h=a.config.removeDialogTabs.split(";");for(m=0;m<h.length;m++)if(p=h[m].split(":"),2==p.length){var r=p[0];k[r]||(k[r]=[]);k[r].push(p[1])}a._.removeDialogTabs=k}if(a._.removeDialogTabs&&(k=a._.removeDialogTabs[b]))for(m=0;m<k.length;m++)g.removeContents(k[m]);if(g.onLoad)this.on("load",g.onLoad);if(g.onShow)this.on("show",g.onShow);if(g.onHide)this.on("hide",g.onHide);if(g.onOk)this.on("ok",function(b){a.fire("saveSnapshot");
+setTimeout(function(){a.fire("saveSnapshot")},0);!1===g.onOk.call(this,b)&&(b.data.hide=!1)});this.state=CKEDITOR.DIALOG_STATE_IDLE;if(g.onCancel)this.on("cancel",function(a){!1===g.onCancel.call(this,a)&&(a.data.hide=!1)});var l=this,t=function(a){var b=l._.contents,c=!1,d;for(d in b)for(var e in b[d])if(c=a.call(this,b[d][e]))return};this.on("ok",function(a){t(function(b){if(b.validate){var c=b.validate(this),d="string"==typeof c||!1===c;d&&(a.data.hide=!1,a.stop());T.call(b,!d,"string"==typeof c?
+c:void 0);return d}})},this,null,0);this.on("cancel",function(b){t(function(c){if(c.isChanged())return a.config.dialog_noConfirmCancel||confirm(a.lang.common.confirmCancel)||(b.data.hide=!1),!0})},this,null,0);this.parts.close.on("click",function(a){!1!==this.fire("cancel",{hide:!0}).hide&&this.hide();a.data.preventDefault()},this);this.changeFocus=e;var y=this._.element;a.focusManager.add(y,1);this.on("show",function(){y.on("keydown",d,this);if(CKEDITOR.env.gecko)y.on("keypress",f,this)});this.on("hide",
+function(){y.removeListener("keydown",d);CKEDITOR.env.gecko&&y.removeListener("keypress",f);t(function(a){U.apply(a)})});this.on("iframeAdded",function(a){(new CKEDITOR.dom.document(a.data.iframe.$.contentWindow.document)).on("keydown",d,this,null,0)});this.on("show",function(){c();var b=1<l._.pageCount;a.config.dialog_startupFocusTab&&b?(l._.tabBarMode=!0,l._.tabs[l._.currentTabId][0].focus(),l._.currentFocusIndex=-1):this._.hasFocus||(this._.currentFocusIndex=b?-1:this._.focusList.length-1,g.onFocus?
+(b=g.onFocus.call(this))&&b.focus():e(1))},this,null,4294967295);if(CKEDITOR.env.ie6Compat)this.on("load",function(){var a=this.getElement(),b=a.getFirst();b.remove();b.appendTo(a)},this);Y(this);Z(this);(new CKEDITOR.dom.text(g.title,CKEDITOR.document)).appendTo(this.parts.title);for(m=0;m<g.contents.length;m++)(k=g.contents[m])&&this.addPage(k);this.parts.tabs.on("click",function(a){var b=a.data.getTarget();b.hasClass("cke_dialog_tab")&&(b=b.$.id,this.selectPage(b.substring(4,b.lastIndexOf("_"))),
+this._.tabBarMode&&(this._.tabBarMode=!1,this._.currentFocusIndex=-1,e(1)),a.data.preventDefault())},this);m=[];k=CKEDITOR.dialog._.uiElementBuilders.hbox.build(this,{type:"hbox",className:"cke_dialog_footer_buttons",widths:[],children:g.buttons},m).getChild();this.parts.footer.setHtml(m.join(""));for(m=0;m<k.length;m++)this._.buttons[k[m].id]=k[m]};CKEDITOR.dialog.prototype={destroy:function(){this.hide();this._.element.remove()},resize:function(){return function(a,b){this._.contentSize&&this._.contentSize.width==
+a&&this._.contentSize.height==b||(CKEDITOR.dialog.fire("resize",{dialog:this,width:a,height:b},this._.editor),this.fire("resize",{width:a,height:b},this._.editor),this.parts.contents.setStyles({width:a+"px",height:b+"px"}),"rtl"==this._.editor.lang.dir&&this._.position&&(this._.position.x=CKEDITOR.document.getWindow().getViewPaneSize().width-this._.contentSize.width-parseInt(this._.element.getFirst().getStyle("right"),10)),this._.contentSize={width:a,height:b})}}(),getSize:function(){var a=this._.element.getFirst();
+return{width:a.$.offsetWidth||0,height:a.$.offsetHeight||0}},move:function(a,b,c){var e=this._.element.getFirst(),d="rtl"==this._.editor.lang.dir,f="fixed"==e.getComputedStyle("position");CKEDITOR.env.ie&&e.setStyle("zoom","100%");f&&this._.position&&this._.position.x==a&&this._.position.y==b||(this._.position={x:a,y:b},f||(f=CKEDITOR.document.getWindow().getScrollPosition(),a+=f.x,b+=f.y),d&&(f=this.getSize(),a=CKEDITOR.document.getWindow().getViewPaneSize().width-f.width-a),b={top:(0<b?b:0)+"px"},
+b[d?"right":"left"]=(0<a?a:0)+"px",e.setStyles(b),c&&(this._.moved=1))},getPosition:function(){return CKEDITOR.tools.extend({},this._.position)},show:function(){var a=this._.element,b=this.definition;a.getParent()&&a.getParent().equals(CKEDITOR.document.getBody())?a.setStyle("display","block"):a.appendTo(CKEDITOR.document.getBody());this.resize(this._.contentSize&&this._.contentSize.width||b.width||b.minWidth,this._.contentSize&&this._.contentSize.height||b.height||b.minHeight);this.reset();this.selectPage(this.definition.contents[0].id);
+null===CKEDITOR.dialog._.currentZIndex&&(CKEDITOR.dialog._.currentZIndex=this._.editor.config.baseFloatZIndex);this._.element.getFirst().setStyle("z-index",CKEDITOR.dialog._.currentZIndex+=10);null===CKEDITOR.dialog._.currentTop?(CKEDITOR.dialog._.currentTop=this,this._.parentDialog=null,N(this._.editor)):(this._.parentDialog=CKEDITOR.dialog._.currentTop,this._.parentDialog.getElement().getFirst().$.style.zIndex-=Math.floor(this._.editor.config.baseFloatZIndex/2),CKEDITOR.dialog._.currentTop=this);
+a.on("keydown",Q);a.on("keyup",R);this._.hasFocus=!1;for(var c in b.contents)if(b.contents[c]){var a=b.contents[c],e=this._.tabs[a.id],d=a.requiredContent,f=0;if(e){for(var g in this._.contents[a.id]){var h=this._.contents[a.id][g];"hbox"!=h.type&&"vbox"!=h.type&&h.getInputElement()&&(h.requiredContent&&!this._.editor.activeFilter.check(h.requiredContent)?h.disable():(h.enable(),f++))}!f||d&&!this._.editor.activeFilter.check(d)?e[0].addClass("cke_dialog_tab_disabled"):e[0].removeClass("cke_dialog_tab_disabled")}}CKEDITOR.tools.setTimeout(function(){this.layout();
+X(this);this.parts.dialog.setStyle("visibility","");this.fireOnce("load",{});CKEDITOR.ui.fire("ready",this);this.fire("show",{});this._.editor.fire("dialogShow",this);this._.parentDialog||this._.editor.focusManager.lock();this.foreach(function(a){a.setInitValue&&a.setInitValue()})},100,this)},layout:function(){var a=this.parts.dialog,b=this.getSize(),c=CKEDITOR.document.getWindow().getViewPaneSize(),e=(c.width-b.width)/2,d=(c.height-b.height)/2;CKEDITOR.env.ie6Compat||(b.height+(0<d?d:0)>c.height||
+b.width+(0<e?e:0)>c.width?a.setStyle("position","absolute"):a.setStyle("position","fixed"));this.move(this._.moved?this._.position.x:e,this._.moved?this._.position.y:d)},foreach:function(a){for(var b in this._.contents)for(var c in this._.contents[b])a.call(this,this._.contents[b][c]);return this},reset:function(){var a=function(a){a.reset&&a.reset(1)};return function(){this.foreach(a);return this}}(),setupContent:function(){var a=arguments;this.foreach(function(b){b.setup&&b.setup.apply(b,a)})},
+commitContent:function(){var a=arguments;this.foreach(function(b){CKEDITOR.env.ie&&this._.currentFocusIndex==b.focusIndex&&b.getInputElement().$.blur();b.commit&&b.commit.apply(b,a)})},hide:function(){if(this.parts.dialog.isVisible()){this.fire("hide",{});this._.editor.fire("dialogHide",this);this.selectPage(this._.tabIdList[0]);var a=this._.element;a.setStyle("display","none");this.parts.dialog.setStyle("visibility","hidden");for(ba(this);CKEDITOR.dialog._.currentTop!=this;)CKEDITOR.dialog._.currentTop.hide();
+if(this._.parentDialog){var b=this._.parentDialog.getElement().getFirst();b.setStyle("z-index",parseInt(b.$.style.zIndex,10)+Math.floor(this._.editor.config.baseFloatZIndex/2))}else O(this._.editor);if(CKEDITOR.dialog._.currentTop=this._.parentDialog)CKEDITOR.dialog._.currentZIndex-=10;else{CKEDITOR.dialog._.currentZIndex=null;a.removeListener("keydown",Q);a.removeListener("keyup",R);var c=this._.editor;c.focus();setTimeout(function(){c.focusManager.unlock();CKEDITOR.env.iOS&&c.window.focus()},0)}delete this._.parentDialog;
+this.foreach(function(a){a.resetInitValue&&a.resetInitValue()});this.setState(CKEDITOR.DIALOG_STATE_IDLE)}},addPage:function(a){if(!a.requiredContent||this._.editor.filter.check(a.requiredContent)){for(var b=[],c=a.label?' title\x3d"'+CKEDITOR.tools.htmlEncode(a.label)+'"':"",e=CKEDITOR.dialog._.uiElementBuilders.vbox.build(this,{type:"vbox",className:"cke_dialog_page_contents",children:a.elements,expand:!!a.expand,padding:a.padding,style:a.style||"width: 100%;"},b),d=this._.contents[a.id]={},f=e.getChild(),
+g=0;e=f.shift();)e.notAllowed||"hbox"==e.type||"vbox"==e.type||g++,d[e.id]=e,"function"==typeof e.getChild&&f.push.apply(f,e.getChild());g||(a.hidden=!0);b=CKEDITOR.dom.element.createFromHtml(b.join(""));b.setAttribute("role","tabpanel");e=CKEDITOR.env;d="cke_"+a.id+"_"+CKEDITOR.tools.getNextNumber();c=CKEDITOR.dom.element.createFromHtml(['\x3ca class\x3d"cke_dialog_tab"',0<this._.pageCount?" cke_last":"cke_first",c,a.hidden?' style\x3d"display:none"':"",' id\x3d"',d,'"',e.gecko&&!e.hc?"":' href\x3d"javascript:void(0)"',
+' tabIndex\x3d"-1" hidefocus\x3d"true" role\x3d"tab"\x3e',a.label,"\x3c/a\x3e"].join(""));b.setAttribute("aria-labelledby",d);this._.tabs[a.id]=[c,b];this._.tabIdList.push(a.id);!a.hidden&&this._.pageCount++;this._.lastTab=c;this.updateStyle();b.setAttribute("name",a.id);b.appendTo(this.parts.contents);c.unselectable();this.parts.tabs.append(c);a.accessKey&&(S(this,this,"CTRL+"+a.accessKey,ca,da),this._.accessKeyMap["CTRL+"+a.accessKey]=a.id)}},selectPage:function(a){if(this._.currentTabId!=a&&!this._.tabs[a][0].hasClass("cke_dialog_tab_disabled")&&
+!1!==this.fire("selectPage",{page:a,currentPage:this._.currentTabId})){for(var b in this._.tabs){var c=this._.tabs[b][0],e=this._.tabs[b][1];b!=a&&(c.removeClass("cke_dialog_tab_selected"),e.hide());e.setAttribute("aria-hidden",b!=a)}var d=this._.tabs[a];d[0].addClass("cke_dialog_tab_selected");CKEDITOR.env.ie6Compat||CKEDITOR.env.ie7Compat?(K(d[1]),d[1].show(),setTimeout(function(){K(d[1],1)},0)):d[1].show();this._.currentTabId=a;this._.currentTabIndex=CKEDITOR.tools.indexOf(this._.tabIdList,a)}},
+updateStyle:function(){this.parts.dialog[(1===this._.pageCount?"add":"remove")+"Class"]("cke_single_page")},hidePage:function(a){var b=this._.tabs[a]&&this._.tabs[a][0];b&&1!=this._.pageCount&&b.isVisible()&&(a==this._.currentTabId&&this.selectPage(x.call(this)),b.hide(),this._.pageCount--,this.updateStyle())},showPage:function(a){if(a=this._.tabs[a]&&this._.tabs[a][0])a.show(),this._.pageCount++,this.updateStyle()},getElement:function(){return this._.element},getName:function(){return this._.name},
+getContentElement:function(a,b){var c=this._.contents[a];return c&&c[b]},getValueOf:function(a,b){return this.getContentElement(a,b).getValue()},setValueOf:function(a,b,c){return this.getContentElement(a,b).setValue(c)},getButton:function(a){return this._.buttons[a]},click:function(a){return this._.buttons[a].click()},disableButton:function(a){return this._.buttons[a].disable()},enableButton:function(a){return this._.buttons[a].enable()},getPageCount:function(){return this._.pageCount},getParentEditor:function(){return this._.editor},
+getSelectedElement:function(){return this.getParentEditor().getSelection().getSelectedElement()},addFocusable:function(a,b){if("undefined"==typeof b)b=this._.focusList.length,this._.focusList.push(new L(this,a,b));else{this._.focusList.splice(b,0,new L(this,a,b));for(var c=b+1;c<this._.focusList.length;c++)this._.focusList[c].focusIndex++}},setState:function(a){if(this.state!=a){this.state=a;if(a==CKEDITOR.DIALOG_STATE_BUSY){if(!this.parts.spinner){var b=this.getParentEditor().lang.dir,c={attributes:{"class":"cke_dialog_spinner"},
+styles:{"float":"rtl"==b?"right":"left"}};c.styles["margin-"+("rtl"==b?"left":"right")]="8px";this.parts.spinner=CKEDITOR.document.createElement("div",c);this.parts.spinner.setHtml("\x26#8987;");this.parts.spinner.appendTo(this.parts.title,1)}this.parts.spinner.show();this.getButton("ok").disable()}else a==CKEDITOR.DIALOG_STATE_IDLE&&(this.parts.spinner&&this.parts.spinner.hide(),this.getButton("ok").enable());this.fire("state",a)}}};CKEDITOR.tools.extend(CKEDITOR.dialog,{add:function(a,b){this._.dialogDefinitions[a]&&
+"function"!=typeof b||(this._.dialogDefinitions[a]=b)},exists:function(a){return!!this._.dialogDefinitions[a]},getCurrent:function(){return CKEDITOR.dialog._.currentTop},isTabEnabled:function(a,b,c){a=a.config.removeDialogTabs;return!(a&&a.match(new RegExp("(?:^|;)"+b+":"+c+"(?:$|;)","i")))},okButton:function(){var a=function(a,c){c=c||{};return CKEDITOR.tools.extend({id:"ok",type:"button",label:a.lang.common.ok,"class":"cke_dialog_ui_button_ok",onClick:function(a){a=a.data.dialog;!1!==a.fire("ok",
+{hide:!0}).hide&&a.hide()}},c,!0)};a.type="button";a.override=function(b){return CKEDITOR.tools.extend(function(c){return a(c,b)},{type:"button"},!0)};return a}(),cancelButton:function(){var a=function(a,c){c=c||{};return CKEDITOR.tools.extend({id:"cancel",type:"button",label:a.lang.common.cancel,"class":"cke_dialog_ui_button_cancel",onClick:function(a){a=a.data.dialog;!1!==a.fire("cancel",{hide:!0}).hide&&a.hide()}},c,!0)};a.type="button";a.override=function(b){return CKEDITOR.tools.extend(function(c){return a(c,
+b)},{type:"button"},!0)};return a}(),addUIElement:function(a,b){this._.uiElementBuilders[a]=b}});CKEDITOR.dialog._={uiElementBuilders:{},dialogDefinitions:{},currentTop:null,currentZIndex:null};CKEDITOR.event.implementOn(CKEDITOR.dialog);CKEDITOR.event.implementOn(CKEDITOR.dialog.prototype);var aa={resizable:CKEDITOR.DIALOG_RESIZE_BOTH,minWidth:600,minHeight:400,buttons:[CKEDITOR.dialog.okButton,CKEDITOR.dialog.cancelButton]},D=function(a,b,c){for(var e=0,d;d=a[e];e++)if(d.id==b||c&&d[c]&&(d=D(d[c],
+b,c)))return d;return null},E=function(a,b,c,e,d){if(c){for(var f=0,g;g=a[f];f++){if(g.id==c)return a.splice(f,0,b),b;if(e&&g[e]&&(g=E(g[e],b,c,e,!0)))return g}if(d)return null}a.push(b);return b},F=function(a,b,c){for(var e=0,d;d=a[e];e++){if(d.id==b)return a.splice(e,1);if(c&&d[c]&&(d=F(d[c],b,c)))return d}return null},P=function(a,b){this.dialog=a;for(var c=b.contents,e=0,d;d=c[e];e++)c[e]=d&&new M(a,d);CKEDITOR.tools.extend(this,b)};P.prototype={getContents:function(a){return D(this.contents,
+a)},getButton:function(a){return D(this.buttons,a)},addContents:function(a,b){return E(this.contents,a,b)},addButton:function(a,b){return E(this.buttons,a,b)},removeContents:function(a){F(this.contents,a)},removeButton:function(a){F(this.buttons,a)}};M.prototype={get:function(a){return D(this.elements,a,"children")},add:function(a,b){return E(this.elements,a,b,"children")},remove:function(a){F(this.elements,a,"children")}};var J,z={},u,w={},Q=function(a){var b=a.data.$.ctrlKey||a.data.$.metaKey,c=
+a.data.$.altKey,e=a.data.$.shiftKey,d=String.fromCharCode(a.data.$.keyCode);(b=w[(b?"CTRL+":"")+(c?"ALT+":"")+(e?"SHIFT+":"")+d])&&b.length&&(b=b[b.length-1],b.keydown&&b.keydown.call(b.uiElement,b.dialog,b.key),a.data.preventDefault())},R=function(a){var b=a.data.$.ctrlKey||a.data.$.metaKey,c=a.data.$.altKey,e=a.data.$.shiftKey,d=String.fromCharCode(a.data.$.keyCode);(b=w[(b?"CTRL+":"")+(c?"ALT+":"")+(e?"SHIFT+":"")+d])&&b.length&&(b=b[b.length-1],b.keyup&&(b.keyup.call(b.uiElement,b.dialog,b.key),
+a.data.preventDefault()))},S=function(a,b,c,e,d){(w[c]||(w[c]=[])).push({uiElement:a,dialog:b,key:c,keyup:d||a.accessKeyUp,keydown:e||a.accessKeyDown})},ba=function(a){for(var b in w){for(var c=w[b],e=c.length-1;0<=e;e--)c[e].dialog!=a&&c[e].uiElement!=a||c.splice(e,1);0===c.length&&delete w[b]}},da=function(a,b){a._.accessKeyMap[b]&&a.selectPage(a._.accessKeyMap[b])},ca=function(){};(function(){CKEDITOR.ui.dialog={uiElement:function(a,b,c,e,d,f,g){if(!(4>arguments.length)){var h=(e.call?e(b):e)||
+"div",p=["\x3c",h," "],m=(d&&d.call?d(b):d)||{},k=(f&&f.call?f(b):f)||{},q=(g&&g.call?g.call(this,a,b):g)||"",n=this.domId=k.id||CKEDITOR.tools.getNextId()+"_uiElement";b.requiredContent&&!a.getParentEditor().filter.check(b.requiredContent)&&(m.display="none",this.notAllowed=!0);k.id=n;var r={};b.type&&(r["cke_dialog_ui_"+b.type]=1);b.className&&(r[b.className]=1);b.disabled&&(r.cke_disabled=1);for(var l=k["class"]&&k["class"].split?k["class"].split(" "):[],n=0;n<l.length;n++)l[n]&&(r[l[n]]=1);l=
+[];for(n in r)l.push(n);k["class"]=l.join(" ");b.title&&(k.title=b.title);r=(b.style||"").split(";");b.align&&(l=b.align,m["margin-left"]="left"==l?0:"auto",m["margin-right"]="right"==l?0:"auto");for(n in m)r.push(n+":"+m[n]);b.hidden&&r.push("display:none");for(n=r.length-1;0<=n;n--)""===r[n]&&r.splice(n,1);0<r.length&&(k.style=(k.style?k.style+"; ":"")+r.join("; "));for(n in k)p.push(n+'\x3d"'+CKEDITOR.tools.htmlEncode(k[n])+'" ');p.push("\x3e",q,"\x3c/",h,"\x3e");c.push(p.join(""));(this._||(this._=
+{})).dialog=a;"boolean"==typeof b.isChanged&&(this.isChanged=function(){return b.isChanged});"function"==typeof b.isChanged&&(this.isChanged=b.isChanged);"function"==typeof b.setValue&&(this.setValue=CKEDITOR.tools.override(this.setValue,function(a){return function(c){a.call(this,b.setValue.call(this,c))}}));"function"==typeof b.getValue&&(this.getValue=CKEDITOR.tools.override(this.getValue,function(a){return function(){return b.getValue.call(this,a.call(this))}}));CKEDITOR.event.implementOn(this);
+this.registerEvents(b);this.accessKeyUp&&this.accessKeyDown&&b.accessKey&&S(this,a,"CTRL+"+b.accessKey);var t=this;a.on("load",function(){var b=t.getInputElement();if(b){var c=t.type in{checkbox:1,ratio:1}&&CKEDITOR.env.ie&&8>CKEDITOR.env.version?"cke_dialog_ui_focused":"";b.on("focus",function(){a._.tabBarMode=!1;a._.hasFocus=!0;t.fire("focus");c&&this.addClass(c)});b.on("blur",function(){t.fire("blur");c&&this.removeClass(c)})}});CKEDITOR.tools.extend(this,b);this.keyboardFocusable&&(this.tabIndex=
+b.tabIndex||0,this.focusIndex=a._.focusList.push(this)-1,this.on("focus",function(){a._.currentFocusIndex=t.focusIndex}))}},hbox:function(a,b,c,e,d){if(!(4>arguments.length)){this._||(this._={});var f=this._.children=b,g=d&&d.widths||null,h=d&&d.height||null,p,m={role:"presentation"};d&&d.align&&(m.align=d.align);CKEDITOR.ui.dialog.uiElement.call(this,a,d||{type:"hbox"},e,"table",{},m,function(){var a=['\x3ctbody\x3e\x3ctr class\x3d"cke_dialog_ui_hbox"\x3e'];for(p=0;p<c.length;p++){var b="cke_dialog_ui_hbox_child",
+e=[];0===p&&(b="cke_dialog_ui_hbox_first");p==c.length-1&&(b="cke_dialog_ui_hbox_last");a.push('\x3ctd class\x3d"',b,'" role\x3d"presentation" ');g?g[p]&&e.push("width:"+v(g[p])):e.push("width:"+Math.floor(100/c.length)+"%");h&&e.push("height:"+v(h));d&&void 0!==d.padding&&e.push("padding:"+v(d.padding));CKEDITOR.env.ie&&CKEDITOR.env.quirks&&f[p].align&&e.push("text-align:"+f[p].align);0<e.length&&a.push('style\x3d"'+e.join("; ")+'" ');a.push("\x3e",c[p],"\x3c/td\x3e")}a.push("\x3c/tr\x3e\x3c/tbody\x3e");
+return a.join("")})}},vbox:function(a,b,c,e,d){if(!(3>arguments.length)){this._||(this._={});var f=this._.children=b,g=d&&d.width||null,h=d&&d.heights||null;CKEDITOR.ui.dialog.uiElement.call(this,a,d||{type:"vbox"},e,"div",null,{role:"presentation"},function(){var b=['\x3ctable role\x3d"presentation" cellspacing\x3d"0" border\x3d"0" '];b.push('style\x3d"');d&&d.expand&&b.push("height:100%;");b.push("width:"+v(g||"100%"),";");CKEDITOR.env.webkit&&b.push("float:none;");b.push('"');b.push('align\x3d"',
+CKEDITOR.tools.htmlEncode(d&&d.align||("ltr"==a.getParentEditor().lang.dir?"left":"right")),'" ');b.push("\x3e\x3ctbody\x3e");for(var e=0;e<c.length;e++){var k=[];b.push('\x3ctr\x3e\x3ctd role\x3d"presentation" ');g&&k.push("width:"+v(g||"100%"));h?k.push("height:"+v(h[e])):d&&d.expand&&k.push("height:"+Math.floor(100/c.length)+"%");d&&void 0!==d.padding&&k.push("padding:"+v(d.padding));CKEDITOR.env.ie&&CKEDITOR.env.quirks&&f[e].align&&k.push("text-align:"+f[e].align);0<k.length&&b.push('style\x3d"',
+k.join("; "),'" ');b.push(' class\x3d"cke_dialog_ui_vbox_child"\x3e',c[e],"\x3c/td\x3e\x3c/tr\x3e")}b.push("\x3c/tbody\x3e\x3c/table\x3e");return b.join("")})}}}})();CKEDITOR.ui.dialog.uiElement.prototype={getElement:function(){return CKEDITOR.document.getById(this.domId)},getInputElement:function(){return this.getElement()},getDialog:function(){return this._.dialog},setValue:function(a,b){this.getInputElement().setValue(a);!b&&this.fire("change",{value:a});return this},getValue:function(){return this.getInputElement().getValue()},
+isChanged:function(){return!1},selectParentTab:function(){for(var a=this.getInputElement();(a=a.getParent())&&-1==a.$.className.search("cke_dialog_page_contents"););if(!a)return this;a=a.getAttribute("name");this._.dialog._.currentTabId!=a&&this._.dialog.selectPage(a);return this},focus:function(){this.selectParentTab().getInputElement().focus();return this},registerEvents:function(a){var b=/^on([A-Z]\w+)/,c,e=function(a,b,c,d){b.on("load",function(){a.getInputElement().on(c,d,a)})},d;for(d in a)if(c=
+d.match(b))this.eventProcessors[d]?this.eventProcessors[d].call(this,this._.dialog,a[d]):e(this,this._.dialog,c[1].toLowerCase(),a[d]);return this},eventProcessors:{onLoad:function(a,b){a.on("load",b,this)},onShow:function(a,b){a.on("show",b,this)},onHide:function(a,b){a.on("hide",b,this)}},accessKeyDown:function(){this.focus()},accessKeyUp:function(){},disable:function(){var a=this.getElement();this.getInputElement().setAttribute("disabled","true");a.addClass("cke_disabled")},enable:function(){var a=
+this.getElement();this.getInputElement().removeAttribute("disabled");a.removeClass("cke_disabled")},isEnabled:function(){return!this.getElement().hasClass("cke_disabled")},isVisible:function(){return this.getInputElement().isVisible()},isFocusable:function(){return this.isEnabled()&&this.isVisible()?!0:!1}};CKEDITOR.ui.dialog.hbox.prototype=CKEDITOR.tools.extend(new CKEDITOR.ui.dialog.uiElement,{getChild:function(a){if(1>arguments.length)return this._.children.concat();a.splice||(a=[a]);return 2>
+a.length?this._.children[a[0]]:this._.children[a[0]]&&this._.children[a[0]].getChild?this._.children[a[0]].getChild(a.slice(1,a.length)):null}},!0);CKEDITOR.ui.dialog.vbox.prototype=new CKEDITOR.ui.dialog.hbox;(function(){var a={build:function(a,c,e){for(var d=c.children,f,g=[],h=[],p=0;p<d.length&&(f=d[p]);p++){var m=[];g.push(m);h.push(CKEDITOR.dialog._.uiElementBuilders[f.type].build(a,f,m))}return new CKEDITOR.ui.dialog[c.type](a,h,g,e,c)}};CKEDITOR.dialog.addUIElement("hbox",a);CKEDITOR.dialog.addUIElement("vbox",
+a)})();CKEDITOR.dialogCommand=function(a,b){this.dialogName=a;CKEDITOR.tools.extend(this,b,!0)};CKEDITOR.dialogCommand.prototype={exec:function(a){a.openDialog(this.dialogName)},canUndo:!1,editorFocus:1};(function(){var a=/^([a]|[^a])+$/,b=/^\d*$/,c=/^\d*(?:\.\d+)?$/,e=/^(((\d*(\.\d+))|(\d*))(px|\%)?)?$/,d=/^(((\d*(\.\d+))|(\d*))(px|em|ex|in|cm|mm|pt|pc|\%)?)?$/i,f=/^(\s*[\w-]+\s*:\s*[^:;]+(?:;|$))*$/;CKEDITOR.VALIDATE_OR=1;CKEDITOR.VALIDATE_AND=2;CKEDITOR.dialog.validate={functions:function(){var a=
+arguments;return function(){var b=this&&this.getValue?this.getValue():a[0],c,d=CKEDITOR.VALIDATE_AND,e=[],f;for(f=0;f<a.length;f++)if("function"==typeof a[f])e.push(a[f]);else break;f<a.length&&"string"==typeof a[f]&&(c=a[f],f++);f<a.length&&"number"==typeof a[f]&&(d=a[f]);var n=d==CKEDITOR.VALIDATE_AND?!0:!1;for(f=0;f<e.length;f++)n=d==CKEDITOR.VALIDATE_AND?n&&e[f](b):n||e[f](b);return n?!0:c}},regex:function(a,b){return function(c){c=this&&this.getValue?this.getValue():c;return a.test(c)?!0:b}},
+notEmpty:function(b){return this.regex(a,b)},integer:function(a){return this.regex(b,a)},number:function(a){return this.regex(c,a)},cssLength:function(a){return this.functions(function(a){return d.test(CKEDITOR.tools.trim(a))},a)},htmlLength:function(a){return this.functions(function(a){return e.test(CKEDITOR.tools.trim(a))},a)},inlineStyle:function(a){return this.functions(function(a){return f.test(CKEDITOR.tools.trim(a))},a)},equals:function(a,b){return this.functions(function(b){return b==a},b)},
+notEqual:function(a,b){return this.functions(function(b){return b!=a},b)}};CKEDITOR.on("instanceDestroyed",function(a){if(CKEDITOR.tools.isEmpty(CKEDITOR.instances)){for(var b;b=CKEDITOR.dialog._.currentTop;)b.hide();for(var c in z)z[c].remove();z={}}a=a.editor._.storedDialogs;for(var d in a)a[d].destroy()})})();CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{openDialog:function(a,b){var c=null,e=CKEDITOR.dialog._.dialogDefinitions[a];null===CKEDITOR.dialog._.currentTop&&N(this);if("function"==typeof e)c=
+this._.storedDialogs||(this._.storedDialogs={}),c=c[a]||(c[a]=new CKEDITOR.dialog(this,a)),b&&b.call(c,c),c.show();else{if("failed"==e)throw O(this),Error('[CKEDITOR.dialog.openDialog] Dialog "'+a+'" failed when loading definition.');"string"==typeof e&&CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(e),function(){"function"!=typeof CKEDITOR.dialog._.dialogDefinitions[a]&&(CKEDITOR.dialog._.dialogDefinitions[a]="failed");this.openDialog(a,b)},this,0,1)}CKEDITOR.skin.loadPart("dialog");return c}})})();
+CKEDITOR.plugins.add("dialog",{requires:"dialogui",init:function(x){x.on("doubleclick",function(A){A.data.dialog&&x.openDialog(A.data.dialog)},null,null,999)}});(function(){CKEDITOR.plugins.add("a11yhelp",{requires:"dialog",availableLangs:{af:1,ar:1,az:1,bg:1,ca:1,cs:1,cy:1,da:1,de:1,"de-ch":1,el:1,en:1,"en-gb":1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,fr:1,"fr-ca":1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,it:1,ja:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,nb:1,nl:1,no:1,oc:1,pl:1,pt:1,"pt-br":1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,sr:1,"sr-latn":1,sv:1,th:1,tr:1,tt:1,ug:1,uk:1,vi:1,zh:1,"zh-cn":1},init:function(b){var c=this;b.addCommand("a11yHelp",{exec:function(){var a=b.langCode,
+a=c.availableLangs[a]?a:c.availableLangs[a.replace(/-.*/,"")]?a.replace(/-.*/,""):"en";CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(c.path+"dialogs/lang/"+a+".js"),function(){b.lang.a11yhelp=c.langEntries[a];b.openDialog("a11yHelp")})},modes:{wysiwyg:1,source:1},readOnly:1,canUndo:!1});b.setKeystroke(CKEDITOR.ALT+48,"a11yHelp");CKEDITOR.dialog.add("a11yHelp",this.path+"dialogs/a11yhelp.js");b.on("ariaEditorHelpLabel",function(a){a.data.label=b.lang.common.editorHelp})}})})();(function(){function f(c){var a=this.att;c=c&&c.hasAttribute(a)&&c.getAttribute(a)||"";void 0!==c&&this.setValue(c)}function g(){for(var c,a=0;a<arguments.length;a++)if(arguments[a]instanceof CKEDITOR.dom.element){c=arguments[a];break}if(c){var a=this.att,b=this.getValue();b?c.setAttribute(a,b):c.removeAttribute(a,b)}}var k={id:1,dir:1,classes:1,styles:1};CKEDITOR.plugins.add("dialogadvtab",{requires:"dialog",allowedContent:function(c){c||(c=k);var a=[];c.id&&a.push("id");c.dir&&a.push("dir");var b=
+"";a.length&&(b+="["+a.join(",")+"]");c.classes&&(b+="(*)");c.styles&&(b+="{*}");return b},createAdvancedTab:function(c,a,b){a||(a=k);var d=c.lang.common,h={id:"advanced",label:d.advancedTab,title:d.advancedTab,elements:[{type:"vbox",padding:1,children:[]}]},e=[];if(a.id||a.dir)a.id&&e.push({id:"advId",att:"id",type:"text",requiredContent:b?b+"[id]":null,label:d.id,setup:f,commit:g}),a.dir&&e.push({id:"advLangDir",att:"dir",type:"select",requiredContent:b?b+"[dir]":null,label:d.langDir,"default":"",
+style:"width:100%",items:[[d.notSet,""],[d.langDirLTR,"ltr"],[d.langDirRTL,"rtl"]],setup:f,commit:g}),h.elements[0].children.push({type:"hbox",widths:["50%","50%"],children:[].concat(e)});if(a.styles||a.classes)e=[],a.styles&&e.push({id:"advStyles",att:"style",type:"text",requiredContent:b?b+"{cke-xyz}":null,label:d.styles,"default":"",validate:CKEDITOR.dialog.validate.inlineStyle(d.invalidInlineStyle),onChange:function(){},getStyle:function(a,c){var b=this.getValue().match(new RegExp("(?:^|;)\\s*"+
+a+"\\s*:\\s*([^;]*)","i"));return b?b[1]:c},updateStyle:function(a,b){var d=this.getValue(),e=c.document.createElement("span");e.setAttribute("style",d);e.setStyle(a,b);d=CKEDITOR.tools.normalizeCssText(e.getAttribute("style"));this.setValue(d,1)},setup:f,commit:g}),a.classes&&e.push({type:"hbox",widths:["45%","55%"],children:[{id:"advCSSClasses",att:"class",type:"text",requiredContent:b?b+"(cke-xyz)":null,label:d.cssClasses,"default":"",setup:f,commit:g}]}),h.elements[0].children.push({type:"hbox",
+widths:["50%","50%"],children:[].concat(e)});return h}})})();CKEDITOR.plugins.add("basicstyles",{init:function(c){var e=0,d=function(g,d,b,a){if(a){a=new CKEDITOR.style(a);var f=h[b];f.unshift(a);c.attachStyleStateChange(a,function(a){!c.readOnly&&c.getCommand(b).setState(a)});c.addCommand(b,new CKEDITOR.styleCommand(a,{contentForms:f}));c.ui.addButton&&c.ui.addButton(g,{label:d,command:b,toolbar:"basicstyles,"+(e+=10)})}},h={bold:["strong","b",["span",function(a){a=a.styles["font-weight"];return"bold"==a||700<=+a}]],italic:["em","i",["span",function(a){return"italic"==
+a.styles["font-style"]}]],underline:["u",["span",function(a){return"underline"==a.styles["text-decoration"]}]],strike:["s","strike",["span",function(a){return"line-through"==a.styles["text-decoration"]}]],subscript:["sub"],superscript:["sup"]},b=c.config,a=c.lang.basicstyles;d("Bold",a.bold,"bold",b.coreStyles_bold);d("Italic",a.italic,"italic",b.coreStyles_italic);d("Underline",a.underline,"underline",b.coreStyles_underline);d("Strike",a.strike,"strike",b.coreStyles_strike);d("Subscript",a.subscript,
+"subscript",b.coreStyles_subscript);d("Superscript",a.superscript,"superscript",b.coreStyles_superscript);c.setKeystroke([[CKEDITOR.CTRL+66,"bold"],[CKEDITOR.CTRL+73,"italic"],[CKEDITOR.CTRL+85,"underline"]])}});CKEDITOR.config.coreStyles_bold={element:"strong",overrides:"b"};CKEDITOR.config.coreStyles_italic={element:"em",overrides:"i"};CKEDITOR.config.coreStyles_underline={element:"u"};CKEDITOR.config.coreStyles_strike={element:"s",overrides:"strike"};CKEDITOR.config.coreStyles_subscript={element:"sub"};
+CKEDITOR.config.coreStyles_superscript={element:"sup"};(function(){CKEDITOR.plugins.add("panel",{beforeInit:function(a){a.ui.addHandler(CKEDITOR.UI_PANEL,CKEDITOR.ui.panel.handler)}});CKEDITOR.UI_PANEL="panel";CKEDITOR.ui.panel=function(a,b){b&&CKEDITOR.tools.extend(this,b);CKEDITOR.tools.extend(this,{className:"",css:[]});this.id=CKEDITOR.tools.getNextId();this.document=a;this.isFramed=this.forceIFrame||this.css.length;this._={blocks:{}}};CKEDITOR.ui.panel.handler={create:function(a){return new CKEDITOR.ui.panel(a)}};var f=CKEDITOR.addTemplate("panel",
+'\x3cdiv lang\x3d"{langCode}" id\x3d"{id}" dir\x3d{dir} class\x3d"cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}" style\x3d"z-index:{z-index}" role\x3d"presentation"\x3e{frame}\x3c/div\x3e'),g=CKEDITOR.addTemplate("panel-frame",'\x3ciframe id\x3d"{id}" class\x3d"cke_panel_frame" role\x3d"presentation" frameborder\x3d"0" src\x3d"{src}"\x3e\x3c/iframe\x3e'),h=CKEDITOR.addTemplate("panel-frame-inner",'\x3c!DOCTYPE html\x3e\x3chtml class\x3d"cke_panel_container {env}" dir\x3d"{dir}" lang\x3d"{langCode}"\x3e\x3chead\x3e{css}\x3c/head\x3e\x3cbody class\x3d"cke_{dir}" style\x3d"margin:0;padding:0" onload\x3d"{onload}"\x3e\x3c/body\x3e\x3c/html\x3e');
+CKEDITOR.ui.panel.prototype={render:function(a,b){this.getHolderElement=function(){var a=this._.holder;if(!a){if(this.isFramed){var a=this.document.getById(this.id+"_frame"),b=a.getParent(),a=a.getFrameDocument();CKEDITOR.env.iOS&&b.setStyles({overflow:"scroll","-webkit-overflow-scrolling":"touch"});b=CKEDITOR.tools.addFunction(CKEDITOR.tools.bind(function(){this.isLoaded=!0;if(this.onLoad)this.onLoad()},this));a.write(h.output(CKEDITOR.tools.extend({css:CKEDITOR.tools.buildStyleHtml(this.css),onload:"window.parent.CKEDITOR.tools.callFunction("+
+b+");"},d)));a.getWindow().$.CKEDITOR=CKEDITOR;a.on("keydown",function(a){var b=a.data.getKeystroke(),c=this.document.getById(this.id).getAttribute("dir");this._.onKeyDown&&!1===this._.onKeyDown(b)?a.data.preventDefault():(27==b||b==("rtl"==c?39:37))&&this.onEscape&&!1===this.onEscape(b)&&a.data.preventDefault()},this);a=a.getBody();a.unselectable();CKEDITOR.env.air&&CKEDITOR.tools.callFunction(b)}else a=this.document.getById(this.id);this._.holder=a}return a};var d={editorId:a.id,id:this.id,langCode:a.langCode,
+dir:a.lang.dir,cls:this.className,frame:"",env:CKEDITOR.env.cssClass,"z-index":a.config.baseFloatZIndex+1};if(this.isFramed){var e=CKEDITOR.env.air?"javascript:void(0)":CKEDITOR.env.ie?"javascript:void(function(){"+encodeURIComponent("document.open();("+CKEDITOR.tools.fixDomain+")();document.close();")+"}())":"";d.frame=g.output({id:this.id+"_frame",src:e})}e=f.output(d);b&&b.push(e);return e},addBlock:function(a,b){b=this._.blocks[a]=b instanceof CKEDITOR.ui.panel.block?b:new CKEDITOR.ui.panel.block(this.getHolderElement(),
+b);this._.currentBlock||this.showBlock(a);return b},getBlock:function(a){return this._.blocks[a]},showBlock:function(a){a=this._.blocks[a];var b=this._.currentBlock,d=!this.forceIFrame||CKEDITOR.env.ie?this._.holder:this.document.getById(this.id+"_frame");b&&b.hide();this._.currentBlock=a;CKEDITOR.fire("ariaWidget",d);a._.focusIndex=-1;this._.onKeyDown=a.onKeyDown&&CKEDITOR.tools.bind(a.onKeyDown,a);a.show();return a},destroy:function(){this.element&&this.element.remove()}};CKEDITOR.ui.panel.block=
+CKEDITOR.tools.createClass({$:function(a,b){this.element=a.append(a.getDocument().createElement("div",{attributes:{tabindex:-1,"class":"cke_panel_block"},styles:{display:"none"}}));b&&CKEDITOR.tools.extend(this,b);this.element.setAttributes({role:this.attributes.role||"presentation","aria-label":this.attributes["aria-label"],title:this.attributes.title||this.attributes["aria-label"]});this.keys={};this._.focusIndex=-1;this.element.disableContextMenu()},_:{markItem:function(a){-1!=a&&(a=this.element.getElementsByTag("a").getItem(this._.focusIndex=
+a),CKEDITOR.env.webkit&&a.getDocument().getWindow().focus(),a.focus(),this.onMark&&this.onMark(a))}},proto:{show:function(){this.element.setStyle("display","")},hide:function(){this.onHide&&!0===this.onHide.call(this)||this.element.setStyle("display","none")},onKeyDown:function(a,b){var d=this.keys[a];switch(d){case "next":for(var e=this._.focusIndex,d=this.element.getElementsByTag("a"),c;c=d.getItem(++e);)if(c.getAttribute("_cke_focus")&&c.$.offsetWidth){this._.focusIndex=e;c.focus();break}return c||
+b?!1:(this._.focusIndex=-1,this.onKeyDown(a,1));case "prev":e=this._.focusIndex;for(d=this.element.getElementsByTag("a");0<e&&(c=d.getItem(--e));){if(c.getAttribute("_cke_focus")&&c.$.offsetWidth){this._.focusIndex=e;c.focus();break}c=null}return c||b?!1:(this._.focusIndex=d.count(),this.onKeyDown(a,1));case "click":case "mouseup":return e=this._.focusIndex,(c=0<=e&&this.element.getElementsByTag("a").getItem(e))&&(c.$[d]?c.$[d]():c.$["on"+d]()),!1}return!0}}})})();CKEDITOR.plugins.add("floatpanel",{requires:"panel"});
+(function(){function v(a,b,c,l,h){h=CKEDITOR.tools.genKey(b.getUniqueId(),c.getUniqueId(),a.lang.dir,a.uiColor||"",l.css||"",h||"");var g=f[h];g||(g=f[h]=new CKEDITOR.ui.panel(b,l),g.element=c.append(CKEDITOR.dom.element.createFromHtml(g.render(a),b)),g.element.setStyles({display:"none",position:"absolute"}));return g}var f={};CKEDITOR.ui.floatPanel=CKEDITOR.tools.createClass({$:function(a,b,c,l){function h(){e.hide()}c.forceIFrame=1;c.toolbarRelated&&a.elementMode==CKEDITOR.ELEMENT_MODE_INLINE&&
+(b=CKEDITOR.document.getById("cke_"+a.name));var g=b.getDocument();l=v(a,g,b,c,l||0);var m=l.element,p=m.getFirst(),e=this;m.disableContextMenu();this.element=m;this._={editor:a,panel:l,parentElement:b,definition:c,document:g,iframe:p,children:[],dir:a.lang.dir,showBlockParams:null};a.on("mode",h);a.on("resize",h);g.getWindow().on("resize",function(){this.reposition()},this)},proto:{addBlock:function(a,b){return this._.panel.addBlock(a,b)},addListBlock:function(a,b){return this._.panel.addListBlock(a,
+b)},getBlock:function(a){return this._.panel.getBlock(a)},showBlock:function(a,b,c,l,h,g){var m=this._.panel,p=m.showBlock(a);this._.showBlockParams=[].slice.call(arguments);this.allowBlur(!1);var e=this._.editor.editable();this._.returnFocus=e.hasFocus?e:new CKEDITOR.dom.element(CKEDITOR.document.$.activeElement);this._.hideTimeout=0;var k=this.element,e=this._.iframe,e=CKEDITOR.env.ie&&!CKEDITOR.env.edge?e:new CKEDITOR.dom.window(e.$.contentWindow),f=k.getDocument(),r=this._.parentElement.getPositionedAncestor(),
+t=b.getDocumentPosition(f),f=r?r.getDocumentPosition(f):{x:0,y:0},q="rtl"==this._.dir,d=t.x+(l||0)-f.x,n=t.y+(h||0)-f.y;!q||1!=c&&4!=c?q||2!=c&&3!=c||(d+=b.$.offsetWidth-1):d+=b.$.offsetWidth;if(3==c||4==c)n+=b.$.offsetHeight-1;this._.panel._.offsetParentId=b.getId();k.setStyles({top:n+"px",left:0,display:""});k.setOpacity(0);k.getFirst().removeStyle("width");this._.editor.focusManager.add(e);this._.blurSet||(CKEDITOR.event.useCapture=!0,e.on("blur",function(a){function u(){delete this._.returnFocus;
+this.hide()}this.allowBlur()&&a.data.getPhase()==CKEDITOR.EVENT_PHASE_AT_TARGET&&this.visible&&!this._.activeChild&&(CKEDITOR.env.iOS?this._.hideTimeout||(this._.hideTimeout=CKEDITOR.tools.setTimeout(u,0,this)):u.call(this))},this),e.on("focus",function(){this._.focused=!0;this.hideChild();this.allowBlur(!0)},this),CKEDITOR.env.iOS&&(e.on("touchstart",function(){clearTimeout(this._.hideTimeout)},this),e.on("touchend",function(){this._.hideTimeout=0;this.focus()},this)),CKEDITOR.event.useCapture=!1,
+this._.blurSet=1);m.onEscape=CKEDITOR.tools.bind(function(a){if(this.onEscape&&!1===this.onEscape(a))return!1},this);CKEDITOR.tools.setTimeout(function(){var a=CKEDITOR.tools.bind(function(){var a=k;a.removeStyle("width");if(p.autoSize){var b=p.element.getDocument(),b=(CKEDITOR.env.webkit||CKEDITOR.env.edge?p.element:b.getBody()).$.scrollWidth;CKEDITOR.env.ie&&CKEDITOR.env.quirks&&0<b&&(b+=(a.$.offsetWidth||0)-(a.$.clientWidth||0)+3);a.setStyle("width",b+10+"px");b=p.element.$.scrollHeight;CKEDITOR.env.ie&&
+CKEDITOR.env.quirks&&0<b&&(b+=(a.$.offsetHeight||0)-(a.$.clientHeight||0)+3);a.setStyle("height",b+"px");m._.currentBlock.element.setStyle("display","none").removeStyle("display")}else a.removeStyle("height");q&&(d-=k.$.offsetWidth);k.setStyle("left",d+"px");var b=m.element.getWindow(),a=k.$.getBoundingClientRect(),b=b.getViewPaneSize(),c=a.width||a.right-a.left,e=a.height||a.bottom-a.top,l=q?a.right:b.width-a.left,h=q?b.width-a.right:a.left;q?l<c&&(d=h>c?d+c:b.width>c?d-a.left:d-a.right+b.width):
+l<c&&(d=h>c?d-c:b.width>c?d-a.right+b.width:d-a.left);c=a.top;b.height-a.top<e&&(n=c>e?n-e:b.height>e?n-a.bottom+b.height:n-a.top);CKEDITOR.env.ie&&(b=a=new CKEDITOR.dom.element(k.$.offsetParent),"html"==b.getName()&&(b=b.getDocument().getBody()),"rtl"==b.getComputedStyle("direction")&&(d=CKEDITOR.env.ie8Compat?d-2*k.getDocument().getDocumentElement().$.scrollLeft:d-(a.$.scrollWidth-a.$.clientWidth)));var a=k.getFirst(),f;(f=a.getCustomData("activePanel"))&&f.onHide&&f.onHide.call(this,1);a.setCustomData("activePanel",
+this);k.setStyles({top:n+"px",left:d+"px"});k.setOpacity(1);g&&g()},this);m.isLoaded?a():m.onLoad=a;CKEDITOR.tools.setTimeout(function(){var a=CKEDITOR.env.webkit&&CKEDITOR.document.getWindow().getScrollPosition().y;this.focus();p.element.focus();CKEDITOR.env.webkit&&(CKEDITOR.document.getBody().$.scrollTop=a);this.allowBlur(!0);this._.editor.fire("panelShow",this)},0,this)},CKEDITOR.env.air?200:0,this);this.visible=1;this.onShow&&this.onShow.call(this)},reposition:function(){var a=this._.showBlockParams;
+this.visible&&this._.showBlockParams&&(this.hide(),this.showBlock.apply(this,a))},focus:function(){if(CKEDITOR.env.webkit){var a=CKEDITOR.document.getActive();a&&!a.equals(this._.iframe)&&a.$.blur()}(this._.lastFocused||this._.iframe.getFrameDocument().getWindow()).focus()},blur:function(){var a=this._.iframe.getFrameDocument().getActive();a&&a.is("a")&&(this._.lastFocused=a)},hide:function(a){if(this.visible&&(!this.onHide||!0!==this.onHide.call(this))){this.hideChild();CKEDITOR.env.gecko&&this._.iframe.getFrameDocument().$.activeElement.blur();
+this.element.setStyle("display","none");this.visible=0;this.element.getFirst().removeCustomData("activePanel");if(a=a&&this._.returnFocus)CKEDITOR.env.webkit&&a.type&&a.getWindow().$.focus(),a.focus();delete this._.lastFocused;this._.showBlockParams=null;this._.editor.fire("panelHide",this)}},allowBlur:function(a){var b=this._.panel;void 0!==a&&(b.allowBlur=a);return b.allowBlur},showAsChild:function(a,b,c,f,h,g){if(this._.activeChild!=a||a._.panel._.offsetParentId!=c.getId())this.hideChild(),a.onHide=
+CKEDITOR.tools.bind(function(){CKEDITOR.tools.setTimeout(function(){this._.focused||this.hide()},0,this)},this),this._.activeChild=a,this._.focused=!1,a.showBlock(b,c,f,h,g),this.blur(),(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)&&setTimeout(function(){a.element.getChild(0).$.style.cssText+=""},100)},hideChild:function(a){var b=this._.activeChild;b&&(delete b.onHide,delete this._.activeChild,b.hide(),a&&this.focus())}}});CKEDITOR.on("instanceDestroyed",function(){var a=CKEDITOR.tools.isEmpty(CKEDITOR.instances),
+b;for(b in f){var c=f[b];a?c.destroy():c.element.hide()}a&&(f={})})})();CKEDITOR.plugins.add("menu",{requires:"floatpanel",beforeInit:function(l){for(var h=l.config.menu_groups.split(","),r=l._.menuGroups={},t=l._.menuItems={},n=0;n<h.length;n++)r[h[n]]=n+1;l.addMenuGroup=function(a,b){r[a]=b||100};l.addMenuItem=function(a,b){r[b.group]&&(t[a]=new CKEDITOR.menuItem(this,a,b))};l.addMenuItems=function(a){for(var b in a)this.addMenuItem(b,a[b])};l.getMenuItem=function(a){return t[a]};l.removeMenuItem=function(a){delete t[a]}}});
+(function(){function l(a){a.sort(function(a,d){return a.group<d.group?-1:a.group>d.group?1:a.order<d.order?-1:a.order>d.order?1:0})}var h='\x3cspan class\x3d"cke_menuitem"\x3e\x3ca id\x3d"{id}" class\x3d"cke_menubutton cke_menubutton__{name} cke_menubutton_{state} {cls}" href\x3d"{href}" title\x3d"{title}" tabindex\x3d"-1" _cke_focus\x3d1 hidefocus\x3d"true" role\x3d"{role}" aria-label\x3d"{label}" aria-describedby\x3d"{id}_description" aria-haspopup\x3d"{hasPopup}" aria-disabled\x3d"{disabled}" {ariaChecked} draggable\x3d"false"';
+CKEDITOR.env.gecko&&CKEDITOR.env.mac&&(h+=' onkeypress\x3d"return false;"');CKEDITOR.env.gecko&&(h+=' onblur\x3d"this.style.cssText \x3d this.style.cssText;" ondragstart\x3d"return false;"');var h=h+(' onmouseover\x3d"CKEDITOR.tools.callFunction({hoverFn},{index});" onmouseout\x3d"CKEDITOR.tools.callFunction({moveOutFn},{index});" '+(CKEDITOR.env.ie?'onclick\x3d"return false;" onmouseup':"onclick")+'\x3d"CKEDITOR.tools.callFunction({clickFn},{index}); return false;"\x3e'),r=CKEDITOR.addTemplate("menuItem",
+h+'\x3cspan class\x3d"cke_menubutton_inner"\x3e\x3cspan class\x3d"cke_menubutton_icon"\x3e\x3cspan class\x3d"cke_button_icon cke_button__{iconName}_icon" style\x3d"{iconStyle}"\x3e\x3c/span\x3e\x3c/span\x3e\x3cspan class\x3d"cke_menubutton_label"\x3e{label}\x3c/span\x3e{shortcutHtml}{arrowHtml}\x3c/span\x3e\x3c/a\x3e\x3cspan id\x3d"{id}_description" class\x3d"cke_voice_label" aria-hidden\x3d"false"\x3e{ariaShortcut}\x3c/span\x3e\x3c/span\x3e'),t=CKEDITOR.addTemplate("menuArrow",'\x3cspan class\x3d"cke_menuarrow"\x3e\x3cspan\x3e{label}\x3c/span\x3e\x3c/span\x3e'),
+n=CKEDITOR.addTemplate("menuShortcut",'\x3cspan class\x3d"cke_menubutton_label cke_menubutton_shortcut"\x3e{shortcut}\x3c/span\x3e');CKEDITOR.menu=CKEDITOR.tools.createClass({$:function(a,b){b=this._.definition=b||{};this.id=CKEDITOR.tools.getNextId();this.editor=a;this.items=[];this._.listeners=[];this._.level=b.level||1;var d=CKEDITOR.tools.extend({},b.panel,{css:[CKEDITOR.skin.getPath("editor")],level:this._.level-1,block:{}}),m=d.block.attributes=d.attributes||{};!m.role&&(m.role="menu");this._.panelDefinition=
+d},_:{onShow:function(){var a=this.editor.getSelection(),b=a&&a.getStartElement(),d=this.editor.elementPath(),m=this._.listeners;this.removeAll();for(var g=0;g<m.length;g++){var k=m[g](b,a,d);if(k)for(var e in k){var f=this.editor.getMenuItem(e);!f||f.command&&!this.editor.getCommand(f.command).state||(f.state=k[e],this.add(f))}}},onClick:function(a){this.hide();if(a.onClick)a.onClick();else a.command&&this.editor.execCommand(a.command)},onEscape:function(a){var b=this.parent;b?b._.panel.hideChild(1):
+27==a&&this.hide(1);return!1},onHide:function(){this.onHide&&this.onHide()},showSubMenu:function(a){var b=this._.subMenu,d=this.items[a];if(d=d.getItems&&d.getItems()){b?b.removeAll():(b=this._.subMenu=new CKEDITOR.menu(this.editor,CKEDITOR.tools.extend({},this._.definition,{level:this._.level+1},!0)),b.parent=this,b._.onClick=CKEDITOR.tools.bind(this._.onClick,this));for(var m in d){var g=this.editor.getMenuItem(m);g&&(g.state=d[m],b.add(g))}var k=this._.panel.getBlock(this.id).element.getDocument().getById(this.id+
+String(a));setTimeout(function(){b.show(k,2)},0)}else this._.panel.hideChild(1)}},proto:{add:function(a){a.order||(a.order=this.items.length);this.items.push(a)},removeAll:function(){this.items=[]},show:function(a,b,d,m){if(!this.parent&&(this._.onShow(),!this.items.length))return;b=b||("rtl"==this.editor.lang.dir?2:1);var g=this.items,k=this.editor,e=this._.panel,f=this._.element;if(!e){e=this._.panel=new CKEDITOR.ui.floatPanel(this.editor,CKEDITOR.document.getBody(),this._.panelDefinition,this._.level);
+e.onEscape=CKEDITOR.tools.bind(function(a){if(!1===this._.onEscape(a))return!1},this);e.onShow=function(){e._.panel.getHolderElement().getParent().addClass("cke").addClass("cke_reset_all")};e.onHide=CKEDITOR.tools.bind(function(){this._.onHide&&this._.onHide()},this);f=e.addBlock(this.id,this._.panelDefinition.block);f.autoSize=!0;var c=f.keys;c[40]="next";c[9]="next";c[38]="prev";c[CKEDITOR.SHIFT+9]="prev";c["rtl"==k.lang.dir?37:39]=CKEDITOR.env.ie?"mouseup":"click";c[32]=CKEDITOR.env.ie?"mouseup":
+"click";CKEDITOR.env.ie&&(c[13]="mouseup");f=this._.element=f.element;c=f.getDocument();c.getBody().setStyle("overflow","hidden");c.getElementsByTag("html").getItem(0).setStyle("overflow","hidden");this._.itemOverFn=CKEDITOR.tools.addFunction(function(a){clearTimeout(this._.showSubTimeout);this._.showSubTimeout=CKEDITOR.tools.setTimeout(this._.showSubMenu,k.config.menu_subMenuDelay||400,this,[a])},this);this._.itemOutFn=CKEDITOR.tools.addFunction(function(){clearTimeout(this._.showSubTimeout)},this);
+this._.itemClickFn=CKEDITOR.tools.addFunction(function(a){var b=this.items[a];if(b.state==CKEDITOR.TRISTATE_DISABLED)this.hide(1);else if(b.getItems)this._.showSubMenu(a);else this._.onClick(b)},this)}l(g);for(var c=k.elementPath(),c=['\x3cdiv class\x3d"cke_menu'+(c&&c.direction()!=k.lang.dir?" cke_mixed_dir_content":"")+'" role\x3d"presentation"\x3e'],h=g.length,n=h&&g[0].group,q=0;q<h;q++){var p=g[q];n!=p.group&&(c.push('\x3cdiv class\x3d"cke_menuseparator" role\x3d"separator"\x3e\x3c/div\x3e'),
+n=p.group);p.render(this,q,c)}c.push("\x3c/div\x3e");f.setHtml(c.join(""));CKEDITOR.ui.fire("ready",this);this.parent?this.parent._.panel.showAsChild(e,this.id,a,b,d,m):e.showBlock(this.id,a,b,d,m);k.fire("menuShow",[e])},addListener:function(a){this._.listeners.push(a)},hide:function(a){this._.onHide&&this._.onHide();this._.panel&&this._.panel.hide(a)}}});CKEDITOR.menuItem=CKEDITOR.tools.createClass({$:function(a,b,d){CKEDITOR.tools.extend(this,d,{order:0,className:"cke_menubutton__"+b});this.group=
+a._.menuGroups[this.group];this.editor=a;this.name=b},proto:{render:function(a,b,d){var h=a.id+String(b),g="undefined"==typeof this.state?CKEDITOR.TRISTATE_OFF:this.state,k="",e=this.editor,f,c,l=g==CKEDITOR.TRISTATE_ON?"on":g==CKEDITOR.TRISTATE_DISABLED?"disabled":"off";this.role in{menuitemcheckbox:1,menuitemradio:1}&&(k=' aria-checked\x3d"'+(g==CKEDITOR.TRISTATE_ON?"true":"false")+'"');var u=this.getItems,q="\x26#"+("rtl"==this.editor.lang.dir?"9668":"9658")+";",p=this.name;this.icon&&!/\./.test(this.icon)&&
+(p=this.icon);this.command&&(f=e.getCommand(this.command),(f=e.getCommandKeystroke(f))&&(c=CKEDITOR.tools.keystrokeToString(e.lang.common.keyboard,f)));a={id:h,name:this.name,iconName:p,label:this.label,cls:this.className||"",state:l,hasPopup:u?"true":"false",disabled:g==CKEDITOR.TRISTATE_DISABLED,title:this.label+(c?" ("+c.display+")":""),ariaShortcut:c?e.lang.common.keyboardShortcut+" "+c.aria:"",href:"javascript:void('"+(this.label||"").replace("'")+"')",hoverFn:a._.itemOverFn,moveOutFn:a._.itemOutFn,
+clickFn:a._.itemClickFn,index:b,iconStyle:CKEDITOR.skin.getIconStyle(p,"rtl"==this.editor.lang.dir,p==this.icon?null:this.icon,this.iconOffset),shortcutHtml:c?n.output({shortcut:c.display}):"",arrowHtml:u?t.output({label:q}):"",role:this.role?this.role:"menuitem",ariaChecked:k};r.output(a,d)}}})})();CKEDITOR.config.menu_groups="clipboard,form,tablecell,tablecellproperties,tablerow,tablecolumn,table,anchor,link,image,flash,checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div";CKEDITOR.plugins.add("contextmenu",{requires:"menu",onLoad:function(){CKEDITOR.plugins.contextMenu=CKEDITOR.tools.createClass({base:CKEDITOR.menu,$:function(a){this.base.call(this,a,{panel:{className:"cke_menu_panel",attributes:{"aria-label":a.lang.contextmenu.options}}})},proto:{addTarget:function(a,e){a.on("contextmenu",function(a){a=a.data;var c=CKEDITOR.env.webkit?f:CKEDITOR.env.mac?a.$.metaKey:a.$.ctrlKey;if(!e||!c){a.preventDefault();if(CKEDITOR.env.mac&&CKEDITOR.env.webkit){var c=this.editor,
+b=(new CKEDITOR.dom.elementPath(a.getTarget(),c.editable())).contains(function(a){return a.hasAttribute("contenteditable")},!0);b&&"false"==b.getAttribute("contenteditable")&&c.getSelection().fake(b)}var b=a.getTarget().getDocument(),d=a.getTarget().getDocument().getDocumentElement(),c=!b.equals(CKEDITOR.document),b=b.getWindow().getScrollPosition(),g=c?a.$.clientX:a.$.pageX||b.x+a.$.clientX,h=c?a.$.clientY:a.$.pageY||b.y+a.$.clientY;CKEDITOR.tools.setTimeout(function(){this.open(d,null,g,h)},CKEDITOR.env.ie?
+200:0,this)}},this);if(CKEDITOR.env.webkit){var f,d=function(){f=0};a.on("keydown",function(a){f=CKEDITOR.env.mac?a.data.$.metaKey:a.data.$.ctrlKey});a.on("keyup",d);a.on("contextmenu",d)}},open:function(a,e,f,d){this.editor.focus();a=a||CKEDITOR.document.getDocumentElement();this.editor.selectionChange(1);this.show(a,e,f,d)}}})},beforeInit:function(a){var e=a.contextMenu=new CKEDITOR.plugins.contextMenu(a);a.on("contentDom",function(){e.addTarget(a.editable(),!1!==a.config.browserContextMenuOnCtrl)});
+a.addCommand("contextMenu",{exec:function(){a.contextMenu.open(a.document.getBody())}});a.setKeystroke(CKEDITOR.SHIFT+121,"contextMenu");a.setKeystroke(CKEDITOR.CTRL+CKEDITOR.SHIFT+121,"contextMenu")}});CKEDITOR.plugins.add("resize",{init:function(b){function f(d){var e=c.width,m=c.height,f=e+(d.data.$.screenX-n.x)*("rtl"==g?-1:1);d=m+(d.data.$.screenY-n.y);h&&(e=Math.max(a.resize_minWidth,Math.min(f,a.resize_maxWidth)));p&&(m=Math.max(a.resize_minHeight,Math.min(d,a.resize_maxHeight)));b.resize(h?e:null,m)}function k(){CKEDITOR.document.removeListener("mousemove",f);CKEDITOR.document.removeListener("mouseup",k);b.document&&(b.document.removeListener("mousemove",f),b.document.removeListener("mouseup",
+k))}var a=b.config,r=b.ui.spaceId("resizer"),g=b.element?b.element.getDirection(1):"ltr";!a.resize_dir&&(a.resize_dir="vertical");void 0===a.resize_maxWidth&&(a.resize_maxWidth=3E3);void 0===a.resize_maxHeight&&(a.resize_maxHeight=3E3);void 0===a.resize_minWidth&&(a.resize_minWidth=750);void 0===a.resize_minHeight&&(a.resize_minHeight=250);if(!1!==a.resize_enabled){var l=null,n,c,h=("both"==a.resize_dir||"horizontal"==a.resize_dir)&&a.resize_minWidth!=a.resize_maxWidth,p=("both"==a.resize_dir||"vertical"==
+a.resize_dir)&&a.resize_minHeight!=a.resize_maxHeight,q=CKEDITOR.tools.addFunction(function(d){l||(l=b.getResizable());c={width:l.$.offsetWidth||0,height:l.$.offsetHeight||0};n={x:d.screenX,y:d.screenY};a.resize_minWidth>c.width&&(a.resize_minWidth=c.width);a.resize_minHeight>c.height&&(a.resize_minHeight=c.height);CKEDITOR.document.on("mousemove",f);CKEDITOR.document.on("mouseup",k);b.document&&(b.document.on("mousemove",f),b.document.on("mouseup",k));d.preventDefault&&d.preventDefault()});b.on("destroy",
+function(){CKEDITOR.tools.removeFunction(q)});b.on("uiSpace",function(a){if("bottom"==a.data.space){var e="";h&&!p&&(e=" cke_resizer_horizontal");!h&&p&&(e=" cke_resizer_vertical");var c='\x3cspan id\x3d"'+r+'" class\x3d"cke_resizer'+e+" cke_resizer_"+g+'" title\x3d"'+CKEDITOR.tools.htmlEncode(b.lang.common.resize)+'" onmousedown\x3d"CKEDITOR.tools.callFunction('+q+', event)"\x3e'+("ltr"==g?"◢":"◣")+"\x3c/span\x3e";"ltr"==g&&"ltr"==e?a.data.html+=c:a.data.html=c+a.data.html}},b,null,100);b.on("maximize",
+function(a){b.ui.space("resizer")[a.data==CKEDITOR.TRISTATE_ON?"hide":"show"]()})}}});(function(){var c='\x3ca id\x3d"{id}" class\x3d"cke_button cke_button__{name} cke_button_{state} {cls}"'+(CKEDITOR.env.gecko&&!CKEDITOR.env.hc?"":" href\x3d\"javascript:void('{titleJs}')\"")+' title\x3d"{title}" tabindex\x3d"-1" hidefocus\x3d"true" role\x3d"button" aria-labelledby\x3d"{id}_label" aria-describedby\x3d"{id}_description" aria-haspopup\x3d"{hasArrow}" aria-disabled\x3d"{ariaDisabled}"';CKEDITOR.env.gecko&&CKEDITOR.env.mac&&(c+=' onkeypress\x3d"return false;"');CKEDITOR.env.gecko&&(c+=
+' onblur\x3d"this.style.cssText \x3d this.style.cssText;"');var c=c+(' onkeydown\x3d"return CKEDITOR.tools.callFunction({keydownFn},event);" onfocus\x3d"return CKEDITOR.tools.callFunction({focusFn},event);" '+(CKEDITOR.env.ie?'onclick\x3d"return false;" onmouseup':"onclick")+'\x3d"CKEDITOR.tools.callFunction({clickFn},this);return false;"\x3e\x3cspan class\x3d"cke_button_icon cke_button__{iconName}_icon" style\x3d"{style}"'),c=c+'\x3e\x26nbsp;\x3c/span\x3e\x3cspan id\x3d"{id}_label" class\x3d"cke_button_label cke_button__{name}_label" aria-hidden\x3d"false"\x3e{label}\x3c/span\x3e\x3cspan id\x3d"{id}_description" class\x3d"cke_button_label" aria-hidden\x3d"false"\x3e{ariaShortcut}\x3c/span\x3e{arrowHtml}\x3c/a\x3e',
+t=CKEDITOR.addTemplate("buttonArrow",'\x3cspan class\x3d"cke_button_arrow"\x3e'+(CKEDITOR.env.hc?"\x26#9660;":"")+"\x3c/span\x3e"),u=CKEDITOR.addTemplate("button",c);CKEDITOR.plugins.add("button",{beforeInit:function(a){a.ui.addHandler(CKEDITOR.UI_BUTTON,CKEDITOR.ui.button.handler)}});CKEDITOR.UI_BUTTON="button";CKEDITOR.ui.button=function(a){CKEDITOR.tools.extend(this,a,{title:a.label,click:a.click||function(b){b.execCommand(a.command)}});this._={}};CKEDITOR.ui.button.handler={create:function(a){return new CKEDITOR.ui.button(a)}};
+CKEDITOR.ui.button.prototype={render:function(a,b){function c(){var f=a.mode;f&&(f=this.modes[f]?void 0!==m[f]?m[f]:CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED,f=a.readOnly&&!this.readOnly?CKEDITOR.TRISTATE_DISABLED:f,this.setState(f),this.refresh&&this.refresh())}var n=CKEDITOR.env,p=this._.id=CKEDITOR.tools.getNextId(),g="",d=this.command,q,k,h;this._.editor=a;var e={id:p,button:this,editor:a,focus:function(){CKEDITOR.document.getById(p).focus()},execute:function(){this.button.click(a)},attach:function(a){this.button.attach(a)}},
+v=CKEDITOR.tools.addFunction(function(a){if(e.onkey)return a=new CKEDITOR.dom.event(a),!1!==e.onkey(e,a.getKeystroke())}),w=CKEDITOR.tools.addFunction(function(a){var b;e.onfocus&&(b=!1!==e.onfocus(e,new CKEDITOR.dom.event(a)));return b}),r=0;e.clickFn=q=CKEDITOR.tools.addFunction(function(){r&&(a.unlockSelection(1),r=0);e.execute();n.iOS&&a.focus()});if(this.modes){var m={};a.on("beforeModeUnload",function(){a.mode&&this._.state!=CKEDITOR.TRISTATE_DISABLED&&(m[a.mode]=this._.state)},this);a.on("activeFilterChange",
+c,this);a.on("mode",c,this);!this.readOnly&&a.on("readOnly",c,this)}else d&&(d=a.getCommand(d))&&(d.on("state",function(){this.setState(d.state)},this),g+=d.state==CKEDITOR.TRISTATE_ON?"on":d.state==CKEDITOR.TRISTATE_DISABLED?"disabled":"off");if(this.directional)a.on("contentDirChanged",function(b){var c=CKEDITOR.document.getById(this._.id),d=c.getFirst();b=b.data;b!=a.lang.dir?c.addClass("cke_"+b):c.removeClass("cke_ltr").removeClass("cke_rtl");d.setAttribute("style",CKEDITOR.skin.getIconStyle(l,
+"rtl"==b,this.icon,this.iconOffset))},this);d?(k=a.getCommandKeystroke(d))&&(h=CKEDITOR.tools.keystrokeToString(a.lang.common.keyboard,k)):g+="off";var l=k=this.name||this.command;this.icon&&!/\./.test(this.icon)&&(l=this.icon,this.icon=null);g={id:p,name:k,iconName:l,label:this.label,cls:this.className||"",state:g,ariaDisabled:"disabled"==g?"true":"false",title:this.title+(h?" ("+h.display+")":""),ariaShortcut:h?a.lang.common.keyboardShortcut+" "+h.aria:"",titleJs:n.gecko&&!n.hc?"":(this.title||
+"").replace("'",""),hasArrow:this.hasArrow?"true":"false",keydownFn:v,focusFn:w,clickFn:q,style:CKEDITOR.skin.getIconStyle(l,"rtl"==a.lang.dir,this.icon,this.iconOffset),arrowHtml:this.hasArrow?t.output():""};u.output(g,b);if(this.onRender)this.onRender();return e},setState:function(a){if(this._.state==a)return!1;this._.state=a;var b=CKEDITOR.document.getById(this._.id);return b?(b.setState(a,"cke_button"),a==CKEDITOR.TRISTATE_DISABLED?b.setAttribute("aria-disabled",!0):b.removeAttribute("aria-disabled"),
+this.hasArrow?(a=a==CKEDITOR.TRISTATE_ON?this._.editor.lang.button.selectedLabel.replace(/%1/g,this.label):this.label,CKEDITOR.document.getById(this._.id+"_label").setText(a)):a==CKEDITOR.TRISTATE_ON?b.setAttribute("aria-pressed",!0):b.removeAttribute("aria-pressed"),!0):!1},getState:function(){return this._.state},toFeature:function(a){if(this._.feature)return this._.feature;var b=this;this.allowedContent||this.requiredContent||!this.command||(b=a.getCommand(this.command)||b);return this._.feature=
+b}};CKEDITOR.ui.prototype.addButton=function(a,b){this.add(a,CKEDITOR.UI_BUTTON,b)}})();(function(){function D(a){function d(){for(var b=g(),e=CKEDITOR.tools.clone(a.config.toolbarGroups)||v(a),f=0;f<e.length;f++){var m=e[f];if("/"!=m){"string"==typeof m&&(m=e[f]={name:m});var l,d=m.groups;if(d)for(var h=0;h<d.length;h++)l=d[h],(l=b[l])&&c(m,l);(l=b[m.name])&&c(m,l)}}return e}function g(){var b={},c,f,e;for(c in a.ui.items)f=a.ui.items[c],e=f.toolbar||"others",e=e.split(","),f=e[0],e=parseInt(e[1]||-1,10),b[f]||(b[f]=[]),b[f].push({name:c,order:e});for(f in b)b[f]=b[f].sort(function(b,
+a){return b.order==a.order?0:0>a.order?-1:0>b.order?1:b.order<a.order?-1:1});return b}function c(c,e){if(e.length){c.items?c.items.push(a.ui.create("-")):c.items=[];for(var f;f=e.shift();)f="string"==typeof f?f:f.name,b&&-1!=CKEDITOR.tools.indexOf(b,f)||(f=a.ui.create(f))&&a.addFeature(f)&&c.items.push(f)}}function h(b){var a=[],e,d,h;for(e=0;e<b.length;++e)d=b[e],h={},"/"==d?a.push(d):CKEDITOR.tools.isArray(d)?(c(h,CKEDITOR.tools.clone(d)),a.push(h)):d.items&&(c(h,CKEDITOR.tools.clone(d.items)),
+h.name=d.name,a.push(h));return a}var b=a.config.removeButtons,b=b&&b.split(","),e=a.config.toolbar;"string"==typeof e&&(e=a.config["toolbar_"+e]);return a.toolbar=e?h(e):d()}function v(a){return a._.toolbarGroups||(a._.toolbarGroups=[{name:"document",groups:["mode","document","doctools"]},{name:"clipboard",groups:["clipboard","undo"]},{name:"editing",groups:["find","selection","spellchecker"]},{name:"forms"},"/",{name:"basicstyles",groups:["basicstyles","cleanup"]},{name:"paragraph",groups:["list",
+"indent","blocks","align","bidi"]},{name:"links"},{name:"insert"},"/",{name:"styles"},{name:"colors"},{name:"tools"},{name:"others"},{name:"about"}])}var z=function(){this.toolbars=[];this.focusCommandExecuted=!1};z.prototype.focus=function(){for(var a=0,d;d=this.toolbars[a++];)for(var g=0,c;c=d.items[g++];)if(c.focus){c.focus();return}};var E={modes:{wysiwyg:1,source:1},readOnly:1,exec:function(a){a.toolbox&&(a.toolbox.focusCommandExecuted=!0,CKEDITOR.env.ie||CKEDITOR.env.air?setTimeout(function(){a.toolbox.focus()},
+100):a.toolbox.focus())}};CKEDITOR.plugins.add("toolbar",{requires:"button",init:function(a){var d,g=function(c,h){var b,e="rtl"==a.lang.dir,k=a.config.toolbarGroupCycling,q=e?37:39,e=e?39:37,k=void 0===k||k;switch(h){case 9:case CKEDITOR.SHIFT+9:for(;!b||!b.items.length;)if(b=9==h?(b?b.next:c.toolbar.next)||a.toolbox.toolbars[0]:(b?b.previous:c.toolbar.previous)||a.toolbox.toolbars[a.toolbox.toolbars.length-1],b.items.length)for(c=b.items[d?b.items.length-1:0];c&&!c.focus;)(c=d?c.previous:c.next)||
+(b=0);c&&c.focus();return!1;case q:b=c;do b=b.next,!b&&k&&(b=c.toolbar.items[0]);while(b&&!b.focus);b?b.focus():g(c,9);return!1;case 40:return c.button&&c.button.hasArrow?(a.once("panelShow",function(b){b.data._.panel._.currentBlock.onKeyDown(40)}),c.execute()):g(c,40==h?q:e),!1;case e:case 38:b=c;do b=b.previous,!b&&k&&(b=c.toolbar.items[c.toolbar.items.length-1]);while(b&&!b.focus);b?b.focus():(d=1,g(c,CKEDITOR.SHIFT+9),d=0);return!1;case 27:return a.focus(),!1;case 13:case 32:return c.execute(),
+!1}return!0};a.on("uiSpace",function(c){if(c.data.space==a.config.toolbarLocation){c.removeListener();a.toolbox=new z;var d=CKEDITOR.tools.getNextId(),b=['\x3cspan id\x3d"',d,'" class\x3d"cke_voice_label"\x3e',a.lang.toolbar.toolbars,"\x3c/span\x3e",'\x3cspan id\x3d"'+a.ui.spaceId("toolbox")+'" class\x3d"cke_toolbox" role\x3d"group" aria-labelledby\x3d"',d,'" onmousedown\x3d"return false;"\x3e'],d=!1!==a.config.toolbarStartupExpanded,e,k;a.config.toolbarCanCollapse&&a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE&&
+b.push('\x3cspan class\x3d"cke_toolbox_main"'+(d?"\x3e":' style\x3d"display:none"\x3e'));for(var q=a.toolbox.toolbars,f=D(a),m=f.length,l=0;l<m;l++){var r,n=0,w,p=f[l],v="/"!==p&&("/"===f[l+1]||l==m-1),x;if(p)if(e&&(b.push("\x3c/span\x3e"),k=e=0),"/"===p)b.push('\x3cspan class\x3d"cke_toolbar_break"\x3e\x3c/span\x3e');else{x=p.items||p;for(var y=0;y<x.length;y++){var t=x[y],A;if(t){var B=function(c){c=c.render(a,b);u=n.items.push(c)-1;0<u&&(c.previous=n.items[u-1],c.previous.next=c);c.toolbar=n;c.onkey=
+g;c.onfocus=function(){a.toolbox.focusCommandExecuted||a.focus()}};if(t.type==CKEDITOR.UI_SEPARATOR)k=e&&t;else{A=!1!==t.canGroup;if(!n){r=CKEDITOR.tools.getNextId();n={id:r,items:[]};w=p.name&&(a.lang.toolbar.toolbarGroups[p.name]||p.name);b.push('\x3cspan id\x3d"',r,'" class\x3d"cke_toolbar'+(v?' cke_toolbar_last"':'"'),w?' aria-labelledby\x3d"'+r+'_label"':"",' role\x3d"toolbar"\x3e');w&&b.push('\x3cspan id\x3d"',r,'_label" class\x3d"cke_voice_label"\x3e',w,"\x3c/span\x3e");b.push('\x3cspan class\x3d"cke_toolbar_start"\x3e\x3c/span\x3e');
+var u=q.push(n)-1;0<u&&(n.previous=q[u-1],n.previous.next=n)}A?e||(b.push('\x3cspan class\x3d"cke_toolgroup" role\x3d"presentation"\x3e'),e=1):e&&(b.push("\x3c/span\x3e"),e=0);k&&(B(k),k=0);B(t)}}}e&&(b.push("\x3c/span\x3e"),k=e=0);n&&b.push('\x3cspan class\x3d"cke_toolbar_end"\x3e\x3c/span\x3e\x3c/span\x3e')}}a.config.toolbarCanCollapse&&b.push("\x3c/span\x3e");if(a.config.toolbarCanCollapse&&a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var C=CKEDITOR.tools.addFunction(function(){a.execCommand("toolbarCollapse")});
+a.on("destroy",function(){CKEDITOR.tools.removeFunction(C)});a.addCommand("toolbarCollapse",{readOnly:1,exec:function(b){var a=b.ui.space("toolbar_collapser"),c=a.getPrevious(),e=b.ui.space("contents"),d=c.getParent(),f=parseInt(e.$.style.height,10),h=d.$.offsetHeight,g=a.hasClass("cke_toolbox_collapser_min");g?(c.show(),a.removeClass("cke_toolbox_collapser_min"),a.setAttribute("title",b.lang.toolbar.toolbarCollapse)):(c.hide(),a.addClass("cke_toolbox_collapser_min"),a.setAttribute("title",b.lang.toolbar.toolbarExpand));
+a.getFirst().setText(g?"▲":"◀");e.setStyle("height",f-(d.$.offsetHeight-h)+"px");b.fire("resize",{outerHeight:b.container.$.offsetHeight,contentsHeight:e.$.offsetHeight,outerWidth:b.container.$.offsetWidth})},modes:{wysiwyg:1,source:1}});a.setKeystroke(CKEDITOR.ALT+(CKEDITOR.env.ie||CKEDITOR.env.webkit?189:109),"toolbarCollapse");b.push('\x3ca title\x3d"'+(d?a.lang.toolbar.toolbarCollapse:a.lang.toolbar.toolbarExpand)+'" id\x3d"'+a.ui.spaceId("toolbar_collapser")+'" tabIndex\x3d"-1" class\x3d"cke_toolbox_collapser');
+d||b.push(" cke_toolbox_collapser_min");b.push('" onclick\x3d"CKEDITOR.tools.callFunction('+C+')"\x3e','\x3cspan class\x3d"cke_arrow"\x3e\x26#9650;\x3c/span\x3e',"\x3c/a\x3e")}b.push("\x3c/span\x3e");c.data.html+=b.join("")}});a.on("destroy",function(){if(this.toolbox){var a,d=0,b,e,g;for(a=this.toolbox.toolbars;d<a.length;d++)for(e=a[d].items,b=0;b<e.length;b++)g=e[b],g.clickFn&&CKEDITOR.tools.removeFunction(g.clickFn),g.keyDownFn&&CKEDITOR.tools.removeFunction(g.keyDownFn)}});a.on("uiReady",function(){var c=
+a.ui.space("toolbox");c&&a.focusManager.add(c,1)});a.addCommand("toolbarFocus",E);a.setKeystroke(CKEDITOR.ALT+121,"toolbarFocus");a.ui.add("-",CKEDITOR.UI_SEPARATOR,{});a.ui.addHandler(CKEDITOR.UI_SEPARATOR,{create:function(){return{render:function(a,d){d.push('\x3cspan class\x3d"cke_toolbar_separator" role\x3d"separator"\x3e\x3c/span\x3e');return{}}}}})}});CKEDITOR.ui.prototype.addToolbarGroup=function(a,d,g){var c=v(this.editor),h=0===d,b={name:a};if(g){if(g=CKEDITOR.tools.search(c,function(a){return a.name==
+g})){!g.groups&&(g.groups=[]);if(d&&(d=CKEDITOR.tools.indexOf(g.groups,d),0<=d)){g.groups.splice(d+1,0,a);return}h?g.groups.splice(0,0,a):g.groups.push(a);return}d=null}d&&(d=CKEDITOR.tools.indexOf(c,function(a){return a.name==d}));h?c.splice(0,0,a):"number"==typeof d?c.splice(d+1,0,b):c.push(a)}})();CKEDITOR.UI_SEPARATOR="separator";CKEDITOR.config.toolbarLocation="top";(function(){function q(a,e){function l(c){c=k.list[c];var d;c.equals(a.editable())||"true"==c.getAttribute("contenteditable")?(d=a.createRange(),d.selectNodeContents(c),d=d.select()):(d=a.getSelection(),d.selectElement(c));CKEDITOR.env.ie&&a.fire("selectionChange",{selection:d,path:new CKEDITOR.dom.elementPath(c)});a.focus()}function m(){n&&n.setHtml('\x3cspan class\x3d"cke_path_empty"\x3e\x26nbsp;\x3c/span\x3e');delete k.list}var p=a.ui.spaceId("path"),n,k=a._.elementsPath,q=k.idBase;e.html+='\x3cspan id\x3d"'+
+p+'_label" class\x3d"cke_voice_label"\x3e'+a.lang.elementspath.eleLabel+'\x3c/span\x3e\x3cspan id\x3d"'+p+'" class\x3d"cke_path" role\x3d"group" aria-labelledby\x3d"'+p+'_label"\x3e\x3cspan class\x3d"cke_path_empty"\x3e\x26nbsp;\x3c/span\x3e\x3c/span\x3e';a.on("uiReady",function(){var c=a.ui.space("path");c&&a.focusManager.add(c,1)});k.onClick=l;var v=CKEDITOR.tools.addFunction(l),w=CKEDITOR.tools.addFunction(function(c,d){var g=k.idBase,b;d=new CKEDITOR.dom.event(d);b="rtl"==a.lang.dir;switch(d.getKeystroke()){case b?
+39:37:case 9:return(b=CKEDITOR.document.getById(g+(c+1)))||(b=CKEDITOR.document.getById(g+"0")),b.focus(),!1;case b?37:39:case CKEDITOR.SHIFT+9:return(b=CKEDITOR.document.getById(g+(c-1)))||(b=CKEDITOR.document.getById(g+(k.list.length-1))),b.focus(),!1;case 27:return a.focus(),!1;case 13:case 32:return l(c),!1}return!0});a.on("selectionChange",function(){for(var c=[],d=k.list=[],g=[],b=k.filters,e=!0,l=a.elementPath().elements,f,u=l.length;u--;){var h=l[u],r=0;f=h.data("cke-display-name")?h.data("cke-display-name"):
+h.data("cke-real-element-type")?h.data("cke-real-element-type"):h.getName();(e=h.hasAttribute("contenteditable")?"true"==h.getAttribute("contenteditable"):e)||h.hasAttribute("contenteditable")||(r=1);for(var t=0;t<b.length;t++){var m=b[t](h,f);if(!1===m){r=1;break}f=m||f}r||(d.unshift(h),g.unshift(f))}d=d.length;for(b=0;b<d;b++)f=g[b],e=a.lang.elementspath.eleTitle.replace(/%1/,f),f=x.output({id:q+b,label:e,text:f,jsTitle:"javascript:void('"+f+"')",index:b,keyDownFn:w,clickFn:v}),c.unshift(f);n||
+(n=CKEDITOR.document.getById(p));g=n;g.setHtml(c.join("")+'\x3cspan class\x3d"cke_path_empty"\x3e\x26nbsp;\x3c/span\x3e');a.fire("elementsPathUpdate",{space:g})});a.on("readOnly",m);a.on("contentDomUnload",m);a.addCommand("elementsPathFocus",y.toolbarFocus);a.setKeystroke(CKEDITOR.ALT+122,"elementsPathFocus")}var y={toolbarFocus:{editorFocus:!1,readOnly:1,exec:function(a){(a=CKEDITOR.document.getById(a._.elementsPath.idBase+"0"))&&a.focus(CKEDITOR.env.ie||CKEDITOR.env.air)}}},e="";CKEDITOR.env.gecko&&
+CKEDITOR.env.mac&&(e+=' onkeypress\x3d"return false;"');CKEDITOR.env.gecko&&(e+=' onblur\x3d"this.style.cssText \x3d this.style.cssText;"');var x=CKEDITOR.addTemplate("pathItem",'\x3ca id\x3d"{id}" href\x3d"{jsTitle}" tabindex\x3d"-1" class\x3d"cke_path_item" title\x3d"{label}"'+e+' hidefocus\x3d"true"  onkeydown\x3d"return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );" onclick\x3d"CKEDITOR.tools.callFunction({clickFn},{index}); return false;" role\x3d"button" aria-label\x3d"{label}"\x3e{text}\x3c/a\x3e');
+CKEDITOR.plugins.add("elementspath",{init:function(a){a._.elementsPath={idBase:"cke_elementspath_"+CKEDITOR.tools.getNextNumber()+"_",filters:[]};a.on("uiSpace",function(e){"bottom"==e.data.space&&q(a,e.data)})}})})();(function(){function q(b,d,a){a=b.config.forceEnterMode||a;"wysiwyg"==b.mode&&(d||(d=b.activeEnterMode),b.elementPath().isContextFor("p")||(d=CKEDITOR.ENTER_BR,a=1),b.fire("saveSnapshot"),d==CKEDITOR.ENTER_BR?t(b,d,null,a):u(b,d,null,a),b.fire("saveSnapshot"))}function v(b){b=b.getSelection().getRanges(!0);for(var d=b.length-1;0<d;d--)b[d].deleteContents();return b[0]}function y(b){var d=b.startContainer.getAscendant(function(a){return a.type==CKEDITOR.NODE_ELEMENT&&"true"==a.getAttribute("contenteditable")},
+!0);if(b.root.equals(d))return b;d=new CKEDITOR.dom.range(d);d.moveToRange(b);return d}CKEDITOR.plugins.add("enterkey",{init:function(b){b.addCommand("enter",{modes:{wysiwyg:1},editorFocus:!1,exec:function(b){q(b)}});b.addCommand("shiftEnter",{modes:{wysiwyg:1},editorFocus:!1,exec:function(b){q(b,b.activeShiftEnterMode,1)}});b.setKeystroke([[13,"enter"],[CKEDITOR.SHIFT+13,"shiftEnter"]])}});var z=CKEDITOR.dom.walker.whitespaces(),A=CKEDITOR.dom.walker.bookmark();CKEDITOR.plugins.enterkey={enterBlock:function(b,
+d,a,h){if(a=a||v(b)){a=y(a);var f=a.document,k=a.checkStartOfBlock(),m=a.checkEndOfBlock(),l=b.elementPath(a.startContainer),c=l.block,n=d==CKEDITOR.ENTER_DIV?"div":"p",e;if(k&&m){if(c&&(c.is("li")||c.getParent().is("li"))){c.is("li")||(c=c.getParent());a=c.getParent();e=a.getParent();h=!c.hasPrevious();var p=!c.hasNext(),n=b.getSelection(),g=n.createBookmarks(),k=c.getDirection(1),m=c.getAttribute("class"),r=c.getAttribute("style"),q=e.getDirection(1)!=k;b=b.enterMode!=CKEDITOR.ENTER_BR||q||r||m;
+if(e.is("li"))h||p?(h&&p&&a.remove(),c[p?"insertAfter":"insertBefore"](e)):c.breakParent(e);else{if(b)if(l.block.is("li")?(e=f.createElement(d==CKEDITOR.ENTER_P?"p":"div"),q&&e.setAttribute("dir",k),r&&e.setAttribute("style",r),m&&e.setAttribute("class",m),c.moveChildren(e)):e=l.block,h||p)e[h?"insertBefore":"insertAfter"](a);else c.breakParent(a),e.insertAfter(a);else if(c.appendBogus(!0),h||p)for(;f=c[h?"getFirst":"getLast"]();)f[h?"insertBefore":"insertAfter"](a);else for(c.breakParent(a);f=c.getLast();)f.insertAfter(a);
+c.remove()}n.selectBookmarks(g);return}if(c&&c.getParent().is("blockquote")){c.breakParent(c.getParent());c.getPrevious().getFirst(CKEDITOR.dom.walker.invisible(1))||c.getPrevious().remove();c.getNext().getFirst(CKEDITOR.dom.walker.invisible(1))||c.getNext().remove();a.moveToElementEditStart(c);a.select();return}}else if(c&&c.is("pre")&&!m){t(b,d,a,h);return}if(k=a.splitBlock(n)){d=k.previousBlock;c=k.nextBlock;l=k.wasStartOfBlock;b=k.wasEndOfBlock;c?(g=c.getParent(),g.is("li")&&(c.breakParent(g),
+c.move(c.getNext(),1))):d&&(g=d.getParent())&&g.is("li")&&(d.breakParent(g),g=d.getNext(),a.moveToElementEditStart(g),d.move(d.getPrevious()));if(l||b){if(d){if(d.is("li")||!w.test(d.getName())&&!d.is("pre"))e=d.clone()}else c&&(e=c.clone());e?h&&!e.is("li")&&e.renameNode(n):g&&g.is("li")?e=g:(e=f.createElement(n),d&&(p=d.getDirection())&&e.setAttribute("dir",p));if(f=k.elementPath)for(h=0,n=f.elements.length;h<n;h++){g=f.elements[h];if(g.equals(f.block)||g.equals(f.blockLimit))break;CKEDITOR.dtd.$removeEmpty[g.getName()]&&
+(g=g.clone(),e.moveChildren(g),e.append(g))}e.appendBogus();e.getParent()||a.insertNode(e);e.is("li")&&e.removeAttribute("value");!CKEDITOR.env.ie||!l||b&&d.getChildCount()||(a.moveToElementEditStart(b?d:e),a.select());a.moveToElementEditStart(l&&!b?c:e)}else c.is("li")&&(e=a.clone(),e.selectNodeContents(c),e=new CKEDITOR.dom.walker(e),e.evaluator=function(a){return!(A(a)||z(a)||a.type==CKEDITOR.NODE_ELEMENT&&a.getName()in CKEDITOR.dtd.$inline&&!(a.getName()in CKEDITOR.dtd.$empty))},(g=e.next())&&
+g.type==CKEDITOR.NODE_ELEMENT&&g.is("ul","ol")&&(CKEDITOR.env.needsBrFiller?f.createElement("br"):f.createText(" ")).insertBefore(g)),c&&a.moveToElementEditStart(c);a.select();a.scrollIntoView()}}},enterBr:function(b,d,a,h){if(a=a||v(b)){var f=a.document,k=a.checkEndOfBlock(),m=new CKEDITOR.dom.elementPath(b.getSelection().getStartElement()),l=m.block,c=l&&m.block.getName();h||"li"!=c?(!h&&k&&w.test(c)?(k=l.getDirection())?(f=f.createElement("div"),f.setAttribute("dir",k),f.insertAfter(l),a.setStart(f,
+0)):(f.createElement("br").insertAfter(l),CKEDITOR.env.gecko&&f.createText("").insertAfter(l),a.setStartAt(l.getNext(),CKEDITOR.env.ie?CKEDITOR.POSITION_BEFORE_START:CKEDITOR.POSITION_AFTER_START)):(b="pre"==c&&CKEDITOR.env.ie&&8>CKEDITOR.env.version?f.createText("\r"):f.createElement("br"),a.deleteContents(),a.insertNode(b),CKEDITOR.env.needsBrFiller?(f.createText("").insertAfter(b),k&&(l||m.blockLimit).appendBogus(),b.getNext().$.nodeValue="",a.setStartAt(b.getNext(),CKEDITOR.POSITION_AFTER_START)):
+a.setStartAt(b,CKEDITOR.POSITION_AFTER_END)),a.collapse(!0),a.select(),a.scrollIntoView()):u(b,d,a,h)}}};var x=CKEDITOR.plugins.enterkey,t=x.enterBr,u=x.enterBlock,w=/^h[1-6]$/})();(function(){function k(b,f){var g={},c=[],e={nbsp:" ",shy:"­",gt:"\x3e",lt:"\x3c",amp:"\x26",apos:"'",quot:'"'};b=b.replace(/\b(nbsp|shy|gt|lt|amp|apos|quot)(?:,|$)/g,function(b,a){var d=f?"\x26"+a+";":e[a];g[d]=f?e[a]:"\x26"+a+";";c.push(d);return""});if(!f&&b){b=b.split(",");var a=document.createElement("div"),d;a.innerHTML="\x26"+b.join(";\x26")+";";d=a.innerHTML;a=null;for(a=0;a<d.length;a++){var h=d.charAt(a);g[h]="\x26"+b[a]+";";c.push(h)}}g.regex=c.join(f?"|":"");return g}CKEDITOR.plugins.add("entities",
+{afterInit:function(b){function f(a){return h[a]}function g(b){return"force"!=c.entities_processNumerical&&a[b]?a[b]:"\x26#"+b.charCodeAt(0)+";"}var c=b.config;if(b=(b=b.dataProcessor)&&b.htmlFilter){var e=[];!1!==c.basicEntities&&e.push("nbsp,gt,lt,amp");c.entities&&(e.length&&e.push("quot,iexcl,cent,pound,curren,yen,brvbar,sect,uml,copy,ordf,laquo,not,shy,reg,macr,deg,plusmn,sup2,sup3,acute,micro,para,middot,cedil,sup1,ordm,raquo,frac14,frac12,frac34,iquest,times,divide,fnof,bull,hellip,prime,Prime,oline,frasl,weierp,image,real,trade,alefsym,larr,uarr,rarr,darr,harr,crarr,lArr,uArr,rArr,dArr,hArr,forall,part,exist,empty,nabla,isin,notin,ni,prod,sum,minus,lowast,radic,prop,infin,ang,and,or,cap,cup,int,there4,sim,cong,asymp,ne,equiv,le,ge,sub,sup,nsub,sube,supe,oplus,otimes,perp,sdot,lceil,rceil,lfloor,rfloor,lang,rang,loz,spades,clubs,hearts,diams,circ,tilde,ensp,emsp,thinsp,zwnj,zwj,lrm,rlm,ndash,mdash,lsquo,rsquo,sbquo,ldquo,rdquo,bdquo,dagger,Dagger,permil,lsaquo,rsaquo,euro"),
+c.entities_latin&&e.push("Agrave,Aacute,Acirc,Atilde,Auml,Aring,AElig,Ccedil,Egrave,Eacute,Ecirc,Euml,Igrave,Iacute,Icirc,Iuml,ETH,Ntilde,Ograve,Oacute,Ocirc,Otilde,Ouml,Oslash,Ugrave,Uacute,Ucirc,Uuml,Yacute,THORN,szlig,agrave,aacute,acirc,atilde,auml,aring,aelig,ccedil,egrave,eacute,ecirc,euml,igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute,ocirc,otilde,ouml,oslash,ugrave,uacute,ucirc,uuml,yacute,thorn,yuml,OElig,oelig,Scaron,scaron,Yuml"),c.entities_greek&&e.push("Alpha,Beta,Gamma,Delta,Epsilon,Zeta,Eta,Theta,Iota,Kappa,Lambda,Mu,Nu,Xi,Omicron,Pi,Rho,Sigma,Tau,Upsilon,Phi,Chi,Psi,Omega,alpha,beta,gamma,delta,epsilon,zeta,eta,theta,iota,kappa,lambda,mu,nu,xi,omicron,pi,rho,sigmaf,sigma,tau,upsilon,phi,chi,psi,omega,thetasym,upsih,piv"),
+c.entities_additional&&e.push(c.entities_additional));var a=k(e.join(",")),d=a.regex?"["+a.regex+"]":"a^";delete a.regex;c.entities&&c.entities_processNumerical&&(d="[^ -~]|"+d);var d=new RegExp(d,"g"),h=k("nbsp,gt,lt,amp,shy",!0),l=new RegExp(h.regex,"g");b.addRules({text:function(a){return a.replace(l,f).replace(d,g)}},{applyToAll:!0,excludeNestedEditable:!0})}}})})();CKEDITOR.config.basicEntities=!0;CKEDITOR.config.entities=!0;CKEDITOR.config.entities_latin=!0;CKEDITOR.config.entities_greek=!0;
+CKEDITOR.config.entities_additional="#39";CKEDITOR.plugins.add("popup");
+CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{popup:function(e,a,b,d){a=a||"80%";b=b||"70%";"string"==typeof a&&1<a.length&&"%"==a.substr(a.length-1,1)&&(a=parseInt(window.screen.width*parseInt(a,10)/100,10));"string"==typeof b&&1<b.length&&"%"==b.substr(b.length-1,1)&&(b=parseInt(window.screen.height*parseInt(b,10)/100,10));640>a&&(a=640);420>b&&(b=420);var f=parseInt((window.screen.height-b)/2,10),g=parseInt((window.screen.width-a)/2,10);d=(d||"location\x3dno,menubar\x3dno,toolbar\x3dno,dependent\x3dyes,minimizable\x3dno,modal\x3dyes,alwaysRaised\x3dyes,resizable\x3dyes,scrollbars\x3dyes")+",width\x3d"+
+a+",height\x3d"+b+",top\x3d"+f+",left\x3d"+g;var c=window.open("",null,d,!0);if(!c)return!1;try{-1==navigator.userAgent.toLowerCase().indexOf(" chrome/")&&(c.moveTo(g,f),c.resizeTo(a,b)),c.focus(),c.location.href=e}catch(h){window.open(e,null,d,!0)}return!0}});(function(){function g(a,c){var d=[];if(c)for(var b in c)d.push(b+"\x3d"+encodeURIComponent(c[b]));else return a;return a+(-1!=a.indexOf("?")?"\x26":"?")+d.join("\x26")}function k(a){a+="";return a.charAt(0).toUpperCase()+a.substr(1)}function m(){var a=this.getDialog(),c=a.getParentEditor();c._.filebrowserSe=this;var d=c.config["filebrowser"+k(a.getName())+"WindowWidth"]||c.config.filebrowserWindowWidth||"80%",a=c.config["filebrowser"+k(a.getName())+"WindowHeight"]||c.config.filebrowserWindowHeight||
+"70%",b=this.filebrowser.params||{};b.CKEditor=c.name;b.CKEditorFuncNum=c._.filebrowserFn;b.langCode||(b.langCode=c.langCode);b=g(this.filebrowser.url,b);c.popup(b,d,a,c.config.filebrowserWindowFeatures||c.config.fileBrowserWindowFeatures)}function n(){var a=this.getDialog();a.getParentEditor()._.filebrowserSe=this;return a.getContentElement(this["for"][0],this["for"][1]).getInputElement().$.value&&a.getContentElement(this["for"][0],this["for"][1]).getAction()?!0:!1}function p(a,c,d){var b=d.params||
+{};b.CKEditor=a.name;b.CKEditorFuncNum=a._.filebrowserFn;b.langCode||(b.langCode=a.langCode);c.action=g(d.url,b);c.filebrowser=d}function l(a,c,d,b){if(b&&b.length)for(var e,g=b.length;g--;)if(e=b[g],"hbox"!=e.type&&"vbox"!=e.type&&"fieldset"!=e.type||l(a,c,d,e.children),e.filebrowser)if("string"==typeof e.filebrowser&&(e.filebrowser={action:"fileButton"==e.type?"QuickUpload":"Browse",target:e.filebrowser}),"Browse"==e.filebrowser.action){var f=e.filebrowser.url;void 0===f&&(f=a.config["filebrowser"+
+k(c)+"BrowseUrl"],void 0===f&&(f=a.config.filebrowserBrowseUrl));f&&(e.onClick=m,e.filebrowser.url=f,e.hidden=!1)}else if("QuickUpload"==e.filebrowser.action&&e["for"]&&(f=e.filebrowser.url,void 0===f&&(f=a.config["filebrowser"+k(c)+"UploadUrl"],void 0===f&&(f=a.config.filebrowserUploadUrl)),f)){var h=e.onClick;e.onClick=function(a){var b=a.sender;if(h&&!1===h.call(b,a))return!1;if(n.call(b,a)){a=b.getDialog().getContentElement(this["for"][0],this["for"][1]).getInputElement();if(b=new CKEDITOR.dom.element(a.$.form))(a=
+b.$.elements.ckCsrfToken)?a=new CKEDITOR.dom.element(a):(a=new CKEDITOR.dom.element("input"),a.setAttributes({name:"ckCsrfToken",type:"hidden"}),b.append(a)),a.setAttribute("value",CKEDITOR.tools.getCsrfToken());return!0}return!1};e.filebrowser.url=f;e.hidden=!1;p(a,d.getContents(e["for"][0]).get(e["for"][1]),e.filebrowser)}}function h(a,c,d){if(-1!==d.indexOf(";")){d=d.split(";");for(var b=0;b<d.length;b++)if(h(a,c,d[b]))return!0;return!1}return(a=a.getContents(c).get(d).filebrowser)&&a.url}function q(a,
+c){var d=this._.filebrowserSe.getDialog(),b=this._.filebrowserSe["for"],e=this._.filebrowserSe.filebrowser.onSelect;b&&d.getContentElement(b[0],b[1]).reset();if("function"!=typeof c||!1!==c.call(this._.filebrowserSe))if(!e||!1!==e.call(this._.filebrowserSe,a,c))if("string"==typeof c&&c&&alert(c),a&&(b=this._.filebrowserSe,d=b.getDialog(),b=b.filebrowser.target||null))if(b=b.split(":"),e=d.getContentElement(b[0],b[1]))e.setValue(a),d.selectPage(b[0])}CKEDITOR.plugins.add("filebrowser",{requires:"popup",
+init:function(a){a._.filebrowserFn=CKEDITOR.tools.addFunction(q,a);a.on("destroy",function(){CKEDITOR.tools.removeFunction(this._.filebrowserFn)})}});CKEDITOR.on("dialogDefinition",function(a){if(a.editor.plugins.filebrowser)for(var c=a.data.definition,d,b=0;b<c.contents.length;++b)if(d=c.contents[b])l(a.editor,a.data.name,c,d.elements),d.hidden&&d.filebrowser&&(d.hidden=!h(c,d.id,d.filebrowser))})})();(function(){function k(a){var l=a.config,p=a.fire("uiSpace",{space:"top",html:""}).html,t=function(){function f(a,c,e){b.setStyle(c,w(e));b.setStyle("position",a)}function e(a){var b=k.getDocumentPosition();switch(a){case "top":f("absolute","top",b.y-q-r);break;case "pin":f("fixed","top",x);break;case "bottom":f("absolute","top",b.y+(c.height||c.bottom-c.top)+r)}m=a}var m,k,n,c,h,q,v,p=l.floatSpaceDockedOffsetX||0,r=l.floatSpaceDockedOffsetY||0,u=l.floatSpacePinnedOffsetX||0,x=l.floatSpacePinnedOffsetY||
+0;return function(d){if(k=a.editable()){var f=d&&"focus"==d.name;f&&b.show();a.fire("floatingSpaceLayout",{show:f});b.removeStyle("left");b.removeStyle("right");n=b.getClientRect();c=k.getClientRect();h=g.getViewPaneSize();q=n.height;v="pageXOffset"in g.$?g.$.pageXOffset:CKEDITOR.document.$.documentElement.scrollLeft;m?(q+r<=c.top?e("top"):q+r>h.height-c.bottom?e("pin"):e("bottom"),d=h.width/2,d=l.floatSpacePreferRight?"right":0<c.left&&c.right<h.width&&c.width>n.width?"rtl"==l.contentsLangDirection?
+"right":"left":d-c.left>c.right-d?"left":"right",n.width>h.width?(d="left",f=0):(f="left"==d?0<c.left?c.left:0:c.right<h.width?h.width-c.right:0,f+n.width>h.width&&(d="left"==d?"right":"left",f=0)),b.setStyle(d,w(("pin"==m?u:p)+f+("pin"==m?0:"left"==d?v:-v)))):(m="pin",e("pin"),t(d))}}}();if(p){var k=new CKEDITOR.template('\x3cdiv id\x3d"cke_{name}" class\x3d"cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_float cke_{langDir} '+CKEDITOR.env.cssClass+'" dir\x3d"{langDir}" title\x3d"'+(CKEDITOR.env.gecko?
+" ":"")+'" lang\x3d"{langCode}" role\x3d"application" style\x3d"{style}"'+(a.title?' aria-labelledby\x3d"cke_{name}_arialbl"':" ")+"\x3e"+(a.title?'\x3cspan id\x3d"cke_{name}_arialbl" class\x3d"cke_voice_label"\x3e{voiceLabel}\x3c/span\x3e':" ")+'\x3cdiv class\x3d"cke_inner"\x3e\x3cdiv id\x3d"{topId}" class\x3d"cke_top" role\x3d"presentation"\x3e{content}\x3c/div\x3e\x3c/div\x3e\x3c/div\x3e'),b=CKEDITOR.document.getBody().append(CKEDITOR.dom.element.createFromHtml(k.output({content:p,id:a.id,langDir:a.lang.dir,
+langCode:a.langCode,name:a.name,style:"display:none;z-index:"+(l.baseFloatZIndex-1),topId:a.ui.spaceId("top"),voiceLabel:a.title}))),u=CKEDITOR.tools.eventsBuffer(500,t),e=CKEDITOR.tools.eventsBuffer(100,t);b.unselectable();b.on("mousedown",function(a){a=a.data;a.getTarget().hasAscendant("a",1)||a.preventDefault()});a.on("focus",function(b){t(b);a.on("change",u.input);g.on("scroll",e.input);g.on("resize",e.input)});a.on("blur",function(){b.hide();a.removeListener("change",u.input);g.removeListener("scroll",
+e.input);g.removeListener("resize",e.input)});a.on("destroy",function(){g.removeListener("scroll",e.input);g.removeListener("resize",e.input);b.clearCustomData();b.remove()});a.focusManager.hasFocus&&b.show();a.focusManager.add(b,1)}}var g=CKEDITOR.document.getWindow(),w=CKEDITOR.tools.cssLength;CKEDITOR.plugins.add("floatingspace",{init:function(a){a.on("loaded",function(){k(this)},null,null,20)}})})();CKEDITOR.plugins.add("listblock",{requires:"panel",onLoad:function(){var f=CKEDITOR.addTemplate("panel-list",'\x3cul role\x3d"presentation" class\x3d"cke_panel_list"\x3e{items}\x3c/ul\x3e'),g=CKEDITOR.addTemplate("panel-list-item",'\x3cli id\x3d"{id}" class\x3d"cke_panel_listItem" role\x3dpresentation\x3e\x3ca id\x3d"{id}_option" _cke_focus\x3d1 hidefocus\x3dtrue title\x3d"{title}" href\x3d"javascript:void(\'{val}\')"  {onclick}\x3d"CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;" role\x3d"option"\x3e{text}\x3c/a\x3e\x3c/li\x3e'),
+h=CKEDITOR.addTemplate("panel-list-group",'\x3ch1 id\x3d"{id}" class\x3d"cke_panel_grouptitle" role\x3d"presentation" \x3e{label}\x3c/h1\x3e'),k=/\'/g;CKEDITOR.ui.panel.prototype.addListBlock=function(a,b){return this.addBlock(a,new CKEDITOR.ui.listBlock(this.getHolderElement(),b))};CKEDITOR.ui.listBlock=CKEDITOR.tools.createClass({base:CKEDITOR.ui.panel.block,$:function(a,b){b=b||{};var c=b.attributes||(b.attributes={});(this.multiSelect=!!b.multiSelect)&&(c["aria-multiselectable"]=!0);!c.role&&
+(c.role="listbox");this.base.apply(this,arguments);this.element.setAttribute("role",c.role);c=this.keys;c[40]="next";c[9]="next";c[38]="prev";c[CKEDITOR.SHIFT+9]="prev";c[32]=CKEDITOR.env.ie?"mouseup":"click";CKEDITOR.env.ie&&(c[13]="mouseup");this._.pendingHtml=[];this._.pendingList=[];this._.items={};this._.groups={}},_:{close:function(){if(this._.started){var a=f.output({items:this._.pendingList.join("")});this._.pendingList=[];this._.pendingHtml.push(a);delete this._.started}},getClick:function(){this._.click||
+(this._.click=CKEDITOR.tools.addFunction(function(a){var b=this.toggle(a);if(this.onClick)this.onClick(a,b)},this));return this._.click}},proto:{add:function(a,b,c){var d=CKEDITOR.tools.getNextId();this._.started||(this._.started=1,this._.size=this._.size||0);this._.items[a]=d;var e;e=CKEDITOR.tools.htmlEncodeAttr(a).replace(k,"\\'");a={id:d,val:e,onclick:CKEDITOR.env.ie?'onclick\x3d"return false;" onmouseup':"onclick",clickFn:this._.getClick(),title:CKEDITOR.tools.htmlEncodeAttr(c||a),text:b||a};
+this._.pendingList.push(g.output(a))},startGroup:function(a){this._.close();var b=CKEDITOR.tools.getNextId();this._.groups[a]=b;this._.pendingHtml.push(h.output({id:b,label:a}))},commit:function(){this._.close();this.element.appendHtml(this._.pendingHtml.join(""));delete this._.size;this._.pendingHtml=[]},toggle:function(a){var b=this.isMarked(a);b?this.unmark(a):this.mark(a);return!b},hideGroup:function(a){var b=(a=this.element.getDocument().getById(this._.groups[a]))&&a.getNext();a&&(a.setStyle("display",
+"none"),b&&"ul"==b.getName()&&b.setStyle("display","none"))},hideItem:function(a){this.element.getDocument().getById(this._.items[a]).setStyle("display","none")},showAll:function(){var a=this._.items,b=this._.groups,c=this.element.getDocument(),d;for(d in a)c.getById(a[d]).setStyle("display","");for(var e in b)a=c.getById(b[e]),d=a.getNext(),a.setStyle("display",""),d&&"ul"==d.getName()&&d.setStyle("display","")},mark:function(a){this.multiSelect||this.unmarkAll();a=this._.items[a];var b=this.element.getDocument().getById(a);
+b.addClass("cke_selected");this.element.getDocument().getById(a+"_option").setAttribute("aria-selected",!0);this.onMark&&this.onMark(b)},unmark:function(a){var b=this.element.getDocument();a=this._.items[a];var c=b.getById(a);c.removeClass("cke_selected");b.getById(a+"_option").removeAttribute("aria-selected");this.onUnmark&&this.onUnmark(c)},unmarkAll:function(){var a=this._.items,b=this.element.getDocument(),c;for(c in a){var d=a[c];b.getById(d).removeClass("cke_selected");b.getById(d+"_option").removeAttribute("aria-selected")}this.onUnmark&&
+this.onUnmark()},isMarked:function(a){return this.element.getDocument().getById(this._.items[a]).hasClass("cke_selected")},focus:function(a){this._.focusIndex=-1;var b=this.element.getElementsByTag("a"),c,d=-1;if(a)for(c=this.element.getDocument().getById(this._.items[a]).getFirst();a=b.getItem(++d);){if(a.equals(c)){this._.focusIndex=d;break}}else this.element.focus();c&&setTimeout(function(){c.focus()},0)}}})}});CKEDITOR.plugins.add("richcombo",{requires:"floatpanel,listblock,button",beforeInit:function(d){d.ui.addHandler(CKEDITOR.UI_RICHCOMBO,CKEDITOR.ui.richCombo.handler)}});
+(function(){var d='\x3cspan id\x3d"{id}" class\x3d"cke_combo cke_combo__{name} {cls}" role\x3d"presentation"\x3e\x3cspan id\x3d"{id}_label" class\x3d"cke_combo_label"\x3e{label}\x3c/span\x3e\x3ca class\x3d"cke_combo_button" title\x3d"{title}" tabindex\x3d"-1"'+(CKEDITOR.env.gecko&&!CKEDITOR.env.hc?"":" href\x3d\"javascript:void('{titleJs}')\"")+' hidefocus\x3d"true" role\x3d"button" aria-labelledby\x3d"{id}_label" aria-haspopup\x3d"true"';CKEDITOR.env.gecko&&CKEDITOR.env.mac&&(d+=' onkeypress\x3d"return false;"');
+CKEDITOR.env.gecko&&(d+=' onblur\x3d"this.style.cssText \x3d this.style.cssText;"');var d=d+(' onkeydown\x3d"return CKEDITOR.tools.callFunction({keydownFn},event,this);" onfocus\x3d"return CKEDITOR.tools.callFunction({focusFn},event);" '+(CKEDITOR.env.ie?'onclick\x3d"return false;" onmouseup':"onclick")+'\x3d"CKEDITOR.tools.callFunction({clickFn},this);return false;"\x3e\x3cspan id\x3d"{id}_text" class\x3d"cke_combo_text cke_combo_inlinelabel"\x3e{label}\x3c/span\x3e\x3cspan class\x3d"cke_combo_open"\x3e\x3cspan class\x3d"cke_combo_arrow"\x3e'+
+(CKEDITOR.env.hc?"\x26#9660;":CKEDITOR.env.air?"\x26nbsp;":"")+"\x3c/span\x3e\x3c/span\x3e\x3c/a\x3e\x3c/span\x3e"),k=CKEDITOR.addTemplate("combo",d);CKEDITOR.UI_RICHCOMBO="richcombo";CKEDITOR.ui.richCombo=CKEDITOR.tools.createClass({$:function(a){CKEDITOR.tools.extend(this,a,{canGroup:!1,title:a.label,modes:{wysiwyg:1},editorFocus:1});a=this.panel||{};delete this.panel;this.id=CKEDITOR.tools.getNextNumber();this.document=a.parent&&a.parent.getDocument()||CKEDITOR.document;a.className="cke_combopanel";
+a.block={multiSelect:a.multiSelect,attributes:a.attributes};a.toolbarRelated=!0;this._={panelDefinition:a,items:{}}},proto:{renderHtml:function(a){var b=[];this.render(a,b);return b.join("")},render:function(a,b){function g(){if(this.getState()!=CKEDITOR.TRISTATE_ON){var c=this.modes[a.mode]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED;a.readOnly&&!this.readOnly&&(c=CKEDITOR.TRISTATE_DISABLED);this.setState(c);this.setValue("");c!=CKEDITOR.TRISTATE_DISABLED&&this.refresh&&this.refresh()}}var d=
+CKEDITOR.env,h="cke_"+this.id,e=CKEDITOR.tools.addFunction(function(b){l&&(a.unlockSelection(1),l=0);c.execute(b)},this),f=this,c={id:h,combo:this,focus:function(){CKEDITOR.document.getById(h).getChild(1).focus()},execute:function(c){var b=f._;if(b.state!=CKEDITOR.TRISTATE_DISABLED)if(f.createPanel(a),b.on)b.panel.hide();else{f.commit();var d=f.getValue();d?b.list.mark(d):b.list.unmarkAll();b.panel.showBlock(f.id,new CKEDITOR.dom.element(c),4)}},clickFn:e};a.on("activeFilterChange",g,this);a.on("mode",
+g,this);a.on("selectionChange",g,this);!this.readOnly&&a.on("readOnly",g,this);var m=CKEDITOR.tools.addFunction(function(b,d){b=new CKEDITOR.dom.event(b);var g=b.getKeystroke();if(40==g)a.once("panelShow",function(a){a.data._.panel._.currentBlock.onKeyDown(40)});switch(g){case 13:case 32:case 40:CKEDITOR.tools.callFunction(e,d);break;default:c.onkey(c,g)}b.preventDefault()}),n=CKEDITOR.tools.addFunction(function(){c.onfocus&&c.onfocus()}),l=0;c.keyDownFn=m;d={id:h,name:this.name||this.command,label:this.label,
+title:this.title,cls:this.className||"",titleJs:d.gecko&&!d.hc?"":(this.title||"").replace("'",""),keydownFn:m,focusFn:n,clickFn:e};k.output(d,b);if(this.onRender)this.onRender();return c},createPanel:function(a){if(!this._.panel){var b=this._.panelDefinition,d=this._.panelDefinition.block,k=b.parent||CKEDITOR.document.getBody(),h="cke_combopanel__"+this.name,e=new CKEDITOR.ui.floatPanel(a,k,b),f=e.addListBlock(this.id,d),c=this;e.onShow=function(){this.element.addClass(h);c.setState(CKEDITOR.TRISTATE_ON);
+c._.on=1;c.editorFocus&&!a.focusManager.hasFocus&&a.focus();if(c.onOpen)c.onOpen();a.once("panelShow",function(){f.focus(!f.multiSelect&&c.getValue())})};e.onHide=function(b){this.element.removeClass(h);c.setState(c.modes&&c.modes[a.mode]?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED);c._.on=0;if(!b&&c.onClose)c.onClose()};e.onEscape=function(){e.hide(1)};f.onClick=function(a,b){c.onClick&&c.onClick.call(c,a,b);e.hide()};this._.panel=e;this._.list=f;e.getBlock(this.id).onHide=function(){c._.on=
+0;c.setState(CKEDITOR.TRISTATE_OFF)};this.init&&this.init()}},setValue:function(a,b){this._.value=a;var d=this.document.getById("cke_"+this.id+"_text");d&&(a||b?d.removeClass("cke_combo_inlinelabel"):(b=this.label,d.addClass("cke_combo_inlinelabel")),d.setText("undefined"!=typeof b?b:a))},getValue:function(){return this._.value||""},unmarkAll:function(){this._.list.unmarkAll()},mark:function(a){this._.list.mark(a)},hideItem:function(a){this._.list.hideItem(a)},hideGroup:function(a){this._.list.hideGroup(a)},
+showAll:function(){this._.list.showAll()},add:function(a,b,d){this._.items[a]=d||a;this._.list.add(a,b,d)},startGroup:function(a){this._.list.startGroup(a)},commit:function(){this._.committed||(this._.list.commit(),this._.committed=1,CKEDITOR.ui.fire("ready",this));this._.committed=1},setState:function(a){if(this._.state!=a){var b=this.document.getById("cke_"+this.id);b.setState(a,"cke_combo");a==CKEDITOR.TRISTATE_DISABLED?b.setAttribute("aria-disabled",!0):b.removeAttribute("aria-disabled");this._.state=
+a}},getState:function(){return this._.state},enable:function(){this._.state==CKEDITOR.TRISTATE_DISABLED&&this.setState(this._.lastState)},disable:function(){this._.state!=CKEDITOR.TRISTATE_DISABLED&&(this._.lastState=this._.state,this.setState(CKEDITOR.TRISTATE_DISABLED))}},statics:{handler:{create:function(a){return new CKEDITOR.ui.richCombo(a)}}}});CKEDITOR.ui.prototype.addRichCombo=function(a,b){this.add(a,CKEDITOR.UI_RICHCOMBO,b)}})();CKEDITOR.plugins.add("format",{requires:"richcombo",init:function(a){if(!a.blockless){for(var f=a.config,c=a.lang.format,l=f.format_tags.split(";"),d={},m=0,n=[],g=0;g<l.length;g++){var h=l[g],k=new CKEDITOR.style(f["format_"+h]);if(!a.filter.customConfig||a.filter.check(k))m++,d[h]=k,d[h]._.enterMode=a.config.enterMode,n.push(k)}0!==m&&a.ui.addRichCombo("Format",{label:c.label,title:c.panelTitle,toolbar:"styles,20",allowedContent:n,panel:{css:[CKEDITOR.skin.getPath("editor")].concat(f.contentsCss),
+multiSelect:!1,attributes:{"aria-label":c.panelTitle}},init:function(){this.startGroup(c.panelTitle);for(var a in d){var e=c["tag_"+a];this.add(a,d[a].buildPreview(e),e)}},onClick:function(b){a.focus();a.fire("saveSnapshot");b=d[b];var e=a.elementPath();a[b.checkActive(e,a)?"removeStyle":"applyStyle"](b);setTimeout(function(){a.fire("saveSnapshot")},0)},onRender:function(){a.on("selectionChange",function(b){var e=this.getValue();b=b.data.path;this.refresh();for(var c in d)if(d[c].checkActive(b,a)){c!=
+e&&this.setValue(c,a.lang.format["tag_"+c]);return}this.setValue("")},this)},onOpen:function(){this.showAll();for(var b in d)a.activeFilter.check(d[b])||this.hideItem(b)},refresh:function(){var b=a.elementPath();if(b){if(b.isContextFor("p"))for(var c in d)if(a.activeFilter.check(d[c]))return;this.setState(CKEDITOR.TRISTATE_DISABLED)}}})}}});CKEDITOR.config.format_tags="p;h1;h2;h3;h4;h5;h6;pre;address;div";CKEDITOR.config.format_p={element:"p"};CKEDITOR.config.format_div={element:"div"};
+CKEDITOR.config.format_pre={element:"pre"};CKEDITOR.config.format_address={element:"address"};CKEDITOR.config.format_h1={element:"h1"};CKEDITOR.config.format_h2={element:"h2"};CKEDITOR.config.format_h3={element:"h3"};CKEDITOR.config.format_h4={element:"h4"};CKEDITOR.config.format_h5={element:"h5"};CKEDITOR.config.format_h6={element:"h6"};(function(){var b={canUndo:!1,exec:function(a){var b=a.document.createElement("hr");a.insertElement(b)},allowedContent:"hr",requiredContent:"hr"};CKEDITOR.plugins.add("horizontalrule",{init:function(a){a.blockless||(a.addCommand("horizontalrule",b),a.ui.addButton&&a.ui.addButton("HorizontalRule",{label:a.lang.horizontalrule.toolbar,command:"horizontalrule",toolbar:"insert,40"}))}})})();CKEDITOR.plugins.add("htmlwriter",{init:function(b){var a=new CKEDITOR.htmlWriter;a.forceSimpleAmpersand=b.config.forceSimpleAmpersand;a.indentationChars=b.config.dataIndentationChars||"\t";b.dataProcessor.writer=a}});
+CKEDITOR.htmlWriter=CKEDITOR.tools.createClass({base:CKEDITOR.htmlParser.basicWriter,$:function(){this.base();this.indentationChars="\t";this.selfClosingEnd=" /\x3e";this.lineBreakChars="\n";this.sortAttributes=1;this._.indent=0;this._.indentation="";this._.inPre=0;this._.rules={};var b=CKEDITOR.dtd,a;for(a in CKEDITOR.tools.extend({},b.$nonBodyContent,b.$block,b.$listItem,b.$tableContent))this.setRules(a,{indent:!b[a]["#"],breakBeforeOpen:1,breakBeforeClose:!b[a]["#"],breakAfterClose:1,needsSpace:a in
+b.$block&&!(a in{li:1,dt:1,dd:1})});this.setRules("br",{breakAfterOpen:1});this.setRules("title",{indent:0,breakAfterOpen:0});this.setRules("style",{indent:0,breakBeforeClose:1});this.setRules("pre",{breakAfterOpen:1,indent:0})},proto:{openTag:function(b){var a=this._.rules[b];this._.afterCloser&&a&&a.needsSpace&&this._.needsSpace&&this._.output.push("\n");this._.indent?this.indentation():a&&a.breakBeforeOpen&&(this.lineBreak(),this.indentation());this._.output.push("\x3c",b);this._.afterCloser=0},
+openTagClose:function(b,a){var c=this._.rules[b];a?(this._.output.push(this.selfClosingEnd),c&&c.breakAfterClose&&(this._.needsSpace=c.needsSpace)):(this._.output.push("\x3e"),c&&c.indent&&(this._.indentation+=this.indentationChars));c&&c.breakAfterOpen&&this.lineBreak();"pre"==b&&(this._.inPre=1)},attribute:function(b,a){"string"==typeof a&&(this.forceSimpleAmpersand&&(a=a.replace(/&amp;/g,"\x26")),a=CKEDITOR.tools.htmlEncodeAttr(a));this._.output.push(" ",b,'\x3d"',a,'"')},closeTag:function(b){var a=
+this._.rules[b];a&&a.indent&&(this._.indentation=this._.indentation.substr(this.indentationChars.length));this._.indent?this.indentation():a&&a.breakBeforeClose&&(this.lineBreak(),this.indentation());this._.output.push("\x3c/",b,"\x3e");"pre"==b&&(this._.inPre=0);a&&a.breakAfterClose&&(this.lineBreak(),this._.needsSpace=a.needsSpace);this._.afterCloser=1},text:function(b){this._.indent&&(this.indentation(),!this._.inPre&&(b=CKEDITOR.tools.ltrim(b)));this._.output.push(b)},comment:function(b){this._.indent&&
+this.indentation();this._.output.push("\x3c!--",b,"--\x3e")},lineBreak:function(){!this._.inPre&&0<this._.output.length&&this._.output.push(this.lineBreakChars);this._.indent=1},indentation:function(){!this._.inPre&&this._.indentation&&this._.output.push(this._.indentation);this._.indent=0},reset:function(){this._.output=[];this._.indent=0;this._.indentation="";this._.afterCloser=0;this._.inPre=0;this._.needsSpace=0},setRules:function(b,a){var c=this._.rules[b];c?CKEDITOR.tools.extend(c,a,!0):this._.rules[b]=
+a}}});(function(){function g(a,b){var c=l.exec(a),d=l.exec(b);if(c){if(!c[2]&&"px"==d[2])return d[1];if("px"==c[2]&&!d[2])return d[1]+"px"}return b}var k=CKEDITOR.htmlParser.cssStyle,h=CKEDITOR.tools.cssLength,l=/^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i,m={elements:{$:function(a){var b=a.attributes;if((b=(b=(b=b&&b["data-cke-realelement"])&&new CKEDITOR.htmlParser.fragment.fromHtml(decodeURIComponent(b)))&&b.children[0])&&a.attributes["data-cke-resizable"]){var c=(new k(a)).rules;a=b.attributes;var d=c.width,
+c=c.height;d&&(a.width=g(a.width,d));c&&(a.height=g(a.height,c))}return b}}};CKEDITOR.plugins.add("fakeobjects",{init:function(a){a.filter.allow("img[!data-cke-realelement,src,alt,title](*){*}","fakeobjects")},afterInit:function(a){(a=(a=a.dataProcessor)&&a.htmlFilter)&&a.addRules(m,{applyToAll:!0})}});CKEDITOR.editor.prototype.createFakeElement=function(a,b,c,d){var e=this.lang.fakeobjects,e=e[c]||e.unknown;b={"class":b,"data-cke-realelement":encodeURIComponent(a.getOuterHtml()),"data-cke-real-node-type":a.type,
+alt:e,title:e,align:a.getAttribute("align")||""};CKEDITOR.env.hc||(b.src=CKEDITOR.tools.transparentImageData);c&&(b["data-cke-real-element-type"]=c);d&&(b["data-cke-resizable"]=d,c=new k,d=a.getAttribute("width"),a=a.getAttribute("height"),d&&(c.rules.width=h(d)),a&&(c.rules.height=h(a)),c.populate(b));return this.document.createElement("img",{attributes:b})};CKEDITOR.editor.prototype.createFakeParserElement=function(a,b,c,d){var e=this.lang.fakeobjects,e=e[c]||e.unknown,f;f=new CKEDITOR.htmlParser.basicWriter;
+a.writeHtml(f);f=f.getHtml();b={"class":b,"data-cke-realelement":encodeURIComponent(f),"data-cke-real-node-type":a.type,alt:e,title:e,align:a.attributes.align||""};CKEDITOR.env.hc||(b.src=CKEDITOR.tools.transparentImageData);c&&(b["data-cke-real-element-type"]=c);d&&(b["data-cke-resizable"]=d,d=a.attributes,a=new k,c=d.width,d=d.height,void 0!==c&&(a.rules.width=h(c)),void 0!==d&&(a.rules.height=h(d)),a.populate(b));return new CKEDITOR.htmlParser.element("img",b)};CKEDITOR.editor.prototype.restoreRealElement=
+function(a){if(a.data("cke-real-node-type")!=CKEDITOR.NODE_ELEMENT)return null;var b=CKEDITOR.dom.element.createFromHtml(decodeURIComponent(a.data("cke-realelement")),this.document);if(a.data("cke-resizable")){var c=a.getStyle("width");a=a.getStyle("height");c&&b.setAttribute("width",g(b.getAttribute("width"),c));a&&b.setAttribute("height",g(b.getAttribute("height"),a))}return b}})();(function(){CKEDITOR.plugins.add("iframe",{requires:"dialog,fakeobjects",onLoad:function(){CKEDITOR.addCss("img.cke_iframe{background-image: url("+CKEDITOR.getUrl(this.path+"images/placeholder.png")+");background-position: center center;background-repeat: no-repeat;border: 1px solid #a9a9a9;width: 80px;height: 80px;}")},init:function(a){var b=a.lang.iframe,c="iframe[align,longdesc,frameborder,height,name,scrolling,src,title,width]";a.plugins.dialogadvtab&&(c+=";iframe"+a.plugins.dialogadvtab.allowedContent({id:1,
+classes:1,styles:1}));CKEDITOR.dialog.add("iframe",this.path+"dialogs/iframe.js");a.addCommand("iframe",new CKEDITOR.dialogCommand("iframe",{allowedContent:c,requiredContent:"iframe"}));a.ui.addButton&&a.ui.addButton("Iframe",{label:b.toolbar,command:"iframe",toolbar:"insert,80"});a.on("doubleclick",function(a){var b=a.data.element;b.is("img")&&"iframe"==b.data("cke-real-element-type")&&(a.data.dialog="iframe")});a.addMenuItems&&a.addMenuItems({iframe:{label:b.title,command:"iframe",group:"image"}});
+a.contextMenu&&a.contextMenu.addListener(function(a){if(a&&a.is("img")&&"iframe"==a.data("cke-real-element-type"))return{iframe:CKEDITOR.TRISTATE_OFF}})},afterInit:function(a){var b=a.dataProcessor;(b=b&&b.dataFilter)&&b.addRules({elements:{iframe:function(b){return a.createFakeParserElement(b,"cke_iframe","iframe",!0)}}})}})})();(function(){function m(a){function f(a){var b=!1;g.attachListener(g,"keydown",function(){var d=c.getBody().getElementsByTag(a);if(!b){for(var e=0;e<d.count();e++)d.getItem(e).setCustomData("retain",!0);b=!0}},null,null,1);g.attachListener(g,"keyup",function(){var d=c.getElementsByTag(a);b&&(1!=d.count()||d.getItem(0).getCustomData("retain")||d.getItem(0).hasAttribute("data-cke-temp")||d.getItem(0).remove(1),b=!1)})}var b=this.editor,c=a.document,d=c.body,e=c.getElementById("cke_actscrpt");e&&e.parentNode.removeChild(e);
+(e=c.getElementById("cke_shimscrpt"))&&e.parentNode.removeChild(e);(e=c.getElementById("cke_basetagscrpt"))&&e.parentNode.removeChild(e);d.contentEditable=!0;CKEDITOR.env.ie&&(d.hideFocus=!0,d.disabled=!0,d.removeAttribute("disabled"));delete this._.isLoadingData;this.$=d;c=new CKEDITOR.dom.document(c);this.setup();this.fixInitialSelection();var g=this;CKEDITOR.env.ie&&!CKEDITOR.env.edge&&c.getDocumentElement().addClass(c.$.compatMode);CKEDITOR.env.ie&&!CKEDITOR.env.edge&&b.enterMode!=CKEDITOR.ENTER_P?
+f("p"):CKEDITOR.env.edge&&b.enterMode!=CKEDITOR.ENTER_DIV&&f("div");if(CKEDITOR.env.webkit||CKEDITOR.env.ie&&10<CKEDITOR.env.version)c.getDocumentElement().on("mousedown",function(a){a.data.getTarget().is("html")&&setTimeout(function(){b.editable().focus()})});n(b);try{b.document.$.execCommand("2D-position",!1,!0)}catch(h){}(CKEDITOR.env.gecko||CKEDITOR.env.ie&&"CSS1Compat"==b.document.$.compatMode)&&this.attachListener(this,"keydown",function(a){var c=a.data.getKeystroke();if(33==c||34==c)if(CKEDITOR.env.ie)setTimeout(function(){b.getSelection().scrollIntoView()},
+0);else if(b.window.$.innerHeight>this.$.offsetHeight){var d=b.createRange();d[33==c?"moveToElementEditStart":"moveToElementEditEnd"](this);d.select();a.data.preventDefault()}});CKEDITOR.env.ie&&this.attachListener(c,"blur",function(){try{c.$.selection.empty()}catch(a){}});CKEDITOR.env.iOS&&this.attachListener(c,"touchend",function(){a.focus()});d=b.document.getElementsByTag("title").getItem(0);d.data("cke-title",d.getText());CKEDITOR.env.ie&&(b.document.$.title=this._.docTitle);CKEDITOR.tools.setTimeout(function(){"unloaded"==
+this.status&&(this.status="ready");b.fire("contentDom");this._.isPendingFocus&&(b.focus(),this._.isPendingFocus=!1);setTimeout(function(){b.fire("dataReady")},0)},0,this)}function n(a){function f(){var c;a.editable().attachListener(a,"selectionChange",function(){var d=a.getSelection().getSelectedElement();d&&(c&&(c.detachEvent("onresizestart",b),c=null),d.$.attachEvent("onresizestart",b),c=d.$)})}function b(a){a.returnValue=!1}if(CKEDITOR.env.gecko)try{var c=a.document.$;c.execCommand("enableObjectResizing",
+!1,!a.config.disableObjectResizing);c.execCommand("enableInlineTableEditing",!1,!a.config.disableNativeTableHandles)}catch(d){}else CKEDITOR.env.ie&&11>CKEDITOR.env.version&&a.config.disableObjectResizing&&f(a)}function p(){var a=[];if(8<=CKEDITOR.document.$.documentMode){a.push("html.CSS1Compat [contenteditable\x3dfalse]{min-height:0 !important}");var f=[],b;for(b in CKEDITOR.dtd.$removeEmpty)f.push("html.CSS1Compat "+b+"[contenteditable\x3dfalse]");a.push(f.join(",")+"{display:inline-block}")}else CKEDITOR.env.gecko&&
+(a.push("html{height:100% !important}"),a.push("img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}"));a.push("html{cursor:text;*cursor:auto}");a.push("img,input,textarea{cursor:default}");return a.join("\n")}var l;CKEDITOR.plugins.add("wysiwygarea",{init:function(a){a.config.fullPage&&a.addFeature({allowedContent:"html head title; style [media,type]; body (*)[id]; meta link [*]",requiredContent:"body"});a.addMode("wysiwyg",function(f){function b(b){b&&b.removeListener();
+a.editable(new l(a,d.$.contentWindow.document.body));a.setData(a.getData(1),f)}var c="document.open();"+(CKEDITOR.env.ie?"("+CKEDITOR.tools.fixDomain+")();":"")+"document.close();",c=CKEDITOR.env.air?"javascript:void(0)":CKEDITOR.env.ie&&!CKEDITOR.env.edge?"javascript:void(function(){"+encodeURIComponent(c)+"}())":"",d=CKEDITOR.dom.element.createFromHtml('\x3ciframe src\x3d"'+c+'" frameBorder\x3d"0"\x3e\x3c/iframe\x3e');d.setStyles({width:"100%",height:"100%"});d.addClass("cke_wysiwyg_frame").addClass("cke_reset");
+c=a.ui.space("contents");c.append(d);var e=CKEDITOR.env.ie&&!CKEDITOR.env.edge||CKEDITOR.env.gecko;if(e)d.on("load",b);var g=a.title,h=a.fire("ariaEditorHelpLabel",{}).label;g&&(CKEDITOR.env.ie&&h&&(g+=", "+h),d.setAttribute("title",g));if(h){var g=CKEDITOR.tools.getNextId(),k=CKEDITOR.dom.element.createFromHtml('\x3cspan id\x3d"'+g+'" class\x3d"cke_voice_label"\x3e'+h+"\x3c/span\x3e");c.append(k,1);d.setAttribute("aria-describedby",g)}a.on("beforeModeUnload",function(a){a.removeListener();k&&k.remove()});
+d.setAttributes({tabIndex:a.tabIndex,allowTransparency:"true"});!e&&b();a.fire("ariaWidget",d)})}});CKEDITOR.editor.prototype.addContentsCss=function(a){var f=this.config,b=f.contentsCss;CKEDITOR.tools.isArray(b)||(f.contentsCss=b?[b]:[]);f.contentsCss.push(a)};l=CKEDITOR.tools.createClass({$:function(){this.base.apply(this,arguments);this._.frameLoadedHandler=CKEDITOR.tools.addFunction(function(a){CKEDITOR.tools.setTimeout(m,0,this,a)},this);this._.docTitle=this.getWindow().getFrame().getAttribute("title")},
+base:CKEDITOR.editable,proto:{setData:function(a,f){var b=this.editor;if(f)this.setHtml(a),this.fixInitialSelection(),b.fire("dataReady");else{this._.isLoadingData=!0;b._.dataStore={id:1};var c=b.config,d=c.fullPage,e=c.docType,g=CKEDITOR.tools.buildStyleHtml(p()).replace(/<style>/,'\x3cstyle data-cke-temp\x3d"1"\x3e');d||(g+=CKEDITOR.tools.buildStyleHtml(b.config.contentsCss));var h=c.baseHref?'\x3cbase href\x3d"'+c.baseHref+'" data-cke-temp\x3d"1" /\x3e':"";d&&(a=a.replace(/<!DOCTYPE[^>]*>/i,function(a){b.docType=
+e=a;return""}).replace(/<\?xml\s[^\?]*\?>/i,function(a){b.xmlDeclaration=a;return""}));a=b.dataProcessor.toHtml(a);d?(/<body[\s|>]/.test(a)||(a="\x3cbody\x3e"+a),/<html[\s|>]/.test(a)||(a="\x3chtml\x3e"+a+"\x3c/html\x3e"),/<head[\s|>]/.test(a)?/<title[\s|>]/.test(a)||(a=a.replace(/<head[^>]*>/,"$\x26\x3ctitle\x3e\x3c/title\x3e")):a=a.replace(/<html[^>]*>/,"$\x26\x3chead\x3e\x3ctitle\x3e\x3c/title\x3e\x3c/head\x3e"),h&&(a=a.replace(/<head[^>]*?>/,"$\x26"+h)),a=a.replace(/<\/head\s*>/,g+"$\x26"),a=
+e+a):a=c.docType+'\x3chtml dir\x3d"'+c.contentsLangDirection+'" lang\x3d"'+(c.contentsLanguage||b.langCode)+'"\x3e\x3chead\x3e\x3ctitle\x3e'+this._.docTitle+"\x3c/title\x3e"+h+g+"\x3c/head\x3e\x3cbody"+(c.bodyId?' id\x3d"'+c.bodyId+'"':"")+(c.bodyClass?' class\x3d"'+c.bodyClass+'"':"")+"\x3e"+a+"\x3c/body\x3e\x3c/html\x3e";CKEDITOR.env.gecko&&(a=a.replace(/<body/,'\x3cbody contenteditable\x3d"true" '),2E4>CKEDITOR.env.version&&(a=a.replace(/<body[^>]*>/,"$\x26\x3c!-- cke-content-start --\x3e")));
+c='\x3cscript id\x3d"cke_actscrpt" type\x3d"text/javascript"'+(CKEDITOR.env.ie?' defer\x3d"defer" ':"")+"\x3evar wasLoaded\x3d0;function onload(){if(!wasLoaded)window.parent.CKEDITOR.tools.callFunction("+this._.frameLoadedHandler+",window);wasLoaded\x3d1;}"+(CKEDITOR.env.ie?"onload();":'document.addEventListener("DOMContentLoaded", onload, false );')+"\x3c/script\x3e";CKEDITOR.env.ie&&9>CKEDITOR.env.version&&(c+='\x3cscript id\x3d"cke_shimscrpt"\x3ewindow.parent.CKEDITOR.tools.enableHtml5Elements(document)\x3c/script\x3e');
+h&&CKEDITOR.env.ie&&10>CKEDITOR.env.version&&(c+='\x3cscript id\x3d"cke_basetagscrpt"\x3evar baseTag \x3d document.querySelector( "base" );baseTag.href \x3d baseTag.href;\x3c/script\x3e');a=a.replace(/(?=\s*<\/(:?head)>)/,c);this.clearCustomData();this.clearListeners();b.fire("contentDomUnload");var k=this.getDocument();try{k.write(a)}catch(l){setTimeout(function(){k.write(a)},0)}}},getData:function(a){if(a)return this.getHtml();a=this.editor;var f=a.config,b=f.fullPage,c=b&&a.docType,d=b&&a.xmlDeclaration,
+e=this.getDocument(),b=b?e.getDocumentElement().getOuterHtml():e.getBody().getHtml();CKEDITOR.env.gecko&&f.enterMode!=CKEDITOR.ENTER_BR&&(b=b.replace(/<br>(?=\s*(:?$|<\/body>))/,""));b=a.dataProcessor.toDataFormat(b);d&&(b=d+"\n"+b);c&&(b=c+"\n"+b);return b},focus:function(){this._.isLoadingData?this._.isPendingFocus=!0:l.baseProto.focus.call(this)},detach:function(){var a=this.editor,f=a.document,b;try{b=a.window.getFrame()}catch(c){}l.baseProto.detach.call(this);this.clearCustomData();f.getDocumentElement().clearCustomData();
+CKEDITOR.tools.removeFunction(this._.frameLoadedHandler);b&&b.getParent()?(b.clearCustomData(),(a=b.removeCustomData("onResize"))&&a.removeListener(),b.remove()):CKEDITOR.warn("editor-destroy-iframe")}}})})();CKEDITOR.config.disableObjectResizing=!1;CKEDITOR.config.disableNativeTableHandles=!0;CKEDITOR.config.disableNativeSpellChecker=!0;(function(){function e(b,a){a||(a=b.getSelection().getSelectedElement());if(a&&a.is("img")&&!a.data("cke-realelement")&&!a.isReadOnly())return a}function f(b){var a=b.getStyle("float");if("inherit"==a||"none"==a)a=0;a||(a=b.getAttribute("align"));return a}CKEDITOR.plugins.add("image",{requires:"dialog",init:function(b){if(!b.plugins.image2){CKEDITOR.dialog.add("image",this.path+"dialogs/image.js");var a="img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}";
+CKEDITOR.dialog.isTabEnabled(b,"image","advanced")&&(a="img[alt,dir,id,lang,longdesc,!src,title]{*}(*)");b.addCommand("image",new CKEDITOR.dialogCommand("image",{allowedContent:a,requiredContent:"img[alt,src]",contentTransformations:[["img{width}: sizeToStyle","img[width]: sizeToAttribute"],["img{float}: alignmentToStyle","img[align]: alignmentToAttribute"]]}));b.ui.addButton&&b.ui.addButton("Image",{label:b.lang.common.image,command:"image",toolbar:"insert,10"});b.on("doubleclick",function(b){var a=
+b.data.element;!a.is("img")||a.data("cke-realelement")||a.isReadOnly()||(b.data.dialog="image")});b.addMenuItems&&b.addMenuItems({image:{label:b.lang.image.menu,command:"image",group:"image"}});b.contextMenu&&b.contextMenu.addListener(function(a){if(e(b,a))return{image:CKEDITOR.TRISTATE_OFF}})}},afterInit:function(b){function a(a){var d=b.getCommand("justify"+a);if(d){if("left"==a||"right"==a)d.on("exec",function(d){var c=e(b),g;c&&(g=f(c),g==a?(c.removeStyle("float"),a==f(c)&&c.removeAttribute("align")):
+c.setStyle("float",a),d.cancel())});d.on("refresh",function(d){var c=e(b);c&&(c=f(c),this.setState(c==a?CKEDITOR.TRISTATE_ON:"right"==a||"left"==a?CKEDITOR.TRISTATE_OFF:CKEDITOR.TRISTATE_DISABLED),d.cancel())})}}b.plugins.image2||(a("left"),a("right"),a("center"),a("block"))}})})();CKEDITOR.config.image_removeLinkByEmptyURL=!0;(function(){function m(a,b){var e,f;b.on("refresh",function(a){var b=[k],c;for(c in a.data.states)b.push(a.data.states[c]);this.setState(CKEDITOR.tools.search(b,p)?p:k)},b,null,100);b.on("exec",function(b){e=a.getSelection();f=e.createBookmarks(1);b.data||(b.data={});b.data.done=!1},b,null,0);b.on("exec",function(){a.forceNextSelectionCheck();e.selectBookmarks(f)},b,null,100)}var k=CKEDITOR.TRISTATE_DISABLED,p=CKEDITOR.TRISTATE_OFF;CKEDITOR.plugins.add("indent",{init:function(a){var b=CKEDITOR.plugins.indent.genericDefinition;
+m(a,a.addCommand("indent",new b(!0)));m(a,a.addCommand("outdent",new b));a.ui.addButton&&(a.ui.addButton("Indent",{label:a.lang.indent.indent,command:"indent",directional:!0,toolbar:"indent,20"}),a.ui.addButton("Outdent",{label:a.lang.indent.outdent,command:"outdent",directional:!0,toolbar:"indent,10"}));a.on("dirChanged",function(b){var f=a.createRange(),l=b.data.node;f.setStartBefore(l);f.setEndAfter(l);for(var n=new CKEDITOR.dom.walker(f),c;c=n.next();)if(c.type==CKEDITOR.NODE_ELEMENT)if(!c.equals(l)&&
+c.getDirection())f.setStartAfter(c),n=new CKEDITOR.dom.walker(f);else{var d=a.config.indentClasses;if(d)for(var g="ltr"==b.data.dir?["_rtl",""]:["","_rtl"],h=0;h<d.length;h++)c.hasClass(d[h]+g[0])&&(c.removeClass(d[h]+g[0]),c.addClass(d[h]+g[1]));d=c.getStyle("margin-right");g=c.getStyle("margin-left");d?c.setStyle("margin-left",d):c.removeStyle("margin-left");g?c.setStyle("margin-right",g):c.removeStyle("margin-right")}})}});CKEDITOR.plugins.indent={genericDefinition:function(a){this.isIndent=!!a;
+this.startDisabled=!this.isIndent},specificDefinition:function(a,b,e){this.name=b;this.editor=a;this.jobs={};this.enterBr=a.config.enterMode==CKEDITOR.ENTER_BR;this.isIndent=!!e;this.relatedGlobal=e?"indent":"outdent";this.indentKey=e?9:CKEDITOR.SHIFT+9;this.database={}},registerCommands:function(a,b){a.on("pluginsLoaded",function(){for(var a in b)(function(a,b){var e=a.getCommand(b.relatedGlobal),c;for(c in b.jobs)e.on("exec",function(d){d.data.done||(a.fire("lockSnapshot"),b.execJob(a,c)&&(d.data.done=
+!0),a.fire("unlockSnapshot"),CKEDITOR.dom.element.clearAllMarkers(b.database))},this,null,c),e.on("refresh",function(d){d.data.states||(d.data.states={});d.data.states[b.name+"@"+c]=b.refreshJob(a,c,d.data.path)},this,null,c);a.addFeature(b)})(this,b[a])})}};CKEDITOR.plugins.indent.genericDefinition.prototype={context:"p",exec:function(){}};CKEDITOR.plugins.indent.specificDefinition.prototype={execJob:function(a,b){var e=this.jobs[b];if(e.state!=k)return e.exec.call(this,a)},refreshJob:function(a,
+b,e){b=this.jobs[b];a.activeFilter.checkFeature(this)?b.state=b.refresh.call(this,a,e):b.state=k;return b.state},getContext:function(a){return a.contains(this.context)}}})();(function(){function f(b,c,a){if(!b.getCustomData("indent_processed")){var d=this.editor,l=this.isIndent;if(c){d=b.$.className.match(this.classNameRegex);a=0;d&&(d=d[1],a=CKEDITOR.tools.indexOf(c,d)+1);if(0>(a+=l?1:-1))return;a=Math.min(a,c.length);a=Math.max(a,0);b.$.className=CKEDITOR.tools.ltrim(b.$.className.replace(this.classNameRegex,""));0<a&&b.addClass(c[a-1])}else{c=m(b,a);a=parseInt(b.getStyle(c),10);var g=d.config.indentOffset||40;isNaN(a)&&(a=0);a+=(l?1:-1)*g;if(0>a)return;a=Math.max(a,
+0);a=Math.ceil(a/g)*g;b.setStyle(c,a?a+(d.config.indentUnit||"px"):"");""===b.getAttribute("style")&&b.removeAttribute("style")}CKEDITOR.dom.element.setMarker(this.database,b,"indent_processed",1)}}function m(b,c){return"ltr"==(c||b.getComputedStyle("direction"))?"margin-left":"margin-right"}var h=CKEDITOR.dtd.$listItem,p=CKEDITOR.dtd.$list,k=CKEDITOR.TRISTATE_DISABLED,n=CKEDITOR.TRISTATE_OFF;CKEDITOR.plugins.add("indentblock",{requires:"indent",init:function(b){function c(){a.specificDefinition.apply(this,
+arguments);this.allowedContent={"div h1 h2 h3 h4 h5 h6 ol p pre ul":{propertiesOnly:!0,styles:d?null:"margin-left,margin-right",classes:d||null}};this.contentTransformations=[["div: splitMarginShorthand"],["h1: splitMarginShorthand"],["h2: splitMarginShorthand"],["h3: splitMarginShorthand"],["h4: splitMarginShorthand"],["h5: splitMarginShorthand"],["h6: splitMarginShorthand"],["ol: splitMarginShorthand"],["p: splitMarginShorthand"],["pre: splitMarginShorthand"],["ul: splitMarginShorthand"]];this.enterBr&&
+(this.allowedContent.div=!0);this.requiredContent=(this.enterBr?"div":"p")+(d?"("+d.join(",")+")":"{margin-left}");this.jobs={20:{refresh:function(a,b){var e=b.block||b.blockLimit;if(!e.is(h))var c=e.getAscendant(h),e=c&&b.contains(c)||e;e.is(h)&&(e=e.getParent());if(this.enterBr||this.getContext(b)){if(d){var c=d,e=e.$.className.match(this.classNameRegex),f=this.isIndent,c=e?f?e[1]!=c.slice(-1):!0:f;return c?n:k}return this.isIndent?n:e?CKEDITOR[0>=(parseInt(e.getStyle(m(e)),10)||0)?"TRISTATE_DISABLED":
+"TRISTATE_OFF"]:k}return k},exec:function(a){var b=a.getSelection(),b=b&&b.getRanges()[0],c;if(c=a.elementPath().contains(p))f.call(this,c,d);else for(b=b.createIterator(),a=a.config.enterMode,b.enforceRealBlocks=!0,b.enlargeBr=a!=CKEDITOR.ENTER_BR;c=b.getNextParagraph(a==CKEDITOR.ENTER_P?"p":"div");)c.isReadOnly()||f.call(this,c,d);return!0}}}}var a=CKEDITOR.plugins.indent,d=b.config.indentClasses;a.registerCommands(b,{indentblock:new c(b,"indentblock",!0),outdentblock:new c(b,"outdentblock")});
+CKEDITOR.tools.extend(c.prototype,a.specificDefinition.prototype,{context:{div:1,dl:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,ul:1,ol:1,p:1,pre:1,table:1},classNameRegex:d?new RegExp("(?:^|\\s+)("+d.join("|")+")(?\x3d$|\\s)"):null})}})})();(function(){function w(c){function f(b){for(var e=d.startContainer,a=d.endContainer;e&&!e.getParent().equals(b);)e=e.getParent();for(;a&&!a.getParent().equals(b);)a=a.getParent();if(!e||!a)return!1;for(var g=e,e=[],k=!1;!k;)g.equals(a)&&(k=!0),e.push(g),g=g.getNext();if(1>e.length)return!1;g=b.getParents(!0);for(a=0;a<g.length;a++)if(g[a].getName&&p[g[a].getName()]){b=g[a];break}for(var g=l.isIndent?1:-1,a=e[0],e=e[e.length-1],k=CKEDITOR.plugins.list.listToArray(b,q),n=k[e.getCustomData("listarray_index")].indent,
+a=a.getCustomData("listarray_index");a<=e.getCustomData("listarray_index");a++)if(k[a].indent+=g,0<g){var h=k[a].parent;k[a].parent=new CKEDITOR.dom.element(h.getName(),h.getDocument())}for(a=e.getCustomData("listarray_index")+1;a<k.length&&k[a].indent>n;a++)k[a].indent+=g;e=CKEDITOR.plugins.list.arrayToList(k,q,null,c.config.enterMode,b.getDirection());if(!l.isIndent){var f;if((f=b.getParent())&&f.is("li"))for(var g=e.listNode.getChildren(),r=[],m,a=g.count()-1;0<=a;a--)(m=g.getItem(a))&&m.is&&m.is("li")&&
+r.push(m)}e&&e.listNode.replace(b);if(r&&r.length)for(a=0;a<r.length;a++){for(m=b=r[a];(m=m.getNext())&&m.is&&m.getName()in p;)CKEDITOR.env.needsNbspFiller&&!b.getFirst(x)&&b.append(d.document.createText(" ")),b.append(m);b.insertAfter(f)}e&&c.fire("contentDomInvalidated");return!0}for(var l=this,q=this.database,p=this.context,n=c.getSelection(),n=(n&&n.getRanges()).createIterator(),d;d=n.getNextRange();){for(var b=d.getCommonAncestor();b&&(b.type!=CKEDITOR.NODE_ELEMENT||!p[b.getName()]);){if(c.editable().equals(b)){b=
+!1;break}b=b.getParent()}b||(b=d.startPath().contains(p))&&d.setEndAt(b,CKEDITOR.POSITION_BEFORE_END);if(!b){var h=d.getEnclosedNode();h&&h.type==CKEDITOR.NODE_ELEMENT&&h.getName()in p&&(d.setStartAt(h,CKEDITOR.POSITION_AFTER_START),d.setEndAt(h,CKEDITOR.POSITION_BEFORE_END),b=h)}b&&d.startContainer.type==CKEDITOR.NODE_ELEMENT&&d.startContainer.getName()in p&&(h=new CKEDITOR.dom.walker(d),h.evaluator=t,d.startContainer=h.next());b&&d.endContainer.type==CKEDITOR.NODE_ELEMENT&&d.endContainer.getName()in
+p&&(h=new CKEDITOR.dom.walker(d),h.evaluator=t,d.endContainer=h.previous());if(b)return f(b)}return 0}function t(c){return c.type==CKEDITOR.NODE_ELEMENT&&c.is("li")}function x(c){return y(c)&&z(c)}var y=CKEDITOR.dom.walker.whitespaces(!0),z=CKEDITOR.dom.walker.bookmark(!1,!0),u=CKEDITOR.TRISTATE_DISABLED,v=CKEDITOR.TRISTATE_OFF;CKEDITOR.plugins.add("indentlist",{requires:"indent",init:function(c){function f(c){l.specificDefinition.apply(this,arguments);this.requiredContent=["ul","ol"];c.on("key",
+function(f){if("wysiwyg"==c.mode&&f.data.keyCode==this.indentKey){var n=this.getContext(c.elementPath());!n||this.isIndent&&CKEDITOR.plugins.indentList.firstItemInPath(this.context,c.elementPath(),n)||(c.execCommand(this.relatedGlobal),f.cancel())}},this);this.jobs[this.isIndent?10:30]={refresh:this.isIndent?function(c,f){var d=this.getContext(f),b=CKEDITOR.plugins.indentList.firstItemInPath(this.context,f,d);return d&&this.isIndent&&!b?v:u}:function(c,f){return!this.getContext(f)||this.isIndent?
+u:v},exec:CKEDITOR.tools.bind(w,this)}}var l=CKEDITOR.plugins.indent;l.registerCommands(c,{indentlist:new f(c,"indentlist",!0),outdentlist:new f(c,"outdentlist")});CKEDITOR.tools.extend(f.prototype,l.specificDefinition.prototype,{context:{ol:1,ul:1}})}});CKEDITOR.plugins.indentList={};CKEDITOR.plugins.indentList.firstItemInPath=function(c,f,l){var q=f.contains(t);l||(l=f.contains(c));return l&&q&&q.equals(l.getFirst(t))}})();(function(){function n(a,c){c=void 0===c||c;var b;if(c)b=a.getComputedStyle("text-align");else{for(;!a.hasAttribute||!a.hasAttribute("align")&&!a.getStyle("text-align");){b=a.getParent();if(!b)break;a=b}b=a.getStyle("text-align")||a.getAttribute("align")||""}b&&(b=b.replace(/(?:-(?:moz|webkit)-)?(?:start|auto)/i,""));!b&&c&&(b="rtl"==a.getComputedStyle("direction")?"right":"left");return b}function g(a,c,b){this.editor=a;this.name=c;this.value=b;this.context="p";c=a.config.justifyClasses;var h=a.config.enterMode==
+CKEDITOR.ENTER_P?"p":"div";if(c){switch(b){case "left":this.cssClassName=c[0];break;case "center":this.cssClassName=c[1];break;case "right":this.cssClassName=c[2];break;case "justify":this.cssClassName=c[3]}this.cssClassRegex=new RegExp("(?:^|\\s+)(?:"+c.join("|")+")(?\x3d$|\\s)");this.requiredContent=h+"("+this.cssClassName+")"}else this.requiredContent=h+"{text-align}";this.allowedContent={"caption div h1 h2 h3 h4 h5 h6 p pre td th li":{propertiesOnly:!0,styles:this.cssClassName?null:"text-align",
+classes:this.cssClassName||null}};a.config.enterMode==CKEDITOR.ENTER_BR&&(this.allowedContent.div=!0)}function l(a){var c=a.editor,b=c.createRange();b.setStartBefore(a.data.node);b.setEndAfter(a.data.node);for(var h=new CKEDITOR.dom.walker(b),d;d=h.next();)if(d.type==CKEDITOR.NODE_ELEMENT)if(!d.equals(a.data.node)&&d.getDirection())b.setStartAfter(d),h=new CKEDITOR.dom.walker(b);else{var e=c.config.justifyClasses;e&&(d.hasClass(e[0])?(d.removeClass(e[0]),d.addClass(e[2])):d.hasClass(e[2])&&(d.removeClass(e[2]),
+d.addClass(e[0])));e=d.getStyle("text-align");"left"==e?d.setStyle("text-align","right"):"right"==e&&d.setStyle("text-align","left")}}g.prototype={exec:function(a){var c=a.getSelection(),b=a.config.enterMode;if(c){for(var h=c.createBookmarks(),d=c.getRanges(),e=this.cssClassName,g,f,k=a.config.useComputedState,k=void 0===k||k,m=d.length-1;0<=m;m--)for(g=d[m].createIterator(),g.enlargeBr=b!=CKEDITOR.ENTER_BR;f=g.getNextParagraph(b==CKEDITOR.ENTER_P?"p":"div");)if(!f.isReadOnly()){f.removeAttribute("align");
+f.removeStyle("text-align");var l=e&&(f.$.className=CKEDITOR.tools.ltrim(f.$.className.replace(this.cssClassRegex,""))),p=this.state==CKEDITOR.TRISTATE_OFF&&(!k||n(f,!0)!=this.value);e?p?f.addClass(e):l||f.removeAttribute("class"):p&&f.setStyle("text-align",this.value)}a.focus();a.forceNextSelectionCheck();c.selectBookmarks(h)}},refresh:function(a,c){var b=c.block||c.blockLimit;this.setState("body"!=b.getName()&&n(b,this.editor.config.useComputedState)==this.value?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF)}};
+CKEDITOR.plugins.add("justify",{init:function(a){if(!a.blockless){var c=new g(a,"justifyleft","left"),b=new g(a,"justifycenter","center"),h=new g(a,"justifyright","right"),d=new g(a,"justifyblock","justify");a.addCommand("justifyleft",c);a.addCommand("justifycenter",b);a.addCommand("justifyright",h);a.addCommand("justifyblock",d);a.ui.addButton&&(a.ui.addButton("JustifyLeft",{label:a.lang.justify.left,command:"justifyleft",toolbar:"align,10"}),a.ui.addButton("JustifyCenter",{label:a.lang.justify.center,
+command:"justifycenter",toolbar:"align,20"}),a.ui.addButton("JustifyRight",{label:a.lang.justify.right,command:"justifyright",toolbar:"align,30"}),a.ui.addButton("JustifyBlock",{label:a.lang.justify.block,command:"justifyblock",toolbar:"align,40"}));a.on("dirChanged",l)}}})})();(function(){function p(c){return c.replace(/'/g,"\\$\x26")}function q(c){for(var b,a=c.length,f=[],e=0;e<a;e++)b=c.charCodeAt(e),f.push(b);return"String.fromCharCode("+f.join(",")+")"}function r(c,b){var a=c.plugins.link,f=a.compiledProtectionFunction.params,e,d;d=[a.compiledProtectionFunction.name,"("];for(var g=0;g<f.length;g++)a=f[g].toLowerCase(),e=b[a],0<g&&d.push(","),d.push("'",e?p(encodeURIComponent(b[a])):"","'");d.push(")");return d.join("")}function n(c){c=c.config.emailProtection||"";
+var b;c&&"encode"!=c&&(b={},c.replace(/^([^(]+)\(([^)]+)\)$/,function(a,c,e){b.name=c;b.params=[];e.replace(/[^,\s]+/g,function(a){b.params.push(a)})}));return b}CKEDITOR.plugins.add("link",{requires:"dialog,fakeobjects",onLoad:function(){function c(b){return a.replace(/%1/g,"rtl"==b?"right":"left").replace(/%2/g,"cke_contents_"+b)}var b="background:url("+CKEDITOR.getUrl(this.path+"images"+(CKEDITOR.env.hidpi?"/hidpi":"")+"/anchor.png")+") no-repeat %1 center;border:1px dotted #00f;background-size:16px;",
+a=".%2 a.cke_anchor,.%2 a.cke_anchor_empty,.cke_editable.%2 a[name],.cke_editable.%2 a[data-cke-saved-name]{"+b+"padding-%1:18px;cursor:auto;}.%2 img.cke_anchor{"+b+"width:16px;min-height:15px;height:1.15em;vertical-align:text-bottom;}";CKEDITOR.addCss(c("ltr")+c("rtl"))},init:function(c){var b="a[!href]";CKEDITOR.dialog.isTabEnabled(c,"link","advanced")&&(b=b.replace("]",",accesskey,charset,dir,id,lang,name,rel,tabindex,title,type,download]{*}(*)"));CKEDITOR.dialog.isTabEnabled(c,"link","target")&&
+(b=b.replace("]",",target,onclick]"));c.addCommand("link",new CKEDITOR.dialogCommand("link",{allowedContent:b,requiredContent:"a[href]"}));c.addCommand("anchor",new CKEDITOR.dialogCommand("anchor",{allowedContent:"a[!name,id]",requiredContent:"a[name]"}));c.addCommand("unlink",new CKEDITOR.unlinkCommand);c.addCommand("removeAnchor",new CKEDITOR.removeAnchorCommand);c.setKeystroke(CKEDITOR.CTRL+76,"link");c.ui.addButton&&(c.ui.addButton("Link",{label:c.lang.link.toolbar,command:"link",toolbar:"links,10"}),
+c.ui.addButton("Unlink",{label:c.lang.link.unlink,command:"unlink",toolbar:"links,20"}),c.ui.addButton("Anchor",{label:c.lang.link.anchor.toolbar,command:"anchor",toolbar:"links,30"}));CKEDITOR.dialog.add("link",this.path+"dialogs/link.js");CKEDITOR.dialog.add("anchor",this.path+"dialogs/anchor.js");c.on("doubleclick",function(a){var b=CKEDITOR.plugins.link.getSelectedLink(c)||a.data.element;b.isReadOnly()||(b.is("a")?(a.data.dialog=!b.getAttribute("name")||b.getAttribute("href")&&b.getChildCount()?
+"link":"anchor",a.data.link=b):CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,b)&&(a.data.dialog="anchor"))},null,null,0);c.on("doubleclick",function(a){a.data.dialog in{link:1,anchor:1}&&a.data.link&&c.getSelection().selectElement(a.data.link)},null,null,20);c.addMenuItems&&c.addMenuItems({anchor:{label:c.lang.link.anchor.menu,command:"anchor",group:"anchor",order:1},removeAnchor:{label:c.lang.link.anchor.remove,command:"removeAnchor",group:"anchor",order:5},link:{label:c.lang.link.menu,command:"link",
+group:"link",order:1},unlink:{label:c.lang.link.unlink,command:"unlink",group:"link",order:5}});c.contextMenu&&c.contextMenu.addListener(function(a){if(!a||a.isReadOnly())return null;a=CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,a);if(!a&&!(a=CKEDITOR.plugins.link.getSelectedLink(c)))return null;var b={};a.getAttribute("href")&&a.getChildCount()&&(b={link:CKEDITOR.TRISTATE_OFF,unlink:CKEDITOR.TRISTATE_OFF});a&&a.hasAttribute("name")&&(b.anchor=b.removeAnchor=CKEDITOR.TRISTATE_OFF);return b});this.compiledProtectionFunction=
+n(c)},afterInit:function(c){c.dataProcessor.dataFilter.addRules({elements:{a:function(a){return a.attributes.name?a.children.length?null:c.createFakeParserElement(a,"cke_anchor","anchor"):null}}});var b=c._.elementsPath&&c._.elementsPath.filters;b&&b.push(function(a,b){if("a"==b&&(CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,a)||a.getAttribute("name")&&(!a.getAttribute("href")||!a.getChildCount())))return"anchor"})}});var t=/^javascript:/,u=/^mailto:([^?]+)(?:\?(.+))?$/,v=/subject=([^;?:@&=$,\/]*)/i,
+w=/body=([^;?:@&=$,\/]*)/i,x=/^#(.*)$/,y=/^((?:http|https|ftp|news):\/\/)?(.*)$/,z=/^(_(?:self|top|parent|blank))$/,A=/^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,B=/^javascript:([^(]+)\(([^)]+)\)$/,C=/\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/,D=/(?:^|,)([^=]+)=(\d+|yes|no)/gi,m={id:"advId",dir:"advLangDir",accessKey:"advAccessKey",name:"advName",lang:"advLangCode",tabindex:"advTabIndex",
+title:"advTitle",type:"advContentType","class":"advCSSClasses",charset:"advCharset",style:"advStyles",rel:"advRel"};CKEDITOR.plugins.link={getSelectedLink:function(c){var b=c.getSelection(),a=b.getSelectedElement();return a&&a.is("a")?a:(b=b.getRanges()[0])?(b.shrink(CKEDITOR.SHRINK_TEXT),c.elementPath(b.getCommonAncestor()).contains("a",1)):null},getEditorAnchors:function(c){for(var b=c.editable(),a=b.isInline()&&!c.plugins.divarea?c.document:b,b=a.getElementsByTag("a"),a=a.getElementsByTag("img"),
+f=[],e=0,d;d=b.getItem(e++);)(d.data("cke-saved-name")||d.hasAttribute("name"))&&f.push({name:d.data("cke-saved-name")||d.getAttribute("name"),id:d.getAttribute("id")});for(e=0;d=a.getItem(e++);)(d=this.tryRestoreFakeAnchor(c,d))&&f.push({name:d.getAttribute("name"),id:d.getAttribute("id")});return f},fakeAnchor:!0,tryRestoreFakeAnchor:function(c,b){if(b&&b.data("cke-real-element-type")&&"anchor"==b.data("cke-real-element-type")){var a=c.restoreRealElement(b);if(a.data("cke-saved-name"))return a}},
+parseLinkAttributes:function(c,b){var a=b&&(b.data("cke-saved-href")||b.getAttribute("href"))||"",f=c.plugins.link.compiledProtectionFunction,e=c.config.emailProtection,d,g={};a.match(t)&&("encode"==e?a=a.replace(A,function(a,b,c){c=c||"";return"mailto:"+String.fromCharCode.apply(String,b.split(","))+c.replace(/\\'/g,"'")}):e&&a.replace(B,function(a,b,c){if(b==f.name){g.type="email";a=g.email={};b=/(^')|('$)/g;c=c.match(/[^,\s]+/g);for(var d=c.length,e,h,k=0;k<d;k++)e=decodeURIComponent,h=c[k].replace(b,
+"").replace(/\\'/g,"'"),h=e(h),e=f.params[k].toLowerCase(),a[e]=h;a.address=[a.name,a.domain].join("@")}}));if(!g.type)if(e=a.match(x))g.type="anchor",g.anchor={},g.anchor.name=g.anchor.id=e[1];else if(e=a.match(u)){d=a.match(v);a=a.match(w);g.type="email";var k=g.email={};k.address=e[1];d&&(k.subject=decodeURIComponent(d[1]));a&&(k.body=decodeURIComponent(a[1]))}else a&&(d=a.match(y))&&(g.type="url",g.url={},g.url.protocol=d[1],g.url.url=d[2]);if(b){if(a=b.getAttribute("target"))g.target={type:a.match(z)?
+a:"frame",name:a};else if(a=(a=b.data("cke-pa-onclick")||b.getAttribute("onclick"))&&a.match(C))for(g.target={type:"popup",name:a[1]};e=D.exec(a[2]);)"yes"!=e[2]&&"1"!=e[2]||e[1]in{height:1,width:1,top:1,left:1}?isFinite(e[2])&&(g.target[e[1]]=e[2]):g.target[e[1]]=!0;null!==b.getAttribute("download")&&(g.download=!0);var a={},h;for(h in m)(e=b.getAttribute(h))&&(a[m[h]]=e);if(h=b.data("cke-saved-name")||a.advName)a.advName=h;CKEDITOR.tools.isEmpty(a)||(g.advanced=a)}return g},getLinkAttributes:function(c,
+b){var a=c.config.emailProtection||"",f={};switch(b.type){case "url":var a=b.url&&void 0!==b.url.protocol?b.url.protocol:"http://",e=b.url&&CKEDITOR.tools.trim(b.url.url)||"";f["data-cke-saved-href"]=0===e.indexOf("/")?e:a+e;break;case "anchor":a=b.anchor&&b.anchor.id;f["data-cke-saved-href"]="#"+(b.anchor&&b.anchor.name||a||"");break;case "email":var d=b.email,e=d.address;switch(a){case "":case "encode":var g=encodeURIComponent(d.subject||""),k=encodeURIComponent(d.body||""),d=[];g&&d.push("subject\x3d"+
+g);k&&d.push("body\x3d"+k);d=d.length?"?"+d.join("\x26"):"";"encode"==a?(a=["javascript:void(location.href\x3d'mailto:'+",q(e)],d&&a.push("+'",p(d),"'"),a.push(")")):a=["mailto:",e,d];break;default:a=e.split("@",2),d.name=a[0],d.domain=a[1],a=["javascript:",r(c,d)]}f["data-cke-saved-href"]=a.join("")}if(b.target)if("popup"==b.target.type){for(var a=["window.open(this.href, '",b.target.name||"","', '"],h="resizable status location toolbar menubar fullscreen scrollbars dependent".split(" "),e=h.length,
+g=function(a){b.target[a]&&h.push(a+"\x3d"+b.target[a])},d=0;d<e;d++)h[d]+=b.target[h[d]]?"\x3dyes":"\x3dno";g("width");g("left");g("height");g("top");a.push(h.join(","),"'); return false;");f["data-cke-pa-onclick"]=a.join("")}else"notSet"!=b.target.type&&b.target.name&&(f.target=b.target.name);b.download&&(f.download="");if(b.advanced){for(var l in m)(a=b.advanced[m[l]])&&(f[l]=a);f.name&&(f["data-cke-saved-name"]=f.name)}f["data-cke-saved-href"]&&(f.href=f["data-cke-saved-href"]);l={target:1,onclick:1,
+"data-cke-pa-onclick":1,"data-cke-saved-name":1,download:1};b.advanced&&CKEDITOR.tools.extend(l,m);for(var n in f)delete l[n];return{set:f,removed:CKEDITOR.tools.objectKeys(l)}},showDisplayTextForElement:function(c,b){var a={img:1,table:1,tbody:1,thead:1,tfoot:1,input:1,select:1,textarea:1};return b.widgets&&b.widgets.focused?!1:!c||!c.getName||!c.is(a)}};CKEDITOR.unlinkCommand=function(){};CKEDITOR.unlinkCommand.prototype={exec:function(c){var b=new CKEDITOR.style({element:"a",type:CKEDITOR.STYLE_INLINE,
+alwaysRemoveElement:1});c.removeStyle(b)},refresh:function(c,b){var a=b.lastElement&&b.lastElement.getAscendant("a",!0);a&&"a"==a.getName()&&a.getAttribute("href")&&a.getChildCount()?this.setState(CKEDITOR.TRISTATE_OFF):this.setState(CKEDITOR.TRISTATE_DISABLED)},contextSensitive:1,startDisabled:1,requiredContent:"a[href]"};CKEDITOR.removeAnchorCommand=function(){};CKEDITOR.removeAnchorCommand.prototype={exec:function(c){var b=c.getSelection(),a=b.createBookmarks(),f;if(b&&(f=b.getSelectedElement())&&
+(f.getChildCount()?f.is("a"):CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,f)))f.remove(1);else if(f=CKEDITOR.plugins.link.getSelectedLink(c))f.hasAttribute("href")?(f.removeAttributes({name:1,"data-cke-saved-name":1}),f.removeClass("cke_anchor")):f.remove(1);b.selectBookmarks(a)},requiredContent:"a[name]"};CKEDITOR.tools.extend(CKEDITOR.config,{linkShowAdvancedTab:!0,linkShowTargetTab:!0})})();(function(){function I(b,m,e){function c(c){if(!(!(a=d[c?"getFirst":"getLast"]())||a.is&&a.isBlockBoundary()||!(p=m.root[c?"getPrevious":"getNext"](CKEDITOR.dom.walker.invisible(!0)))||p.is&&p.isBlockBoundary({br:1})))b.document.createElement("br")[c?"insertBefore":"insertAfter"](a)}for(var f=CKEDITOR.plugins.list.listToArray(m.root,e),g=[],k=0;k<m.contents.length;k++){var h=m.contents[k];(h=h.getAscendant("li",!0))&&!h.getCustomData("list_item_processed")&&(g.push(h),CKEDITOR.dom.element.setMarker(e,
+h,"list_item_processed",!0))}h=null;for(k=0;k<g.length;k++)h=g[k].getCustomData("listarray_index"),f[h].indent=-1;for(k=h+1;k<f.length;k++)if(f[k].indent>f[k-1].indent+1){g=f[k-1].indent+1-f[k].indent;for(h=f[k].indent;f[k]&&f[k].indent>=h;)f[k].indent+=g,k++;k--}var d=CKEDITOR.plugins.list.arrayToList(f,e,null,b.config.enterMode,m.root.getAttribute("dir")).listNode,a,p;c(!0);c();d.replace(m.root);b.fire("contentDomInvalidated")}function B(b,m){this.name=b;this.context=this.type=m;this.allowedContent=
+m+" li";this.requiredContent=m}function E(b,m,e,c){for(var f,g;f=b[c?"getLast":"getFirst"](J);)(g=f.getDirection(1))!==m.getDirection(1)&&f.setAttribute("dir",g),f.remove(),e?f[c?"insertBefore":"insertAfter"](e):m.append(f,c)}function F(b){function m(e){var c=b[e?"getPrevious":"getNext"](u);c&&c.type==CKEDITOR.NODE_ELEMENT&&c.is(b.getName())&&(E(b,c,null,!e),b.remove(),b=c)}m();m(1)}function G(b){return b.type==CKEDITOR.NODE_ELEMENT&&(b.getName()in CKEDITOR.dtd.$block||b.getName()in CKEDITOR.dtd.$listItem)&&
+CKEDITOR.dtd[b.getName()]["#"]}function C(b,m,e){b.fire("saveSnapshot");e.enlarge(CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS);var c=e.extractContents();m.trim(!1,!0);var f=m.createBookmark(),g=new CKEDITOR.dom.elementPath(m.startContainer),k=g.block,g=g.lastElement.getAscendant("li",1)||k,h=new CKEDITOR.dom.elementPath(e.startContainer),d=h.contains(CKEDITOR.dtd.$listItem),h=h.contains(CKEDITOR.dtd.$list);k?(k=k.getBogus())&&k.remove():h&&(k=h.getPrevious(u))&&z(k)&&k.remove();(k=c.getLast())&&k.type==CKEDITOR.NODE_ELEMENT&&
+k.is("br")&&k.remove();(k=m.startContainer.getChild(m.startOffset))?c.insertBefore(k):m.startContainer.append(c);d&&(c=A(d))&&(g.contains(d)?(E(c,d.getParent(),d),c.remove()):g.append(c));for(;e.checkStartOfBlock()&&e.checkEndOfBlock();){h=e.startPath();c=h.block;if(!c)break;c.is("li")&&(g=c.getParent(),c.equals(g.getLast(u))&&c.equals(g.getFirst(u))&&(c=g));e.moveToPosition(c,CKEDITOR.POSITION_BEFORE_START);c.remove()}e=e.clone();c=b.editable();e.setEndAt(c,CKEDITOR.POSITION_BEFORE_END);e=new CKEDITOR.dom.walker(e);
+e.evaluator=function(a){return u(a)&&!z(a)};(e=e.next())&&e.type==CKEDITOR.NODE_ELEMENT&&e.getName()in CKEDITOR.dtd.$list&&F(e);m.moveToBookmark(f);m.select();b.fire("saveSnapshot")}function A(b){return(b=b.getLast(u))&&b.type==CKEDITOR.NODE_ELEMENT&&b.getName()in v?b:null}var v={ol:1,ul:1},K=CKEDITOR.dom.walker.whitespaces(),H=CKEDITOR.dom.walker.bookmark(),u=function(b){return!(K(b)||H(b))},z=CKEDITOR.dom.walker.bogus();CKEDITOR.plugins.list={listToArray:function(b,m,e,c,f){if(!v[b.getName()])return[];
+c||(c=0);e||(e=[]);for(var g=0,k=b.getChildCount();g<k;g++){var h=b.getChild(g);h.type==CKEDITOR.NODE_ELEMENT&&h.getName()in CKEDITOR.dtd.$list&&CKEDITOR.plugins.list.listToArray(h,m,e,c+1);if("li"==h.$.nodeName.toLowerCase()){var d={parent:b,indent:c,element:h,contents:[]};f?d.grandparent=f:(d.grandparent=b.getParent(),d.grandparent&&"li"==d.grandparent.$.nodeName.toLowerCase()&&(d.grandparent=d.grandparent.getParent()));m&&CKEDITOR.dom.element.setMarker(m,h,"listarray_index",e.length);e.push(d);
+for(var a=0,p=h.getChildCount(),l;a<p;a++)l=h.getChild(a),l.type==CKEDITOR.NODE_ELEMENT&&v[l.getName()]?CKEDITOR.plugins.list.listToArray(l,m,e,c+1,d.grandparent):d.contents.push(l)}}return e},arrayToList:function(b,m,e,c,f){e||(e=0);if(!b||b.length<e+1)return null;for(var g,k=b[e].parent.getDocument(),h=new CKEDITOR.dom.documentFragment(k),d=null,a=e,p=Math.max(b[e].indent,0),l=null,q,n,t=c==CKEDITOR.ENTER_P?"p":"div";;){var r=b[a];g=r.grandparent;q=r.element.getDirection(1);if(r.indent==p){d&&b[a].parent.getName()==
+d.getName()||(d=b[a].parent.clone(!1,1),f&&d.setAttribute("dir",f),h.append(d));l=d.append(r.element.clone(0,1));q!=d.getDirection(1)&&l.setAttribute("dir",q);for(g=0;g<r.contents.length;g++)l.append(r.contents[g].clone(1,1));a++}else if(r.indent==Math.max(p,0)+1)r=b[a-1].element.getDirection(1),a=CKEDITOR.plugins.list.arrayToList(b,null,a,c,r!=q?q:null),!l.getChildCount()&&CKEDITOR.env.needsNbspFiller&&7>=k.$.documentMode&&l.append(k.createText(" ")),l.append(a.listNode),a=a.nextIndex;else if(-1==
+r.indent&&!e&&g){v[g.getName()]?(l=r.element.clone(!1,!0),q!=g.getDirection(1)&&l.setAttribute("dir",q)):l=new CKEDITOR.dom.documentFragment(k);var d=g.getDirection(1)!=q,y=r.element,D=y.getAttribute("class"),z=y.getAttribute("style"),A=l.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT&&(c!=CKEDITOR.ENTER_BR||d||z||D),w,B=r.contents.length,x;for(g=0;g<B;g++)if(w=r.contents[g],H(w)&&1<B)A?x=w.clone(1,1):l.append(w.clone(1,1));else if(w.type==CKEDITOR.NODE_ELEMENT&&w.isBlockBoundary()){d&&!w.getDirection()&&
+w.setAttribute("dir",q);n=w;var C=y.getAttribute("style");C&&n.setAttribute("style",C.replace(/([^;])$/,"$1;")+(n.getAttribute("style")||""));D&&w.addClass(D);n=null;x&&(l.append(x),x=null);l.append(w.clone(1,1))}else A?(n||(n=k.createElement(t),l.append(n),d&&n.setAttribute("dir",q)),z&&n.setAttribute("style",z),D&&n.setAttribute("class",D),x&&(n.append(x),x=null),n.append(w.clone(1,1))):l.append(w.clone(1,1));x&&((n||l).append(x),x=null);l.type==CKEDITOR.NODE_DOCUMENT_FRAGMENT&&a!=b.length-1&&(CKEDITOR.env.needsBrFiller&&
+(q=l.getLast())&&q.type==CKEDITOR.NODE_ELEMENT&&q.is("br")&&q.remove(),(q=l.getLast(u))&&q.type==CKEDITOR.NODE_ELEMENT&&q.is(CKEDITOR.dtd.$block)||l.append(k.createElement("br")));q=l.$.nodeName.toLowerCase();"div"!=q&&"p"!=q||l.appendBogus();h.append(l);d=null;a++}else return null;n=null;if(b.length<=a||Math.max(b[a].indent,0)<p)break}if(m)for(b=h.getFirst();b;){if(b.type==CKEDITOR.NODE_ELEMENT&&(CKEDITOR.dom.element.clearMarkers(m,b),b.getName()in CKEDITOR.dtd.$listItem&&(e=b,k=f=c=void 0,c=e.getDirection()))){for(f=
+e.getParent();f&&!(k=f.getDirection());)f=f.getParent();c==k&&e.removeAttribute("dir")}b=b.getNextSourceNode()}return{listNode:h,nextIndex:a}}};var L=/^h[1-6]$/,J=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_ELEMENT);B.prototype={exec:function(b){this.refresh(b,b.elementPath());var m=b.config,e=b.getSelection(),c=e&&e.getRanges();if(this.state==CKEDITOR.TRISTATE_OFF){var f=b.editable();if(f.getFirst(u)){var g=1==c.length&&c[0];(m=g&&g.getEnclosedNode())&&m.is&&this.type==m.getName()&&this.setState(CKEDITOR.TRISTATE_ON)}else m.enterMode==
+CKEDITOR.ENTER_BR?f.appendBogus():c[0].fixBlock(1,m.enterMode==CKEDITOR.ENTER_P?"p":"div"),e.selectRanges(c)}for(var m=e.createBookmarks(!0),f=[],k={},c=c.createIterator(),h=0;(g=c.getNextRange())&&++h;){var d=g.getBoundaryNodes(),a=d.startNode,p=d.endNode;a.type==CKEDITOR.NODE_ELEMENT&&"td"==a.getName()&&g.setStartAt(d.startNode,CKEDITOR.POSITION_AFTER_START);p.type==CKEDITOR.NODE_ELEMENT&&"td"==p.getName()&&g.setEndAt(d.endNode,CKEDITOR.POSITION_BEFORE_END);g=g.createIterator();for(g.forceBrBreak=
+this.state==CKEDITOR.TRISTATE_OFF;d=g.getNextParagraph();)if(!d.getCustomData("list_block")){CKEDITOR.dom.element.setMarker(k,d,"list_block",1);for(var l=b.elementPath(d),a=l.elements,p=0,l=l.blockLimit,q,n=a.length-1;0<=n&&(q=a[n]);n--)if(v[q.getName()]&&l.contains(q)){l.removeCustomData("list_group_object_"+h);(a=q.getCustomData("list_group_object"))?a.contents.push(d):(a={root:q,contents:[d]},f.push(a),CKEDITOR.dom.element.setMarker(k,q,"list_group_object",a));p=1;break}p||(p=l,p.getCustomData("list_group_object_"+
+h)?p.getCustomData("list_group_object_"+h).contents.push(d):(a={root:p,contents:[d]},CKEDITOR.dom.element.setMarker(k,p,"list_group_object_"+h,a),f.push(a)))}}for(q=[];0<f.length;)if(a=f.shift(),this.state==CKEDITOR.TRISTATE_OFF)if(v[a.root.getName()]){c=b;h=a;a=k;g=q;p=CKEDITOR.plugins.list.listToArray(h.root,a);l=[];for(d=0;d<h.contents.length;d++)n=h.contents[d],(n=n.getAscendant("li",!0))&&!n.getCustomData("list_item_processed")&&(l.push(n),CKEDITOR.dom.element.setMarker(a,n,"list_item_processed",
+!0));for(var n=h.root.getDocument(),t=void 0,r=void 0,d=0;d<l.length;d++){var y=l[d].getCustomData("listarray_index"),t=p[y].parent;t.is(this.type)||(r=n.createElement(this.type),t.copyAttributes(r,{start:1,type:1}),r.removeStyle("list-style-type"),p[y].parent=r)}a=CKEDITOR.plugins.list.arrayToList(p,a,null,c.config.enterMode);p=void 0;l=a.listNode.getChildCount();for(d=0;d<l&&(p=a.listNode.getChild(d));d++)p.getName()==this.type&&g.push(p);a.listNode.replace(h.root);c.fire("contentDomInvalidated")}else{p=
+b;g=a;d=q;l=g.contents;c=g.root.getDocument();h=[];1==l.length&&l[0].equals(g.root)&&(a=c.createElement("div"),l[0].moveChildren&&l[0].moveChildren(a),l[0].append(a),l[0]=a);g=g.contents[0].getParent();for(n=0;n<l.length;n++)g=g.getCommonAncestor(l[n].getParent());t=p.config.useComputedState;p=a=void 0;t=void 0===t||t;for(n=0;n<l.length;n++)for(r=l[n];y=r.getParent();){if(y.equals(g)){h.push(r);!p&&r.getDirection()&&(p=1);r=r.getDirection(t);null!==a&&(a=a&&a!=r?null:r);break}r=y}if(!(1>h.length)){l=
+h[h.length-1].getNext();n=c.createElement(this.type);d.push(n);for(t=d=void 0;h.length;)d=h.shift(),t=c.createElement("li"),r=d,r.is("pre")||L.test(r.getName())||"false"==r.getAttribute("contenteditable")?d.appendTo(t):(d.copyAttributes(t),a&&d.getDirection()&&(t.removeStyle("direction"),t.removeAttribute("dir")),d.moveChildren(t),d.remove()),t.appendTo(n);a&&p&&n.setAttribute("dir",a);l?n.insertBefore(l):n.appendTo(g)}}else this.state==CKEDITOR.TRISTATE_ON&&v[a.root.getName()]&&I.call(this,b,a,k);
+for(n=0;n<q.length;n++)F(q[n]);CKEDITOR.dom.element.clearAllMarkers(k);e.selectBookmarks(m);b.focus()},refresh:function(b,m){var e=m.contains(v,1),c=m.blockLimit||m.root;e&&c.contains(e)?this.setState(e.is(this.type)?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF):this.setState(CKEDITOR.TRISTATE_OFF)}};CKEDITOR.plugins.add("list",{requires:"indentlist",init:function(b){b.blockless||(b.addCommand("numberedlist",new B("numberedlist","ol")),b.addCommand("bulletedlist",new B("bulletedlist","ul")),b.ui.addButton&&
+(b.ui.addButton("NumberedList",{label:b.lang.list.numberedlist,command:"numberedlist",directional:!0,toolbar:"list,10"}),b.ui.addButton("BulletedList",{label:b.lang.list.bulletedlist,command:"bulletedlist",directional:!0,toolbar:"list,20"})),b.on("key",function(m){var e=m.data.domEvent.getKey(),c;if("wysiwyg"==b.mode&&e in{8:1,46:1}){var f=b.getSelection().getRanges()[0],g=f&&f.startPath();if(f&&f.collapsed){var k=8==e,h=b.editable(),d=new CKEDITOR.dom.walker(f.clone());d.evaluator=function(a){return u(a)&&
+!z(a)};d.guard=function(a,b){return!(b&&a.type==CKEDITOR.NODE_ELEMENT&&a.is("table"))};e=f.clone();if(k){var a;(a=g.contains(v))&&f.checkBoundaryOfElement(a,CKEDITOR.START)&&(a=a.getParent())&&a.is("li")&&(a=A(a))?(c=a,a=a.getPrevious(u),e.moveToPosition(a&&z(a)?a:c,CKEDITOR.POSITION_BEFORE_START)):(d.range.setStartAt(h,CKEDITOR.POSITION_AFTER_START),d.range.setEnd(f.startContainer,f.startOffset),(a=d.previous())&&a.type==CKEDITOR.NODE_ELEMENT&&(a.getName()in v||a.is("li"))&&(a.is("li")||(d.range.selectNodeContents(a),
+d.reset(),d.evaluator=G,a=d.previous()),c=a,e.moveToElementEditEnd(c),e.moveToPosition(e.endPath().block,CKEDITOR.POSITION_BEFORE_END)));if(c)C(b,e,f),m.cancel();else{var p=g.contains(v);p&&f.checkBoundaryOfElement(p,CKEDITOR.START)&&(c=p.getFirst(u),f.checkBoundaryOfElement(c,CKEDITOR.START)&&(a=p.getPrevious(u),A(c)?a&&(f.moveToElementEditEnd(a),f.select()):b.execCommand("outdent"),m.cancel()))}}else if(c=g.contains("li")){if(d.range.setEndAt(h,CKEDITOR.POSITION_BEFORE_END),k=(h=c.getLast(u))&&
+G(h)?h:c,g=0,(a=d.next())&&a.type==CKEDITOR.NODE_ELEMENT&&a.getName()in v&&a.equals(h)?(g=1,a=d.next()):f.checkBoundaryOfElement(k,CKEDITOR.END)&&(g=2),g&&a){f=f.clone();f.moveToElementEditStart(a);if(1==g&&(e.optimize(),!e.startContainer.equals(c))){for(c=e.startContainer;c.is(CKEDITOR.dtd.$inline);)p=c,c=c.getParent();p&&e.moveToPosition(p,CKEDITOR.POSITION_AFTER_END)}2==g&&(e.moveToPosition(e.endPath().block,CKEDITOR.POSITION_BEFORE_END),f.endPath().block&&f.moveToPosition(f.endPath().block,CKEDITOR.POSITION_AFTER_START));
+C(b,e,f);m.cancel()}}else d.range.setEndAt(h,CKEDITOR.POSITION_BEFORE_END),(a=d.next())&&a.type==CKEDITOR.NODE_ELEMENT&&a.is(v)&&(a=a.getFirst(u),g.block&&f.checkStartOfBlock()&&f.checkEndOfBlock()?(g.block.remove(),f.moveToElementEditStart(a),f.select()):A(a)?(f.moveToElementEditStart(a),f.select()):(f=f.clone(),f.moveToElementEditStart(a),C(b,e,f)),m.cancel());setTimeout(function(){b.selectionChange(1)})}}}))}})})();(function(){CKEDITOR.plugins.liststyle={requires:"dialog,contextmenu",init:function(a){if(!a.blockless){var b;b=new CKEDITOR.dialogCommand("numberedListStyle",{requiredContent:"ol",allowedContent:"ol{list-style-type}[start]; li{list-style-type}[value]",contentTransformations:[["ol: listTypeToStyle"]]});b=a.addCommand("numberedListStyle",b);a.addFeature(b);CKEDITOR.dialog.add("numberedListStyle",this.path+"dialogs/liststyle.js");b=new CKEDITOR.dialogCommand("bulletedListStyle",{requiredContent:"ul",
+allowedContent:"ul{list-style-type}",contentTransformations:[["ul: listTypeToStyle"]]});b=a.addCommand("bulletedListStyle",b);a.addFeature(b);CKEDITOR.dialog.add("bulletedListStyle",this.path+"dialogs/liststyle.js");a.addMenuGroup("list",108);a.addMenuItems({numberedlist:{label:a.lang.liststyle.numberedTitle,group:"list",command:"numberedListStyle"},bulletedlist:{label:a.lang.liststyle.bulletedTitle,group:"list",command:"bulletedListStyle"}});a.contextMenu.addListener(function(a){if(!a||a.isReadOnly())return null;
+for(;a;){var b=a.getName();if("ol"==b)return{numberedlist:CKEDITOR.TRISTATE_OFF};if("ul"==b)return{bulletedlist:CKEDITOR.TRISTATE_OFF};a=a.getParent()}return null})}}};CKEDITOR.plugins.add("liststyle",CKEDITOR.plugins.liststyle)})();(function(){function V(a,c,d){return n(c)&&n(d)&&d.equals(c.getNext(function(a){return!(E(a)||F(a)||u(a))}))}function z(a){this.upper=a[0];this.lower=a[1];this.set.apply(this,a.slice(2))}function O(a){var c=a.element;if(c&&n(c)&&(c=c.getAscendant(a.triggers,!0))&&a.editable.contains(c)){var d=P(c);if("true"==d.getAttribute("contenteditable"))return c;if(d.is(a.triggers))return d}return null}function ka(a,c,d){r(a,c);r(a,d);a=c.size.bottom;d=d.size.top;return a&&d?0|(a+d)/2:a||d}function w(a,c,d){return c=
+c[d?"getPrevious":"getNext"](function(b){return b&&b.type==CKEDITOR.NODE_TEXT&&!E(b)||n(b)&&!u(b)&&!A(a,b)})}function q(a,c,d){return a>c&&a<d}function P(a,c){if(a.data("cke-editable"))return null;for(c||(a=a.getParent());a&&!a.data("cke-editable");){if(a.hasAttribute("contenteditable"))return a;a=a.getParent()}return null}function la(a){var c=a.doc,d=G('\x3cspan contenteditable\x3d"false" style\x3d"'+Q+"position:absolute;border-top:1px dashed "+a.boxColor+'"\x3e\x3c/span\x3e',c),b=CKEDITOR.getUrl(this.path+
+"images/"+(t.hidpi?"hidpi/":"")+"icon"+(a.rtl?"-rtl":"")+".png");v(d,{attach:function(){this.wrap.getParent()||this.wrap.appendTo(a.editable,!0);return this},lineChildren:[v(G('\x3cspan title\x3d"'+a.editor.lang.magicline.title+'" contenteditable\x3d"false"\x3e\x26#8629;\x3c/span\x3e',c),{base:Q+"height:17px;width:17px;"+(a.rtl?"left":"right")+":17px;background:url("+b+") center no-repeat "+a.boxColor+";cursor:pointer;"+(t.hc?"font-size: 15px;line-height:14px;border:1px solid #fff;text-align:center;":
+"")+(t.hidpi?"background-size: 9px 10px;":""),looks:["top:-8px; border-radius: 2px;","top:-17px; border-radius: 2px 2px 0px 0px;","top:-1px; border-radius: 0px 0px 2px 2px;"]}),v(G(W,c),{base:X+"left:0px;border-left-color:"+a.boxColor+";",looks:["border-width:8px 0 8px 8px;top:-8px","border-width:8px 0 0 8px;top:-8px","border-width:0 0 8px 8px;top:0px"]}),v(G(W,c),{base:X+"right:0px;border-right-color:"+a.boxColor+";",looks:["border-width:8px 8px 8px 0;top:-8px","border-width:8px 8px 0 0;top:-8px",
+"border-width:0 8px 8px 0;top:0px"]})],detach:function(){this.wrap.getParent()&&this.wrap.remove();return this},mouseNear:function(){r(a,this);var b=a.holdDistance,c=this.size;return c&&q(a.mouse.y,c.top-b,c.bottom+b)&&q(a.mouse.x,c.left-b,c.right+b)?!0:!1},place:function(){var b=a.view,c=a.editable,d=a.trigger,h=d.upper,g=d.lower,l=h||g,p=l.getParent(),m={};this.trigger=d;h&&r(a,h,!0);g&&r(a,g,!0);r(a,p,!0);a.inInlineMode&&H(a,!0);p.equals(c)?(m.left=b.scroll.x,m.right=-b.scroll.x,m.width=""):(m.left=
+l.size.left-l.size.margin.left+b.scroll.x-(a.inInlineMode?b.editable.left+b.editable.border.left:0),m.width=l.size.outerWidth+l.size.margin.left+l.size.margin.right+b.scroll.x,m.right="");h&&g?m.top=h.size.margin.bottom===g.size.margin.top?0|h.size.bottom+h.size.margin.bottom/2:h.size.margin.bottom<g.size.margin.top?h.size.bottom+h.size.margin.bottom:h.size.bottom+h.size.margin.bottom-g.size.margin.top:h?g||(m.top=h.size.bottom+h.size.margin.bottom):m.top=g.size.top-g.size.margin.top;d.is(C)||q(m.top,
+b.scroll.y-15,b.scroll.y+5)?(m.top=a.inInlineMode?0:b.scroll.y,this.look(C)):d.is(D)||q(m.top,b.pane.bottom-5,b.pane.bottom+15)?(m.top=a.inInlineMode?b.editable.height+b.editable.padding.top+b.editable.padding.bottom:b.pane.bottom-1,this.look(D)):(a.inInlineMode&&(m.top-=b.editable.top+b.editable.border.top),this.look(x));a.inInlineMode&&(m.top--,m.top+=b.editable.scroll.top,m.left+=b.editable.scroll.left);for(var n in m)m[n]=CKEDITOR.tools.cssLength(m[n]);this.setStyles(m)},look:function(a){if(this.oldLook!=
+a){for(var b=this.lineChildren.length,c;b--;)(c=this.lineChildren[b]).setAttribute("style",c.base+c.looks[0|a/2]);this.oldLook=a}},wrap:new R("span",a.doc)});for(c=d.lineChildren.length;c--;)d.lineChildren[c].appendTo(d);d.look(x);d.appendTo(d.wrap);d.unselectable();d.lineChildren[0].on("mouseup",function(b){d.detach();S(a,function(b){var c=a.line.trigger;b[c.is(I)?"insertBefore":"insertAfter"](c.is(I)?c.lower:c.upper)},!0);a.editor.focus();t.ie||a.enterMode==CKEDITOR.ENTER_BR||a.hotNode.scrollIntoView();
+b.data.preventDefault(!0)});d.on("mousedown",function(a){a.data.preventDefault(!0)});a.line=d}function S(a,c,d){var b=new CKEDITOR.dom.range(a.doc),e=a.editor,f;t.ie&&a.enterMode==CKEDITOR.ENTER_BR?f=a.doc.createText(J):(f=(f=P(a.element,!0))&&f.data("cke-enter-mode")||a.enterMode,f=new R(K[f],a.doc),f.is("br")||a.doc.createText(J).appendTo(f));d&&e.fire("saveSnapshot");c(f);b.moveToPosition(f,CKEDITOR.POSITION_AFTER_START);e.getSelection().selectRanges([b]);a.hotNode=f;d&&e.fire("saveSnapshot")}
+function Y(a,c){return{canUndo:!0,modes:{wysiwyg:1},exec:function(){function d(b){var d=t.ie&&9>t.version?" ":J,f=a.hotNode&&a.hotNode.getText()==d&&a.element.equals(a.hotNode)&&a.lastCmdDirection===!!c;S(a,function(d){f&&a.hotNode&&a.hotNode.remove();d[c?"insertAfter":"insertBefore"](b);d.setAttributes({"data-cke-magicline-hot":1,"data-cke-magicline-dir":!!c});a.lastCmdDirection=!!c});t.ie||a.enterMode==CKEDITOR.ENTER_BR||a.hotNode.scrollIntoView();a.line.detach()}return function(b){b=b.getSelection().getStartElement();
+var e;b=b.getAscendant(Z,1);if(!aa(a,b)&&b&&!b.equals(a.editable)&&!b.contains(a.editable)){(e=P(b))&&"false"==e.getAttribute("contenteditable")&&(b=e);a.element=b;e=w(a,b,!c);var f;n(e)&&e.is(a.triggers)&&e.is(ma)&&(!w(a,e,!c)||(f=w(a,e,!c))&&n(f)&&f.is(a.triggers))?d(e):(f=O(a,b),n(f)&&(w(a,f,!c)?(b=w(a,f,!c))&&n(b)&&b.is(a.triggers)&&d(f):d(f)))}}}()}}function A(a,c){if(!c||c.type!=CKEDITOR.NODE_ELEMENT||!c.$)return!1;var d=a.line;return d.wrap.equals(c)||d.wrap.contains(c)}function n(a){return a&&
+a.type==CKEDITOR.NODE_ELEMENT&&a.$}function u(a){if(!n(a))return!1;var c;(c=ba(a))||(n(a)?(c={left:1,right:1,center:1},c=!(!c[a.getComputedStyle("float")]&&!c[a.getAttribute("align")])):c=!1);return c}function ba(a){return!!{absolute:1,fixed:1}[a.getComputedStyle("position")]}function L(a,c){return n(c)?c.is(a.triggers):null}function aa(a,c){if(!c)return!1;for(var d=c.getParents(1),b=d.length;b--;)for(var e=a.tabuList.length;e--;)if(d[b].hasAttribute(a.tabuList[e]))return!0;return!1}function na(a,
+c,d){c=c[d?"getLast":"getFirst"](function(b){return a.isRelevant(b)&&!b.is(oa)});if(!c)return!1;r(a,c);return d?c.size.top>a.mouse.y:c.size.bottom<a.mouse.y}function ca(a){var c=a.editable,d=a.mouse,b=a.view,e=a.triggerOffset;H(a);var f=d.y>(a.inInlineMode?b.editable.top+b.editable.height/2:Math.min(b.editable.height,b.pane.height)/2),c=c[f?"getLast":"getFirst"](function(a){return!(E(a)||F(a))});if(!c)return null;A(a,c)&&(c=a.line.wrap[f?"getPrevious":"getNext"](function(a){return!(E(a)||F(a))}));
+if(!n(c)||u(c)||!L(a,c))return null;r(a,c);return!f&&0<=c.size.top&&q(d.y,0,c.size.top+e)?(a=a.inInlineMode||0===b.scroll.y?C:x,new z([null,c,I,M,a])):f&&c.size.bottom<=b.pane.height&&q(d.y,c.size.bottom-e,b.pane.height)?(a=a.inInlineMode||q(c.size.bottom,b.pane.height-e,b.pane.height)?D:x,new z([c,null,da,M,a])):null}function ea(a){var c=a.mouse,d=a.view,b=a.triggerOffset,e=O(a);if(!e)return null;r(a,e);var b=Math.min(b,0|e.size.outerHeight/2),f=[],k,h;if(q(c.y,e.size.top-1,e.size.top+b))h=!1;else if(q(c.y,
+e.size.bottom-b,e.size.bottom+1))h=!0;else return null;if(u(e)||na(a,e,h)||e.getParent().is(fa))return null;var g=w(a,e,!h);if(g){if(g&&g.type==CKEDITOR.NODE_TEXT)return null;if(n(g)){if(u(g)||!L(a,g)||g.getParent().is(fa))return null;f=[g,e][h?"reverse":"concat"]().concat([T,M])}}else e.equals(a.editable[h?"getLast":"getFirst"](a.isRelevant))?(H(a),h&&q(c.y,e.size.bottom-b,d.pane.height)&&q(e.size.bottom,d.pane.height-b,d.pane.height)?k=D:q(c.y,0,e.size.top+b)&&(k=C)):k=x,f=[null,e][h?"reverse":
+"concat"]().concat([h?da:I,M,k,e.equals(a.editable[h?"getLast":"getFirst"](a.isRelevant))?h?D:C:x]);return 0 in f?new z(f):null}function U(a,c,d,b){for(var e=c.getDocumentPosition(),f={},k={},h={},g={},l=y.length;l--;)f[y[l]]=parseInt(c.getComputedStyle.call(c,"border-"+y[l]+"-width"),10)||0,h[y[l]]=parseInt(c.getComputedStyle.call(c,"padding-"+y[l]),10)||0,k[y[l]]=parseInt(c.getComputedStyle.call(c,"margin-"+y[l]),10)||0;d&&!b||N(a,b);g.top=e.y-(d?0:a.view.scroll.y);g.left=e.x-(d?0:a.view.scroll.x);
+g.outerWidth=c.$.offsetWidth;g.outerHeight=c.$.offsetHeight;g.height=g.outerHeight-(h.top+h.bottom+f.top+f.bottom);g.width=g.outerWidth-(h.left+h.right+f.left+f.right);g.bottom=g.top+g.outerHeight;g.right=g.left+g.outerWidth;a.inInlineMode&&(g.scroll={top:c.$.scrollTop,left:c.$.scrollLeft});return v({border:f,padding:h,margin:k,ignoreScroll:d},g,!0)}function r(a,c,d){if(!n(c))return c.size=null;if(!c.size)c.size={};else if(c.size.ignoreScroll==d&&c.size.date>new Date-ga)return null;return v(c.size,
+U(a,c,d),{date:+new Date},!0)}function H(a,c){a.view.editable=U(a,a.editable,c,!0)}function N(a,c){a.view||(a.view={});var d=a.view;if(!(!c&&d&&d.date>new Date-ga)){var b=a.win,d=b.getScrollPosition(),b=b.getViewPaneSize();v(a.view,{scroll:{x:d.x,y:d.y,width:a.doc.$.documentElement.scrollWidth-b.width,height:a.doc.$.documentElement.scrollHeight-b.height},pane:{width:b.width,height:b.height,bottom:b.height+d.y},date:+new Date},!0)}}function pa(a,c,d,b){for(var e=b,f=b,k=0,h=!1,g=!1,l=a.view.pane.height,
+p=a.mouse;p.y+k<l&&0<p.y-k;){h||(h=c(e,b));g||(g=c(f,b));!h&&0<p.y-k&&(e=d(a,{x:p.x,y:p.y-k}));!g&&p.y+k<l&&(f=d(a,{x:p.x,y:p.y+k}));if(h&&g)break;k+=2}return new z([e,f,null,null])}CKEDITOR.plugins.add("magicline",{init:function(a){var c=a.config,d=c.magicline_triggerOffset||30,b={editor:a,enterMode:c.enterMode,triggerOffset:d,holdDistance:0|d*(c.magicline_holdDistance||.5),boxColor:c.magicline_color||"#ff0000",rtl:"rtl"==c.contentsLangDirection,tabuList:["data-cke-hidden-sel"].concat(c.magicline_tabuList||
+[]),triggers:c.magicline_everywhere?Z:{table:1,hr:1,div:1,ul:1,ol:1,dl:1,form:1,blockquote:1}},e,f,k;b.isRelevant=function(a){return n(a)&&!A(b,a)&&!u(a)};a.on("contentDom",function(){var d=a.editable(),g=a.document,l=a.window;v(b,{editable:d,inInlineMode:d.isInline(),doc:g,win:l,hotNode:null},!0);b.boundary=b.inInlineMode?b.editable:b.doc.getDocumentElement();d.is(B.$inline)||(b.inInlineMode&&!ba(d)&&d.setStyles({position:"relative",top:null,left:null}),la.call(this,b),N(b),d.attachListener(a,"beforeUndoImage",
+function(){b.line.detach()}),d.attachListener(a,"beforeGetData",function(){b.line.wrap.getParent()&&(b.line.detach(),a.once("getData",function(){b.line.attach()},null,null,1E3))},null,null,0),d.attachListener(b.inInlineMode?g:g.getWindow().getFrame(),"mouseout",function(c){if("wysiwyg"==a.mode)if(b.inInlineMode){var d=c.data.$.clientX;c=c.data.$.clientY;N(b);H(b,!0);var e=b.view.editable,f=b.view.scroll;d>e.left-f.x&&d<e.right-f.x&&c>e.top-f.y&&c<e.bottom-f.y||(clearTimeout(k),k=null,b.line.detach())}else clearTimeout(k),
+k=null,b.line.detach()}),d.attachListener(d,"keyup",function(){b.hiddenMode=0}),d.attachListener(d,"keydown",function(c){if("wysiwyg"==a.mode)switch(c.data.getKeystroke()){case 2228240:case 16:b.hiddenMode=1,b.line.detach()}}),d.attachListener(b.inInlineMode?d:g,"mousemove",function(c){f=!0;if("wysiwyg"==a.mode&&!a.readOnly&&!k){var d={x:c.data.$.clientX,y:c.data.$.clientY};k=setTimeout(function(){b.mouse=d;k=b.trigger=null;N(b);f&&!b.hiddenMode&&a.focusManager.hasFocus&&!b.line.mouseNear()&&(b.element=
+ha(b,!0))&&((b.trigger=ca(b)||ea(b)||ia(b))&&!aa(b,b.trigger.upper||b.trigger.lower)?b.line.attach().place():(b.trigger=null,b.line.detach()),f=!1)},30)}}),d.attachListener(l,"scroll",function(){"wysiwyg"==a.mode&&(b.line.detach(),t.webkit&&(b.hiddenMode=1,clearTimeout(e),e=setTimeout(function(){b.mouseDown||(b.hiddenMode=0)},50)))}),d.attachListener(ja?g:l,"mousedown",function(){"wysiwyg"==a.mode&&(b.line.detach(),b.hiddenMode=1,b.mouseDown=1)}),d.attachListener(ja?g:l,"mouseup",function(){b.hiddenMode=
+0;b.mouseDown=0}),a.addCommand("accessPreviousSpace",Y(b)),a.addCommand("accessNextSpace",Y(b,!0)),a.setKeystroke([[c.magicline_keystrokePrevious,"accessPreviousSpace"],[c.magicline_keystrokeNext,"accessNextSpace"]]),a.on("loadSnapshot",function(){var c,d,e,f;for(f in{p:1,br:1,div:1})for(c=a.document.getElementsByTag(f),e=c.count();e--;)if((d=c.getItem(e)).data("cke-magicline-hot")){b.hotNode=d;b.lastCmdDirection="true"===d.data("cke-magicline-dir")?!0:!1;return}}),this.backdoor={accessFocusSpace:S,
+boxTrigger:z,isLine:A,getAscendantTrigger:O,getNonEmptyNeighbour:w,getSize:U,that:b,triggerEdge:ea,triggerEditable:ca,triggerExpand:ia})},this)}});var v=CKEDITOR.tools.extend,R=CKEDITOR.dom.element,G=R.createFromHtml,t=CKEDITOR.env,ja=CKEDITOR.env.ie&&9>CKEDITOR.env.version,B=CKEDITOR.dtd,K={},I=128,da=64,T=32,M=16,C=4,D=2,x=1,J=" ",fa=B.$listItem,oa=B.$tableContent,ma=v({},B.$nonEditable,B.$empty),Z=B.$block,ga=100,Q="width:0px;height:0px;padding:0px;margin:0px;display:block;z-index:9999;color:#fff;position:absolute;font-size: 0px;line-height:0px;",
+X=Q+"border-color:transparent;display:block;border-style:solid;",W="\x3cspan\x3e"+J+"\x3c/span\x3e";K[CKEDITOR.ENTER_BR]="br";K[CKEDITOR.ENTER_P]="p";K[CKEDITOR.ENTER_DIV]="div";z.prototype={set:function(a,c,d){this.properties=a+c+(d||x);return this},is:function(a){return(this.properties&a)==a}};var ha=function(){function a(a,d){var b=a.$.elementFromPoint(d.x,d.y);return b&&b.nodeType?new CKEDITOR.dom.element(b):null}return function(c,d,b){if(!c.mouse)return null;var e=c.doc,f=c.line.wrap;b=b||c.mouse;
+var k=a(e,b);d&&A(c,k)&&(f.hide(),k=a(e,b),f.show());return!k||k.type!=CKEDITOR.NODE_ELEMENT||!k.$||t.ie&&9>t.version&&!c.boundary.equals(k)&&!c.boundary.contains(k)?null:k}}(),E=CKEDITOR.dom.walker.whitespaces(),F=CKEDITOR.dom.walker.nodeType(CKEDITOR.NODE_COMMENT),ia=function(){function a(a){var b=a.element,e,f,k;if(!n(b)||b.contains(a.editable)||b.isReadOnly())return null;k=pa(a,function(a,b){return!b.equals(a)},function(a,b){return ha(a,!0,b)},b);e=k.upper;f=k.lower;if(V(a,e,f))return k.set(T,
+8);if(e&&b.contains(e))for(;!e.getParent().equals(b);)e=e.getParent();else e=b.getFirst(function(b){return c(a,b)});if(f&&b.contains(f))for(;!f.getParent().equals(b);)f=f.getParent();else f=b.getLast(function(b){return c(a,b)});if(!e||!f)return null;r(a,e);r(a,f);if(!q(a.mouse.y,e.size.top,f.size.bottom))return null;for(var b=Number.MAX_VALUE,h,g,l,p;f&&!f.equals(e)&&(g=e.getNext(a.isRelevant));)h=Math.abs(ka(a,e,g)-a.mouse.y),h<b&&(b=h,l=e,p=g),e=g,r(a,e);if(!l||!p||!q(a.mouse.y,l.size.top,p.size.bottom))return null;
+k.upper=l;k.lower=p;return k.set(T,8)}function c(a,b){return!(b&&b.type==CKEDITOR.NODE_TEXT||F(b)||u(b)||A(a,b)||b.type==CKEDITOR.NODE_ELEMENT&&b.$&&b.is("br"))}return function(c){var b=a(c),e;if(e=b){e=b.upper;var f=b.lower;e=!e||!f||u(f)||u(e)||f.equals(e)||e.equals(f)||f.contains(e)||e.contains(f)?!1:L(c,e)&&L(c,f)&&V(c,e,f)?!0:!1}return e?b:null}}(),y=["top","left","right","bottom"]})();CKEDITOR.config.magicline_keystrokePrevious=CKEDITOR.CTRL+CKEDITOR.SHIFT+51;
+CKEDITOR.config.magicline_keystrokeNext=CKEDITOR.CTRL+CKEDITOR.SHIFT+52;(function(){function n(a){if(!a||a.type!=CKEDITOR.NODE_ELEMENT||"form"!=a.getName())return[];for(var e=[],f=["style","className"],b=0;b<f.length;b++){var c=a.$.elements.namedItem(f[b]);c&&(c=new CKEDITOR.dom.element(c),e.push([c,c.nextSibling]),c.remove())}return e}function t(a,e){if(a&&a.type==CKEDITOR.NODE_ELEMENT&&"form"==a.getName()&&0<e.length)for(var f=e.length-1;0<=f;f--){var b=e[f][0],c=e[f][1];c?b.insertBefore(c):b.appendTo(a)}}function r(a,e){var f=n(a),b={},c=a.$;e||(b["class"]=c.className||
+"",c.className="");b.inline=c.style.cssText||"";e||(c.style.cssText="position: static; overflow: visible");t(f);return b}function u(a,e){var f=n(a),b=a.$;"class"in e&&(b.className=e["class"]);"inline"in e&&(b.style.cssText=e.inline);t(f)}function v(a){if(!a.editable().isInline()){var e=CKEDITOR.instances,f;for(f in e){var b=e[f];"wysiwyg"!=b.mode||b.readOnly||(b=b.document.getBody(),b.setAttribute("contentEditable",!1),b.setAttribute("contentEditable",!0))}a.editable().hasFocus&&(a.toolbox.focus(),
+a.focus())}}CKEDITOR.plugins.add("maximize",{init:function(a){function e(){var b=c.getViewPaneSize();a.resize(b.width,b.height,null,!0)}if(a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var f=a.lang,b=CKEDITOR.document,c=b.getWindow(),l,m,p,n=CKEDITOR.TRISTATE_OFF;a.addCommand("maximize",{modes:{wysiwyg:!CKEDITOR.env.iOS,source:!CKEDITOR.env.iOS},readOnly:1,editorFocus:!1,exec:function(){var h=a.container.getFirst(function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasClass("cke_inner")}),g=a.ui.space("contents");
+if("wysiwyg"==a.mode){var d=a.getSelection();l=d&&d.getRanges();m=c.getScrollPosition()}else{var k=a.editable().$;l=!CKEDITOR.env.ie&&[k.selectionStart,k.selectionEnd];m=[k.scrollLeft,k.scrollTop]}if(this.state==CKEDITOR.TRISTATE_OFF){c.on("resize",e);p=c.getScrollPosition();for(d=a.container;d=d.getParent();)d.setCustomData("maximize_saved_styles",r(d)),d.setStyle("z-index",a.config.baseFloatZIndex-5);g.setCustomData("maximize_saved_styles",r(g,!0));h.setCustomData("maximize_saved_styles",r(h,!0));
+g={overflow:CKEDITOR.env.webkit?"":"hidden",width:0,height:0};b.getDocumentElement().setStyles(g);!CKEDITOR.env.gecko&&b.getDocumentElement().setStyle("position","fixed");CKEDITOR.env.gecko&&CKEDITOR.env.quirks||b.getBody().setStyles(g);CKEDITOR.env.ie?setTimeout(function(){c.$.scrollTo(0,0)},0):c.$.scrollTo(0,0);h.setStyle("position",CKEDITOR.env.gecko&&CKEDITOR.env.quirks?"fixed":"absolute");h.$.offsetLeft;h.setStyles({"z-index":a.config.baseFloatZIndex-5,left:"0px",top:"0px"});h.addClass("cke_maximized");
+e();g=h.getDocumentPosition();h.setStyles({left:-1*g.x+"px",top:-1*g.y+"px"});CKEDITOR.env.gecko&&v(a)}else if(this.state==CKEDITOR.TRISTATE_ON){c.removeListener("resize",e);for(var d=[g,h],q=0;q<d.length;q++)u(d[q],d[q].getCustomData("maximize_saved_styles")),d[q].removeCustomData("maximize_saved_styles");for(d=a.container;d=d.getParent();)u(d,d.getCustomData("maximize_saved_styles")),d.removeCustomData("maximize_saved_styles");CKEDITOR.env.ie?setTimeout(function(){c.$.scrollTo(p.x,p.y)},0):c.$.scrollTo(p.x,
+p.y);h.removeClass("cke_maximized");CKEDITOR.env.webkit&&(h.setStyle("display","inline"),setTimeout(function(){h.setStyle("display","block")},0));a.fire("resize",{outerHeight:a.container.$.offsetHeight,contentsHeight:g.$.offsetHeight,outerWidth:a.container.$.offsetWidth})}this.toggleState();if(d=this.uiItems[0])g=this.state==CKEDITOR.TRISTATE_OFF?f.maximize.maximize:f.maximize.minimize,d=CKEDITOR.document.getById(d._.id),d.getChild(1).setHtml(g),d.setAttribute("title",g),d.setAttribute("href",'javascript:void("'+
+g+'");');"wysiwyg"==a.mode?l?(CKEDITOR.env.gecko&&v(a),a.getSelection().selectRanges(l),(k=a.getSelection().getStartElement())&&k.scrollIntoView(!0)):c.$.scrollTo(m.x,m.y):(l&&(k.selectionStart=l[0],k.selectionEnd=l[1]),k.scrollLeft=m[0],k.scrollTop=m[1]);l=m=null;n=this.state;a.fire("maximize",this.state)},canUndo:!1});a.ui.addButton&&a.ui.addButton("Maximize",{label:f.maximize.maximize,command:"maximize",toolbar:"tools,10"});a.on("mode",function(){var b=a.getCommand("maximize");b.setState(b.state==
+CKEDITOR.TRISTATE_DISABLED?CKEDITOR.TRISTATE_DISABLED:n)},null,null,100)}}})})();CKEDITOR.plugins.add("removeformat",{init:function(a){a.addCommand("removeFormat",CKEDITOR.plugins.removeformat.commands.removeformat);a.ui.addButton&&a.ui.addButton("RemoveFormat",{label:a.lang.removeformat.toolbar,command:"removeFormat",toolbar:"cleanup,10"})}});
+CKEDITOR.plugins.removeformat={commands:{removeformat:{exec:function(a){for(var h=a._.removeFormatRegex||(a._.removeFormatRegex=new RegExp("^(?:"+a.config.removeFormatTags.replace(/,/g,"|")+")$","i")),e=a._.removeAttributes||(a._.removeAttributes=a.config.removeFormatAttributes.split(",")),f=CKEDITOR.plugins.removeformat.filter,m=a.getSelection().getRanges(),n=m.createIterator(),p=function(a){return a.type==CKEDITOR.NODE_ELEMENT},c;c=n.getNextRange();){c.collapsed||c.enlarge(CKEDITOR.ENLARGE_ELEMENT);
+var l=c.createBookmark(),b=l.startNode,d=l.endNode,k=function(b){for(var c=a.elementPath(b),e=c.elements,d=1,g;(g=e[d])&&!g.equals(c.block)&&!g.equals(c.blockLimit);d++)h.test(g.getName())&&f(a,g)&&b.breakParent(g)};k(b);if(d)for(k(d),b=b.getNextSourceNode(!0,CKEDITOR.NODE_ELEMENT);b&&!b.equals(d);)if(b.isReadOnly()){if(b.getPosition(d)&CKEDITOR.POSITION_CONTAINS)break;b=b.getNext(p)}else k=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT),"img"==b.getName()&&b.data("cke-realelement")||!f(a,b)||(h.test(b.getName())?
+b.remove(1):(b.removeAttributes(e),a.fire("removeFormatCleanup",b))),b=k;c.moveToBookmark(l)}a.forceNextSelectionCheck();a.getSelection().selectRanges(m)}}},filter:function(a,h){for(var e=a._.removeFormatFilters||[],f=0;f<e.length;f++)if(!1===e[f](h))return!1;return!0}};CKEDITOR.editor.prototype.addRemoveFormatFilter=function(a){this._.removeFormatFilters||(this._.removeFormatFilters=[]);this._.removeFormatFilters.push(a)};CKEDITOR.config.removeFormatTags="b,big,cite,code,del,dfn,em,font,i,ins,kbd,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var";
+CKEDITOR.config.removeFormatAttributes="class,style,lang,width,height,align,hspace,valign";(function(){var f={preserveState:!0,editorFocus:!1,readOnly:1,exec:function(a){this.toggleState();this.refresh(a)},refresh:function(a){if(a.document){var b=this.state==CKEDITOR.TRISTATE_ON?"attachClass":"removeClass";a.editable()[b]("cke_show_borders")}}};CKEDITOR.plugins.add("showborders",{modes:{wysiwyg:1},onLoad:function(){var a;a=(CKEDITOR.env.ie6Compat?[".%1 table.%2,",".%1 table.%2 td, .%1 table.%2 th","{","border : #d3d3d3 1px dotted","}"]:".%1 table.%2,;.%1 table.%2 \x3e tr \x3e td, .%1 table.%2 \x3e tr \x3e th,;.%1 table.%2 \x3e tbody \x3e tr \x3e td, .%1 table.%2 \x3e tbody \x3e tr \x3e th,;.%1 table.%2 \x3e thead \x3e tr \x3e td, .%1 table.%2 \x3e thead \x3e tr \x3e th,;.%1 table.%2 \x3e tfoot \x3e tr \x3e td, .%1 table.%2 \x3e tfoot \x3e tr \x3e th;{;border : #d3d3d3 1px dotted;}".split(";")).join("").replace(/%2/g,
+"cke_show_border").replace(/%1/g,"cke_show_borders ");CKEDITOR.addCss(a)},init:function(a){var b=a.addCommand("showborders",f);b.canUndo=!1;!1!==a.config.startupShowBorders&&b.setState(CKEDITOR.TRISTATE_ON);a.on("mode",function(){b.state!=CKEDITOR.TRISTATE_DISABLED&&b.refresh(a)},null,null,100);a.on("contentDom",function(){b.state!=CKEDITOR.TRISTATE_DISABLED&&b.refresh(a)});a.on("removeFormatCleanup",function(d){d=d.data;a.getCommand("showborders").state==CKEDITOR.TRISTATE_ON&&d.is("table")&&(!d.hasAttribute("border")||
+0>=parseInt(d.getAttribute("border"),10))&&d.addClass("cke_show_border")})},afterInit:function(a){var b=a.dataProcessor;a=b&&b.dataFilter;b=b&&b.htmlFilter;a&&a.addRules({elements:{table:function(a){a=a.attributes;var b=a["class"],c=parseInt(a.border,10);c&&!(0>=c)||b&&-1!=b.indexOf("cke_show_border")||(a["class"]=(b||"")+" cke_show_border")}}});b&&b.addRules({elements:{table:function(a){a=a.attributes;var b=a["class"];b&&(a["class"]=b.replace("cke_show_border","").replace(/\s{2}/," ").replace(/^\s+|\s+$/,
+""))}}})}});CKEDITOR.on("dialogDefinition",function(a){var b=a.data.name;if("table"==b||"tableProperties"==b)if(a=a.data.definition,b=a.getContents("info").get("txtBorder"),b.commit=CKEDITOR.tools.override(b.commit,function(a){return function(b,c){a.apply(this,arguments);var e=parseInt(this.getValue(),10);c[!e||0>=e?"addClass":"removeClass"]("cke_show_border")}}),a=(a=a.getContents("advanced"))&&a.get("advCSSClasses"))a.setup=CKEDITOR.tools.override(a.setup,function(a){return function(){a.apply(this,
+arguments);this.setValue(this.getValue().replace(/cke_show_border/,""))}}),a.commit=CKEDITOR.tools.override(a.commit,function(a){return function(b,c){a.apply(this,arguments);parseInt(c.getAttribute("border"),10)||c.addClass("cke_show_border")}})})})();(function(){CKEDITOR.plugins.add("sourcearea",{init:function(a){function d(){var a=e&&this.equals(CKEDITOR.document.getActive());this.hide();this.setStyle("height",this.getParent().$.clientHeight+"px");this.setStyle("width",this.getParent().$.clientWidth+"px");this.show();a&&this.focus()}if(a.elementMode!=CKEDITOR.ELEMENT_MODE_INLINE){var f=CKEDITOR.plugins.sourcearea;a.addMode("source",function(e){var b=a.ui.space("contents").getDocument().createElement("textarea");b.setStyles(CKEDITOR.tools.extend({width:CKEDITOR.env.ie7Compat?
+"99%":"100%",height:"100%",resize:"none",outline:"none","text-align":"left"},CKEDITOR.tools.cssVendorPrefix("tab-size",a.config.sourceAreaTabSize||4)));b.setAttribute("dir","ltr");b.addClass("cke_source").addClass("cke_reset").addClass("cke_enable_context_menu");a.ui.space("contents").append(b);b=a.editable(new c(a,b));b.setData(a.getData(1));CKEDITOR.env.ie&&(b.attachListener(a,"resize",d,b),b.attachListener(CKEDITOR.document.getWindow(),"resize",d,b),CKEDITOR.tools.setTimeout(d,0,b));a.fire("ariaWidget",
+this);e()});a.addCommand("source",f.commands.source);a.ui.addButton&&a.ui.addButton("Source",{label:a.lang.sourcearea.toolbar,command:"source",toolbar:"mode,10"});a.on("mode",function(){a.getCommand("source").setState("source"==a.mode?CKEDITOR.TRISTATE_ON:CKEDITOR.TRISTATE_OFF)});var e=CKEDITOR.env.ie&&9==CKEDITOR.env.version}}});var c=CKEDITOR.tools.createClass({base:CKEDITOR.editable,proto:{setData:function(a){this.setValue(a);this.status="ready";this.editor.fire("dataReady")},getData:function(){return this.getValue()},
+insertHtml:function(){},insertElement:function(){},insertText:function(){},setReadOnly:function(a){this[(a?"set":"remove")+"Attribute"]("readOnly","readonly")},detach:function(){c.baseProto.detach.call(this);this.clearCustomData();this.remove()}}})})();
+CKEDITOR.plugins.sourcearea={commands:{source:{modes:{wysiwyg:1,source:1},editorFocus:!1,readOnly:1,exec:function(c){"wysiwyg"==c.mode&&c.fire("saveSnapshot");c.getCommand("source").setState(CKEDITOR.TRISTATE_DISABLED);c.setMode("source"==c.mode?"wysiwyg":"source")},canUndo:!1}}};(function(){function k(c){return{editorFocus:!1,canUndo:!1,modes:{wysiwyg:1},exec:function(d){if(d.editable().hasFocus){var e=d.getSelection(),b;if(b=(new CKEDITOR.dom.elementPath(e.getCommonAncestor(),e.root)).contains({td:1,th:1},1)){var e=d.createRange(),a=CKEDITOR.tools.tryThese(function(){var a=b.getParent().$.cells[b.$.cellIndex+(c?-1:1)];a.parentNode.parentNode;return a},function(){var a=b.getParent(),a=a.getAscendant("table").$.rows[a.$.rowIndex+(c?-1:1)];return a.cells[c?a.cells.length-1:
+0]});if(a||c)if(a)a=new CKEDITOR.dom.element(a),e.moveToElementEditStart(a),e.checkStartOfBlock()&&e.checkEndOfBlock()||e.selectNodeContents(a);else return!0;else{for(var f=b.getAscendant("table").$,a=b.getParent().$.cells,f=new CKEDITOR.dom.element(f.insertRow(-1),d.document),g=0,h=a.length;g<h;g++)f.append((new CKEDITOR.dom.element(a[g],d.document)).clone(!1,!1)).appendBogus();e.moveToElementEditStart(f)}e.select(!0);return!0}}return!1}}}var h={editorFocus:!1,modes:{wysiwyg:1,source:1}},g={exec:function(c){c.container.focusNext(!0,
+c.tabIndex)}},f={exec:function(c){c.container.focusPrevious(!0,c.tabIndex)}};CKEDITOR.plugins.add("tab",{init:function(c){for(var d=!1!==c.config.enableTabKeyTools,e=c.config.tabSpaces||0,b="";e--;)b+=" ";if(b)c.on("key",function(a){9==a.data.keyCode&&(c.insertText(b),a.cancel())});if(d)c.on("key",function(a){(9==a.data.keyCode&&c.execCommand("selectNextCell")||a.data.keyCode==CKEDITOR.SHIFT+9&&c.execCommand("selectPreviousCell"))&&a.cancel()});c.addCommand("blur",CKEDITOR.tools.extend(g,h));c.addCommand("blurBack",
+CKEDITOR.tools.extend(f,h));c.addCommand("selectNextCell",k());c.addCommand("selectPreviousCell",k(!0))}})})();
+CKEDITOR.dom.element.prototype.focusNext=function(k,h){var g=void 0===h?this.getTabIndex():h,f,c,d,e,b,a;if(0>=g)for(b=this.getNextSourceNode(k,CKEDITOR.NODE_ELEMENT);b;){if(b.isVisible()&&0===b.getTabIndex()){d=b;break}b=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT)}else for(b=this.getDocument().getBody().getFirst();b=b.getNextSourceNode(!1,CKEDITOR.NODE_ELEMENT);){if(!f)if(!c&&b.equals(this)){if(c=!0,k){if(!(b=b.getNextSourceNode(!0,CKEDITOR.NODE_ELEMENT)))break;f=1}}else c&&!this.contains(b)&&
+(f=1);if(b.isVisible()&&!(0>(a=b.getTabIndex()))){if(f&&a==g){d=b;break}a>g&&(!d||!e||a<e)?(d=b,e=a):d||0!==a||(d=b,e=a)}}d&&d.focus()};
+CKEDITOR.dom.element.prototype.focusPrevious=function(k,h){for(var g=void 0===h?this.getTabIndex():h,f,c,d,e=0,b,a=this.getDocument().getBody().getLast();a=a.getPreviousSourceNode(!1,CKEDITOR.NODE_ELEMENT);){if(!f)if(!c&&a.equals(this)){if(c=!0,k){if(!(a=a.getPreviousSourceNode(!0,CKEDITOR.NODE_ELEMENT)))break;f=1}}else c&&!this.contains(a)&&(f=1);if(a.isVisible()&&!(0>(b=a.getTabIndex())))if(0>=g){if(f&&0===b){d=a;break}b>e&&(d=a,e=b)}else{if(f&&b==g){d=a;break}b<g&&(!d||b>e)&&(d=a,e=b)}}d&&d.focus()};(function(){function m(a,d){CKEDITOR.tools.extend(this,{editor:a,editable:a.editable(),doc:a.document,win:a.window},d,!0);this.inline=this.editable.isInline();this.inline||(this.frame=this.win.getFrame());this.target=this[this.inline?"editable":"doc"]}function n(a,d){CKEDITOR.tools.extend(this,d,{editor:a},!0)}function p(a,d){var b=a.editable();CKEDITOR.tools.extend(this,{editor:a,editable:b,inline:b.isInline(),doc:a.document,win:a.window,container:CKEDITOR.document.getBody(),winTop:CKEDITOR.document.getWindow()},
+d,!0);this.hidden={};this.visible={};this.inline||(this.frame=this.win.getFrame());this.queryViewport();var c=CKEDITOR.tools.bind(this.queryViewport,this),e=CKEDITOR.tools.bind(this.hideVisible,this),g=CKEDITOR.tools.bind(this.removeAll,this);b.attachListener(this.winTop,"resize",c);b.attachListener(this.winTop,"scroll",c);b.attachListener(this.winTop,"resize",e);b.attachListener(this.win,"scroll",e);b.attachListener(this.inline?b:this.frame,"mouseout",function(a){var b=a.data.$.clientX;a=a.data.$.clientY;
+this.queryViewport();(b<=this.rect.left||b>=this.rect.right||a<=this.rect.top||a>=this.rect.bottom)&&this.hideVisible();(0>=b||b>=this.winTopPane.width||0>=a||a>=this.winTopPane.height)&&this.hideVisible()},this);b.attachListener(a,"resize",c);b.attachListener(a,"mode",g);a.on("destroy",g);this.lineTpl=(new CKEDITOR.template('\x3cdiv data-cke-lineutils-line\x3d"1" class\x3d"cke_reset_all" style\x3d"{lineStyle}"\x3e\x3cspan style\x3d"{tipLeftStyle}"\x3e\x26nbsp;\x3c/span\x3e\x3cspan style\x3d"{tipRightStyle}"\x3e\x26nbsp;\x3c/span\x3e\x3c/div\x3e')).output({lineStyle:CKEDITOR.tools.writeCssText(CKEDITOR.tools.extend({},
+t,this.lineStyle,!0)),tipLeftStyle:CKEDITOR.tools.writeCssText(CKEDITOR.tools.extend({},q,{left:"0px","border-left-color":"red","border-width":"6px 0 6px 6px"},this.tipCss,this.tipLeftStyle,!0)),tipRightStyle:CKEDITOR.tools.writeCssText(CKEDITOR.tools.extend({},q,{right:"0px","border-right-color":"red","border-width":"6px 6px 6px 0"},this.tipCss,this.tipRightStyle,!0))})}function l(a){var d;if(d=a&&a.type==CKEDITOR.NODE_ELEMENT)d=!(r[a.getComputedStyle("float")]||r[a.getAttribute("align")]);return d&&
+!u[a.getComputedStyle("position")]}CKEDITOR.plugins.add("lineutils");CKEDITOR.LINEUTILS_BEFORE=1;CKEDITOR.LINEUTILS_AFTER=2;CKEDITOR.LINEUTILS_INSIDE=4;m.prototype={start:function(a){var d=this,b=this.editor,c=this.doc,e,g,f,h,k=CKEDITOR.tools.eventsBuffer(50,function(){b.readOnly||"wysiwyg"!=b.mode||(d.relations={},(g=c.$.elementFromPoint(f,h))&&g.nodeType&&(e=new CKEDITOR.dom.element(g),d.traverseSearch(e),isNaN(f+h)||d.pixelSearch(e,f,h),a&&a(d.relations,f,h)))});this.listener=this.editable.attachListener(this.target,
+"mousemove",function(a){f=a.data.$.clientX;h=a.data.$.clientY;k.input()});this.editable.attachListener(this.inline?this.editable:this.frame,"mouseout",function(){k.reset()})},stop:function(){this.listener&&this.listener.removeListener()},getRange:function(){var a={};a[CKEDITOR.LINEUTILS_BEFORE]=CKEDITOR.POSITION_BEFORE_START;a[CKEDITOR.LINEUTILS_AFTER]=CKEDITOR.POSITION_AFTER_END;a[CKEDITOR.LINEUTILS_INSIDE]=CKEDITOR.POSITION_AFTER_START;return function(d){var b=this.editor.createRange();b.moveToPosition(this.relations[d.uid].element,
+a[d.type]);return b}}(),store:function(){function a(a,b,c){var e=a.getUniqueId();e in c?c[e].type|=b:c[e]={element:a,type:b}}return function(d,b){var c;b&CKEDITOR.LINEUTILS_AFTER&&l(c=d.getNext())&&c.isVisible()&&(a(c,CKEDITOR.LINEUTILS_BEFORE,this.relations),b^=CKEDITOR.LINEUTILS_AFTER);b&CKEDITOR.LINEUTILS_INSIDE&&l(c=d.getFirst())&&c.isVisible()&&(a(c,CKEDITOR.LINEUTILS_BEFORE,this.relations),b^=CKEDITOR.LINEUTILS_INSIDE);a(d,b,this.relations)}}(),traverseSearch:function(a){var d,b,c;do if(c=a.$["data-cke-expando"],
+!(c&&c in this.relations)){if(a.equals(this.editable))break;if(l(a))for(d in this.lookups)(b=this.lookups[d](a))&&this.store(a,b)}while((!a||a.type!=CKEDITOR.NODE_ELEMENT||"true"!=a.getAttribute("contenteditable"))&&(a=a.getParent()))},pixelSearch:function(){function a(a,c,e,g,f){for(var h=0,k;f(e);){e+=g;if(25==++h)break;if(k=this.doc.$.elementFromPoint(c,e))if(k==a)h=0;else if(d(a,k)&&(h=0,l(k=new CKEDITOR.dom.element(k))))return k}}var d=CKEDITOR.env.ie||CKEDITOR.env.webkit?function(a,c){return a.contains(c)}:
+function(a,c){return!!(a.compareDocumentPosition(c)&16)};return function(b,c,d){var g=this.win.getViewPaneSize().height,f=a.call(this,b.$,c,d,-1,function(a){return 0<a});c=a.call(this,b.$,c,d,1,function(a){return a<g});if(f)for(this.traverseSearch(f);!f.getParent().equals(b);)f=f.getParent();if(c)for(this.traverseSearch(c);!c.getParent().equals(b);)c=c.getParent();for(;f||c;){f&&(f=f.getNext(l));if(!f||f.equals(c))break;this.traverseSearch(f);c&&(c=c.getPrevious(l));if(!c||c.equals(f))break;this.traverseSearch(c)}}}(),
+greedySearch:function(){this.relations={};for(var a=this.editable.getElementsByTag("*"),d=0,b,c,e;b=a.getItem(d++);)if(!b.equals(this.editable)&&b.type==CKEDITOR.NODE_ELEMENT&&(b.hasAttribute("contenteditable")||!b.isReadOnly())&&l(b)&&b.isVisible())for(e in this.lookups)(c=this.lookups[e](b))&&this.store(b,c);return this.relations}};n.prototype={locate:function(){function a(a,b){var c=a.element[b===CKEDITOR.LINEUTILS_BEFORE?"getPrevious":"getNext"]();return c&&l(c)?(a.siblingRect=c.getClientRect(),
+b==CKEDITOR.LINEUTILS_BEFORE?(a.siblingRect.bottom+a.elementRect.top)/2:(a.elementRect.bottom+a.siblingRect.top)/2):b==CKEDITOR.LINEUTILS_BEFORE?a.elementRect.top:a.elementRect.bottom}return function(d){var b;this.locations={};for(var c in d)b=d[c],b.elementRect=b.element.getClientRect(),b.type&CKEDITOR.LINEUTILS_BEFORE&&this.store(c,CKEDITOR.LINEUTILS_BEFORE,a(b,CKEDITOR.LINEUTILS_BEFORE)),b.type&CKEDITOR.LINEUTILS_AFTER&&this.store(c,CKEDITOR.LINEUTILS_AFTER,a(b,CKEDITOR.LINEUTILS_AFTER)),b.type&
+CKEDITOR.LINEUTILS_INSIDE&&this.store(c,CKEDITOR.LINEUTILS_INSIDE,(b.elementRect.top+b.elementRect.bottom)/2);return this.locations}}(),sort:function(){var a,d,b,c;return function(e,g){a=this.locations;d=[];for(var f in a)for(var h in a[f])if(b=Math.abs(e-a[f][h]),d.length){for(c=0;c<d.length;c++)if(b<d[c].dist){d.splice(c,0,{uid:+f,type:h,dist:b});break}c==d.length&&d.push({uid:+f,type:h,dist:b})}else d.push({uid:+f,type:h,dist:b});return"undefined"!=typeof g?d.slice(0,g):d}}(),store:function(a,
+d,b){this.locations[a]||(this.locations[a]={});this.locations[a][d]=b}};var q={display:"block",width:"0px",height:"0px","border-color":"transparent","border-style":"solid",position:"absolute",top:"-6px"},t={height:"0px","border-top":"1px dashed red",position:"absolute","z-index":9999};p.prototype={removeAll:function(){for(var a in this.hidden)this.hidden[a].remove(),delete this.hidden[a];for(a in this.visible)this.visible[a].remove(),delete this.visible[a]},hideLine:function(a){var d=a.getUniqueId();
+a.hide();this.hidden[d]=a;delete this.visible[d]},showLine:function(a){var d=a.getUniqueId();a.show();this.visible[d]=a;delete this.hidden[d]},hideVisible:function(){for(var a in this.visible)this.hideLine(this.visible[a])},placeLine:function(a,d){var b,c,e;if(b=this.getStyle(a.uid,a.type)){for(e in this.visible)if(this.visible[e].getCustomData("hash")!==this.hash){c=this.visible[e];break}if(!c)for(e in this.hidden)if(this.hidden[e].getCustomData("hash")!==this.hash){this.showLine(c=this.hidden[e]);
+break}c||this.showLine(c=this.addLine());c.setCustomData("hash",this.hash);this.visible[c.getUniqueId()]=c;c.setStyles(b);d&&d(c)}},getStyle:function(a,d){var b=this.relations[a],c=this.locations[a][d],e={};e.width=b.siblingRect?Math.max(b.siblingRect.width,b.elementRect.width):b.elementRect.width;e.top=this.inline?c+this.winTopScroll.y-this.rect.relativeY:this.rect.top+this.winTopScroll.y+c;if(e.top-this.winTopScroll.y<this.rect.top||e.top-this.winTopScroll.y>this.rect.bottom)return!1;this.inline?
+e.left=b.elementRect.left-this.rect.relativeX:(0<b.elementRect.left?e.left=this.rect.left+b.elementRect.left:(e.width+=b.elementRect.left,e.left=this.rect.left),0<(b=e.left+e.width-(this.rect.left+this.winPane.width))&&(e.width-=b));e.left+=this.winTopScroll.x;for(var g in e)e[g]=CKEDITOR.tools.cssLength(e[g]);return e},addLine:function(){var a=CKEDITOR.dom.element.createFromHtml(this.lineTpl);a.appendTo(this.container);return a},prepare:function(a,d){this.relations=a;this.locations=d;this.hash=Math.random()},
+cleanup:function(){var a,d;for(d in this.visible)a=this.visible[d],a.getCustomData("hash")!==this.hash&&this.hideLine(a)},queryViewport:function(){this.winPane=this.win.getViewPaneSize();this.winTopScroll=this.winTop.getScrollPosition();this.winTopPane=this.winTop.getViewPaneSize();this.rect=this.getClientRect(this.inline?this.editable:this.frame)},getClientRect:function(a){a=a.getClientRect();var d=this.container.getDocumentPosition(),b=this.container.getComputedStyle("position");a.relativeX=a.relativeY=
+0;"static"!=b&&(a.relativeY=d.y,a.relativeX=d.x,a.top-=a.relativeY,a.bottom-=a.relativeY,a.left-=a.relativeX,a.right-=a.relativeX);return a}};var r={left:1,right:1,center:1},u={absolute:1,fixed:1};CKEDITOR.plugins.lineutils={finder:m,locator:n,liner:p}})();(function(){function q(b,a,c){a.type||(a.type="auto");if(c&&!1===b.fire("beforePaste",a)||!a.dataValue&&a.dataTransfer.isEmpty())return!1;a.dataValue||(a.dataValue="");if(CKEDITOR.env.gecko&&"drop"==a.method&&b.toolbox)b.once("afterPaste",function(){b.toolbox.focus()});return b.fire("paste",a)}function z(b){function a(){var a=b.editable();if(CKEDITOR.plugins.clipboard.isCustomCopyCutSupported){var c=function(a){b.readOnly&&"cut"==a.name||m.initPasteDataTransfer(a,b);a.data.preventDefault()};a.on("copy",
+c);a.on("cut",c);a.on("cut",function(){b.readOnly||b.extractSelectedHtml()},null,null,999)}a.on(m.mainPasteEvent,function(b){"beforepaste"==m.mainPasteEvent&&p||u(b)});"beforepaste"==m.mainPasteEvent&&(a.on("paste",function(a){v||(f(),a.data.preventDefault(),u(a),d("paste")||b.openDialog("paste"))}),a.on("contextmenu",g,null,null,0),a.on("beforepaste",function(b){!b.data||b.data.$.ctrlKey||b.data.$.shiftKey||g()},null,null,0));a.on("beforecut",function(){!p&&h(b)});var e;a.attachListener(CKEDITOR.env.ie?
+a:b.document.getDocumentElement(),"mouseup",function(){e=setTimeout(function(){r()},0)});b.on("destroy",function(){clearTimeout(e)});a.on("keyup",r)}function c(a){return{type:a,canUndo:"cut"==a,startDisabled:!0,fakeKeystroke:"cut"==a?CKEDITOR.CTRL+88:CKEDITOR.CTRL+67,exec:function(){"cut"==this.type&&h();var a;var c=this.type;if(CKEDITOR.env.ie)a=d(c);else try{a=b.document.$.execCommand(c,!1,null)}catch(g){a=!1}a||b.showNotification(b.lang.clipboard[this.type+"Error"]);return a}}}function e(){return{canUndo:!1,
+async:!0,fakeKeystroke:CKEDITOR.CTRL+86,exec:function(b,a){var c=this,d=function(a,d){a&&q(b,a,!!d);b.fire("afterCommandExec",{name:"paste",command:c,returnValue:!!a})};"string"==typeof a?d({dataValue:a,method:"paste",dataTransfer:m.initPasteDataTransfer()},1):b.getClipboardData(d)}}}function f(){v=1;setTimeout(function(){v=0},100)}function g(){p=1;setTimeout(function(){p=0},10)}function d(a){var c=b.document,d=c.getBody(),g=!1,e=function(){g=!0};d.on(a,e);7<CKEDITOR.env.version?c.$.execCommand(a):
+c.$.selection.createRange().execCommand(a);d.removeListener(a,e);return g}function h(){if(CKEDITOR.env.ie&&!CKEDITOR.env.quirks){var a=b.getSelection(),c,d,g;a.getType()==CKEDITOR.SELECTION_ELEMENT&&(c=a.getSelectedElement())&&(d=a.getRanges()[0],g=b.document.createText(""),g.insertBefore(c),d.setStartBefore(g),d.setEndAfter(c),a.selectRanges([d]),setTimeout(function(){c.getParent()&&(g.remove(),a.selectElement(c))},0))}}function n(a,c){var d=b.document,g=b.editable(),e=function(b){b.cancel()},h;
+if(!d.getById("cke_pastebin")){var k=b.getSelection(),u=k.createBookmarks();CKEDITOR.env.ie&&k.root.fire("selectionchange");var l=new CKEDITOR.dom.element(!CKEDITOR.env.webkit&&!g.is("body")||CKEDITOR.env.ie?"div":"body",d);l.setAttributes({id:"cke_pastebin","data-cke-temp":"1"});var f=0,d=d.getWindow();CKEDITOR.env.webkit?(g.append(l),l.addClass("cke_editable"),g.is("body")||(f="static"!=g.getComputedStyle("position")?g:CKEDITOR.dom.element.get(g.$.offsetParent),f=f.getDocumentPosition().y)):g.getAscendant(CKEDITOR.env.ie?
+"body":"html",1).append(l);l.setStyles({position:"absolute",top:d.getScrollPosition().y-f+10+"px",width:"1px",height:Math.max(1,d.getViewPaneSize().height-20)+"px",overflow:"hidden",margin:0,padding:0});CKEDITOR.env.safari&&l.setStyles(CKEDITOR.tools.cssVendorPrefix("user-select","text"));(f=l.getParent().isReadOnly())?(l.setOpacity(0),l.setAttribute("contenteditable",!0)):l.setStyle("ltr"==b.config.contentsLangDirection?"left":"right","-10000px");b.on("selectionChange",e,null,null,0);if(CKEDITOR.env.webkit||
+CKEDITOR.env.gecko)h=g.once("blur",e,null,null,-100);f&&l.focus();f=new CKEDITOR.dom.range(l);f.selectNodeContents(l);var n=f.select();CKEDITOR.env.ie&&(h=g.once("blur",function(){b.lockSelection(n)}));var r=CKEDITOR.document.getWindow().getScrollPosition().y;setTimeout(function(){CKEDITOR.env.webkit&&(CKEDITOR.document.getBody().$.scrollTop=r);h&&h.removeListener();CKEDITOR.env.ie&&g.focus();k.selectBookmarks(u);l.remove();var a;CKEDITOR.env.webkit&&(a=l.getFirst())&&a.is&&a.hasClass("Apple-style-span")&&
+(l=a);b.removeListener("selectionChange",e);c(l.getHtml())},0)}}function w(){if("paste"==m.mainPasteEvent)return b.fire("beforePaste",{type:"auto",method:"paste"}),!1;b.focus();f();var a=b.focusManager;a.lock();if(b.editable().fire(m.mainPasteEvent)&&!d("paste"))return a.unlock(),!1;a.unlock();return!0}function k(a){if("wysiwyg"==b.mode)switch(a.data.keyCode){case CKEDITOR.CTRL+86:case CKEDITOR.SHIFT+45:a=b.editable();f();"paste"==m.mainPasteEvent&&a.fire("beforepaste");break;case CKEDITOR.CTRL+88:case CKEDITOR.SHIFT+
+46:b.fire("saveSnapshot"),setTimeout(function(){b.fire("saveSnapshot")},50)}}function u(a){var c={type:"auto",method:"paste",dataTransfer:m.initPasteDataTransfer(a)};c.dataTransfer.cacheData();var d=!1!==b.fire("beforePaste",c);d&&m.canClipboardApiBeTrusted(c.dataTransfer,b)?(a.data.preventDefault(),setTimeout(function(){q(b,c)},0)):n(a,function(a){c.dataValue=a.replace(/<span[^>]+data-cke-bookmark[^<]*?<\/span>/ig,"");d&&q(b,c)})}function r(){if("wysiwyg"==b.mode){var a=t("paste");b.getCommand("cut").setState(t("cut"));
+b.getCommand("copy").setState(t("copy"));b.getCommand("paste").setState(a);b.fire("pasteState",a)}}function t(a){if(x&&a in{paste:1,cut:1})return CKEDITOR.TRISTATE_DISABLED;if("paste"==a)return CKEDITOR.TRISTATE_OFF;a=b.getSelection();var c=a.getRanges();return a.getType()==CKEDITOR.SELECTION_NONE||1==c.length&&c[0].collapsed?CKEDITOR.TRISTATE_DISABLED:CKEDITOR.TRISTATE_OFF}var m=CKEDITOR.plugins.clipboard,p=0,v=0,x=0;(function(){b.on("key",k);b.on("contentDom",a);b.on("selectionChange",function(b){x=
+b.data.selection.getRanges()[0].checkReadOnly();r()});b.contextMenu&&b.contextMenu.addListener(function(b,a){x=a.getRanges()[0].checkReadOnly();return{cut:t("cut"),copy:t("copy"),paste:t("paste")}})})();(function(){function a(c,d,g,e,h){var k=b.lang.clipboard[d];b.addCommand(d,g);b.ui.addButton&&b.ui.addButton(c,{label:k,command:d,toolbar:"clipboard,"+e});b.addMenuItems&&b.addMenuItem(d,{label:k,command:d,group:"clipboard",order:h})}a("Cut","cut",c("cut"),10,1);a("Copy","copy",c("copy"),20,4);a("Paste",
+"paste",e(),30,8)})();b.getClipboardData=function(a,c){function d(a){a.removeListener();a.cancel();c(a.data)}function g(a){a.removeListener();a.cancel();f=!0;c({type:k,dataValue:a.data.dataValue,dataTransfer:a.data.dataTransfer,method:"paste"})}function e(){this.customTitle=a&&a.title}var h=!1,k="auto",f=!1;c||(c=a,a=null);b.on("paste",d,null,null,0);b.on("beforePaste",function(a){a.removeListener();h=!0;k=a.data.type},null,null,1E3);!1===w()&&(b.removeListener("paste",d),h&&b.fire("pasteDialog",
+e)?(b.on("pasteDialogCommit",g),b.on("dialogHide",function(a){a.removeListener();a.data.removeListener("pasteDialogCommit",g);setTimeout(function(){f||c(null)},10)})):c(null))}}function A(b){if(CKEDITOR.env.webkit){if(!b.match(/^[^<]*$/g)&&!b.match(/^(<div><br( ?\/)?><\/div>|<div>[^<]*<\/div>)*$/gi))return"html"}else if(CKEDITOR.env.ie){if(!b.match(/^([^<]|<br( ?\/)?>)*$/gi)&&!b.match(/^(<p>([^<]|<br( ?\/)?>)*<\/p>|(\r\n))*$/gi))return"html"}else if(CKEDITOR.env.gecko){if(!b.match(/^([^<]|<br( ?\/)?>)*$/gi))return"html"}else return"html";
+return"htmlifiedtext"}function B(b,a){function c(a){return CKEDITOR.tools.repeat("\x3c/p\x3e\x3cp\x3e",~~(a/2))+(1==a%2?"\x3cbr\x3e":"")}a=a.replace(/\s+/g," ").replace(/> +</g,"\x3e\x3c").replace(/<br ?\/>/gi,"\x3cbr\x3e");a=a.replace(/<\/?[A-Z]+>/g,function(a){return a.toLowerCase()});if(a.match(/^[^<]$/))return a;CKEDITOR.env.webkit&&-1<a.indexOf("\x3cdiv\x3e")&&(a=a.replace(/^(<div>(<br>|)<\/div>)(?!$|(<div>(<br>|)<\/div>))/g,"\x3cbr\x3e").replace(/^(<div>(<br>|)<\/div>){2}(?!$)/g,"\x3cdiv\x3e\x3c/div\x3e"),
+a.match(/<div>(<br>|)<\/div>/)&&(a="\x3cp\x3e"+a.replace(/(<div>(<br>|)<\/div>)+/g,function(a){return c(a.split("\x3c/div\x3e\x3cdiv\x3e").length+1)})+"\x3c/p\x3e"),a=a.replace(/<\/div><div>/g,"\x3cbr\x3e"),a=a.replace(/<\/?div>/g,""));CKEDITOR.env.gecko&&b.enterMode!=CKEDITOR.ENTER_BR&&(CKEDITOR.env.gecko&&(a=a.replace(/^<br><br>$/,"\x3cbr\x3e")),-1<a.indexOf("\x3cbr\x3e\x3cbr\x3e")&&(a="\x3cp\x3e"+a.replace(/(<br>){2,}/g,function(a){return c(a.length/4)})+"\x3c/p\x3e"));return C(b,a)}function D(){function b(){var a=
+{},b;for(b in CKEDITOR.dtd)"$"!=b.charAt(0)&&"div"!=b&&"span"!=b&&(a[b]=1);return a}var a={};return{get:function(c){return"plain-text"==c?a.plainText||(a.plainText=new CKEDITOR.filter("br")):"semantic-content"==c?((c=a.semanticContent)||(c=new CKEDITOR.filter,c.allow({$1:{elements:b(),attributes:!0,styles:!1,classes:!1}}),c=a.semanticContent=c),c):c?new CKEDITOR.filter(c):null}}}function y(b,a,c){a=CKEDITOR.htmlParser.fragment.fromHtml(a);var e=new CKEDITOR.htmlParser.basicWriter;c.applyTo(a,!0,!1,
+b.activeEnterMode);a.writeHtml(e);return e.getHtml()}function C(b,a){b.enterMode==CKEDITOR.ENTER_BR?a=a.replace(/(<\/p><p>)+/g,function(a){return CKEDITOR.tools.repeat("\x3cbr\x3e",a.length/7*2)}).replace(/<\/?p>/g,""):b.enterMode==CKEDITOR.ENTER_DIV&&(a=a.replace(/<(\/)?p>/g,"\x3c$1div\x3e"));return a}function E(b){b.data.preventDefault();b.data.$.dataTransfer.dropEffect="none"}function F(b){var a=CKEDITOR.plugins.clipboard;b.on("contentDom",function(){function c(a,c,d){c.select();q(b,{dataTransfer:d,
+method:"drop"},1);d.sourceEditor.fire("saveSnapshot");d.sourceEditor.editable().extractHtmlFromRange(a);d.sourceEditor.getSelection().selectRanges([a]);d.sourceEditor.fire("saveSnapshot")}function e(d,c){d.select();q(b,{dataTransfer:c,method:"drop"},1);a.resetDragDataTransfer()}function f(a,d,c){var g={$:a.data.$,target:a.data.getTarget()};d&&(g.dragRange=d);c&&(g.dropRange=c);!1===b.fire(a.name,g)&&a.data.preventDefault()}function g(a){a.type!=CKEDITOR.NODE_ELEMENT&&(a=a.getParent());return a.getChildCount()}
+var d=b.editable(),h=CKEDITOR.plugins.clipboard.getDropTarget(b),n=b.ui.space("top"),w=b.ui.space("bottom");a.preventDefaultDropOnElement(n);a.preventDefaultDropOnElement(w);d.attachListener(h,"dragstart",f);d.attachListener(b,"dragstart",a.resetDragDataTransfer,a,null,1);d.attachListener(b,"dragstart",function(d){a.initDragDataTransfer(d,b)},null,null,2);d.attachListener(b,"dragstart",function(){var d=a.dragRange=b.getSelection().getRanges()[0];CKEDITOR.env.ie&&10>CKEDITOR.env.version&&(a.dragStartContainerChildCount=
+d?g(d.startContainer):null,a.dragEndContainerChildCount=d?g(d.endContainer):null)},null,null,100);d.attachListener(h,"dragend",f);d.attachListener(b,"dragend",a.initDragDataTransfer,a,null,1);d.attachListener(b,"dragend",a.resetDragDataTransfer,a,null,100);d.attachListener(h,"dragover",function(a){var b=a.data.getTarget();b&&b.is&&b.is("html")?a.data.preventDefault():CKEDITOR.env.ie&&CKEDITOR.plugins.clipboard.isFileApiSupported&&a.data.$.dataTransfer.types.contains("Files")&&a.data.preventDefault()});
+d.attachListener(h,"drop",function(d){if(!d.data.$.defaultPrevented){d.data.preventDefault();var c=d.data.getTarget();if(!c.isReadOnly()||c.type==CKEDITOR.NODE_ELEMENT&&c.is("html")){var c=a.getRangeAtDropPosition(d,b),g=a.dragRange;c&&f(d,g,c)}}},null,null,9999);d.attachListener(b,"drop",a.initDragDataTransfer,a,null,1);d.attachListener(b,"drop",function(d){if(d=d.data){var g=d.dropRange,h=d.dragRange,f=d.dataTransfer;f.getTransferType(b)==CKEDITOR.DATA_TRANSFER_INTERNAL?setTimeout(function(){a.internalDrop(h,
+g,f,b)},0):f.getTransferType(b)==CKEDITOR.DATA_TRANSFER_CROSS_EDITORS?c(h,g,f):e(g,f)}},null,null,9999)})}CKEDITOR.plugins.add("clipboard",{requires:"dialog",init:function(b){var a,c=D();b.config.forcePasteAsPlainText?a="plain-text":b.config.pasteFilter?a=b.config.pasteFilter:!CKEDITOR.env.webkit||"pasteFilter"in b.config||(a="semantic-content");b.pasteFilter=c.get(a);z(b);F(b);CKEDITOR.dialog.add("paste",CKEDITOR.getUrl(this.path+"dialogs/paste.js"));if(CKEDITOR.env.gecko){var e=["image/png","image/jpeg",
+"image/gif"],f;b.on("paste",function(a){var d=a.data,c=d.dataTransfer;if(!d.dataValue&&"paste"==d.method&&c&&1==c.getFilesCount()&&f!=c.id&&(c=c.getFile(0),-1!=CKEDITOR.tools.indexOf(e,c.type))){var n=new FileReader;n.addEventListener("load",function(){a.data.dataValue='\x3cimg src\x3d"'+n.result+'" /\x3e';b.fire("paste",a.data)},!1);n.addEventListener("abort",function(){b.fire("paste",a.data)},!1);n.addEventListener("error",function(){b.fire("paste",a.data)},!1);n.readAsDataURL(c);f=d.dataTransfer.id;
+a.stop()}},null,null,1)}b.on("paste",function(a){a.data.dataTransfer||(a.data.dataTransfer=new CKEDITOR.plugins.clipboard.dataTransfer);if(!a.data.dataValue){var d=a.data.dataTransfer,c=d.getData("text/html");if(c)a.data.dataValue=c,a.data.type="html";else if(c=d.getData("text/plain"))a.data.dataValue=b.editable().transformPlainTextToHtml(c),a.data.type="text"}},null,null,1);b.on("paste",function(a){var b=a.data.dataValue,c=CKEDITOR.dtd.$block;-1<b.indexOf("Apple-")&&(b=b.replace(/<span class="Apple-converted-space">&nbsp;<\/span>/gi,
+" "),"html"!=a.data.type&&(b=b.replace(/<span class="Apple-tab-span"[^>]*>([^<]*)<\/span>/gi,function(a,b){return b.replace(/\t/g,"\x26nbsp;\x26nbsp; \x26nbsp;")})),-1<b.indexOf('\x3cbr class\x3d"Apple-interchange-newline"\x3e')&&(a.data.startsWithEOL=1,a.data.preSniffing="html",b=b.replace(/<br class="Apple-interchange-newline">/,"")),b=b.replace(/(<[^>]+) class="Apple-[^"]*"/gi,"$1"));if(b.match(/^<[^<]+cke_(editable|contents)/i)){var e,f,k=new CKEDITOR.dom.element("div");for(k.setHtml(b);1==k.getChildCount()&&
+(e=k.getFirst())&&e.type==CKEDITOR.NODE_ELEMENT&&(e.hasClass("cke_editable")||e.hasClass("cke_contents"));)k=f=e;f&&(b=f.getHtml().replace(/<br>$/i,""))}CKEDITOR.env.ie?b=b.replace(/^&nbsp;(?: |\r\n)?<(\w+)/g,function(b,d){return d.toLowerCase()in c?(a.data.preSniffing="html","\x3c"+d):b}):CKEDITOR.env.webkit?b=b.replace(/<\/(\w+)><div><br><\/div>$/,function(b,d){return d in c?(a.data.endsWithEOL=1,"\x3c/"+d+"\x3e"):b}):CKEDITOR.env.gecko&&(b=b.replace(/(\s)<br>$/,"$1"));a.data.dataValue=b},null,
+null,3);b.on("paste",function(a){a=a.data;var d=a.type,e=a.dataValue,f,p=b.config.clipboard_defaultContentType||"html",k=a.dataTransfer.getTransferType(b);f="html"==d||"html"==a.preSniffing?"html":A(e);"htmlifiedtext"==f&&(e=B(b.config,e));"text"==d&&"html"==f?e=y(b,e,c.get("plain-text")):k==CKEDITOR.DATA_TRANSFER_EXTERNAL&&b.pasteFilter&&!a.dontFilter&&(e=y(b,e,b.pasteFilter));a.startsWithEOL&&(e='\x3cbr data-cke-eol\x3d"1"\x3e'+e);a.endsWithEOL&&(e+='\x3cbr data-cke-eol\x3d"1"\x3e');"auto"==d&&
+(d="html"==f||"html"==p?"html":"text");a.type=d;a.dataValue=e;delete a.preSniffing;delete a.startsWithEOL;delete a.endsWithEOL},null,null,6);b.on("paste",function(a){a=a.data;a.dataValue&&(b.insertHtml(a.dataValue,a.type,a.range),setTimeout(function(){b.fire("afterPaste")},0))},null,null,1E3);b.on("pasteDialog",function(a){setTimeout(function(){b.openDialog("paste",a.data)},0)})}});CKEDITOR.plugins.clipboard={isCustomCopyCutSupported:!CKEDITOR.env.ie&&!CKEDITOR.env.iOS,isCustomDataTypesSupported:!CKEDITOR.env.ie,
+isFileApiSupported:!CKEDITOR.env.ie||9<CKEDITOR.env.version,mainPasteEvent:CKEDITOR.env.ie&&!CKEDITOR.env.edge?"beforepaste":"paste",canClipboardApiBeTrusted:function(b,a){return b.getTransferType(a)!=CKEDITOR.DATA_TRANSFER_EXTERNAL||CKEDITOR.env.chrome&&!b.isEmpty()||CKEDITOR.env.gecko&&(b.getData("text/html")||b.getFilesCount())?!0:!1},getDropTarget:function(b){var a=b.editable();return CKEDITOR.env.ie&&9>CKEDITOR.env.version||a.isInline()?a:b.document},fixSplitNodesAfterDrop:function(b,a,c,e){function f(b,
+c,e){var f=b;f.type==CKEDITOR.NODE_TEXT&&(f=b.getParent());if(f.equals(c)&&e!=c.getChildCount())return b=a.startContainer.getChild(a.startOffset-1),c=a.startContainer.getChild(a.startOffset),b&&b.type==CKEDITOR.NODE_TEXT&&c&&c.type==CKEDITOR.NODE_TEXT&&(e=b.getLength(),b.setText(b.getText()+c.getText()),c.remove(),a.setStart(b,e),a.collapse(!0)),!0}var g=a.startContainer;"number"==typeof e&&"number"==typeof c&&g.type==CKEDITOR.NODE_ELEMENT&&(f(b.startContainer,g,c)||f(b.endContainer,g,e))},isDropRangeAffectedByDragRange:function(b,
+a){var c=a.startContainer,e=a.endOffset;return b.endContainer.equals(c)&&b.endOffset<=e||b.startContainer.getParent().equals(c)&&b.startContainer.getIndex()<e||b.endContainer.getParent().equals(c)&&b.endContainer.getIndex()<e?!0:!1},internalDrop:function(b,a,c,e){var f=CKEDITOR.plugins.clipboard,g=e.editable(),d,h;e.fire("saveSnapshot");e.fire("lockSnapshot",{dontUpdate:1});CKEDITOR.env.ie&&10>CKEDITOR.env.version&&this.fixSplitNodesAfterDrop(b,a,f.dragStartContainerChildCount,f.dragEndContainerChildCount);
+(h=this.isDropRangeAffectedByDragRange(b,a))||(d=b.createBookmark(!1));f=a.clone().createBookmark(!1);h&&(d=b.createBookmark(!1));b=d.startNode;a=d.endNode;h=f.startNode;a&&b.getPosition(h)&CKEDITOR.POSITION_PRECEDING&&a.getPosition(h)&CKEDITOR.POSITION_FOLLOWING&&h.insertBefore(b);b=e.createRange();b.moveToBookmark(d);g.extractHtmlFromRange(b,1);a=e.createRange();a.moveToBookmark(f);q(e,{dataTransfer:c,method:"drop",range:a},1);e.fire("unlockSnapshot")},getRangeAtDropPosition:function(b,a){var c=
+b.data.$,e=c.clientX,f=c.clientY,g=a.getSelection(!0).getRanges()[0],d=a.createRange();if(b.data.testRange)return b.data.testRange;if(document.caretRangeFromPoint)c=a.document.$.caretRangeFromPoint(e,f),d.setStart(CKEDITOR.dom.node(c.startContainer),c.startOffset),d.collapse(!0);else if(c.rangeParent)d.setStart(CKEDITOR.dom.node(c.rangeParent),c.rangeOffset),d.collapse(!0);else{if(CKEDITOR.env.ie&&8<CKEDITOR.env.version&&g&&a.editable().hasFocus)return g;if(document.body.createTextRange){a.focus();
+c=a.document.getBody().$.createTextRange();try{for(var h=!1,n=0;20>n&&!h;n++){if(!h)try{c.moveToPoint(e,f-n),h=!0}catch(p){}if(!h)try{c.moveToPoint(e,f+n),h=!0}catch(k){}}if(h){var u="cke-temp-"+(new Date).getTime();c.pasteHTML('\x3cspan id\x3d"'+u+'"\x3e​\x3c/span\x3e');var r=a.document.getById(u);d.moveToPosition(r,CKEDITOR.POSITION_BEFORE_START);r.remove()}else{var t=a.document.$.elementFromPoint(e,f),m=new CKEDITOR.dom.element(t),q;if(m.equals(a.editable())||"html"==m.getName())return g&&g.startContainer&&
+!g.startContainer.equals(a.editable())?g:null;q=m.getClientRect();e<q.left?d.setStartAt(m,CKEDITOR.POSITION_AFTER_START):d.setStartAt(m,CKEDITOR.POSITION_BEFORE_END);d.collapse(!0)}}catch(v){return null}}else return null}return d},initDragDataTransfer:function(b,a){var c=b.data.$?b.data.$.dataTransfer:null,e=new this.dataTransfer(c,a);c?this.dragData&&e.id==this.dragData.id?e=this.dragData:this.dragData=e:this.dragData?e=this.dragData:this.dragData=e;b.data.dataTransfer=e},resetDragDataTransfer:function(){this.dragData=
+null},initPasteDataTransfer:function(b,a){if(this.isCustomCopyCutSupported){if(b&&b.data&&b.data.$){var c=new this.dataTransfer(b.data.$.clipboardData,a);this.copyCutData&&c.id==this.copyCutData.id?(c=this.copyCutData,c.$=b.data.$.clipboardData):this.copyCutData=c;return c}return new this.dataTransfer(null,a)}return new this.dataTransfer(CKEDITOR.env.edge&&b&&b.data.$&&b.data.$.clipboardData||null,a)},preventDefaultDropOnElement:function(b){b&&b.on("dragover",E)}};var p=CKEDITOR.plugins.clipboard.isCustomDataTypesSupported?
+"cke/id":"Text";CKEDITOR.plugins.clipboard.dataTransfer=function(b,a){b&&(this.$=b);this._={metaRegExp:/^<meta.*?>/i,bodyRegExp:/<body(?:[\s\S]*?)>([\s\S]*)<\/body>/i,fragmentRegExp:/\x3c!--(?:Start|End)Fragment--\x3e/g,data:{},files:[],normalizeType:function(a){a=a.toLowerCase();return"text"==a||"text/plain"==a?"Text":"url"==a?"URL":a}};this.id=this.getData(p);this.id||(this.id="Text"==p?"":"cke-"+CKEDITOR.tools.getUniqueId());if("Text"!=p)try{this.$.setData(p,this.id)}catch(c){}a&&(this.sourceEditor=
+a,this.setData("text/html",a.getSelectedHtml(1)),"Text"==p||this.getData("text/plain")||this.setData("text/plain",a.getSelection().getSelectedText()))};CKEDITOR.DATA_TRANSFER_INTERNAL=1;CKEDITOR.DATA_TRANSFER_CROSS_EDITORS=2;CKEDITOR.DATA_TRANSFER_EXTERNAL=3;CKEDITOR.plugins.clipboard.dataTransfer.prototype={getData:function(b){b=this._.normalizeType(b);var a=this._.data[b];if(void 0===a||null===a||""===a)try{a=this.$.getData(b)}catch(c){}if(void 0===a||null===a||""===a)a="";"text/html"==b?(a=a.replace(this._.metaRegExp,
+""),(b=this._.bodyRegExp.exec(a))&&b.length&&(a=b[1],a=a.replace(this._.fragmentRegExp,""))):"Text"==b&&CKEDITOR.env.gecko&&this.getFilesCount()&&"file://"==a.substring(0,7)&&(a="");return a},setData:function(b,a){b=this._.normalizeType(b);this._.data[b]=a;if(CKEDITOR.plugins.clipboard.isCustomDataTypesSupported||"URL"==b||"Text"==b){"Text"==p&&"Text"==b&&(this.id=a);try{this.$.setData(b,a)}catch(c){}}},getTransferType:function(b){return this.sourceEditor?this.sourceEditor==b?CKEDITOR.DATA_TRANSFER_INTERNAL:
+CKEDITOR.DATA_TRANSFER_CROSS_EDITORS:CKEDITOR.DATA_TRANSFER_EXTERNAL},cacheData:function(){function b(b){b=a._.normalizeType(b);var c=a.getData(b);c&&(a._.data[b]=c)}if(this.$){var a=this,c,e;if(CKEDITOR.plugins.clipboard.isCustomDataTypesSupported){if(this.$.types)for(c=0;c<this.$.types.length;c++)b(this.$.types[c])}else b("Text"),b("URL");e=this._getImageFromClipboard();if(this.$&&this.$.files||e){this._.files=[];if(this.$.files&&this.$.files.length)for(c=0;c<this.$.files.length;c++)this._.files.push(this.$.files[c]);
+0===this._.files.length&&e&&this._.files.push(e)}}},getFilesCount:function(){return this._.files.length?this._.files.length:this.$&&this.$.files&&this.$.files.length?this.$.files.length:this._getImageFromClipboard()?1:0},getFile:function(b){return this._.files.length?this._.files[b]:this.$&&this.$.files&&this.$.files.length?this.$.files[b]:0===b?this._getImageFromClipboard():void 0},isEmpty:function(){var b={},a;if(this.getFilesCount())return!1;for(a in this._.data)b[a]=1;if(this.$)if(CKEDITOR.plugins.clipboard.isCustomDataTypesSupported){if(this.$.types)for(var c=
+0;c<this.$.types.length;c++)b[this.$.types[c]]=1}else b.Text=1,b.URL=1;"Text"!=p&&(b[p]=0);for(a in b)if(b[a]&&""!==this.getData(a))return!1;return!0},_getImageFromClipboard:function(){var b;if(this.$&&this.$.items&&this.$.items[0])try{if((b=this.$.items[0].getAsFile())&&b.type)return b}catch(a){}}}})();(function(){function f(a){return a.getName&&!a.hasAttribute("data-cke-temp")}CKEDITOR.plugins.add("widgetselection",{init:function(a){if(CKEDITOR.env.webkit){var b=CKEDITOR.plugins.widgetselection;a.on("contentDom",function(a){a=a.editor;var d=a.document,e=a.editable();e.attachListener(d,"keydown",function(a){var c=a.data.$;65==a.data.getKey()&&(CKEDITOR.env.mac&&c.metaKey||!CKEDITOR.env.mac&&c.ctrlKey)&&CKEDITOR.tools.setTimeout(function(){b.addFillers(e)||b.removeFillers(e)},0)},null,null,-1);a.on("selectionCheck",
+function(a){b.removeFillers(a.editor.editable())});a.on("paste",function(a){a.data.dataValue=b.cleanPasteData(a.data.dataValue)});"selectall"in a.plugins&&b.addSelectAllIntegration(a)})}}});CKEDITOR.plugins.widgetselection={startFiller:null,endFiller:null,fillerAttribute:"data-cke-filler-webkit",fillerContent:"\x26nbsp;",fillerTagName:"div",addFillers:function(a){var b=a.editor;if(!this.isWholeContentSelected(a)&&0<a.getChildCount()){var c=a.getFirst(f),d=a.getLast(f);c&&c.type==CKEDITOR.NODE_ELEMENT&&
+!c.isEditable()&&(this.startFiller=this.createFiller(),a.append(this.startFiller,1));d&&d.type==CKEDITOR.NODE_ELEMENT&&!d.isEditable()&&(this.endFiller=this.createFiller(!0),a.append(this.endFiller,0));if(this.hasFiller(a))return b=b.createRange(),b.selectNodeContents(a),b.select(),!0}return!1},removeFillers:function(a){if(this.hasFiller(a)&&!this.isWholeContentSelected(a)){var b=a.findOne(this.fillerTagName+"["+this.fillerAttribute+"\x3dstart]"),c=a.findOne(this.fillerTagName+"["+this.fillerAttribute+
+"\x3dend]");this.startFiller&&b&&this.startFiller.equals(b)?this.removeFiller(this.startFiller,a):this.startFiller=b;this.endFiller&&c&&this.endFiller.equals(c)?this.removeFiller(this.endFiller,a):this.endFiller=c}},cleanPasteData:function(a){a&&a.length&&(a=a.replace(this.createFillerRegex(),"").replace(this.createFillerRegex(!0),""));return a},isWholeContentSelected:function(a){var b=a.editor.getSelection().getRanges()[0];return!b||b&&b.collapsed?!1:(b=b.clone(),b.enlarge(CKEDITOR.ENLARGE_ELEMENT),
+!!(b&&a&&b.startContainer&&b.endContainer&&0===b.startOffset&&b.endOffset===a.getChildCount()&&b.startContainer.equals(a)&&b.endContainer.equals(a)))},hasFiller:function(a){return 0<a.find(this.fillerTagName+"["+this.fillerAttribute+"]").count()},createFiller:function(a){var b=new CKEDITOR.dom.element(this.fillerTagName);b.setHtml(this.fillerContent);b.setAttribute(this.fillerAttribute,a?"end":"start");b.setAttribute("data-cke-temp",1);b.setStyles({display:"block",width:0,height:0,padding:0,border:0,
+margin:0,position:"absolute",top:0,left:"-9999px",opacity:0,overflow:"hidden"});return b},removeFiller:function(a,b){if(a){var c=b.editor,d=b.editor.getSelection().getRanges()[0].startPath(),e=c.createRange(),g,f;d.contains(a)&&(g=a.getHtml(),f=!0);d="start"==a.getAttribute(this.fillerAttribute);a.remove();g&&0<g.length&&g!=this.fillerContent?(b.insertHtmlIntoRange(g,c.getSelection().getRanges()[0]),e.setStartAt(b.getChild(b.getChildCount()-1),CKEDITOR.POSITION_BEFORE_END),c.getSelection().selectRanges([e])):
+f&&(d?e.setStartAt(b.getFirst().getNext(),CKEDITOR.POSITION_AFTER_START):e.setEndAt(b.getLast().getPrevious(),CKEDITOR.POSITION_BEFORE_END),b.editor.getSelection().selectRanges([e]))}},createFillerRegex:function(a){var b=this.createFiller(a).getOuterHtml().replace(/style="[^"]*"/gi,'style\x3d"[^"]*"').replace(/>[^<]*</gi,"\x3e[^\x3c]*\x3c");return new RegExp((a?"":"^")+b+(a?"$":""))},addSelectAllIntegration:function(a){var b=this;a.editable().attachListener(a,"beforeCommandExec",function(c){var d=
+a.editable();"selectAll"==c.data.name&&d&&b.addFillers(d)},null,null,9999)}}})();(function(){function p(a){this.editor=a;this.registered={};this.instances={};this.selected=[];this.widgetHoldingFocusedEditable=this.focused=null;this._={nextId:0,upcasts:[],upcastCallbacks:[],filters:{}};F(this);G(this);this.on("checkWidgets",H);this.editor.on("contentDomInvalidated",this.checkWidgets,this);I(this);J(this);K(this);L(this);M(this)}function g(a,b,c,d,e){var f=a.editor;CKEDITOR.tools.extend(this,d,{editor:f,id:b,inline:"span"==c.getParent().getName(),element:c,data:CKEDITOR.tools.extend({},
+"function"==typeof d.defaults?d.defaults():d.defaults),dataReady:!1,inited:!1,ready:!1,edit:g.prototype.edit,focusedEditable:null,definition:d,repository:a,draggable:!1!==d.draggable,_:{downcastFn:d.downcast&&"string"==typeof d.downcast?d.downcasts[d.downcast]:d.downcast}},!0);a.fire("instanceCreated",this);N(this,d);this.init&&this.init();this.inited=!0;(a=this.element.data("cke-widget-data"))&&this.setData(JSON.parse(decodeURIComponent(a)));e&&this.setData(e);this.data.classes||this.setData("classes",
+this.getClasses());this.dataReady=!0;r(this);this.fire("data",this.data);this.isInited()&&f.editable().contains(this.wrapper)&&(this.ready=!0,this.fire("ready"))}function q(a,b,c){CKEDITOR.dom.element.call(this,b.$);this.editor=a;this._={};b=this.filter=c.filter;CKEDITOR.dtd[this.getName()].p?(this.enterMode=b?b.getAllowedEnterMode(a.enterMode):a.enterMode,this.shiftEnterMode=b?b.getAllowedEnterMode(a.shiftEnterMode,!0):a.shiftEnterMode):this.enterMode=this.shiftEnterMode=CKEDITOR.ENTER_BR}function O(a,
+b){a.addCommand(b.name,{exec:function(a,d){function e(){a.widgets.finalizeCreation(k)}var f=a.widgets.focused;if(f&&f.name==b.name)f.edit();else if(b.insert)b.insert();else if(b.template){var f="function"==typeof b.defaults?b.defaults():b.defaults,f=CKEDITOR.dom.element.createFromHtml(b.template.output(f)),h,l=a.widgets.wrapElement(f,b.name),k=new CKEDITOR.dom.documentFragment(l.getDocument());k.append(l);(h=a.widgets.initOn(f,b,d&&d.startupData))?(f=h.once("edit",function(b){if(b.data.dialog)h.once("dialog",
+function(b){b=b.data;var d,f;d=b.once("ok",e,null,null,20);f=b.once("cancel",function(b){b.data&&!1===b.data.hide||a.widgets.destroy(h,!0)});b.once("hide",function(){d.removeListener();f.removeListener()})});else e()},null,null,999),h.edit(),f.removeListener()):e()}},allowedContent:b.allowedContent,requiredContent:b.requiredContent,contentForms:b.contentForms,contentTransformations:b.contentTransformations})}function P(a,b){function c(b,d,c){var e=CKEDITOR.tools.getIndex(a._.upcasts,function(a){return a[2]>
+c});0>e&&(e=a._.upcasts.length);a._.upcasts.splice(e,0,[b,d,c])}var d=b.upcast,e=b.upcastPriority||10;if(d)if("string"==typeof d)for(d=d.split(",");d.length;)c(b.upcasts[d.pop()],b.name,e);else c(d,b.name,e)}function t(a,b){a.focused=null;if(b.isInited()){var c=b.editor.checkDirty();a.fire("widgetBlurred",{widget:b});b.setFocused(!1);!c&&b.editor.resetDirty()}}function H(a){a=a.data;if("wysiwyg"==this.editor.mode){var b=this.editor.editable(),c=this.instances,d,e,f,h;if(b){for(d in c)c[d].isReady()&&
+!b.contains(c[d].wrapper)&&this.destroy(c[d],!0);if(a&&a.initOnlyNew)c=this.initOnAll();else{var l=b.find(".cke_widget_wrapper"),c=[];d=0;for(e=l.count();d<e;d++){f=l.getItem(d);if(h=!this.getByElement(f,!0)){a:{h=Q;for(var k=f;k=k.getParent();)if(h(k)){h=!0;break a}h=!1}h=!h}h&&b.contains(f)&&(f.addClass("cke_widget_new"),c.push(this.initOn(f.getFirst(g.isDomWidgetElement))))}}a&&a.focusInited&&1==c.length&&c[0].focus()}}}function u(a,b,c){if(!c.allowedContent)return null;var d=this._.filters[a];
+d||(this._.filters[a]=d={});(a=d[b])||(d[b]=a=new CKEDITOR.filter(c.allowedContent));return a}function R(a){var b=[],c=a._.upcasts,d=a._.upcastCallbacks;return{toBeWrapped:b,iterator:function(a){var f,h,l,k,m;if("data-cke-widget-wrapper"in a.attributes)return(a=a.getFirst(g.isParserWidgetElement))&&b.push([a]),!1;if("data-widget"in a.attributes)return b.push([a]),!1;if(m=c.length){if(a.attributes["data-cke-widget-upcasted"])return!1;k=0;for(f=d.length;k<f;++k)if(!1===d[k](a))return;for(k=0;k<m;++k)if(f=
+c[k],l={},h=f[0](a,l))return h instanceof CKEDITOR.htmlParser.element&&(a=h),a.attributes["data-cke-widget-data"]=encodeURIComponent(JSON.stringify(l)),a.attributes["data-cke-widget-upcasted"]=1,b.push([a,f[1]]),!1}}}}function v(a,b){return{tabindex:-1,contenteditable:"false","data-cke-widget-wrapper":1,"data-cke-filter":"off","class":"cke_widget_wrapper cke_widget_new cke_widget_"+(a?"inline":"block")+(b?" cke_widget_"+b:"")}}function w(a,b,c){if(a.type==CKEDITOR.NODE_ELEMENT){var d=CKEDITOR.dtd[a.name];
+if(d&&!d[c.name]){var d=a.split(b),e=a.parent;b=d.getIndex();a.children.length||(--b,a.remove());d.children.length||d.remove();return w(e,b,c)}}a.add(c,b)}function x(a,b){return"boolean"==typeof a.inline?a.inline:!!CKEDITOR.dtd.$inline[b]}function Q(a){return a.hasAttribute("data-cke-temp")}function n(a,b,c,d){var e=a.editor;e.fire("lockSnapshot");c?(d=c.data("cke-widget-editable"),d=b.editables[d],a.widgetHoldingFocusedEditable=b,b.focusedEditable=d,c.addClass("cke_widget_editable_focused"),d.filter&&
+e.setActiveFilter(d.filter),e.setActiveEnterMode(d.enterMode,d.shiftEnterMode)):(d||b.focusedEditable.removeClass("cke_widget_editable_focused"),b.focusedEditable=null,a.widgetHoldingFocusedEditable=null,e.setActiveFilter(null),e.setActiveEnterMode(null,null));e.fire("unlockSnapshot")}function S(a){a.contextMenu&&a.contextMenu.addListener(function(b){if(b=a.widgets.getByElement(b,!0))return b.fire("contextMenu",{})})}function T(a,b){return CKEDITOR.tools.trim(b)}function L(a){var b=a.editor,c=CKEDITOR.plugins.lineutils;
+b.on("dragstart",function(d){var c=d.data.target;g.isDomDragHandler(c)&&(c=a.getByElement(c),d.data.dataTransfer.setData("cke/widget-id",c.id),b.focus(),c.focus())});b.on("drop",function(d){var c=d.data.dataTransfer,f=c.getData("cke/widget-id"),h=c.getTransferType(b),c=b.createRange();""!==f&&h===CKEDITOR.DATA_TRANSFER_CROSS_EDITORS?d.cancel():""!==f&&h==CKEDITOR.DATA_TRANSFER_INTERNAL&&(f=a.instances[f])&&(c.setStartBefore(f.wrapper),c.setEndAfter(f.wrapper),d.data.dragRange=c,delete CKEDITOR.plugins.clipboard.dragStartContainerChildCount,
+delete CKEDITOR.plugins.clipboard.dragEndContainerChildCount,d.data.dataTransfer.setData("text/html",b.editable().getHtmlFromRange(c).getHtml()),b.widgets.destroy(f,!0))});b.on("contentDom",function(){var d=b.editable();CKEDITOR.tools.extend(a,{finder:new c.finder(b,{lookups:{"default":function(b){if(!b.is(CKEDITOR.dtd.$listItem)&&b.is(CKEDITOR.dtd.$block)&&!g.isDomNestedEditable(b)&&!a._.draggedWidget.wrapper.contains(b)){var c=g.getNestedEditable(d,b);if(c){b=a._.draggedWidget;if(a.getByElement(c)==
+b)return;c=CKEDITOR.filter.instances[c.data("cke-filter")];b=b.requiredContent;if(c&&b&&!c.check(b))return}return CKEDITOR.LINEUTILS_BEFORE|CKEDITOR.LINEUTILS_AFTER}}}}),locator:new c.locator(b),liner:new c.liner(b,{lineStyle:{cursor:"move !important","border-top-color":"#666"},tipLeftStyle:{"border-left-color":"#666"},tipRightStyle:{"border-right-color":"#666"}})},!0)})}function J(a){var b=a.editor;b.on("contentDom",function(){var c=b.editable(),d=c.isInline()?c:b.document,e,f;c.attachListener(d,
+"mousedown",function(c){var d=c.data.getTarget();if(!d.type)return!1;e=a.getByElement(d);f=0;e&&(e.inline&&d.type==CKEDITOR.NODE_ELEMENT&&d.hasAttribute("data-cke-widget-drag-handler")?(f=1,a.focused!=e&&b.getSelection().removeAllRanges()):g.getNestedEditable(e.wrapper,d)?e=null:(c.data.preventDefault(),CKEDITOR.env.ie||e.focus()))});c.attachListener(d,"mouseup",function(){f&&e&&e.wrapper&&(f=0,e.focus())});CKEDITOR.env.ie&&c.attachListener(d,"mouseup",function(){setTimeout(function(){e&&e.wrapper&&
+c.contains(e.wrapper)&&(e.focus(),e=null)})})});b.on("doubleclick",function(b){var d=a.getByElement(b.data.element);if(d&&!g.getNestedEditable(d.wrapper,b.data.element))return d.fire("doubleclick",{element:b.data.element})},null,null,1)}function K(a){a.editor.on("key",function(b){var c=a.focused,d=a.widgetHoldingFocusedEditable,e;c?e=c.fire("key",{keyCode:b.data.keyCode}):d&&(c=b.data.keyCode,b=d.focusedEditable,c==CKEDITOR.CTRL+65?(c=b.getBogus(),d=d.editor.createRange(),d.selectNodeContents(b),
+c&&d.setEndAt(c,CKEDITOR.POSITION_BEFORE_START),d.select(),e=!1):8==c||46==c?(e=d.editor.getSelection().getRanges(),d=e[0],e=!(1==e.length&&d.collapsed&&d.checkBoundaryOfElement(b,CKEDITOR[8==c?"START":"END"]))):e=void 0);return e},null,null,1)}function M(a){function b(b){a.focused&&y(a.focused,"cut"==b.name)}var c=a.editor;c.on("contentDom",function(){var a=c.editable();a.attachListener(a,"copy",b);a.attachListener(a,"cut",b)})}function I(a){var b=a.editor;b.on("selectionCheck",function(){a.fire("checkSelection")});
+a.on("checkSelection",a.checkSelection,a);b.on("selectionChange",function(c){var d=(c=g.getNestedEditable(b.editable(),c.data.selection.getStartElement()))&&a.getByElement(c),e=a.widgetHoldingFocusedEditable;e?e===d&&e.focusedEditable.equals(c)||(n(a,e,null),d&&c&&n(a,d,c)):d&&c&&n(a,d,c)});b.on("dataReady",function(){z(a).commit()});b.on("blur",function(){var b;(b=a.focused)&&t(a,b);(b=a.widgetHoldingFocusedEditable)&&n(a,b,null)})}function G(a){var b=a.editor,c={};b.on("toDataFormat",function(b){var e=
+CKEDITOR.tools.getNextNumber(),f=[];b.data.downcastingSessionId=e;c[e]=f;b.data.dataValue.forEach(function(b){var c=b.attributes,d;if("data-cke-widget-id"in c){if(c=a.instances[c["data-cke-widget-id"]])d=b.getFirst(g.isParserWidgetElement),f.push({wrapper:b,element:d,widget:c,editables:{}}),"1"!=d.attributes["data-cke-widget-keep-attr"]&&delete d.attributes["data-widget"]}else if("data-cke-widget-editable"in c)return f[f.length-1].editables[c["data-cke-widget-editable"]]=b,!1},CKEDITOR.NODE_ELEMENT,
+!0)},null,null,8);b.on("toDataFormat",function(a){if(a.data.downcastingSessionId){a=c[a.data.downcastingSessionId];for(var b,f,h,l,g,m;b=a.shift();){f=b.widget;h=b.element;l=f._.downcastFn&&f._.downcastFn.call(f,h);for(m in b.editables)g=b.editables[m],delete g.attributes.contenteditable,g.setHtml(f.editables[m].getData());l||(l=h);b.wrapper.replaceWith(l)}}},null,null,13);b.on("contentDomUnload",function(){a.destroyAll(!0)})}function F(a){var b=a.editor,c,d;b.on("toHtml",function(b){var d=R(a),h;
+for(b.data.dataValue.forEach(d.iterator,CKEDITOR.NODE_ELEMENT,!0);h=d.toBeWrapped.pop();){var l=h[0],k=l.parent;k.type==CKEDITOR.NODE_ELEMENT&&k.attributes["data-cke-widget-wrapper"]&&k.replaceWith(l);a.wrapElement(h[0],h[1])}c=b.data.protectedWhitespaces?3==b.data.dataValue.children.length&&g.isParserWidgetWrapper(b.data.dataValue.children[1]):1==b.data.dataValue.children.length&&g.isParserWidgetWrapper(b.data.dataValue.children[0])},null,null,8);b.on("dataReady",function(){if(d)for(var c=b.editable().find(".cke_widget_wrapper"),
+f,h,l=0,k=c.count();l<k;++l)f=c.getItem(l),h=f.getFirst(g.isDomWidgetElement),h.type==CKEDITOR.NODE_ELEMENT&&h.data("widget")?(h.replace(f),a.wrapElement(h)):f.remove();d=0;a.destroyAll(!0);a.initOnAll()});b.on("loadSnapshot",function(b){/data-cke-widget/.test(b.data)&&(d=1);a.destroyAll(!0)},null,null,9);b.on("paste",function(a){a=a.data;a.dataValue=a.dataValue.replace(U,T);a.range&&(a=g.getNestedEditable(b.editable(),a.range.startContainer))&&(a=CKEDITOR.filter.instances[a.data("cke-filter")])&&
+b.setActiveFilter(a)});b.on("afterInsertHtml",function(d){d.data.intoRange?a.checkWidgets({initOnlyNew:!0}):(b.fire("lockSnapshot"),a.checkWidgets({initOnlyNew:!0,focusInited:c}),b.fire("unlockSnapshot"))})}function z(a){var b=a.selected,c=[],d=b.slice(0),e=null;return{select:function(a){0>CKEDITOR.tools.indexOf(b,a)&&c.push(a);a=CKEDITOR.tools.indexOf(d,a);0<=a&&d.splice(a,1);return this},focus:function(a){e=a;return this},commit:function(){var f=a.focused!==e,h,g;a.editor.fire("lockSnapshot");for(f&&
+(h=a.focused)&&t(a,h);h=d.pop();)b.splice(CKEDITOR.tools.indexOf(b,h),1),h.isInited()&&(g=h.editor.checkDirty(),h.setSelected(!1),!g&&h.editor.resetDirty());f&&e&&(g=a.editor.checkDirty(),a.focused=e,a.fire("widgetFocused",{widget:e}),e.setFocused(!0),!g&&a.editor.resetDirty());for(;h=c.pop();)b.push(h),h.setSelected(!0);a.editor.fire("unlockSnapshot")}}}function A(a,b,c){var d=0;b=B(b);var e=a.data.classes||{},f;if(b){for(e=CKEDITOR.tools.clone(e);f=b.pop();)c?e[f]||(d=e[f]=1):e[f]&&(delete e[f],
+d=1);d&&a.setData("classes",e)}}function C(a){a.cancel()}function y(a,b){var c=a.editor,d=c.document;if(!d.getById("cke_copybin")){var e=c.blockless||CKEDITOR.env.ie?"span":"div",f=d.createElement(e),h=d.createElement(e),e=CKEDITOR.env.ie&&9>CKEDITOR.env.version;h.setAttributes({id:"cke_copybin","data-cke-temp":"1"});f.setStyles({position:"absolute",width:"1px",height:"1px",overflow:"hidden"});f.setStyle("ltr"==c.config.contentsLangDirection?"left":"right","-5000px");var g=c.createRange();g.setStartBefore(a.wrapper);
+g.setEndAfter(a.wrapper);f.setHtml('\x3cspan data-cke-copybin-start\x3d"1"\x3e​\x3c/span\x3e'+c.editable().getHtmlFromRange(g).getHtml()+'\x3cspan data-cke-copybin-end\x3d"1"\x3e​\x3c/span\x3e');c.fire("saveSnapshot");c.fire("lockSnapshot");h.append(f);c.editable().append(h);var k=c.on("selectionChange",C,null,null,0),m=a.repository.on("checkSelection",C,null,null,0);if(e)var n=d.getDocumentElement().$,p=n.scrollTop;g=c.createRange();g.selectNodeContents(f);g.select();e&&(n.scrollTop=p);setTimeout(function(){b||
+a.focus();h.remove();k.removeListener();m.removeListener();c.fire("unlockSnapshot");b&&(a.repository.del(a),c.fire("saveSnapshot"))},100)}}function B(a){return(a=(a=a.getDefinition().attributes)&&a["class"])?a.split(/\s+/):null}function D(){var a=CKEDITOR.document.getActive(),b=this.editor,c=b.editable();(c.isInline()?c:b.document.getWindow().getFrame()).equals(a)&&b.focusManager.focus(c)}function E(){CKEDITOR.env.gecko&&this.editor.unlockSelection();CKEDITOR.env.webkit||(this.editor.forceNextSelectionCheck(),
+this.editor.selectionChange(1))}function V(a){var b=null;a.on("data",function(){var a=this.data.classes,d;if(b!=a){for(d in b)a&&a[d]||this.removeClass(d);for(d in a)this.addClass(d);b=a}})}function W(a){a.on("data",function(){if(a.wrapper){var b=this.getLabel?this.getLabel():this.editor.lang.widget.label.replace(/%1/,this.pathName||this.element.getName());a.wrapper.setAttribute("role","region");a.wrapper.setAttribute("aria-label",b)}},null,null,9999)}function X(a){if(a.draggable){var b=a.editor,
+c=a.wrapper.getLast(g.isDomDragHandlerContainer),d;c?d=c.findOne("img"):(c=new CKEDITOR.dom.element("span",b.document),c.setAttributes({"class":"cke_reset cke_widget_drag_handler_container",style:"background:rgba(220,220,220,0.5);background-image:url("+b.plugins.widget.path+"images/handle.png)"}),d=new CKEDITOR.dom.element("img",b.document),d.setAttributes({"class":"cke_reset cke_widget_drag_handler","data-cke-widget-drag-handler":"1",src:CKEDITOR.tools.transparentImageData,width:15,title:b.lang.widget.move,
+height:15,role:"presentation"}),a.inline&&d.setAttribute("draggable","true"),c.append(d),a.wrapper.append(c));a.wrapper.on("dragover",function(a){a.data.preventDefault()});a.wrapper.on("mouseenter",a.updateDragHandlerPosition,a);setTimeout(function(){a.on("data",a.updateDragHandlerPosition,a)},50);if(!a.inline&&(d.on("mousedown",Y,a),CKEDITOR.env.ie&&9>CKEDITOR.env.version))d.on("dragstart",function(a){a.data.preventDefault(!0)});a.dragHandlerContainer=c}}function Y(a){function b(){var b;for(q.reset();b=
+g.pop();)b.removeListener();var c=k;b=a.sender;var d=this.repository.finder,e=this.repository.liner,f=this.editor,h=this.editor.editable();CKEDITOR.tools.isEmpty(e.visible)||(c=d.getRange(c[0]),this.focus(),f.fire("drop",{dropRange:c,target:c.startContainer}));h.removeClass("cke_widget_dragging");e.hideVisible();f.fire("dragend",{target:b})}var c=this.repository.finder,d=this.repository.locator,e=this.repository.liner,f=this.editor,h=f.editable(),g=[],k=[],m,n;this.repository._.draggedWidget=this;
+var p=c.greedySearch(),q=CKEDITOR.tools.eventsBuffer(50,function(){m=d.locate(p);k=d.sort(n,1);k.length&&(e.prepare(p,m),e.placeLine(k[0]),e.cleanup())});h.addClass("cke_widget_dragging");g.push(h.on("mousemove",function(a){n=a.data.$.clientY;q.input()}));f.fire("dragstart",{target:a.sender});g.push(f.document.once("mouseup",b,this));h.isInline()||g.push(CKEDITOR.document.once("mouseup",b,this))}function Z(a){var b,c,d=a.editables;a.editables={};if(a.editables)for(b in d)c=d[b],a.initEditable(b,"string"==
+typeof c?{selector:c}:c)}function aa(a){if(a.mask){var b=a.wrapper.findOne(".cke_widget_mask");b||(b=new CKEDITOR.dom.element("img",a.editor.document),b.setAttributes({src:CKEDITOR.tools.transparentImageData,"class":"cke_reset cke_widget_mask"}),a.wrapper.append(b));a.mask=b}}function ba(a){if(a.parts){var b={},c,d;for(d in a.parts)c=a.wrapper.findOne(a.parts[d]),b[d]=c;a.parts=b}}function N(a,b){ca(a);ba(a);Z(a);aa(a);X(a);V(a);W(a);if(CKEDITOR.env.ie&&9>CKEDITOR.env.version)a.wrapper.on("dragstart",
+function(b){var d=b.data.getTarget();g.getNestedEditable(a,d)||a.inline&&g.isDomDragHandler(d)||b.data.preventDefault()});a.wrapper.removeClass("cke_widget_new");a.element.addClass("cke_widget_element");a.on("key",function(b){b=b.data.keyCode;if(13==b)a.edit();else{if(b==CKEDITOR.CTRL+67||b==CKEDITOR.CTRL+88){y(a,b==CKEDITOR.CTRL+88);return}if(b in da||CKEDITOR.CTRL&b||CKEDITOR.ALT&b)return}return!1},null,null,999);a.on("doubleclick",function(b){a.edit()&&b.cancel()});if(b.data)a.on("data",b.data);
+if(b.edit)a.on("edit",b.edit)}function ca(a){(a.wrapper=a.element.getParent()).setAttribute("data-cke-widget-id",a.id)}function r(a){a.element.data("cke-widget-data",encodeURIComponent(JSON.stringify(a.data)))}CKEDITOR.plugins.add("widget",{requires:"lineutils,clipboard,widgetselection",onLoad:function(){CKEDITOR.addCss(".cke_widget_wrapper{position:relative;outline:none}.cke_widget_inline{display:inline-block}.cke_widget_wrapper:hover\x3e.cke_widget_element{outline:2px solid yellow;cursor:default}.cke_widget_wrapper:hover .cke_widget_editable{outline:2px solid yellow}.cke_widget_wrapper.cke_widget_focused\x3e.cke_widget_element,.cke_widget_wrapper .cke_widget_editable.cke_widget_editable_focused{outline:2px solid #ace}.cke_widget_editable{cursor:text}.cke_widget_drag_handler_container{position:absolute;width:15px;height:0;display:none;opacity:0.75;transition:height 0s 0.2s;line-height:0}.cke_widget_wrapper:hover\x3e.cke_widget_drag_handler_container{height:15px;transition:none}.cke_widget_drag_handler_container:hover{opacity:1}img.cke_widget_drag_handler{cursor:move;width:15px;height:15px;display:inline-block}.cke_widget_mask{position:absolute;top:0;left:0;width:100%;height:100%;display:block}.cke_editable.cke_widget_dragging, .cke_editable.cke_widget_dragging *{cursor:move !important}")},
+beforeInit:function(a){a.widgets=new p(a)},afterInit:function(a){var b=a.widgets.registered,c,d,e;for(d in b)c=b[d],(e=c.button)&&a.ui.addButton&&a.ui.addButton(CKEDITOR.tools.capitalize(c.name,!0),{label:e,command:c.name,toolbar:"insert,10"});S(a)}});p.prototype={MIN_SELECTION_CHECK_INTERVAL:500,add:function(a,b){b=CKEDITOR.tools.prototypedCopy(b);b.name=a;b._=b._||{};this.editor.fire("widgetDefinition",b);b.template&&(b.template=new CKEDITOR.template(b.template));O(this.editor,b);P(this,b);return this.registered[a]=
+b},addUpcastCallback:function(a){this._.upcastCallbacks.push(a)},checkSelection:function(){var a=this.editor.getSelection(),b=a.getSelectedElement(),c=z(this),d;if(b&&(d=this.getByElement(b,!0)))return c.focus(d).select(d).commit();a=a.getRanges()[0];if(!a||a.collapsed)return c.commit();a=new CKEDITOR.dom.walker(a);for(a.evaluator=g.isDomWidgetWrapper;b=a.next();)c.select(this.getByElement(b));c.commit()},checkWidgets:function(a){this.fire("checkWidgets",CKEDITOR.tools.copy(a||{}))},del:function(a){if(this.focused===
+a){var b=a.editor,c=b.createRange(),d;(d=c.moveToClosestEditablePosition(a.wrapper,!0))||(d=c.moveToClosestEditablePosition(a.wrapper,!1));d&&b.getSelection().selectRanges([c])}a.wrapper.remove();this.destroy(a,!0)},destroy:function(a,b){this.widgetHoldingFocusedEditable===a&&n(this,a,null,b);a.destroy(b);delete this.instances[a.id];this.fire("instanceDestroyed",a)},destroyAll:function(a,b){var c,d,e=this.instances;if(b&&!a){d=b.find(".cke_widget_wrapper");for(var e=d.count(),f=0;f<e;++f)(c=this.getByElement(d.getItem(f),
+!0))&&this.destroy(c)}else for(d in e)c=e[d],this.destroy(c,a)},finalizeCreation:function(a){(a=a.getFirst())&&g.isDomWidgetWrapper(a)&&(this.editor.insertElement(a),a=this.getByElement(a),a.ready=!0,a.fire("ready"),a.focus())},getByElement:function(){function a(a){return a.is(b)&&a.data("cke-widget-id")}var b={div:1,span:1};return function(b,d){if(!b)return null;var e=a(b);if(!d&&!e){var f=this.editor.editable();do b=b.getParent();while(b&&!b.equals(f)&&!(e=a(b)))}return this.instances[e]||null}}(),
+initOn:function(a,b,c){b?"string"==typeof b&&(b=this.registered[b]):b=this.registered[a.data("widget")];if(!b)return null;var d=this.wrapElement(a,b.name);return d?d.hasClass("cke_widget_new")?(a=new g(this,this._.nextId++,a,b,c),a.isInited()?this.instances[a.id]=a:null):this.getByElement(a):null},initOnAll:function(a){a=(a||this.editor.editable()).find(".cke_widget_new");for(var b=[],c,d=a.count();d--;)(c=this.initOn(a.getItem(d).getFirst(g.isDomWidgetElement)))&&b.push(c);return b},onWidget:function(a){var b=
+Array.prototype.slice.call(arguments);b.shift();for(var c in this.instances){var d=this.instances[c];d.name==a&&d.on.apply(d,b)}this.on("instanceCreated",function(d){d=d.data;d.name==a&&d.on.apply(d,b)})},parseElementClasses:function(a){if(!a)return null;a=CKEDITOR.tools.trim(a).split(/\s+/);for(var b,c={},d=0;b=a.pop();)-1==b.indexOf("cke_")&&(c[b]=d=1);return d?c:null},wrapElement:function(a,b){var c=null,d,e;if(a instanceof CKEDITOR.dom.element){b=b||a.data("widget");d=this.registered[b];if(!d)return null;
+if((c=a.getParent())&&c.type==CKEDITOR.NODE_ELEMENT&&c.data("cke-widget-wrapper"))return c;a.hasAttribute("data-cke-widget-keep-attr")||a.data("cke-widget-keep-attr",a.data("widget")?1:0);a.data("widget",b);e=x(d,a.getName());c=new CKEDITOR.dom.element(e?"span":"div");c.setAttributes(v(e,b));c.data("cke-display-name",d.pathName?d.pathName:a.getName());a.getParent(!0)&&c.replace(a);a.appendTo(c)}else if(a instanceof CKEDITOR.htmlParser.element){b=b||a.attributes["data-widget"];d=this.registered[b];
+if(!d)return null;if((c=a.parent)&&c.type==CKEDITOR.NODE_ELEMENT&&c.attributes["data-cke-widget-wrapper"])return c;"data-cke-widget-keep-attr"in a.attributes||(a.attributes["data-cke-widget-keep-attr"]=a.attributes["data-widget"]?1:0);b&&(a.attributes["data-widget"]=b);e=x(d,a.name);c=new CKEDITOR.htmlParser.element(e?"span":"div",v(e,b));c.attributes["data-cke-display-name"]=d.pathName?d.pathName:a.name;d=a.parent;var f;d&&(f=a.getIndex(),a.remove());c.add(a);d&&w(d,f,c)}return c},_tests_createEditableFilter:u};
+CKEDITOR.event.implementOn(p.prototype);g.prototype={addClass:function(a){this.element.addClass(a);this.wrapper.addClass(g.WRAPPER_CLASS_PREFIX+a)},applyStyle:function(a){A(this,a,1)},checkStyleActive:function(a){a=B(a);var b;if(!a)return!1;for(;b=a.pop();)if(!this.hasClass(b))return!1;return!0},destroy:function(a){this.fire("destroy");if(this.editables)for(var b in this.editables)this.destroyEditable(b,a);a||("0"==this.element.data("cke-widget-keep-attr")&&this.element.removeAttribute("data-widget"),
+this.element.removeAttributes(["data-cke-widget-data","data-cke-widget-keep-attr"]),this.element.removeClass("cke_widget_element"),this.element.replace(this.wrapper));this.wrapper=null},destroyEditable:function(a,b){var c=this.editables[a];c.removeListener("focus",E);c.removeListener("blur",D);this.editor.focusManager.remove(c);b||(this.repository.destroyAll(!1,c),c.removeClass("cke_widget_editable"),c.removeClass("cke_widget_editable_focused"),c.removeAttributes(["contenteditable","data-cke-widget-editable",
+"data-cke-enter-mode"]));delete this.editables[a]},edit:function(){var a={dialog:this.dialog},b=this;if(!1===this.fire("edit",a)||!a.dialog)return!1;this.editor.openDialog(a.dialog,function(a){var d,e;!1!==b.fire("dialog",a)&&(d=a.on("show",function(){a.setupContent(b)}),e=a.on("ok",function(){var d,e=b.on("data",function(a){d=1;a.cancel()},null,null,0);b.editor.fire("saveSnapshot");a.commitContent(b);e.removeListener();d&&(b.fire("data",b.data),b.editor.fire("saveSnapshot"))}),a.once("hide",function(){d.removeListener();
+e.removeListener()}))});return!0},getClasses:function(){return this.repository.parseElementClasses(this.element.getAttribute("class"))},hasClass:function(a){return this.element.hasClass(a)},initEditable:function(a,b){var c=this._findOneNotNested(b.selector);return c&&c.is(CKEDITOR.dtd.$editable)?(c=new q(this.editor,c,{filter:u.call(this.repository,this.name,a,b)}),this.editables[a]=c,c.setAttributes({contenteditable:"true","data-cke-widget-editable":a,"data-cke-enter-mode":c.enterMode}),c.filter&&
+c.data("cke-filter",c.filter.id),c.addClass("cke_widget_editable"),c.removeClass("cke_widget_editable_focused"),b.pathName&&c.data("cke-display-name",b.pathName),this.editor.focusManager.add(c),c.on("focus",E,this),CKEDITOR.env.ie&&c.on("blur",D,this),c._.initialSetData=!0,c.setData(c.getHtml()),!0):!1},_findOneNotNested:function(a){a=this.wrapper.find(a);for(var b,c,d=0;d<a.count();d++)if(b=a.getItem(d),c=b.getAscendant(g.isDomWidgetWrapper),this.wrapper.equals(c))return b;return null},isInited:function(){return!(!this.wrapper||
+!this.inited)},isReady:function(){return this.isInited()&&this.ready},focus:function(){var a=this.editor.getSelection();if(a){var b=this.editor.checkDirty();a.fake(this.wrapper);!b&&this.editor.resetDirty()}this.editor.focus()},removeClass:function(a){this.element.removeClass(a);this.wrapper.removeClass(g.WRAPPER_CLASS_PREFIX+a)},removeStyle:function(a){A(this,a,0)},setData:function(a,b){var c=this.data,d=0;if("string"==typeof a)c[a]!==b&&(c[a]=b,d=1);else{var e=a;for(a in e)c[a]!==e[a]&&(d=1,c[a]=
+e[a])}d&&this.dataReady&&(r(this),this.fire("data",c));return this},setFocused:function(a){this.wrapper[a?"addClass":"removeClass"]("cke_widget_focused");this.fire(a?"focus":"blur");return this},setSelected:function(a){this.wrapper[a?"addClass":"removeClass"]("cke_widget_selected");this.fire(a?"select":"deselect");return this},updateDragHandlerPosition:function(){var a=this.editor,b=this.element.$,c=this._.dragHandlerOffset,b={x:b.offsetLeft,y:b.offsetTop-15};c&&b.x==c.x&&b.y==c.y||(c=a.checkDirty(),
+a.fire("lockSnapshot"),this.dragHandlerContainer.setStyles({top:b.y+"px",left:b.x+"px",display:"block"}),a.fire("unlockSnapshot"),!c&&a.resetDirty(),this._.dragHandlerOffset=b)}};CKEDITOR.event.implementOn(g.prototype);g.getNestedEditable=function(a,b){return!b||b.equals(a)?null:g.isDomNestedEditable(b)?b:g.getNestedEditable(a,b.getParent())};g.isDomDragHandler=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute("data-cke-widget-drag-handler")};g.isDomDragHandlerContainer=function(a){return a.type==
+CKEDITOR.NODE_ELEMENT&&a.hasClass("cke_widget_drag_handler_container")};g.isDomNestedEditable=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute("data-cke-widget-editable")};g.isDomWidgetElement=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute("data-widget")};g.isDomWidgetWrapper=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&a.hasAttribute("data-cke-widget-wrapper")};g.isParserWidgetElement=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&!!a.attributes["data-widget"]};
+g.isParserWidgetWrapper=function(a){return a.type==CKEDITOR.NODE_ELEMENT&&!!a.attributes["data-cke-widget-wrapper"]};g.WRAPPER_CLASS_PREFIX="cke_widget_wrapper_";q.prototype=CKEDITOR.tools.extend(CKEDITOR.tools.prototypedCopy(CKEDITOR.dom.element.prototype),{setData:function(a){this._.initialSetData||this.editor.widgets.destroyAll(!1,this);this._.initialSetData=!1;a=this.editor.dataProcessor.toHtml(a,{context:this.getName(),filter:this.filter,enterMode:this.enterMode});this.setHtml(a);this.editor.widgets.initOnAll(this)},
+getData:function(){return this.editor.dataProcessor.toDataFormat(this.getHtml(),{context:this.getName(),filter:this.filter,enterMode:this.enterMode})}});var U=/^(?:<(?:div|span)(?: data-cke-temp="1")?(?: id="cke_copybin")?(?: data-cke-temp="1")?>)?(?:<(?:div|span)(?: style="[^"]+")?>)?<span [^>]*data-cke-copybin-start="1"[^>]*>.?<\/span>([\s\S]+)<span [^>]*data-cke-copybin-end="1"[^>]*>.?<\/span>(?:<\/(?:div|span)>)?(?:<\/(?:div|span)>)?$/i,da={37:1,38:1,39:1,40:1,8:1,46:1};(function(){function a(){}
+function b(a,b,c){return c&&this.checkElement(a)?(a=c.widgets.getByElement(a,!0))&&a.checkStyleActive(this):!1}var c={};CKEDITOR.style.addCustomHandler({type:"widget",setup:function(a){this.widget=a.widget;if(this.group="string"==typeof a.group?[a.group]:a.group){a=this.widget;var b;c[a]||(c[a]={});for(var f=0,h=this.group.length;f<h;f++)b=this.group[f],c[a][b]||(c[a][b]=[]),c[a][b].push(this)}},apply:function(a){var b;a instanceof CKEDITOR.editor&&this.checkApplicable(a.elementPath(),a)&&(b=a.widgets.focused,
+this.group&&this.removeStylesFromSameGroup(a),b.applyStyle(this))},remove:function(a){a instanceof CKEDITOR.editor&&this.checkApplicable(a.elementPath(),a)&&a.widgets.focused.removeStyle(this)},removeStylesFromSameGroup:function(a){var b,f,h=!1;if(!(a instanceof CKEDITOR.editor))return!1;f=a.elementPath();if(this.checkApplicable(f,a))for(var g=0,k=this.group.length;g<k;g++){b=c[this.widget][this.group[g]];for(var m=0;m<b.length;m++)b[m]!==this&&b[m].checkActive(f,a)&&(a.widgets.focused.removeStyle(b[m]),
+h=!0)}return h},checkActive:function(a,b){return this.checkElementMatch(a.lastElement,0,b)},checkApplicable:function(a,b){return b instanceof CKEDITOR.editor?this.checkElement(a.lastElement):!1},checkElementMatch:b,checkElementRemovable:b,checkElement:function(a){return g.isDomWidgetWrapper(a)?(a=a.getFirst(g.isDomWidgetElement))&&a.data("widget")==this.widget:!1},buildPreview:function(a){return a||this._.definition.name},toAllowedContentRules:function(a){if(!a)return null;a=a.widgets.registered[this.widget];
+var b,c={};if(!a)return null;if(a.styleableElements){b=this.getClassesArray();if(!b)return null;c[a.styleableElements]={classes:b,propertiesOnly:!0};return c}return a.styleToAllowedContentRules?a.styleToAllowedContentRules(this):null},getClassesArray:function(){var a=this._.definition.attributes&&this._.definition.attributes["class"];return a?CKEDITOR.tools.trim(a).split(/\s+/):null},applyToRange:a,removeFromRange:a,applyToObject:a})})();CKEDITOR.plugins.widget=g;g.repository=p;g.nestedEditable=q})();(function(){CKEDITOR.plugins.add("oembed",{icons:"oembed",hidpi:!0,requires:"widget,dialog",version:1.17,init:function(e){function l(a,d,c,f,g,j,h,b){jQuery("body").oembed(a,{onEmbed:function(d){var g=jQuery.fn.oembed.getOEmbedProvider(a);b.element.data("resizeType",j);if("responsive"==j||"custom"==j)b.element.data("maxWidth",c),b.element.data("maxHeight",f);b.element.data("align",h);"center"==h?(b.inline||b.element.setStyle("text-align","center"),b.element.removeStyle("float")):(b.inline||b.element.removeStyle("text-align"),
+"none"==h?b.element.removeStyle("float"):b.element.setStyle("float",h));"string"===typeof d.code?(b.element.$.firstChild&&b.element.$.removeChild(b.element.$.firstChild),b.element.appendHtml(d.code),b.element.data("oembed",a),b.element.data("oembed_provider",g.name),b.element.addClass("oembed-provider-"+g.name)):"string"===typeof d.code[0].outerHTML?(b.element.$.firstChild&&b.element.$.removeChild(b.element.$.firstChild),b.element.appendHtml(d.code[0].outerHTML),b.element.data("oembed",a),b.element.data("oembed_provider",
+g.name),b.element.addClass("oembed-provider-"+g.name)):alert(e.lang.oembed.noEmbedCode)},onError:function(a){0<a.indexOf("vimeo.com")?alert(e.lang.oembed.noVimeo):alert(e.lang.oembed.Error)},maxHeight:f,maxWidth:c,useResponsiveResize:g,embedMethod:"editor"})}(function(){"undefined"===typeof jQuery?CKEDITOR.scriptLoader.load("//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js",function(){jQuery.noConflict();"undefined"===typeof jQuery.fn.oembed&&CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath("oembed")+
+"libs/jquery.oembed.min.js"))}):"undefined"===typeof jQuery.fn.oembed&&CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath("oembed")+"libs/jquery.oembed.min.js"))})();CKEDITOR.tools.extend(CKEDITOR.editor.prototype,{oEmbed:function(a,d,c,f){function g(){if(null==d||"undefined"==d)d=null;if(null==c||"undefined"==c)c=null;if(null==f||"undefined"==f)f=!1;l(a,e,!1,d,c,f)}if(1>a.length||0>a.indexOf("http"))return alert(e.lang.oembed.invalidUrl),!1;"undefined"===typeof jQuery.fn.oembed?
+CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath("oembed")+"libs/jquery.oembed.min.js"),function(){g()}):g();return!0}});e.widgets.add("oembed",{draggable:!1,mask:!0,dialog:"oembed",allowedContent:{div:{styles:"text-align,float",attributes:"*",classes:null!=e.config.oembed_WrapperClass?e.config.oembed_WrapperClass:"embeddedContent"},"div(embeddedContent,oembed-provider-*) iframe":{attributes:"*"},"div(embeddedContent,oembed-provider-*) blockquote":{attributes:"*"},"div(embeddedContent,oembed-provider-*) script":{attributes:"*"}},
+template:'<div class="'+(null!=e.config.oembed_WrapperClass?e.config.oembed_WrapperClass:"embeddedContent")+'"></div>',upcast:function(a){return"div"==a.name&&a.hasClass(null!=e.config.oembed_WrapperClass?e.config.oembed_WrapperClass:"embeddedContent")},init:function(){var a={oembed:this.element.data("oembed")||"",resizeType:this.element.data("resizeType")||"noresize",maxWidth:this.element.data("maxWidth")||560,maxHeight:this.element.data("maxHeight")||315,align:this.element.data("align")||"none",
+oembed_provider:this.element.data("oembed_provider")||""};this.setData(a);this.element.addClass("oembed-provider-"+a.oembed_provider);this.on("dialog",function(a){a.data.widget=this},this)}});e.ui.addButton("oembed",{label:e.lang.oembed.button,command:"oembed",toolbar:"insert,10",icon:this.path+"icons/"+(CKEDITOR.env.hidpi?"hidpi/":"")+"oembed.png"});var k=function(){var a=this.getDialog(),d=this.getValue(),c=a.getContentElement("general","maxSizeBox").getElement(),a=a.getContentElement("general",
+"sizeBox").getElement();"noresize"==d?(c.hide(),a.hide()):"custom"==d?(c.hide(),a.show()):(c.show(),a.hide())};String.prototype.beginsWith=function(a){return 0===this.indexOf(a)};CKEDITOR.dialog.add("oembed",function(a){return{title:a.lang.oembed.title,minWidth:CKEDITOR.env.ie&&CKEDITOR.env.quirks?568:550,minHeight:155,onShow:function(){var a={oembed:this.widget.element.data("oembed")||"",resizeType:this.widget.element.data("resizeType")||"noresize",maxWidth:this.widget.element.data("maxWidth"),maxHeight:this.widget.element.data("maxHeight"),
+align:this.widget.element.data("align")||"none"};this.widget.setData(a);this.getContentElement("general","resizeType").setValue(a.resizeType);this.getContentElement("general","align").setValue(a.align);var a=this.getContentElement("general","resizeType").getValue(),c=this.getContentElement("general","maxSizeBox").getElement(),f=this.getContentElement("general","sizeBox").getElement();"noresize"==a?(c.hide(),f.hide()):"custom"==a?(c.hide(),f.show()):(c.show(),f.hide())},onOk:function(){},contents:[{label:a.lang.common.generalTab,
+id:"general",elements:[{type:"html",id:"oembedHeader",html:'<div style="white-space:normal;width:500px;padding-bottom:10px">'+a.lang.oembed.pasteUrl+"</div>"},{type:"text",id:"embedCode",focus:function(){this.getElement().focus()},label:a.lang.oembed.url,title:a.lang.oembed.pasteUrl,setup:function(a){a.data.oembed&&this.setValue(a.data.oembed)},commit:function(d){var c=CKEDITOR.dialog.getCurrent(),f=c.getValueOf("general","embedCode").replace(/\s/g,""),g=c.getContentElement("general","resizeType").getValue(),
+e=c.getContentElement("general","align").getValue(),h=null,b=null,i=!1,k=c.getParentEditor();if(1>f.length||0>f.indexOf("http"))return alert(a.lang.oembed.invalidUrl),!1;"noresize"==g?(i=!1,b=h=null):"responsive"==g?(h=c.getContentElement("general","maxWidth").getInputElement().getValue(),b=c.getContentElement("general","maxHeight").getInputElement().getValue(),i=!0):"custom"==g&&(h=c.getContentElement("general","width").getInputElement().getValue(),b=c.getContentElement("general","height").getInputElement().getValue(),
+i=!1);l(f,k,h,b,i,g,e,d);d.setData("oembed",f);d.setData("resizeType",g);d.setData("align",e);d.setData("maxWidth",h);d.setData("maxHeight",b)}},{type:"hbox",widths:["50%","50%"],children:[{id:"resizeType",type:"select",label:a.lang.oembed.resizeType,"default":"noresize",setup:function(a){a.data.resizeType&&this.setValue(a.data.resizeType)},items:[[a.lang.oembed.noresize,"noresize"],[a.lang.oembed.responsive,"responsive"],[a.lang.oembed.custom,"custom"]],onChange:k},{type:"hbox",id:"maxSizeBox",widths:["120px",
+"120px"],style:"float:left;position:absolute;left:58%;width:200px",children:[{type:"text",width:"100px",id:"maxWidth","default":null!=a.config.oembed_maxWidth?a.config.oembed_maxWidth:"560",label:a.lang.oembed.maxWidth,title:a.lang.oembed.maxWidthTitle,setup:function(a){a.data.maxWidth&&this.setValue(a.data.maxWidth)}},{type:"text",id:"maxHeight",width:"120px","default":null!=a.config.oembed_maxHeight?a.config.oembed_maxHeight:"315",label:a.lang.oembed.maxHeight,title:a.lang.oembed.maxHeightTitle,
+setup:function(a){a.data.maxHeight&&this.setValue(a.data.maxHeight)}}]},{type:"hbox",id:"sizeBox",widths:["120px","120px"],style:"float:left;position:absolute;left:58%;width:200px",children:[{type:"text",id:"width",width:"100px","default":null!=a.config.oembed_maxWidth?a.config.oembed_maxWidth:"560",label:a.lang.oembed.width,title:a.lang.oembed.widthTitle,setup:function(a){a.data.maxWidth&&this.setValue(a.data.maxWidth)}},{type:"text",id:"height",width:"120px","default":null!=a.config.oembed_maxHeight?
+a.config.oembed_maxHeight:"315",label:a.lang.oembed.height,title:a.lang.oembed.heightTitle,setup:function(a){a.data.maxHeight&&this.setValue(a.data.maxHeight)}}]}]},{type:"hbox",id:"alignment",children:[{id:"align",type:"radio",items:[[a.lang.oembed.none,"none"],[a.lang.common.alignLeft,"left"],[a.lang.common.alignCenter,"center"],[a.lang.common.alignRight,"right"]],label:a.lang.common.align,setup:function(a){this.setValue(a.data.align)}}]}]}]}})}})})();CKEDITOR.config.plugins='dialogui,dialog,a11yhelp,dialogadvtab,basicstyles,panel,floatpanel,menu,contextmenu,resize,button,toolbar,elementspath,enterkey,entities,popup,filebrowser,floatingspace,listblock,richcombo,format,horizontalrule,htmlwriter,fakeobjects,iframe,wysiwygarea,image,indent,indentblock,indentlist,justify,link,list,liststyle,magicline,maximize,removeformat,showborders,sourcearea,tab,lineutils,clipboard,widgetselection,widget,oembed';CKEDITOR.config.skin='moono';(function() {var setIcons = function(icons, strip) {var path = CKEDITOR.getUrl( 'plugins/' + strip );icons = icons.split( ',' );for ( var i = 0; i < icons.length; i++ )CKEDITOR.skin.icons[ icons[ i ] ] = { path: path, offset: -icons[ ++i ], bgsize : icons[ ++i ] };};if (CKEDITOR.env.hidpi) setIcons('bold,0,,italic,24,,strike,48,,subscript,72,,superscript,96,,underline,120,,horizontalrule,144,,iframe,168,,image,192,,indent-rtl,216,,indent,240,,outdent-rtl,264,,outdent,288,,justifyblock,312,,justifycenter,336,,justifyleft,360,,justifyright,384,,anchor-rtl,408,,anchor,432,,link,456,,unlink,480,,bulletedlist-rtl,504,,bulletedlist,528,,numberedlist-rtl,552,,numberedlist,576,,maximize,600,,removeformat,624,,source-rtl,648,,source,672,,copy-rtl,696,,copy,720,,cut-rtl,744,,cut,768,,paste-rtl,792,,paste,816,,oembed,840,','icons_hidpi.png');else setIcons('bold,0,auto,italic,24,auto,strike,48,auto,subscript,72,auto,superscript,96,auto,underline,120,auto,horizontalrule,144,auto,iframe,168,auto,image,192,auto,indent-rtl,216,auto,indent,240,auto,outdent-rtl,264,auto,outdent,288,auto,justifyblock,312,auto,justifycenter,336,auto,justifyleft,360,auto,justifyright,384,auto,anchor-rtl,408,auto,anchor,432,auto,link,456,auto,unlink,480,auto,bulletedlist-rtl,504,auto,bulletedlist,528,auto,numberedlist-rtl,552,auto,numberedlist,576,auto,maximize,600,auto,removeformat,624,auto,source-rtl,648,auto,source,672,auto,copy-rtl,696,auto,copy,720,auto,cut-rtl,744,auto,cut,768,auto,paste-rtl,792,auto,paste,816,auto,oembed,840,auto','icons.png');})();CKEDITOR.lang.languages={"en":1,"fr":1};}());
\ No newline at end of file
diff --git a/release/config.js b/release/config.js
new file mode 100644 (file)
index 0000000..01a391a
--- /dev/null
@@ -0,0 +1,10 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.editorConfig = function( config ) {
+       // Define changes to default configuration here. For example:
+       // config.language = 'fr';
+       // config.uiColor = '#AADC6E';
+};
diff --git a/release/contents.css b/release/contents.css
new file mode 100644 (file)
index 0000000..920f2ca
--- /dev/null
@@ -0,0 +1,208 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+body\r
+{\r
+       /* Font */\r
+       font-family: sans-serif, Arial, Verdana, "Trebuchet MS";\r
+       font-size: 12px;\r
+\r
+       /* Text color */\r
+       color: #333;\r
+\r
+       /* Remove the background color to make it transparent */\r
+       background-color: #fff;\r
+\r
+       margin: 20px;\r
+}\r
+\r
+.cke_editable\r
+{\r
+       font-size: 13px;\r
+       line-height: 1.6;\r
+\r
+       /* Fix for missing scrollbars with RTL texts. (#10488) */\r
+       word-wrap: break-word;\r
+}\r
+\r
+blockquote\r
+{\r
+       font-style: italic;\r
+       font-family: Georgia, Times, "Times New Roman", serif;\r
+       padding: 2px 0;\r
+       border-style: solid;\r
+       border-color: #ccc;\r
+       border-width: 0;\r
+}\r
+\r
+.cke_contents_ltr blockquote\r
+{\r
+       padding-left: 20px;\r
+       padding-right: 8px;\r
+       border-left-width: 5px;\r
+}\r
+\r
+.cke_contents_rtl blockquote\r
+{\r
+       padding-left: 8px;\r
+       padding-right: 20px;\r
+       border-right-width: 5px;\r
+}\r
+\r
+a\r
+{\r
+       color: #0782C1;\r
+}\r
+\r
+ol,ul,dl\r
+{\r
+       /* IE7: reset rtl list margin. (#7334) */\r
+       *margin-right: 0px;\r
+       /* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/\r
+       padding: 0 40px;\r
+}\r
+\r
+h1,h2,h3,h4,h5,h6\r
+{\r
+       font-weight: normal;\r
+       line-height: 1.2;\r
+}\r
+\r
+hr\r
+{\r
+       border: 0px;\r
+       border-top: 1px solid #ccc;\r
+}\r
+\r
+img.right\r
+{\r
+       border: 1px solid #ccc;\r
+       float: right;\r
+       margin-left: 15px;\r
+       padding: 5px;\r
+}\r
+\r
+img.left\r
+{\r
+       border: 1px solid #ccc;\r
+       float: left;\r
+       margin-right: 15px;\r
+       padding: 5px;\r
+}\r
+\r
+pre\r
+{\r
+       white-space: pre-wrap; /* CSS 2.1 */\r
+       word-wrap: break-word; /* IE7 */\r
+       -moz-tab-size: 4;\r
+       tab-size: 4;\r
+}\r
+\r
+.marker\r
+{\r
+       background-color: Yellow;\r
+}\r
+\r
+span[lang]\r
+{\r
+       font-style: italic;\r
+}\r
+\r
+figure\r
+{\r
+       text-align: center;\r
+       border: solid 1px #ccc;\r
+       border-radius: 2px;\r
+       background: rgba(0,0,0,0.05);\r
+       padding: 10px;\r
+       margin: 10px 20px;\r
+       display: inline-block;\r
+}\r
+\r
+figure > figcaption\r
+{\r
+       text-align: center;\r
+       display: block; /* For IE8 */\r
+}\r
+\r
+a > img {\r
+       padding: 1px;\r
+       margin: 1px;\r
+       border: none;\r
+       outline: 1px solid #0782C1;\r
+}\r
+\r
+/* Widget Styles */\r
+.code-featured\r
+{\r
+       border: 5px solid red;\r
+}\r
+\r
+.math-featured\r
+{\r
+       padding: 20px;\r
+       box-shadow: 0 0 2px rgba(200, 0, 0, 1);\r
+       background-color: rgba(255, 0, 0, 0.05);\r
+       margin: 10px;\r
+}\r
+\r
+.image-clean\r
+{\r
+       border: 0;\r
+       background: none;\r
+       padding: 0;\r
+}\r
+\r
+.image-clean > figcaption\r
+{\r
+       font-size: .9em;\r
+       text-align: right;\r
+}\r
+\r
+.image-grayscale\r
+{\r
+       background-color: white;\r
+       color: #666;\r
+}\r
+\r
+.image-grayscale img, img.image-grayscale\r
+{\r
+       filter: grayscale(100%);\r
+}\r
+\r
+.embed-240p\r
+{\r
+       max-width: 426px;\r
+       max-height: 240px;\r
+       margin:0 auto;\r
+}\r
+\r
+.embed-360p\r
+{\r
+       max-width: 640px;\r
+       max-height: 360px;\r
+       margin:0 auto;\r
+}\r
+\r
+.embed-480p\r
+{\r
+       max-width: 854px;\r
+       max-height: 480px;\r
+       margin:0 auto;\r
+}\r
+\r
+.embed-720p\r
+{\r
+       max-width: 1280px;\r
+       max-height: 720px;\r
+       margin:0 auto;\r
+}\r
+\r
+.embed-1080p\r
+{\r
+       max-width: 1920px;\r
+       max-height: 1080px;\r
+       margin:0 auto;\r
+}\r
diff --git a/release/lang/en.js b/release/lang/en.js
new file mode 100644 (file)
index 0000000..509a5f6
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/
+CKEDITOR.lang['en']={"editor":"Rich Text Editor","editorPanel":"Rich Text Editor panel","common":{"editorHelp":"Press ALT 0 for help","browseServer":"Browse Server","url":"URL","protocol":"Protocol","upload":"Upload","uploadSubmit":"Send it to the Server","image":"Image","flash":"Flash","form":"Form","checkbox":"Checkbox","radio":"Radio Button","textField":"Text Field","textarea":"Textarea","hiddenField":"Hidden Field","button":"Button","select":"Selection Field","imageButton":"Image Button","notSet":"<not set>","id":"Id","name":"Name","langDir":"Language Direction","langDirLtr":"Left to Right (LTR)","langDirRtl":"Right to Left (RTL)","langCode":"Language Code","longDescr":"Long Description URL","cssClass":"Stylesheet Classes","advisoryTitle":"Advisory Title","cssStyle":"Style","ok":"OK","cancel":"Cancel","close":"Close","preview":"Preview","resize":"Resize","generalTab":"General","advancedTab":"Advanced","validateNumberFailed":"This value is not a number.","confirmNewPage":"Any unsaved changes to this content will be lost. Are you sure you want to load new page?","confirmCancel":"You have changed some options. Are you sure you want to close the dialog window?","options":"Options","target":"Target","targetNew":"New Window (_blank)","targetTop":"Topmost Window (_top)","targetSelf":"Same Window (_self)","targetParent":"Parent Window (_parent)","langDirLTR":"Left to Right (LTR)","langDirRTL":"Right to Left (RTL)","styles":"Style","cssClasses":"Stylesheet Classes","width":"Width","height":"Height","align":"Alignment","alignLeft":"Left","alignRight":"Right","alignCenter":"Center","alignJustify":"Justify","alignTop":"Top","alignMiddle":"Middle","alignBottom":"Bottom","alignNone":"None","invalidValue":"Invalid value.","invalidHeight":"Height must be a number.","invalidWidth":"Width must be a number.","invalidCssLength":"Value specified for the \"%1\" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).","invalidHtmlLength":"Value specified for the \"%1\" field must be a positive number with or without a valid HTML measurement unit (px or %).","invalidInlineStyle":"Value specified for the inline style must consist of one or more tuples with the format of \"name : value\", separated by semi-colons.","cssLengthTooltip":"Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).","unavailable":"%1<span class=\"cke_accessibility\">, unavailable</span>","keyboard":{"8":"Backspace","13":"Enter","16":"Shift","17":"Ctrl","18":"Alt","32":"Space","35":"End","36":"Home","46":"Delete","224":"Command"},"keyboardShortcut":"Keyboard shortcut"},"basicstyles":{"bold":"Bold","italic":"Italic","strike":"Strikethrough","subscript":"Subscript","superscript":"Superscript","underline":"Underline"},"contextmenu":{"options":"Context Menu Options"},"button":{"selectedLabel":"%1 (Selected)"},"toolbar":{"toolbarCollapse":"Collapse Toolbar","toolbarExpand":"Expand Toolbar","toolbarGroups":{"document":"Document","clipboard":"Clipboard/Undo","editing":"Editing","forms":"Forms","basicstyles":"Basic Styles","paragraph":"Paragraph","links":"Links","insert":"Insert","styles":"Styles","colors":"Colors","tools":"Tools"},"toolbars":"Editor toolbars"},"elementspath":{"eleLabel":"Elements path","eleTitle":"%1 element"},"format":{"label":"Format","panelTitle":"Paragraph Format","tag_address":"Address","tag_div":"Normal (DIV)","tag_h1":"Heading 1","tag_h2":"Heading 2","tag_h3":"Heading 3","tag_h4":"Heading 4","tag_h5":"Heading 5","tag_h6":"Heading 6","tag_p":"Normal","tag_pre":"Formatted"},"horizontalrule":{"toolbar":"Insert Horizontal Line"},"fakeobjects":{"anchor":"Anchor","flash":"Flash Animation","hiddenfield":"Hidden Field","iframe":"IFrame","unknown":"Unknown Object"},"iframe":{"border":"Show frame border","noUrl":"Please type the iframe URL","scrolling":"Enable scrollbars","title":"IFrame Properties","toolbar":"IFrame"},"image":{"alt":"Alternative Text","border":"Border","btnUpload":"Send it to the Server","button2Img":"Do you want to transform the selected image button on a simple image?","hSpace":"HSpace","img2Button":"Do you want to transform the selected image on a image button?","infoTab":"Image Info","linkTab":"Link","lockRatio":"Lock Ratio","menu":"Image Properties","resetSize":"Reset Size","title":"Image Properties","titleButton":"Image Button Properties","upload":"Upload","urlMissing":"Image source URL is missing.","vSpace":"VSpace","validateBorder":"Border must be a whole number.","validateHSpace":"HSpace must be a whole number.","validateVSpace":"VSpace must be a whole number."},"indent":{"indent":"Increase Indent","outdent":"Decrease Indent"},"justify":{"block":"Justify","center":"Center","left":"Align Left","right":"Align Right"},"link":{"acccessKey":"Access Key","advanced":"Advanced","advisoryContentType":"Advisory Content Type","advisoryTitle":"Advisory Title","anchor":{"toolbar":"Anchor","menu":"Edit Anchor","title":"Anchor Properties","name":"Anchor Name","errorName":"Please type the anchor name","remove":"Remove Anchor"},"anchorId":"By Element Id","anchorName":"By Anchor Name","charset":"Linked Resource Charset","cssClasses":"Stylesheet Classes","download":"Force Download","displayText":"Display Text","emailAddress":"E-Mail Address","emailBody":"Message Body","emailSubject":"Message Subject","id":"Id","info":"Link Info","langCode":"Language Code","langDir":"Language Direction","langDirLTR":"Left to Right (LTR)","langDirRTL":"Right to Left (RTL)","menu":"Edit Link","name":"Name","noAnchors":"(No anchors available in the document)","noEmail":"Please type the e-mail address","noUrl":"Please type the link URL","other":"<other>","popupDependent":"Dependent (Netscape)","popupFeatures":"Popup Window Features","popupFullScreen":"Full Screen (IE)","popupLeft":"Left Position","popupLocationBar":"Location Bar","popupMenuBar":"Menu Bar","popupResizable":"Resizable","popupScrollBars":"Scroll Bars","popupStatusBar":"Status Bar","popupToolbar":"Toolbar","popupTop":"Top Position","rel":"Relationship","selectAnchor":"Select an Anchor","styles":"Style","tabIndex":"Tab Index","target":"Target","targetFrame":"<frame>","targetFrameName":"Target Frame Name","targetPopup":"<popup window>","targetPopupName":"Popup Window Name","title":"Link","toAnchor":"Link to anchor in the text","toEmail":"E-mail","toUrl":"URL","toolbar":"Link","type":"Link Type","unlink":"Unlink","upload":"Upload"},"list":{"bulletedlist":"Insert/Remove Bulleted List","numberedlist":"Insert/Remove Numbered List"},"liststyle":{"armenian":"Armenian numbering","bulletedTitle":"Bulleted List Properties","circle":"Circle","decimal":"Decimal (1, 2, 3, etc.)","decimalLeadingZero":"Decimal leading zero (01, 02, 03, etc.)","disc":"Disc","georgian":"Georgian numbering (an, ban, gan, etc.)","lowerAlpha":"Lower Alpha (a, b, c, d, e, etc.)","lowerGreek":"Lower Greek (alpha, beta, gamma, etc.)","lowerRoman":"Lower Roman (i, ii, iii, iv, v, etc.)","none":"None","notset":"<not set>","numberedTitle":"Numbered List Properties","square":"Square","start":"Start","type":"Type","upperAlpha":"Upper Alpha (A, B, C, D, E, etc.)","upperRoman":"Upper Roman (I, II, III, IV, V, etc.)","validateStartNumber":"List start number must be a whole number."},"magicline":{"title":"Insert paragraph here"},"maximize":{"maximize":"Maximize","minimize":"Minimize"},"removeformat":{"toolbar":"Remove Format"},"sourcearea":{"toolbar":"Source"},"clipboard":{"copy":"Copy","copyError":"Your browser security settings don't permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).","cut":"Cut","cutError":"Your browser security settings don't permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).","paste":"Paste","pasteArea":"Paste Area","pasteMsg":"Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK","securityMsg":"Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.","title":"Paste"},"widget":{"move":"Click and drag to move","label":"%1 widget"},"oembed":{"title":"Embed Media Content (Photo, Video, Audio or Rich Content)","button":"Embed Media from External Sites","pasteUrl":"Paste a URL (shorted URLs are also supported) from one of the supported sites (e.g. YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.).","invalidUrl":"Please provide a valid URL.","noEmbedCode":"No embed code found, or site is not supported.","url":"URL:","width":"Width:","height":"Height:","widthTitle":"Width for the embeded content","heightTitle":"Height for the embeded content","maxWidth":"Max. Width:","maxHeight":"Max. Height:","maxWidthTitle":"Maximum Width for the embeded Content","maxHeightTitle":"Maximum Height for the embeded Content","none":"None","resizeType":"Resize Type (videos only):","noresize":"No Resize (use default)","responsive":"Responsive Resize","custom":"Specific Resize","noVimeo":"The owner of this video has set domain restrictions and you will not be able to embed it on your website.","Error":"Media Content could not been retrieved, please try a different URL."}};
\ No newline at end of file
diff --git a/release/lang/fr.js b/release/lang/fr.js
new file mode 100644 (file)
index 0000000..8e6daa7
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/
+CKEDITOR.lang['fr']={"editor":"Éditeur de texte enrichi","editorPanel":"Tableau de bord de l'éditeur de texte enrichi","common":{"editorHelp":"Utilisez le raccourci Alt-0 pour obtenir de l'aide","browseServer":"Parcourir le serveur","url":"URL","protocol":"Protocole","upload":"Téléverser","uploadSubmit":"Envoyer sur le serveur","image":"Image","flash":"Flash","form":"Formulaire","checkbox":"Case à cocher","radio":"Bouton radio","textField":"Champ texte","textarea":"Zone de texte","hiddenField":"Champ invisible","button":"Bouton","select":"Liste déroulante","imageButton":"Bouton avec image","notSet":"<indéfini>","id":"ID","name":"Nom","langDir":"Sens d'écriture","langDirLtr":"Gauche à droite (LTR)","langDirRtl":"Droite à gauche (RTL)","langCode":"Code de langue","longDescr":"URL de description longue","cssClass":"Classes de style","advisoryTitle":"Infobulle","cssStyle":"Style","ok":"OK","cancel":"Annuler","close":"Fermer","preview":"Aperçu","resize":"Redimensionner","generalTab":"Général","advancedTab":"Avancé","validateNumberFailed":"Cette valeur n'est pas un nombre.","confirmNewPage":"Les changements non sauvegardés seront perdus. Êtes-vous sûr de vouloir charger une nouvelle page ?","confirmCancel":"Certaines options ont été modifiées. Êtes-vous sûr de vouloir fermer ?","options":"Options","target":"Cible","targetNew":"Nouvelle fenêtre (_blank)","targetTop":"Fenêtre supérieure (_top)","targetSelf":"Même fenêtre (_self)","targetParent":"Fenêtre parent (_parent)","langDirLTR":"Gauche à droite (LTR)","langDirRTL":"Droite à gauche (RTL)","styles":"Style","cssClasses":"Classes de style","width":"Largeur","height":"Hauteur","align":"Alignement","alignLeft":"Gauche","alignRight":"Droite","alignCenter":"Centrer","alignJustify":"Justifier","alignTop":"Haut","alignMiddle":"Milieu","alignBottom":"Bas","alignNone":"Aucun","invalidValue":"Valeur invalide.","invalidHeight":"La hauteur doit être un nombre.","invalidWidth":"La largeur doit être un nombre.","invalidCssLength":"La valeur spécifiée pour le champ « %1 » doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).","invalidHtmlLength":"La valeur spécifiée pour le champ « %1 » doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).","invalidInlineStyle":"La valeur spécifiée pour le style en ligne doit être composée d'un ou plusieurs couples au format « nom : valeur », séparés par des points-virgules.","cssLengthTooltip":"Entrer un nombre pour une valeur en pixels ou un nombre avec une unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).","unavailable":"%1<span class=\"cke_accessibility\">, indisponible</span>","keyboard":{"8":"Backspace","13":"Entrée","16":"Majuscule","17":"Ctrl","18":"Alt","32":"Space","35":"Fin","36":"Origine","46":"Supprimer","224":"Command"},"keyboardShortcut":"Keyboard shortcut"},"basicstyles":{"bold":"Gras","italic":"Italique","strike":"Barré","subscript":"Indice","superscript":"Exposant","underline":"Souligné"},"contextmenu":{"options":"Options du menu contextuel"},"button":{"selectedLabel":"%1 (Sélectionné)"},"toolbar":{"toolbarCollapse":"Enrouler la barre d'outils","toolbarExpand":"Dérouler la barre d'outils","toolbarGroups":{"document":"Document","clipboard":"Presse-papier/Défaire","editing":"Édition","forms":"Formulaires","basicstyles":"Styles de base","paragraph":"Paragraphe","links":"Liens","insert":"Insérer","styles":"Styles","colors":"Couleurs","tools":"Outils"},"toolbars":"Barres d'outils de l'éditeur"},"elementspath":{"eleLabel":"Chemin des éléments","eleTitle":"Élément %1"},"format":{"label":"Format","panelTitle":"Format de paragraphe","tag_address":"Adresse","tag_div":"Division","tag_h1":"Titre 1","tag_h2":"Titre 2","tag_h3":"Titre 3","tag_h4":"Titre 4","tag_h5":"Titre 5","tag_h6":"Titre 6","tag_p":"Normal","tag_pre":"Préformaté"},"horizontalrule":{"toolbar":"Ligne horizontale"},"fakeobjects":{"anchor":"Ancre","flash":"Animation Flash","hiddenfield":"Champ invisible","iframe":"Cadre de contenu incorporé","unknown":"Objet inconnu"},"iframe":{"border":"Afficher la bordure du cadre","noUrl":"Veuillez entrer l'URL du contenu du cadre","scrolling":"Activer les barres de défilement","title":"Propriétés du cadre de contenu incorporé","toolbar":"Cadre de contenu incorporé"},"image":{"alt":"Texte alternatif","border":"Bordure","btnUpload":"Envoyer sur le serveur","button2Img":"Voulez-vous transformer le bouton avec image sélectionné en simple image ?","hSpace":"Espacement horizontal","img2Button":"Voulez-vous transformer l'image sélectionnée en bouton avec image ?","infoTab":"Informations sur l'image","linkTab":"Lien","lockRatio":"Conserver les proportions","menu":"Propriétés de l'image","resetSize":"Réinitialiser la taille","title":"Propriétés de l'image","titleButton":"Propriétés du bouton avec image","upload":"Téléverser","urlMissing":"L'URL source de l'image est manquante.","vSpace":"Espacement vertical","validateBorder":"La bordure doit être un nombre entier.","validateHSpace":"L'espacement horizontal doit être un nombre entier.","validateVSpace":"L'espacement vertical doit être un nombre entier."},"indent":{"indent":"Augmenter le retrait","outdent":"Diminuer le retrait"},"justify":{"block":"Justifier","center":"Centrer","left":"Aligner à gauche","right":"Aligner à droite"},"link":{"acccessKey":"Touche d'accessibilité","advanced":"Avancé","advisoryContentType":"Type de contenu (indicatif)","advisoryTitle":"Infobulle","anchor":{"toolbar":"Ancre","menu":"Modifier l'ancre","title":"Propriétés de l'ancre","name":"Nom de l'ancre","errorName":"Veuillez entrer le nom de l'ancre.","remove":"Supprimer l'ancre"},"anchorId":"Par ID d'élément","anchorName":"Par nom d'ancre","charset":"Encodage de la ressource liée","cssClasses":"Classes de style","download":"Force Download","displayText":"Display Text","emailAddress":"Adresse électronique","emailBody":"Corps du message","emailSubject":"Sujet du message","id":"ID","info":"Informations sur le lien","langCode":"Code de langue","langDir":"Sens d'écriture","langDirLTR":"Gauche à droite","langDirRTL":"Droite à gauche (RTL)","menu":"Modifier le lien","name":"Nom","noAnchors":"(Aucune ancre disponible dans ce document)","noEmail":"Veuillez entrer l'adresse électronique","noUrl":"Veuillez entrer l'URL du lien","other":"<autre>","popupDependent":"Dépendante (Netscape)","popupFeatures":"Caractéristiques de la fenêtre surgissante","popupFullScreen":"Plein écran (IE)","popupLeft":"À gauche","popupLocationBar":"Barre d'adresse","popupMenuBar":"Barre de menu","popupResizable":"Redimensionnable","popupScrollBars":"Barres de défilement","popupStatusBar":"Barre d'état","popupToolbar":"Barre d'outils","popupTop":"En haut","rel":"Relation","selectAnchor":"Sélectionner une ancre","styles":"Style","tabIndex":"Indice de tabulation","target":"Cible","targetFrame":"<cadre>","targetFrameName":"Nom du cadre affecté","targetPopup":"<fenêtre surgissante>","targetPopupName":"Nom de la fenêtre surgissante","title":"Lien","toAnchor":"Ancre","toEmail":"Courriel","toUrl":"URL","toolbar":"Lien","type":"Type de lien","unlink":"Supprimer le lien","upload":"Téléverser"},"list":{"bulletedlist":"Insérer/Supprimer une liste à puces","numberedlist":"Insérer/Supprimer une liste numérotée"},"liststyle":{"armenian":"Numération arménienne","bulletedTitle":"Propriétés de la liste à puces","circle":"Cercle","decimal":"Décimal (1, 2, 3, etc.)","decimalLeadingZero":"Décimal précédé par un 0 (01, 02, 03, etc.)","disc":"Disque","georgian":"Numération géorgienne (an, ban, gan, etc.)","lowerAlpha":"Lettres minuscules (a, b, c, d, e, etc.)","lowerGreek":"Grec minuscule (alpha, bêta, gamma, etc.)","lowerRoman":"Chiffres romains minuscules (i, ii, iii, iv, v, etc.)","none":"Aucun","notset":"<indéfini>","numberedTitle":"Propriétés de la liste numérotée","square":"Carré","start":"Début","type":"Type","upperAlpha":"Lettres majuscules (A, B, C, D, E, etc.)","upperRoman":"Chiffres romains majuscules (I, II, III, IV, V, etc.)","validateStartNumber":"Le premier élément de la liste doit être un nombre entier."},"magicline":{"title":"Insérer un paragraphe ici"},"maximize":{"maximize":"Agrandir","minimize":"Réduire"},"removeformat":{"toolbar":"Supprimer la mise en forme"},"sourcearea":{"toolbar":"Source"},"clipboard":{"copy":"Copier","copyError":"Les paramètres de sécurité de votre navigateur n'autorisent pas l'éditeur à exécuter automatiquement l'opération « Copier ». Veuillez utiliser le raccourci clavier à cet effet (Ctrl/Cmd+C).","cut":"Couper","cutError":"Les paramètres de sécurité de votre navigateur n'autorisent pas l'éditeur à exécuter automatiquement l'opération « Couper ». Veuillez utiliser le raccourci clavier à cet effet (Ctrl/Cmd+X).","paste":"Coller","pasteArea":"Coller la zone","pasteMsg":"Veuillez coller le texte dans la zone suivante en utilisant le raccourci clavier (<strong>Ctrl/Cmd+V</strong>) et cliquez sur OK.","securityMsg":"Les paramètres de sécurité de votre navigateur empêchent l'éditeur d'accéder directement aux données du presse-papier. Vous devez les coller à nouveau dans cette fenêtre.","title":"Coller"},"widget":{"move":"Cliquer et glisser pour déplacer","label":"Élément %1"},"oembed":{"title":"Intégrer des contenus multimédia externes. (Photo, Video, Audio, ...)","button":"Insérer des contenus multimédia provenant de nombreux sites.","pasteUrl":"Coller l'URL de partage que vous voulez publier. De nombreux services sont pris en charge tels que : (YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.). Vous pouvez aussi utiliser les URLs courtes.","invalidUrl":"Merci de fournir une URL valide !","noEmbedCode":"Aucun code d'intégration trouvé ou le site n'est pas supporté !","url":"URL:","width":"Largeur:","height":"Hauteur:","widthTitle":"Largeur du conteneur.","heightTitle":"Hauteur du conteneur.","maxWidth":"Max. Largeur:","maxHeight":"Max. Hauteur:","maxWidthTitle":"Largeur maximale du conteneur.","maxHeightTitle":"Hauteur maximale du conteneur.","resizeType":"Resize Type (Only Video's):","none":"None","noresize":"No Resize (use default)","responsive":"Responsive Resize","custom":"Specific Resize","noVimeo":"The owner of this video has set domain restrictions and you will not be able to embed it on your website.","Error":"Media Content could not been retrieved, please try a different URL."}};
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/a11yhelp.js b/release/plugins/a11yhelp/dialogs/a11yhelp.js
new file mode 100644 (file)
index 0000000..6c268ca
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add("a11yHelp",function(h){var a=h.lang.a11yhelp,b=h.lang.common.keyboard,n=CKEDITOR.tools.getNextId(),e={8:b[8],9:a.tab,13:b[13],16:b[16],17:b[17],18:b[18],19:a.pause,20:a.capslock,27:a.escape,33:a.pageUp,34:a.pageDown,35:b[35],36:b[36],37:a.leftArrow,38:a.upArrow,39:a.rightArrow,40:a.downArrow,45:a.insert,46:b[46],91:a.leftWindowKey,92:a.rightWindowKey,93:a.selectKey,96:a.numpad0,97:a.numpad1,98:a.numpad2,99:a.numpad3,100:a.numpad4,101:a.numpad5,102:a.numpad6,103:a.numpad7,104:a.numpad8,
+105:a.numpad9,106:a.multiply,107:a.add,109:a.subtract,110:a.decimalPoint,111:a.divide,112:a.f1,113:a.f2,114:a.f3,115:a.f4,116:a.f5,117:a.f6,118:a.f7,119:a.f8,120:a.f9,121:a.f10,122:a.f11,123:a.f12,144:a.numLock,145:a.scrollLock,186:a.semiColon,187:a.equalSign,188:a.comma,189:a.dash,190:a.period,191:a.forwardSlash,192:a.graveAccent,219:a.openBracket,220:a.backSlash,221:a.closeBracket,222:a.singleQuote};e[CKEDITOR.ALT]=b[18];e[CKEDITOR.SHIFT]=b[16];e[CKEDITOR.CTRL]=b[17];var g=[CKEDITOR.ALT,CKEDITOR.SHIFT,
+CKEDITOR.CTRL],p=/\$\{(.*?)\}/g,t=function(){var a=h.keystrokeHandler.keystrokes,b={},d;for(d in a)b[a[d]]=d;return function(a,d){var c;if(b[d]){c=b[d];for(var k,l,m=[],f=0;f<g.length;f++)l=g[f],k=c/g[f],1<k&&2>=k&&(c-=l,m.push(e[l]));m.push(e[c]||String.fromCharCode(c));c=m.join("+")}else c=a;return c}}();return{title:a.title,minWidth:600,minHeight:400,contents:[{id:"info",label:h.lang.common.generalTab,expand:!0,elements:[{type:"html",id:"legends",style:"white-space:normal;",focus:function(){this.getElement().focus()},
+html:function(){for(var b='\x3cdiv class\x3d"cke_accessibility_legend" role\x3d"document" aria-labelledby\x3d"'+n+'_arialbl" tabIndex\x3d"-1"\x3e%1\x3c/div\x3e\x3cspan id\x3d"'+n+'_arialbl" class\x3d"cke_voice_label"\x3e'+a.contents+" \x3c/span\x3e",e=[],d=a.legend,h=d.length,g=0;g<h;g++){for(var c=d[g],k=[],l=c.items,m=l.length,f=0;f<m;f++){var q=l[f],r=q.legend.replace(p,t);r.match(p)||k.push("\x3cdt\x3e%1\x3c/dt\x3e\x3cdd\x3e%2\x3c/dd\x3e".replace("%1",q.name).replace("%2",r))}e.push("\x3ch1\x3e%1\x3c/h1\x3e\x3cdl\x3e%2\x3c/dl\x3e".replace("%1",
+c.name).replace("%2",k.join("")))}return b.replace("%1",e.join(""))}()+'\x3cstyle type\x3d"text/css"\x3e.cke_accessibility_legend{width:600px;height:400px;padding-right:5px;overflow-y:auto;overflow-x:hidden;}.cke_browser_quirks .cke_accessibility_legend,{height:390px}.cke_accessibility_legend *{white-space:normal;}.cke_accessibility_legend h1{font-size: 20px;border-bottom: 1px solid #AAA;margin: 5px 0px 15px;}.cke_accessibility_legend dl{margin-left: 5px;}.cke_accessibility_legend dt{font-size: 13px;font-weight: bold;}.cke_accessibility_legend dd{margin:10px}\x3c/style\x3e'}]}],
+buttons:[CKEDITOR.dialog.cancelButton]}});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/_translationstatus.txt b/release/plugins/a11yhelp/dialogs/lang/_translationstatus.txt
new file mode 100644 (file)
index 0000000..28e8dae
--- /dev/null
@@ -0,0 +1,25 @@
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+\r
+cs.js      Found: 30 Missing: 0\r
+cy.js      Found: 30 Missing: 0\r
+da.js      Found: 12 Missing: 18\r
+de.js      Found: 30 Missing: 0\r
+el.js      Found: 25 Missing: 5\r
+eo.js      Found: 30 Missing: 0\r
+fa.js      Found: 30 Missing: 0\r
+fi.js      Found: 30 Missing: 0\r
+fr.js      Found: 30 Missing: 0\r
+gu.js      Found: 12 Missing: 18\r
+he.js      Found: 30 Missing: 0\r
+it.js      Found: 30 Missing: 0\r
+mk.js      Found: 5 Missing: 25\r
+nb.js      Found: 30 Missing: 0\r
+nl.js      Found: 30 Missing: 0\r
+no.js      Found: 30 Missing: 0\r
+pt-br.js   Found: 30 Missing: 0\r
+ro.js      Found: 6 Missing: 24\r
+tr.js      Found: 30 Missing: 0\r
+ug.js      Found: 27 Missing: 3\r
+vi.js      Found: 6 Missing: 24\r
+zh-cn.js   Found: 30 Missing: 0\r
diff --git a/release/plugins/a11yhelp/dialogs/lang/af.js b/release/plugins/a11yhelp/dialogs/lang/af.js
new file mode 100644 (file)
index 0000000..293a69d
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","af",{title:"Toeganglikheid instruksies",contents:"Hulp inhoud. Druk ESC om toe te maak.",legend:[{name:"Algemeen",items:[{name:"Bewerker balk",legend:"Druk ${toolbarFocus} om op die werkbalk te land. Beweeg na die volgende en voorige wekrbalkgroep met TAB and SHIFT+TAB. Beweeg na die volgende en voorige werkbalkknop met die regter of linker pyl. Druk SPASIE of ENTER om die knop te bevestig."},{name:"Bewerker dialoog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Bewerkerinhoudmenu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pouse",capslock:"Hoofletterslot",escape:"Ontsnap",pageUp:"Blaaiop",pageDown:"Blaaiaf",leftArrow:"Linkspyl",upArrow:"Oppyl",rightArrow:"Regterpyl",downArrow:"Afpyl",insert:"Toevoeg",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Nommerblok 0",numpad1:"Nommerblok 1",numpad2:"Nommerblok 2",numpad3:"Nommerblok 3",numpad4:"Nommerblok 4",numpad5:"Nommerblok 5",numpad6:"Nommerblok 6",
+numpad7:"Nommerblok 7",numpad8:"Nommerblok 8",numpad9:"Nommerblok 9",multiply:"Maal",add:"Plus",subtract:"Minus",decimalPoint:"Desimaalepunt",divide:"Gedeeldeur",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Nommervergrendel",scrollLock:"Rolvergrendel",semiColon:"Kommapunt",equalSign:"Isgelykaan",comma:"Komma",dash:"Koppelteken",period:"Punt",forwardSlash:"Skuinsstreep",graveAccent:"Aksentteken",openBracket:"Oopblokhakkie",backSlash:"Trustreep",
+closeBracket:"Toeblokhakkie",singleQuote:"Enkelaanhaalingsteken"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ar.js b/release/plugins/a11yhelp/dialogs/lang/ar.js
new file mode 100644 (file)
index 0000000..a18ea8a
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ar",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"عام",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"إضافة",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"تقسيم",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"فاصلة",dash:"Dash",period:"نقطة",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/az.js b/release/plugins/a11yhelp/dialogs/lang/az.js
new file mode 100644 (file)
index 0000000..97c8ae6
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","az",{title:"Əlillərə dəstək üzrə təlimat",contents:"Kömək. Pəncərəni bağlamaq üçün ESC basın.",legend:[{name:"Əsas",items:[{name:"Düzəliş edənin alətlər çubuğu",legend:"Panelə keçmək üçün ${toolbarFocus} basın. Növbəti panelə TAB, əvvəlki panelə isə SHIFT+TAB düyməsi vasitəsi ilə keçə bilərsiz. Paneldəki düymələr arasında sol və sağ ox düyməsi ilə keçid edə bilərsiz. Seçilmiş düyməsi SPACE və ya ENTER ilə işlədə bilərsiniz."},{name:"Redaktorun pəncərəsi",legend:"Pəncərə içində növbəti element seçmək üçün TAB düyməni basın, əvvəlki isə - SHIFT+TAB. Təsdiq edilməsi üçün ENTER, imtina edilməsi isə ESC diymələri istifadə edin. Pəncərədə bir neçə vərəq olanda olnarın siyahı ALT+F10 ilə aça bilərsiz. Vərəqlərin siyahı fokus altında olanda ox düymələr vasitəsi ilə onların arasında keçid edə bilərsiz."},
+{name:"Redaktorun seçimlərin menyusu",legend:"Seçimləri redaktə etmək üçün ${contextMenu} ya da APPLICATION KEY basın. Növbəti seçimə keçmək üçün TAB ya AŞAĞI OX düyməsini basın, əvvəlki isə - SHIFT+TAB ya YUXARI OX. Seçimi arımaq SPACE ya ENTER düymələri istifadə edin. Alt menyunu açmaq üçün SPACE, ENTER ya SAĞA OX basın. ESC ya SOLA OX ilə geriyə qayıda bilərsiz. Bütün menyunu ESC ilə bağlıyın."},{name:"Düzəliş edənin siyahı qutusu",legend:"Siyahı qutusu içində növbəti bənd seçmək üçün TAB ya AŞAĞI OX, əvvəlki isə SHIFT+TAB ya YUXARI OX basın. Seçimi arımaq SPACE ya ENTER düymələri istifadə edin. Siyahı qutusu ESC ilə bağlıyın."},
+{name:"Redaktor elementin cığır paneli",legend:"Elementin cığır paneli seçmək üçün ${elementsPathFocus} basın. Növbəti element seçmək üçün TAB ya SAĞA OX, əvvəlki isə SHIFT+TAB ya SOLA OX istifadə edin. Elementi arımaq SPACE ya ENTER düymələri mövcuddur."}]},{name:"Əmrlər",items:[{name:"Əmri geri qaytar",legend:"${undo} basın"},{name:"Geri əmri",legend:"${redo} basın"},{name:"Qalın əmri",legend:"${bold}  basın"},{name:"Kursiv əmri",legend:"${italic} basın"},{name:"Altdan xətt əmri",legend:"${underline} basın"},
+{name:"Link əmri",legend:"${link} basın"},{name:"Paneli gizlət əmri",legend:"${toolbarCollapse} basın"},{name:"Əvvəlki fokus sahəsi seç əmrı",legend:"Kursordan əvvəl ən yaxın əlçatmaz yerə dəymək üçün ${accessPreviousSpace} basın, misal üçün: iki dal-badal HR teg. Uzaq yerlərə dəymək üçün bir neçə dəfə basın."},{name:"Növbəti fokus sahəsi seç əmrı",legend:"Kursordan sonra ən yaxın əlçatmaz yerə dəymək üçün ${accessNextSpace} basın, misal üçün: iki dal-badal HR teg. Uzaq yerlərə dəymək üçün bir neçə dəfə basın."},
+{name:"Hərtərəfli Kömək",legend:"${a11yHelp} basın"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Sola ox işarəsi",upArrow:"Yuxarı ox işarəsi",rightArrow:"Sağa ox işarəsi",downArrow:"Aşağı ox işarəsi",insert:"Insert",leftWindowKey:"Soldaki Windows düyməsi",rightWindowKey:"Sağdaki Windows düyməsi",selectKey:"Düyməni seçin",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",
+numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Vurma",add:"Əlavə et",subtract:"Çıxma",decimalPoint:"Onluq kəsri tam ədəddən ayıran nöqtə",divide:"Bölüşdürmə",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Nöqtəli verqül",equalSign:"Barəbərlik işarəsi",comma:"Vergül",dash:"Defis",period:"Nöqtə",forwardSlash:"Çəp xətt",graveAccent:"Vurğu işarəsi",openBracket:"Açılan mötərizə",
+backSlash:"Tərs çəpəki xətt",closeBracket:"Bağlanan mötərizə",singleQuote:"Tək dırnaq"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/bg.js b/release/plugins/a11yhelp/dialogs/lang/bg.js
new file mode 100644 (file)
index 0000000..d6db25a
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","bg",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Общо",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ca.js b/release/plugins/a11yhelp/dialogs/lang/ca.js
new file mode 100644 (file)
index 0000000..fc56282
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ca",{title:"Instruccions d'Accessibilitat",contents:"Continguts de l'Ajuda. Per tancar aquest quadre de diàleg premi ESC.",legend:[{name:"General",items:[{name:"Editor de barra d'eines",legend:"Premi ${toolbarFocus} per desplaçar-se per la barra d'eines. Vagi en el següent i anterior grup de barra d'eines amb TAB i SHIFT+TAB. Vagi en el següent i anterior botó de la barra d'eines amb RIGHT ARROW i LEFT ARROW. Premi SPACE o ENTER per activar el botó de la barra d'eines."},
+{name:"Editor de quadre de diàleg",legend:"Dins d'un quadre de diàleg, premi la tecla TAB per desplaçar-se fins al següent element del quadre de diàleg, premi la tecla Shift + TAB per desplaçar-se a l'anterior element del quadre de diàleg, premi la tecla ENTER per confirmar el quadre de diàleg, premi la tecla ESC per cancel·lar el quadre de diàleg. Quan un quadre de diàleg té diverses pestanyes, la llista de pestanyes pot ser assolit ja sigui amb ALT + F10 o TAB, com a part de l'ordre de tabulació del quadre de diàleg. Amb la llista de pestanyes seleccionada, pot anar a la fitxa següent i anterior amb la tecla FLETXA DRETA i ESQUERRA, respectivament."},
+{name:"Editor de menú contextual",legend:"Premi ${contextMenu} o APPLICATION KEY per obrir el menú contextual. Després desplacis a la següent opció del menú amb TAB o DOWN ARROW. Desplacis a l'anterior opció amb SHIFT+TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l'opció del menú. Obri el submenú de l'actual opció utilitzant SPACE o ENTER o RIGHT ARROW. Pot tornar a l'opció del menú pare amb ESC o LEFT ARROW. Tanqui el menú contextual amb ESC."},{name:"Editor de caixa de llista",legend:"Dins d'un quadre de llista, desplacis al següent element de la llista amb TAB o DOWN ARROW. Desplacis a l'anterior element de la llista amb SHIFT+TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l'opció de la llista. Premi ESC per tancar el quadre de llista."},
+{name:"Editor de barra de ruta de l'element",legend:"Premi ${elementsPathFocus} per anar als elements de la barra de ruta. Desplacis al botó de l'element següent amb TAB o RIGHT ARROW. Desplacis a l'anterior botó amb SHIFT+TAB o LEFT ARROW. Premi SPACE o ENTER per seleccionar l'element a l'editor."}]},{name:"Ordres",items:[{name:"Desfer ordre",legend:"Premi ${undo}"},{name:"Refer ordre",legend:"Premi ${redo}"},{name:"Ordre negreta",legend:"Premi ${bold}"},{name:"Ordre cursiva",legend:"Premi ${italic}"},
+{name:"Ordre subratllat",legend:"Premi ${underline}"},{name:"Ordre enllaç",legend:"Premi ${link}"},{name:"Ordre amagar barra d'eines",legend:"Premi ${toolbarCollapse}"},{name:"Ordre per accedir a l'anterior espai enfocat",legend:"Premi ${accessPreviousSpace} per accedir a l'enfocament d'espai més proper inabastable abans del símbol d'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d'espais distants."},{name:"Ordre per accedir al següent espai enfocat",
+legend:"Premi ${accessNextSpace} per accedir a l'enfocament d'espai més proper inabastable després del símbol d'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d'espais distants."},{name:"Ajuda d'accessibilitat",legend:"Premi ${a11yHelp}"}]}],tab:"Tabulació",pause:"Pausa",capslock:"Bloqueig de majúscules",escape:"Escape",pageUp:"Pàgina Amunt",pageDown:"Pàgina Avall",leftArrow:"Fletxa Esquerra",upArrow:"Fletxa Amunt",rightArrow:"Fletxa Dreta",
+downArrow:"Fletxa Avall",insert:"Inserir",leftWindowKey:"Tecla Windows Esquerra",rightWindowKey:"Tecla Windows Dreta",selectKey:"Tecla Seleccionar",numpad0:"Teclat Numèric 0",numpad1:"Teclat Numèric 1",numpad2:"Teclat Numèric 2",numpad3:"Teclat Numèric 3",numpad4:"Teclat Numèric 4",numpad5:"Teclat Numèric 5",numpad6:"Teclat Numèric 6",numpad7:"Teclat Numèric 7",numpad8:"Teclat Numèric 8",numpad9:"Teclat Numèric 9",multiply:"Multiplicació",add:"Suma",subtract:"Resta",decimalPoint:"Punt Decimal",divide:"Divisió",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Bloqueig Teclat Numèric",scrollLock:"Bloqueig de Desplaçament",semiColon:"Punt i Coma",equalSign:"Símbol Igual",comma:"Coma",dash:"Guió",period:"Punt",forwardSlash:"Barra Diagonal",graveAccent:"Accent Obert",openBracket:"Claudàtor Obert",backSlash:"Barra Invertida",closeBracket:"Claudàtor Tancat",singleQuote:"Cometa Simple"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/cs.js b/release/plugins/a11yhelp/dialogs/lang/cs.js
new file mode 100644 (file)
index 0000000..de8ef8c
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","cs",{title:"Instrukce pro přístupnost",contents:"Obsah nápovědy. Pro uzavření tohoto dialogu stiskněte klávesu ESC.",legend:[{name:"Obecné",items:[{name:"Panel nástrojů editoru",legend:"Stiskněte${toolbarFocus} k procházení panelu nástrojů. Přejděte na další a předchozí skupiny pomocí TAB a SHIFT+TAB. Přechod na další a předchozí tlačítko panelu nástrojů je pomocí ŠIPKA VPRAVO nebo ŠIPKA VLEVO. Stisknutím mezerníku nebo klávesy ENTER tlačítko aktivujete."},{name:"Dialogové okno editoru",
+legend:"Uvnitř dialogového okna stiskněte TAB pro přesunutí na další prvek okna, stiskněte SHIFT+TAB pro přesun na předchozí prvek okna, stiskněte ENTER pro odeslání dialogu, stiskněte ESC pro jeho zrušení. Pro dialogová okna, která mají mnoho karet stiskněte ALT+F10 pro zaměření seznamu karet, nebo TAB, pro posun podle pořadí karet.Při zaměření seznamu karet se můžete jimi posouvat pomocí ŠIPKY VPRAVO a VLEVO."},{name:"Kontextové menu editoru",legend:"Stiskněte ${contextMenu} nebo klávesu APPLICATION k otevření kontextového menu. Pak se přesuňte na další možnost menu pomocí TAB nebo ŠIPKY DOLŮ. Přesuňte se na předchozí možnost pomocí  SHIFT+TAB nebo ŠIPKY NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti menu. Podmenu současné možnosti otevřete pomocí MEZERNÍKU nebo ENTER či ŠIPKY DOLEVA. Kontextové menu uzavřete stiskem ESC."},
+{name:"Rámeček seznamu editoru",legend:"Uvnitř rámečku seznamu se přesunete na další položku menu pomocí TAB nebo ŠIPKA DOLŮ. Na předchozí položku se přesunete SHIFT+TAB nebo ŠIPKA NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti seznamu. Stiskněte ESC pro uzavření seznamu."},{name:"Lišta cesty prvku v editoru",legend:"Stiskněte ${elementsPathFocus} pro procházení lišty cesty prvku. Na další tlačítko prvku se přesunete pomocí TAB nebo ŠIPKA VPRAVO. Na předchozí tlačítko se přesunete pomocí SHIFT+TAB nebo ŠIPKA VLEVO. Stiskněte MEZERNÍK nebo ENTER pro vybrání prvku v editoru."}]},
+{name:"Příkazy",items:[{name:" Příkaz Zpět",legend:"Stiskněte ${undo}"},{name:" Příkaz Znovu",legend:"Stiskněte ${redo}"},{name:" Příkaz Tučné",legend:"Stiskněte ${bold}"},{name:" Příkaz Kurzíva",legend:"Stiskněte ${italic}"},{name:" Příkaz Podtržení",legend:"Stiskněte ${underline}"},{name:" Příkaz Odkaz",legend:"Stiskněte ${link}"},{name:" Příkaz Skrýt panel nástrojů",legend:"Stiskněte ${toolbarCollapse}"},{name:"Příkaz pro přístup k předchozímu prostoru zaměření",legend:"Stiskněte ${accessPreviousSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření před stříškou, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte."},
+{name:"Příkaz pro přístup k dalšímu prostoru zaměření",legend:"Stiskněte ${accessNextSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření po stříšce, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte."},{name:" Nápověda přístupnosti",legend:"Stiskněte ${a11yHelp}"}]}],tab:"Tabulátor",pause:"Pauza",capslock:"Caps lock",escape:"Escape",pageUp:"Stránka nahoru",pageDown:"Stránka dolů",leftArrow:"Šipka vlevo",upArrow:"Šipka nahoru",
+rightArrow:"Šipka vpravo",downArrow:"Šipka dolů",insert:"Vložit",leftWindowKey:"Levá klávesa Windows",rightWindowKey:"Pravá klávesa Windows",selectKey:"Vyberte klávesu",numpad0:"Numerická klávesa 0",numpad1:"Numerická klávesa 1",numpad2:"Numerická klávesa 2",numpad3:"Numerická klávesa 3",numpad4:"Numerická klávesa 4",numpad5:"Numerická klávesa 5",numpad6:"Numerická klávesa 6",numpad7:"Numerická klávesa 7",numpad8:"Numerická klávesa 8",numpad9:"Numerická klávesa 9",multiply:"Numerická klávesa násobení",
+add:"Přidat",subtract:"Numerická klávesa odečítání",decimalPoint:"Desetinná tečka",divide:"Numerická klávesa dělení",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num lock",scrollLock:"Scroll lock",semiColon:"Středník",equalSign:"Rovnítko",comma:"Čárka",dash:"Pomlčka",period:"Tečka",forwardSlash:"Lomítko",graveAccent:"Přízvuk",openBracket:"Otevřená hranatá závorka",backSlash:"Obrácené lomítko",closeBracket:"Uzavřená hranatá závorka",
+singleQuote:"Jednoduchá uvozovka"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/cy.js b/release/plugins/a11yhelp/dialogs/lang/cy.js
new file mode 100644 (file)
index 0000000..31e94af
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","cy",{title:"Canllawiau Hygyrchedd",contents:"Cynnwys Cymorth. I gau y deialog hwn, pwyswch ESC.",legend:[{name:"Cyffredinol",items:[{name:"Bar Offer y Golygydd",legend:"Pwyswch $ {toolbarFocus} i fynd at y bar offer. Symudwch i'r grŵp bar offer nesaf a blaenorol gyda TAB a SHIFT+TAB. Symudwch i'r botwm bar offer nesaf a blaenorol gyda SAETH DDE neu SAETH CHWITH. Pwyswch SPACE neu ENTER i wneud botwm y bar offer yn weithredol."},{name:"Deialog y Golygydd",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Dewislen Cyd-destun y Golygydd",legend:"Pwyswch $ {contextMenu} neu'r ALLWEDD 'APPLICATION' i agor y ddewislen cyd-destun. Yna symudwch i'r opsiwn ddewislen nesaf gyda'r TAB neu'r SAETH I LAWR. Symudwch i'r opsiwn blaenorol gyda SHIFT+TAB neu'r SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn ddewislen. Agorwch is-dewislen yr opsiwn cyfredol gyda SPACE neu ENTER neu SAETH DDE. Ewch yn ôl i'r eitem ar y ddewislen uwch gydag ESC neu SAETH CHWITH. Ceuwch y ddewislen cyd-destun gydag ESC."},
+{name:"Blwch Rhestr y Golygydd",legend:"Tu mewn y blwch rhestr, ewch i'r eitem rhestr nesaf gyda TAB neu'r SAETH I LAWR. Symudwch i restr eitem flaenorol gyda SHIFT+TAB neu SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn o'r rhestr. Pwyswch ESC i gau'r rhestr."},{name:"Bar Llwybr Elfen y Golygydd",legend:"Pwyswch ${elementsPathFocus} i fynd i'r bar llwybr elfennau. Symudwch i fotwm yr elfen nesaf gyda TAB neu SAETH DDE. Symudwch i fotwm blaenorol gyda SHIFT+TAB neu SAETH CHWITH. Pwyswch SPACE neu ENTER i ddewis yr elfen yn y golygydd."}]},
+{name:"Gorchmynion",items:[{name:"Gorchymyn dadwneud",legend:"Pwyswch ${undo}"},{name:"Gorchymyn ailadrodd",legend:"Pwyswch ${redo}"},{name:"Gorchymyn Bras",legend:"Pwyswch ${bold}"},{name:"Gorchymyn italig",legend:"Pwyswch ${italig}"},{name:"Gorchymyn tanlinellu",legend:"Pwyso ${underline}"},{name:"Gorchymyn dolen",legend:"Pwyswch ${link}"},{name:"Gorchymyn Cwympo'r Dewislen",legend:"Pwyswch ${toolbarCollapse}"},{name:"Myned i orchymyn bwlch ffocws blaenorol",legend:"Pwyswch ${accessPreviousSpace} i fyned i'r \"blwch ffocws sydd methu ei gyrraedd\" cyn y caret, er enghraifft: dwy elfen HR drws nesaf i'w gilydd. AIladroddwch y cyfuniad allwedd i gyrraedd bylchau ffocws pell."},
+{name:"Ewch i'r gorchymyn blwch ffocws nesaf",legend:"Pwyswch ${accessNextSpace} i fyned i'r blwch ffocws agosaf nad oes modd ei gyrraedd ar ôl y caret, er enghraifft: dwy elfen HR drws nesaf i'w gilydd. Ailadroddwch y cyfuniad allwedd i gyrraedd blychau ffocws pell."},{name:"Cymorth Hygyrchedd",legend:"Pwyswch ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",
+insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",
+scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/da.js b/release/plugins/a11yhelp/dialogs/lang/da.js
new file mode 100644 (file)
index 0000000..c3e4a97
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","da",{title:"Tilgængelighedsinstrukser",contents:"Onlinehjælp. For at lukke dette vindue klik ESC",legend:[{name:"Generelt",items:[{name:"Editor værktøjslinje",legend:"Tryk ${toolbarFocus} for at navigere til værktøjslinjen. Flyt til næste eller forrige værktøjsline gruppe ved hjælp af TAB eller SHIFT+TAB. Flyt til næste eller forrige værktøjslinje knap med venstre- eller højre piltast. Tryk på SPACE eller ENTER for at aktivere værktøjslinje knappen."},{name:"Editor dialogboks",
+legend:"Inde i en dialogboks kan du, trykke på TAB for at navigere til næste element, trykke på SHIFT+TAB for at navigere til forrige element, trykke på ENTER for at afsende eller trykke på ESC for at lukke dialogboksen.\r\nNår en dialogboks har flere faner, fanelisten kan tilgås med ALT+F10 eller med TAB. Hvis fanelisten er i fokus kan du skifte til næste eller forrige tab, med højre- og venstre piltast."},{name:"Redaktør kontekstmenu",legend:"Tryk ${contextMenu} eller APPLICATION KEY for at åbne kontekstmenuen. Flyt derefter til næste menuvalg med TAB eller PIL NED. Flyt til forrige valg med SHIFT+TAB eller PIL OP. Tryk MELLEMRUM eller RETUR for at vælge menu-muligheder. Åben under-menu af aktuelle valg med MELLEMRUM eller RETUR eller HØJRE PIL. Gå tilbage til overliggende menu-emne med ESC eller VENSTRE PIL. Luk kontekstmenu med ESC."},
+{name:"Redaktør listeboks",legend:"Flyt til næste emne med TAB eller PIL NED inde i en listeboks. Flyt til forrige listeemne med SHIFT+TAB eller PIL OP. Tryk MELLEMRUM eller RETUR for at vælge liste-muligheder. Tryk ESC for at lukke liste-boksen."},{name:"Redaktør elementsti-bar",legend:"Tryk ${elementsPathFocus} for at navigere til elementernes sti-bar. Flyt til næste element-knap med TAB eller HØJRE PIL. Flyt til forrige knap med SHIFT+TAB eller VENSTRE PIL. Klik MELLEMRUM eller RETUR for at vælge element i editoren."}]},
+{name:"Kommandoer",items:[{name:"Fortryd kommando",legend:"Klik på ${undo}"},{name:"Gentag kommando",legend:"Klik ${redo}"},{name:"Fed kommando",legend:"Klik ${bold}"},{name:"Kursiv kommando",legend:"Klik ${italic}"},{name:"Understregnings kommando",legend:"Klik ${underline}"},{name:"Link kommando",legend:"Klik ${link}"},{name:"Klap værktøjslinje sammen kommando ",legend:"Klik ${toolbarCollapse}"},{name:"Adgang til forrige fokusområde kommando",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:"Tilgængelighedshjælp",legend:"Kilk ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Venstre pil",upArrow:"Pil op",rightArrow:"Højre pil",downArrow:"Pil ned",insert:"Insert",leftWindowKey:"Venstre Windows tast",
+rightWindowKey:"Højre Windows tast",selectKey:"Select-knap",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Gange",add:"Plus",subtract:"Minus",decimalPoint:"Komma",divide:"Divider",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semikolon",
+equalSign:"Lighedstegn",comma:"Komma",dash:"Bindestreg",period:"Punktum",forwardSlash:"Skråstreg",graveAccent:"Accent grave",openBracket:"Start klamme",backSlash:"Omvendt skråstreg",closeBracket:"Slut klamme",singleQuote:"Enkelt citationstegn"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/de-ch.js b/release/plugins/a11yhelp/dialogs/lang/de-ch.js
new file mode 100644 (file)
index 0000000..a09f882
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","de-ch",{title:"Barrierefreiheitinformationen",contents:"Hilfeinhalt. Um den Dialog zu schliessen die Taste ESC drücken.",legend:[{name:"Allgemein",items:[{name:"Editorwerkzeugleiste",legend:"Drücken Sie ${toolbarFocus} auf der Symbolleiste. Gehen Sie zur nächsten oder vorherigen Symbolleistengruppe mit TAB und SHIFT+TAB. Gehen Sie zur nächsten oder vorherigen Symbolleiste auf die Schaltfläche mit dem RECHTS- oder LINKS-Pfeil. Drücken Sie die Leertaste oder Eingabetaste, um die Schaltfläche in der Symbolleiste aktivieren."},
+{name:"Editordialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Editor-Kontextmenü",legend:"Dürcken Sie ${contextMenu} oder die Anwendungstaste um das Kontextmenü zu öffnen. Man kann die Pfeiltasten zum Wechsel benutzen. Mit der Leertaste oder der Enter-Taste kann man den Menüpunkt aufrufen. Schliessen Sie das Kontextmenü mit der ESC-Taste."},
+{name:"Editor-Listenbox",legend:"Innerhalb einer Listenbox kann man mit der TAB-Taste oder den Pfeilrunter-Taste den nächsten Menüeintrag wählen. Mit der SHIFT+TAB Tastenkombination oder der Pfeilhoch-Taste gelangt man zum vorherigen Menüpunkt. Mit der Leertaste oder Enter kann man den Menüpunkt auswählen. Drücken Sie ESC zum Verlassen des Menüs."},{name:"Editor-Elementpfadleiste",legend:"Drücken Sie ${elementsPathFocus} um sich durch die Pfadleiste zu bewegen. Um zum nächsten Element zu gelangen drücken Sie TAB oder die Pfeilrechts-Taste. Zum vorherigen Element gelangen Sie mit der SHIFT+TAB oder der Pfeillinks-Taste. Drücken Sie die Leertaste oder Enter um das Element auszuwählen."}]},
+{name:"Befehle",items:[{name:"Rückgängig-Befehl",legend:"Drücken Sie ${undo}"},{name:"Wiederherstellen-Befehl",legend:"Drücken Sie ${redo}"},{name:"Fettschrift-Befehl",legend:"Drücken Sie ${bold}"},{name:"Kursiv-Befehl",legend:"Drücken Sie ${italic}"},{name:"Unterstreichen-Befehl",legend:"Drücken Sie ${underline}"},{name:"Link-Befehl",legend:"Drücken Sie ${link}"},{name:"Werkzeugleiste einklappen-Befehl",legend:"Drücken Sie ${toolbarCollapse}"},{name:"Zugang bisheriger Fokussierung Raumbefehl ",legend:"Drücken Sie ${accessPreviousSpace}  auf den am nächsten nicht erreichbar Fokus-Abstand vor die Einfügemarke zugreifen: zwei benachbarte HR-Elemente. Wiederholen Sie die Tastenkombination um entfernte Fokusräume zu erreichen. "},
+{name:"Zugang nächster Schwerpunkt Raumbefehl ",legend:"Drücken Sie $ { accessNextSpace }, um den nächsten unerreichbar Fokus Leerzeichen nach dem Cursor zum Beispiel auf: zwei benachbarten HR Elemente. Wiederholen Sie die Tastenkombination zum fernen Fokus Bereiche zu erreichen. "},{name:"Eingabehilfen",legend:"Drücken Sie ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Feststell",escape:"Escape",pageUp:"Bild auf",pageDown:"Bild ab",leftArrow:"Linke Pfeiltaste",upArrow:"Obere Pfeiltaste",rightArrow:"Rechte Pfeiltaste",
+downArrow:"Untere Pfeiltaste",insert:"Einfügen",leftWindowKey:"Linke Windowstaste",rightWindowKey:"Rechte Windowstaste",selectKey:"Taste auswählen",numpad0:"Ziffernblock 0",numpad1:"Ziffernblock 1",numpad2:"Ziffernblock 2",numpad3:"Ziffernblock 3",numpad4:"Ziffernblock 4",numpad5:"Ziffernblock 5",numpad6:"Ziffernblock 6",numpad7:"Ziffernblock 7",numpad8:"Ziffernblock 8",numpad9:"Ziffernblock 9",multiply:"Multiplizieren",add:"Addieren",subtract:"Subtrahieren",decimalPoint:"Punkt",divide:"Dividieren",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Ziffernblock feststellen",scrollLock:"Rollen",semiColon:"Semikolon",equalSign:"Gleichheitszeichen",comma:"Komma",dash:"Bindestrich",period:"Punkt",forwardSlash:"Schrägstrich",graveAccent:"Gravis",openBracket:"Öffnende eckige Klammer",backSlash:"Rückwärtsgewandter Schrägstrich",closeBracket:"Schliessende eckige Klammer",singleQuote:"Einfaches Anführungszeichen"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/de.js b/release/plugins/a11yhelp/dialogs/lang/de.js
new file mode 100644 (file)
index 0000000..0a09795
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","de",{title:"Barrierefreiheitinformationen",contents:"Hilfeinhalt. Um den Dialog zu schliessen die Taste ESC drücken.",legend:[{name:"Allgemein",items:[{name:"Editorwerkzeugleiste",legend:"Drücken Sie ${toolbarFocus} auf der Symbolleiste. Gehen Sie zur nächsten oder vorherigen Symbolleistengruppe mit TAB und SHIFT+TAB. Gehen Sie zur nächsten oder vorherigen Symbolleiste auf die Schaltfläche mit dem RECHTS- oder LINKS-Pfeil. Drücken Sie die Leertaste oder Eingabetaste, um die Schaltfläche in der Symbolleiste aktivieren."},
+{name:"Editordialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Editor-Kontextmenü",legend:"Dürcken Sie ${contextMenu} oder die Anwendungstaste um das Kontextmenü zu öffnen. Man kann die Pfeiltasten zum Wechsel benutzen. Mit der Leertaste oder der Enter-Taste kann man den Menüpunkt aufrufen. Schliessen Sie das Kontextmenü mit der ESC-Taste."},
+{name:"Editor-Listenbox",legend:"Innerhalb einer Listenbox kann man mit der TAB-Taste oder den Pfeilrunter-Taste den nächsten Menüeintrag wählen. Mit der SHIFT+TAB Tastenkombination oder der Pfeilhoch-Taste gelangt man zum vorherigen Menüpunkt. Mit der Leertaste oder Enter kann man den Menüpunkt auswählen. Drücken Sie ESC zum Verlassen des Menüs."},{name:"Editor-Elementpfadleiste",legend:"Drücken Sie ${elementsPathFocus} um sich durch die Pfadleiste zu bewegen. Um zum nächsten Element zu gelangen drücken Sie TAB oder die Pfeilrechts-Taste. Zum vorherigen Element gelangen Sie mit der SHIFT+TAB oder der Pfeillinks-Taste. Drücken Sie die Leertaste oder Enter um das Element auszuwählen."}]},
+{name:"Befehle",items:[{name:"Rückgängig-Befehl",legend:"Drücken Sie ${undo}"},{name:"Wiederherstellen-Befehl",legend:"Drücken Sie ${redo}"},{name:"Fettschrift-Befehl",legend:"Drücken Sie ${bold}"},{name:"Kursiv-Befehl",legend:"Drücken Sie ${italic}"},{name:"Unterstreichen-Befehl",legend:"Drücken Sie ${underline}"},{name:"Link-Befehl",legend:"Drücken Sie ${link}"},{name:"Werkzeugleiste einklappen-Befehl",legend:"Drücken Sie ${toolbarCollapse}"},{name:"Zugang bisheriger Fokussierung Raumbefehl ",legend:"Drücken Sie ${accessPreviousSpace}  auf den am nächsten nicht erreichbar Fokus-Abstand vor die Einfügemarke zugreifen: zwei benachbarte HR-Elemente. Wiederholen Sie die Tastenkombination um entfernte Fokusräume zu erreichen. "},
+{name:"Zugang nächster Schwerpunkt Raumbefehl ",legend:"Drücken Sie $ { accessNextSpace }, um den nächsten unerreichbar Fokus Leerzeichen nach dem Cursor zum Beispiel auf: zwei benachbarten HR Elemente. Wiederholen Sie die Tastenkombination zum fernen Fokus Bereiche zu erreichen. "},{name:"Eingabehilfen",legend:"Drücken Sie ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Feststell",escape:"Escape",pageUp:"Bild auf",pageDown:"Bild ab",leftArrow:"Linke Pfeiltaste",upArrow:"Obere Pfeiltaste",rightArrow:"Rechte Pfeiltaste",
+downArrow:"Untere Pfeiltaste",insert:"Einfügen",leftWindowKey:"Linke Windowstaste",rightWindowKey:"Rechte Windowstaste",selectKey:"Taste auswählen",numpad0:"Ziffernblock 0",numpad1:"Ziffernblock 1",numpad2:"Ziffernblock 2",numpad3:"Ziffernblock 3",numpad4:"Ziffernblock 4",numpad5:"Ziffernblock 5",numpad6:"Ziffernblock 6",numpad7:"Ziffernblock 7",numpad8:"Ziffernblock 8",numpad9:"Ziffernblock 9",multiply:"Multiplizieren",add:"Addieren",subtract:"Subtrahieren",decimalPoint:"Punkt",divide:"Dividieren",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Ziffernblock feststellen",scrollLock:"Rollen",semiColon:"Semikolon",equalSign:"Gleichheitszeichen",comma:"Komma",dash:"Bindestrich",period:"Punkt",forwardSlash:"Schrägstrich",graveAccent:"Gravis",openBracket:"Öffnende eckige Klammer",backSlash:"Rückwärtsgewandter Schrägstrich",closeBracket:"Schließende eckige Klammer",singleQuote:"Einfaches Anführungszeichen"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/el.js b/release/plugins/a11yhelp/dialogs/lang/el.js
new file mode 100644 (file)
index 0000000..19a44b0
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","el",{title:"Οδηγίες Προσβασιμότητας",contents:"Περιεχόμενα Βοήθειας. Πατήστε ESC για κλείσιμο.",legend:[{name:"Γενικά",items:[{name:"Εργαλειοθήκη Επεξεργαστή",legend:"Πατήστε ${toolbarFocus} για να περιηγηθείτε στην γραμμή εργαλείων. Μετακινηθείτε ανάμεσα στις ομάδες της γραμμής εργαλείων με TAB και SHIFT+TAB. Μετακινηθείτε ανάμεσα στα κουμπιά εργαλείων με το ΔΕΞΙ ή ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να ενεργοποιήσετε το ενεργό κουμπί εργαλείου."},{name:"Παράθυρο Διαλόγου Επεξεργαστή",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Αναδυόμενο Μενού Επεξεργαστή",legend:"Πατήστε ${contextMenu} ή APPLICATION KEY για να ανοίξετε το αναδυόμενο μενού. Μετά μετακινηθείτε στην επόμενη επιλογή του μενού με  TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στην προηγούμενη επιλογή με SHIFT+TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξτε το τρέχων στοιχείο. Ανοίξτε το αναδυόμενο μενού της τρέχουσας επιλογής με ΔΙΑΣΤΗΜΑ ή ENTER ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μεταβείτε πίσω στο αρχικό στοιχείο μενού με το ESC ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Κλείστε το αναδυόμενο μενού με ESC."},
+{name:"Κουτί Λίστας Επεξεργαστών",legend:"Μέσα σε ένα κουτί λίστας, μετακινηθείτε στο επόμενο στοιχείο με TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στο προηγούμενο στοιχείο με SHIFT+TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε ένα στοιχείο. Πατήστε ESC για να κλείσετε το κουτί της λίστας."},{name:"Μπάρα Διαδρομών Στοιχείων Επεξεργαστή",legend:"Πατήστε ${elementsPathFocus} για να περιηγηθείτε στην μπάρα διαδρομών στοιχείων του επεξεργαστή. Μετακινηθείτε στο κουμπί του επόμενου στοιχείου με το TAB ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μετακινηθείτε στο κουμπί του προηγούμενου στοιχείου με το SHIFT+TAB ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε το στοιχείο στον επεξεργαστή."}]},
+{name:"Εντολές",items:[{name:"Εντολή αναίρεσης",legend:"Πατήστε ${undo}"},{name:"Εντολή επανάληψης",legend:"Πατήστε ${redo}"},{name:"Εντολή έντονης γραφής",legend:"Πατήστε ${bold}"},{name:"Εντολή πλάγιας γραφής",legend:"Πατήστε ${italic}"},{name:"Εντολή υπογράμμισης",legend:"Πατήστε ${underline}"},{name:"Εντολή συνδέσμου",legend:"Πατήστε ${link}"},{name:"Εντολή Σύμπτηξης Εργαλειοθήκης",legend:"Πατήστε ${toolbarCollapse}"},{name:"Πρόσβαση στην προηγούμενη εντολή του χώρου εστίασης ",legend:"Πατήστε ${accessPreviousSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης πριν το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για να φθάσετε στους χώρους μακρινής εστίασης. "},
+{name:"Πρόσβαση στην επόμενη εντολή του χώρου εστίασης",legend:"Πατήστε ${accessNextSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης μετά το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για τους χώρους μακρινής εστίασης. "},{name:"Βοήθεια Προσβασιμότητας",legend:"Πατήστε ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Αριστερό Βέλος",upArrow:"Πάνω Βέλος",rightArrow:"Δεξί Βέλος",
+downArrow:"Κάτω Βέλος",insert:"Insert ",leftWindowKey:"Αριστερό Πλήκτρο Windows",rightWindowKey:"Δεξί Πλήκτρο Windows",selectKey:"Πλήκτρο Select",numpad0:"Αριθμητικό πληκτρολόγιο 0",numpad1:"Αριθμητικό Πληκτρολόγιο 1",numpad2:"Αριθμητικό πληκτρολόγιο 2",numpad3:"Αριθμητικό πληκτρολόγιο 3",numpad4:"Αριθμητικό πληκτρολόγιο 4",numpad5:"Αριθμητικό πληκτρολόγιο 5",numpad6:"Αριθμητικό πληκτρολόγιο 6",numpad7:"Αριθμητικό πληκτρολόγιο 7",numpad8:"Αριθμητικό πληκτρολόγιο 8",numpad9:"Αριθμητικό πληκτρολόγιο 9",
+multiply:"Πολλαπλασιασμός",add:"Πρόσθεση",subtract:"Αφαίρεση",decimalPoint:"Υποδιαστολή",divide:"Διαίρεση",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"6",f7:"7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Ερωτηματικό",equalSign:"Σύμβολο Ισότητας",comma:"Κόμμα",dash:"Παύλα",period:"Τελεία",forwardSlash:"Κάθετος",graveAccent:"Βαρεία",openBracket:"Άνοιγμα Παρένθεσης",backSlash:"Ανάστροφη Κάθετος",closeBracket:"Κλείσιμο Παρένθεσης",singleQuote:"Απόστροφος"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/en-gb.js b/release/plugins/a11yhelp/dialogs/lang/en-gb.js
new file mode 100644 (file)
index 0000000..26dfdf0
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","en-gb",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"General",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/en.js b/release/plugins/a11yhelp/dialogs/lang/en.js
new file mode 100644 (file)
index 0000000..52708c9
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","en",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"General",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/eo.js b/release/plugins/a11yhelp/dialogs/lang/eo.js
new file mode 100644 (file)
index 0000000..01edb4d
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","eo",{title:"Uzindikoj pri atingeblo",contents:"Helpilenhavo. Por fermi tiun dialogon, premu la ESKAPAN klavon.",legend:[{name:"Ĝeneralaĵoj",items:[{name:"Ilbreto de la redaktilo",legend:"Premu ${toolbarFocus} por atingi la ilbreton. Moviĝu al la sekva aŭ antaŭa grupoj de la ilbreto per la klavoj TABA kaj MAJUSKLIGA+TABA. Moviĝu al la sekva aŭ antaŭa butonoj de la ilbreto per la klavoj SAGO DEKSTREN kaj SAGO MALDEKSTREN. Premu la SPACETklavon aŭ la ENENklavon por aktivigi la ilbretbutonon."},
+{name:"Redaktildialogo",legend:"En dialogo, premu la TABAN klavon por navigi al la sekva dialogelemento, premu la MAJUSKLIGAN+TABAN klavon por iri al la antaŭa dialogelemento, premu la ENEN klavon por sendi la dialogon, premu la ESKAPAN klavon por nuligi la dialogon. Kiam dialogo havas multajn langetojn, eblas atingi la langetliston aŭ per ALT+F10 aŭ per la TABA klavo kiel parton de la dialoga taba ordo. En langetlisto, moviĝu al la sekva kaj antaŭa langeto per la klavoj SAGO DEKSTREN KAJ MALDEKSTREN respektive."},
+{name:"Kunteksta menuo de la redaktilo",legend:"Premu ${contextMenu} aŭ entajpu la KLAVKOMBINAĴON por malfermi la kuntekstan menuon. Poste moviĝu al la sekva opcio de la menuo per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa opcio per la klavoj MAJUSKLGA + TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la menuopcion. Malfermu la submenuon de la kuranta opcio per la SPACETklavo aŭ la ENENklavo aŭ la SAGO DEKSTREN. Revenu al la elemento de la patra menuo per la klavoj ESKAPA aŭ SAGO MALDEKSTREN. Fermu la kuntekstan menuon per la ESKAPA klavo."},
+{name:"Fallisto de la redaktilo",legend:"En fallisto, moviĝu al la sekva listelemento per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa listelemento per la klavoj MAJUSKLIGA+TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la opcion en la listo. Premu la ESKAPAN klavon por fermi la falmenuon."},{name:"Breto indikanta la vojon al la redaktilelementoj",legend:"Premu ${elementsPathFocus} por navigi al la breto indikanta la vojon al la redaktilelementoj. Moviĝu al la butono de la sekva elemento per la klavoj TABA aŭ SAGO DEKSTREN. Moviĝu al la butono de la antaŭa elemento per la klavoj MAJUSKLIGA+TABA aŭ SAGO MALDEKSTREN. Premu la SPACETklavon aŭ ENENklavon por selekti la elementon en la redaktilo."}]},
+{name:"Komandoj",items:[{name:"Komando malfari",legend:"Premu ${undo}"},{name:"Komando refari",legend:"Premu ${redo}"},{name:"Komando grasa",legend:"Premu ${bold}"},{name:"Komando kursiva",legend:"Premu ${italic}"},{name:"Komando substreki",legend:"Premu ${underline}"},{name:"Komando ligilo",legend:"Premu ${link}"},{name:"Komando faldi la ilbreton",legend:"Premu ${toolbarCollapse}"},{name:"Komando por atingi la antaŭan fokusan spacon",legend:"Press ${accessPreviousSpace} por atingi la plej proksiman neatingeblan fokusan spacon antaŭ la kursoro, ekzemple : du kuntuŝiĝajn HR elementojn. Ripetu la klavkombinaĵon por atingi malproksimajn fokusajn spacojn."},
+{name:"Komando por atingi la sekvan fokusan spacon",legend:"Press ${accessNextSpace} por atingi la plej proksiman neatingeblan fokusan spacon post la kursoro, ekzemple : du kuntuŝiĝajn HR elementojn. Ripetu la klavkombinajôn por atingi malproksimajn fokusajn spacojn"},{name:"Helpilo pri atingeblo",legend:"Premu ${a11yHelp}"}]}],tab:"Tabo",pause:"Paŭzo",capslock:"Majuskla baskulo",escape:"Eskapa klavo",pageUp:"Antaŭa Paĝo",pageDown:"Sekva Paĝo",leftArrow:"Sago Maldekstren",upArrow:"Sago Supren",rightArrow:"Sago Dekstren",
+downArrow:"Sago Suben",insert:"Enmeti",leftWindowKey:"Maldekstra Windows-klavo",rightWindowKey:"Dekstra Windows-klavo",selectKey:"Selektklavo",numpad0:"Nombra Klavaro 0",numpad1:"Nombra Klavaro 1",numpad2:"Nombra Klavaro 2",numpad3:"Nombra Klavaro 3",numpad4:"Nombra Klavaro 4",numpad5:"Nombra Klavaro 5",numpad6:"Nombra Klavaro 6",numpad7:"Nombra Klavaro 7",numpad8:"Nombra Klavaro 8",numpad9:"Nombra Klavaro 9",multiply:"Obligi",add:"Almeti",subtract:"Subtrahi",decimalPoint:"Dekuma Punkto",divide:"Dividi",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Nombra Baskulo",scrollLock:"Ruluma Baskulo",semiColon:"Punktokomo",equalSign:"Egalsigno",comma:"Komo",dash:"Haltostreko",period:"Punkto",forwardSlash:"Oblikvo",graveAccent:"Malakuto",openBracket:"Malferma Krampo",backSlash:"Retroklino",closeBracket:"Ferma Krampo",singleQuote:"Citilo"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/es.js b/release/plugins/a11yhelp/dialogs/lang/es.js
new file mode 100644 (file)
index 0000000..2aa0c5c
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","es",{title:"Instrucciones de accesibilidad",contents:"Ayuda. Para cerrar presione ESC.",legend:[{name:"General",items:[{name:"Barra de herramientas del editor",legend:'Presiona ${toolbarFocus} para navegar por la barra de herramientas. Para moverse por los distintos grupos de herramientas usa las teclas TAB y MAY+TAB. Para moverse por las distintas herramientas usa FLECHA DERECHA o FECHA IZQUIERDA. Presiona "espacio" o "intro" para activar la herramienta.'},{name:"Editor de diálogo",
+legend:"Dentro del diálogo, presione TAB para navegar a los siguientes elementos de diálogo, presione SHIFT+TAB para moverse a los anteriores elementos de diálogo, presione ENTER para enviar el diálogo, presiona ESC para cancelar el diálogo. Cuando el diálogo tiene multiples pestañas, la lista de pestañas puede ser abarcada con ALT + F10 or con TAB como parte del orden de pestañas del diálogo. ECon la pestaña enfocada, puede moverse a la siguiente o anterior pestaña con las FLECHAS IZQUIRDA y DERECHA respectivamente."},
+{name:"Editor del menú contextual",legend:"Presiona ${contextMenu} o TECLA MENÚ para abrir el menú contextual. Entonces muévete a la siguiente opción del menú con TAB o FLECHA ABAJO. Muévete a la opción previa con SHIFT + TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para seleccionar la opción del menú. Abre el submenú de la opción actual con ESPACIO o ENTER o FLECHA DERECHA. Regresa al elemento padre del menú con ESC o FLECHA IZQUIERDA. Cierra el menú contextual con ESC."},{name:"Lista del Editor",
+legend:"Dentro de una lista, te mueves al siguiente elemento de la lista con TAB o FLECHA ABAJO. Te mueves al elemento previo de la lista con SHIFT+TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para elegir la opción de la lista. Presiona ESC para cerrar la lista."},{name:"Barra de Ruta del Elemento en el Editor",legend:"Presiona ${elementsPathFocus} para navegar a los elementos de la barra de ruta. Te mueves al siguiente elemento botón con TAB o FLECHA DERECHA. Te mueves al botón previo con SHIFT+TAB o FLECHA IZQUIERDA. Presiona ESPACIO o ENTER para seleccionar el elemento en el editor."}]},
+{name:"Comandos",items:[{name:"Comando deshacer",legend:"Presiona ${undo}"},{name:"Comando rehacer",legend:"Presiona ${redo}"},{name:"Comando negrita",legend:"Presiona ${bold}"},{name:"Comando itálica",legend:"Presiona ${italic}"},{name:"Comando subrayar",legend:"Presiona ${underline}"},{name:"Comando liga",legend:"Presiona ${liga}"},{name:"Comando colapsar barra de herramientas",legend:"Presiona ${toolbarCollapse}"},{name:"Comando accesar el anterior espacio de foco",legend:"Presiona ${accessPreviousSpace} para accesar el espacio de foco no disponible más cercano anterior al cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes."},
+{name:"Comando accesar el siguiente spacio de foco",legend:"Presiona ${accessNextSpace} para accesar el espacio de foco no disponible más cercano después del cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes."},{name:"Ayuda de Accesibilidad",legend:"Presiona ${a11yHelp}"}]}],tab:"Tabulador",pause:"Pausa",capslock:"Bloq. Mayús.",escape:"Escape",pageUp:"Regresar Página",pageDown:"Avanzar Página",leftArrow:"Flecha Izquierda",upArrow:"Flecha Arriba",
+rightArrow:"Flecha Derecha",downArrow:"Flecha Abajo",insert:"Insertar",leftWindowKey:"Tecla Windows Izquierda",rightWindowKey:"Tecla Windows Derecha",selectKey:"Tecla de Selección",numpad0:"Tecla 0 del teclado numérico",numpad1:"Tecla 1 del teclado numérico",numpad2:"Tecla 2 del teclado numérico",numpad3:"Tecla 3 del teclado numérico",numpad4:"Tecla 4 del teclado numérico",numpad5:"Tecla 5 del teclado numérico",numpad6:"Tecla 6 del teclado numérico",numpad7:"Tecla 7 del teclado numérico",numpad8:"Tecla 8 del teclado numérico",
+numpad9:"Tecla 9 del teclado numérico",multiply:"Multiplicar",add:"Sumar",subtract:"Restar",decimalPoint:"Punto Decimal",divide:"Dividir",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Punto y coma",equalSign:"Signo de Igual",comma:"Coma",dash:"Guión",period:"Punto",forwardSlash:"Diagonal",graveAccent:"Acento Grave",openBracket:"Abrir llave",backSlash:"Diagonal Invertida",closeBracket:"Cerrar llave",
+singleQuote:"Comillas simples"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/et.js b/release/plugins/a11yhelp/dialogs/lang/et.js
new file mode 100644 (file)
index 0000000..c5987d4
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","et",{title:"Accessibility Instructions",contents:"Abi sisu. Selle dialoogi sulgemiseks vajuta ESC klahvi.",legend:[{name:"Üldine",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/eu.js b/release/plugins/a11yhelp/dialogs/lang/eu.js
new file mode 100644 (file)
index 0000000..36cf177
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","eu",{title:"Erabilerraztasunaren argibideak",contents:"Laguntzaren edukiak. Elkarrizketa-koadro hau ixteko sakatu ESC.",legend:[{name:"Orokorra",items:[{name:"Editorearen tresna-barra",legend:"Sakatu ${toolbarFocus} tresna-barrara nabigatzeko. Tresna-barrako aurreko eta hurrengo taldera joateko erabili TAB eta MAIUS+TAB. Tresna-barrako aurreko eta hurrengo botoira joateko erabili ESKUIN-GEZIA eta EZKER-GEZIA. Sakatu ZURIUNEA edo SARTU tresna-barrako botoia aktibatzeko."},
+{name:"Editorearen elkarrizketa-koadroa",legend:"Elkarrizketa-koadro baten barruan sakatu TAB hurrengo elementura nabigatzeko, sakatu MAIUS+TAB aurreko elementura joateko, sakatu SARTU elkarrizketa-koadroa bidaltzeko eta sakatu ESC uzteko. Elkarrizketa-koadro batek hainbat fitxa dituenean, ALT+F10 erabiliz irits daiteke fitxen zerrendara, edo TAB erabiliz. Fokoa fitxen zerrendak duenean, aurreko eta hurrengo fitxetara joateko erabili EZKER-GEZIA eta ESKUIN-GEZIA."},{name:"Editorearen testuinguru-menua",
+legend:"Sakatu ${contextMenu} edo APLIKAZIO TEKLA testuinguru-menua irekitzeko. Menuko hurrengo aukerara joateko erabili TAB edo BEHERA GEZIA. Aurreko aukerara nabigatzeko erabili MAIUS+TAB edo GORA GEZIA. Sakatu ZURIUNEA edo SARTU menuko aukera hautatzeko. Ireki uneko aukeraren azpi-menua ZURIUNEA edo SARTU edo ESKUIN-GEZIA erabiliz. Menuko aukera gurasora itzultzeko erabili ESC edo EZKER-GEZIA. Testuinguru-menua ixteko sakatu ESC."},{name:"Editorearen zerrenda-koadroa",legend:"Zerrenda-koadro baten barruan, zerrendako hurrengo elementura joateko erabili TAB edo BEHERA GEZIA. Zerrendako aurreko elementura nabigatzeko MAIUS+TAB edo GORA GEZIA. Sakatu ZURIUNEA edo SARTU zerrendako aukera hautatzeko. Sakatu ESC zerrenda-koadroa ixteko."},
+{name:"Editorearen elementuaren bide-barra",legend:"Sakatu ${elementsPathFocus} elementuaren bide-barrara nabigatzeko. Hurrengo elementuaren botoira joateko erabili TAB edo ESKUIN-GEZIA. Aurreko botoira joateko aldiz erabili MAIUS+TAB edo EZKER-GEZIA. Elementua editorean hautatzeko sakatu ZURIUNEA edo SARTU."}]},{name:"Komandoak",items:[{name:"Desegin komandoa",legend:"Sakatu ${undo}"},{name:"Berregin komandoa",legend:"Sakatu ${redo}"},{name:"Lodia komandoa",legend:"Sakatu ${bold}"},{name:"Etzana komandoa",
+legend:"Sakatu ${italic}"},{name:"Azpimarratu komandoa",legend:"Sakatu ${underline}"},{name:"Esteka komandoa",legend:"Sakatu ${link}"},{name:"Tolestu tresna-barra komandoa",legend:"Sakatu ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:"Erabilerraztasunaren laguntza",legend:"Sakatu ${a11yHelp}"}]}],tab:"Tabuladorea",pause:"Pausatu",capslock:"Blok Maius",escape:"Ihes",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Ezker-gezia",upArrow:"Gora gezia",rightArrow:"Eskuin-gezia",downArrow:"Behera gezia",insert:"Txertatu",leftWindowKey:"Ezkerreko Windows tekla",rightWindowKey:"Eskuineko Windows tekla",selectKey:"Hautatu tekla",numpad0:"Zenbakizko teklatua 0",numpad1:"Zenbakizko teklatua 1",numpad2:"Zenbakizko teklatua 2",numpad3:"Zenbakizko teklatua 3",
+numpad4:"Zenbakizko teklatua 4",numpad5:"Zenbakizko teklatua 5",numpad6:"Zenbakizko teklatua 6",numpad7:"Zenbakizko teklatua 7",numpad8:"Zenbakizko teklatua 8",numpad9:"Zenbakizko teklatua 9",multiply:"Biderkatu",add:"Gehitu",subtract:"Kendu",decimalPoint:"Koma hamartarra",divide:"Zatitu",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Blok Zenb",scrollLock:"Blok Korr",semiColon:"Puntu eta koma",equalSign:"Berdin zeinua",comma:"Koma",
+dash:"Marratxoa",period:"Puntua",forwardSlash:"Barra",graveAccent:"Azentu kamutsa",openBracket:"Parentesia ireki",backSlash:"Alderantzizko barra",closeBracket:"Itxi parentesia",singleQuote:"Komatxo bakuna"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/fa.js b/release/plugins/a11yhelp/dialogs/lang/fa.js
new file mode 100644 (file)
index 0000000..be36987
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","fa",{title:"دستورالعمل‌های دسترسی",contents:"راهنمای فهرست مطالب. برای بستن این کادر محاوره‌ای ESC را فشار دهید.",legend:[{name:"عمومی",items:[{name:"نوار ابزار ویرایشگر",legend:"${toolbarFocus} را برای باز کردن نوار ابزار بفشارید. با کلید Tab و Shift+Tab در مجموعه نوار ابزار بعدی و قبلی حرکت کنید. برای حرکت در کلید نوار ابزار قبلی و بعدی با کلید جهت‌نمای راست و چپ جابجا شوید. کلید Space یا Enter را برای فعال کردن کلید نوار ابزار بفشارید."},{name:"پنجره محاورهای ویرایشگر",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"منوی متنی ویرایشگر",legend:"${contextMenu} یا کلید برنامههای کاربردی را برای باز کردن منوی متن را بفشارید. سپس میتوانید برای حرکت به گزینه بعدی منو با کلید Tab و یا کلید جهتنمای پایین جابجا شوید. حرکت به گزینه قبلی با Shift+Tab یا کلید جهتنمای بالا. فشردن Space یا Enter برای انتخاب یک گزینه از منو. باز کردن زیر شاخه گزینه منو جاری با کلید Space یا Enter و یا کلید جهتنمای راست و چپ. بازگشت به منوی والد با کلید Esc یا کلید جهتنمای چپ. بستن منوی متن با Esc."},
+{name:"جعبه فهرست ویرایشگر",legend:"در داخل جعبه لیست، قلم دوم از اقلام لیست بعدی را با TAB و یا Arrow Down حرکت دهید. انتقال به قلم دوم از اقلام لیست قبلی را با SHIFT + TAB یا UP ARROW. کلید Space یا ENTER را برای انتخاب گزینه لیست بفشارید. کلید ESC را برای بستن جعبه لیست بفشارید."},{name:"ویرایشگر عنصر نوار راه",legend:"برای رفتن به مسیر عناصر ${elementsPathFocus} را بفشارید. حرکت به کلید عنصر بعدی با کلید Tab یا کلید جهت‌نمای راست. برگشت به کلید قبلی با Shift+Tab یا کلید جهت‌نمای چپ. فشردن Space یا Enter برای انتخاب یک عنصر در ویرایشگر."}]},
+{name:"فرمان‌ها",items:[{name:"بازگشت به آخرین فرمان",legend:"فشردن ${undo}"},{name:"انجام مجدد فرمان",legend:"فشردن ${redo}"},{name:"فرمان درشت کردن متن",legend:"فشردن ${bold}"},{name:"فرمان کج کردن متن",legend:"فشردن ${italic}"},{name:"فرمان زیرخطدار کردن متن",legend:"فشردن ${underline}"},{name:"فرمان پیوند دادن",legend:"فشردن ${link}"},{name:"بستن نوار ابزار فرمان",legend:"فشردن ${toolbarCollapse}"},{name:"دسترسی به فرمان محل تمرکز قبلی",legend:"فشردن ${accessPreviousSpace} برای دسترسی به نزدیک‌ترین فضای قابل دسترسی تمرکز قبل از هشتک، برای مثال: دو عنصر مجاور HR -خط افقی-. تکرار کلید ترکیبی برای رسیدن به فضاهای تمرکز از راه دور."},
+{name:"دسترسی به فضای دستور بعدی",legend:"برای دسترسی به نزدیک‌ترین فضای تمرکز غیر قابل دسترس، ${accessNextSpace} را پس از علامت هشتک بفشارید، برای مثال:  دو عنصر مجاور HR -خط افقی-. کلید ترکیبی را برای رسیدن به فضای تمرکز تکرار کنید."},{name:"راهنمای دسترسی",legend:"فشردن ${a11yHelp}"}]}],tab:"برگه",pause:"توقف",capslock:"Caps Lock",escape:"گریز",pageUp:"صفحه به بالا",pageDown:"صفحه به پایین",leftArrow:"پیکان چپ",upArrow:"پیکان بالا",rightArrow:"پیکان راست",downArrow:"پیکان پایین",insert:"ورود",
+leftWindowKey:"کلید چپ ویندوز",rightWindowKey:"کلید راست ویندوز",selectKey:"انتخاب کلید",numpad0:"کلید شماره 0",numpad1:"کلید شماره 1",numpad2:"کلید شماره 2",numpad3:"کلید شماره 3",numpad4:"کلید شماره 4",numpad5:"کلید شماره 5",numpad6:"کلید شماره 6",numpad7:"کلید شماره 7",numpad8:"کلید شماره 8",numpad9:"کلید شماره 9",multiply:"ضرب",add:"افزودن",subtract:"تفریق",decimalPoint:"نقطه‌ی اعشار",divide:"جدا کردن",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",
+f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"علامت تساوی",comma:"کاما",dash:"خط تیره",period:"دوره",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/fi.js b/release/plugins/a11yhelp/dialogs/lang/fi.js
new file mode 100644 (file)
index 0000000..28b5d28
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","fi",{title:"Saavutettavuus ohjeet",contents:"Ohjeen sisällöt. Sulkeaksesi tämän dialogin paina ESC.",legend:[{name:"Yleinen",items:[{name:"Editorin työkalupalkki",legend:"Paina ${toolbarFocus} siirtyäksesi työkalupalkkiin. Siirry seuraavaan ja edelliseen työkalupalkin ryhmään TAB ja SHIFT+TAB näppäimillä. Siirry seuraavaan ja edelliseen työkalupainikkeeseen käyttämällä NUOLI OIKEALLE tai NUOLI VASEMMALLE näppäimillä. Paina VÄLILYÖNTI tai ENTER näppäintä aktivoidaksesi työkalupainikkeen."},
+{name:"Editorin dialogi",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Editorin oheisvalikko",legend:"Paina ${contextMenu} tai SOVELLUSPAINIKETTA avataksesi oheisvalikon. Liiku seuraavaan valikon vaihtoehtoon TAB tai NUOLI ALAS näppäimillä. Siirry edelliseen vaihtoehtoon SHIFT+TAB tai NUOLI YLÖS näppäimillä. Paina VÄLILYÖNTI tai ENTER valitaksesi valikon kohdan. Avataksesi nykyisen kohdan alivalikon paina VÄLILYÖNTI tai ENTER tai NUOLI OIKEALLE painiketta. Siirtyäksesi takaisin valikon ylemmälle tasolle paina ESC tai NUOLI vasemmalle. Oheisvalikko suljetaan ESC painikkeella."},
+{name:"Editorin listalaatikko",legend:"Listalaatikon sisällä siirry seuraavaan listan kohtaan TAB tai NUOLI ALAS painikkeilla. Siirry edelliseen listan kohtaan SHIFT+TAB tai NUOLI YLÖS painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi listan vaihtoehdon. Paina ESC sulkeaksesi listalaatikon."},{name:"Editorin elementtipolun palkki",legend:"Paina ${elementsPathFocus} siirtyäksesi elementtipolun palkkiin. Siirry seuraavaan elementtipainikkeeseen TAB tai NUOLI OIKEALLE painikkeilla. Siirry aiempaan painikkeeseen SHIFT+TAB tai NUOLI VASEMMALLE painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi elementin editorissa."}]},
+{name:"Komennot",items:[{name:"Peruuta komento",legend:"Paina ${undo}"},{name:"Tee uudelleen komento",legend:"Paina ${redo}"},{name:"Lihavoi komento",legend:"Paina ${bold}"},{name:"Kursivoi komento",legend:"Paina ${italic}"},{name:"Alleviivaa komento",legend:"Paina ${underline}"},{name:"Linkki komento",legend:"Paina ${link}"},{name:"Pienennä työkalupalkki komento",legend:"Paina ${toolbarCollapse}"},{name:"Siirry aiempaan fokustilaan komento",legend:"Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin edellä olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin."},
+{name:"Siirry seuraavaan fokustilaan komento",legend:"Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin jälkeen olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin."},{name:"Saavutettavuus ohjeet",legend:"Paina ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",
+downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numeronäppäimistö 0",numpad1:"Numeronäppäimistö 1",numpad2:"Numeronäppäimistö 2",numpad3:"Numeronäppäimistö 3",numpad4:"Numeronäppäimistö 4",numpad5:"Numeronäppäimistö 5",numpad6:"Numeronäppäimistö 6",numpad7:"Numeronäppäimistö 7",numpad8:"Numeronäppäimistö 8",numpad9:"Numeronäppäimistö 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",
+divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Puolipiste",equalSign:"Equal Sign",comma:"Pilkku",dash:"Dash",period:"Piste",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/fo.js b/release/plugins/a11yhelp/dialogs/lang/fo.js
new file mode 100644 (file)
index 0000000..03e54f1
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","fo",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"General",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Falda",add:"Pluss",subtract:"Frádráttar",decimalPoint:"Decimal Point",divide:"Býta",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semikolon",equalSign:"Javnatekn",comma:"Komma",dash:"Dash",period:"Punktum",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/fr-ca.js b/release/plugins/a11yhelp/dialogs/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..5aac06b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","fr-ca",{title:"Instructions d'accessibilité",contents:"Contenu de l'aide.  Pour fermer cette fenêtre, appuyez sur ESC.",legend:[{name:"Général",items:[{name:"Barre d'outil de l'éditeur",legend:"Appuyer sur ${toolbarFocus} pour accéder à la barre d'outils. Se déplacer vers les groupes suivant ou précédent de la barre d'outil avec les touches TAB et SHIFT+TAB. Se déplacer vers les boutons suivant ou précédent de la barre d'outils avec les touches FLECHE DROITE et FLECHE GAUCHE. Appuyer sur la barre d'espace ou la touche ENTRER pour activer le bouton de barre d'outils."},
+{name:"Dialogue de l'éditeur",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Menu contextuel de l'éditeur",legend:"Appuyer sur ${contextMenu} ou entrer le RACCOURCI CLAVIER pour ouvrir le menu contextuel. Puis se déplacer vers l'option suivante du menu avec les touches TAB ou FLECHE BAS. Se déplacer vers l'option précédente avec les touches SHIFT+TAB ou FLECHE HAUT. appuyer sur la BARRE D'ESPACE ou la touche ENTREE pour sélectionner l'option du menu. Oovrir le sous-menu de l'option courante avec la BARRE D'ESPACE ou les touches ENTREE ou FLECHE DROITE. Revenir à l'élément de menu parent avec les touches ESC ou FLECHE GAUCHE. Fermer le menu contextuel avec ESC."},
+{name:"Menu déroulant de l'éditeur",legend:"A l'intérieur d'une liste en menu déroulant, se déplacer vers l'élément suivant de la liste avec les touches TAB ou FLECHE BAS. Se déplacer vers l'élément précédent de la liste avec les touches SHIFT+TAB ou FLECHE HAUT. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'option dans la liste. Appuyer sur ESC pour fermer le menu déroulant."},{name:"Barre d'emplacement des éléments de l'éditeur",legend:"Appuyer sur ${elementsPathFocus} pour naviguer vers la barre d'emplacement des éléments de léditeur. Se déplacer vers le bouton d'élément suivant avec les touches TAB ou FLECHE DROITE. Se déplacer vers le bouton d'élément précédent avec les touches SHIFT+TAB ou FLECHE GAUCHE. Appuyer sur la BARRE D'ESPACE ou sur ENTREE pour sélectionner l'élément dans l'éditeur."}]},
+{name:"Commandes",items:[{name:"Annuler",legend:"Appuyer sur ${undo}"},{name:"Refaire",legend:"Appuyer sur ${redo}"},{name:"Gras",legend:"Appuyer sur ${bold}"},{name:"Italique",legend:"Appuyer sur ${italic}"},{name:"Souligné",legend:"Appuyer sur ${underline}"},{name:"Lien",legend:"Appuyer sur ${link}"},{name:"Enrouler la barre d'outils",legend:"Appuyer sur ${toolbarCollapse}"},{name:"Accéder à l'objet de focus précédent",legend:"Appuyer ${accessPreviousSpace} pour accéder au prochain espace disponible avant le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d'espaces distantes."},
+{name:"Accéder au prochain objet de focus",legend:"Appuyer ${accessNextSpace} pour accéder au prochain espace disponible après le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d'espaces distantes."},{name:"Aide d'accessibilité",legend:"Appuyer sur ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",
+insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",
+scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/fr.js b/release/plugins/a11yhelp/dialogs/lang/fr.js
new file mode 100644 (file)
index 0000000..0cf67e8
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","fr",{title:"Instructions d'accessibilité",contents:"Contenu de l'aide. Pour fermer cette fenêtre, appuyez sur la touche Échap.",legend:[{name:"Général",items:[{name:"Barre d'outils de l'éditeur",legend:"Appuyer sur ${toolbarFocus} pour accéder à la barre d'outils. Se déplacer vers le groupe suivant ou précédent de la barre d'outils avec les touches Tab et Maj+Tab. Se déplacer vers le bouton suivant ou précédent de la barre d'outils avec les touches Flèche droite et Flèche gauche. Appuyer sur la barre d'espace ou la touche Entrée pour activer le bouton de barre d'outils."},
+{name:"Fenêtre de l'éditeur",legend:"Dans une boîte de dialogue, appuyer sur Tab pour passer à l'élément suivant, appuyer sur Maj+Tab pour passer à l'élément précédent, appuyer sur Entrée pour valider, appuyer sur Échap pour annuler. Quand une boîte de dialogue possède des onglets, la liste peut être atteinte avec Alt+F10 ou avec Tab. Dans la liste des onglets, se déplacer vers le suivant et le précédent avec les touches Flèche droite et Flèche gauche respectivement."},{name:"Menu contextuel de l'éditeur",
+legend:"Appuyer sur ${contextMenu} ou sur la touche Menu pour ouvrir le menu contextuel. Se déplacer ensuite vers l'option suivante du menu avec les touches Tab ou Flèche bas. Se déplacer vers l'option précédente avec les touches Maj+Tab ou Flèche haut. Appuyer sur la barre d'espace ou la touche Entrée pour sélectionner l'option du menu. Appuyer sur la barre d'espace, la touche Entrée ou Flèche droite pour ouvrir le sous-menu de l'option sélectionnée. Revenir à l'élément de menu parent avec la touche Échap ou Flèche gauche. Fermer le menu contextuel avec Échap."},
+{name:"Zone de liste de l'éditeur",legend:"Dans une liste en menu déroulant, se déplacer vers l'élément suivant de la liste avec les touches Tab ou Flèche bas. Se déplacer vers l'élément précédent de la liste avec les touches Maj+Tab ou Flèche haut. Appuyer sur la barre d'espace ou sur Entrée pour sélectionner l'option dans la liste. Appuyer sur Échap pour fermer le menu déroulant."},{name:"Barre du chemin d'éléments de l'éditeur",legend:"Appuyer sur ${elementsPathFocus} pour naviguer vers la barre du fil d'Ariane des éléments. Se déplacer vers le bouton de l'élément suivant avec les touches Tab ou Flèche droite. Se déplacer vers le bouton précédent avec les touches Maj+Tab ou Flèche gauche. Appuyer sur la barre d'espace ou sur Entrée pour sélectionner l'élément dans l'éditeur."}]},
+{name:"Commandes",items:[{name:" Annuler la commande",legend:"Appuyer sur ${undo}"},{name:"Commande restaurer",legend:"Appuyer sur ${redo}"},{name:" Commande gras",legend:"Appuyer sur ${bold}"},{name:" Commande italique",legend:"Appuyer sur ${italic}"},{name:" Commande souligné",legend:"Appuyer sur ${underline}"},{name:" Commande lien",legend:"Appuyer sur ${link}"},{name:" Commande enrouler la barre d'outils",legend:"Appuyer sur ${toolbarCollapse}"},{name:"Commande d'accès à l'élément sélectionnable précédent",
+legend:"Appuyer sur ${accessNextSpace} pour accéder à l'élément sélectionnable inatteignable le plus proche avant le curseur, par exemple : deux lignes horizontales adjacentes. Répéter la combinaison de touches pour atteindre les éléments sélectionnables précédents."},{name:"Commande d'accès à l'élément sélectionnable suivant",legend:"Appuyer sur ${accessNextSpace} pour accéder à l'élément sélectionnable inatteignable le plus proche après le curseur, par exemple : deux lignes horizontales adjacentes. Répéter la combinaison de touches pour atteindre les éléments sélectionnables suivants."},
+{name:" Aide sur l'accessibilité",legend:"Appuyer sur ${a11yHelp}"}]}],tab:"Tabulation",pause:"Pause",capslock:"Verr. Maj.",escape:"Échap",pageUp:"Page supérieure",pageDown:"Page suivante",leftArrow:"Flèche gauche",upArrow:"Flèche haut",rightArrow:"Flèche droite",downArrow:"Flèche basse",insert:"Inser",leftWindowKey:"Touche Windows gauche",rightWindowKey:"Touche Windows droite",selectKey:"Touche Sélectionner",numpad0:"0 du pavé numérique",numpad1:"1 du pavé numérique",numpad2:"2 du pavé numérique",
+numpad3:"3 du pavé numérique",numpad4:"4 du pavé numérique",numpad5:"5 du pavé numérique",numpad6:"6 du pavé numérique",numpad7:"7 du pavé numérique",numpad8:"Pavé numérique 8",numpad9:"9 du pavé numérique",multiply:"Multiplier",add:"Plus",subtract:"Moins",decimalPoint:"Point décimal",divide:"Diviser",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Verr. Num.",scrollLock:"Arrêt défil.",semiColon:"Point-virgule",equalSign:"Signe égal",
+comma:"Virgule",dash:"Tiret",period:"Point",forwardSlash:"Barre oblique",graveAccent:"Accent grave",openBracket:"Parenthèse ouvrante",backSlash:"Barre oblique inverse",closeBracket:"Parenthèse fermante",singleQuote:"Apostrophe"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/gl.js b/release/plugins/a11yhelp/dialogs/lang/gl.js
new file mode 100644 (file)
index 0000000..43dc741
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","gl",{title:"Instrucións de accesibilidade",contents:"Axuda. Para pechar este diálogo prema ESC.",legend:[{name:"Xeral",items:[{name:"Barra de ferramentas do editor",legend:"Prema ${toolbarFocus} para navegar pola barra de ferramentas. Para moverse polos distintos grupos de ferramentas use as teclas TAB e MAIÚS+TAB. Para moverse polas distintas ferramentas use FRECHA DEREITA ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para activar o botón da barra de ferramentas."},
+{name:"Editor de diálogo",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Editor do menú contextual",legend:"Prema ${contextMenu} ou a TECLA MENÚ para abrir o menú contextual. A seguir móvase á seguinte opción do menú con TAB ou FRECHA ABAIXO. Móvase á opción anterior con MAIÚS + TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para seleccionar a opción do menú. Abra o submenú da opción actual con ESPAZO ou INTRO ou FRECHA DEREITA. Regrese ao elemento principal do menú con ESC ou FRECHA ESQUERDA. Peche o menú contextual con ESC."},
+{name:"Lista do editor",legend:"Dentro dunha lista, móvase ao seguinte elemento da lista con TAB ou FRECHA ABAIXO. Móvase ao elemento anterior da lista con MAIÚS+TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para escoller a opción da lista. Prema ESC para pechar a lista."},{name:"Barra da ruta ao elemento no editor",legend:"Prema ${elementsPathFocus} para navegar ata os elementos da barra de ruta. Móvase ao seguinte elemento botón con TAB ou FRECHA DEREITA. Móvase ao botón anterior con MAIÚS+TAB ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para seleccionar o elemento no editor."}]},
+{name:"Ordes",items:[{name:"Orde «desfacer»",legend:"Prema ${undo}"},{name:"Orde «refacer»",legend:"Prema ${redo}"},{name:"Orde «negra»",legend:"Prema ${bold}"},{name:"Orde «cursiva»",legend:"Prema ${italic}"},{name:"Orde «subliñar»",legend:"Prema ${underline}"},{name:"Orde «ligazón»",legend:"Prema ${link}"},{name:"Orde «contraer a barra de ferramentas»",legend:"Prema ${toolbarCollapse}"},{name:"Orde «acceder ao anterior espazo en foco»",legend:"Prema ${accessPreviousSpace} para acceder ao espazo máis próximo de foco inalcanzábel anterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes."},
+{name:"Orde «acceder ao seguinte espazo en foco»",legend:"Prema ${accessNextSpace} para acceder ao espazo máis próximo de foco inalcanzábel posterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes."},{name:"Axuda da accesibilidade",legend:"Prema ${a11yHelp}"}]}],tab:"Tabulador",pause:"Pausa",capslock:"Bloq. Maiús",escape:"Escape",pageUp:"Páxina arriba",pageDown:"Páxina abaixo",leftArrow:"Frecha esquerda",upArrow:"Frecha arriba",
+rightArrow:"Frecha dereita",downArrow:"Frecha abaixo",insert:"Inserir",leftWindowKey:"Tecla Windows esquerda",rightWindowKey:"Tecla Windows dereita",selectKey:"Escolla a tecla",numpad0:"Tec. numérico 0",numpad1:"Tec. numérico 1",numpad2:"Tec. numérico 2",numpad3:"Tec. numérico 3",numpad4:"Tec. numérico 4",numpad5:"Tec. numérico 5",numpad6:"Tec. numérico 6",numpad7:"Tec. numérico 7",numpad8:"Tec. numérico 8",numpad9:"Tec. numérico 9",multiply:"Multiplicar",add:"Sumar",subtract:"Restar",decimalPoint:"Punto decimal",
+divide:"Dividir",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Bloq. num.",scrollLock:"Bloq. despraz.",semiColon:"Punto e coma",equalSign:"Signo igual",comma:"Coma",dash:"Guión",period:"Punto",forwardSlash:"Barra inclinada",graveAccent:"Acento grave",openBracket:"Abrir corchete",backSlash:"Barra invertida",closeBracket:"Pechar corchete",singleQuote:"Comiña simple"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/gu.js b/release/plugins/a11yhelp/dialogs/lang/gu.js
new file mode 100644 (file)
index 0000000..f6e83f3
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","gu",{title:"એક્ક્ષેબિલિટી ની વિગતો",contents:"હેલ્પ. આ બંધ કરવા ESC દબાવો.",legend:[{name:"જનરલ",items:[{name:"એડિટર ટૂલબાર",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"એડિટર ડાયલોગ",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"કમાંડસ",items:[{name:"અન્ડું કમાંડ",legend:"$ દબાવો {undo}"},{name:"ફરી કરો કમાંડ",legend:"$ દબાવો {redo}"},{name:"બોલ્દનો કમાંડ",legend:"$ દબાવો {bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/he.js b/release/plugins/a11yhelp/dialogs/lang/he.js
new file mode 100644 (file)
index 0000000..9c86b8c
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","he",{title:"הוראות נגישות",contents:"הוראות נגישות. לסגירה לחץ אסקייפ (ESC).",legend:[{name:"כללי",items:[{name:"סרגל הכלים",legend:"לחץ על ${toolbarFocus} כדי לנווט לסרגל הכלים. עבור לכפתור הבא עם מקש הטאב (TAB) או חץ שמאלי. עבור לכפתור הקודם עם מקש השיפט (SHIFT) + טאב (TAB) או חץ ימני. לחץ רווח או אנטר (ENTER) כדי להפעיל את הכפתור הנבחר."},{name:"דיאלוגים (חלונות תשאול)",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"תפריט ההקשר (Context Menu)",legend:"לחץ ${contextMenu} או APPLICATION KEYכדי לפתוח את תפריט ההקשר. עבור לאפשרות הבאה עם טאב (TAB) או חץ למטה. עבור לאפשרות הקודמת עם שיפט (SHIFT) + טאב (TAB) או חץ למעלה. לחץ רווח או אנטר (ENTER) כדי לבחור את האפשרות. פתח את תת התפריט (Sub-menu) של האפשרות הנוכחית עם רווח או אנטר (ENTER) או חץ שמאלי. חזור לתפריט האב עם אסקייפ (ESC) או חץ שמאלי. סגור את תפריט ההקשר עם אסקייפ (ESC)."},{name:"תפריטים צפים (List boxes)",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"עץ אלמנטים (Elements Path)",legend:"לחץ ${elementsPathFocus} כדי לנווט לעץ האלמנטים. עבור לפריט הבא עם טאב (TAB) או חץ ימני. עבור לפריט הקודם עם שיפט (SHIFT) + טאב (TAB) או חץ שמאלי. לחץ רווח או אנטר (ENTER) כדי לבחור את האלמנט בעורך."}]},{name:"פקודות",items:[{name:" ביטול צעד אחרון",legend:"לחץ ${undo}"},{name:" חזרה על צעד אחרון",legend:"לחץ ${redo}"},{name:" הדגשה",legend:"לחץ ${bold}"},{name:" הטייה",legend:"לחץ ${italic}"},{name:" הוספת קו תחתון",legend:"לחץ ${underline}"},{name:" הוספת לינק",
+legend:"לחץ ${link}"},{name:" כיווץ סרגל הכלים",legend:"לחץ ${toolbarCollapse}"},{name:"גישה למיקום המיקוד הקודם",legend:"לחץ ${accessPreviousSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב לפני הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר."},{name:"גישה למיקום המיקוד הבא",legend:"לחץ ${accessNextSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב אחרי הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר."},
+{name:" הוראות נגישות",legend:"לחץ ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"חץ שמאלה",upArrow:"חץ למעלה",rightArrow:"חץ ימינה",downArrow:"חץ למטה",insert:"הכנס",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"בחר מקש",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",
+numpad9:"Numpad 9",multiply:"Multiply",add:"הוסף",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"סלאש",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"סלאש הפוך",closeBracket:"Close Bracket",singleQuote:"ציטוט יחיד"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/hi.js b/release/plugins/a11yhelp/dialogs/lang/hi.js
new file mode 100644 (file)
index 0000000..5443d24
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","hi",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"सामान्य",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/hr.js b/release/plugins/a11yhelp/dialogs/lang/hr.js
new file mode 100644 (file)
index 0000000..7434d61
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","hr",{title:"Upute dostupnosti",contents:"Sadržaj pomoći. Za zatvaranje pritisnite ESC.",legend:[{name:"Općenito",items:[{name:"Alatna traka",legend:"Pritisni ${toolbarFocus} za navigaciju do alatne trake. Pomicanje do prethodne ili sljedeće alatne grupe vrši se pomoću SHIFT+TAB i TAB. Pomicanje do prethodnog ili sljedećeg gumba u alatnoj traci vrši se pomoću lijeve i desne strelice kursora. Pritisnite SPACE ili ENTER za aktivaciju alatne trake."},{name:"Dijalog",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Kontekstni izbornik",legend:"Pritisnite ${contextMenu} ili APPLICATION tipku za otvaranje kontekstnog izbornika. Pomicanje se vrši TAB ili strelicom kursora prema dolje ili SHIFT+TAB ili strelica kursora prema gore. SPACE ili ENTER odabiru opciju izbornika. Otvorite podizbornik trenutne opcije sa  SPACE, ENTER ili desna strelica kursora. Povratak na prethodni izbornik vrši se sa ESC ili lijevom strelicom kursora. Zatvaranje se vrši pritiskom na tipku ESC."},
+{name:"Lista",legend:"Unutar list-boxa, pomicanje na sljedeću stavku vrši se sa TAB ili strelica kursora prema dolje. Na prethodnu sa SHIFT+TAB ili strelica prema gore. Pritiskom na SPACE ili ENTER odabire se stavka ili ESC za zatvaranje."},{name:"Traka putanje elemenata",legend:"Pritisnite ${elementsPathFocus} za navigaciju po putanji elemenata. Pritisnite TAB ili desnu strelicu kursora za pomicanje na sljedeći element ili SHIFT+TAB ili lijeva strelica kursora za pomicanje na prethodni element. Pritiskom na SPACE ili ENTER vrši se odabir elementa."}]},
+{name:"Naredbe",items:[{name:"Vrati naredbu",legend:"Pritisni ${undo}"},{name:"Ponovi naredbu",legend:"Pritisni ${redo}"},{name:"Bold naredba",legend:"Pritisni ${bold}"},{name:"Italic naredba",legend:"Pritisni ${italic}"},{name:"Underline naredba",legend:"Pritisni ${underline}"},{name:"Link naredba",legend:"Pritisni ${link}"},{name:"Smanji alatnu traku naredba",legend:"Pritisni ${toolbarCollapse}"},{name:"Access previous focus space naredba",legend:"Pritisni ${accessPreviousSpace} za pristup najbližem nedostupnom razmaku prije kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak."},
+{name:"Access next focus space naredba",legend:"Pritisni ${accessNextSpace} za pristup najbližem nedostupnom razmaku nakon kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak."},{name:"Pomoć za dostupnost",legend:"Pritisni ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",
+rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",
+equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/hu.js b/release/plugins/a11yhelp/dialogs/lang/hu.js
new file mode 100644 (file)
index 0000000..b547453
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","hu",{title:"Kisegítő utasítások",contents:"Súgó tartalmak. A párbeszédablak bezárásához nyomjon ESC-et.",legend:[{name:"Általános",items:[{name:"Szerkesztő Eszköztár",legend:"Nyomjon ${toolbarFocus} hogy kijelölje az eszköztárat. A következő és előző eszköztár csoporthoz a TAB és SHIFT+TAB-al juthat el. A következő és előző eszköztár gombhoz a BAL NYÍL vagy JOBB NYÍL gombbal juthat el. Nyomjon SPACE-t vagy ENTER-t hogy aktiválja az eszköztár gombot."},{name:"Szerkesző párbeszéd ablak",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Szerkesztő helyi menü",legend:"Nyomjon ${contextMenu}-t vagy ALKALMAZÁS BILLENTYŰT a helyi menü megnyitásához. Ezután a következő menüpontra léphet a TAB vagy LEFELÉ NYÍLLAL. Az előző opciót a SHIFT+TAB vagy FELFELÉ NYÍLLAL érheti el. Nyomjon SPACE-t vagy ENTER-t a menüpont kiválasztásához. A jelenlegi menüpont almenüjének megnyitásához nyomjon SPACE-t vagy ENTER-t, vagy JOBB NYILAT. A főmenühöz való visszatéréshez nyomjon ESC-et vagy BAL NYILAT. A helyi menü bezárása az ESC billentyűvel lehetséges."},
+{name:"Szerkesztő lista",legend:"A listán belül a következő elemre a TAB vagy LEFELÉ NYÍLLAL mozoghat. Az előző elem kiválasztásához nyomjon SHIFT+TAB-ot vagy FELFELÉ NYILAT. Nyomjon SPACE-t vagy ENTER-t az elem kiválasztásához. Az ESC billentyű megnyomásával bezárhatja a listát."},{name:"Szerkesztő elem utak sáv",legend:"Nyomj ${elementsPathFocus} hogy kijelöld a elemek út sávját. A következő elem gombhoz a TAB-al vagy a JOBB NYÍLLAL juthatsz el. Az előző gombhoz a SHIFT+TAB vagy BAL NYÍLLAL mehetsz. A SPACE vagy ENTER billentyűvel kiválaszthatod az elemet a szerkesztőben."}]},
+{name:"Parancsok",items:[{name:"Parancs visszavonása",legend:"Nyomj ${undo}"},{name:"Parancs megismétlése",legend:"Nyomjon ${redo}"},{name:"Félkövér parancs",legend:"Nyomjon ${bold}"},{name:"Dőlt parancs",legend:"Nyomjon ${italic}"},{name:"Aláhúzott parancs",legend:"Nyomjon ${underline}"},{name:"Link parancs",legend:"Nyomjon ${link}"},{name:"Szerkesztősáv összecsukása parancs",legend:"Nyomjon ${toolbarCollapse}"},{name:"Hozzáférés az előző fókusz helyhez parancs",legend:"Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel előtt, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket."},
+{name:"Hozzáférés a következő fókusz helyhez parancs",legend:"Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel után, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket."},{name:"Kisegítő súgó",legend:"Nyomjon ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"balra nyíl",upArrow:"felfelé nyíl",rightArrow:"jobbra nyíl",
+downArrow:"lefelé nyíl",insert:"Insert",leftWindowKey:"bal Windows-billentyű",rightWindowKey:"jobb Windows-billentyű",selectKey:"Billentyű választása",numpad0:"Számbillentyűk 0",numpad1:"Számbillentyűk 1",numpad2:"Számbillentyűk 2",numpad3:"Számbillentyűk 3",numpad4:"Számbillentyűk 4",numpad5:"Számbillentyűk 5",numpad6:"Számbillentyűk 6",numpad7:"Számbillentyűk 7",numpad8:"Számbillentyűk 8",numpad9:"Számbillentyűk 9",multiply:"Szorzás",add:"Hozzáadás",subtract:"Kivonás",decimalPoint:"Tizedespont",
+divide:"Osztás",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Pontosvessző",equalSign:"Egyenlőségjel",comma:"Vessző",dash:"Kötőjel",period:"Pont",forwardSlash:"Perjel",graveAccent:"Visszafelé dőlő ékezet",openBracket:"Nyitó szögletes zárójel",backSlash:"fordított perjel",closeBracket:"Záró szögletes zárójel",singleQuote:"szimpla idézőjel"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/id.js b/release/plugins/a11yhelp/dialogs/lang/id.js
new file mode 100644 (file)
index 0000000..8177096
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","id",{title:"Instruksi Accessibility",contents:"Bantuan. Tekan ESC untuk menutup dialog ini.",legend:[{name:"Umum",items:[{name:"Toolbar Editor",legend:"Tekan ${toolbarFocus} untuk berpindah ke toolbar. Untuk berpindah ke group toolbar selanjutnya dan sebelumnya gunakan TAB dan SHIFT+TAB. Untuk berpindah ke tombol toolbar selanjutnya dan sebelumnya gunakan RIGHT ARROW atau LEFT ARROW. Tekan SPASI atau ENTER untuk mengaktifkan tombol toolbar."},{name:"Dialog Editor",
+legend:"Pada jendela dialog, tekan TAB untuk berpindah pada elemen dialog selanjutnya, tekan SHIFT+TAB untuk berpindah pada elemen dialog sebelumnya, tekan ENTER untuk submit dialog, tekan ESC untuk membatalkan dialog. Pada dialog dengan multi tab, daftar tab dapat diakses dengan ALT+F10 ataupun dengan tombol TAB sesuai urutan tab pada dialog. Jika daftar tab aktif terpilih, untuk berpindah tab dapat menggunakan RIGHT dan LEFT ARROW."},{name:"Context Menu Editor",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},
+{name:"List Box Editor",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},
+{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",
+rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",
+equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/it.js b/release/plugins/a11yhelp/dialogs/lang/it.js
new file mode 100644 (file)
index 0000000..8824874
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","it",{title:"Istruzioni di Accessibilità",contents:"Contenuti di Aiuto. Per chiudere questa finestra premi ESC.",legend:[{name:"Generale",items:[{name:"Barra degli strumenti Editor",legend:"Premere ${toolbarFocus} per passare alla barra degli strumenti. Usare TAB per spostarsi al gruppo successivo, MAIUSC+TAB per spostarsi a quello precedente. Usare FRECCIA DESTRA per spostarsi al pulsante successivo, FRECCIA SINISTRA per spostarsi a quello precedente. Premere SPAZIO o INVIO per attivare il pulsante della barra degli strumenti."},
+{name:"Finestra Editor",legend:"All'interno di una finestra di dialogo è possibile premere TAB per passare all'elemento successivo della finestra, MAIUSC+TAB per passare a quello precedente; premere INVIO per inviare i dati della finestra, oppure ESC per annullare l'operazione. Quando una finestra di dialogo ha più schede, è possibile passare all'elenco delle schede sia con ALT+F10 che con TAB, in base all'ordine delle tabulazioni della finestra. Quando l'elenco delle schede è attivo, premere la FRECCIA DESTRA o la FRECCIA SINISTRA per passare rispettivamente alla scheda successiva o a quella precedente."},
+{name:"Menù contestuale Editor",legend:"Premi ${contextMenu} o TASTO APPLICAZIONE per aprire il menu contestuale. Dunque muoviti all'opzione successiva del menu con il tasto TAB o con la Freccia Sotto. Muoviti all'opzione precedente con  MAIUSC+TAB o con Freccia Sopra. Premi SPAZIO o INVIO per scegliere l'opzione di menu. Apri il sottomenu dell'opzione corrente con SPAZIO o INVIO oppure con la Freccia Destra. Torna indietro al menu superiore con ESC oppure Freccia Sinistra. Chiudi il menu contestuale con ESC."},
+{name:"Box Lista Editor",legend:"All'interno di un elenco di opzioni, per spostarsi all'elemento successivo premere TAB oppure FRECCIA GIÙ. Per spostarsi all'elemento precedente usare SHIFT+TAB oppure FRECCIA SU. Premere SPAZIO o INVIO per selezionare l'elemento della lista. Premere ESC per chiudere l'elenco di opzioni."},{name:"Barra percorso elementi editor",legend:"Premere ${elementsPathFocus} per passare agli elementi della barra del percorso. Usare TAB o FRECCIA DESTRA per passare al pulsante successivo. Per passare al pulsante precedente premere MAIUSC+TAB o FRECCIA SINISTRA. Premere SPAZIO o INVIO per selezionare l'elemento nell'editor."}]},
+{name:"Comandi",items:[{name:" Annulla comando",legend:"Premi ${undo}"},{name:" Ripeti comando",legend:"Premi ${redo}"},{name:" Comando Grassetto",legend:"Premi ${bold}"},{name:" Comando Corsivo",legend:"Premi ${italic}"},{name:" Comando Sottolineato",legend:"Premi ${underline}"},{name:" Comando Link",legend:"Premi ${link}"},{name:" Comando riduci barra degli strumenti",legend:"Premi ${toolbarCollapse}"},{name:"Comando di accesso al precedente spazio di focus",legend:"Premi ${accessPreviousSpace} per accedere il più vicino spazio di focus non raggiungibile prima del simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti."},
+{name:"Comando di accesso al prossimo spazio di focus",legend:"Premi ${accessNextSpace} per accedere il più vicino spazio di focus non raggiungibile dopo il simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti."},{name:" Aiuto Accessibilità",legend:"Premi ${a11yHelp}"}]}],tab:"Tab",pause:"Pausa",capslock:"Bloc Maiusc",escape:"Esc",pageUp:"Pagina sù",pageDown:"Pagina giù",leftArrow:"Freccia sinistra",upArrow:"Freccia su",rightArrow:"Freccia destra",
+downArrow:"Freccia giù",insert:"Ins",leftWindowKey:"Tasto di Windows sinistro",rightWindowKey:"Tasto di Windows destro",selectKey:"Tasto di selezione",numpad0:"0 sul tastierino numerico",numpad1:"1 sul tastierino numerico",numpad2:"2 sul tastierino numerico",numpad3:"3 sul tastierino numerico",numpad4:"4 sul tastierino numerico",numpad5:"5 sul tastierino numerico",numpad6:"6 sul tastierino numerico",numpad7:"7 sul tastierino numerico",numpad8:"8 sul tastierino numerico",numpad9:"9 sul tastierino numerico",
+multiply:"Moltiplicazione",add:"Più",subtract:"Sottrazione",decimalPoint:"Punto decimale",divide:"Divisione",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Bloc Num",scrollLock:"Bloc Scorr",semiColon:"Punto-e-virgola",equalSign:"Segno di uguale",comma:"Virgola",dash:"Trattino",period:"Punto",forwardSlash:"Barra",graveAccent:"Accento grave",openBracket:"Parentesi quadra aperta",backSlash:"Barra rovesciata",closeBracket:"Parentesi quadra chiusa",
+singleQuote:"Apostrofo"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ja.js b/release/plugins/a11yhelp/dialogs/lang/ja.js
new file mode 100644 (file)
index 0000000..abcca24
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ja",{title:"ユーザー補助の説明",contents:"ヘルプ このダイアログを閉じるには ESCを押してください。",legend:[{name:"全般",items:[{name:"エディターツールバー",legend:"${toolbarFocus} を押すとツールバーのオン/オフ操作ができます。カーソルをツールバーのグループで移動させるにはTabかSHIFT+Tabを押します。グループ内でカーソルを移動させるには、右カーソルか左カーソルを押します。スペースキーやエンターを押すとボタンを有効/無効にすることができます。"},{name:"編集ダイアログ",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"エディターのメニュー",legend:"${contextMenu} キーかAPPLICATION KEYを押すとコンテキストメニューが開きます。Tabか下カーソルでメニューのオプション選択が下に移動します。戻るには、SHIFT+Tabか上カーソルです。スペースもしくはENTERキーでメニューオプションを決定できます。現在選んでいるオプションのサブメニューを開くには、スペース、もしくは右カーソルを押します。サブメニューから親メニューに戻るには、ESCか左カーソルを押してください。ESCでコンテキストメニュー自体をキャンセルできます。"},{name:"エディターリストボックス",legend:"リストボックス内で移動するには、Tabか下カーソルで次のアイテムへ移動します。SHIFT+Tabで前のアイテムに戻ります。リストのオプションを選択するには、スペースもしくは、ENTERを押してください。リストボックスを閉じるには、ESCを押してください。"},{name:"エディター要素パスバー",legend:"${elementsPathFocus} を押すとエレメントパスバーを操作出来ます。Tabか右カーソルで次のエレメントを選択できます。前のエレメントを選択するには、SHIFT+Tabか左カーソルです。スペースもしくは、ENTERでエディタ内の対象エレメントを選択出来ます。"}]},
+{name:"コマンド",items:[{name:"元に戻す",legend:"${undo} をクリック"},{name:"やり直し",legend:"${redo} をクリック"},{name:"太字",legend:"${bold} をクリック"},{name:"斜体 ",legend:"${italic} をクリック"},{name:"下線",legend:"${underline} をクリック"},{name:"リンク",legend:"${link} をクリック"},{name:"ツールバーを縮める",legend:"${toolbarCollapse} をクリック"},{name:"前のカーソル移動のできないポイントへ",legend:"${accessPreviousSpace} を押すとカーソルより前にあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。"},{name:"次のカーソル移動のできないポイントへ",legend:"${accessNextSpace} を押すとカーソルより後ろにあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。"},
+{name:"ユーザー補助ヘルプ",legend:"${a11yHelp} をクリック"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"左矢印",upArrow:"上矢印",rightArrow:"右矢印",downArrow:"下矢印",insert:"Insert",leftWindowKey:"左Windowキー",rightWindowKey:"右のWindowキー",selectKey:"Select",numpad0:"Num 0",numpad1:"Num 1",numpad2:"Num 2",numpad3:"Num 3",numpad4:"Num 4",numpad5:"Num 5",numpad6:"Num 6",numpad7:"Num 7",numpad8:"Num 8",numpad9:"Num 9",multiply:"掛ける",add:"足す",subtract:"引く",decimalPoint:"小数点",
+divide:"割る",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"セミコロン",equalSign:"イコール記号",comma:"カンマ",dash:"ダッシュ",period:"ピリオド",forwardSlash:"フォワードスラッシュ",graveAccent:"グレイヴアクセント",openBracket:"開きカッコ",backSlash:"バックスラッシュ",closeBracket:"閉じカッコ",singleQuote:"シングルクォート"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/km.js b/release/plugins/a11yhelp/dialogs/lang/km.js
new file mode 100644 (file)
index 0000000..2035512
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","km",{title:"Accessibility Instructions",contents:"មាតិកា​ជំនួយ។ ដើម្បី​បិទ​ផ្ទាំង​នេះ សូម​ចុច ESC ។",legend:[{name:"ទូទៅ",items:[{name:"របារ​ឧបករណ៍​កម្មវិធី​និពន្ធ",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"ផ្ទាំង​កម្មវិធីនិពន្ធ",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"ម៉ីនុយបរិបទអ្នកកែសម្រួល",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"ប្រអប់បញ្ជីអ្នកកែសម្រួល",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"ពាក្យបញ្ជា",items:[{name:"ការ​បញ្ជា​មិនធ្វើវិញ",legend:"ចុច ${undo}"},{name:"ការបញ្ជា​ធ្វើវិញ",legend:"ចុច ${redo}"},{name:"ការបញ្ជា​អក្សរ​ដិត",legend:"ចុច ${bold}"},{name:"ការបញ្ជា​អក្សរ​ទ្រេត",legend:"ចុច ${italic}"},{name:"ពាក្យបញ្ជា​បន្ទាត់​ពីក្រោម",
+legend:"ចុច ${underline}"},{name:"ពាក្យបញ្ជា​តំណ",legend:"ចុច ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:"ជំនួយ​ពី​ភាព​ងាយស្រួល",legend:"ជួយ ${a11yHelp}"}]}],tab:"Tab",pause:"ផ្អាក",capslock:"Caps Lock",escape:"ចាកចេញ",pageUp:"ទំព័រ​លើ",pageDown:"ទំព័រ​ក្រោម",leftArrow:"ព្រួញ​ឆ្វេង",upArrow:"ព្រួញ​លើ",rightArrow:"ព្រួញ​ស្ដាំ",downArrow:"ព្រួញ​ក្រោម",insert:"បញ្ចូល",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"ជ្រើស​គ្រាប់​ចុច",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"គុណ",add:"បន្ថែម",subtract:"ដក",decimalPoint:"ចំណុចទសភាគ",divide:"ចែក",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"បិទ​រំកិល",semiColon:"ចុច​ក្បៀស",equalSign:"សញ្ញា​អឺរ៉ូ",comma:"ក្បៀស",dash:"Dash",period:"ចុច",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"តង្កៀប​បើក",backSlash:"Backslash",closeBracket:"តង្កៀប​បិទ",singleQuote:"បន្តក់​មួយ"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ko.js b/release/plugins/a11yhelp/dialogs/lang/ko.js
new file mode 100644 (file)
index 0000000..f493dc1
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ko",{title:"접근성 설명",contents:"도움말. 이 창을 닫으시려면 ESC 를 누르세요.",legend:[{name:"일반",items:[{name:"편집기 툴바",legend:"툴바를 탐색하시려면 ${toolbarFocus} 를 투르세요. 이전/다음 툴바 그룹으로 이동하시려면 TAB 키 또는 SHIFT+TAB 키를 누르세요. 이전/다음 툴바 버튼으로 이동하시려면 오른쪽 화살표 키 또는 왼쪽 화살표 키를 누르세요. 툴바 버튼을 활성화 하려면 SPACE 키 또는 ENTER 키를 누르세요."},{name:"편집기 다이얼로그",legend:"TAB 키를 누르면 다음 대화상자로 이동하고, SHIFT+TAB 키를 누르면 이전 대화상자로 이동합니다. 대화상자를 제출하려면 ENTER 키를 누르고, ESC 키를 누르면 대화상자를 취소합니다. 대화상자에 탭이 여러개 있을 때, ALT+F10 키 또는 TAB 키를 누르면 순서에 따라 탭 목록에 도달할 수 있습니다. 탭 목록에 초점이 맞을 때, 오른쪽과 왼쪽 화살표 키를 이용하면 각각 다음과 이전 탭으로 이동할 수 있습니다."},
+{name:"편집기 환경 메뉴",legend:"${contextMenu} 또는 어플리케이션 키를 누르면 환경-메뉴를 열 수 있습니다. 환경-메뉴에서 TAB 키 또는 아래 화살표 키를 누르면 다음 메뉴 옵션으로 이동할 수 있습니다. 이전 옵션으로 이동은 SHIFT+TAB 키 또는 위 화살표 키를 눌러서 할 수 있습니다. 스페이스 키 또는 ENTER 키를 눌러서 메뉴 옵션을 선택할 수 있습니다. 스페이스 키 또는 ENTER 키 또는 오른쪽 화살표 키를 눌러서 하위 메뉴를 열 수 있습니다. 부모 메뉴 항목으로 돌아가려면 ESC 키 또는 왼쪽 화살표 키를 누릅니다. ESC 키를 눌러서 환경-메뉴를 닫습니다."},{name:"편집기 목록 박스",legend:"리스트-박스 내에서, 목록의 다음 항목으로 이동하려면 TAB 키 또는 아래쪽 화살표 키를 누릅니다. 목록의 이전 항목으로 이동하려면 SHIFT+TAB 키 또는 위쪽 화살표 키를 누릅니다. 스페이스 키 또는 ENTER 키를 누르면 목록의 해당 옵션을 선택합니다. ESC 키를 눌러서 리스트-박스를 닫을 수 있습니다."},
+{name:"편집기 요소 경로 막대",legend:"${elementsPathFocus}를 눌러서 요소 경로 막대를 탐색할 수 있습니다. 다음 요소로 이동하려면 TAB 키 또는 오른쪽 화살표 키를 누릅니다. SHIFT+TAB 키 또는 왼쪽 화살표 키를 누르면 이전 버튼으로 이동할 수 있습니다. 스페이스 키나 ENTER 키를 누르면 편집기의 해당 항목을 선택합니다."}]},{name:"명령",items:[{name:" 명령 실행 취소",legend:"${undo} 누르시오"},{name:" 명령 다시 실행",legend:"${redo} 누르시오"},{name:" 굵게 명령",legend:"${bold} 누르시오"},{name:" 기울임 꼴 명령",legend:"${italic} 누르시오"},{name:" 밑줄 명령",legend:"${underline} 누르시오"},{name:" 링크 명령",legend:"${link} 누르시오"},{name:" 툴바 줄이기 명령",legend:"${toolbarCollapse} 누르시오"},
+{name:" 이전 포커스 공간 접근 명령",legend:"탈자 기호(^) 이전에 ${accessPreviousSpace} 를 누르면, 접근 불가능하면서 가장 가까운 포커스 영역에 접근합니다. 예를 들면, 두 인접한 HR 요소가 있습니다. 키 조합을 반복해서 멀리있는 포커스 영역들에 도달할 수 있습니다."},{name:"다음 포커스 공간 접근 명령",legend:"탈자 기호(^) 다음에 ${accessNextSpace} 를 누르면, 접근 불가능하면서 가장 가까운 포커스 영역에 접근합니다. 예를 들면, 두 인접한 HR 요소가 있습니다. 키 조합을 반복해서 멀리있는 포커스 영역들에 도달할 수 있습니다. "},{name:" 접근성 도움말",legend:"${a11yHelp} 누르시오"}]}],tab:"탭 키",pause:"일시정지 키",capslock:"캡스 록 키",escape:"이스케이프 키",pageUp:"페이지 업 키",pageDown:"페이지 다운 키",leftArrow:"왼쪽 화살표 키",
+upArrow:"위쪽 화살표 키",rightArrow:"오른쪽 화살표 키",downArrow:"아래쪽 화살표 키",insert:"인서트 키",leftWindowKey:"왼쪽 윈도우 키",rightWindowKey:"오른쪽 윈도우 키",selectKey:"셀렉트 키",numpad0:"숫자 패드 0 키",numpad1:"숫자 패드 1 키",numpad2:"숫자 패드 2 키",numpad3:"숫자 패드 3 키",numpad4:"숫자 패드 4 키",numpad5:"숫자 패드 5 키",numpad6:"숫자 패드 6 키",numpad7:"숫자 패드 7 키",numpad8:"숫자 패드 8 키",numpad9:"숫자 패드 9 키",multiply:"곱셈(*) 키",add:"덧셈(+) 키",subtract:"뺄셈(-) 키",decimalPoint:"온점(.) 키",divide:"나눗셈(/) 키",f1:"F1 키",f2:"F2 키",f3:"F3 키",f4:"F4 키",f5:"F5 키",f6:"F6 키",
+f7:"F7 키",f8:"F8 키",f9:"F9 키",f10:"F10 키",f11:"F11 키",f12:"F12 키",numLock:"Num Lock 키",scrollLock:"Scroll Lock 키",semiColon:"세미콜론(;) 키",equalSign:"등호(\x3d) 키",comma:"쉼표(,) 키",dash:"대시(-) 키",period:"온점(.) 키",forwardSlash:"슬래시(/) 키",graveAccent:"억음 악센트(`) 키",openBracket:"브라켓 열기([) 키",backSlash:"역슬래시(\\\\) 키",closeBracket:"브라켓 닫기(]) 키",singleQuote:"외 따옴표(') 키"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ku.js b/release/plugins/a11yhelp/dialogs/lang/ku.js
new file mode 100644 (file)
index 0000000..9bf5eab
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ku",{title:"ڕێنمای لەبەردەستدابوون",contents:"پێکهاتەی یارمەتی. کلیك ESC بۆ داخستنی ئەم دیالۆگه.",legend:[{name:"گشتی",items:[{name:"تووڵامرازی دەستكاریكەر",legend:"کلیك ${toolbarFocus} بۆ ڕابەری تووڵامراز. بۆ گواستنەوەی پێشوو داهاتووی گرووپی تووڵامرازی داگرتنی کلیلی TAB لەگەڵ‌ SHIFT+TAB. بۆ گواستنەوەی پێشوو داهاتووی دووگمەی تووڵامرازی لەڕێی کلیلی تیری دەستی ڕاست یان کلیلی تیری دەستی چەپ. کلیکی کلیلی SPACE یان ENTER بۆ چالاککردنی دووگمەی تووڵامراز."},{name:"دیالۆگی دەستكاریكەر",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"پێڕستی سەرنووسەر",legend:"کلیك ${contextMenu} یان دوگمەی لیسته‌(Menu) بۆ کردنەوەی لیستەی دەق. بۆ چوونە هەڵبژاردەیەکی تر له‌ لیسته‌ کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوارەوه‌ بۆ چوون بۆ هەڵبژاردەی پێشوو کلیکی کلیلی SHIFT+TAB یان کلیلی تیری ڕوو له‌ سەرەوە. داگرتنی کلیلی SPACE یان ENTER بۆ هەڵبژاردنی هەڵبژاردەی لیسته‌. بۆ کردنەوەی لقی ژێر لیسته‌ لەهەڵبژاردەی لیستە کلیکی کلیلی SPACE یان ENTER یان کلیلی تیری دەستی ڕاست. بۆ گەڕانەوه بۆ سەرەوەی لیسته‌ کلیکی کلیلی ESC یان کلیلی تیری دەستی چەپ. بۆ داخستنی لیستە کلیكی کلیلی ESC بکە."},
+{name:"لیستی سنووقی سەرنووسەر",legend:"لەناو سنوقی لیست, چۆن بۆ هەڵنبژاردەی لیستێکی تر کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوار. چوون بۆ هەڵبژاردەی لیستی پێشوو کلیکی کلیلی SHIFT+TAB یان کلیلی تیری ڕوو لەسەرەوه‌. کلیکی کلیلی SPACE یان ENTER بۆ دیاریکردنی ‌هەڵبژاردەی لیست. کلیکی کلیلی ESC بۆ داخستنی سنوقی لیست."},{name:"تووڵامرازی توخم",legend:"کلیك ${elementsPathFocus} بۆ ڕابەری تووڵامرازی توخمەکان. چوون بۆ دوگمەی توخمێکی تر کلیکی کلیلی TAB یان کلیلی تیری دەستی ڕاست. چوون بۆ دوگمەی توخمی پێشوو کلیلی SHIFT+TAB یان کلیکی کلیلی تیری دەستی چەپ. داگرتنی کلیلی SPACE یان ENTER بۆ دیاریکردنی توخمەکه‌ لەسەرنووسه."}]},
+{name:"فەرمانەکان",items:[{name:"پووچکردنەوەی فەرمان",legend:"کلیك ${undo}"},{name:"هەڵگەڕانەوەی فەرمان",legend:"کلیك ${redo}"},{name:"فەرمانی دەقی قەڵەو",legend:"کلیك ${bold}"},{name:"فەرمانی دەقی لار",legend:"کلیك ${italic}"},{name:"فەرمانی ژێرهێڵ",legend:"کلیك ${underline}"},{name:"فەرمانی به‌ستەر",legend:"کلیك ${link}"},{name:"شاردەنەوەی تووڵامراز",legend:"کلیك ${toolbarCollapse}"},{name:"چوونەناو سەرنجدانی پێشوی فەرمانی بۆشایی",legend:"کلیک ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:"چوونەناو سەرنجدانی داهاتووی فەرمانی بۆشایی",legend:"کلیک ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:"دەستپێگەیشتنی یارمەتی",legend:"کلیك ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",
+leftWindowKey:"پەنجەرەی چەپ",rightWindowKey:"پەنجەرەی ڕاست",selectKey:"Select",numpad0:"Numpad 0",numpad1:"1",numpad2:"2",numpad3:"3",numpad4:"4",numpad5:"5",numpad6:"6",numpad7:"7",numpad8:"8",numpad9:"9",multiply:"*",add:"+",subtract:"-",decimalPoint:".",divide:"/",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:";",equalSign:"\x3d",comma:",",dash:"-",period:".",forwardSlash:"/",graveAccent:"`",
+openBracket:"[",backSlash:"\\\\",closeBracket:"}",singleQuote:"'"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/lt.js b/release/plugins/a11yhelp/dialogs/lang/lt.js
new file mode 100644 (file)
index 0000000..c766236
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","lt",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Bendros savybės",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/lv.js b/release/plugins/a11yhelp/dialogs/lang/lv.js
new file mode 100644 (file)
index 0000000..dddea99
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","lv",{title:"Pieejamības instrukcija",contents:"Palīdzības saturs. Lai aizvērtu ciet šo dialogu nospiediet ESC.",legend:[{name:"Galvenais",items:[{name:"Redaktora rīkjosla",legend:"Nospiediet ${toolbarFocus} lai pārvietotos uz rīkjoslu. Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas grupu izmantojiet pogu TAB un SHIFT+TAB. Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas pogu izmantojiet Kreiso vai Labo bultiņu. Nospiediet Atstarpi vai ENTER lai aktivizētu rīkjosla pogu."},
+{name:"Redaktora dialoga  logs",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Redaktora satura izvēle",legend:"Nospiediet ${contextMenu} vai APPLICATION KEY lai atvērtu satura izvēlni. Lai pārvietotos uz nākošo izvēlnes opciju izmantojiet pogu TAB vai pogu Bultiņu uz leju. Lai pārvietotos uz iepriekšējo opciju izmantojiet  SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvelētos izvēlnes opciju. Atveriet tekošajā opcija apakšizvēlni ar SAPCE vai ENTER ka ari to var izdarīt ar Labo bultiņu. Lai atgrieztos atpakaļ uz sakuma izvēlni nospiediet ESC vai Kreiso bultiņu. Lai aizvērtu ciet izvēlnes saturu nospiediet ESC."},
+{name:"Redaktora saraksta lauks",legend:"Saraksta laukā, lai pārvietotos uz nākošo saraksta elementu nospiediet TAB vai pogu Bultiņa uz leju. Lai pārvietotos uz iepriekšējo saraksta elementu nospiediet SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvēlētos saraksta opcijas. Nospiediet ESC lai aizvērtu saraksta lauku."},{name:"Redaktora elementa ceļa josla",legend:"Nospiediet ${elementsPathFocus} lai pārvietotos uz elementa ceļa joslu. Lai pārvietotos uz nākošo elementa pogu izmantojiet TAB vai Labo bultiņu. Lai pārvietotos uz iepriekšējo elementa pogu izmantojiet SHIFT+TAB vai Kreiso bultiņu. Nospiediet SPACE vai ENTER lai izvēlētos elementu redaktorā."}]},
+{name:"Komandas",items:[{name:"Komanda atcelt darbību",legend:"Nospiediet ${undo}"},{name:"Komanda atkārtot darbību",legend:"Nospiediet ${redo}"},{name:"Treknraksta komanda",legend:"Nospiediet ${bold}"},{name:"Kursīva komanda",legend:"Nospiediet ${italic}"},{name:"Apakšsvītras komanda ",legend:"Nospiediet ${underline}"},{name:"Hipersaites komanda",legend:"Nospiediet ${link}"},{name:"Rīkjoslas aizvēršanas komanda",legend:"Nospiediet ${toolbarCollapse}"},{name:"Piekļūt iepriekšējai fokusa vietas komandai",
+legend:"Nospiediet ${accessPreviousSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pirms kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām."},{name:"Piekļūt nākošā fokusa apgabala komandai",legend:"Nospiediet ${accessNextSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pēc kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām."},
+{name:"Pieejamības palīdzība",legend:"Nospiediet ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/mk.js b/release/plugins/a11yhelp/dialogs/lang/mk.js
new file mode 100644 (file)
index 0000000..f294271
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","mk",{title:"Инструкции за пристапност",contents:"Содржина на делот за помош. За да го затворите овој дијалог притиснете ESC.",legend:[{name:"Општо",items:[{name:"Мени за уредувачот",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Дијалот за едиторот",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Контекст-мени на уредувачот",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},
+{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},
+{name:"Наредби",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Пауза",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Up",leftArrow:"Стрелка лево",upArrow:"Стрелка горе",rightArrow:"Стрелка десно",downArrow:"Стрелка доле",insert:"Insert",
+leftWindowKey:"Лево Windows копче",rightWindowKey:"Десно Windows копче",selectKey:"Select копче",numpad0:"Нум. таст. 0",numpad1:"Нум. таст. 1",numpad2:"Нум. таст. 2",numpad3:"Нум. таст. 3",numpad4:"Нум. таст. 4",numpad5:"Нум. таст. 5",numpad6:"Нум. таст. 6",numpad7:"Нум. таст. 7",numpad8:"Нум. таст. 8",numpad9:"Нум. таст. 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",
+f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/mn.js b/release/plugins/a11yhelp/dialogs/lang/mn.js
new file mode 100644 (file)
index 0000000..1f1af29
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","mn",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Ерөнхий",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/nb.js b/release/plugins/a11yhelp/dialogs/lang/nb.js
new file mode 100644 (file)
index 0000000..340d604
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","nb",{title:"Instruksjoner for tilgjengelighet",contents:"Innhold for hjelp. Trykk ESC for å lukke denne dialogen.",legend:[{name:"Generelt",items:[{name:"Verktøylinje for editor",legend:"Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT+TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen."},{name:"Dialog for editor",
+legend:"Mens du er i en dialog, trykk TAB for å navigere til neste dialogelement, trykk SHIFT+TAB for å flytte til forrige dialogelement, trykk ENTER for å akseptere dialogen, trykk ESC for å avbryte dialogen. Når en dialog har flere faner, kan fanelisten nås med enten ALT+F10 eller med TAB. Når fanelisten er fokusert, går man til neste og forrige fane med henholdsvis HØYRE og VENSTRE PILTAST."},{name:"Kontekstmeny for editor",legend:"Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC."},
+{name:"Listeboks for editor",legend:"I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen."},{name:"Verktøylinje for elementsti",legend:"Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren."}]},
+{name:"Hurtigtaster",items:[{name:"Angre",legend:"Trykk ${undo}"},{name:"Gjør om",legend:"Trykk ${redo}"},{name:"Fet tekst",legend:"Trykk ${bold}"},{name:"Kursiv tekst",legend:"Trykk ${italic}"},{name:"Understreking",legend:"Trykk ${underline}"},{name:"Lenke",legend:"Trykk ${link}"},{name:"Skjul verktøylinje",legend:"Trykk ${toolbarCollapse}"},{name:"Gå til forrige fokusområde",legend:"Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet."},
+{name:"Gå til neste fokusområde",legend:"Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet."},{name:"Hjelp for tilgjengelighet",legend:"Trykk ${a11yHelp}"}]}],tab:"Tabulator",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Venstre piltast",upArrow:"Opp-piltast",
+rightArrow:"Høyre piltast",downArrow:"Ned-piltast",insert:"Insert",leftWindowKey:"Venstre Windows-tast",rightWindowKey:"Høyre Windows-tast",selectKey:"Velg nøkkel",numpad0:"Numerisk tastatur 0",numpad1:"Numerisk tastatur 1",numpad2:"Numerisk tastatur 2",numpad3:"Numerisk tastatur 3",numpad4:"Numerisk tastatur 4",numpad5:"Numerisk tastatur 5",numpad6:"Numerisk tastatur 6",numpad7:"Numerisk tastatur 7",numpad8:"Numerisk tastatur 8",numpad9:"Numerisk tastatur 9",multiply:"Multipliser",add:"Legg til",
+subtract:"Trekk fra",decimalPoint:"Desimaltegn",divide:"Divider",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semikolon",equalSign:"Likhetstegn",comma:"Komma",dash:"Bindestrek",period:"Punktum",forwardSlash:"Forover skråstrek",graveAccent:"Grav aksent",openBracket:"Åpne parentes",backSlash:"Bakover skråstrek",closeBracket:"Lukk parentes",singleQuote:"Enkelt sitattegn"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/nl.js b/release/plugins/a11yhelp/dialogs/lang/nl.js
new file mode 100644 (file)
index 0000000..62df667
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","nl",{title:"Toegankelijkheidsinstructies",contents:"Help-inhoud. Druk op ESC om dit dialoog te sluiten.",legend:[{name:"Algemeen",items:[{name:"Werkbalk tekstverwerker",legend:"Druk op ${toolbarFocus} om naar de werkbalk te navigeren. Om te schakelen naar de volgende en vorige werkbalkgroep, gebruik TAB en SHIFT+TAB. Om te schakelen naar de volgende en vorige werkbalkknop, gebruik de PIJL RECHTS en PIJL LINKS. Druk op SPATIE of ENTER om een werkbalkknop te activeren."},
+{name:"Dialoog tekstverwerker",legend:"In een dialoogvenster, druk op TAB om te navigeren naar het volgende veld. Druk op SHIFT+TAB om naar het vorige veld te navigeren. Druk op ENTER om het dialoogvenster te verzenden. Druk op ESC om het dialoogvenster te sluiten. Bij dialoogvensters met meerdere tabbladen kan de tabset bereikt worden met ALT+F10 of met TAB als onderdeel van de tabvolgorde in het dialoogvenster. Als de tabset focus heeft, kun je schakalen naar het volgende en vorige tabblad met respectievelijk PIJL RECHTS en PIJL LINKS."},
+{name:"Contextmenu tekstverwerker",legend:"Druk op ${contextMenu} of APPLICATION KEY om het contextmenu te openen. Schakel naar de volgende menuoptie met TAB of PIJL OMLAAG. Schakel naar de vorige menuoptie met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om een menuoptie te selecteren. Op een submenu van de huidige optie met SPATIE, ENTER of PIJL RECHTS. Ga terug naar de bovenliggende menuoptie met ESC of PIJL LINKS. Sluit het contextmenu met ESC."},{name:"Keuzelijst tekstverwerker",legend:"In een keuzelijst, schakel naar het volgende item met TAB of PIJL OMLAAG. Schakel naar het vorige item met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om het item te selecteren. Druk op ESC om de keuzelijst te sluiten."},
+{name:"Elementenpad werkbalk tekstverwerker",legend:"Druk op ${elementsPathFocus} om naar het elementenpad te navigeren. Om te schakelen naar het volgende element, gebruik TAB of PIJL RECHTS. Om te schakelen naar het vorige element, gebruik SHIFT+TAB or PIJL LINKS. Druk op SPATIE of ENTER om een element te selecteren in de tekstverwerker."}]},{name:"Opdrachten",items:[{name:"Ongedaan maken opdracht",legend:"Druk op ${undo}"},{name:"Opnieuw uitvoeren opdracht",legend:"Druk op ${redo}"},{name:"Vetgedrukt opdracht",
+legend:"Druk op ${bold}"},{name:"Cursief opdracht",legend:"Druk op ${italic}"},{name:"Onderstrepen opdracht",legend:"Druk op ${underline}"},{name:"Link opdracht",legend:"Druk op ${link}"},{name:"Werkbalk inklappen opdracht",legend:"Druk op ${toolbarCollapse}"},{name:"Ga naar vorige focus spatie commando",legend:"Druk ${accessPreviousSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie voor de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken."},
+{name:"Ga naar volgende focus spatie commando",legend:"Druk ${accessNextSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie na de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken."},{name:"Toegankelijkheidshulp",legend:"Druk op ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Pijl naar links",upArrow:"Pijl omhoog",rightArrow:"Pijl naar rechts",
+downArrow:"Pijl naar beneden",insert:"Invoegen",leftWindowKey:"Linker Windows-toets",rightWindowKey:"Rechter Windows-toets",selectKey:"Selecteer toets",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Vermenigvuldigen",add:"Toevoegen",subtract:"Aftrekken",decimalPoint:"Decimaalteken",divide:"Delen",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",
+f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Puntkomma",equalSign:"Is gelijk-teken",comma:"Komma",dash:"Koppelteken",period:"Punt",forwardSlash:"Slash",graveAccent:"Accent grave",openBracket:"Vierkant haakje openen",backSlash:"Backslash",closeBracket:"Vierkant haakje sluiten",singleQuote:"Apostrof"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/no.js b/release/plugins/a11yhelp/dialogs/lang/no.js
new file mode 100644 (file)
index 0000000..8aa90a4
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","no",{title:"Instruksjoner for tilgjengelighet",contents:"Innhold for hjelp. Trykk ESC for å lukke denne dialogen.",legend:[{name:"Generelt",items:[{name:"Verktøylinje for editor",legend:"Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT+TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen."},{name:"Dialog for editor",
+legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Kontekstmeny for editor",legend:"Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC."},
+{name:"Listeboks for editor",legend:"I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen."},{name:"Verktøylinje for elementsti",legend:"Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren."}]},
+{name:"Kommandoer",items:[{name:"Angre",legend:"Trykk ${undo}"},{name:"Gjør om",legend:"Trykk ${redo}"},{name:"Fet tekst",legend:"Trykk ${bold}"},{name:"Kursiv tekst",legend:"Trykk ${italic}"},{name:"Understreking",legend:"Trykk ${underline}"},{name:"Link",legend:"Trykk ${link}"},{name:"Skjul verktøylinje",legend:"Trykk ${toolbarCollapse}"},{name:"Gå til forrige fokusområde",legend:"Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet."},
+{name:"Gå til neste fokusområde",legend:"Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet."},{name:"Hjelp for tilgjengelighet",legend:"Trykk ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",
+downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",
+f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/oc.js b/release/plugins/a11yhelp/dialogs/lang/oc.js
new file mode 100644 (file)
index 0000000..f63c119
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","oc",{title:"Instruccions d'accessibilitat",contents:"Contengut de l'ajuda. Per tampar aquesta fenèstra, quichatz sus la tòca Escap.",legend:[{name:"General",items:[{name:"Barra d'aisinas de l'editor",legend:"Quichar sus ${toolbarFocus} per accedir a la barra d'aisinas. Se desplaçar cap al groupe seguent o precedent de la barra d'aisinas amb las tòcas Tab e Maj+Tab. Se desplaçar cap al boton seguent o precedent de la barra d'aisinas amb las tòcas Sageta dreita e Sageta esquèrra. Quichar sus la barra d'espaci o la tòca Entrada per activer lo boton de barra d'aisinas."},
+{name:"Fenèstra de l'editor",legend:"Dins una bóstia de dialòg, quichar sus Tab per passar a l'element seguent, quichar sus Maj+Tab per passar a l'element precedent, quichar sus Entrada per validar, quichar sus Escap per anullar. Quand una bóstia de dialòg possedís des onglets, la lista pòt èsser atenta amb Alt+F10 o amb Tab. Dins la lista dels onglets, se desplaçar cap al seguent e lo precedent amb las tòcas Sageta dreita e Sageta esquèrra respectivament."},{name:"Menú contextual de l'editor",legend:"Quichar sus ${contextMenu} o sus la tòca Menú per dobrir lo menú contextual. Se desplaçar ensuite cap a l'opcion seguenta del menú amb las tòcas Tab o Sageta bas. Se desplaçar cap a l'opcion precedenta amb las tòcas Maj+Tab o Sageta naut. Quichar sus la barra d'espaci o la tòca Entrada per seleccionar l'opcion del menu. Quichar sus la barra d'espaci, la tòca Entrada o Sageta dreita per dobrir lo sosmenú de l'opcion seleccionada. Tornar a l'element de menú parent amb la tòca Escap o Sageta esquèrra. Tampar lo menú contextual amb Escap."},
+{name:"Zòna de lista de l'editor",legend:"Dins una lista en menú desenrotlant, se desplaçar cap a l'element seguent de la lista amb las tòcas Tab o Sageta bas. Se desplaçar cap a l'element precedent de la lista amb las tòcas Maj+Tab o Sageta naut. Quichar sus la barra d'espaci o sus Entrada per seleccionar l'opcion dins la lista. Quichar sus Escap per tampar lo menú desenrotlant."},{name:"Barra del camin d'elements de l'editor",legend:"Quichar sus ${elementsPathFocus} per naviguer cap a la barra del fial d'Ariana dels elements. Se desplaçar cap al boton de l'element seguent amb las tòcas Tab o Sageta dreita. Se desplaçar cap al boton precedent amb las tòcas Maj+Tab o Sageta esquèrra. Quichar sus la barra d'espaci o sus Entrada per seleccionar l'element dins l'editor."}]},
+{name:"Comandas",items:[{name:"Anullar la comanda",legend:"Quichar sus ${undo}"},{name:"Comanda restablir",legend:"Quichar sus ${redo}"},{name:" Comanda gras",legend:"Quichar sus ${bold}"},{name:" Comanda italica",legend:"Quichar sus ${italic}"},{name:" Comanda solinhat",legend:"Quichar sus ${underline}"},{name:" Comanda ligam",legend:"Quichar sus ${link}"},{name:"Comanda enrotlar la barra d'aisinas",legend:"Quichar sus ${toolbarCollapse}"},{name:"Comanda d'accès a l'element seleccionable precedent",
+legend:"Quichar sus ${accessNextSpace} per accedir a l'element seleccionable inategnible lo mai pròche abans lo cursor, per exemple : doas linhas orizontalas adjacentas. Repetir la combinason de tòcas per aténher los elements seleccionables precedents."},{name:"Comanda d'accès a l'element seleccionable seguent",legend:"Quichar sus ${accessNextSpace} per accedir a l'element seleccionable inatenhible lo mai pròche aprèp lo cursor, per exemple : doas linhas orizontalas adjacentas. Repetir la combinason de tòcas per aténher los elements seleccionables seguents."},
+{name:" Ajuda sus l'accessibilitat",legend:"Quichar sus ${a11yHelp}"}]}],tab:"Tabulacion",pause:"Pausa",capslock:"Verr. Maj.",escape:"Escap",pageUp:"Pagina superiora",pageDown:"Pagina seguenta",leftArrow:"Sageta esquèrra",upArrow:"Sageta naut",rightArrow:"Sageta dreita",downArrow:"Sageta bassa",insert:"Inser",leftWindowKey:"Tòca Windows esquèrra",rightWindowKey:"Tòca Windows dreita",selectKey:"Tòca Seleccionar",numpad0:"0 del pavat numeric",numpad1:"1 del pavat numeric",numpad2:"2 del pavat numeric",
+numpad3:"3 del pavat numeric",numpad4:"4 del pavat numeric",numpad5:"5 del pavat numeric",numpad6:"6 del pavat numeric",numpad7:"7 del pavat numeric",numpad8:"Pavat numeric 8",numpad9:"9 del pavat numeric",multiply:"Multiplicar",add:"Plus",subtract:"Mens",decimalPoint:"Punt decimal",divide:"Devesir",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Verr. Num.",scrollLock:"Arrèst desfil.",semiColon:"Punt-virgula",equalSign:"Signe egal",comma:"Virgula",
+dash:"Jonhent",period:"Punt",forwardSlash:"Barra oblica",graveAccent:"Accent grèu",openBracket:"Parentèsi dobèrta",backSlash:"Barra oblica invèrsa",closeBracket:"Parentèsi tampanta",singleQuote:"Apostròfa"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/pl.js b/release/plugins/a11yhelp/dialogs/lang/pl.js
new file mode 100644 (file)
index 0000000..da634dd
--- /dev/null
@@ -0,0 +1,13 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","pl",{title:"Instrukcje dotyczące dostępności",contents:"Zawartość pomocy. Wciśnij ESC, aby zamknąć to okno.",legend:[{name:"Informacje ogólne",items:[{name:"Pasek narzędzi edytora",legend:"Naciśnij ${toolbarFocus}, by przejść do paska narzędzi. Przejdź do następnej i poprzedniej grupy narzędzi używając TAB oraz SHIFT+TAB. Przejdź do następnego i poprzedniego przycisku paska narzędzi za pomocą STRZAŁKI W PRAWO lub STRZAŁKI W LEWO. Naciśnij SPACJĘ lub ENTER by aktywować przycisk paska narzędzi."},
+{name:"Okno dialogowe edytora",legend:"Wewnątrz okna dialogowego naciśnij TAB, by przejść do kolejnego elementu tego okna lub SHIFT+TAB, by przejść do poprzedniego elementu okna. Naciśnij ENTER w celu zatwierdzenia opcji okna dialogowego lub ESC w celu anulowania zmian. Jeśli okno dialogowe ma kilka zakładek, do listy zakładek można przejść za pomocą ALT+F10 lub TAB. Gdy lista zakładek jest aktywna, możesz przejść do kolejnej i poprzedniej zakładki za pomocą STRZAŁKI W PRAWO i STRZAŁKI W LEWO."},
+{name:"Menu kontekstowe edytora",legend:"Wciśnij ${contextMenu} lub PRZYCISK APLIKACJI aby otworzyć menu kontekstowe. Przejdź do następnej pozycji menu wciskając TAB lub STRZAŁKĘ W DÓŁ. Przejdź do poprzedniej pozycji menu wciskając SHIFT + TAB lub STRZAŁKĘ W GÓRĘ. Wciśnij SPACJĘ lub ENTER aby wygrać pozycję menu. Otwórz pod-menu obecnej pozycji wciskając SPACJĘ lub ENTER lub STRZAŁKĘ W PRAWO. Wróć do pozycji nadrzędnego menu wciskając ESC lub STRZAŁKĘ W LEWO. Zamknij menu wciskając ESC."},{name:"Lista w edytorze",
+legend:"Wewnątrz listy przejdź do kolejnego elementu listy za pomocą przycisku TAB lub STRZAŁKI W DÓŁ. Przejdź do poprzedniego elementu listy za pomocą SHIFT+TAB lub STRZAŁKI W GÓRĘ. Naciśnij SPACJĘ lub ENTER w celu wybrania opcji z listy. Naciśnij ESC, by zamknąć listę."},{name:"Pasek ścieżki elementów edytora",legend:"Naciśnij ${elementsPathFocus} w celu przejścia do paska ścieżki elementów edytora. W celu przejścia do kolejnego elementu naciśnij klawisz TAB lub STRZAŁKI W PRAWO. W celu przejścia do poprzedniego elementu naciśnij klawisze SHIFT+TAB lub STRZAŁKI W LEWO. By wybrać element w edytorze, użyj klawisza SPACJI lub ENTER."}]},
+{name:"Polecenia",items:[{name:"Polecenie Cofnij",legend:"Naciśnij ${undo}"},{name:"Polecenie Ponów",legend:"Naciśnij ${redo}"},{name:"Polecenie Pogrubienie",legend:"Naciśnij ${bold}"},{name:"Polecenie Kursywa",legend:"Naciśnij ${italic}"},{name:"Polecenie Podkreślenie",legend:"Naciśnij ${underline}"},{name:"Polecenie Wstaw/ edytuj odnośnik",legend:"Naciśnij ${link}"},{name:"Polecenie schowaj pasek narzędzi",legend:"Naciśnij ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:"Pomoc dotycząca dostępności",legend:"Naciśnij ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Strzałka w lewo",upArrow:"Strzałka w górę",rightArrow:"Strzałka w prawo",downArrow:"Strzałka w dół",
+insert:"Insert",leftWindowKey:"Lewy klawisz Windows",rightWindowKey:"Prawy klawisz Windows",selectKey:"Klawisz wyboru",numpad0:"Klawisz 0 na klawiaturze numerycznej",numpad1:"Klawisz 1 na klawiaturze numerycznej",numpad2:"Klawisz 2 na klawiaturze numerycznej",numpad3:"Klawisz 3 na klawiaturze numerycznej",numpad4:"Klawisz 4 na klawiaturze numerycznej",numpad5:"Klawisz 5 na klawiaturze numerycznej",numpad6:"Klawisz 6 na klawiaturze numerycznej",numpad7:"Klawisz 7 na klawiaturze numerycznej",numpad8:"Klawisz 8 na klawiaturze numerycznej",
+numpad9:"Klawisz 9 na klawiaturze numerycznej",multiply:"Przemnóż",add:"Plus",subtract:"Minus",decimalPoint:"Separator dziesiętny",divide:"Podziel",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Średnik",equalSign:"Znak równości",comma:"Przecinek",dash:"Pauza",period:"Kropka",forwardSlash:"Ukośnik prawy",graveAccent:"Akcent słaby",openBracket:"Nawias kwadratowy otwierający",backSlash:"Ukośnik lewy",
+closeBracket:"Nawias kwadratowy zamykający",singleQuote:"Apostrof"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/pt-br.js b/release/plugins/a11yhelp/dialogs/lang/pt-br.js
new file mode 100644 (file)
index 0000000..5f07352
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","pt-br",{title:"Instruções de Acessibilidade",contents:"Conteúdo da Ajuda. Para fechar este diálogo pressione ESC.",legend:[{name:"Geral",items:[{name:"Barra de Ferramentas do Editor",legend:"Pressione ${toolbarFocus} para navegar para a barra de ferramentas. Mova para o anterior ou próximo grupo de ferramentas com TAB e SHIFT+TAB. Mova para o anterior ou próximo botão com SETA PARA DIREITA or SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para ativar o botão da barra de ferramentas."},
+{name:"Diálogo do Editor",legend:"Dentro de um diálogo, pressione TAB para navegar para o próximo elemento. Pressione SHIFT+TAB para mover para o elemento anterior. Pressione ENTER ara enviar o diálogo. pressione ESC para cancelar o diálogo. Quando um diálogo tem múltiplas abas, a lista de abas pode ser acessada com ALT+F10 ou TAB, como parte da ordem de tabulação do diálogo. Com a lista de abas em foco, mova para a próxima aba e para a aba anterior com a SETA DIREITA ou SETA ESQUERDA, respectivamente."},
+{name:"Menu de Contexto do Editor",legend:"Pressione ${contextMenu} ou TECLA DE MENU para abrir o menu de contexto, então mova para a próxima opção com TAB ou SETA PARA BAIXO. Mova para a anterior com SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu. Abra o submenu da opção atual com ESPAÇO ou ENTER ou SETA PARA DIREITA. Volte para o menu pai com ESC ou SETA PARA ESQUERDA. Feche o menu de contexto com ESC."},{name:"Caixa de Lista do Editor",legend:"Dentro de uma caixa de lista, mova para o próximo item com TAB ou SETA PARA BAIXO. Mova para o item anterior com SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar uma opção na lista. Pressione ESC para fechar a caixa de lista."},
+{name:"Barra de Caminho do Elementos do Editor",legend:"Pressione ${elementsPathFocus} para a barra de caminho dos elementos. Mova para o próximo botão de elemento com TAB ou SETA PARA DIREITA. Mova para o botão anterior com SHIFT+TAB ou SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar o elemento no editor."}]},{name:"Comandos",items:[{name:" Comando Desfazer",legend:"Pressione ${undo}"},{name:" Comando Refazer",legend:"Pressione ${redo}"},{name:" Comando Negrito",legend:"Pressione ${bold}"},
+{name:" Comando Itálico",legend:"Pressione ${italic}"},{name:" Comando Sublinhado",legend:"Pressione ${underline}"},{name:" Comando Link",legend:"Pressione ${link}"},{name:" Comando Fechar Barra de Ferramentas",legend:"Pressione ${toolbarCollapse}"},{name:"Acessar o comando anterior de spaço de foco",legend:"Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo antes do cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes."},
+{name:"Acessar próximo fomando de spaço de foco",legend:"Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo após o cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes."},{name:" Ajuda de Acessibilidade",legend:"Pressione ${a11yHelp}"}]}],tab:"Tecla Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Seta à Esquerda",upArrow:"Seta à Cima",rightArrow:"Seta à Direita",
+downArrow:"Seta à Baixo",insert:"Insert",leftWindowKey:"Tecla do Windows Esquerda",rightWindowKey:"Tecla do Windows Direita",selectKey:"Tecla Selecionar",numpad0:"0 do Teclado Numérico",numpad1:"1 do Teclado Numérico",numpad2:"2 do Teclado Numérico",numpad3:"3 do Teclado Numérico",numpad4:"4 do Teclado Numérico",numpad5:"5 do Teclado Numérico",numpad6:"6 do Teclado Numérico",numpad7:"7 do Teclado Numérico",numpad8:"8 do Teclado Numérico",numpad9:"9 do Teclado Numérico",multiply:"Multiplicar",add:"Mais",
+subtract:"Subtrair",decimalPoint:"Ponto",divide:"Dividir",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Ponto-e-vírgula",equalSign:"Igual",comma:"Vírgula",dash:"Hífen",period:"Ponto",forwardSlash:"Barra",graveAccent:"Acento Grave",openBracket:"Abrir Conchetes",backSlash:"Contra-barra",closeBracket:"Fechar Colchetes",singleQuote:"Aspas Simples"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/pt.js b/release/plugins/a11yhelp/dialogs/lang/pt.js
new file mode 100644 (file)
index 0000000..9d3a27e
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","pt",{title:"Instruções de acessibilidade",contents:"Conteúdo de ajuda. Use a tecla ESC para fechar esta janela.",legend:[{name:"Geral",items:[{name:"Barra de ferramentas do editor",legend:"Clique em ${toolbarFocus} para navegar na barra de ferramentas. Para navegar entre o grupo da barra de ferramentas anterior e seguinte use TAB e SHIFT+TAB. Para navegar entre o botão da barra de ferramentas seguinte e anterior use a SETA DIREITA ou SETA ESQUERDA. Carregue em ESPAÇO ou ENTER para ativar o botão da barra de ferramentas."},
+{name:"Janela do editor",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Menu de contexto do editor",legend:"Clique em ${contextMenu} ou TECLA APLICAÇÃO para abrir o menu de contexto. Depois vá para a opção do menu seguinte com TAB ou SETA PARA BAIXO. Vá para a opção anterior com  SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu.  Abra o submenu da opção atual com ESPAÇO, ENTER ou SETA DIREITA. GVá para o item do menu parente  com ESC ou SETA ESQUERDA. Feche o menu de contexto com ESC."},
+{name:"Editor de caixa em lista",legend:"Dentro de uma lista, para navegar para o item seguinte da lista use TAB ou SETA PARA BAIXO. Para o item anterior da lista use SHIFT+TAB ou SETA PARA BAIXO. Carregue em ESPAÇO ou ENTER para selecionar a opção lista. Carregue em ESC para fechar a caixa da lista."},{name:"Editor da barra de caminho dos elementos",legend:"Clique em ${elementsPathFocus} para navegar na barra de caminho dos elementos. Para o botão do elemento seguinte use TAB ou SETA DIREITA. para o botão anterior use SHIFT+TAB ou SETA ESQUERDA. Carregue em ESPAÇO ou ENTER para selecionar o elemento no editor."}]},
+{name:"Comandos",items:[{name:"Comando de anular",legend:"Carregar ${undo}"},{name:"Comando de refazer",legend:"Clique ${redo}"},{name:"Comando de negrito",legend:"Pressione ${bold}"},{name:"Comando de itálico",legend:"Pressione ${italic}"},{name:"Comando de sublinhado",legend:"Pressione ${underline}"},{name:"Comando de hiperligação",legend:"Pressione ${link}"},{name:"Comando de ocultar barra de ferramentas",legend:"Pressione ${toolbarCollapse}"},{name:"Aceder ao comando espaço de foco anterior",
+legend:"Clique em ${accessPreviousSpace} para aceder ao espaço do focos inalcançável mais perto antes do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes."},{name:"Acesso comando do espaço focus seguinte",legend:"Pressione ${accessNextSpace} para aceder ao espaço do focos inalcançável mais perto depois do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes."},
+{name:"Ajuda a acessibilidade",legend:"Pressione ${a11yHelp}"}]}],tab:"Tab",pause:"Pausa",capslock:"Maiúsculas",escape:"Esc",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Seta esquerda",upArrow:"Seta para cima",rightArrow:"Seta direita",downArrow:"Seta para baixo",insert:"Inserir",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",
+numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiplicar",add:"Adicionar",subtract:"Subtrair",decimalPoint:"Decimal Point",divide:"Separar",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Vírgula",dash:"Cardinal",period:"Ponto",forwardSlash:"Forward Slash",graveAccent:"Acento grave",openBracket:"Open Bracket",backSlash:"Backslash",
+closeBracket:"Close Bracket",singleQuote:"Plica"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ro.js b/release/plugins/a11yhelp/dialogs/lang/ro.js
new file mode 100644 (file)
index 0000000..7a916d2
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ro",{title:"Instrucțiuni de accesibilitate",contents:"Cuprins. Pentru a închide acest dialog, apăsați tasta ESC.",legend:[{name:"General",items:[{name:"Editează bara instrumente.",legend:"Apasă ${toolbarFocus} pentru a naviga prin bara de instrumente. Pentru a te mișca prin grupurile de instrumente folosește tastele TAB și SHIFT+TAB. Pentru a te mișca intre diverse instrumente folosește tastele SĂGEATĂ DREAPTA sau SĂGEATĂ STÂNGA. Apasă butonul SPAȚIU sau ENTER pentru activarea instrumentului."},
+{name:"Dialog editor",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Editor meniu contextual",legend:"Apasă ${contextMenu} sau TASTA MENIU pentru a deschide meniul contextual. Treci la următoarea opțiune din meniu cu TAB sau SĂGEATĂ JOS. Treci la opțiunea anterioară cu  SHIFT+TAB sau SĂGEATĂ SUS. Apasă SPAȚIU sau ENTER pentru a selecta opțiunea din meniu. Deschide sub-meniul opțiunii curente cu SPAȚIU sau ENTER sau SĂGEATĂ DREAPTA. Revino la elementul din meniul părinte cu ESC sau SĂGEATĂ STÂNGA. Închide meniul de context cu ESC."},
+{name:"Editor Casetă Listă",legend:"În interiorul unei liste, treci la următorull element cu TAB sau SĂGEATĂ JOS. Treci la elementul anterior din listă cu SHIFT+TAB sau SĂGEATĂ SUS. Apasă SPAȚIU sau ENTER pentru a selecta opțiunea din listă. Apasă ESC pentru a închide lista."},{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},
+{name:"Comenzi",items:[{name:" Undo command",legend:"Apasă ${undo}"},{name:"Comanda precedentă",legend:"Apasă ${redo}"},{name:"Comanda Îngroșat",legend:"Apasă ${bold}"},{name:"Comanda Inclinat",legend:"Apasă ${italic}"},{name:"Comanda Subliniere",legend:"Apasă ${underline}"},{name:"Comanda Legatură",legend:"Apasă ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",
+rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",
+equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ru.js b/release/plugins/a11yhelp/dialogs/lang/ru.js
new file mode 100644 (file)
index 0000000..34f5cea
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ru",{title:"Горячие клавиши",contents:"Помощь. Для закрытия этого окна нажмите ESC.",legend:[{name:"Основное",items:[{name:"Панель инструментов",legend:"Нажмите ${toolbarFocus} для перехода к панели инструментов. Для перемещения между группами панели инструментов используйте TAB и SHIFT+TAB. Для перемещения между кнопками панели иструментов используйте кнопки ВПРАВО или ВЛЕВО. Нажмите ПРОБЕЛ или ENTER для запуска кнопки панели инструментов."},{name:"Диалоги",legend:'Внутри диалога, нажмите TAB чтобы перейти к следующему элементу диалога, нажмите SHIFT+TAB чтобы перейти к предыдущему элементу диалога, нажмите ENTER чтобы отправить диалог, нажмите ESC чтобы отменить диалог. Когда диалоговое окно имеет несколько вкладок, получить доступ к панели вкладок как части диалога можно нажатием или сочетания ALT+F10 или TAB, при этом активные элементы диалога будут перебираться с учетом порядка табуляции. При активной панели вкладок, переход к следующей или предыдущей вкладке осуществляется нажатием стрелки "ВПРАВО" или стрелки "ВЛЕВО" соответственно.'},
+{name:"Контекстное меню",legend:'Нажмите ${contextMenu} или клавишу APPLICATION, чтобы открыть контекстное меню. Затем перейдите к следующему пункту меню с помощью TAB или стрелкой "ВНИЗ". Переход к предыдущей опции - SHIFT+TAB или стрелкой "ВВЕРХ". Нажмите SPACE, или ENTER, чтобы задействовать опцию меню. Открыть подменю текущей опции - SPACE или ENTER или стрелкой "ВПРАВО". Возврат к родительскому пункту меню - ESC или стрелкой "ВЛЕВО". Закрытие контекстного меню - ESC.'},{name:"Редактор списка",
+legend:'Внутри окна списка, переход к следующему пункту списка - TAB или стрелкой "ВНИЗ". Переход к предыдущему пункту списка - SHIFT+TAB или стрелкой "ВВЕРХ". Нажмите SPACE, или ENTER, чтобы задействовать опцию списка. Нажмите ESC, чтобы закрыть окно списка.'},{name:"Путь к элементу",legend:'Нажмите ${elementsPathFocus}, чтобы перейти к панели пути элементов. Переход к следующей кнопке элемента - TAB или стрелкой "ВПРАВО". Переход к предыдущей кнопку - SHIFT+TAB или стрелкой "ВЛЕВО". Нажмите SPACE, или ENTER, чтобы выбрать элемент в редакторе.'}]},
+{name:"Команды",items:[{name:"Отменить",legend:"Нажмите ${undo}"},{name:"Повторить",legend:"Нажмите ${redo}"},{name:"Полужирный",legend:"Нажмите ${bold}"},{name:"Курсив",legend:"Нажмите ${italic}"},{name:"Подчеркнутый",legend:"Нажмите ${underline}"},{name:"Гиперссылка",legend:"Нажмите ${link}"},{name:"Свернуть панель инструментов",legend:"Нажмите ${toolbarCollapse}"},{name:"Команды доступа к предыдущему фокусному пространству",legend:'Нажмите ${accessPreviousSpace}, чтобы обратиться к ближайшему недостижимому фокусному пространству перед символом "^", например: два смежных HR элемента. Повторите комбинацию клавиш, чтобы достичь отдаленных фокусных пространств.'},
+{name:"Команды доступа к следующему фокусному пространству",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:"Справка по горячим клавишам",legend:"Нажмите ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Esc",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Стрелка влево",upArrow:"Стрелка вверх",rightArrow:"Стрелка вправо",downArrow:"Стрелка вниз",
+insert:"Insert",leftWindowKey:"Левая клавиша Windows",rightWindowKey:"Правая клавиша Windows",selectKey:"Выбрать",numpad0:"Цифра 0",numpad1:"Цифра 1",numpad2:"Цифра 2",numpad3:"Цифра 3",numpad4:"Цифра 4",numpad5:"Цифра 5",numpad6:"Цифра 6",numpad7:"Цифра 7",numpad8:"Цифра 8",numpad9:"Цифра 9",multiply:"Умножить",add:"Плюс",subtract:"Вычесть",decimalPoint:"Десятичная точка",divide:"Делить",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",
+scrollLock:"Scroll Lock",semiColon:"Точка с запятой",equalSign:"Равно",comma:"Запятая",dash:"Тире",period:"Точка",forwardSlash:"Наклонная черта",graveAccent:"Апостроф",openBracket:"Открыть скобку",backSlash:"Обратная наклонная черта",closeBracket:"Закрыть скобку",singleQuote:"Одинарная кавычка"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/si.js b/release/plugins/a11yhelp/dialogs/lang/si.js
new file mode 100644 (file)
index 0000000..7ca7341
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","si",{title:"ළඟා වියහැකි ",contents:"උදව් සඳහා අන්තර්ගතය.නික්මයෙමට ESC බොත්තම ඔබන්න",legend:[{name:"පොදු කරුණු",items:[{name:"සංස්කරණ මෙවලම් ",legend:"ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT+TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට SPACE හෝ ENTER බොත්තම ඔබන්න."},{name:"සංස්කරණ ",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"සංස්කරණ අඩංගුවට ",legend:"ඔබන්න ${අන්තර්ගත මෙනුව} හෝ  APPLICATION KEY  අන්තර්ගත-මෙනුව විවුරතකිරීමට. ඊළඟ මෙනුව-ව්කල්පයන්ට යෑමට TAB හෝ DOWN ARROW බොත්තම ද, පෙර විකල්පයන්ටයෑමට SHIFT+TAB හෝ  UP ARROW බොත්තම ද, මෙනුව-ව්කල්පයන් තේරීමට SPACE හෝ ENTER බොත්තම ද,  දැනට විවුර්තව ඇති උප-මෙනුවක වීකල්ප තේරීමට SPACE හෝ ENTER හෝ RIGHT ARROW ද, නැවත පෙර ප්‍රධාන මෙනුවට යෑමට  ESC හෝ LEFT ARROW බොත්තම ද.  අන්තර්ගත-මෙනුව වැසීමට  ESC බොත්තම ද ඔබන්න."},{name:"සංස්කරණ තේරුම් ",legend:"තේරුම් කොටුව තුළ , ඊළඟ අයිතමයට යෑමට TAB හෝ DOWN ARROW , පෙර අයිතමයට යෑමට SHIFT+TAB හෝ UP ARROW . අයිතම විකල්පයන් තේරීමට SPACE හෝ ENTER ,තේරුම් කොටුව වැසීමට ESC බොත්තම් ද ඔබන්න."},
+{name:"සංස්කරණ අංග සහිත ",legend:"ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT+TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට SPACE හෝ ENTER බොත්තම ඔබන්න."}]},{name:"විධාන",items:[{name:"විධානය වෙනස් ",legend:"ඔබන්න ${වෙනස් කිරීම}"},{name:"විධාන නැවත් පෙර පරිදිම වෙනස්කර ගැනීම.",legend:"ඔබන්න ${නැවත් පෙර පරිදිම වෙනස්කර ගැනීම}"},{name:"තද අකුරින් විධාන",legend:"ඔබන්න ${තද }"},
+{name:"බැධී අකුරු විධාන",legend:"ඔබන්න ${බැධී අකුරු }"},{name:"යටින් ඉරි ඇද ඇති විධාන.",legend:"ඔබන්න ${යටින් ඉරි ඇද ඇති}"},{name:"සම්බන්ධිත විධාන",legend:"ඔබන්න ${සම්බන්ධ }"},{name:"මෙවලම් තීරු හැකුලුම් විධාන",legend:"ඔබන්න ${මෙවලම් තීරු හැකුලුම් }"},{name:"යොමුවීමට පෙර  වැදගත්  විධාන",legend:"ඔබන්න ${යොමුවීමට ඊළඟ }"},{name:"යොමුවීමට ඊළග වැදගත්  විධාන",legend:"ඔබන්න ${යොමුවීමට ඊළඟ }"},{name:"ප්‍රවේශ ",legend:"ඔබන්න  ${a11y }"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",
+pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sk.js b/release/plugins/a11yhelp/dialogs/lang/sk.js
new file mode 100644 (file)
index 0000000..f637562
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sk",{title:"Inštrukcie prístupnosti",contents:"Pomocný obsah. Pre zatvorenie tohto okna, stlačte ESC.",legend:[{name:"Všeobecne",items:[{name:"Lišta nástrojov editora",legend:"Stlačte ${toolbarFocus} pre navigáciu na lištu nástrojov. Medzi ďalšou a predchádzajúcou lištou nástrojov sa pohybujete s TAB a SHIFT+TAB. Medzi ďalším a predchádzajúcim tlačidlom na lište nástrojov sa pohybujete s pravou šípkou a ľavou šípkou. Stlačte medzerník alebo ENTER pre aktiváciu tlačidla lišty nástrojov."},
+{name:"Editorový dialóg",legend:"V dialógovom okne stlačte TAB pre presun na ďalší prvok, SHIFT+TAB pre presun na predchádzajúci prvok, ENTER pre odoslanie, ESC pre zrušenie. Keď má dialógové okno viacero kariet, zoznam kariet dosiahnete buď stlačením ALT+F10 alebo s TAB v príslušnom poradí kariet. So zameraným zoznamom kariet sa pohybujte k ďalšej alebo predchádzajúcej karte cez PRAVÚ a ĽAVÚ ŠÍPKU."},{name:"Editorové kontextové menu",legend:"Stlačte ${contextMenu} alebo APPLICATION KEY pre otvorenie kontextového menu. Potom sa presúvajte na ďalšie možnosti menu s TAB alebo dolnou šípkou. Presunte sa k predchádzajúcej možnosti s SHIFT+TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti menu. Otvorte pod-menu danej možnosti s medzerníkom, alebo ENTER, alebo pravou šípkou. Vráťte sa späť do položky rodičovského menu s ESC alebo ľavou šípkou. Zatvorte kontextové menu s ESC."},
+{name:"Editorov box zoznamu",legend:"V boxe zoznamu, presuňte sa na ďalšiu položku v zozname s TAB alebo dolnou šípkou. Presuňte sa k predchádzajúcej položke v zozname so SHIFT+TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti zoznamu. Stlačte ESC pre zatvorenie boxu zoznamu."},{name:"Editorove pásmo cesty prvku",legend:"Stlačte ${elementsPathFocus} pre navigovanie na pásmo cesty elementu. Presuňte sa na tlačidlo ďalšieho prvku s TAB alebo pravou šípkou. Presuňte sa k predchádzajúcemu tlačidlu s SHIFT+TAB alebo ľavou šípkou. Stlačte medzerník alebo ENTER pre výber prvku v editore."}]},
+{name:"Príkazy",items:[{name:"Vrátiť príkazy",legend:"Stlačte ${undo}"},{name:"Nanovo vrátiť príkaz",legend:"Stlačte ${redo}"},{name:"Príkaz na stučnenie",legend:"Stlačte ${bold}"},{name:"Príkaz na kurzívu",legend:"Stlačte ${italic}"},{name:"Príkaz na podčiarknutie",legend:"Stlačte ${underline}"},{name:"Príkaz na odkaz",legend:"Stlačte ${link}"},{name:"Príkaz na zbalenie lišty nástrojov",legend:"Stlačte ${toolbarCollapse}"},{name:"Prejsť na predchádzajúcu zamerateľnú medzeru príkazu",legend:"Stlačte ${accessPreviousSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery pred vsuvkuo. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier."},
+{name:"Prejsť na ďalší ",legend:"Stlačte ${accessNextSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery po vsuvke. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier."},{name:"Pomoc prístupnosti",legend:"Stlačte ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Stránka hore",pageDown:"Stránka dole",leftArrow:"Šípka naľavo",upArrow:"Šípka hore",rightArrow:"Šípka napravo",
+downArrow:"Šípka dole",insert:"Insert",leftWindowKey:"Ľavé Windows tlačidlo",rightWindowKey:"Pravé Windows tlačidlo",selectKey:"Tlačidlo Select",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Násobenie",add:"Sčítanie",subtract:"Odčítanie",decimalPoint:"Desatinná čiarka",divide:"Delenie",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",
+f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Bodkočiarka",equalSign:"Rovná sa",comma:"Čiarka",dash:"Pomĺčka",period:"Bodka",forwardSlash:"Lomítko",graveAccent:"Zdôrazňovanie prízvuku",openBracket:"Hranatá zátvorka otváracia",backSlash:"Backslash",closeBracket:"Hranatá zátvorka zatváracia",singleQuote:"Jednoduché úvodzovky"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sl.js b/release/plugins/a11yhelp/dialogs/lang/sl.js
new file mode 100644 (file)
index 0000000..01cfc7f
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sl",{title:"Navodila za dostopnost",contents:"Vsebina pomoči. Če želite zapreti pogovorno okno, pritisnite ESC.",legend:[{name:"Splošno",items:[{name:"Orodna vrstica urejevalnika",legend:"Pritisnite ${toolbarFocus} za pomik v orodno vrstico. Z TAB in SHIFT+TAB se pomikate na naslednjo in prejšnjo skupino orodne vrstice. Z DESNO PUŠČICO ali LEVO PUŠČICO se pomikate na naslednji in prejšnji gumb orodne vrstice. Pritisnite SPACE ali ENTER, da aktivirate gumb orodne vrstice."},
+{name:"Urejevalno Pogovorno Okno",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},{name:"Kontekstni meni urejevalnika",legend:"Pritisnite ${contextMenu} ali APPLICATION KEY, da odprete kontekstni meni. Nato se premaknite na naslednjo možnost menija s tipko TAB ali PUŠČICA DOL. Premakniti se na prejšnjo možnost z SHIFT + TAB ali PUŠČICA GOR. Pritisnite SPACE ali ENTER za izbiro možnosti menija. Odprite podmeni trenutne možnosti menija s tipko SPACE ali ENTER ali DESNA PUŠČICA. Vrnite se na matični element menija s tipko ESC ali LEVA PUŠČICA. Zaprite kontekstni meni z ESC."},
+{name:"Urejevalno Seznamsko Polje",legend:"Znotraj seznama, se premaknete na naslednji element seznama s tipko TAB ali PUŠČICO DOL. Z SHIFT+TAB ali PUŠČICO GOR se premaknete na prejšnji element seznama. Pritisnite tipko SPACE ali ENTER za izbiro elementa. Pritisnite tipko ESC, da zaprete seznam."},{name:"Urejevalna vrstica poti elementa",legend:"Pritisnite ${elementsPathFocus} za pomikanje po vrstici elementnih poti. S TAB ali DESNA PUŠČICA se premaknete na naslednji gumb elementa. Z SHIFT+TAB ali LEVO PUŠČICO se premaknete na prejšnji gumb elementa. Pritisnite SPACE ali ENTER za izbiro elementa v urejevalniku."}]},
+{name:"Ukazi",items:[{name:"Razveljavi ukaz",legend:"Pritisnite ${undo}"},{name:"Ponovi ukaz",legend:"Pritisnite ${redo}"},{name:"Krepki ukaz",legend:"Pritisnite ${bold}"},{name:"Ležeči ukaz",legend:"Pritisnite ${italic}"},{name:"Poudarni ukaz",legend:"Pritisnite ${underline}"},{name:"Ukaz povezave",legend:"Pritisnite ${link}"},{name:"Skrči Orodno Vrstico Ukaz",legend:"Pritisnite ${toolbarCollapse}"},{name:"Dostop do prejšnjega ukaza ostrenja",legend:"Pritisnite ${accessPreviousSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora pred strešico, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore."},
+{name:"Dostop do naslednjega ukaza ostrenja",legend:"Pritisnite ${accessNextSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora po strešici, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore."},{name:"Pomoč dostopnosti",legend:"Pritisnite ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Puščica levo",upArrow:"Puščica gor",rightArrow:"Puščica desno",
+downArrow:"Puščica dol",insert:"Insert",leftWindowKey:"Leva tipka Windows",rightWindowKey:"Desna tipka Windows",selectKey:"Select tipka",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Zmnoži",add:"Dodaj",subtract:"Odštej",decimalPoint:"Decimalna vejica",divide:"Deli",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",
+f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Podpičje",equalSign:"Enačaj",comma:"Vejica",dash:"Vezaj",period:"Pika",forwardSlash:"Desna poševnica",graveAccent:"Krativec",openBracket:"Oklepaj",backSlash:"Leva poševnica",closeBracket:"Zaklepaj",singleQuote:"Opuščaj"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sq.js b/release/plugins/a11yhelp/dialogs/lang/sq.js
new file mode 100644 (file)
index 0000000..247e9fa
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sq",{title:"Udhëzimet e Qasjes",contents:"Përmbajtja ndihmëse. Për ta mbyllur dialogun shtyp ESC.",legend:[{name:"Të përgjithshme",items:[{name:"Shiriti i Redaktuesit",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Dialogu i Redaktuesit",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Komandat",items:[{name:"Rikthe komandën",legend:"Shtyp ${undo}"},{name:"Ribëj komandën",legend:"Shtyp ${redo}"},{name:"Komanda e trashjes së tekstit",legend:"Shtyp ${bold}"},{name:"Komanda kursive",legend:"Shtyp ${italic}"},
+{name:"Komanda e nënvijëzimit",legend:"Shtyp ${underline}"},{name:"Komanda e Nyjes",legend:"Shtyp ${link}"},{name:" Toolbar Collapse command",legend:"Shtyp ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:"Ndihmë Qasjeje",legend:"Shtyp ${a11yHelp}"}]}],tab:"Fletë",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Shenja majtas",upArrow:"Shenja sipër",rightArrow:"Shenja djathtas",downArrow:"Shenja poshtë",insert:"Shto",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Shto",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Presje",dash:"vizë",period:"Pikë",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Hape kllapën",backSlash:"Backslash",closeBracket:"Mbylle kllapën",
+singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sr-latn.js b/release/plugins/a11yhelp/dialogs/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..da29ebd
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sr-latn",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Opšte",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sr.js b/release/plugins/a11yhelp/dialogs/lang/sr.js
new file mode 100644 (file)
index 0000000..02ebb1c
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sr",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Опште",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Commands",items:[{name:" Undo command",legend:"Press ${undo}"},{name:" Redo command",legend:"Press ${redo}"},{name:" Bold command",legend:"Press ${bold}"},{name:" Italic command",legend:"Press ${italic}"},{name:" Underline command",
+legend:"Press ${underline}"},{name:" Link command",legend:"Press ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/sv.js b/release/plugins/a11yhelp/dialogs/lang/sv.js
new file mode 100644 (file)
index 0000000..720193f
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","sv",{title:"Hjälpmedelsinstruktioner",contents:"Hjälpinnehåll. För att stänga denna dialogruta trycker du på ESC.",legend:[{name:"Allmänt",items:[{name:"Editor verktygsfält",legend:"Tryck på ${toolbarFocus} för att navigera till verktygsfältet. Flytta till nästa och föregående verktygsfältsgrupp med TAB och SHIFT+TAB. Flytta till nästa och föregående knapp i verktygsfältet med HÖGERPIL eller VÄNSTERPIL. Tryck SPACE eller ENTER för att aktivera knappen i verktygsfältet."},
+{name:"Dialogeditor",legend:"Inuti en dialogruta, tryck TAB för att navigera till nästa fält i dialogrutan, tryck SKIFT+TAB för att flytta till föregående fält, tryck ENTER för att skicka. Du avbryter och stänger dialogen med ESC. För dialogrutor som har flera flikar, tryck ALT+F10 eller TAB för att navigera till fliklistan. med fliklistan vald flytta till nästa och föregående flik med HÖGER- eller VÄNSTERPIL."},{name:"Editor för innehållsmeny",legend:"Tryck på $ {contextMenu} eller PROGRAMTANGENTEN för att öppna snabbmenyn. Flytta sedan till nästa menyalternativ med TAB eller NEDPIL. Flytta till föregående alternativ med SHIFT + TABB eller UPPIL. Tryck Space eller ENTER för att välja menyalternativ. Öppna undermeny av nuvarande alternativ med SPACE eller ENTER eller HÖGERPIL. Gå tillbaka till överordnade menyalternativ med ESC eller VÄNSTERPIL. Stäng snabbmenyn med ESC."},
+{name:"Editor för list-box",legend:"Inuti en list-box, gå till nästa listobjekt med TAB eller NEDPIL. Flytta till föregående listobjekt med SHIFT+TAB eller UPPIL. Tryck SPACE eller ENTER för att välja listan alternativet. Tryck ESC för att stänga list-boxen."},{name:"Editor för elementens sökväg",legend:"Tryck på ${elementsPathFocus} för att navigera till verktygsfältet för elementens sökvägar. Flytta till nästa elementknapp med TAB eller HÖGERPIL. Flytta till föregående knapp med SKIFT+TAB eller VÄNSTERPIL. Tryck SPACE eller ENTER för att välja element i redigeraren."}]},
+{name:"Kommandon",items:[{name:"Ångra kommando",legend:"Tryck på ${undo}"},{name:"Gör om kommando",legend:"Tryck på ${redo}"},{name:"Kommandot fet stil",legend:"Tryck på ${bold}"},{name:"Kommandot kursiv",legend:"Tryck på ${italic}"},{name:"Kommandot understruken",legend:"Tryck på ${underline}"},{name:"Kommandot länk",legend:"Tryck på ${link}"},{name:"Verktygsfält Dölj kommandot",legend:"Tryck på ${toolbarCollapse}"},{name:"Gå till föregående fokus plats",legend:"Tryck på ${accessPreviousSpace} för att gå till närmast onåbara utrymme före markören, exempel: två intilliggande HR element. Repetera tangentkombinationen för att gå till nästa."},
+{name:"Tillgå nästa fokuskommandots utrymme",legend:"Tryck ${accessNextSpace} på för att komma åt den närmaste onåbar fokus utrymme efter cirkumflex, till exempel: två intilliggande HR element. Upprepa tangentkombinationen för att nå avlägsna fokus utrymmen."},{name:"Hjälp om tillgänglighet",legend:"Tryck ${a11yHelp}"}]}],tab:"Tab",pause:"Paus",capslock:"Caps lock",escape:"Escape",pageUp:"Sida Up",pageDown:"Sida Ned",leftArrow:"Vänsterpil",upArrow:"Uppil",rightArrow:"Högerpil",downArrow:"Nedåtpil",
+insert:"Infoga",leftWindowKey:"Vänster Windowstangent",rightWindowKey:"Höger Windowstangent",selectKey:"Välj tangent",numpad0:"Nummer 0",numpad1:"Nummer 1",numpad2:"Nummer 2",numpad3:"Nummer 3",numpad4:"Nummer 4",numpad5:"Nummer 5",numpad6:"Nummer 6",numpad7:"Nummer 7",numpad8:"Nummer 8",numpad9:"Nummer 9",multiply:"Multiplicera",add:"Addera",subtract:"Minus",decimalPoint:"Decimalpunkt",divide:"Dividera",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",
+numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semikolon",equalSign:"Lika med tecken",comma:"Komma",dash:"Minus",period:"Punkt",forwardSlash:"Snedstreck framåt",graveAccent:"Accent",openBracket:"Öppningsparentes",backSlash:"Snedstreck bakåt",closeBracket:"Slutparentes",singleQuote:"Enkelt Citattecken"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/th.js b/release/plugins/a11yhelp/dialogs/lang/th.js
new file mode 100644 (file)
index 0000000..a61d6cf
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","th",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"ทั่วไป",items:[{name:"แถบเครื่องมือสำหรับเครื่องมือช่วยพิมพ์",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"คำสั่ง",items:[{name:"เลิกทำคำสั่ง",legend:"วาง ${undo}"},{name:"คำสั่งสำหรับทำซ้ำ",legend:"วาง ${redo}"},{name:"คำสั่งสำหรับตัวหนา",legend:"วาง ${bold}"},{name:"คำสั่งสำหรับตัวเอียง",legend:"วาง ${italic}"},{name:"คำสั่งสำหรับขีดเส้นใต้",
+legend:"วาง ${underline}"},{name:"คำสั่งสำหรับลิงก์",legend:"วาง ${link}"},{name:" Toolbar Collapse command",legend:"Press ${toolbarCollapse}"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"Press ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Left Arrow",upArrow:"Up Arrow",rightArrow:"Right Arrow",downArrow:"Down Arrow",insert:"Insert",leftWindowKey:"Left Windows key",rightWindowKey:"Right Windows key",selectKey:"Select key",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",
+numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Multiply",add:"Add",subtract:"Subtract",decimalPoint:"Decimal Point",divide:"Divide",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Semicolon",equalSign:"Equal Sign",comma:"Comma",dash:"Dash",period:"Period",forwardSlash:"Forward Slash",graveAccent:"Grave Accent",openBracket:"Open Bracket",backSlash:"Backslash",closeBracket:"Close Bracket",singleQuote:"Single Quote"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/tr.js b/release/plugins/a11yhelp/dialogs/lang/tr.js
new file mode 100644 (file)
index 0000000..87769c2
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","tr",{title:"Erişilebilirlik Talimatları",contents:"Yardım içeriği. Bu pencereyi kapatmak için ESC tuşuna basın.",legend:[{name:"Genel",items:[{name:"Düzenleyici Araç Çubuğu",legend:"Araç çubuğunda gezinmek için ${toolbarFocus} basın. TAB ve SHIFT+TAB ile önceki ve sonraki araç çubuğu grubuna taşıyın. SAĞ OK veya SOL OK ile önceki ve sonraki bir araç çubuğu düğmesini hareket ettirin. SPACE tuşuna basın veya araç çubuğu düğmesini etkinleştirmek için ENTER tuşna basın."},
+{name:"Diyalog Düzenleyici",legend:"Dialog penceresi içinde, sonraki iletişim alanına gitmek için SEKME tuşuna basın, önceki alana geçmek için SHIFT + TAB tuşuna basın, pencereyi göndermek için ENTER tuşuna basın, dialog penceresini iptal etmek için ESC tuşuna basın. Birden çok sekme sayfaları olan diyalogların, sekme listesine gitmek için ALT + F10 tuşlarına basın. Sonra TAB veya SAĞ OK sonraki sekmeye taşıyın. SHIFT + TAB veya SOL OK ile önceki sekmeye geçin. Sekme sayfayı seçmek için SPACE veya ENTER tuşuna basın."},
+{name:"İçerik Menü Editörü",legend:"İçerik menüsünü açmak için ${contextMenu} veya UYGULAMA TUŞU'na basın. Daha sonra SEKME veya AŞAĞI OK ile bir sonraki menü seçeneği taşıyın. SHIFT + TAB veya YUKARI OK ile önceki seçeneğe gider. Menü seçeneğini seçmek için SPACE veya ENTER tuşuna basın. Seçili seçeneğin alt menüsünü SPACE ya da ENTER veya SAĞ OK açın. Üst menü öğesini geçmek için ESC veya SOL OK ile geri dönün. ESC ile bağlam menüsünü kapatın."},{name:"Liste Kutusu Editörü",legend:"Liste kutusu içinde, bir sonraki liste öğesine SEKME VEYA AŞAĞI OK ile taşıyın. SHIFT+TAB veya YUKARI önceki liste öğesi taşıyın. Liste seçeneği seçmek için SPACE veya ENTER tuşuna basın. Liste kutusunu kapatmak için ESC tuşuna basın."},
+{name:"Element Yol Çubuğu Editörü",legend:"Elementlerin yol çubuğunda gezinmek için ${ElementsPathFocus} basın. SEKME veya SAĞ OK ile sonraki element düğmesine taşıyın. SHIFT+TAB veya SOL OK önceki düğmeye hareket ettirin. Editör içindeki elementi seçmek için ENTER veya SPACE tuşuna basın."}]},{name:"Komutlar",items:[{name:"Komutu geri al",legend:"$(undo)'ya basın"},{name:"Komutu geri al",legend:"${redo} basın"},{name:" Kalın komut",legend:"${bold} basın"},{name:" İtalik komutu",legend:"${italic} basın"},
+{name:" Alttan çizgi komutu",legend:"${underline} basın"},{name:" Bağlantı komutu",legend:"${link} basın"},{name:" Araç çubuğu Toplama komutu",legend:"${toolbarCollapse} basın"},{name:"Önceki komut alanına odaklan",legend:"Düzeltme imleçinden önce, en yakın uzaktaki alana erişmek için ${accessPreviousSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın."},{name:"Sonraki komut alanına odaklan",legend:"Düzeltme imleçinden sonra, en yakın uzaktaki alana erişmek için ${accessNextSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın."},
+{name:"Erişilebilirlik Yardımı",legend:"${a11yHelp}'e basın"}]}],tab:"Sekme tuşu",pause:"Durdurma tuşu",capslock:"Büyük harf tuşu",escape:"Vazgeç tuşu",pageUp:"Sayfa Yukarı",pageDown:"Sayfa Aşağı",leftArrow:"Sol ok",upArrow:"Yukarı ok",rightArrow:"Sağ ok",downArrow:"Aşağı ok",insert:"Araya gir",leftWindowKey:"Sol windows tuşu",rightWindowKey:"Sağ windows tuşu",selectKey:"Seçme tuşu",numpad0:"Nümerik 0",numpad1:"Nümerik 1",numpad2:"Nümerik 2",numpad3:"Nümerik 3",numpad4:"Nümerik 4",numpad5:"Nümerik 5",
+numpad6:"Nümerik 6",numpad7:"Nümerik 7",numpad8:"Nümerik 8",numpad9:"Nümerik 9",multiply:"Çarpma",add:"Toplama",subtract:"Çıkarma",decimalPoint:"Ondalık işareti",divide:"Bölme",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lk",scrollLock:"Scr Lk",semiColon:"Noktalı virgül",equalSign:"Eşittir",comma:"Virgül",dash:"Eksi",period:"Nokta",forwardSlash:"İleri eğik çizgi",graveAccent:"Üst tırnak",openBracket:"Parantez aç",backSlash:"Ters eğik çizgi",
+closeBracket:"Parantez kapa",singleQuote:"Tek tırnak"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/tt.js b/release/plugins/a11yhelp/dialogs/lang/tt.js
new file mode 100644 (file)
index 0000000..665dd37
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","tt",{title:"Accessibility Instructions",contents:"Help Contents. To close this dialog press ESC.",legend:[{name:"Гомуми",items:[{name:"Editor Toolbar",legend:"Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button."},{name:"Editor Dialog",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Editor Context Menu",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC."},{name:"Editor List Box",legend:"Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box."},
+{name:"Editor Element Path Bar",legend:"Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor."}]},{name:"Командалар",items:[{name:"Кайтару",legend:"${undo} басыгыз"},{name:"Кабатлау",legend:"${redo} басыгыз"},{name:"Калын",legend:"${bold} басыгыз"},{name:"Курсив",legend:"${italic} басыгыз"},{name:"Астына сызылган",legend:"${underline} басыгыз"},
+{name:"Сылталама",legend:"${link} басыгыз"},{name:" Toolbar Collapse command",legend:"${toolbarCollapse} басыгыз"},{name:" Access previous focus space command",legend:"Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},{name:" Access next focus space command",legend:"Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces."},
+{name:" Accessibility Help",legend:"${a11yHelp} басыгыз"}]}],tab:"Tab",pause:"Тыныш",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Сул якка ук",upArrow:"Өскә таба ук",rightArrow:"Уң якка ук",downArrow:"Аска таба ук",insert:"Өстәү",leftWindowKey:"Сул Windows төймəсе",rightWindowKey:"Уң Windows төймəсе",selectKey:"Select төймəсе",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",
+numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Тапкырлау",add:"Кушу",subtract:"Алу",decimalPoint:"Унарлы нокта",divide:"Бүлү",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Нокталы өтер",equalSign:"Тигезлек билгесе",comma:"Өтер",dash:"Сызык",period:"Дәрәҗә",forwardSlash:"Кыек сызык",graveAccent:"Гравис",openBracket:"Җәя ачу",backSlash:"Кире кыек сызык",closeBracket:"Җәя ябу",
+singleQuote:"Бер иңле куштырнаклар"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/ug.js b/release/plugins/a11yhelp/dialogs/lang/ug.js
new file mode 100644 (file)
index 0000000..fb74e51
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","ug",{title:"قوشۇمچە چۈشەندۈرۈش",contents:"ياردەم مەزمۇنى. بۇ سۆزلەشكۈنى ياپماقچى بولسىڭىز ESC نى بېسىڭ.",legend:[{name:"ئادەتتىكى",items:[{name:"قورال بالداق تەھرىر",legend:"${toolbarFocus} بېسىلسا قورال بالداققا يېتەكلەيدۇ، TAB ياكى SHIFT+TAB ئارقىلىق قورال بالداق گۇرۇپپىسى تاللىنىدۇ، ئوڭ سول يا ئوقتا توپچا تاللىنىدۇ، بوشلۇق ياكى Enter كۇنۇپكىسىدا تاللانغان توپچىنى قوللىنىدۇ."},{name:"تەھرىرلىگۈچ سۆزلەشكۈسى",legend:"سۆزلەشكۈدە TAB كۇنۇپكىسىدا كېيىنكى سۆز بۆلىكىگە يۆتكىلىدۇ، SHIFT+TAB بىرىكمە كۇنۇپكىسىدا ئالدىنقى سۆز بۆلىكىگە يۆتكىلىدۇ، ENTER كۇنۇپكىسىدا سۆزلەشكۈنى تاپشۇرىدۇ، ESC كۇنۇپكىسى سۆزلەشكۈدىن ۋاز كېچىدۇ. كۆپ بەتكۈچلۈك سۆزلەشكۈگە نىسبەتەن، ALT+F10 دا بەتكۈچ تىزىمىغا يۆتكەيدۇ. ئاندىن TAB كۇنۇپكىسى ياكى ئوڭ يا ئوق كۇنۇپكىسى كېيىنكى بەتكۈچكە يۆتكەيدۇ؛SHIFT+ TAB كۇنۇپكىسى ياكى سول يا ئوق كۇنۇپكىسى ئالدىنقى بەتكۈچكە يۆتكەيدۇ. بوشلۇق كۇنۇپكىسى ياكى ENTER كۇنۇپكىسى بەتكۈچنى تاللايدۇ."},
+{name:"تەھرىرلىگۈچ تىل مۇھىت تىزىملىكى",legend:"${contextMenu} ياكى ئەپ كۇنۇپكىسىدا تىل مۇھىت تىزىملىكىنى ئاچىدۇ. ئاندىن TAB ياكى ئاستى يا ئوق كۇنۇپكىسىدا كېيىنكى تىزىملىك تۈرىگە يۆتكەيدۇ؛ SHIFT+TAB ياكى ئۈستى يا ئوق كۇنۇپكىسىدا ئالدىنقى تىزىملىك تۈرىگە يۆتكەيدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىملىك تۈرىنى تاللايدۇ. بوشلۇق، ENTER ياكى ئوڭ يا ئوق كۇنۇپكىسىدا تارماق تىزىملىكنى ئاچىدۇ. قايتىش تىزىملىكىگە ESC ياكى سول يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ESC كۇنۇپكىسىدا تىل مۇھىت تىزىملىكى تاقىلىدۇ."},{name:"تەھرىرلىگۈچ تىزىمى",
+legend:"تىزىم قۇتىسىدا، كېيىنكى تىزىم تۈرىگە يۆتكەشتە TAB ياكى ئاستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ئالدىنقى تىزىم تۈرىگە يۆتكەشتە SHIFT+TAB ياكى ئۈستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىم تۈرىنى تاللايدۇ.ESC كۇنۇپكىسىدا تىزىم قۇتىسىنى يىغىدۇ."},{name:"تەھرىرلىگۈچ ئېلېمېنت يول بالداق",legend:"${elementsPathFocus} بېسىلسا ئېلېمېنت يول بالداققا يېتەكلەيدۇ، TAB ياكى ئوڭ يا ئوقتا كېيىنكى ئېلېمېنت تاللىنىدۇ، SHIFT+TAB ياكى سول يا ئوقتا ئالدىنقى ئېلېمېنت تاللىنىدۇ، بوشلۇق ياكى Enter كۇنۇپكىسىدا تەھرىرلىگۈچتىكى ئېلېمېنت تاللىنىدۇ."}]},
+{name:"بۇيرۇق",items:[{name:"بۇيرۇقتىن يېنىۋال",legend:"${undo} نى بېسىڭ"},{name:"قايتىلاش بۇيرۇقى",legend:"${redo} نى بېسىڭ"},{name:"توملىتىش بۇيرۇقى",legend:"${bold} نى بېسىڭ"},{name:"يانتۇ بۇيرۇقى",legend:"${italic} نى بېسىڭ"},{name:"ئاستى سىزىق بۇيرۇقى",legend:"${underline} نى بېسىڭ"},{name:"ئۇلانما بۇيرۇقى",legend:"${link} نى بېسىڭ"},{name:"قورال بالداق قاتلاش بۇيرۇقى",legend:"${toolbarCollapse} نى بېسىڭ"},{name:"ئالدىنقى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق",legend:"${accessPreviousSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ ئالدىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ."},
+{name:"كېيىنكى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق",legend:"${accessNextSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ كەينىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ."},{name:"توسالغۇسىز لايىھە چۈشەندۈرۈشى",legend:"${a11yHelp} نى بېسىڭ"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Escape",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"سول يا ئوق",
+upArrow:"ئۈستى يا ئوق",rightArrow:"ئوڭ يا ئوق",downArrow:"ئاستى يا ئوق",insert:"قىستۇر",leftWindowKey:"سول Windows كۇنۇپكىسى",rightWindowKey:"ئوڭ Windows كۇنۇپكىسى",selectKey:"تاللاش كۇنۇپكىسى",numpad0:"سان تاختا 0",numpad1:"سان تاختا 1",numpad2:"سان تاختا 2",numpad3:"سان تاختا 3",numpad4:"سان تاختا 4",numpad5:"سان تاختا 5",numpad6:"سان تاختا 6",numpad7:"سان تاختا 7",numpad8:"سان تاختا 8",numpad9:"سان تاختا 9",multiply:"يۇلتۇز كۇنۇپكىسى",add:"قوشۇش",subtract:"ئېلىش",decimalPoint:"كەسىر چېكىت",divide:"بۆلۈش",
+f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"سان قۇلۇپ كۇنۇپكىسى",scrollLock:"سۈرگۈچ قۇلۇپ كۇنۇپكىسى",semiColon:"چېكىتلىك پەش",equalSign:"تەڭلىك بەلگىسى",comma:"پەش",dash:"سىزىقچە",period:"چېكىت",forwardSlash:"سولغا يانتۇ سىزىق",graveAccent:"ئۇرغۇ بەلگىسى",openBracket:"ئېچىلغان تىرناق",backSlash:"ئوڭغا يانتۇ سىزىق",closeBracket:"يېپىلغان تىرناق",singleQuote:"يالاڭ پەش"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/uk.js b/release/plugins/a11yhelp/dialogs/lang/uk.js
new file mode 100644 (file)
index 0000000..4aff22c
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","uk",{title:"Спеціальні Інструкції",contents:"Довідка. Натисніть ESC і вона зникне.",legend:[{name:"Основне",items:[{name:"Панель Редактора",legend:"Натисніть ${toolbarFocus} для переходу до панелі інструментів. Для переміщення між групами панелі інструментів використовуйте TAB і SHIFT+TAB. Для переміщення між кнопками панелі іструментів використовуйте кнопки СТРІЛКА ВПРАВО або ВЛІВО. Натисніть ПРОПУСК або ENTER для запуску кнопки панелі інструментів."},{name:"Діалог Редактора",
+legend:'Усередині діалогу, натисніть TAB щоб перейти до наступного елементу діалогу, натисніть SHIFT+TAB щоб перейти до попереднього елемента діалогу, натисніть ENTER щоб відправити діалог, натисніть ESC щоб скасувати діалог. Коли діалогове вікно має декілька вкладок, отримати доступ до панелі вкладок як частині діалогу можна натисканням або поєднання ALT+F10 або TAB, при цьому активні елементи діалогу будуть перебиратися з урахуванням порядку табуляції. При активній панелі вкладок, перехід до наступної або попередньої вкладці здійснюється натисканням стрілки "ВПРАВО" або стрілки "ВЛЕВО" відповідно.'},
+{name:"Контекстне Меню Редактора",legend:"Press ${contextMenu} or APPLICATION KEY to open context-menu. Потім перейдіть до наступного пункту меню за допомогою TAB або СТРІЛКИ ВНИЗ. Натисніть ПРОПУСК або ENTER для вибору параметру меню. Відкрийте підменю поточного параметру, натиснувши ПРОПУСК або ENTER або СТРІЛКУ ВПРАВО. Перейдіть до батьківського елемента меню, натиснувши ESC або СТРІЛКУ ВЛІВО. Закрийте контекстне меню, натиснувши ESC."},{name:"Скринька Списків Редактора",legend:"Усередині списку, перехід до наступного пункту списку виконується клавішею TAB або СТРІЛКА ВНИЗ. Перехід до попереднього елемента списку клавішею SHIFT+TAB або СТРІЛКА ВГОРУ. Натисніть ПРОПУСК або ENTER, щоб вибрати параметр списку. Натисніть клавішу ESC, щоб закрити список."},
+{name:"Шлях до елемента редактора",legend:"Натисніть ${elementsPathFocus} для навігації між елементами панелі. Перейдіть до наступного елемента кнопкою TAB або СТРІЛКА ВПРАВО. Перейдіть до попереднього елемента кнопкою SHIFT+TAB або СТРІЛКА ВЛІВО. Натисніть ПРОПУСК або ENTER для вибору елемента в редакторі."}]},{name:"Команди",items:[{name:"Відмінити команду",legend:"Натисніть ${undo}"},{name:"Повторити",legend:"Натисніть ${redo}"},{name:"Жирний",legend:"Натисніть ${bold}"},{name:"Курсив",legend:"Натисніть ${italic}"},
+{name:"Підкреслений",legend:"Натисніть ${underline}"},{name:"Посилання",legend:"Натисніть ${link}"},{name:"Згорнути панель інструментів",legend:"Натисніть ${toolbarCollapse}"},{name:"Доступ до попереднього місця фокусування",legend:"Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування перед кареткою, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування."},{name:"Доступ до наступного місця фокусування",legend:"Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування після каретки, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування."},
+{name:"Допомога з доступності",legend:"Натисніть ${a11yHelp}"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Esc",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"Ліва стрілка",upArrow:"Стрілка вгору",rightArrow:"Права стрілка",downArrow:"Стрілка вниз",insert:"Вставити",leftWindowKey:"Ліва клавіша Windows",rightWindowKey:"Права клавіша Windows",selectKey:"Виберіть клавішу",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",
+numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"Множення",add:"Додати",subtract:"Віднімання",decimalPoint:"Десяткова кома",divide:"Ділення",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Крапка з комою",equalSign:"Знак рівності",comma:"Кома",dash:"Тире",period:"Період",forwardSlash:"Коса риска",graveAccent:"Гравіс",openBracket:"Відкрити дужку",backSlash:"Зворотна коса риска",
+closeBracket:"Закрити дужку",singleQuote:"Одинарні лапки"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/vi.js b/release/plugins/a11yhelp/dialogs/lang/vi.js
new file mode 100644 (file)
index 0000000..616286b
--- /dev/null
@@ -0,0 +1,11 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","vi",{title:"Hướng dẫn trợ năng",contents:"Nội dung Hỗ trợ. Nhấn ESC để đóng hộp thoại.",legend:[{name:"Chung",items:[{name:"Thanh công cụ soạn thảo",legend:"Nhấn ${toolbarFocus} để điều hướng đến thanh công cụ. Nhấn TAB và SHIFT+TAB để chuyển đến nhóm thanh công cụ khác. Nhấn MŨI TÊN PHẢI hoặc MŨI TÊN TRÁI để chuyển sang nút khác trên thanh công cụ. Nhấn PHÍM CÁCH hoặc ENTER để kích hoạt nút trên thanh công cụ."},{name:"Hộp thoại Biên t",legend:"Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively."},
+{name:"Trình đơn Ngữ cảnh cBộ soạn thảo",legend:"Nhấn ${contextMenu} hoặc PHÍM ỨNG DỤNG để mở thực đơn ngữ cảnh. Sau đó nhấn TAB hoặc MŨI TÊN XUỐNG để di chuyển đến tuỳ chọn tiếp theo của thực đơn. Nhấn SHIFT+TAB hoặc MŨI TÊN LÊN để quay lại tuỳ chọn trước. Nhấn DẤU CÁCH hoặc ENTER để chọn tuỳ chọn của thực đơn. Nhấn DẤU CÁCH hoặc ENTER hoặc MŨI TÊN SANG PHẢI để mở thực đơn con của tuỳ chọn hiện tại. Nhấn ESC hoặc MŨI TÊN SANG TRÁI để quay trở lại thực đơn gốc. Nhấn ESC để đóng thực đơn ngữ cảnh."},
+{name:"Hộp danh sách trình biên tập",legend:"Trong một danh sách chọn, di chuyển đối tượng tiếp theo với phím TAB hoặc phím mũi tên hướng xuống. Di chuyển đến đối tượng trước đó bằng cách nhấn tổ hợp phím SHIFT+TAB hoặc mũi tên hướng lên. Phím khoảng cách hoặc phím ENTER để chọn các tùy chọn trong danh sách. Nhấn phím ESC để đóng lại danh sách chọn."},{name:"Thanh đường dẫn các đối tượng",legend:"Nhấn ${elementsPathFocus} để điều hướng các đối tượng trong thanh đường dẫn. Di chuyển đến đối tượng tiếp theo bằng phím TAB hoặc phím mũi tên bên phải. Di chuyển đến đối tượng trước đó bằng tổ hợp phím SHIFT+TAB hoặc phím mũi tên bên trái. Nhấn phím khoảng cách hoặc ENTER để chọn đối tượng trong trình soạn thảo."}]},
+{name:"Lệnh",items:[{name:"Làm lại lện",legend:"Ấn ${undo}"},{name:"Làm lại lệnh",legend:"Ấn ${redo}"},{name:"Lệnh in đậm",legend:"Ấn ${bold}"},{name:"Lệnh in nghiêng",legend:"Ấn ${italic}"},{name:"Lệnh gạch dưới",legend:"Ấn ${underline}"},{name:"Lệnh liên kết",legend:"Nhấn ${link}"},{name:"Lệnh hiển thị thanh công cụ",legend:"Nhấn${toolbarCollapse}"},{name:"Truy cập đến lệnh tập trung vào khoảng cách trước đó",legend:"Ấn ${accessPreviousSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách."},
+{name:"Truy cập phần đối tượng lệnh khoảng trống",legend:"Ấn ${accessNextSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách."},{name:"Trợ giúp liên quan",legend:"Nhấn ${a11yHelp}"}]}],tab:"Phím Tab",pause:"Phím Pause",capslock:"Phím Caps Lock",escape:"Phím Escape",pageUp:"Phím Page Up",pageDown:"Phím Page Down",leftArrow:"Phím Left Arrow",
+upArrow:"Phím Up Arrow",rightArrow:"Phím Right Arrow",downArrow:"Phím Down Arrow",insert:"Chèn",leftWindowKey:"Phím Left Windows",rightWindowKey:"Phím Right Windows ",selectKey:"Chọn phím",numpad0:"Phím 0",numpad1:"Phím 1",numpad2:"Phím 2",numpad3:"Phím 3",numpad4:"Phím 4",numpad5:"Phím 5",numpad6:"Phím 6",numpad7:"Phím 7",numpad8:"Phím 8",numpad9:"Phím 9",multiply:"Nhân",add:"Thêm",subtract:"Trừ",decimalPoint:"Điểm số thập phân",divide:"Chia",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",
+f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"Dấu chấm phẩy",equalSign:"Đăng nhập bằng",comma:"Dấu phẩy",dash:"Dấu gạch ngang",period:"Phím .",forwardSlash:"Phím /",graveAccent:"Phím `",openBracket:"Open Bracket",backSlash:"Dấu gạch chéo ngược",closeBracket:"Gần giá đỡ",singleQuote:"Trích dẫn"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/zh-cn.js b/release/plugins/a11yhelp/dialogs/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..6c16130
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","zh-cn",{title:"辅助功能说明",contents:"帮助内容。要关闭此对话框请按 ESC 键。",legend:[{name:"常规",items:[{name:"编辑器工具栏",legend:"按 ${toolbarFocus} 切换到工具栏,使用 TAB 键和 SHIFT+TAB 组合键移动到上一个和下一个工具栏组。使用左右箭头键移动到上一个或下一个工具栏按钮。按空格键或回车键以选中工具栏按钮。"},{name:"编辑器对话框",legend:"在对话框内,按 TAB 键移动到下一个字段,按 SHIFT + TAB 组合键移动到上一个字段,按 ENTER 键提交对话框,按 ESC 键取消对话框。对于有多选项卡的对话框,可以按 ALT + F10 直接切换到或者按 TAB 键逐步移到选项卡列表,当焦点移到选项卡列表时可以用左右箭头键来移动到前后的选项卡。"},{name:"编辑器上下文菜单",legend:"用 ${contextMenu} 或者“应用程序键”打开上下文菜单。然后用 TAB 键或者下箭头键来移动到下一个菜单项;SHIFT + TAB 组合键或者上箭头键移动到上一个菜单项。用 SPACE 键或者 ENTER 键选择菜单项。用 SPACE 键,ENTER 键或者右箭头键打开子菜单。返回菜单用 ESC 键或者左箭头键。用 ESC 键关闭上下文菜单。"},
+{name:"编辑器列表框",legend:"在列表框中,移到下一列表项用 TAB 键或者下箭头键。移到上一列表项用SHIFT+TAB 组合键或者上箭头键,用 SPACE 键或者 ENTER 键选择列表项。用 ESC 键收起列表框。"},{name:"编辑器元素路径栏",legend:"按 ${elementsPathFocus} 以导航到元素路径栏,使用 TAB 键或右箭头键选择下一个元素,使用 SHIFT+TAB 组合键或左箭头键选择上一个元素,按空格键或回车键以选定编辑器里的元素。"}]},{name:"命令",items:[{name:" 撤消命令",legend:"按 ${undo}"},{name:" 重做命令",legend:"按 ${redo}"},{name:" 加粗命令",legend:"按 ${bold}"},{name:" 倾斜命令",legend:"按 ${italic}"},{name:" 下划线命令",legend:"按 ${underline}"},{name:" 链接命令",legend:"按 ${link}"},{name:" 工具栏折叠命令",legend:"按 ${toolbarCollapse}"},
+{name:"访问前一个焦点区域的命令",legend:"按 ${accessPreviousSpace} 访问^符号前最近的不可访问的焦点区域,例如:两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。"},{name:"访问下一个焦点区域命令",legend:"按 ${accessNextSpace} 以访问^符号后最近的不可访问的焦点区域。例如:两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。"},{name:"辅助功能帮助",legend:"按 ${a11yHelp}"}]}],tab:"Tab 键",pause:"暂停键",capslock:"大写锁定键",escape:"Esc 键",pageUp:"上翻页键",pageDown:"下翻页键",leftArrow:"向左箭头键",upArrow:"向上箭头键",rightArrow:"向右箭头键",downArrow:"向下箭头键",insert:"插入键",leftWindowKey:"左 WIN 键",rightWindowKey:"右 WIN 键",selectKey:"选择键",numpad0:"小键盘 0 键",
+numpad1:"小键盘 1 键",numpad2:"小键盘 2 键",numpad3:"小键盘 3 键",numpad4:"小键盘 4 键",numpad5:"小键盘 5 键",numpad6:"小键盘 6 键",numpad7:"小键盘 7 键",numpad8:"小键盘 8 键",numpad9:"小键盘 9 键",multiply:"星号键",add:"加号键",subtract:"减号键",decimalPoint:"小数点键",divide:"除号键",f1:"F1 键",f2:"F2 键",f3:"F3 键",f4:"F4 键",f5:"F5 键",f6:"F6 键",f7:"F7 键",f8:"F8 键",f9:"F9 键",f10:"F10 键",f11:"F11 键",f12:"F12 键",numLock:"数字锁定键",scrollLock:"滚动锁定键",semiColon:"分号键",equalSign:"等号键",comma:"逗号键",dash:"短划线键",period:"句号键",forwardSlash:"斜杠键",graveAccent:"重音符键",
+openBracket:"左中括号键",backSlash:"反斜杠键",closeBracket:"右中括号键",singleQuote:"单引号键"});
\ No newline at end of file
diff --git a/release/plugins/a11yhelp/dialogs/lang/zh.js b/release/plugins/a11yhelp/dialogs/lang/zh.js
new file mode 100644 (file)
index 0000000..a43d47a
--- /dev/null
@@ -0,0 +1,9 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.plugins.setLang("a11yhelp","zh",{title:"輔助工具指南",contents:"說明內容。若要關閉此對話框請按「ESC」。",legend:[{name:"一般",items:[{name:"編輯器工具列",legend:"請按 ${toolbarFocus} 以導覽到工具列。利用 TAB 或 SHIFT+TAB 以便移動到下一個及前一個工具列群組。利用右方向鍵或左方向鍵以便移動到下一個及上一個工具列按鈕。按下空白鍵或 ENTER 鍵啟用工具列按鈕。"},{name:"編輯器對話方塊",legend:"在對話框中,按下 TAB 鍵以導覽到下一個對話框元素,按下 SHIFT+TAB 以移動到上一個對話框元素,按下 ENTER 以遞交對話框,按下 ESC 以取消對話框。當對話框有多個分頁時,可以使用 ALT+F10 或是在對話框分頁順序中的一部份按下 TAB 以使用分頁列表。焦點在分頁列表上時,分別使用右方向鍵及左方向鍵移動到下一個及上一個分頁。"},{name:"編輯器內容功能表",legend:"請按下「${contextMenu}」或是「應用程式鍵」以開啟內容選單。以「TAB」或是「↓」鍵移動到下一個選單選項。以「SHIFT + TAB」或是「↑」鍵移動到上一個選單選項。按下「空白鍵」或是「ENTER」鍵以選取選單選項。以「空白鍵」或「ENTER」或「→」開啟目前選項之子選單。以「ESC」或「←」回到父選單。以「ESC」鍵關閉內容選單」。"},
+{name:"編輯器清單方塊",legend:"在清單方塊中,使用 TAB 或下方向鍵移動到下一個列表項目。使用 SHIFT+TAB 或上方向鍵移動到上一個列表項目。按下空白鍵或 ENTER 以選取列表選項。按下 ESC 以關閉清單方塊。"},{name:"編輯器元件路徑工具列",legend:"請按 ${elementsPathFocus} 以瀏覽元素路徑列。利用 TAB 或右方向鍵以便移動到下一個元素按鈕。利用 SHIFT 或左方向鍵以便移動到上一個按鈕。按下空白鍵或 ENTER 鍵來選取在編輯器中的元素。"}]},{name:"命令",items:[{name:"復原命令",legend:"請按下「${undo}」"},{name:"重複命令",legend:"請按下「 ${redo}」"},{name:"粗體命令",legend:"請按下「${bold}」"},{name:"斜體",legend:"請按下「${italic}」"},{name:"底線命令",legend:"請按下「${underline}」"},{name:"連結",legend:"請按下「${link}」"},
+{name:"隱藏工具列",legend:"請按下「${toolbarCollapse}」"},{name:"存取前一個焦點空間命令",legend:"請按下 ${accessPreviousSpace} 以存取最近但無法靠近之插字符號前的焦點空間。舉例:二個相鄰的 HR 元素。\r\n重複按鍵以存取較遠的焦點空間。"},{name:"存取下一個焦點空間命令",legend:"請按下 ${accessNextSpace} 以存取最近但無法靠近之插字符號後的焦點空間。舉例:二個相鄰的 HR 元素。\r\n重複按鍵以存取較遠的焦點空間。"},{name:"協助工具說明",legend:"請按下「${a11yHelp}」"}]}],tab:"Tab",pause:"Pause",capslock:"Caps Lock",escape:"Esc",pageUp:"Page Up",pageDown:"Page Down",leftArrow:"向左箭號",upArrow:"向上鍵號",rightArrow:"向右鍵號",downArrow:"向下鍵號",insert:"插入",leftWindowKey:"左方 Windows 鍵",
+rightWindowKey:"右方 Windows 鍵",selectKey:"選擇鍵",numpad0:"Numpad 0",numpad1:"Numpad 1",numpad2:"Numpad 2",numpad3:"Numpad 3",numpad4:"Numpad 4",numpad5:"Numpad 5",numpad6:"Numpad 6",numpad7:"Numpad 7",numpad8:"Numpad 8",numpad9:"Numpad 9",multiply:"乘號",add:"新增",subtract:"減號",decimalPoint:"小數點",divide:"除號",f1:"F1",f2:"F2",f3:"F3",f4:"F4",f5:"F5",f6:"F6",f7:"F7",f8:"F8",f9:"F9",f10:"F10",f11:"F11",f12:"F12",numLock:"Num Lock",scrollLock:"Scroll Lock",semiColon:"分號",equalSign:"等號",comma:"逗號",dash:"虛線",
+period:"句點",forwardSlash:"斜線",graveAccent:"抑音符號",openBracket:"左方括號",backSlash:"反斜線",closeBracket:"右方括號",singleQuote:"單引號"});
\ No newline at end of file
diff --git a/release/plugins/clipboard/dialogs/paste.js b/release/plugins/clipboard/dialogs/paste.js
new file mode 100644 (file)
index 0000000..927b942
--- /dev/null
@@ -0,0 +1,12 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add("paste",function(c){function k(a){var b=new CKEDITOR.dom.document(a.document),g=b.getBody(),d=b.getById("cke_actscrpt");d&&d.remove();g.setAttribute("contenteditable",!0);g.on(e.mainPasteEvent,function(a){a=e.initPasteDataTransfer(a);f?a!=f&&(f=e.initPasteDataTransfer()):f=a});if(CKEDITOR.env.ie&&8>CKEDITOR.env.version)b.getWindow().on("blur",function(){b.$.selection.empty()});b.on("keydown",function(a){a=a.data;var b;switch(a.getKeystroke()){case 27:this.hide();b=1;break;case 9:case CKEDITOR.SHIFT+
+9:this.changeFocus(1),b=1}b&&a.preventDefault()},this);c.fire("ariaWidget",new CKEDITOR.dom.element(a.frameElement));b.getWindow().getFrame().removeCustomData("pendingFocus")&&g.focus()}var h=c.lang.clipboard,e=CKEDITOR.plugins.clipboard,f;c.on("pasteDialogCommit",function(a){a.data&&c.fire("paste",{type:"auto",dataValue:a.data.dataValue,method:"paste",dataTransfer:a.data.dataTransfer||e.initPasteDataTransfer()})},null,null,1E3);return{title:h.title,minWidth:CKEDITOR.env.ie&&CKEDITOR.env.quirks?370:
+350,minHeight:CKEDITOR.env.quirks?250:245,onShow:function(){this.parts.dialog.$.offsetHeight;this.setupContent();this.parts.title.setHtml(this.customTitle||h.title);this.customTitle=null},onLoad:function(){(CKEDITOR.env.ie7Compat||CKEDITOR.env.ie6Compat)&&"rtl"==c.lang.dir&&this.parts.contents.setStyle("overflow","hidden")},onOk:function(){this.commitContent()},contents:[{id:"general",label:c.lang.common.generalTab,elements:[{type:"html",id:"securityMsg",html:'\x3cdiv style\x3d"white-space:normal;width:340px"\x3e'+
+h.securityMsg+"\x3c/div\x3e"},{type:"html",id:"pasteMsg",html:'\x3cdiv style\x3d"white-space:normal;width:340px"\x3e'+h.pasteMsg+"\x3c/div\x3e"},{type:"html",id:"editing_area",style:"width:100%;height:100%",html:"",focus:function(){var a=this.getInputElement(),b=a.getFrameDocument().getBody();!b||b.isReadOnly()?a.setCustomData("pendingFocus",1):b.focus()},setup:function(){var a=this.getDialog(),b='\x3chtml dir\x3d"'+c.config.contentsLangDirection+'" lang\x3d"'+(c.config.contentsLanguage||c.langCode)+
+'"\x3e\x3chead\x3e\x3cstyle\x3ebody{margin:3px;height:95%;word-break:break-all;}\x3c/style\x3e\x3c/head\x3e\x3cbody\x3e\x3cscript id\x3d"cke_actscrpt" type\x3d"text/javascript"\x3ewindow.parent.CKEDITOR.tools.callFunction('+CKEDITOR.tools.addFunction(k,a)+",this);\x3c/script\x3e\x3c/body\x3e\x3c/html\x3e",g=CKEDITOR.env.air?"javascript:void(0)":CKEDITOR.env.ie&&!CKEDITOR.env.edge?"javascript:void((function(){"+encodeURIComponent("document.open();("+CKEDITOR.tools.fixDomain+")();document.close();")+
+'})())"':"",d=CKEDITOR.dom.element.createFromHtml('\x3ciframe class\x3d"cke_pasteframe" frameborder\x3d"0"  allowTransparency\x3d"true" src\x3d"'+g+'" aria-label\x3d"'+h.pasteArea+'" aria-describedby\x3d"'+a.getContentElement("general","pasteMsg").domId+'"\x3e\x3c/iframe\x3e');f=null;d.on("load",function(a){a.removeListener();a=d.getFrameDocument();a.write(b);c.focusManager.add(a.getBody());CKEDITOR.env.air&&k.call(this,a.getWindow().$)},a);d.setCustomData("dialog",a);a=this.getElement();a.setHtml("");
+a.append(d);if(CKEDITOR.env.ie&&!CKEDITOR.env.edge){var e=CKEDITOR.dom.element.createFromHtml('\x3cspan tabindex\x3d"-1" style\x3d"position:absolute" role\x3d"presentation"\x3e\x3c/span\x3e');e.on("focus",function(){setTimeout(function(){d.$.contentWindow.focus()})});a.append(e);this.focus=function(){e.focus();this.fire("focus")}}this.getInputElement=function(){return d};CKEDITOR.env.ie&&(a.setStyle("display","block"),a.setStyle("height",d.$.offsetHeight+2+"px"))},commit:function(){var a=this.getDialog().getParentEditor(),
+b=this.getInputElement().getFrameDocument().getBody(),c=b.getBogus(),d;c&&c.remove();d=b.getHtml();setTimeout(function(){a.fire("pasteDialogCommit",{dataValue:d,dataTransfer:f||e.initPasteDataTransfer()})},0)}}]}]}});
\ No newline at end of file
diff --git a/release/plugins/dialog/dialogDefinition.js b/release/plugins/dialog/dialogDefinition.js
new file mode 100644 (file)
index 0000000..5c35976
--- /dev/null
@@ -0,0 +1,4 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
diff --git a/release/plugins/icons.png b/release/plugins/icons.png
new file mode 100644 (file)
index 0000000..d33f614
Binary files /dev/null and b/release/plugins/icons.png differ
diff --git a/release/plugins/icons_hidpi.png b/release/plugins/icons_hidpi.png
new file mode 100644 (file)
index 0000000..cf4f8cb
Binary files /dev/null and b/release/plugins/icons_hidpi.png differ
diff --git a/release/plugins/iframe/dialogs/iframe.js b/release/plugins/iframe/dialogs/iframe.js
new file mode 100644 (file)
index 0000000..d431e5f
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(){function c(b){var c=this instanceof CKEDITOR.ui.dialog.checkbox;b.hasAttribute(this.id)&&(b=b.getAttribute(this.id),c?this.setValue(e[this.id]["true"]==b.toLowerCase()):this.setValue(b))}function d(b){var c=""===this.getValue(),a=this instanceof CKEDITOR.ui.dialog.checkbox,d=this.getValue();c?b.removeAttribute(this.att||this.id):a?b.setAttribute(this.id,e[this.id][d]):b.setAttribute(this.att||this.id,d)}var e={scrolling:{"true":"yes","false":"no"},frameborder:{"true":"1","false":"0"}};
+CKEDITOR.dialog.add("iframe",function(b){var f=b.lang.iframe,a=b.lang.common,e=b.plugins.dialogadvtab;return{title:f.title,minWidth:350,minHeight:260,onShow:function(){this.fakeImage=this.iframeNode=null;var a=this.getSelectedElement();a&&a.data("cke-real-element-type")&&"iframe"==a.data("cke-real-element-type")&&(this.fakeImage=a,this.iframeNode=a=b.restoreRealElement(a),this.setupContent(a))},onOk:function(){var a;a=this.fakeImage?this.iframeNode:new CKEDITOR.dom.element("iframe");var c={},d={};
+this.commitContent(a,c,d);a=b.createFakeElement(a,"cke_iframe","iframe",!0);a.setAttributes(d);a.setStyles(c);this.fakeImage?(a.replace(this.fakeImage),b.getSelection().selectElement(a)):b.insertElement(a)},contents:[{id:"info",label:a.generalTab,accessKey:"I",elements:[{type:"vbox",padding:0,children:[{id:"src",type:"text",label:a.url,required:!0,validate:CKEDITOR.dialog.validate.notEmpty(f.noUrl),setup:c,commit:d}]},{type:"hbox",children:[{id:"width",type:"text",requiredContent:"iframe[width]",
+style:"width:100%",labelLayout:"vertical",label:a.width,validate:CKEDITOR.dialog.validate.htmlLength(a.invalidHtmlLength.replace("%1",a.width)),setup:c,commit:d},{id:"height",type:"text",requiredContent:"iframe[height]",style:"width:100%",labelLayout:"vertical",label:a.height,validate:CKEDITOR.dialog.validate.htmlLength(a.invalidHtmlLength.replace("%1",a.height)),setup:c,commit:d},{id:"align",type:"select",requiredContent:"iframe[align]","default":"",items:[[a.notSet,""],[a.alignLeft,"left"],[a.alignRight,
+"right"],[a.alignTop,"top"],[a.alignMiddle,"middle"],[a.alignBottom,"bottom"]],style:"width:100%",labelLayout:"vertical",label:a.align,setup:function(a,b){c.apply(this,arguments);if(b){var d=b.getAttribute("align");this.setValue(d&&d.toLowerCase()||"")}},commit:function(a,b,c){d.apply(this,arguments);this.getValue()&&(c.align=this.getValue())}}]},{type:"hbox",widths:["50%","50%"],children:[{id:"scrolling",type:"checkbox",requiredContent:"iframe[scrolling]",label:f.scrolling,setup:c,commit:d},{id:"frameborder",
+type:"checkbox",requiredContent:"iframe[frameborder]",label:f.border,setup:c,commit:d}]},{type:"hbox",widths:["50%","50%"],children:[{id:"name",type:"text",requiredContent:"iframe[name]",label:a.name,setup:c,commit:d},{id:"title",type:"text",requiredContent:"iframe[title]",label:a.advisoryTitle,setup:c,commit:d}]},{id:"longdesc",type:"text",requiredContent:"iframe[longdesc]",label:a.longDescr,setup:c,commit:d}]},e&&e.createAdvancedTab(b,{id:1,classes:1,styles:1},"iframe")]}})})();
\ No newline at end of file
diff --git a/release/plugins/iframe/images/placeholder.png b/release/plugins/iframe/images/placeholder.png
new file mode 100644 (file)
index 0000000..4af0956
Binary files /dev/null and b/release/plugins/iframe/images/placeholder.png differ
diff --git a/release/plugins/image/dialogs/image.js b/release/plugins/image/dialogs/image.js
new file mode 100644 (file)
index 0000000..ad47e6b
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(){var v=function(d,l){function v(){var a=arguments,b=this.getContentElement("advanced","txtdlgGenStyle");b&&b.commit.apply(b,a);this.foreach(function(b){b.commit&&"txtdlgGenStyle"!=b.id&&b.commit.apply(b,a)})}function k(a){if(!w){w=1;var b=this.getDialog(),c=b.imageElement;if(c){this.commit(1,c);a=[].concat(a);for(var d=a.length,f,g=0;g<d;g++)(f=b.getContentElement.apply(b,a[g].split(":")))&&f.setup(1,c)}w=0}}var m=/^\s*(\d+)((px)|\%)?\s*$/i,z=/(^\s*(\d+)((px)|\%)?\s*$)|^$/i,r=/^\d+px$/,
+A=function(){var a=this.getValue(),b=this.getDialog(),c=a.match(m);c&&("%"==c[2]&&n(b,!1),a=c[1]);b.lockRatio&&(c=b.originalElement,"true"==c.getCustomData("isReady")&&("txtHeight"==this.id?(a&&"0"!=a&&(a=Math.round(a/c.$.height*c.$.width)),isNaN(a)||b.setValueOf("info","txtWidth",a)):(a&&"0"!=a&&(a=Math.round(a/c.$.width*c.$.height)),isNaN(a)||b.setValueOf("info","txtHeight",a))));e(b)},e=function(a){if(!a.originalElement||!a.preview)return 1;a.commitContent(4,a.preview);return 0},w,n=function(a,
+b){if(!a.getContentElement("info","ratioLock"))return null;var c=a.originalElement;if(!c)return null;if("check"==b){if(!a.userlockRatio&&"true"==c.getCustomData("isReady")){var d=a.getValueOf("info","txtWidth"),f=a.getValueOf("info","txtHeight"),c=1E3*c.$.width/c.$.height,g=1E3*d/f;a.lockRatio=!1;d||f?isNaN(c)||isNaN(g)||Math.round(c)!=Math.round(g)||(a.lockRatio=!0):a.lockRatio=!0}}else void 0!==b?a.lockRatio=b:(a.userlockRatio=1,a.lockRatio=!a.lockRatio);d=CKEDITOR.document.getById(t);a.lockRatio?
+d.removeClass("cke_btn_unlocked"):d.addClass("cke_btn_unlocked");d.setAttribute("aria-checked",a.lockRatio);CKEDITOR.env.hc&&d.getChild(0).setHtml(a.lockRatio?CKEDITOR.env.ie?"■":"▣":CKEDITOR.env.ie?"□":"▢");return a.lockRatio},B=function(a,b){var c=a.originalElement;if("true"==c.getCustomData("isReady")){var d=a.getContentElement("info","txtWidth"),f=a.getContentElement("info","txtHeight"),g;b?c=g=0:(g=c.$.width,c=c.$.height);d&&d.setValue(g);f&&f.setValue(c)}e(a)},C=function(a,b){function c(a,b){var c=
+a.match(m);return c?("%"==c[2]&&(c[1]+="%",n(d,!1)),c[1]):b}if(1==a){var d=this.getDialog(),f="",g="txtWidth"==this.id?"width":"height",e=b.getAttribute(g);e&&(f=c(e,f));f=c(b.getStyle(g),f);this.setValue(f)}},x,u=function(){var a=this.originalElement,b=CKEDITOR.document.getById(p);a.setCustomData("isReady","true");a.removeListener("load",u);a.removeListener("error",h);a.removeListener("abort",h);b&&b.setStyle("display","none");this.dontResetSize||B(this,!1===d.config.image_prefillDimensions);this.firstLoad&&
+CKEDITOR.tools.setTimeout(function(){n(this,"check")},0,this);this.dontResetSize=this.firstLoad=!1;e(this)},h=function(){var a=this.originalElement,b=CKEDITOR.document.getById(p);a.removeListener("load",u);a.removeListener("error",h);a.removeListener("abort",h);a=CKEDITOR.getUrl(CKEDITOR.plugins.get("image").path+"images/noimage.png");this.preview&&this.preview.setAttribute("src",a);b&&b.setStyle("display","none");n(this,!1)},q=function(a){return CKEDITOR.tools.getNextId()+"_"+a},t=q("btnLockSizes"),
+y=q("btnResetSize"),p=q("ImagePreviewLoader"),E=q("previewLink"),D=q("previewImage");return{title:d.lang.image["image"==l?"title":"titleButton"],minWidth:"moono-lisa"==(CKEDITOR.skinName||d.config.skin)?500:420,minHeight:360,onShow:function(){this.linkEditMode=this.imageEditMode=this.linkElement=this.imageElement=!1;this.lockRatio=!0;this.userlockRatio=0;this.dontResetSize=!1;this.firstLoad=!0;this.addLink=!1;var a=this.getParentEditor(),b=a.getSelection(),c=(b=b&&b.getSelectedElement())&&a.elementPath(b).contains("a",
+1),d=CKEDITOR.document.getById(p);d&&d.setStyle("display","none");x=new CKEDITOR.dom.element("img",a.document);this.preview=CKEDITOR.document.getById(D);this.originalElement=a.document.createElement("img");this.originalElement.setAttribute("alt","");this.originalElement.setCustomData("isReady","false");c&&(this.linkElement=c,this.addLink=this.linkEditMode=!0,a=c.getChildren(),1==a.count()&&(d=a.getItem(0),d.type==CKEDITOR.NODE_ELEMENT&&(d.is("img")||d.is("input"))&&(this.imageElement=a.getItem(0),
+this.imageElement.is("img")?this.imageEditMode="img":this.imageElement.is("input")&&(this.imageEditMode="input"))),"image"==l&&this.setupContent(2,c));if(this.customImageElement)this.imageEditMode="img",this.imageElement=this.customImageElement,delete this.customImageElement;else if(b&&"img"==b.getName()&&!b.data("cke-realelement")||b&&"input"==b.getName()&&"image"==b.getAttribute("type"))this.imageEditMode=b.getName(),this.imageElement=b;this.imageEditMode&&(this.cleanImageElement=this.imageElement,
+this.imageElement=this.cleanImageElement.clone(!0,!0),this.setupContent(1,this.imageElement));n(this,!0);CKEDITOR.tools.trim(this.getValueOf("info","txtUrl"))||(this.preview.removeAttribute("src"),this.preview.setStyle("display","none"))},onOk:function(){if(this.imageEditMode){var a=this.imageEditMode;"image"==l&&"input"==a&&confirm(d.lang.image.button2Img)?(this.imageElement=d.document.createElement("img"),this.imageElement.setAttribute("alt",""),d.insertElement(this.imageElement)):"image"!=l&&"img"==
+a&&confirm(d.lang.image.img2Button)?(this.imageElement=d.document.createElement("input"),this.imageElement.setAttributes({type:"image",alt:""}),d.insertElement(this.imageElement)):(this.imageElement=this.cleanImageElement,delete this.cleanImageElement)}else"image"==l?this.imageElement=d.document.createElement("img"):(this.imageElement=d.document.createElement("input"),this.imageElement.setAttribute("type","image")),this.imageElement.setAttribute("alt","");this.linkEditMode||(this.linkElement=d.document.createElement("a"));
+this.commitContent(1,this.imageElement);this.commitContent(2,this.linkElement);this.imageElement.getAttribute("style")||this.imageElement.removeAttribute("style");this.imageEditMode?!this.linkEditMode&&this.addLink?(d.insertElement(this.linkElement),this.imageElement.appendTo(this.linkElement)):this.linkEditMode&&!this.addLink&&(d.getSelection().selectElement(this.linkElement),d.insertElement(this.imageElement)):this.addLink?this.linkEditMode?this.linkElement.equals(d.getSelection().getSelectedElement())?
+(this.linkElement.setHtml(""),this.linkElement.append(this.imageElement,!1)):d.insertElement(this.imageElement):(d.insertElement(this.linkElement),this.linkElement.append(this.imageElement,!1)):d.insertElement(this.imageElement)},onLoad:function(){"image"!=l&&this.hidePage("Link");var a=this._.element.getDocument();this.getContentElement("info","ratioLock")&&(this.addFocusable(a.getById(y),5),this.addFocusable(a.getById(t),5));this.commitContent=v},onHide:function(){this.preview&&this.commitContent(8,
+this.preview);this.originalElement&&(this.originalElement.removeListener("load",u),this.originalElement.removeListener("error",h),this.originalElement.removeListener("abort",h),this.originalElement.remove(),this.originalElement=!1);delete this.imageElement},contents:[{id:"info",label:d.lang.image.infoTab,accessKey:"I",elements:[{type:"vbox",padding:0,children:[{type:"hbox",widths:["280px","110px"],align:"right",className:"cke_dialog_image_url",children:[{id:"txtUrl",type:"text",label:d.lang.common.url,
+required:!0,onChange:function(){var a=this.getDialog(),b=this.getValue();if(0<b.length){var a=this.getDialog(),c=a.originalElement;a.preview&&a.preview.removeStyle("display");c.setCustomData("isReady","false");var d=CKEDITOR.document.getById(p);d&&d.setStyle("display","");c.on("load",u,a);c.on("error",h,a);c.on("abort",h,a);c.setAttribute("src",b);a.preview&&(x.setAttribute("src",b),a.preview.setAttribute("src",x.$.src),e(a))}else a.preview&&(a.preview.removeAttribute("src"),a.preview.setStyle("display",
+"none"))},setup:function(a,b){if(1==a){var c=b.data("cke-saved-src")||b.getAttribute("src");this.getDialog().dontResetSize=!0;this.setValue(c);this.setInitValue()}},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())?(b.data("cke-saved-src",this.getValue()),b.setAttribute("src",this.getValue())):8==a&&(b.setAttribute("src",""),b.removeAttribute("src"))},validate:CKEDITOR.dialog.validate.notEmpty(d.lang.image.urlMissing)},{type:"button",id:"browse",style:"display:inline-block;margin-top:14px;",
+align:"center",label:d.lang.common.browseServer,hidden:!0,filebrowser:"info:txtUrl"}]}]},{id:"txtAlt",type:"text",label:d.lang.image.alt,accessKey:"T","default":"",onChange:function(){e(this.getDialog())},setup:function(a,b){1==a&&this.setValue(b.getAttribute("alt"))},commit:function(a,b){1==a?(this.getValue()||this.isChanged())&&b.setAttribute("alt",this.getValue()):4==a?b.setAttribute("alt",this.getValue()):8==a&&b.removeAttribute("alt")}},{type:"hbox",children:[{id:"basic",type:"vbox",children:[{type:"hbox",
+requiredContent:"img{width,height}",widths:["50%","50%"],children:[{type:"vbox",padding:1,children:[{type:"text",width:"45px",id:"txtWidth",label:d.lang.common.width,onKeyUp:A,onChange:function(){k.call(this,"advanced:txtdlgGenStyle")},validate:function(){var a=this.getValue().match(z);(a=!(!a||0===parseInt(a[1],10)))||alert(d.lang.common.invalidWidth);return a},setup:C,commit:function(a,b){var c=this.getValue();1==a?(c&&d.activeFilter.check("img{width,height}")?b.setStyle("width",CKEDITOR.tools.cssLength(c)):
+b.removeStyle("width"),b.removeAttribute("width")):4==a?c.match(m)?b.setStyle("width",CKEDITOR.tools.cssLength(c)):(c=this.getDialog().originalElement,"true"==c.getCustomData("isReady")&&b.setStyle("width",c.$.width+"px")):8==a&&(b.removeAttribute("width"),b.removeStyle("width"))}},{type:"text",id:"txtHeight",width:"45px",label:d.lang.common.height,onKeyUp:A,onChange:function(){k.call(this,"advanced:txtdlgGenStyle")},validate:function(){var a=this.getValue().match(z);(a=!(!a||0===parseInt(a[1],10)))||
+alert(d.lang.common.invalidHeight);return a},setup:C,commit:function(a,b){var c=this.getValue();1==a?(c&&d.activeFilter.check("img{width,height}")?b.setStyle("height",CKEDITOR.tools.cssLength(c)):b.removeStyle("height"),b.removeAttribute("height")):4==a?c.match(m)?b.setStyle("height",CKEDITOR.tools.cssLength(c)):(c=this.getDialog().originalElement,"true"==c.getCustomData("isReady")&&b.setStyle("height",c.$.height+"px")):8==a&&(b.removeAttribute("height"),b.removeStyle("height"))}}]},{id:"ratioLock",
+type:"html",className:"cke_dialog_image_ratiolock",style:"margin-top:30px;width:40px;height:40px;",onLoad:function(){var a=CKEDITOR.document.getById(y),b=CKEDITOR.document.getById(t);a&&(a.on("click",function(a){B(this);a.data&&a.data.preventDefault()},this.getDialog()),a.on("mouseover",function(){this.addClass("cke_btn_over")},a),a.on("mouseout",function(){this.removeClass("cke_btn_over")},a));b&&(b.on("click",function(a){n(this);var b=this.originalElement,d=this.getValueOf("info","txtWidth");"true"==
+b.getCustomData("isReady")&&d&&(b=b.$.height/b.$.width*d,isNaN(b)||(this.setValueOf("info","txtHeight",Math.round(b)),e(this)));a.data&&a.data.preventDefault()},this.getDialog()),b.on("mouseover",function(){this.addClass("cke_btn_over")},b),b.on("mouseout",function(){this.removeClass("cke_btn_over")},b))},html:'\x3cdiv\x3e\x3ca href\x3d"javascript:void(0)" tabindex\x3d"-1" title\x3d"'+d.lang.image.lockRatio+'" class\x3d"cke_btn_locked" id\x3d"'+t+'" role\x3d"checkbox"\x3e\x3cspan class\x3d"cke_icon"\x3e\x3c/span\x3e\x3cspan class\x3d"cke_label"\x3e'+
+d.lang.image.lockRatio+'\x3c/span\x3e\x3c/a\x3e\x3ca href\x3d"javascript:void(0)" tabindex\x3d"-1" title\x3d"'+d.lang.image.resetSize+'" class\x3d"cke_btn_reset" id\x3d"'+y+'" role\x3d"button"\x3e\x3cspan class\x3d"cke_label"\x3e'+d.lang.image.resetSize+"\x3c/span\x3e\x3c/a\x3e\x3c/div\x3e"}]},{type:"vbox",padding:1,children:[{type:"text",id:"txtBorder",requiredContent:"img{border-width}",width:"60px",label:d.lang.image.border,"default":"",onKeyUp:function(){e(this.getDialog())},onChange:function(){k.call(this,
+"advanced:txtdlgGenStyle")},validate:CKEDITOR.dialog.validate.integer(d.lang.image.validateBorder),setup:function(a,b){if(1==a){var c;c=(c=(c=b.getStyle("border-width"))&&c.match(/^(\d+px)(?: \1 \1 \1)?$/))&&parseInt(c[1],10);isNaN(parseInt(c,10))&&(c=b.getAttribute("border"));this.setValue(c)}},commit:function(a,b){var c=parseInt(this.getValue(),10);1==a||4==a?(isNaN(c)?!c&&this.isChanged()&&b.removeStyle("border"):(b.setStyle("border-width",CKEDITOR.tools.cssLength(c)),b.setStyle("border-style",
+"solid")),1==a&&b.removeAttribute("border")):8==a&&(b.removeAttribute("border"),b.removeStyle("border-width"),b.removeStyle("border-style"),b.removeStyle("border-color"))}},{type:"text",id:"txtHSpace",requiredContent:"img{margin-left,margin-right}",width:"60px",label:d.lang.image.hSpace,"default":"",onKeyUp:function(){e(this.getDialog())},onChange:function(){k.call(this,"advanced:txtdlgGenStyle")},validate:CKEDITOR.dialog.validate.integer(d.lang.image.validateHSpace),setup:function(a,b){if(1==a){var c,
+d;c=b.getStyle("margin-left");d=b.getStyle("margin-right");c=c&&c.match(r);d=d&&d.match(r);c=parseInt(c,10);d=parseInt(d,10);c=c==d&&c;isNaN(parseInt(c,10))&&(c=b.getAttribute("hspace"));this.setValue(c)}},commit:function(a,b){var c=parseInt(this.getValue(),10);1==a||4==a?(isNaN(c)?!c&&this.isChanged()&&(b.removeStyle("margin-left"),b.removeStyle("margin-right")):(b.setStyle("margin-left",CKEDITOR.tools.cssLength(c)),b.setStyle("margin-right",CKEDITOR.tools.cssLength(c))),1==a&&b.removeAttribute("hspace")):
+8==a&&(b.removeAttribute("hspace"),b.removeStyle("margin-left"),b.removeStyle("margin-right"))}},{type:"text",id:"txtVSpace",requiredContent:"img{margin-top,margin-bottom}",width:"60px",label:d.lang.image.vSpace,"default":"",onKeyUp:function(){e(this.getDialog())},onChange:function(){k.call(this,"advanced:txtdlgGenStyle")},validate:CKEDITOR.dialog.validate.integer(d.lang.image.validateVSpace),setup:function(a,b){if(1==a){var c,d;c=b.getStyle("margin-top");d=b.getStyle("margin-bottom");c=c&&c.match(r);
+d=d&&d.match(r);c=parseInt(c,10);d=parseInt(d,10);c=c==d&&c;isNaN(parseInt(c,10))&&(c=b.getAttribute("vspace"));this.setValue(c)}},commit:function(a,b){var c=parseInt(this.getValue(),10);1==a||4==a?(isNaN(c)?!c&&this.isChanged()&&(b.removeStyle("margin-top"),b.removeStyle("margin-bottom")):(b.setStyle("margin-top",CKEDITOR.tools.cssLength(c)),b.setStyle("margin-bottom",CKEDITOR.tools.cssLength(c))),1==a&&b.removeAttribute("vspace")):8==a&&(b.removeAttribute("vspace"),b.removeStyle("margin-top"),b.removeStyle("margin-bottom"))}},
+{id:"cmbAlign",requiredContent:"img{float}",type:"select",widths:["35%","65%"],style:"width:90px",label:d.lang.common.align,"default":"",items:[[d.lang.common.notSet,""],[d.lang.common.alignLeft,"left"],[d.lang.common.alignRight,"right"]],onChange:function(){e(this.getDialog());k.call(this,"advanced:txtdlgGenStyle")},setup:function(a,b){if(1==a){var c=b.getStyle("float");switch(c){case "inherit":case "none":c=""}!c&&(c=(b.getAttribute("align")||"").toLowerCase());this.setValue(c)}},commit:function(a,
+b){var c=this.getValue();if(1==a||4==a){if(c?b.setStyle("float",c):b.removeStyle("float"),1==a)switch(c=(b.getAttribute("align")||"").toLowerCase(),c){case "left":case "right":b.removeAttribute("align")}}else 8==a&&b.removeStyle("float")}}]}]},{type:"vbox",height:"250px",children:[{type:"html",id:"htmlPreview",style:"width:95%;",html:"\x3cdiv\x3e"+CKEDITOR.tools.htmlEncode(d.lang.common.preview)+'\x3cbr\x3e\x3cdiv id\x3d"'+p+'" class\x3d"ImagePreviewLoader" style\x3d"display:none"\x3e\x3cdiv class\x3d"loading"\x3e\x26nbsp;\x3c/div\x3e\x3c/div\x3e\x3cdiv class\x3d"ImagePreviewBox"\x3e\x3ctable\x3e\x3ctr\x3e\x3ctd\x3e\x3ca href\x3d"javascript:void(0)" target\x3d"_blank" onclick\x3d"return false;" id\x3d"'+
+E+'"\x3e\x3cimg id\x3d"'+D+'" alt\x3d"" /\x3e\x3c/a\x3e'+(d.config.image_previewText||"Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. Nunc imperdiet gravida mauris.")+
+"\x3c/td\x3e\x3c/tr\x3e\x3c/table\x3e\x3c/div\x3e\x3c/div\x3e"}]}]}]},{id:"Link",requiredContent:"a[href]",label:d.lang.image.linkTab,padding:0,elements:[{id:"txtUrl",type:"text",label:d.lang.common.url,style:"width: 100%","default":"",setup:function(a,b){if(2==a){var c=b.data("cke-saved-href");c||(c=b.getAttribute("href"));this.setValue(c)}},commit:function(a,b){if(2==a&&(this.getValue()||this.isChanged())){var c=this.getValue();b.data("cke-saved-href",c);b.setAttribute("href",c);this.getValue()||
+!d.config.image_removeLinkByEmptyURL?this.getDialog().addLink=!0:this.getDialog().addLink=!1}}},{type:"button",id:"browse",className:"cke_dialog_image_browse",filebrowser:{action:"Browse",target:"Link:txtUrl",url:d.config.filebrowserImageBrowseLinkUrl},style:"float:right",hidden:!0,label:d.lang.common.browseServer},{id:"cmbTarget",type:"select",requiredContent:"a[target]",label:d.lang.common.target,"default":"",items:[[d.lang.common.notSet,""],[d.lang.common.targetNew,"_blank"],[d.lang.common.targetTop,
+"_top"],[d.lang.common.targetSelf,"_self"],[d.lang.common.targetParent,"_parent"]],setup:function(a,b){2==a&&this.setValue(b.getAttribute("target")||"")},commit:function(a,b){2==a&&(this.getValue()||this.isChanged())&&b.setAttribute("target",this.getValue())}}]},{id:"Upload",hidden:!0,filebrowser:"uploadButton",label:d.lang.image.upload,elements:[{type:"file",id:"upload",label:d.lang.image.btnUpload,style:"height:40px",size:38},{type:"fileButton",id:"uploadButton",filebrowser:"info:txtUrl",label:d.lang.image.btnUpload,
+"for":["Upload","upload"]}]},{id:"advanced",label:d.lang.common.advancedTab,elements:[{type:"hbox",widths:["50%","25%","25%"],children:[{type:"text",id:"linkId",requiredContent:"img[id]",label:d.lang.common.id,setup:function(a,b){1==a&&this.setValue(b.getAttribute("id"))},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("id",this.getValue())}},{id:"cmbLangDir",type:"select",requiredContent:"img[dir]",style:"width : 100px;",label:d.lang.common.langDir,"default":"",items:[[d.lang.common.notSet,
+""],[d.lang.common.langDirLtr,"ltr"],[d.lang.common.langDirRtl,"rtl"]],setup:function(a,b){1==a&&this.setValue(b.getAttribute("dir"))},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("dir",this.getValue())}},{type:"text",id:"txtLangCode",requiredContent:"img[lang]",label:d.lang.common.langCode,"default":"",setup:function(a,b){1==a&&this.setValue(b.getAttribute("lang"))},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("lang",this.getValue())}}]},
+{type:"text",id:"txtGenLongDescr",requiredContent:"img[longdesc]",label:d.lang.common.longDescr,setup:function(a,b){1==a&&this.setValue(b.getAttribute("longDesc"))},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("longDesc",this.getValue())}},{type:"hbox",widths:["50%","50%"],children:[{type:"text",id:"txtGenClass",requiredContent:"img(cke-xyz)",label:d.lang.common.cssClass,"default":"",setup:function(a,b){1==a&&this.setValue(b.getAttribute("class"))},commit:function(a,
+b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("class",this.getValue())}},{type:"text",id:"txtGenTitle",requiredContent:"img[title]",label:d.lang.common.advisoryTitle,"default":"",onChange:function(){e(this.getDialog())},setup:function(a,b){1==a&&this.setValue(b.getAttribute("title"))},commit:function(a,b){1==a?(this.getValue()||this.isChanged())&&b.setAttribute("title",this.getValue()):4==a?b.setAttribute("title",this.getValue()):8==a&&b.removeAttribute("title")}}]},{type:"text",id:"txtdlgGenStyle",
+requiredContent:"img{cke-xyz}",label:d.lang.common.cssStyle,validate:CKEDITOR.dialog.validate.inlineStyle(d.lang.common.invalidInlineStyle),"default":"",setup:function(a,b){if(1==a){var c=b.getAttribute("style");!c&&b.$.style.cssText&&(c=b.$.style.cssText);this.setValue(c);var d=b.$.style.height,c=b.$.style.width,d=(d?d:"").match(m),c=(c?c:"").match(m);this.attributesInStyle={height:!!d,width:!!c}}},onChange:function(){k.call(this,"info:cmbFloat info:cmbAlign info:txtVSpace info:txtHSpace info:txtBorder info:txtWidth info:txtHeight".split(" "));
+e(this)},commit:function(a,b){1==a&&(this.getValue()||this.isChanged())&&b.setAttribute("style",this.getValue())}}]}]}};CKEDITOR.dialog.add("image",function(d){return v(d,"image")});CKEDITOR.dialog.add("imagebutton",function(d){return v(d,"imagebutton")})})();
\ No newline at end of file
diff --git a/release/plugins/image/images/noimage.png b/release/plugins/image/images/noimage.png
new file mode 100644 (file)
index 0000000..74c6ee9
Binary files /dev/null and b/release/plugins/image/images/noimage.png differ
diff --git a/release/plugins/link/dialogs/anchor.js b/release/plugins/link/dialogs/anchor.js
new file mode 100644 (file)
index 0000000..255d60c
--- /dev/null
@@ -0,0 +1,7 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+CKEDITOR.dialog.add("anchor",function(c){function d(a,b){return a.createFakeElement(a.document.createElement("a",{attributes:b}),"cke_anchor","anchor")}return{title:c.lang.link.anchor.title,minWidth:300,minHeight:60,onOk:function(){var a=CKEDITOR.tools.trim(this.getValueOf("info","txtName")),a={id:a,name:a,"data-cke-saved-name":a};if(this._.selectedElement)this._.selectedElement.data("cke-realelement")?(a=d(c,a),a.replace(this._.selectedElement),CKEDITOR.env.ie&&c.getSelection().selectElement(a)):
+this._.selectedElement.setAttributes(a);else{var b=c.getSelection(),b=b&&b.getRanges()[0];b.collapsed?(a=d(c,a),b.insertNode(a)):(CKEDITOR.env.ie&&9>CKEDITOR.env.version&&(a["class"]="cke_anchor"),a=new CKEDITOR.style({element:"a",attributes:a}),a.type=CKEDITOR.STYLE_INLINE,c.applyStyle(a))}},onHide:function(){delete this._.selectedElement},onShow:function(){var a=c.getSelection(),b=a.getSelectedElement(),d=b&&b.data("cke-realelement"),e=d?CKEDITOR.plugins.link.tryRestoreFakeAnchor(c,b):CKEDITOR.plugins.link.getSelectedLink(c);
+if(e){this._.selectedElement=e;var f=e.data("cke-saved-name");this.setValueOf("info","txtName",f||"");!d&&a.selectElement(e);b&&(this._.selectedElement=b)}this.getContentElement("info","txtName").focus()},contents:[{id:"info",label:c.lang.link.anchor.title,accessKey:"I",elements:[{type:"text",id:"txtName",label:c.lang.link.anchor.name,required:!0,validate:function(){return this.getValue()?!0:(alert(c.lang.link.anchor.errorName),!1)}}]}]}});
\ No newline at end of file
diff --git a/release/plugins/link/dialogs/link.js b/release/plugins/link/dialogs/link.js
new file mode 100644 (file)
index 0000000..bd837a2
--- /dev/null
@@ -0,0 +1,28 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(){CKEDITOR.dialog.add("link",function(e){var m=CKEDITOR.plugins.link,p,q=function(){var a=this.getDialog(),b=a.getContentElement("target","popupFeatures"),a=a.getContentElement("target","linkTargetName"),n=this.getValue();if(b&&a)switch(b=b.getElement(),b.hide(),a.setValue(""),n){case "frame":a.setLabel(e.lang.link.targetFrameName);a.getElement().show();break;case "popup":b.show();a.setLabel(e.lang.link.targetPopupName);a.getElement().show();break;default:a.setValue(n),a.getElement().hide()}},
+h=function(a){a.target&&this.setValue(a.target[this.id]||"")},f=function(a){a.advanced&&this.setValue(a.advanced[this.id]||"")},k=function(a){a.target||(a.target={});a.target[this.id]=this.getValue()||""},l=function(a){a.advanced||(a.advanced={});a.advanced[this.id]=this.getValue()||""},c=e.lang.common,b=e.lang.link,g;return{title:b.title,minWidth:"moono-lisa"==(CKEDITOR.skinName||e.config.skin)?450:350,minHeight:240,contents:[{id:"info",label:b.info,title:b.info,elements:[{type:"text",id:"linkDisplayText",
+label:b.displayText,setup:function(){this.enable();this.setValue(e.getSelection().getSelectedText());p=this.getValue()},commit:function(a){a.linkText=this.isEnabled()?this.getValue():""}},{id:"linkType",type:"select",label:b.type,"default":"url",items:[[b.toUrl,"url"],[b.toAnchor,"anchor"],[b.toEmail,"email"]],onChange:function(){var a=this.getDialog(),b=["urlOptions","anchorOptions","emailOptions"],n=this.getValue(),d=a.definition.getContents("upload"),d=d&&d.hidden;"url"==n?(e.config.linkShowTargetTab&&
+a.showPage("target"),d||a.showPage("upload")):(a.hidePage("target"),d||a.hidePage("upload"));for(d=0;d<b.length;d++){var c=a.getContentElement("info",b[d]);c&&(c=c.getElement().getParent().getParent(),b[d]==n+"Options"?c.show():c.hide())}a.layout()},setup:function(a){this.setValue(a.type||"url")},commit:function(a){a.type=this.getValue()}},{type:"vbox",id:"urlOptions",children:[{type:"hbox",widths:["25%","75%"],children:[{id:"protocol",type:"select",label:c.protocol,"default":"http://",items:[["http://‎",
+"http://"],["https://‎","https://"],["ftp://‎","ftp://"],["news://‎","news://"],[b.other,""]],setup:function(a){a.url&&this.setValue(a.url.protocol||"")},commit:function(a){a.url||(a.url={});a.url.protocol=this.getValue()}},{type:"text",id:"url",label:c.url,required:!0,onLoad:function(){this.allowOnChange=!0},onKeyUp:function(){this.allowOnChange=!1;var a=this.getDialog().getContentElement("info","protocol"),b=this.getValue(),c=/^((javascript:)|[#\/\.\?])/i,d=/^(http|https|ftp|news):\/\/(?=.)/i.exec(b);
+d?(this.setValue(b.substr(d[0].length)),a.setValue(d[0].toLowerCase())):c.test(b)&&a.setValue("");this.allowOnChange=!0},onChange:function(){if(this.allowOnChange)this.onKeyUp()},validate:function(){var a=this.getDialog();return a.getContentElement("info","linkType")&&"url"!=a.getValueOf("info","linkType")?!0:!e.config.linkJavaScriptLinksAllowed&&/javascript\:/.test(this.getValue())?(alert(c.invalidValue),!1):this.getDialog().fakeObj?!0:CKEDITOR.dialog.validate.notEmpty(b.noUrl).apply(this)},setup:function(a){this.allowOnChange=
+!1;a.url&&this.setValue(a.url.url);this.allowOnChange=!0},commit:function(a){this.onChange();a.url||(a.url={});a.url.url=this.getValue();this.allowOnChange=!1}}],setup:function(){this.getDialog().getContentElement("info","linkType")||this.getElement().show()}},{type:"button",id:"browse",hidden:"true",filebrowser:"info:url",label:c.browseServer}]},{type:"vbox",id:"anchorOptions",width:260,align:"center",padding:0,children:[{type:"fieldset",id:"selectAnchorText",label:b.selectAnchor,setup:function(){g=
+m.getEditorAnchors(e);this.getElement()[g&&g.length?"show":"hide"]()},children:[{type:"hbox",id:"selectAnchor",children:[{type:"select",id:"anchorName","default":"",label:b.anchorName,style:"width: 100%;",items:[[""]],setup:function(a){this.clear();this.add("");if(g)for(var b=0;b<g.length;b++)g[b].name&&this.add(g[b].name);a.anchor&&this.setValue(a.anchor.name);(a=this.getDialog().getContentElement("info","linkType"))&&"email"==a.getValue()&&this.focus()},commit:function(a){a.anchor||(a.anchor={});
+a.anchor.name=this.getValue()}},{type:"select",id:"anchorId","default":"",label:b.anchorId,style:"width: 100%;",items:[[""]],setup:function(a){this.clear();this.add("");if(g)for(var b=0;b<g.length;b++)g[b].id&&this.add(g[b].id);a.anchor&&this.setValue(a.anchor.id)},commit:function(a){a.anchor||(a.anchor={});a.anchor.id=this.getValue()}}],setup:function(){this.getElement()[g&&g.length?"show":"hide"]()}}]},{type:"html",id:"noAnchors",style:"text-align: center;",html:'\x3cdiv role\x3d"note" tabIndex\x3d"-1"\x3e'+
+CKEDITOR.tools.htmlEncode(b.noAnchors)+"\x3c/div\x3e",focus:!0,setup:function(){this.getElement()[g&&g.length?"hide":"show"]()}}],setup:function(){this.getDialog().getContentElement("info","linkType")||this.getElement().hide()}},{type:"vbox",id:"emailOptions",padding:1,children:[{type:"text",id:"emailAddress",label:b.emailAddress,required:!0,validate:function(){var a=this.getDialog();return a.getContentElement("info","linkType")&&"email"==a.getValueOf("info","linkType")?CKEDITOR.dialog.validate.notEmpty(b.noEmail).apply(this):
+!0},setup:function(a){a.email&&this.setValue(a.email.address);(a=this.getDialog().getContentElement("info","linkType"))&&"email"==a.getValue()&&this.select()},commit:function(a){a.email||(a.email={});a.email.address=this.getValue()}},{type:"text",id:"emailSubject",label:b.emailSubject,setup:function(a){a.email&&this.setValue(a.email.subject)},commit:function(a){a.email||(a.email={});a.email.subject=this.getValue()}},{type:"textarea",id:"emailBody",label:b.emailBody,rows:3,"default":"",setup:function(a){a.email&&
+this.setValue(a.email.body)},commit:function(a){a.email||(a.email={});a.email.body=this.getValue()}}],setup:function(){this.getDialog().getContentElement("info","linkType")||this.getElement().hide()}}]},{id:"target",requiredContent:"a[target]",label:b.target,title:b.target,elements:[{type:"hbox",widths:["50%","50%"],children:[{type:"select",id:"linkTargetType",label:c.target,"default":"notSet",style:"width : 100%;",items:[[c.notSet,"notSet"],[b.targetFrame,"frame"],[b.targetPopup,"popup"],[c.targetNew,
+"_blank"],[c.targetTop,"_top"],[c.targetSelf,"_self"],[c.targetParent,"_parent"]],onChange:q,setup:function(a){a.target&&this.setValue(a.target.type||"notSet");q.call(this)},commit:function(a){a.target||(a.target={});a.target.type=this.getValue()}},{type:"text",id:"linkTargetName",label:b.targetFrameName,"default":"",setup:function(a){a.target&&this.setValue(a.target.name)},commit:function(a){a.target||(a.target={});a.target.name=this.getValue().replace(/([^\x00-\x7F]|\s)/gi,"")}}]},{type:"vbox",
+width:"100%",align:"center",padding:2,id:"popupFeatures",children:[{type:"fieldset",label:b.popupFeatures,children:[{type:"hbox",children:[{type:"checkbox",id:"resizable",label:b.popupResizable,setup:h,commit:k},{type:"checkbox",id:"status",label:b.popupStatusBar,setup:h,commit:k}]},{type:"hbox",children:[{type:"checkbox",id:"location",label:b.popupLocationBar,setup:h,commit:k},{type:"checkbox",id:"toolbar",label:b.popupToolbar,setup:h,commit:k}]},{type:"hbox",children:[{type:"checkbox",id:"menubar",
+label:b.popupMenuBar,setup:h,commit:k},{type:"checkbox",id:"fullscreen",label:b.popupFullScreen,setup:h,commit:k}]},{type:"hbox",children:[{type:"checkbox",id:"scrollbars",label:b.popupScrollBars,setup:h,commit:k},{type:"checkbox",id:"dependent",label:b.popupDependent,setup:h,commit:k}]},{type:"hbox",children:[{type:"text",widths:["50%","50%"],labelLayout:"horizontal",label:c.width,id:"width",setup:h,commit:k},{type:"text",labelLayout:"horizontal",widths:["50%","50%"],label:b.popupLeft,id:"left",
+setup:h,commit:k}]},{type:"hbox",children:[{type:"text",labelLayout:"horizontal",widths:["50%","50%"],label:c.height,id:"height",setup:h,commit:k},{type:"text",labelLayout:"horizontal",label:b.popupTop,widths:["50%","50%"],id:"top",setup:h,commit:k}]}]}]}]},{id:"upload",label:b.upload,title:b.upload,hidden:!0,filebrowser:"uploadButton",elements:[{type:"file",id:"upload",label:c.upload,style:"height:40px",size:29},{type:"fileButton",id:"uploadButton",label:c.uploadSubmit,filebrowser:"info:url","for":["upload",
+"upload"]}]},{id:"advanced",label:b.advanced,title:b.advanced,elements:[{type:"vbox",padding:1,children:[{type:"hbox",widths:["45%","35%","20%"],children:[{type:"text",id:"advId",requiredContent:"a[id]",label:b.id,setup:f,commit:l},{type:"select",id:"advLangDir",requiredContent:"a[dir]",label:b.langDir,"default":"",style:"width:110px",items:[[c.notSet,""],[b.langDirLTR,"ltr"],[b.langDirRTL,"rtl"]],setup:f,commit:l},{type:"text",id:"advAccessKey",requiredContent:"a[accesskey]",width:"80px",label:b.acccessKey,
+maxLength:1,setup:f,commit:l}]},{type:"hbox",widths:["45%","35%","20%"],children:[{type:"text",label:b.name,id:"advName",requiredContent:"a[name]",setup:f,commit:l},{type:"text",label:b.langCode,id:"advLangCode",requiredContent:"a[lang]",width:"110px","default":"",setup:f,commit:l},{type:"text",label:b.tabIndex,id:"advTabIndex",requiredContent:"a[tabindex]",width:"80px",maxLength:5,setup:f,commit:l}]}]},{type:"vbox",padding:1,children:[{type:"hbox",widths:["45%","55%"],children:[{type:"text",label:b.advisoryTitle,
+requiredContent:"a[title]","default":"",id:"advTitle",setup:f,commit:l},{type:"text",label:b.advisoryContentType,requiredContent:"a[type]","default":"",id:"advContentType",setup:f,commit:l}]},{type:"hbox",widths:["45%","55%"],children:[{type:"text",label:b.cssClasses,requiredContent:"a(cke-xyz)","default":"",id:"advCSSClasses",setup:f,commit:l},{type:"text",label:b.charset,requiredContent:"a[charset]","default":"",id:"advCharset",setup:f,commit:l}]},{type:"hbox",widths:["45%","55%"],children:[{type:"text",
+label:b.rel,requiredContent:"a[rel]","default":"",id:"advRel",setup:f,commit:l},{type:"text",label:b.styles,requiredContent:"a{cke-xyz}","default":"",id:"advStyles",validate:CKEDITOR.dialog.validate.inlineStyle(e.lang.common.invalidInlineStyle),setup:f,commit:l}]},{type:"hbox",widths:["45%","55%"],children:[{type:"checkbox",id:"download",requiredContent:"a[download]",label:b.download,setup:function(a){void 0!==a.download&&this.setValue("checked","checked")},commit:function(a){this.getValue()&&(a.download=
+this.getValue())}}]}]}]}],onShow:function(){var a=this.getParentEditor(),b=a.getSelection(),c=b.getSelectedElement(),d=this.getContentElement("info","linkDisplayText").getElement().getParent().getParent(),e=null;(e=m.getSelectedLink(a))&&e.hasAttribute("href")?c||(b.selectElement(e),c=e):e=null;m.showDisplayTextForElement(c,a)?d.show():d.hide();a=m.parseLinkAttributes(a,e);this._.selectedElement=e;this.setupContent(a)},onOk:function(){var a={};this.commitContent(a);var b=e.getSelection(),c=m.getLinkAttributes(e,
+a);if(this._.selectedElement){var d=this._.selectedElement,g=d.data("cke-saved-href"),h=d.getHtml(),f;d.setAttributes(c.set);d.removeAttributes(c.removed);if(a.linkText&&p!=a.linkText)f=a.linkText;else if(g==h||"email"==a.type&&-1!=h.indexOf("@"))f="email"==a.type?a.email.address:c.set["data-cke-saved-href"];f&&(d.setText(f),b.selectElement(d));delete this._.selectedElement}else{b=b.getRanges()[0];b.collapsed?(a=new CKEDITOR.dom.text(a.linkText||("email"==a.type?a.email.address:c.set["data-cke-saved-href"]),
+e.document),b.insertNode(a),b.selectNodeContents(a)):p!==a.linkText&&(a=new CKEDITOR.dom.text(a.linkText,e.document),b.shrink(CKEDITOR.SHRINK_TEXT),e.editable().extractHtmlFromRange(b),b.insertNode(a));a=b._find("a");for(d=0;d<a.length;d++)a[d].remove(!0);c=new CKEDITOR.style({element:"a",attributes:c.set});c.type=CKEDITOR.STYLE_INLINE;c.applyToRange(b,e);b.select()}},onLoad:function(){e.config.linkShowAdvancedTab||this.hidePage("advanced");e.config.linkShowTargetTab||this.hidePage("target")},onFocus:function(){var a=
+this.getContentElement("info","linkType");a&&"url"==a.getValue()&&(a=this.getContentElement("info","url"),a.select())}}})})();
\ No newline at end of file
diff --git a/release/plugins/link/images/anchor.png b/release/plugins/link/images/anchor.png
new file mode 100644 (file)
index 0000000..d94adb4
Binary files /dev/null and b/release/plugins/link/images/anchor.png differ
diff --git a/release/plugins/link/images/hidpi/anchor.png b/release/plugins/link/images/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..186c3e9
Binary files /dev/null and b/release/plugins/link/images/hidpi/anchor.png differ
diff --git a/release/plugins/liststyle/dialogs/liststyle.js b/release/plugins/liststyle/dialogs/liststyle.js
new file mode 100644 (file)
index 0000000..3d5a56f
--- /dev/null
@@ -0,0 +1,10 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+(function(){function d(c,d){var b;try{b=c.getSelection().getRanges()[0]}catch(f){return null}b.shrink(CKEDITOR.SHRINK_TEXT);return c.elementPath(b.getCommonAncestor()).contains(d,1)}function e(c,e){var b=c.lang.liststyle;if("bulletedListStyle"==e)return{title:b.bulletedTitle,minWidth:300,minHeight:50,contents:[{id:"info",accessKey:"I",elements:[{type:"select",label:b.type,id:"type",align:"center",style:"width:150px",items:[[b.notset,""],[b.circle,"circle"],[b.disc,"disc"],[b.square,"square"]],setup:function(a){a=
+a.getStyle("list-style-type")||h[a.getAttribute("type")]||a.getAttribute("type")||"";this.setValue(a)},commit:function(a){var b=this.getValue();b?a.setStyle("list-style-type",b):a.removeStyle("list-style-type")}}]}],onShow:function(){var a=this.getParentEditor();(a=d(a,"ul"))&&this.setupContent(a)},onOk:function(){var a=this.getParentEditor();(a=d(a,"ul"))&&this.commitContent(a)}};if("numberedListStyle"==e){var g=[[b.notset,""],[b.lowerRoman,"lower-roman"],[b.upperRoman,"upper-roman"],[b.lowerAlpha,
+"lower-alpha"],[b.upperAlpha,"upper-alpha"],[b.decimal,"decimal"]];(!CKEDITOR.env.ie||7<CKEDITOR.env.version)&&g.concat([[b.armenian,"armenian"],[b.decimalLeadingZero,"decimal-leading-zero"],[b.georgian,"georgian"],[b.lowerGreek,"lower-greek"]]);return{title:b.numberedTitle,minWidth:300,minHeight:50,contents:[{id:"info",accessKey:"I",elements:[{type:"hbox",widths:["25%","75%"],children:[{label:b.start,type:"text",id:"start",validate:CKEDITOR.dialog.validate.integer(b.validateStartNumber),setup:function(a){a=
+a.getFirst(f).getAttribute("value")||a.getAttribute("start")||1;this.setValue(a)},commit:function(a){var b=a.getFirst(f),c=b.getAttribute("value")||a.getAttribute("start")||1;a.getFirst(f).removeAttribute("value");var d=parseInt(this.getValue(),10);isNaN(d)?a.removeAttribute("start"):a.setAttribute("start",d);a=b;b=c;for(d=isNaN(d)?1:d;(a=a.getNext(f))&&b++;)a.getAttribute("value")==b&&a.setAttribute("value",d+b-c)}},{type:"select",label:b.type,id:"type",style:"width: 100%;",items:g,setup:function(a){a=
+a.getStyle("list-style-type")||h[a.getAttribute("type")]||a.getAttribute("type")||"";this.setValue(a)},commit:function(a){var b=this.getValue();b?a.setStyle("list-style-type",b):a.removeStyle("list-style-type")}}]}]}],onShow:function(){var a=this.getParentEditor();(a=d(a,"ol"))&&this.setupContent(a)},onOk:function(){var a=this.getParentEditor();(a=d(a,"ol"))&&this.commitContent(a)}}}}var f=function(c){return c.type==CKEDITOR.NODE_ELEMENT&&c.is("li")},h={a:"lower-alpha",A:"upper-alpha",i:"lower-roman",
+I:"upper-roman",1:"decimal",disc:"disc",circle:"circle",square:"square"};CKEDITOR.dialog.add("numberedListStyle",function(c){return e(c,"numberedListStyle")});CKEDITOR.dialog.add("bulletedListStyle",function(c){return e(c,"bulletedListStyle")})})();
\ No newline at end of file
diff --git a/release/plugins/magicline/images/hidpi/icon-rtl.png b/release/plugins/magicline/images/hidpi/icon-rtl.png
new file mode 100644 (file)
index 0000000..4a8d2bf
Binary files /dev/null and b/release/plugins/magicline/images/hidpi/icon-rtl.png differ
diff --git a/release/plugins/magicline/images/hidpi/icon.png b/release/plugins/magicline/images/hidpi/icon.png
new file mode 100644 (file)
index 0000000..b981bb5
Binary files /dev/null and b/release/plugins/magicline/images/hidpi/icon.png differ
diff --git a/release/plugins/magicline/images/icon-rtl.png b/release/plugins/magicline/images/icon-rtl.png
new file mode 100644 (file)
index 0000000..55b5b5f
Binary files /dev/null and b/release/plugins/magicline/images/icon-rtl.png differ
diff --git a/release/plugins/magicline/images/icon.png b/release/plugins/magicline/images/icon.png
new file mode 100644 (file)
index 0000000..e063433
Binary files /dev/null and b/release/plugins/magicline/images/icon.png differ
diff --git a/release/plugins/oembed/LICENSE.md b/release/plugins/oembed/LICENSE.md
new file mode 100644 (file)
index 0000000..be0064f
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)\r
+\r
+Copyright (c) Ingo Herbote\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all\r
+copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+SOFTWARE.\r
diff --git a/release/plugins/oembed/README.md b/release/plugins/oembed/README.md
new file mode 100644 (file)
index 0000000..64c729c
--- /dev/null
@@ -0,0 +1,201 @@
+CKEditor-oEmbed-Plugin\r
+======================\r
+\r
+oEmbed Plugin for CKEditor\r
+\r
+This Plugin allows to insert embedded content (such as photos, videos, audio, and other rich media) via the OEmbed API. You only have to provide the url to the site (It works also when the url is shortened) you want to embed and the plugin does the rest.\r
+\r
+This Plugin uses the jquery-oembed-all Plugin  located at https://github.com/starfishmod/jquery-oembed-all.\r
+\r
+####Demo\r
+\r
+http://w8tcha.github.com/CKEditor-oEmbed-Plugin/\r
+\r
+####Currently Supported Sites...\r
+\r
+###Video\r
+* Youtube - oembed - YQL\r
+* Blip - oEmbed\r
+* Hulu - oEmbed\r
+* Vimeo - oEmbed\r
+* National film board of Canada - oEmbed\r
+* Qik - oEmbed\r
+* Dotsub - oEmbed\r
+* Clikthrough - oEmbed\r
+* Kino Map - oEmbed\r
+* Funny Or Die - Embedded\r
+* College Humour - Embedded\r
+* Metacafe - Embedded\r
+* embedr - Embedded\r
+* 5min - oEmbed is XML only - using YQL to translate it\r
+* ustream.tv - oEmbed is not JSONP enabled - using YQL to translate it\r
+* viddler - OGP\r
+* twitvid - Embedded\r
+* bambuser - Embedded\r
+* xtranormal - Embedded\r
+* Gametrailers - Embedded\r
+* Vzarr - Embedded\r
+* VHX - oembed\r
+* bambuser - oembed\r
+* dailymotion.com - oembed\r
+* animoto - oembed\r
+* justin.tv - YQL JSON\r
+* livestream - OGP\r
+* scivee - embedded\r
+* veoh - embedded\r
+* minoto-video - oembed using YQL\r
+* TrailerAddict - OGP\r
+* vodpod - oembed YQL - broken as the oembed has absolute positioning which breaks the display\r
+* fora.tv -OGP YQL\r
+* TED - OGP YQL\r
+* Aniboom - embedded\r
+* Comedy Central - OGP\r
+* snotr - embedded\r
+* zapiks - OGP\r
+* youku - embedded\r
+* wistia - Oembed\r
+\r
+###Audio\r
+* Soundcloud - oEmbed\r
+* HuffDuffer - oEmbed\r
+* BandCamp - YQL and Embedded\r
+* podomatic - OGP\r
+* rdio.com - oEmbed\r
+* hark.com - OGP\r
+* chirb.it - YQL and oembed\r
+* official.fm - YQL and oembed\r
+* mixcloud - YQL and oembed\r
+* shoudio - oembed\r
+* audioboo.fm - OGP\r
+* Spotify - OGP YQL\r
+\r
+###Photo\r
+* flickr - oEmbed\r
+* photobucket - oEmbed\r
+* instagram - oEmbed\r
+* yfrog - oEmbed\r
+* 23HQ - oEmbed\r
+* Smugmug - oEmbed\r
+* twitpic - OGP YQL\r
+* 500px.com - OGP\r
+* visual.ly - YQL Lookup\r
+* img.ly - Thumbnail view\r
+* imgur.com - Thumbnail view\r
+* twitgoo.com - Thumbnail view\r
+* gravatar - Thumbnail view when using mailto\r
+* pintrest - YQL - Embedded view of a sort.\r
+* circuitlab - image view\r
+* skitch - YQL oembed\r
+* graphic.ly  - OGP\r
+* dribble - jsonp lookup\r
+* Lockerz - YQL lookup\r
+* AsciiArtFarts - YQL Lookup\r
+* lego cusoo - OGP over YQL\r
+* plannary - OGP over YQL\r
+* propic - OGP\r
+* avairy.com - OGP\r
+* lomography - ogp\r
+* weheartit - ogp\r
+* glogster - ogp\r
+* chart.ly - embedded\r
+* twitrpix - OGP\r
+* chictopia - OGP\r
+\r
+###Rich\r
+* Meetup - oEmbed\r
+* gigapans - Embedded\r
+* Slideshare - oEmbed\r
+* ebay - Embedded\r
+* scribd - Embedded\r
+* screenr - Embedded\r
+* tumblr- JSONP lookup\r
+* imdb - JSONP lookup via imdbapi.com\r
+* wikipedia- JSONP lookup\r
+* github- JSONP lookup (CSS)\r
+* eventful - OGP\r
+* myspace - OGP\r
+* live Journal - JSONP Lookup (CSS)\r
+* wordpress - oEmbed (wordpress.com, wp.me, blogs.cnn.com, techcrunch.com). I can add other wordpress sites as well.\r
+* circuitbee -Embedded\r
+* stack overflow - JSONP Lookup (CSS)\r
+* Facebook - JSONP Lookup (CSS)\r
+* Pastebin - Embedded\r
+* Pastie - YQL lookup\r
+* kickstarter - Embedded\r
+* issuu - OGP\r
+* reelapp.com - Embedded\r
+* Etsy - OGP over YQL\r
+* Amazon - Embedded - Requires Affiliate code\r
+* linkedin - Embedded IFRAME - found a link that works :)\r
+* Lanyrd - YQL (CSS)\r
+* twitter - Oembed - status only - but that is ok I think\r
+* github gist - oembed\r
+* speakerdeck - yql oembed\r
+* dipity - yql oembed\r
+* dailymile - oembed\r
+* deviantart - oembed\r
+* Roomshare Japan - oembed\r
+* mobypictures - oembed\r
+* prezi - embedded\r
+* popplet - embedded\r
+* authorstream - OGP\r
+* googlecalendar - Iframe\r
+* cacoo - oembed\r
+* pearltrees - embedded\r
+* urtak - oembed - is broken in iframe return atm -seems to be an embed.ly issue??\r
+* jotform - embedded\r
+* Urban Dictionary - YQL lookup\r
+* Ars Technica - YQL Lookup\r
+* Eventbrite - OGP YQL\r
+* last.fm OGP YQL\r
+* Rotten Tomatoes - OGP YQL\r
+* iFixit - OGP\r
+* qwiki - OGP\r
+* brighttalk - Meta info\r
+* tinychat - OGP\r
+* tourwrist - embedded\r
+* bnter - OGP\r
+* bigthink - OGP\r
+* wirewax - OGP\r
+* whosay - OGP\r
+* timetoast - embedded\r
+* tripline - OGP\r
+* jsfiddle - embedded\r
+\r
+\r
+####License\r
+\r
+Licensed under the terms of the MIT License.\r
+\r
+####Dependencies\r
+This Plugin requires the following plugins to work: Widget, Dialog.\r
+\r
+####Installation\r
+\r
+ 1. Before you can use the plugin you also need to download & install the widget plugin, if you have it not installed. http://ckeditor.com/addon/widget\r
+ 2. Extract the contents of the file into the "plugins" folder of CKEditor.\r
+ 3. In the CKEditor configuration file (config.js) add the following code:\r
+\r
+````js\r
+config.extraPlugins = 'oembed,widget';\r
+````\r
+\r
+2a. Additionally you can also set the default values vor the Max. Width/Height Values\r
+\r
+````js\r
+config.oembed_maxWidth = '560';\r
+config.oembed_maxHeight = '315';\r
+````\r
+\r
+and also you can define an css class for the embeded content wrapper (div), by default there is no Class defined\r
+\r
+````js\r
+config.oembed_WrapperClass = 'embededContent';\r
+````\r
+\r
+\r
+3. and also include the plugin in the toolbar\r
+\r
+````js\r
+toolbar :[ ... ['oembed']...]\r
+````\r
diff --git a/release/plugins/oembed/libs/jquery.oembed.min.js b/release/plugins/oembed/libs/jquery.oembed.min.js
new file mode 100644 (file)
index 0000000..5a64c0d
--- /dev/null
@@ -0,0 +1,71 @@
+(function(b){function m(){return"file:"===window.location.protocol?"http://":"//"}function o(a,b){return b=b?b:"",a?o(--a,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(60*Math.random()))+b):b}function q(a,b){var h=a.apiendpoint,d="",c,h=h+(0>=h.indexOf("?")?"?":"&"),h=h.replace("#","%23");null!==a.maxWidth&&("undefined"==typeof a.params.maxwidth||null===a.params.maxwidth)&&(a.params.maxwidth=a.maxWidth);null!==a.maxHeight&&("undefined"==typeof a.params.maxheight||
+null===a.params.maxheight)&&(a.params.maxheight=a.maxHeight);for(c in a.params)c!=a.callbackparameter&&null!==a.params[c]&&(d+="&"+escape(c)+"="+a.params[c]);return h+="format="+a.format+"&url="+escape(b)+d,"json"!=a.dataType&&(h+="&"+a.callbackparameter+"=?"),h}function n(a,l,h){b("#jqoembeddata").data(l,a.code);j.beforeEmbed.call(h,a);j.onEmbed.call(h,a);j.afterEmbed.call(h,a)}function e(a,l,h){var d,c,f;if(void 0!=b("#jqoembeddata").data(l)&&"iframe"!=h.embedtag.tag)c={code:b("#jqoembeddata").data(l)},
+n(c,l,a);else if(h.yql){c=h.yql.from||"htmlstring";var g=h.yql.url?h.yql.url(l):l;f="SELECT * FROM "+c+' WHERE url="'+g+'" and '+(/html/.test(c)?"xpath":"itemPath")+"='"+(h.yql.xpath||"/")+"'";"html"==c&&(f+=" and compat='html5'");f=b.extend({url:m()+"query.yahooapis.com/v1/public/yql",dataType:"jsonp",data:{q:f,format:"json",env:"store://datatables.org/alltableswithkeys",callback:"?"},success:function(c){var d,f,e,k,j;if(h.yql.xpath&&"//meta|//title|//link"==h.yql.xpath){d={};null==c.query.results&&
+(c.query.results={meta:[]});e=0;for(k=c.query.results.meta.length;e<k;e++)(f=c.query.results.meta[e].name||c.query.results.meta[e].property||null,null!=f)&&(d[f.toLowerCase()]=c.query.results.meta[e].content);if(d.hasOwnProperty("title")&&d.hasOwnProperty("og:title")||null!=c.query.results.title&&(d.title=c.query.results.title),!d.hasOwnProperty("og:image")&&c.query.results.hasOwnProperty("link")){e=0;for(k=c.query.results.link.length;e<k;e++)c.query.results.link[e].hasOwnProperty("rel")&&"apple-touch-icon"==
+c.query.results.link[e].rel&&(d["og:image"]="/"==c.query.results.link[e].href.charAt(0)?g.match(/^(([a-z]+:)?(\/\/)?[^\/]+\/).*$/)[1]+c.query.results.link[e].href:c.query.results.link[e].href)}c=h.yql.datareturn(d)}else c=h.yql.datareturn?h.yql.datareturn(c.query.results):c.query.results.result;!1!==c&&(j=b.extend({},c),j.code=c,n(j,l,a))},error:function(){j.onError.call(a,l,h)}},j.ajaxOptions||{});b.ajax(f)}else if(h.templateRegex)if(""!==h.embedtag.tag){c=h.embedtag.flashvars||"";f=h.embedtag.tag||
+"embed";d=h.embedtag.width||"auto";var e=h.embedtag.height||"auto",p=l.replace(h.templateRegex,h.apiendpoint);if(h.nocache||(p+="&jqoemcache="+o(5)),h.apikey&&(p=p.replace("_APIKEY_",j.apikeys[h.name])),j.maxHeight&&j.maxWidth)if(j.useResponsiveResize){var r=0,s=d,t=e;d>j.maxWidth&&(r=j.maxWidth/d,s=j.maxWidth,t=e*r,e*=r,d*=r);e>j.maxHeight&&(r=j.maxHeight/e,t=j.maxHeight,s=d*r,d*=r);e=t;d=s}else e=j.maxHeight,d=j.maxWidth;d=b("<"+f+"/>").attr("src",p).attr("width",d).attr("height",e).attr("allowfullscreen",
+h.embedtag.allowfullscreen||"true").attr("allowscriptaccess",h.embedtag.allowfullscreen||"always").css("max-height",j.maxHeight||"auto").css("max-width",j.maxWidth||"auto");"embed"==f&&d.attr("type",h.embedtag.type||"application/x-shockwave-flash").attr("flashvars",l.replace(h.templateRegex,c));"iframe"==f&&d.attr("scrolling",h.embedtag.scrolling||"no").attr("frameborder",h.embedtag.frameborder||"0");c={code:d};n(c,l,a)}else h.apiendpoint?(h.apikey&&(h.apiendpoint=h.apiendpoint.replace("_APIKEY_",
+j.apikeys[h.name])),f=b.extend({url:l.replace(h.templateRegex,h.apiendpoint),dataType:"jsonp",success:function(c){var d=b.extend({},c);d.code=h.templateData(c);n(d,l,a)},error:function(){j.onError.call(a,l,h)}},j.ajaxOptions||{}),b.ajax(f)):(c={code:l.replace(h.templateRegex,h.template)},n(c,l,a));else c=q(h,l),f=b.extend({url:c,dataType:h.dataType||"jsonp",success:function(c){c=b.extend({},c);switch(c.type){case "file":case "photo":c.code=b.fn.oembed.getPhotoCode(l,c);break;case "link":c.code="Flickr"==
+c.provider_name?b.fn.oembed.getPhotoCode(l,c):b.fn.oembed.getGenericCode(l,c);break;case "video":case "rich":c.code=b.fn.oembed.getRichCode(l,c);break;default:c.code=b.fn.oembed.getGenericCode(l,c)}n(c,l,a)},error:function(){j.onError.call(a,l,h)}},j.ajaxOptions||{}),b.ajax(f)}function p(a){if(null===a)return null;var b,e={};for(b in a)null!==b&&(e[b.toLowerCase()]=a[b]);return e}b.fn.oembed=function(a,l,h){j=b.extend(!0,b.fn.oembed.defaults,l);var d="0rz.tw 1link.in 1url.com 2.gp 2big.at 2tu.us 3.ly 307.to 4ms.me 4sq.com 4url.cc 6url.com 7.ly a.gg a.nf aa.cx abcurl.net ad.vu adf.ly adjix.com afx.cc all.fuseurl.com alturl.com amzn.to ar.gy arst.ch atu.ca azc.cc b23.ru b2l.me bacn.me bcool.bz binged.it bit.ly bizj.us bloat.me bravo.ly bsa.ly budurl.com canurl.com chilp.it chzb.gr cl.lk cl.ly clck.ru cli.gs cliccami.info clickthru.ca clop.in conta.cc cort.as cot.ag crks.me ctvr.us cutt.us dai.ly decenturl.com dfl8.me digbig.com http://digg.com/[^/]+$ disq.us dld.bz dlvr.it do.my doiop.com dopen.us easyuri.com easyurl.net eepurl.com eweri.com fa.by fav.me fb.me fbshare.me ff.im fff.to fire.to firsturl.de firsturl.net flic.kr flq.us fly2.ws fon.gs freak.to fuseurl.com fuzzy.to fwd4.me fwib.net g.ro.lt gizmo.do gl.am go.9nl.com go.ign.com go.usa.gov goo.gl goshrink.com gurl.es hex.io hiderefer.com hmm.ph href.in hsblinks.com htxt.it huff.to hulu.com hurl.me hurl.ws icanhaz.com idek.net ilix.in is.gd its.my ix.lt j.mp jijr.com kl.am klck.me korta.nu krunchd.com l9k.net lat.ms liip.to liltext.com linkbee.com linkbun.ch liurl.cn ln-s.net ln-s.ru lnk.gd lnk.ms lnkd.in lnkurl.com lru.jp lt.tl lurl.no macte.ch mash.to merky.de migre.me miniurl.com minurl.fr mke.me moby.to moourl.com mrte.ch myloc.me myurl.in n.pr nbc.co nblo.gs nn.nf not.my notlong.com nsfw.in nutshellurl.com nxy.in nyti.ms o-x.fr oc1.us om.ly omf.gd omoikane.net on.cnn.com on.mktw.net onforb.es orz.se ow.ly ping.fm pli.gs pnt.me politi.co post.ly pp.gg profile.to ptiturl.com pub.vitrue.com qlnk.net qte.me qu.tc qy.fi r.ebay.com r.im rb6.me read.bi readthis.ca reallytinyurl.com redir.ec redirects.ca redirx.com retwt.me ri.ms rickroll.it riz.gd rt.nu ru.ly rubyurl.com rurl.org rww.tw s4c.in s7y.us safe.mn sameurl.com sdut.us shar.es shink.de shorl.com short.ie short.to shortlinks.co.uk shorturl.com shout.to show.my shrinkify.com shrinkr.com shrt.fr shrt.st shrten.com shrunkin.com simurl.com slate.me smallr.com smsh.me smurl.name sn.im snipr.com snipurl.com snurl.com sp2.ro spedr.com srnk.net srs.li starturl.com stks.co su.pr surl.co.uk surl.hu t.cn t.co t.lh.com ta.gd tbd.ly tcrn.ch tgr.me tgr.ph tighturl.com tiniuri.com tiny.cc tiny.ly tiny.pl tinylink.in tinyuri.ca tinyurl.com tk. tl.gd tmi.me tnij.org tnw.to tny.com to.ly togoto.us totc.us toysr.us tpm.ly tr.im tra.kz trunc.it twhub.com twirl.at twitclicks.com twitterurl.net twitterurl.org twiturl.de twurl.cc twurl.nl u.mavrev.com u.nu u76.org ub0.cc ulu.lu updating.me ur1.ca url.az url.co.uk url.ie url360.me url4.eu urlborg.com urlbrief.com urlcover.com urlcut.com urlenco.de urli.nl urls.im urlshorteningservicefortwitter.com urlx.ie urlzen.com usat.ly use.my vb.ly vevo.ly vgn.am vl.am vm.lc w55.de wapo.st wapurl.co.uk wipi.es wp.me x.vu xr.com xrl.in xrl.us xurl.es xurl.jp y.ahoo.it yatuc.com ye.pe yep.it yfrog.com yhoo.it yiyd.com youtu.be yuarel.com z0p.de zi.ma zi.mu zipmyurl.com zud.me zurl.ws zz.gd zzang.kr ›.ws ✩.ws ✿.ws ❥.ws ➔.ws ➞.ws ➡.ws ➨.ws ➯.ws ➹.ws ➽.ws".split(" ");
+return 0===b("#jqoembeddata").length&&b('<span id="jqoembeddata"></span>').appendTo("body"),this.each(function(){var c=b(this),f=a&&(!a.indexOf("http://")||!a.indexOf("https://"))?a:c.attr("href"),g,l,m,n,o;if(h?j.onEmbed=h:j.onEmbed||(j.onEmbed=function(a){b.fn.oembed.insertCode(this,j.embedMethod,a)}),null!==f&&void 0!==f){l=0;for(m=d.length;l<m;l++)if(n=RegExp("://"+d[l]+"/","i"),null!==f.match(n))return o=b.extend({url:"http://api.longurl.org/v2/expand",dataType:"jsonp",data:{url:f,format:"json"},
+success:function(a){f=a["long-url"];g=b.fn.oembed.getOEmbedProvider(a["long-url"]);null!==g?(g.params=p(j[g.name])||{},g.maxWidth=j.maxWidth,g.maxHeight=j.maxHeight,e(c,f,g)):j.onProviderNotFound.call(c,f)}},j.ajaxOptions||{}),b.ajax(o),c;g=b.fn.oembed.getOEmbedProvider(f);null!==g?(g.params=p(j[g.name])||{},g.maxWidth=j.maxWidth,g.maxHeight=j.maxHeight,e(c,f,g)):j.onProviderNotFound.call(c,f)}return c})};var j;b.fn.oembed.defaults={maxWidth:null,maxHeight:null,useResponsiveResize:!1,includeHandle:!0,
+embedMethod:"auto",onProviderNotFound:function(){},beforeEmbed:function(){},afterEmbed:function(){},onEmbed:!1,onError:function(){},ajaxOptions:{timeout:2E3}};b.fn.oembed.insertCode=function(a,l,e){if(null!==e)switch("auto"==l&&null!==a.attr("href")?l="append":"auto"==l&&(l="replace"),l){case "replace":a.replaceWith(e.code);break;case "fill":a.html(e.code);break;case "append":a.wrap('<div class="oembedall-container"></div>');l=a.parent();j.includeHandle&&b('<span class="oembedall-closehide">&darr;</span>').insertBefore(a).click(function(){var a=
+encodeURIComponent(b(this).text());b(this).html("%E2%86%91"==a?"&darr;":"&uarr;");b(this).parent().children().last().toggle()});l.append("<br/>");try{e.code.clone().appendTo(l)}catch(d){l.append(e.code)}}};b.fn.oembed.getPhotoCode=function(a,b){var e,d=b.title?b.title:"",c;return d+=b.author_name?" - "+b.author_name:"",d+=b.provider_name?" - "+b.provider_name:"",b.url?e='<div><a href="'+a+"\" target='_blank'><img src=\""+b.url+'" alt="'+d+'"/></a></div>':b.thumbnail_url?(c=b.thumbnail_url.replace("_s",
+"_b"),e='<div><a href="'+a+"\" target='_blank'><img src=\""+c+'" alt="'+d+'"/></a></div>'):e="Flickr"==b.provider_name?'<p><a href="'+a+"\" target='_blank'>"+a+"</a></p>":"<div>Error loading this picture</div>",e};b.fn.oembed.getRichCode=function(a,b){return b.html};b.fn.oembed.getGenericCode=function(a,b){var e='<a href="'+a+'">'+(null!==b.title?b.title:a)+"</a>";return b.html&&(e+="<div>"+b.html+"</div>"),e};b.fn.oembed.getOEmbedProvider=function(a){for(var e,h,d,c=0;c<b.fn.oembed.providers.length;c++){e=
+0;for(h=b.fn.oembed.providers[c].urlschemes.length;e<h;e++)if(d=RegExp(b.fn.oembed.providers[c].urlschemes[e],"i"),null!==a.match(d))return b.fn.oembed.providers[c]}return null};b.fn.oembed.OEmbedProvider=function(a,e,h,d,c){this.name=a;this.type=e;this.urlschemes=h;this.apiendpoint=d;this.maxWidth=500;this.maxHeight=400;c=c||{};c.useYQL&&(c.yql="xml"==c.useYQL?{xpath:"//oembed/html",from:"xml",apiendpoint:this.apiendpoint,url:function(a){return this.apiendpoint+"?format=xml&url="+a},datareturn:function(a){return a.html.replace(/.*\[CDATA\[(.*)\]\]>$/,
+"$1")||""}}:{from:"json",apiendpoint:this.apiendpoint,url:function(a){return this.apiendpoint+"?format=json&url="+a},datareturn:function(a){var c,d,e;if("video"!=a.json.type&&(a.json.url||a.json.thumbnail_url)&&!a.json.html.indexOf("iframe"))return'<img src="'+(a.json.url||a.json.thumbnail_url)+'"  />';if(a.json.html.indexOf("iframe")){a.json.html.indexOf("allowfullscreen>")&&(a.json.html=a.json.html.replace("allowfullscreen>",'allowfullscreen="false">'));var a=b.parseHTML(a.json.html),f=a[0].width,
+l=a[0].height;return j.maxHeight&&j.maxWidth&&(j.useResponsiveResize?(d=f,e=l,f>j.maxWidth&&(c=j.maxWidth/f,d=j.maxWidth,e=l*c,l*=c,f*=c),l>j.maxHeight&&(c=j.maxHeight/l,e=j.maxHeight,d=f*c),l=e,f=d):(l=j.maxHeight,f=j.maxWidth)),a[0].width=f,a[0].height=l,a[0].outerHTML}return a.json.html||""}},this.apiendpoint=null);for(var f in c)this[f]=c[f];this.format=this.format||"json";this.callbackparameter=this.callbackparameter||"callback";this.embedtag=this.embedtag||{tag:""}};b.fn.updateOEmbedProvider=
+function(a,e,h,d,c){for(var f,g=0;g<b.fn.oembed.providers.length;g++)if(b.fn.oembed.providers[g].name===a&&(null!==e&&(b.fn.oembed.providers[g].type=e),null!==h&&(b.fn.oembed.providers[g].urlschemes=h),null!==d&&(b.fn.oembed.providers[g].apiendpoint=d),null!==c))for(f in b.fn.oembed.providers[g].extraSettings=c,c)null!==c[f]&&(b.fn.oembed.providers[g][f]=c[f])};b.fn.oembed.providers=[new b.fn.oembed.OEmbedProvider("youtube","video",["youtube\\.com/watch.+v=[\\w-]+&?","youtu\\.be/[\\w-]+","youtube.com/embed"],
+m()+"www.youtube.com/embed/$1?wmode=transparent",{templateRegex:/.*(?:v\=|be\/|embed\/)([\w\-]+)&?.*/,embedtag:{tag:"iframe",width:"425",height:"349"}}),new b.fn.oembed.OEmbedProvider("youtubeiframe","video",["youtube.com/embed"],"$1?wmode=transparent",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"425",height:"349"}}),new b.fn.oembed.OEmbedProvider("wistia","video",["wistia.com/m/.+","wistia.com/embed/.+","wi.st/m/.+","wi.st/embed/.+"],"http://fast.wistia.com/oembed",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("xtranormal",
+"video",["xtranormal\\.com/watch/.+"],"http://www.xtranormal.com/xtraplayr/$1/$2",{templateRegex:/.*com\/watch\/([\w\-]+)\/([\w\-]+).*/,embedtag:{tag:"iframe",width:"320",height:"269"}}),new b.fn.oembed.OEmbedProvider("scivee","video",["scivee.tv/node/.+"],"http://www.scivee.tv/flash/embedCast.swf?",{templateRegex:/.*tv\/node\/(.+)/,embedtag:{width:"480",height:"400",flashvars:"id=$1&type=3"}}),new b.fn.oembed.OEmbedProvider("veoh","video",["veoh.com/watch/.+"],"http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1337&permalinkId=$1&player=videodetailsembedded&videoAutoPlay=0&id=anonymous",
+{templateRegex:/.*watch\/([^\?]+).*/,embedtag:{width:"410",height:"341"}}),new b.fn.oembed.OEmbedProvider("gametrailers","video",["gametrailers\\.com/video/.+"],"http://media.mtvnservices.com/mgid:moses:video:gametrailers.com:$2",{templateRegex:/.*com\/video\/([\w\-]+)\/([\w\-]+).*/,embedtag:{width:"512",height:"288"}}),new b.fn.oembed.OEmbedProvider("funnyordie","video",["funnyordie\\.com/videos/.+"],"http://player.ordienetworks.com/flash/fodplayer.swf?",{templateRegex:/.*videos\/([^\/]+)\/([^\/]+)?/,
+embedtag:{width:512,height:328,flashvars:"key=$1"}}),new b.fn.oembed.OEmbedProvider("colledgehumour","video",["collegehumor\\.com/video/.+"],"http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=$1&use_node_id=true&fullscreen=1",{templateRegex:/.*video\/([^\/]+).*/,embedtag:{width:600,height:338}}),new b.fn.oembed.OEmbedProvider("metacafe","video",["metacafe\\.com/watch/.+"],"http://www.metacafe.com/fplayer/$1/$2.swf",{templateRegex:/.*watch\/(\d+)\/(\w+)\/.*/,embedtag:{width:400,height:345}}),
+new b.fn.oembed.OEmbedProvider("bambuser","video",["bambuser\\.com/channel/.*/broadcast/.*"],"http://static.bambuser.com/r/player.swf?vid=$1",{templateRegex:/.*bambuser\.com\/channel\/.*\/broadcast\/(\w+).*/,embedtag:{width:512,height:339}}),new b.fn.oembed.OEmbedProvider("twitvid","video",["twitvid\\.com/.+"],"http://www.twitvid.com/embed.php?guid=$1&autoplay=0",{templateRegex:/.*twitvid\.com\/(\w+).*/,embedtag:{tag:"iframe",width:480,height:360}}),new b.fn.oembed.OEmbedProvider("aniboom","video",
+["aniboom\\.com/animation-video/.+"],"http://api.aniboom.com/e/$1",{templateRegex:/.*animation-video\/(\d+).*/,embedtag:{width:594,height:334}}),new b.fn.oembed.OEmbedProvider("vzaar","video",["vzaar\\.com/videos/.+","vzaar.tv/.+"],"http://view.vzaar.com/$1/player?",{templateRegex:/.*\/(\d+).*/,embedtag:{tag:"iframe",width:576,height:324}}),new b.fn.oembed.OEmbedProvider("snotr","video",["snotr\\.com/video/.+"],"http://www.snotr.com/embed/$1",{templateRegex:/.*\/(\d+).*/,embedtag:{tag:"iframe",width:400,
+height:330,nocache:1}}),new b.fn.oembed.OEmbedProvider("youku","video",["v.youku.com/v_show/id_.+"],"http://player.youku.com/player.php/sid/$1/v.swf",{templateRegex:/.*id_(.+)\.html.*/,embedtag:{width:480,height:400,nocache:1}}),new b.fn.oembed.OEmbedProvider("tudou","video",["tudou.com/programs/view/.+/"],"http://www.tudou.com/v/$1/v.swf",{templateRegex:/.*view\/(.+)\//,embedtag:{width:480,height:400,nocache:1}}),new b.fn.oembed.OEmbedProvider("embedr","video",["embedr\\.com/playlist/.+"],"http://embedr.com/swf/slider/$1/425/520/default/false/std?",
+{templateRegex:/.*playlist\/([^\/]+).*/,embedtag:{width:425,height:520}}),new b.fn.oembed.OEmbedProvider("blip","video",["blip\\.tv/.+"],"http://blip.tv/oembed/"),new b.fn.oembed.OEmbedProvider("minoto-video","video",["http://api.minoto-video.com/publishers/.+/videos/.+","http://dashboard.minoto-video.com/main/video/details/.+","http://embed.minoto-video.com/.+"],"http://api.minoto-video.com/services/oembed.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("animoto","video",["animoto.com/play/.+"],
+"http://animoto.com/services/oembed"),new b.fn.oembed.OEmbedProvider("hulu","video",["hulu\\.com/watch/.*"],"http://www.hulu.com/api/oembed.json"),new b.fn.oembed.OEmbedProvider("ustream","video",["ustream\\.tv/recorded/.*"],"http://www.ustream.tv/oembed",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("videojug","video",["videojug\\.com/(film|payer|interview).*"],"http://www.videojug.com/oembed.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("sapo","video",["videos\\.sapo\\.pt/.*"],"http://videos.sapo.pt/oembed",
+{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("vodpod","video",["vodpod.com/watch/.*"],"http://vodpod.com/oembed.js",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("vimeo","video",["www.vimeo.com/groups/.*/videos/.*","www.vimeo.com/.*","vimeo.com/groups/.*/videos/.*","vimeo.com/.*"],"//vimeo.com/api/oembed.json"),new b.fn.oembed.OEmbedProvider("dailymotion","video",["dailymotion\\.com/.+"],"http://www.dailymotion.com/services/oembed"),new b.fn.oembed.OEmbedProvider("5min","video",["www\\.5min\\.com/.+"],
+"http://api.5min.com/oembed.xml",{useYQL:"xml"}),new b.fn.oembed.OEmbedProvider("National Film Board of Canada","video",["nfb\\.ca/film/.+"],"http://www.nfb.ca/remote/services/oembed/",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("qik","video",["qik\\.com/\\w+"],"http://qik.com/api/oembed.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("revision3","video",["revision3\\.com"],"http://revision3.com/api/oembed/"),new b.fn.oembed.OEmbedProvider("dotsub","video",["dotsub\\.com/view/.+"],"http://dotsub.com/services/oembed",
+{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("clikthrough","video",["clikthrough\\.com/theater/video/\\d+"],"http://clikthrough.com/services/oembed"),new b.fn.oembed.OEmbedProvider("Kinomap","video",["kinomap\\.com/.+"],"http://www.kinomap.com/oembed"),new b.fn.oembed.OEmbedProvider("VHX","video",["vhx.tv/.+"],"http://vhx.tv/services/oembed.json"),new b.fn.oembed.OEmbedProvider("bambuser","video",["bambuser.com/.+"],"http://api.bambuser.com/oembed/iframe.json"),new b.fn.oembed.OEmbedProvider("justin.tv",
+"video",["justin.tv/.+"],"http://api.justin.tv/api/embed/from_url.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("official.fm","rich",["official.fm/.+"],"http://official.fm/services/oembed",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("chirbit","rich",["chirb.it/.+"],"http://chirb.it/oembed.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("Huffduffer","rich",["huffduffer.com/[-.\\w@]+/\\d+"],"http://huffduffer.com/oembed"),new b.fn.oembed.OEmbedProvider("Spotify","rich",["open.spotify.com/(track|album|user)/"],
+"https://embed.spotify.com/oembed/"),new b.fn.oembed.OEmbedProvider("shoudio","rich",["shoudio.com/.+","shoud.io/.+"],"http://shoudio.com/api/oembed"),new b.fn.oembed.OEmbedProvider("mixcloud","rich",["mixcloud.com/.+"],m()+"www.mixcloud.com/oembed/",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("rdio.com","rich",["rd.io/.+","rdio.com"],m()+"www.rdio.com/api/oembed/"),new b.fn.oembed.OEmbedProvider("Soundcloud","rich",["soundcloud.com/.+","snd.sc/.+"],m()+"soundcloud.com/oembed",{format:"js"}),
+new b.fn.oembed.OEmbedProvider("bandcamp","rich",["bandcamp\\.com/album/.+"],null,{yql:{xpath:"//meta[contains(@content, \\'EmbeddedPlayer\\')]",from:"html",datareturn:function(a){return a.meta?'<iframe width="400" height="100" src="'+a.meta.content+'" allowtransparency="true" frameborder="0"></iframe>':!1}}}),new b.fn.oembed.OEmbedProvider("deviantart","photo",["deviantart.com/.+","fav.me/.+","deviantart.com/.+"],"http://backend.deviantart.com/oembed",{format:"jsonp"}),new b.fn.oembed.OEmbedProvider("skitch",
+"photo",["skitch.com/.+"],null,{yql:{xpath:"json",from:"json",url:function(a){return"http://skitch.com/oembed/?format=json&url="+a},datareturn:function(a){return b.fn.oembed.getPhotoCode(a.json.url,a.json)}}}),new b.fn.oembed.OEmbedProvider("mobypicture","photo",["mobypicture.com/user/.+/view/.+","moby.to/.+"],"http://api.mobypicture.com/oEmbed"),new b.fn.oembed.OEmbedProvider("flickr","photo",["flickr\\.com/photos/.+"],"http://flickr.com/services/oembed",{callbackparameter:"jsoncallback"}),new b.fn.oembed.OEmbedProvider("photobucket",
+"photo",["photobucket\\.com/(albums|groups)/.+"],m()+"photobucket.com/oembed/"),new b.fn.oembed.OEmbedProvider("instagram","photo",["instagr\\.?am(\\.com)?/.+"],m()+"api.instagram.com/oembed"),new b.fn.oembed.OEmbedProvider("SmugMug","photo",["smugmug.com/[-.\\w@]+/.+"],"http://api.smugmug.com/services/oembed/"),new b.fn.oembed.OEmbedProvider("dribbble","photo",["dribbble.com/shots/.+"],"http://api.dribbble.com/shots/$1?callback=?",{templateRegex:/.*shots\/([\d]+).*/,templateData:function(a){return a.image_teaser_url?
+'<img src="'+a.image_teaser_url+'"/>':!1}}),new b.fn.oembed.OEmbedProvider("chart.ly","photo",["chart\\.ly/[a-z0-9]{6,8}"],"http://chart.ly/uploads/large_$1.png",{templateRegex:/.*ly\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new b.fn.oembed.OEmbedProvider("circuitlab","photo",["circuitlab.com/circuit/.+"],"https://www.circuitlab.com/circuit/$1/screenshot/540x405/",{templateRegex:/.*circuit\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new b.fn.oembed.OEmbedProvider("23hq","photo",["23hq.com/[-.\\w@]+/photo/.+"],
+"http://www.23hq.com/23/oembed",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("img.ly","photo",["img\\.ly/.+"],"http://img.ly/show/thumb/$1",{templateRegex:/.*ly\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new b.fn.oembed.OEmbedProvider("twitgoo.com","photo",["twitgoo\\.com/.+"],"http://twitgoo.com/show/thumb/$1",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new b.fn.oembed.OEmbedProvider("imgur.com","photo",["imgur\\.com/gallery/.+"],m()+"imgur.com/$1l.jpg",{templateRegex:/.*gallery\/([^\/]+).*/,
+embedtag:{tag:"img"},nocache:1}),new b.fn.oembed.OEmbedProvider("visual.ly","rich",["visual\\.ly/.+"],null,{yql:{xpath:"//a[@id=\\'gc_article_graphic_image\\']/img",from:"htmlstring"}}),new b.fn.oembed.OEmbedProvider("gravtar","photo",["mailto:.+"],null,{templateRegex:/mailto:([^\/]+).*/,template:function(a,b){return'<img src="http://gravatar.com/avatar/'+b.md5()+'.jpg" alt="on Gravtar" class="jqoaImg">'}}),new b.fn.oembed.OEmbedProvider("twitter","rich",["twitter.com/.+"],"https://api.twitter.com/1/statuses/oembed.json?id="),
+new b.fn.oembed.OEmbedProvider("gmep","rich",["gmep.imeducate.com/.*","gmep.org/.*"],"http://gmep.org/oembed.json"),new b.fn.oembed.OEmbedProvider("urtak","rich",["urtak.com/(u|clr)/.+"],"http://oembed.urtak.com/1/oembed"),new b.fn.oembed.OEmbedProvider("cacoo","rich",["cacoo.com/.+"],"http://cacoo.com/oembed.json"),new b.fn.oembed.OEmbedProvider("dailymile","rich",["dailymile.com/people/.*/entries/.*"],"http://api.dailymile.com/oembed"),new b.fn.oembed.OEmbedProvider("dipity","rich",["dipity.com/timeline/.+"],
+"http://www.dipity.com/oembed/timeline/",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("sketchfab","rich",["sketchfab.com/show/.+"],"http://sketchfab.com/oembed",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("speakerdeck","rich",["speakerdeck.com/.+"],"http://speakerdeck.com/oembed.json",{useYQL:"json"}),new b.fn.oembed.OEmbedProvider("popplet","rich",["popplet.com/app/.*"],"http://popplet.com/app/Popplet_Alpha.swf?page_id=$1&em=1",{templateRegex:/.*#\/([^\/]+).*/,embedtag:{width:460,height:460}}),
+new b.fn.oembed.OEmbedProvider("pearltrees","rich",["pearltrees.com/.*"],"http://cdn.pearltrees.com/s/embed/getApp?",{templateRegex:/.*N-f=1_(\d+).*N-p=(\d+).*/,embedtag:{width:460,height:460,flashvars:"lang=en_US&amp;embedId=pt-embed-$1-693&amp;treeId=$1&amp;pearlId=$2&amp;treeTitle=Diagrams%2FVisualization&amp;site=www.pearltrees.com%2FF"}}),new b.fn.oembed.OEmbedProvider("prezi","rich",["prezi.com/.*"],"http://prezi.com/bin/preziloader.swf?",{templateRegex:/.*com\/([^\/]+)\/.*/,embedtag:{width:550,
+height:400,flashvars:"prezi_id=$1&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"}}),new b.fn.oembed.OEmbedProvider("tourwrist","rich",["tourwrist.com/tours/.+"],null,{templateRegex:/.*tours.([\d]+).*/,template:function(a,b){return setTimeout(function(){loadEmbeds&&loadEmbeds()},2E3),"<div id='"+b+"' class='tourwrist-tour-embed direct'></div> <script type='text/javascript' src='http://tourwrist.com/tour_embed.js'><\/script>"}}),new b.fn.oembed.OEmbedProvider("meetup","rich",
+["meetup\\.(com|ps)/.+"],m()+"api.meetup.com/oembed"),new b.fn.oembed.OEmbedProvider("ebay","rich",["ebay\\.*"],m()+"togo.ebay.com/togo/togo.swf?2008013100",{templateRegex:/.*\/([^\/]+)\/(\d{10,13}).*/,embedtag:{width:355,height:300,flashvars:"base=http://togo.ebay.com/togo/&lang=en-us&mode=normal&itemid=$2&query=$1"}}),new b.fn.oembed.OEmbedProvider("wikipedia","rich",["wikipedia.org/wiki/.+"],"http://$1.wikipedia.org/w/api.php?action=parse&page=$2&format=json&section=0&callback=?",{templateRegex:/.*\/\/([\w]+).*\/wiki\/([^\/]+).*/,
+templateData:function(a){if(!a.parse)return!1;var b=a.parse.text["*"].replace(/href="\/wiki/g,'href="http://en.wikipedia.org/wiki');return'<div id="content"><h3><a class="nav-link" href="http://en.wikipedia.org/wiki/'+a.parse.displaytitle+'">'+a.parse.displaytitle+"</a></h3>"+b+"</div>"}}),new b.fn.oembed.OEmbedProvider("imdb","rich",["imdb.com/title/.+"],"http://www.imdbapi.com/?i=$1&callback=?",{templateRegex:/.*\/title\/([^\/]+).*/,templateData:function(a){return a.Title?'<div id="content"><h3><a class="nav-link" href="http://imdb.com/title/'+
+a.ID+'/">'+a.Title+"</a> ("+a.Year+")</h3><p>Starring: "+a.Actors+'</p><div id="photo-wrap" style="margin: auto;width:600px;height:450px;"><img class="photo" id="photo-display" src="'+a.Poster+'" alt="'+a.Title+'"></div>  <div id="view-photo-caption">'+a.Plot+"</div></div>":!1}}),new b.fn.oembed.OEmbedProvider("livejournal","rich",["livejournal.com/"],"http://ljpic.seacrow.com/json/$2$4?jsonp=?",{templateRegex:/(http:\/\/(((?!users).)+)\.livejournal\.com|.*users\.livejournal\.com\/([^\/]+)).*/,templateData:function(a){return!!a.username&&
+'<div><img src="'+a.image+'" align="left" style="margin-right: 1em;" /><span class="oembedall-ljuser"><a href="http://'+a.username+'.livejournal.com/profile"><img src="http://www.livejournal.com/img/userinfo.gif" alt="[info]" width="17" height="17" /></a><a href="http://'+a.username+'.livejournal.com/">'+a.username+"</a></span><br />"+a.name+"</div>"}}),new b.fn.oembed.OEmbedProvider("circuitbee","rich",["circuitbee\\.com/circuit/view/.+"],"http://c.circuitbee.com/build/r/schematic-embed.html?id=$1",
+{templateRegex:/.*circuit\/view\/(\d+).*/,embedtag:{tag:"iframe",width:"500",height:"350"}}),new b.fn.oembed.OEmbedProvider("googlecalendar","rich",["www.google.com/calendar/embed?.+"],"$1",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"800",height:"600"}}),new b.fn.oembed.OEmbedProvider("jsfiddle","rich",["jsfiddle.net/[^/]+/?"],"http://jsfiddle.net/$1/embedded/result,js,resources,html,css/?",{templateRegex:/.*net\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"300"}}),new b.fn.oembed.OEmbedProvider("jsbin",
+"rich",["jsbin.com/.+"],"http://jsbin.com/$1/?",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"300"}}),new b.fn.oembed.OEmbedProvider("jotform","rich",["form.jotform.co/form/.+"],"$1?",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"100%",height:"507"}}),new b.fn.oembed.OEmbedProvider("reelapp","rich",["reelapp\\.com/.+"],"http://www.reelapp.com/$1/embed",{templateRegex:/.*com\/(\S{6}).*/,embedtag:{tag:"iframe",width:"400",height:"338"}}),new b.fn.oembed.OEmbedProvider("linkedin",
+"rich",["linkedin.com/pub/.+"],"https://www.linkedin.com/cws/member/public_profile?public_profile_url=$1&format=inline&isFramed=true",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"368px",height:"auto"}}),new b.fn.oembed.OEmbedProvider("timetoast","rich",["timetoast.com/timelines/[0-9]+"],"http://www.timetoast.com/flash/TimelineViewer.swf?passedTimelines=$1",{templateRegex:/.*timelines\/([0-9]*)/,embedtag:{width:550,height:400,nocache:1}}),new b.fn.oembed.OEmbedProvider("pastebin","rich",["pastebin\\.com/[\\S]{8}"],
+"http://pastebin.com/embed_iframe.php?i=$1",{templateRegex:/.*\/(\S{8}).*/,embedtag:{tag:"iframe",width:"100%",height:"auto"}}),new b.fn.oembed.OEmbedProvider("mixlr","rich",["mixlr.com/.+"],"http://mixlr.com/embed/$1?autoplay=ae",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"auto"}}),new b.fn.oembed.OEmbedProvider("pastie","rich",["pastie\\.org/pastes/.+"],null,{yql:{xpath:'//pre[@class="textmate-source"]'}}),new b.fn.oembed.OEmbedProvider("github","rich",["gist.github.com/.+"],
+"https://github.com/api/oembed"),new b.fn.oembed.OEmbedProvider("github","rich",["github.com/[-.\\w@]+/[-.\\w@]+"],"https://api.github.com/repos/$1/$2?callback=?",{templateRegex:/.*\/([^\/]+)\/([^\/]+).*/,templateData:function(a){return a.data.html_url?'<div class="oembedall-githubrepos"><ul class="oembedall-repo-stats"><li>'+a.data.language+'</li><li class="oembedall-watchers"><a title="Watchers" href="'+a.data.html_url+'/watchers">&#x25c9; '+a.data.watchers+'</a></li><li class="oembedall-forks"><a title="Forks" href="'+
+a.data.html_url+'/network">&#x0265; '+a.data.forks+'</a></li></ul><h3><a href="'+a.data.html_url+'">'+a.data.name+'</a></h3><div class="oembedall-body"><p class="oembedall-description">'+a.data.description+'</p><p class="oembedall-updated-at">Last updated: '+a.data.pushed_at+"</p></div></div>":!1}}),new b.fn.oembed.OEmbedProvider("facebook","rich",["facebook.com/(people/[^\\/]+/\\d+|[^\\/]+$)"],"https://graph.facebook.com/$2$3/?callback=?",{templateRegex:/.*facebook.com\/(people\/[^\/]+\/(\d+).*|([^\/]+$))/,
+templateData:function(a){if(!a.id)return!1;var b='<div class="oembedall-facebook1"><div class="oembedall-facebook2"><a href="http://www.facebook.com/">facebook</a> ';return b+=a.from?'<a href="http://www.facebook.com/'+a.from.id+'">'+a.from.name+"</a>":a.link?'<a href="'+a.link+'">'+a.name+"</a>":a.username?'<a href="http://www.facebook.com/'+a.username+'">'+a.name+"</a>":'<a href="http://www.facebook.com/'+a.id+'">'+a.name+"</a>",b+='</div><div class="oembedall-facebookBody"><div class="contents">',
+b+=a.picture?'<a href="'+a.link+'"><img src="'+a.picture+'"></a>':'<img src="https://graph.facebook.com/'+a.id+'/picture">',a.from&&(b+='<a href="'+a.link+'">'+a.name+"</a>"),a.founded&&(b+="Founded: <strong>"+a.founded+"</strong><br>"),a.category&&(b+="Category: <strong>"+a.category+"</strong><br>"),a.website&&(b+='Website: <strong><a href="'+a.website+'">'+a.website+"</a></strong><br>"),a.gender&&(b+="Gender: <strong>"+a.gender+"</strong><br>"),a.description&&(b+=a.description+"<br>"),b+"</div></div>"}}),
+new b.fn.oembed.OEmbedProvider("stackoverflow","rich",["stackoverflow.com/questions/[\\d]+"],"http://api.stackoverflow.com/1.1/questions/$1?body=true&jsonp=?",{templateRegex:/.*questions\/([\d]+).*/,templateData:function(a){if(!a.questions)return!1;var a=a.questions[0],e=b(a.body).text(),e='<div class="oembedall-stoqembed"><div class="oembedall-statscontainer"><div class="oembedall-statsarrow"></div><div class="oembedall-stats"><div class="oembedall-vote"><div class="oembedall-votes"><span class="oembedall-vote-count-post"><strong>'+
+(a.up_vote_count-a.down_vote_count)+'</strong></span><div class="oembedall-viewcount">vote(s)</div></div></div><div class="oembedall-status"><strong>'+a.answer_count+'</strong>answer</div></div><div class="oembedall-views">'+a.view_count+' view(s)</div></div><div class="oembedall-summary"><h3><a class="oembedall-question-hyperlink" href="http://stackoverflow.com/questions/'+a.question_id+'/">'+a.title+'</a></h3><div class="oembedall-excerpt">'+e.substring(0,100)+'...</div><div class="oembedall-tags">';
+for(i in a.tags)e+='<a title="" class="oembedall-post-tag" href="http://stackoverflow.com/questions/tagged/'+a.tags[i]+'">'+a.tags[i]+"</a>";return e+('</div><div class="oembedall-fr"><div class="oembedall-user-info"><div class="oembedall-user-gravatar32"><a href="http://stackoverflow.com/users/'+a.owner.user_id+"/"+a.owner.display_name+'"><img width="32" height="32" alt="" src="http://www.gravatar.com/avatar/'+a.owner.email_hash+'?s=32&amp;d=identicon&amp;r=PG"></a></div><div class="oembedall-user-details"><a href="http://stackoverflow.com/users/'+
+a.owner.user_id+"/"+a.owner.display_name+'">'+a.owner.display_name+'</a><br><span title="reputation score" class="oembedall-reputation-score">'+a.owner.reputation+"</span></div></div></div></div></div>")}}),new b.fn.oembed.OEmbedProvider("wordpress","rich",["wordpress\\.com/.+","blogs\\.cnn\\.com/.+","techcrunch\\.com/.+","wp\\.me/.+"],"http://public-api.wordpress.com/oembed/1.0/?for=jquery-oembed-all"),new b.fn.oembed.OEmbedProvider("screenr","rich",["screenr.com"],"http://www.screenr.com/embed/$1",
+{templateRegex:/.*\/([^\/]+).*/,embedtag:{tag:"iframe",width:"650",height:396}}),new b.fn.oembed.OEmbedProvider("gigpans","rich",["gigapan\\.org/[-.\\w@]+/\\d+"],"http://gigapan.org/gigapans/$1/options/nosnapshots/iframe/flash.html",{templateRegex:/.*\/(\d+)\/?.*/,embedtag:{tag:"iframe",width:"100%",height:400}}),new b.fn.oembed.OEmbedProvider("scribd","rich",["scribd\\.com/.+"],m()+"www.scribd.com/embeds/$1/content?start_page=1&view_mode=list",{templateRegex:/.*doc\/([^\/]+).*/,embedtag:{tag:"iframe",
+width:"100%",height:600}}),new b.fn.oembed.OEmbedProvider("kickstarter","rich",["kickstarter\\.com/projects/.+"],"$1/widget/card.html",{templateRegex:/([^\?]+).*/,embedtag:{tag:"iframe",width:"220",height:380}}),new b.fn.oembed.OEmbedProvider("amazon","rich",["amzn.com/B+","amazon.com.*/(B\\S+)($|\\/.*)"],m()+"rcm.amazon.com/e/cm?t=_APIKEY_&o=1&p=8&l=as1&asins=$1&ref=qf_br_asin_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr",{apikey:!0,templateRegex:/.*\/(B[0-9A-Z]+)($|\/.*)/,
+embedtag:{tag:"iframe",width:"120px",height:"240px"}}),new b.fn.oembed.OEmbedProvider("slideshare","rich",["slideshare.net"],m()+"www.slideshare.net/api/oembed/2",{format:"jsonp"}),new b.fn.oembed.OEmbedProvider("roomsharejp","rich",["roomshare\\.jp/(en/)?post/.*"],"http://roomshare.jp/oembed.json"),new b.fn.oembed.OEmbedProvider("lanyard","rich",["lanyrd.com/\\d+/.+"],null,{yql:{xpath:'(//div[@class="primary"])[1]',from:"htmlstring",datareturn:function(a){return a.result?'<div class="oembedall-lanyard">'+
+a.result+"</div>":!1}}}),new b.fn.oembed.OEmbedProvider("asciiartfarts","rich",["asciiartfarts.com/\\d+.html"],null,{yql:{xpath:"//pre/font",from:"htmlstring",datareturn:function(a){return a.result?'<pre style="background-color:000;">'+a.result+"</div>":!1}}}),new b.fn.oembed.OEmbedProvider("opengraph","rich",[".*"],null,{yql:{xpath:"//meta|//title|//link",from:"html",datareturn:function(a){var e,h,d;return(!a["og:title"]&&a.title&&a.description&&(a["og:title"]=a.title),!a["og:title"]&&!a.title)?
+!1:(e=b("<p/>"),a["og:video"]?(h=b('<embed src="'+a["og:video"]+'"/>'),h.attr("type",a["og:video:type"]||"application/x-shockwave-flash").css("max-height",j.maxHeight||"auto").css("max-width",j.maxWidth||"auto"),a["og:video:width"]&&h.attr("width",a["og:video:width"]),a["og:video:height"]&&h.attr("height",a["og:video:height"]),e.append(h)):a["og:image"]&&(d=b('<img src="'+a["og:image"]+'">'),d.css("max-height",j.maxHeight||"auto").css("max-width",j.maxWidth||"auto"),a["og:image:width"]&&d.attr("width",
+a["og:image:width"]),a["og:image:height"]&&d.attr("height",a["og:image:height"]),e.append(d)),a["og:title"]&&e.append("<b>"+a["og:title"]+"</b><br/>"),a["og:description"]?e.append(a["og:description"]+"<br/>"):a.description&&e.append(a.description+"<br/>"),e)}}})]})(jQuery);
+String.prototype.md5=function(){var b=function(b,m){var j=(b&65535)+(m&65535);return(b>>16)+(m>>16)+(j>>16)<<16|j&65535},m=function(e,m,j,a,l,h){e=b(b(m,e),b(a,h));return b(e<<l|e>>>32-l,j)},o=function(b,p,j,a,l,h,d){return m(p&j|~p&a,b,p,l,h,d)},q=function(b,p,j,a,l,h,d){return m(p&a|j&~a,b,p,l,h,d)},n=function(b,p,j,a,l,h,d){return m(j^(p|~a),b,p,l,h,d)};return function(b){for(var m="",j=4*b.length,a=0;a<j;a++)m+="0123456789abcdef".charAt(b[a>>2]>>8*(a%4)+4&15)+"0123456789abcdef".charAt(b[a>>2]>>
+8*(a%4)&15);return m}(function(e){for(var p,j,a,l,h=e.length,d=1732584193,c=-271733879,f=-1732584194,g=271733878,k=0;k<h;k+=16)p=d,j=c,a=f,l=g,d=o(d,c,f,g,e[k+0],7,-680876936),g=o(g,d,c,f,e[k+1],12,-389564586),f=o(f,g,d,c,e[k+2],17,606105819),c=o(c,f,g,d,e[k+3],22,-1044525330),d=o(d,c,f,g,e[k+4],7,-176418897),g=o(g,d,c,f,e[k+5],12,1200080426),f=o(f,g,d,c,e[k+6],17,-1473231341),c=o(c,f,g,d,e[k+7],22,-45705983),d=o(d,c,f,g,e[k+8],7,1770035416),g=o(g,d,c,f,e[k+9],12,-1958414417),f=o(f,g,d,c,e[k+10],
+17,-42063),c=o(c,f,g,d,e[k+11],22,-1990404162),d=o(d,c,f,g,e[k+12],7,1804603682),g=o(g,d,c,f,e[k+13],12,-40341101),f=o(f,g,d,c,e[k+14],17,-1502002290),c=o(c,f,g,d,e[k+15],22,1236535329),d=q(d,c,f,g,e[k+1],5,-165796510),g=q(g,d,c,f,e[k+6],9,-1069501632),f=q(f,g,d,c,e[k+11],14,643717713),c=q(c,f,g,d,e[k+0],20,-373897302),d=q(d,c,f,g,e[k+5],5,-701558691),g=q(g,d,c,f,e[k+10],9,38016083),f=q(f,g,d,c,e[k+15],14,-660478335),c=q(c,f,g,d,e[k+4],20,-405537848),d=q(d,c,f,g,e[k+9],5,568446438),g=q(g,d,c,f,e[k+
+14],9,-1019803690),f=q(f,g,d,c,e[k+3],14,-187363961),c=q(c,f,g,d,e[k+8],20,1163531501),d=q(d,c,f,g,e[k+13],5,-1444681467),g=q(g,d,c,f,e[k+2],9,-51403784),f=q(f,g,d,c,e[k+7],14,1735328473),c=q(c,f,g,d,e[k+12],20,-1926607734),d=m(c^f^g,d,c,e[k+5],4,-378558),g=m(d^c^f,g,d,e[k+8],11,-2022574463),f=m(g^d^c,f,g,e[k+11],16,1839030562),c=m(f^g^d,c,f,e[k+14],23,-35309556),d=m(c^f^g,d,c,e[k+1],4,-1530992060),g=m(d^c^f,g,d,e[k+4],11,1272893353),f=m(g^d^c,f,g,e[k+7],16,-155497632),c=m(f^g^d,c,f,e[k+10],23,-1094730640),
+d=m(c^f^g,d,c,e[k+13],4,681279174),g=m(d^c^f,g,d,e[k+0],11,-358537222),f=m(g^d^c,f,g,e[k+3],16,-722521979),c=m(f^g^d,c,f,e[k+6],23,76029189),d=m(c^f^g,d,c,e[k+9],4,-640364487),g=m(d^c^f,g,d,e[k+12],11,-421815835),f=m(g^d^c,f,g,e[k+15],16,530742520),c=m(f^g^d,c,f,e[k+2],23,-995338651),d=n(d,c,f,g,e[k+0],6,-198630844),g=n(g,d,c,f,e[k+7],10,1126891415),f=n(f,g,d,c,e[k+14],15,-1416354905),c=n(c,f,g,d,e[k+5],21,-57434055),d=n(d,c,f,g,e[k+12],6,1700485571),g=n(g,d,c,f,e[k+3],10,-1894986606),f=n(f,g,d,c,
+e[k+10],15,-1051523),c=n(c,f,g,d,e[k+1],21,-2054922799),d=n(d,c,f,g,e[k+8],6,1873313359),g=n(g,d,c,f,e[k+15],10,-30611744),f=n(f,g,d,c,e[k+6],15,-1560198380),c=n(c,f,g,d,e[k+13],21,1309151649),d=n(d,c,f,g,e[k+4],6,-145523070),g=n(g,d,c,f,e[k+11],10,-1120210379),f=n(f,g,d,c,e[k+2],15,718787259),c=n(c,f,g,d,e[k+9],21,-343485551),d=b(d,p),c=b(c,j),f=b(f,a),g=b(g,l);return[d,c,f,g]}(function(b){for(var m=(b.length+8>>6)+1,j=[],a=16*m,l=b.length,h=0;h<a;h++)j.push(0);for(a=0;a<l;a++)j[a>>2]|=(b.charCodeAt(a)&
+255)<<8*(a%4);return j[a>>2]|=128<<8*(a%4),j[16*m-2]=8*l,j}(this)))};
\ No newline at end of file
diff --git a/release/plugins/widget/images/handle.png b/release/plugins/widget/images/handle.png
new file mode 100644 (file)
index 0000000..ba8cda5
Binary files /dev/null and b/release/plugins/widget/images/handle.png differ
diff --git a/release/samples/css/samples.css b/release/samples/css/samples.css
new file mode 100644 (file)
index 0000000..f1973d0
--- /dev/null
@@ -0,0 +1,1632 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+@media (max-width: 900px) {\r
+  .global-is-mobile-hidden {\r
+    display: none !important;\r
+  }\r
+}\r
+article,\r
+aside,\r
+details,\r
+figcaption,\r
+figure,\r
+footer,\r
+header,\r
+hgroup,\r
+main,\r
+menu,\r
+nav,\r
+section {\r
+  display: block;\r
+}\r
+body,\r
+html {\r
+  margin: 0;\r
+  padding: 0;\r
+  font: 16px / 1.8 Arial, 'Helvetica Neue', Helvetica, sans-serif;\r
+  font-weight: 300;\r
+  color: #575757;\r
+}\r
+.grid-width-10 {\r
+  width: 10%;\r
+}\r
+.grid-width-20 {\r
+  width: 20%;\r
+}\r
+.grid-width-30 {\r
+  width: 30%;\r
+}\r
+.grid-width-40 {\r
+  width: 40%;\r
+}\r
+.grid-width-50 {\r
+  width: 50%;\r
+}\r
+.grid-width-60 {\r
+  width: 60%;\r
+}\r
+.grid-width-70 {\r
+  width: 70%;\r
+}\r
+.grid-width-80 {\r
+  width: 80%;\r
+}\r
+.grid-width-90 {\r
+  width: 90%;\r
+}\r
+.grid-width-100 {\r
+  width: 100%;\r
+}\r
+@media (max-width: 900px) {\r
+  .grid-width-10,\r
+  .grid-width-20,\r
+  .grid-width-30,\r
+  .grid-width-40,\r
+  .grid-width-50,\r
+  .grid-width-60,\r
+  .grid-width-70,\r
+  .grid-width-80,\r
+  .grid-width-90,\r
+  .grid-width-100 {\r
+    width: 100%;\r
+  }\r
+}\r
+*[class*="grid-width"] {\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+  padding-left: 4%;\r
+  padding-right: 4%;\r
+  float: left;\r
+}\r
+*[class*="grid-width"]:after,\r
+.grid-container:after,\r
+*[class*="grid-width"]:before,\r
+.grid-container:before {\r
+  content: '';\r
+  display: block;\r
+  overflow: hidden;\r
+  visibility: hidden;\r
+  font-size: 0;\r
+  line-height: 0;\r
+  width: 0;\r
+  height: 0;\r
+}\r
+*[class*="grid-width"]:after,\r
+.grid-container:after {\r
+  clear: both;\r
+}\r
+.grid-container {\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+  margin-left: auto;\r
+  margin-right: auto;\r
+}\r
+.grid-container-nested *[class*="grid-width"]:first-child {\r
+  padding-left: 0;\r
+}\r
+.grid-container-nested *[class*="grid-width"]:last-child {\r
+  padding-right: 0;\r
+}\r
+@media (max-width: 900px) {\r
+  .grid-container-nested *[class*="grid-width"]:first-child {\r
+    padding-left: 4%;\r
+  }\r
+  .grid-container-nested *[class*="grid-width"]:last-child {\r
+    padding-right: 4%;\r
+  }\r
+}\r
+.header-a {\r
+  min-height: 140px;\r
+  overflow: hidden;\r
+}\r
+.header-a .header-a-logo {\r
+  margin: 40px 0 0;\r
+}\r
+@media (max-width: 900px) {\r
+  .header-a .header-a-logo {\r
+    text-align: center;\r
+  }\r
+}\r
+.header-a .header-a-logo img {\r
+  border: transparent;\r
+}\r
+.navigation-a {\r
+  height: 30px;\r
+  background: #3D3D3D;\r
+  position: absolute;\r
+  left: 0;\r
+  right: 0;\r
+  top: 0;\r
+  padding: 0;\r
+  overflow: hidden;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-a {\r
+    text-align: center;\r
+  }\r
+}\r
+.navigation-a ul {\r
+  list-style: none;\r
+  margin: 0;\r
+  overflow: hidden;\r
+}\r
+.navigation-a ul li,\r
+.navigation-a ul li a {\r
+  display: inline-block;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-a ul {\r
+    width: auto;\r
+    text-overflow: ellipsis;\r
+    white-space: nowrap;\r
+    display: inline-block;\r
+    float: none;\r
+  }\r
+  .navigation-a ul:before,\r
+  .navigation-a ul:after {\r
+    display: none;\r
+  }\r
+}\r
+.navigation-a ul.navigation-a-left {\r
+  text-align: left;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-a ul.navigation-a-left {\r
+    padding-right: 0;\r
+  }\r
+}\r
+.navigation-a ul.navigation-a-right {\r
+  text-align: right;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-a ul.navigation-a-right {\r
+    padding-left: 23px;\r
+  }\r
+}\r
+.navigation-a ul li + li {\r
+  margin-left: 23px;\r
+}\r
+.navigation-a ul li a {\r
+  font-size: 10px;\r
+  font-size: 0.625rem;\r
+  line-height: 18px;\r
+  line-height: 1.13rem;\r
+  line-height: 30px;\r
+  float: left;\r
+  color: #ddd;\r
+  font-weight: bold;\r
+  text-decoration: none;\r
+  text-transform: uppercase;\r
+}\r
+.navigation-a ul li a:hover {\r
+  cursor: pointer;\r
+  color: #fff;\r
+}\r
+.icon-navigation-a-github:before,\r
+.icon-navigation-a-github:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAAXNSR0IArs4c6QAAAa9JREFUOBGNlM8rRGEUht0pDGosjKYZpUSIkuwsiCaxUEqK2VOUBcrWv2BjxUJho6wsLLDzY2fhD5iR5NeOcJvIjOfM3O927m3mmlPPnPec835nZprvjlVVJvL5fCOjMWiDCLzCLVxZlpUj/x8saYV9+IZS8UJzFWoCt2GYgk+oJG4wJUouZDANv5VsUZ47dNSzkEYHfIDEHixDWgoiB/rTHlPPwBNInPmXHRb7hdeUDFG10AN1Th1Fd5mD6BMwMVnoUyVA3t3EkjkQlDFfmwPkc7NsQTXf0bGgJWaGb16dk18+EmLYawzkC+6Q3KdK4kiZqtGdskx/kmdlCJS86RuGrDLFZJmtGi1KB0q+VhOGsDLZsiyjGsOY4qoOkrO+YUauwCDoOKWo9xk9JfM+MPdSzqZdA8UlyDO3AvKLPsIG9LsmBHUKduEHdCy6PrpJZyKXdwKMOemaissOHJ9O9xTeh57GluMYIsehWy8STW/d8ZhkI0b9PjFasA1fsAOb0KCN1PLXYyKLGNdzj2YYArnZDyDRrA3Ua4UuDzd5QM/KaoxhmAO5Om5Qt8OI2/CJP6MVa1dvltQ5AAAAAElFTkSuQmCC");\r
+}\r
+.navigation-b {\r
+  text-align: right;\r
+  margin: 52px 0 0;\r
+  overflow: visible;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-b {\r
+    text-align: center;\r
+    margin-top: 20px;\r
+    padding: 0;\r
+  }\r
+}\r
+.navigation-b ul {\r
+  padding: 0;\r
+  list-style: none;\r
+  margin: 0;\r
+  overflow: visible;\r
+}\r
+.navigation-b ul li,\r
+.navigation-b ul li a {\r
+  display: inline-block;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-b ul {\r
+    display: table;\r
+    width: 100%;\r
+    padding-bottom: 1.5em;\r
+  }\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-b ul li {\r
+    display: table-row;\r
+  }\r
+}\r
+.navigation-b ul li + li {\r
+  margin-left: 20px;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-b ul li + li {\r
+    margin-left: 0;\r
+  }\r
+}\r
+.navigation-b ul li a {\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+  text-transform: uppercase;\r
+  text-decoration: none;\r
+  outline: none;\r
+}\r
+@media (max-width: 900px) {\r
+  .navigation-b ul li a {\r
+    width: 100%;\r
+    -webkit-border-radius: 0;\r
+    -webkit-background-clip: padding-box;\r
+    -moz-border-radius: 0;\r
+    -moz-background-clip: padding;\r
+    border-radius: 0;\r
+    background-clip: padding-box;\r
+  }\r
+}\r
+.footer-a {\r
+  font-size: 13px;\r
+  font-size: 0.8125rem;\r
+  line-height: 23.4px;\r
+  line-height: 1.46rem;\r
+  padding-top: 2.25em;\r
+  padding-bottom: 2.25em;\r
+  overflow: hidden;\r
+  color: #8a8a8a;\r
+}\r
+.footer-a a {\r
+  color: #27C0D8;\r
+  text-decoration: none;\r
+  border-bottom: 1px dotted #27C0D8;\r
+}\r
+.footer-a a:hover {\r
+  color: #23adc2;\r
+}\r
+.footer-a p {\r
+  margin: 0;\r
+  display: inline-block;\r
+  text-align: center;\r
+}\r
+.content {\r
+  font-size: 14px;\r
+  font-size: 0.875rem;\r
+  line-height: 25.2px;\r
+  line-height: 1.57rem;\r
+  overflow: hidden;\r
+  padding-top: 1.5em;\r
+  padding-bottom: 1.5em;\r
+}\r
+.content p {\r
+  margin: 0.75em 0;\r
+}\r
+.content ul,\r
+.content ol,\r
+.content pre,\r
+.content blockquote,\r
+.content textarea:not([class^="cke"]),\r
+.content .cke {\r
+  margin: 1.875em 0;\r
+}\r
+.content code,\r
+.content kbd {\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  padding: 3px 4px;\r
+}\r
+.content pre,\r
+.content code,\r
+.content kbd,\r
+.content blockquote {\r
+  background: #f5f5f5;\r
+}\r
+.content blockquote,\r
+.content pre {\r
+  background: none;\r
+  border-left: 4px solid #27C0D8;\r
+  padding: 1.5em 2.25em;\r
+}\r
+.content p a,\r
+.content ul a,\r
+.content ol a,\r
+.content blockquote a,\r
+.content h1 a,\r
+.content h2 a,\r
+.content h3 a,\r
+.content h4 a,\r
+.content h5 a {\r
+  color: #27C0D8;\r
+  text-decoration: none;\r
+  border-bottom: 1px dotted #27C0D8;\r
+}\r
+.content p a:hover,\r
+.content ul a:hover,\r
+.content ol a:hover,\r
+.content blockquote a:hover,\r
+.content h1 a:hover,\r
+.content h2 a:hover,\r
+.content h3 a:hover,\r
+.content h4 a:hover,\r
+.content h5 a:hover {\r
+  color: #23adc2;\r
+}\r
+.content h1,\r
+.content h2,\r
+.content h3,\r
+.content h4,\r
+.content h5 {\r
+  color: #000;\r
+  font-weight: 100;\r
+}\r
+.content h1 code,\r
+.content h2 code,\r
+.content h3 code,\r
+.content h4 code,\r
+.content h5 code,\r
+.content h1 kbd,\r
+.content h2 kbd,\r
+.content h3 kbd,\r
+.content h4 kbd,\r
+.content h5 kbd {\r
+  font-size: inherit;\r
+}\r
+.content h1 a.content-heading-anchor,\r
+.content h2 a.content-heading-anchor,\r
+.content h3 a.content-heading-anchor,\r
+.content h4 a.content-heading-anchor,\r
+.content h5 a.content-heading-anchor {\r
+  font-weight: 100;\r
+  vertical-align: middle;\r
+  opacity: 0;\r
+  border: 0;\r
+}\r
+.content h1:hover a.content-heading-anchor,\r
+.content h2:hover a.content-heading-anchor,\r
+.content h3:hover a.content-heading-anchor,\r
+.content h4:hover a.content-heading-anchor,\r
+.content h5:hover a.content-heading-anchor {\r
+  opacity: 1;\r
+}\r
+.content h1:target a,\r
+.content h2:target a,\r
+.content h3:target a,\r
+.content h4:target a,\r
+.content h5:target a {\r
+  -webkit-animation: targetLinkOpacity 0.5s linear alternate;\r
+  -moz-animation: targetLinkOpacity 0.5s linear alternate;\r
+  -o-animation: targetLinkOpacity 0.5s linear alternate;\r
+  animation: targetLinkOpacity 0.5s linear alternate;\r
+  opacity: 1;\r
+}\r
+.content input,\r
+.content select,\r
+.content textarea:not([class^="cke"]) {\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);\r
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);\r
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);\r
+  font: inherit;\r
+  color: inherit;\r
+  border: 1px solid #D9D9D9;\r
+  padding: .2em .5em;\r
+}\r
+.content input:focus,\r
+.content select:focus,\r
+.content textarea:not([class^="cke"]):focus {\r
+  border-color: #66afe9;\r
+  outline: 0;\r
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;\r
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;\r
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;\r
+}\r
+.content abbr {\r
+  border-bottom: 1px dotted #666;\r
+  cursor: pointer;\r
+}\r
+.content blockquote {\r
+  font-style: italic;\r
+  font-family: Georgia, Times, "Times New Roman", serif;\r
+  font-size: 16px;\r
+  font-size: 1rem;\r
+  line-height: 28.8px;\r
+  line-height: 1.8rem;\r
+}\r
+.content em {\r
+  font-style: italic;\r
+}\r
+.content h1 {\r
+  font-size: 36px;\r
+  font-size: 2.25rem;\r
+  line-height: 64.8px;\r
+  line-height: 4.05rem;\r
+  margin: 1.125em 0 0;\r
+}\r
+.content h2 {\r
+  font-size: 27.2px;\r
+  font-size: 1.7rem;\r
+  line-height: 48.96px;\r
+  line-height: 3.06rem;\r
+  margin: 0.9em 0 0;\r
+}\r
+.content h3 {\r
+  font-size: 24px;\r
+  font-size: 1.5rem;\r
+  line-height: 43.2px;\r
+  line-height: 2.7rem;\r
+  font-weight: 500;\r
+  margin: 0.75em 0 0;\r
+}\r
+.content h4 {\r
+  font-size: 19.2px;\r
+  font-size: 1.2rem;\r
+  line-height: 34.56px;\r
+  line-height: 2.16rem;\r
+  font-weight: 500;\r
+  margin: 0.75em 0 0;\r
+}\r
+.content h5 {\r
+  font-size: 17.6px;\r
+  font-size: 1.1rem;\r
+  line-height: 31.68px;\r
+  line-height: 1.98rem;\r
+  font-weight: 500;\r
+  margin: 0.75em 0 0;\r
+}\r
+.content hr {\r
+  border: 0;\r
+  border-top: 4px solid #D9D9D9;\r
+  margin: 1.5em 0;\r
+}\r
+.content input[type="text"] {\r
+  height: 1.8em;\r
+  line-height: 1.8em;\r
+}\r
+.content input[type="button"] {\r
+  -webkit-appearance: button;\r
+  -moz-appearance: button;\r
+  appearance: button;\r
+}\r
+.content kbd {\r
+  font-size: 12px;\r
+  font-size: 0.75rem;\r
+  line-height: 21.6px;\r
+  line-height: 1.35rem;\r
+  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;\r
+  padding: 2px 6px;\r
+  -webkit-box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;\r
+  -moz-box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;\r
+  box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;\r
+}\r
+.content p img {\r
+  vertical-align: middle;\r
+}\r
+.content p pre {\r
+  padding: 1.5em;\r
+}\r
+.content pre {\r
+  padding: 0;\r
+  border: 0;\r
+  tab-size: 4;\r
+  -o-tab-size: 4;\r
+  -moz-tab-size: 4;\r
+}\r
+.content pre,\r
+.content code {\r
+  font-size: 11.89px;\r
+  font-size: 0.743rem;\r
+  line-height: 21.4px;\r
+  line-height: 1.34rem;\r
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;\r
+}\r
+.content pre a,\r
+.content code a {\r
+  border: 0;\r
+}\r
+.content pre code {\r
+  padding: 0.75em;\r
+  display: block;\r
+}\r
+.content strong {\r
+  color: #000;\r
+}\r
+.content ul ul,\r
+.content ol ul,\r
+.content ul ol,\r
+.content ol ol {\r
+  margin: 0.75em 0;\r
+}\r
+.content ul li,\r
+.content ol li {\r
+  font-size: 14px;\r
+  font-size: 0.875rem;\r
+  line-height: 30.24px;\r
+  line-height: 1.89rem;\r
+}\r
+.content textarea:not([class^="cke"]) {\r
+  width: 100%;\r
+}\r
+.content div.todo {\r
+  border: 2px dotted #444;\r
+  padding: 10px;\r
+  margin: 60px 0 10px 0;\r
+  /* Remove me some day */\r
+}\r
+.content div.todo:before {\r
+  content: "TODO";\r
+  font-weight: bold;\r
+}\r
+body a.button-a,\r
+body button.button-a,\r
+body input.button-a {\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  font-size: 14px;\r
+  font-size: 0.875rem;\r
+  line-height: 25.2px;\r
+  line-height: 1.57rem;\r
+  height: 36px;\r
+  line-height: 36px;\r
+  padding: 0 1.1em;\r
+  font-weight: 700;\r
+  color: #3e3e3e;\r
+  white-space: nowrap;\r
+  text-decoration: none;\r
+  display: inline-block;\r
+  cursor: pointer;\r
+  border: 0;\r
+  vertical-align: middle;\r
+  margin: 1px 0;\r
+  background: transparent;\r
+}\r
+body a.button-a.icon-pos-left,\r
+body button.button-a.icon-pos-left,\r
+body input.button-a.icon-pos-left {\r
+  padding-left: .8em;\r
+}\r
+body a.button-a.icon-pos-right,\r
+body button.button-a.icon-pos-right,\r
+body input.button-a.icon-pos-right {\r
+  padding-right: .8em;\r
+}\r
+body a.button-a.button-a-no-text,\r
+body button.button-a.button-a-no-text,\r
+body input.button-a.button-a-no-text {\r
+  -webkit-border-radius: 100px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 100px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 100px;\r
+  background-clip: padding-box;\r
+  width: 36px;\r
+  padding: 0;\r
+  text-indent: -999px;\r
+  overflow: hidden;\r
+  position: relative;\r
+  text-align: center;\r
+}\r
+body a.button-a.button-a-no-text:before,\r
+body button.button-a.button-a-no-text:before,\r
+body input.button-a.button-a-no-text:before {\r
+  position: absolute;\r
+  left: 50%;\r
+  top: 50%;\r
+  margin: -9px 0 0 -9px;\r
+}\r
+@media (max-width: 900px) {\r
+  body a.button-a.button-a-mobile-collapsed,\r
+  body button.button-a.button-a-mobile-collapsed,\r
+  body input.button-a.button-a-mobile-collapsed {\r
+    -webkit-border-radius: 100px;\r
+    -webkit-background-clip: padding-box;\r
+    -moz-border-radius: 100px;\r
+    -moz-background-clip: padding;\r
+    border-radius: 100px;\r
+    background-clip: padding-box;\r
+    width: 36px;\r
+    padding: 0;\r
+    text-indent: -999px;\r
+    overflow: hidden;\r
+    position: relative;\r
+    text-align: center;\r
+  }\r
+  body a.button-a.button-a-mobile-collapsed:before,\r
+  body button.button-a.button-a-mobile-collapsed:before,\r
+  body input.button-a.button-a-mobile-collapsed:before {\r
+    position: absolute;\r
+    left: 50%;\r
+    top: 50%;\r
+    margin: -9px 0 0 -9px;\r
+  }\r
+  body a.button-a.button-a-mobile-collapsed:before,\r
+  body button.button-a.button-a-mobile-collapsed:before,\r
+  body input.button-a.button-a-mobile-collapsed:before {\r
+    position: absolute;\r
+    left: 50%;\r
+    top: 50%;\r
+    margin: -9px 0 0 -9px;\r
+  }\r
+}\r
+body a.button-a:active,\r
+body button.button-a:active,\r
+body input.button-a:active,\r
+body a.button-a:hover,\r
+body button.button-a:hover,\r
+body input.button-a:hover {\r
+  color: #fff;\r
+  background: #23adc2;\r
+}\r
+body a.button-a:focus,\r
+body button.button-a:focus,\r
+body input.button-a:focus {\r
+  border-color: #66afe9;\r
+  outline: 0;\r
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;\r
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;\r
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;\r
+}\r
+body a.button-a-soft,\r
+body button.button-a-soft,\r
+body input.button-a-soft {\r
+  background: #e7e7e7;\r
+}\r
+body a.button-a-soft:active,\r
+body button.button-a-soft:active,\r
+body input.button-a-soft:active,\r
+body a.button-a-soft:hover,\r
+body button.button-a-soft:hover,\r
+body input.button-a-soft:hover {\r
+  color: #3e3e3e;\r
+  background: #cecece;\r
+}\r
+body a.button-a-background,\r
+body button.button-a-background,\r
+body input.button-a-background,\r
+body a.navigation-b ul li a:hover,\r
+body button.navigation-b ul li a:hover,\r
+body input.navigation-b ul li a:hover {\r
+  color: #fff;\r
+  background: #27C0D8;\r
+}\r
+body a.button-a-background:active,\r
+body button.button-a-background:active,\r
+body input.button-a-background:active,\r
+body a.button-a-background:hover,\r
+body button.button-a-background:hover,\r
+body input.button-a-background:hover,\r
+body a.navigation-b ul li a:hover:active,\r
+body button.navigation-b ul li a:hover:active,\r
+body input.navigation-b ul li a:hover:active,\r
+body a.navigation-b ul li a:hover:hover,\r
+body button.navigation-b ul li a:hover:hover,\r
+body input.navigation-b ul li a:hover:hover {\r
+  color: #fff;\r
+  background: #23adc2;\r
+}\r
+.balloon-a {\r
+  font-size: 12px;\r
+  font-size: 0.75rem;\r
+  line-height: 21.6px;\r
+  line-height: 1.35rem;\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  border-bottom: 3px solid #d4d4d4;\r
+  background: #ebebeb;\r
+  display: inline-block;\r
+  white-space: nowrap;\r
+  padding: .4em 1.2em .2em;\r
+  font-weight: 700;\r
+  position: relative;\r
+  z-index: 1000;\r
+  text-transform: none;\r
+  color: #575757;\r
+}\r
+.balloon-a:hover {\r
+  color: #575757;\r
+}\r
+.balloon-a:before {\r
+  content: '';\r
+  width: 0;\r
+  height: 0;\r
+  border-style: solid;\r
+  position: absolute;\r
+}\r
+.balloon-a-ne:before,\r
+.balloon-a-nw:before {\r
+  top: -13px;\r
+  border-width: 0 9px 15.6px 9px;\r
+  border-color: transparent transparent #ebebeb transparent;\r
+}\r
+.balloon-a-se:before,\r
+.balloon-a-sw:before {\r
+  bottom: -13px;\r
+  border-width: 15.6px 9px 0 9px;\r
+  border-color: #ebebeb transparent transparent transparent;\r
+}\r
+.balloon-a-nw:before,\r
+.balloon-a-sw:before {\r
+  left: 20px;\r
+}\r
+.balloon-a-ne:before,\r
+.balloon-a-se:before {\r
+  right: 20px;\r
+}\r
+.icon-pos-left:before,\r
+.icon-pos-right:after {\r
+  content: '';\r
+  display: inline-block;\r
+  width: 18px;\r
+  height: 18px;\r
+  vertical-align: middle;\r
+  background-repeat: no-repeat;\r
+}\r
+.icon-pos-left:before {\r
+  margin-right: 10px;\r
+}\r
+.icon-pos-right:after {\r
+  margin-left: 10px;\r
+}\r
+.icon-download:before,\r
+.icon-download:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAQFJREFUOBGtVDESgjAQBGfobHwE/AIa/AN/8EEWfMWGZ+gDaG2ws8BdyY13SRgGcGducre3WQ5NSJIIxnGsES3ijhhcMCdXR7ZYCqIc0SGWQE1ud7sKjRLxXHJQfWpLYwaCk6wxET/u+U2GIngd8yRViINau28bBH/YAGqvSQPhRNQHqBqj3FY0NKq27TW7qhSTDaCOhkaRAj7Hmm8S4V+c6C+gUa+crsizuWmoc70MKbWCnqPy2GvcUJxE4a/sIajRaGkU+/sf4IuISQGePR/T/QMbHEhwPLVnMWPuOCwGnWg41dwVeaN3ccHch70idIRi/6WV0WC2/zMiZm661R+2DxyEdjTuST3mAAAAAElFTkSuQmCC");\r
+}\r
+.icon-question-mark:before,\r
+.icon-question-mark:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAUhJREFUOBGllLFOAkEQhjk0WthT2JFA7Czsqc7OxFLewEeAZ/AVbO0tTLTSBKhstTBUNkYLEoVAbD2//zILe5e9uwCT/JnZmX/+m83ebq0WsCRJYnANxmBhUKxcHGjJpiC1wQBUmTjtbLetKHTAT5WCVxe3kxEjoUmKRL6pvYEZyJt6VpOxCG3nmfyx+yJxBM7BFPg2SDlkTv2sxZqi4YnUvfgswI9FuHAkzz9EUTTRmqYeTifXsvoj/s9i57oi6ljz9kviFdyBCbgHe+rCn4C8jVXQ18rshuKOiTSIXwLkRZWQTurARJrE7wERpea7kD7BkcgB+yB3CFGlPmgqCNiXhEagSGif2qU1Ln8FW/tupK3pXhXZrWNDuCoikY/rHPMT5KFr2MAPTSM90rIrUjJIeq1WV0RTwN7+0rrtILb9M+LEbLq1H7Z/Ea3+RvBddl0AAAAASUVORK5CYII=");\r
+}\r
+.icon-close:before,\r
+.icon-close:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAUlJREFUOBGllDFuwzAMRe3Cd+jYKUCzd/XkDtm9dsoVOuUqBnqBoodwgBwiW8ZsXTIWqPu+Iia0LMAoTOBbJEV+UZTkosjIMAwN6MARXCKky9dkUsYuglagB3OimNU4O1pM1OB7jsHNK7YekeFQJZ5kj/0LcnLA+RMnlHOvDMNv5wO7BFuQkn3hq0ALjKwPVeF4BSaqpLRy0T1ZIHFz75bE2BR8dBImqmBrwRplg09QmR/9GZyBSadAHauXCZkRROKURLlHEemepJIlIyhHotzLg1/N6erTxtmmvqA8muHGIbc1rTBqrEuwnqWnGbbmmz0hwaHtvM2QhWbrXZnosvnTWWPrdCY9w7cDJtf3h9VHjy5Zq9UZ08beyJh7Aicg6W/VYvgnIjJdNn9PMIOITJWcgnV9VvcnEitY/mitNFZZ/hsxsljdv39sfybRQ4R/kU0MAAAAAElFTkSuQmCC");\r
+}\r
+.ie8 .switch > * {\r
+  vertical-align: middle;\r
+}\r
+.ie8 .switch input[type="radio"] {\r
+  margin: 0 0.25em;\r
+  display: inline-block;\r
+}\r
+.ie8 .switch label {\r
+  margin-left: 0 !important;\r
+  margin-right: 0 !important;\r
+}\r
+.ie8 .switch label[data-for="1"] {\r
+  float: left;\r
+}\r
+.ie8 .switch label[data-for="2"] {\r
+  float: right;\r
+}\r
+.ie8 .switch .switch-inner {\r
+  display: none;\r
+}\r
+.switch {\r
+  font-size: 14px;\r
+  font-size: 0.875rem;\r
+  line-height: 25.2px;\r
+  line-height: 1.57rem;\r
+  font-weight: bold;\r
+  background-color: #27C0D8;\r
+  overflow: hidden;\r
+  display: inline-block;\r
+  padding: 0.75em 0.25em;\r
+  color: #fff;\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  position: relative;\r
+}\r
+.switch input[type="radio"] {\r
+  display: none;\r
+}\r
+.switch label {\r
+  position: relative;\r
+  z-index: 2;\r
+  float: left;\r
+  cursor: pointer;\r
+  padding: 0 0.75em;\r
+}\r
+.switch label:hover {\r
+  text-decoration: underline;\r
+}\r
+.switch .switch-inner {\r
+  float: left;\r
+  background-color: #FFF;\r
+  height: 1.5em;\r
+  width: 4.125em;\r
+  padding: 2px;\r
+  margin: 0 0.25em;\r
+  -webkit-border-radius: 5.5px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 5.5px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 5.5px;\r
+  background-clip: padding-box;\r
+}\r
+.switch .switch-inner .handler {\r
+  overflow: hidden;\r
+  position: relative;\r
+  display: block;\r
+  height: 1.5em;\r
+  width: 1.5em;\r
+  background: #25b4cb;\r
+  -webkit-border-radius: 4.5px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 4.5px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 4.5px;\r
+  background-clip: padding-box;\r
+}\r
+.switch .switch-inner .handler:before {\r
+  content: '';\r
+  display: block;\r
+  position: absolute;\r
+  top: 0;\r
+  right: 0;\r
+  bottom: 3px;\r
+  left: 0;\r
+  background-color: #34c4da;\r
+  -webkit-border-bottom-left-radius: 4.5px;\r
+  -moz-border-radius-bottomleft: 4.5px;\r
+  border-bottom-left-radius: 4.5px;\r
+  -webkit-border-bottom-right-radius: 4.5px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius-bottomright: 4.5px;\r
+  -moz-background-clip: padding;\r
+  border-bottom-right-radius: 4.5px;\r
+  background-clip: padding-box;\r
+}\r
+.switch:hover .switch-inner .handler:before {\r
+  background: #45c9dd;\r
+}\r
+.switch input[data-num="2"]:checked ~ .switch-inner > .handler {\r
+  margin-left: auto;\r
+}\r
+.switch input[data-num="2"]:checked ~ label[data-for="1"] {\r
+  padding-right: 5.125em;\r
+  margin-right: -4.375em;\r
+}\r
+.switch input[data-num="1"]:checked ~ label[data-for="2"] {\r
+  padding-left: 5.125em;\r
+  margin-left: -4.375em;\r
+}\r
+.toggler {\r
+  -webkit-user-select: none;\r
+  -moz-user-select: none;\r
+  -ms-user-select: none;\r
+  user-select: none;\r
+}\r
+.toggler label {\r
+  cursor: pointer;\r
+}\r
+.toggler [data-collapse] {\r
+  display: inherit;\r
+}\r
+.toggler [data-expand] {\r
+  display: none;\r
+}\r
+.toggler.collapsed [data-collapse] {\r
+  display: none;\r
+}\r
+.toggler.collapsed [data-expand] {\r
+  display: inherit;\r
+}\r
+.toggler-container {\r
+  overflow: hidden;\r
+}\r
+.toggler-container.collapsed {\r
+  height: 0;\r
+}\r
+.icon-toggler-expanded:before,\r
+.icon-toggler-collapsed:before,\r
+.icon-toggler-expanded:after,\r
+.icon-toggler-collapsed:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAByCAYAAABeOoENAAAAAXNSR0IArs4c6QAAAbxJREFUaAXtmT1KBEEQhRdFQdBEMfQEBoaGopl3MfECXsFERLyBh/AUIuwJDEUQM//eB11Dz1A1uzotGFTBY2rr58306+kNpmazP7Z98V8Kj8JrAT4xcgttXRVXwofwFYAcNdS6RuJegOBTuBUOhc0CfGLkqKHWJeMuFDwJJ0Jk5Kihlp6esW4embuNkVgTNdTS09MMEbkDj76sUUsPvZ2xIwTRATsQuBuxGsTIYdSSo7cztpggwprdyKlJ8ImZUUuM3s48ol1lXwQjwydm5hINl2bF53KMCL82d2mR2GvqnBfg1+aKPbb9p+oGtYXbT1GTFxKiZkfEyHgy7x0y0clR454zSGpDMzaA3fzV30hNln4qkAqkAqlAKpAKpAKpQCqQCqQCqUAqkAqkAqlAKpAKpAKpQCrw3xWY/GGcz++TP9U3Gx40GWdEAxabXA33NBywRCOfdzFcCztDJv12Rz7REMpmIc9qPBNWK0J3COWNxegxIrs+KHZcyHpjsZUSXPaypcLtseJFS3tT84WwUZG4S4vEZkl3wl5FYK4rdrT9R9Y1uIbbT12TFxKiZkfEyCYfWojMJv+NGNGPr99GI9DP7P9TCgAAAABJRU5ErkJggg==");\r
+}\r
+.icon-toggler-expanded.icon-light:before,\r
+.icon-toggler-collapsed.icon-light:before,\r
+.icon-toggler-expanded.icon-light:after,\r
+.icon-toggler-collapsed.icon-light:after {\r
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAByCAYAAABeOoENAAAAAXNSR0IArs4c6QAAAcVJREFUaAXtmT9KA1EQxhMlASE2SkpPkCJlStHOu3gGwRPYBAm5gYfwFBKwtrARRAh26vr7ljfx7TrLChtBcAa+zOSbPy/7vcTC6fV+04qimIArsALrBMXiJq1nUzQEc/AOmkw51QzdgUqAWyD7AEswA6MExeKUk6n2+zBInSJ7BKfuaZDKpRpcMa/UQUgTfWSd1jjEmlSTatXzpRlvJKJsacVtXrVlB72bWgjdiGwmEj8FOq1u4qapRprJVvkgXbFsZCTxomSqL4ssr0uQrY3TJ/AGjeFfVJlM8diaiCuDdlLiIfmNcP1+/wnu0hoVJ84oq7XeUhNXbE4dgPuEgU2Qh3PFbrx+Gs6E2hD/+tMJ3b+QadB2fiLZsG4/2poG3f6M5MMiDgVCgVAgFAgFQoFQIBQIBUKBUCAUCAVCgVAgFAgFQoFQIBQIBf66AiwLuv1jnAH/Zb/Go5abq/qdwvsLFhJNK583ctfg0Bnmrnwq+zVrYoDZM8E52M1yP9uvqcGmZP6O+CTl3LWYHdTm9yk4aCzilLZHe6XmAuzZEGL30ZrEpr64AUc2wDycK7a7X6P42BpzD+9fv4pIxn4tWznnwm0r/gQpiG1tFshTowAAAABJRU5ErkJggg==");\r
+}\r
+.icon-toggler-expanded:before,\r
+.icon-toggler-expanded:after {\r
+  background-position: top left;\r
+}\r
+.icon-toggler-collapsed:before,\r
+.icon-toggler-collapsed:after {\r
+  background-position: bottom left;\r
+}\r
+.modal {\r
+  padding: 20px;\r
+  border-radius: 3px;\r
+  background-color: white;\r
+  max-width: 700px;\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+  width: 80% !important;\r
+  top: 50% !important;\r
+  -webkit-transform: translate(-50%, -50%) !important;\r
+  -moz-transform: translate(-50%, -50%) !important;\r
+  -o-transform: translate(-50%, -50%) !important;\r
+  -ms-transform: translate(-50%, -50%) !important;\r
+  transform: translate(-50%, -50%) !important;\r
+}\r
+.modal-close {\r
+  -webkit-border-radius: 100px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 100px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 100px;\r
+  background-clip: padding-box;\r
+  cursor: pointer;\r
+  height: 18px;\r
+  width: 18px;\r
+  position: absolute;\r
+  top: 10px;\r
+  right: 10px;\r
+  font-size: 17px;\r
+  text-align: center;\r
+  line-height: 19px;\r
+  background: #cccccc;\r
+}\r
+main .grid-container,\r
+header .grid-container,\r
+.navigation-a > div,\r
+footer > div {\r
+  max-width: 968px;\r
+}\r
+.header-a {\r
+  margin-top: 30px;\r
+}\r
+.footer-a {\r
+  border-top: 1px solid #D9D9D9;\r
+}\r
+.adjoined-top {\r
+  background-color: #27C0D8;\r
+  color: #fff;\r
+}\r
+.adjoined-top .content h1,\r
+.adjoined-top .content h2,\r
+.adjoined-top .content h3,\r
+.adjoined-top .content h4,\r
+.adjoined-top .content h5 {\r
+  color: #fff;\r
+}\r
+.adjoined-top .content p {\r
+  font-size: 18px;\r
+  font-size: 1.125rem;\r
+  line-height: 32.4px;\r
+  line-height: 2.02rem;\r
+  font-weight: 100;\r
+}\r
+.adjoined-top .content p a {\r
+  text-decoration: none;\r
+  border-bottom: 1px dotted #fff;\r
+  color: inherit;\r
+}\r
+.adjoined-top .content p a:hover {\r
+  color: #e6e6e6;\r
+}\r
+.adjoined-top .content button {\r
+  color: #fff;\r
+}\r
+.adjoined-top .content strong {\r
+  color: #fff;\r
+}\r
+.adjoined-top .content code {\r
+  font-size: inherit;\r
+  color: #27C0D8;\r
+}\r
+.adjoined-bottom {\r
+  position: relative;\r
+}\r
+.adjoined-bottom:before {\r
+  z-index: -1;\r
+  content: '';\r
+  background: #27C0D8;\r
+  position: absolute;\r
+  top: 0;\r
+  left: 0;\r
+  right: 0;\r
+  height: 50%;\r
+}\r
+main .grid-container,\r
+header .grid-container,\r
+.navigation-a > div,\r
+footer > div {\r
+  max-width: 1052px;\r
+}\r
+main .grid-container.freed-width {\r
+  max-width: none;\r
+}\r
+.switch {\r
+  background: #25b4cb;\r
+  float: right;\r
+  overflow: visible;\r
+}\r
+.switch .balloon-a {\r
+  position: absolute;\r
+  top: -40px;\r
+  right: 50%;\r
+  margin-right: -15px;\r
+  background: #FFEFC1;\r
+  border-bottom-color: #DCDCA4;\r
+}\r
+.switch .balloon-a:before {\r
+  border-color: #FFEFC1 transparent transparent transparent;\r
+}\r
+#toolbar .editors-container {\r
+  overflow: hidden;\r
+  height: 0;\r
+  transition: height 200ms;\r
+}\r
+#toolbar .editors-container.active {\r
+  height: auto;\r
+}\r
+#main #editor {\r
+  background: #FFF;\r
+  padding: 2% 4%;\r
+  border: dashed 5px #27C0D8;\r
+}\r
+#main .adjoined-top:before {\r
+  height: 335px;\r
+}\r
+#toolbar .adjoined-top:before {\r
+  height: 219px;\r
+}\r
+#toolbar .adjoined-top .grid-container-nested {\r
+  height: 147px;\r
+}\r
+.content .grid-switch-magic {\r
+  margin: 3.5em 0 0;\r
+}\r
+#info-box {\r
+  padding-bottom: 0;\r
+}\r
+#info-box > div {\r
+  width: 100%;\r
+  text-align: right;\r
+}\r
+#info-box > div .toggler {\r
+  padding-right: 0;\r
+}\r
+#info-box > div .toggler:hover {\r
+  background: transparent;\r
+  color: #000;\r
+}\r
+#info-box > div .toggler:hover > label {\r
+  text-decoration: underline;\r
+}\r
+#info-box > div h2 {\r
+  float: left;\r
+  margin-top: 0;\r
+}\r
+#info-box > div#instructions-container {\r
+  text-align: left;\r
+}\r
+#toolbarModifierWrapper {\r
+  overflow: hidden;\r
+  height: 0;\r
+  opacity: 0;\r
+  transition: height 200ms;\r
+}\r
+#toolbarModifierWrapper.active {\r
+  height: auto;\r
+  opacity: 1;\r
+}\r
+header {\r
+  overflow: visible;\r
+}\r
+header div.grid-container {\r
+  overflow: visible;\r
+}\r
+header .navigation-b {\r
+  overflow: visible;\r
+}\r
+header .navigation-b ul {\r
+  overflow: visible;\r
+}\r
+header .navigation-b a {\r
+  position: relative;\r
+}\r
+header .balloon-a {\r
+  position: absolute;\r
+  top: 48px;\r
+  left: 50%;\r
+  margin-left: -35px;\r
+}\r
+@media (max-width: 1140px) {\r
+  header .balloon-a {\r
+    left: auto;\r
+    margin-left: auto;\r
+    right: 50%;\r
+    margin-right: -35px;\r
+  }\r
+  header .balloon-a:before {\r
+    left: auto;\r
+    right: 22px;\r
+  }\r
+}\r
+@media (max-width: 900px) {\r
+  header .balloon-a {\r
+    display: none;\r
+  }\r
+}\r
+#toolbar .cke_toolbar {\r
+  pointer-events: none;\r
+  -webkit-user-select: none;\r
+  -moz-user-select: none;\r
+  -ms-user-select: none;\r
+  user-select: none;\r
+  cursor: default;\r
+}\r
+.some-toolbar-active .cke_toolbar {\r
+  zoom: 1;\r
+  filter: alpha(opacity=50);\r
+  -webkit-opacity: 0.5;\r
+  -moz-opacity: 0.5;\r
+  opacity: 0.5;\r
+}\r
+.cke_toolbar.active {\r
+  position: relative;\r
+  zoom: 1;\r
+  filter: alpha(opacity=100);\r
+  -webkit-opacity: 1;\r
+  -moz-opacity: 1;\r
+  opacity: 1;\r
+}\r
+.cke_toolbar.active:after {\r
+  content: '';\r
+  display: block;\r
+  position: absolute;\r
+  top: 0;\r
+  right: 6px;\r
+  bottom: 5px;\r
+  left: 0;\r
+  -webkit-border-radius: 5px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 5px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 5px;\r
+  background-clip: padding-box;\r
+  -webkit-box-shadow: 0px 0px 15px 3px #fff4b0;\r
+  -moz-box-shadow: 0px 0px 15px 3px #fff4b0;\r
+  box-shadow: 0px 0px 15px 3px #fff4b0;\r
+}\r
+.cke_toolbar.active .cke_toolgroup {\r
+  -webkit-box-shadow: none;\r
+  -moz-box-shadow: none;\r
+  box-shadow: none;\r
+  border-color: #e3c300;\r
+}\r
+.cke_toolbar.active .cke_combo,\r
+.cke_toolbar.active .cke_toolgroup {\r
+  position: relative;\r
+  z-index: 2;\r
+}\r
+.cke_toolbar.active .cke_combo_button {\r
+  -webkit-box-shadow: none;\r
+  -moz-box-shadow: none;\r
+  box-shadow: none;\r
+}\r
+.unselectable {\r
+  -webkit-user-select: none;\r
+  -moz-user-select: none;\r
+  -ms-user-select: none;\r
+  user-select: none;\r
+}\r
+.toolbar {\r
+  padding: 5px 0;\r
+  margin-bottom: 2.4em;\r
+  overflow: hidden;\r
+  background: #fff;\r
+}\r
+.toolbar button.button-a.cke_button {\r
+  cursor: pointer;\r
+  display: inline-block;\r
+  padding: 4px 6px;\r
+  outline: 0;\r
+  border: 1px solid #a6a6a6;\r
+}\r
+.toolbar button.button-a.hidden {\r
+  display: none;\r
+}\r
+.toolbar button.button-a.left {\r
+  float: left;\r
+  margin-right: 8px;\r
+}\r
+.toolbar button.button-a.right {\r
+  float: right;\r
+  margin-left: 8px;\r
+}\r
+.toolbar button.button-a .highlight {\r
+  color: #ffefc1;\r
+}\r
+.configContainer.hidden,\r
+.toolbarModifier.hidden,\r
+.toolbarModifier-hints.hidden {\r
+  display: none;\r
+}\r
+.toolbarModifier :focus,\r
+.toolbar button:focus,\r
+.configContainer textarea.configCode:focus {\r
+  outline: none;\r
+}\r
+div.toolbarModifier {\r
+  padding: 0;\r
+  overflow: hidden;\r
+  width: 100%;\r
+  position: relative;\r
+  display: table;\r
+  border-collapse: collapse;\r
+}\r
+div.toolbarModifier ::-moz-focus-inner {\r
+  border: 0;\r
+}\r
+div.toolbarModifier .empty {\r
+  display: none;\r
+}\r
+div.toolbarModifier.empty-visible .empty {\r
+  display: table-row;\r
+  zoom: 1;\r
+  filter: alpha(opacity=60);\r
+  -webkit-opacity: 0.6;\r
+  -moz-opacity: 0.6;\r
+  opacity: 0.6;\r
+}\r
+div.toolbarModifier .empty > p {\r
+  line-height: 31px;\r
+}\r
+div.toolbarModifier > ul {\r
+  padding: 0;\r
+  margin: 0;\r
+  border-top: 1px solid #ccc;\r
+  width: 100%;\r
+}\r
+div.toolbarModifier > ul[data-type="table-header"] {\r
+  display: table-header-group;\r
+}\r
+div.toolbarModifier > ul[data-type="table-body"] {\r
+  display: table-row-group;\r
+}\r
+div.toolbarModifier > ul p {\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+div.toolbarModifier > ul > li {\r
+  display: table-row;\r
+}\r
+div.toolbarModifier > ul > li[data-type="header"] {\r
+  font-weight: bold;\r
+  user-select: none;\r
+  cursor: default;\r
+}\r
+div.toolbarModifier > ul > li[data-type="group"],\r
+div.toolbarModifier > ul > li[data-type="separator"] {\r
+  border-bottom: 1px solid #ccc;\r
+}\r
+div.toolbarModifier > ul > li[data-type="subgroup"] {\r
+  border-top: 1px solid #eee;\r
+}\r
+div.toolbarModifier > ul > li[data-type="subgroup"]:first-child {\r
+  border-top: none;\r
+}\r
+div.toolbarModifier > ul > li[data-type="group"].active,\r
+div.toolbarModifier > ul > li[data-type="group"]:hover,\r
+div.toolbarModifier > ul > li[data-type="separator"].active,\r
+div.toolbarModifier > ul > li[data-type="separator"]:hover {\r
+  overflow: hidden;\r
+  z-index: 2;\r
+}\r
+div.toolbarModifier > ul > li[data-type="group"].active,\r
+div.toolbarModifier > ul > li[data-type="separator"].active,\r
+div.toolbarModifier > ul > li[data-type="group"].active:hover,\r
+div.toolbarModifier > ul > li[data-type="separator"].active:hover {\r
+  background: #f0fafb;\r
+}\r
+div.toolbarModifier > ul > li[data-type="group"]:hover,\r
+div.toolbarModifier > ul > li[data-type="separator"]:hover {\r
+  background: #fffbe3;\r
+}\r
+div.toolbarModifier > ul > li[data-type="separator"] {\r
+  background: #f5f5f5;\r
+}\r
+div.toolbarModifier > ul > li[data-type="separator"]:after {\r
+  content: '';\r
+  width: 100%;\r
+}\r
+div.toolbarModifier > ul > li[data-type="separator"] > p {\r
+  padding: 2px 5px;\r
+}\r
+div.toolbarModifier > ul > li > p,\r
+div.toolbarModifier > ul > li > ul {\r
+  display: table-cell;\r
+  vertical-align: middle;\r
+}\r
+div.toolbarModifier > ul > li p {\r
+  padding-left: 5px;\r
+  min-width: 200px;\r
+}\r
+div.toolbarModifier > ul > li p span {\r
+  white-space: nowrap;\r
+  cursor: default;\r
+}\r
+div.toolbarModifier > ul > li p span button {\r
+  font-size: 12.666px;\r
+  margin-right: 5px;\r
+  cursor: pointer;\r
+  background: #fff;\r
+  -webkit-border-radius: 5px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 5px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 5px;\r
+  background-clip: padding-box;\r
+  border: 1px solid #bbb;\r
+  padding: 0 7px;\r
+  line-height: 12px;\r
+  height: 20px;\r
+}\r
+div.toolbarModifier > ul > li p span button:not(.disabled):hover,\r
+div.toolbarModifier > ul > li p span button:not(.disabled):focus {\r
+  color: #fff;\r
+  background-color: #454545;\r
+  border-color: transparent;\r
+}\r
+div.toolbarModifier > ul > li p span button.move.disabled {\r
+  cursor: default;\r
+  zoom: 1;\r
+  filter: alpha(opacity=20);\r
+  -webkit-opacity: 0.2;\r
+  -moz-opacity: 0.2;\r
+  opacity: 0.2;\r
+}\r
+div.toolbarModifier > ul > li ul {\r
+  border-collapse: collapse;\r
+  padding: 0;\r
+  width: 100%;\r
+}\r
+div.toolbarModifier > ul > li ul li {\r
+  display: table-row;\r
+  list-style-type: none;\r
+  line-height: 1;\r
+}\r
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] {\r
+  border-top: 1px solid #ddd;\r
+}\r
+div.toolbarModifier > ul > li ul li[data-type="subgroup"]:first-child {\r
+  border-top: 0;\r
+}\r
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"] {\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  padding: 0 2px;\r
+}\r
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"]:focus {\r
+  background: rgba(0, 0, 0, 0.04);\r
+}\r
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"] input {\r
+  vertical-align: middle;\r
+}\r
+div.toolbarModifier > ul > li ul li > p,\r
+div.toolbarModifier > ul > li ul li > ul {\r
+  display: table-cell;\r
+  vertical-align: middle;\r
+}\r
+div.toolbarModifier > ul > li ul li ul {\r
+  padding: 0;\r
+}\r
+div.toolbarModifier > ul > li ul li ul li {\r
+  padding: 0;\r
+  display: inline-block;\r
+  cursor: pointer;\r
+  margin: 2px 5px 2px 0;\r
+}\r
+div.toolbarModifier > ul > li ul li ul li .cke_combo_text {\r
+  cursor: pointer;\r
+  white-space: nowrap;\r
+}\r
+div.toolbarModifier > ul > li ul li ul li .cke_toolgroup,\r
+div.toolbarModifier > ul > li ul li ul li .cke_combo_button {\r
+  cursor: pointer;\r
+  margin: 0;\r
+  vertical-align: middle;\r
+  border: 1px solid #ddd;\r
+  font-size: 11.41px;\r
+  font-size: 0.713rem;\r
+  line-height: 20.54px;\r
+  line-height: 1.28rem;\r
+}\r
+div.toolbarModifier > .codemirror-wrapper {\r
+  overflow-y: auto;\r
+}\r
+div.toolbarModifier-hints {\r
+  float: right;\r
+  width: 350px;\r
+  min-width: 150px;\r
+  overflow-y: auto;\r
+  margin-left: 1.5em;\r
+}\r
+div.toolbarModifier-hints h3 {\r
+  font-size: 18.08px;\r
+  font-size: 1.13rem;\r
+  line-height: 32.54px;\r
+  line-height: 2.03rem;\r
+  padding: 0.36em 1.5em;\r
+  background: #f5f5f5;\r
+  border-bottom: 1px solid #ddd;\r
+  margin-top: 0;\r
+  margin-bottom: 1.2em;\r
+}\r
+div.toolbarModifier-hints dl {\r
+  margin-bottom: 1.2em;\r
+  overflow: hidden;\r
+}\r
+div.toolbarModifier-hints dl .list-header {\r
+  font-weight: bold;\r
+  border: 0;\r
+  padding-bottom: 0.6em;\r
+}\r
+div.toolbarModifier-hints dl > p {\r
+  text-align: center;\r
+}\r
+div.toolbarModifier-hints dl dt {\r
+  float: left;\r
+  width: 9em;\r
+  clear: both;\r
+  text-align: right;\r
+  border-top: 1px solid #ddd;\r
+  padding-left: 1.5em;\r
+  padding-right: .1em;\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+}\r
+div.toolbarModifier-hints dl dt code {\r
+  background: none;\r
+  border: none;\r
+  vertical-align: middle;\r
+}\r
+div.toolbarModifier-hints dl dd {\r
+  margin-left: 10em;\r
+  clear: right;\r
+  padding-right: 1.5em;\r
+}\r
+div.toolbarModifier-hints dl dd code {\r
+  line-height: 2.2em;\r
+}\r
+div.toolbarModifier-hints dl dd:after {\r
+  content: '\00a0';\r
+  display: block;\r
+  clear: left;\r
+  float: right;\r
+  height: 0;\r
+  width: 0;\r
+}\r
+.toolbarModifier-hints,\r
+.configContainer textarea.configCode,\r
+.CodeMirror {\r
+  -webkit-border-radius: 3px;\r
+  -webkit-background-clip: padding-box;\r
+  -moz-border-radius: 3px;\r
+  -moz-background-clip: padding;\r
+  border-radius: 3px;\r
+  background-clip: padding-box;\r
+  border: 1px solid #ccc;\r
+  font-size: 13.01px;\r
+  font-size: 0.813rem;\r
+  line-height: 23.42px;\r
+  line-height: 1.46rem;\r
+}\r
+.configContainer textarea.configCode,\r
+.CodeMirror pre,\r
+.CodeMirror-linenumber {\r
+  font-size: 13.01px;\r
+  font-size: 0.813rem;\r
+  line-height: 23.42px;\r
+  line-height: 1.46rem;\r
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;\r
+}\r
+.CodeMirror pre {\r
+  border: none;\r
+  padding: 0;\r
+  margin: 0;\r
+}\r
+.configContainer textarea.configCode {\r
+  -webkit-box-sizing: border-box;\r
+  -moz-box-sizing: border-box;\r
+  box-sizing: border-box;\r
+  color: #575757;\r
+  padding: 10px;\r
+  width: 100%;\r
+  min-height: 500px;\r
+  margin: 0;\r
+  resize: none;\r
+  outline: none;\r
+  -moz-tab-size: 4;\r
+  tab-size: 4;\r
+  white-space: pre;\r
+  word-wrap: normal;\r
+  overflow: auto;\r
+}\r
+.CodeMirror-hints.toolbar-modifier {\r
+  padding: 0;\r
+  color: #575757;\r
+  font-size: 14px;\r
+  font-size: 0.875rem;\r
+  line-height: 25.2px;\r
+  line-height: 1.57rem;\r
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;\r
+}\r
+.CodeMirror-hints.toolbar-modifier .CodeMirror-hint-active {\r
+  color: #575757;\r
+  background: #f0fafb;\r
+}\r
+.CodeMirror-hints.toolbar-modifier > li:hover {\r
+  background: #fffbe3;\r
+}\r
+/* Text modifier */\r
+#toolbarModifierWrapper {\r
+  margin-bottom: 1.2em;\r
+}\r
+#toolbarModifierWrapper .invalid .CodeMirror {\r
+  background: #fff8f8;\r
+  border-color: red;\r
+}\r
+#toolbarModifierWrapper .CodeMirror {\r
+  height: auto;\r
+  padding: 0 0.6em;\r
+}\r
+.staticContainer {\r
+  position: fixed;\r
+  top: 0;\r
+  width: 100%;\r
+  z-index: 10;\r
+}\r
+.staticContainer > .grid-container {\r
+  max-width: 1052px;\r
+}\r
+.staticContainer > .grid-container .inner {\r
+  background: #fff;\r
+}\r
+.staticContainer > .grid-container .inner .toolbar {\r
+  margin-bottom: 0;\r
+}\r
+#help {\r
+  position: relative;\r
+  top: -15px;\r
+  left: -5px;\r
+}\r
+#help-content {\r
+  display: none;\r
+}\r
+/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2dsb2JhbC9nbG9iYWwubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2NvcmUvY29yZS5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvZ3JpZC9ncmlkLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvbm9kZV9tb2R1bGVzL2xlc3NoYXQvYnVpbGQvbGVzc2hhdC5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvaGVhZGVyLWEvaGVhZGVyLWEubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL25hdmlnYXRpb24tYS9uYXZpZ2F0aW9uLWEubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL25hdmlnYXRpb24tYi9uYXZpZ2F0aW9uLWIubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Zvb3Rlci1hL2Zvb3Rlci1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9jb250ZW50L2NvbnRlbnQubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2J1dHRvbi1hL2J1dHRvbi1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9iYWxsb29uLWEvYmFsbG9vbi1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9pY29uL2ljb24ubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL3N3aXRjaC9zd2l0Y2gubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL3RvZ2dsZXIvdG9nZ2xlci5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Jhc2ljc2FtcGxlL2NvcmUubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Jhc2ljc2FtcGxlL2Fkam9pbmVkLmxlc3MiLCIuLi8uLi9zYW1wbGVzL2xlc3MvY3VzdG9tLmxlc3MiLCIuLi8uLi9zYW1wbGVzL3Rvb2xiYXJjb25maWd1cmF0b3IvbGVzcy90b29sYmFybW9kaWZpZXIubGVzcyIsIi4uLy4uL3NhbXBsZXMvdG9vbGJhcmNvbmZpZ3VyYXRvci9sZXNzL2Jhc2UubGVzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBc0RBLFFBSGlDO0VBeUNoQztJQUNDLHdCQUFBOzs7QUMxRkY7QUFBUztBQUFPO0FBQVM7QUFBWTtBQUFRO0FBQVE7QUFBUTtBQUFRO0FBQU07QUFBTTtBQUFLO0VBQ3JGLGNBQUE7O0FBR0Q7QUFBTTtFQUNMLFNBQUE7RUFDQSxVQUFBO0VBQ0Esd0JETitCLHVDQ00vQjtFQUNBLGdCQUFBO0VBQ0EsY0FBQTs7QUNIQSxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsV0FBQTs7QUY0Q0YsUUFIaUM7RUVqQ2hDO0VBS0MsWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0VBQVosWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0VBQVosWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0lBSlosV0FBQTs7O0FBYUYsQ0FBQztFQ3FSQyw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7RURyUkQsZ0JBQUE7RUFDQSxpQkFBQTtFQUNBLFdBQUE7O0FBSUEsQ0FEQSxxQkFDQztBQUFELGVBQUM7QUFBUSxDQURULHFCQUNVO0FBQUQsZUFBQztFQUNULFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxnQkFBQTtFQUNBLGtCQUFBO0VBQ0EsWUFBQTtFQUNBLGNBQUE7RUFDQSxRQUFBO0VBQ0EsU0FBQTs7QUFLRCxDQURBLHFCQUNDO0FBQUQsZUFBQztFQUNBLFdBQUE7O0FBSUY7RUMyUEUsOEJBQUE7RUFDQSwyQkFBQTtFQUNBLHNCQUFBO0VEM1BELGlCQUFBO0VBQ0Esa0JBQUE7O0FBS0Msc0JBREQsRUFBQyxxQkFDQztFQUNBLGVBQUE7O0FBR0Qsc0JBTEQsRUFBQyxxQkFLQztFQUNBLGdCQUFBOztBRmpCSCxRQUhpQztFRTBCOUIsc0JBREQsRUFBQyxxQkFDQztJQUNBLGdCQUFBOztFQUdELHNCQUxELEVBQUMscUJBS0M7SUFDQSxpQkFBQTs7O0FFN0VKO0VBQ0MsaUJBQUE7RUFHQSxnQkFBQTs7QUFKRCxTQU1DO0VBQ0MsZ0JBQUE7O0FKMENGLFFBSGlDO0VBNkNqQyxTSXJGQztJQUlFLGtCQUFBOzs7QUFWSCxTQU1DLGVBT0M7RUFDQyxtQkFBQTs7QUNWSDtFQUNDLFlBQUE7RUFDQSxtQkFBQTtFQUNBLGtCQUFBO0VBQ0EsT0FBQTtFQUNBLFFBQUE7RUFDQSxNQUFBO0VBQ0EsVUFBQTtFQUNBLGdCQUFBOztBTHFDRCxRQUhpQztFQTZDakM7SUs1RUUsa0JBQUE7OztBQVhGLGFBY0M7RUFDQyxnQkFBQTtFQUNBLFNBQUE7RUFDQSxnQkFBQTs7QUFqQkYsYUFjQyxHQUtDO0FBbkJGLGFBY0MsR0FLSyxHQUFHO0VBQ04scUJBQUE7O0FMeUJILFFBSGlDO0VBNkNqQyxhS3pFQztJQVVFLFdBQUE7SUFDQSx1QkFBQTtJQUNBLG1CQUFBO0lBQ0EscUJBQUE7SUFDQSxXQUFBOztFQUVBLGFBaEJGLEdBZ0JHO0VBQVMsYUFoQlosR0FnQmE7SUFDVixhQUFBOzs7QUFLRCxhQXRCRixHQXFCRSxhQUNDO0VBQ0EsZ0JBQUE7O0FMUUosUUFIaUM7RUE2Q2pDLGFLekVDLEdBcUJFLGFBQ0M7SUFJQyxnQkFBQTs7O0FBSUYsYUE5QkYsR0FxQkUsYUFTQztFQUNBLGlCQUFBOztBTEFKLFFBSGlDO0VBNkNqQyxhS3pFQyxHQXFCRSxhQVNDO0lBSUMsa0JBQUE7OztBQU1GLGFBeENGLEdBdUNDLEdBQ0c7RUFDRCxpQkFBQTs7QUF2REosYUFjQyxHQXVDQyxHQUtDO0VMeENGLGVBQUE7RUFDQSxtQkFBQTtFQUNBLGlCQUFBO0VBQ0Esb0JBQUE7RUt1Q0csaUJBQUE7RUFDQSxXQUFBO0VBQ0EsV0FBQTtFQUNBLGlCQUFBO0VBQ0EscUJBQUE7RUFDQSx5QkFBQTs7QUFFQSxhQXJESCxHQXVDQyxHQUtDLEVBU0U7RUFDQSxlQUFBO0VBQ0EsV0FBQTs7QUFRSix5QkFBQztBQUFTLHlCQUFDO0VBQ1Ysc0JBQWtCLHFyQkFBbEI7O0FDcEZGO0VBQ0MsaUJBQUE7RUFDQSxnQkFBQTtFQUNBLGlCQUFBOztBTmdERCxRQUhpQztFQTZDakM7SU12RkUsa0JBQUE7SUFDQSxnQkFBQTtJQUdBLFVBQUE7OztBQVZGLGFBYUM7RUFDQyxVQUFBO0VBQ0EsZ0JBQUE7RUFDQSxTQUFBO0VBQ0EsaUJBQUE7O0FBakJGLGFBYUMsR0FNQztBQW5CRixhQWFDLEdBTUssR0FBRztFQUNOLHFCQUFBOztBTitCSCxRQUhpQztFQTZDakMsYU1oRkM7SUFXRSxjQUFBO0lBQ0EsV0FBQTtJQUNBLHFCQUFBOzs7QU55QkgsUUFIaUM7RUE2Q2pDLGFNaEZDLEdBZ0JDO0lBRUUsa0JBQUE7OztBQUdELGFBckJGLEdBZ0JDLEdBS0c7RUFDRCxpQkFBQTs7QU5nQkosUUFIaUM7RUE2Q2pDLGFNaEZDLEdBZ0JDLEdBS0c7SUFJQSxjQUFBOzs7QUF0Q0wsYUFhQyxHQWdCQyxHQWFDO0VId1FELDhCQUFBO0VBQ0EsMkJBQUE7RUFDQSxzQkFBQTtFR3hRRSx5QkFBQTtFQUNBLHFCQUFBO0VBQ0EsYUFBQTs7QU5LSixRQUhpQztFQTZDakMsYU1oRkMsR0FnQkMsR0FhQztJQU9FLFdBQUE7SUhxT0gsd0JBQUE7SUFBaUMsb0NBQUE7SUFDakMscUJBQUE7SUFBOEIsNkJBQUE7SUFDOUIsZ0JBQUE7SUFBeUIsNEJBQUE7OztBSXhSM0I7RVB3QkMsZUFBQTtFQUNBLG9CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFT3hCQSxtQkFBQTtFQUNBLHNCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxjQUFBOztBQU5ELFNQNEVDO0VBQ0MsY0FBQTtFQUNBLHFCQUFBO0VBRUEsaUNBQUE7O0FBRUEsU0FORCxFQU1FO0VBQ0EsY0FBQTs7QU9uRkgsU0FRQztFQUNDLFNBQUE7RUFDQSxxQkFBQTtFQUNBLGtCQUFBOztBQ1hGO0VSd0JDLGVBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RVF6QkEsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLHFCQUFBOztBQUpELFFBU0M7RUFDQyxnQkFBQTs7QUFWRixRQWFDO0FBYkQsUUFhSztBQWJMLFFBYVM7QUFiVCxRQWFjO0FBYmQsUUFhMEIsU0FBUSxJQUFJO0FBYnRDLFFBYXdEO0VBQ3RELGlCQUFBOztBQWRGLFFBaUJDO0FBakJELFFBaUJPO0VMcVFMLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VLclF6QixnQkFBQTs7QUFuQkYsUUFzQkM7QUF0QkQsUUFzQk07QUF0Qk4sUUFzQlk7QUF0QlosUUFzQmlCO0VBQ2YsbUJBQUE7O0FBdkJGLFFBMEJDO0FBMUJELFFBMEJhO0VBQ1gsZ0JBQUE7RUFDQSw4QkFBQTtFQUNBLHFCQUFBOztBQTdCRixRQW9DQyxFUndDQTtBUTVFRCxRQW9DSSxHUndDSDtBUTVFRCxRQW9DUSxHUndDUDtBUTVFRCxRQW9DWSxXUndDWDtBUTVFRCxRQW9Dd0IsR1J3Q3ZCO0FRNUVELFFBb0M0QixHUndDM0I7QVE1RUQsUUFvQ2dDLEdSd0MvQjtBUTVFRCxRQW9Db0MsR1J3Q25DO0FRNUVELFFBb0N3QyxHUndDdkM7RUFDQyxjQUFBO0VBQ0EscUJBQUE7RUFFQSxpQ0FBQTs7QUFFQSxRUTlDRCxFUndDQSxFQU1FO0FBQUQsUVE5Q0UsR1J3Q0gsRUFNRTtBQUFELFFROUNNLEdSd0NQLEVBTUU7QUFBRCxRUTlDVSxXUndDWCxFQU1FO0FBQUQsUVE5Q3NCLEdSd0N2QixFQU1FO0FBQUQsUVE5QzBCLEdSd0MzQixFQU1FO0FBQUQsUVE5QzhCLEdSd0MvQixFQU1FO0FBQUQsUVE5Q2tDLEdSd0NuQyxFQU1FO0FBQUQsUVE5Q3NDLEdSd0N2QyxFQU1FO0VBQ0EsY0FBQTs7QVFuRkgsUUF3Q0M7QUF4Q0QsUUF3Q0s7QUF4Q0wsUUF3Q1M7QUF4Q1QsUUF3Q2E7QUF4Q2IsUUF3Q2lCO0VBQ2YsV0FBQTtFQUNBLGdCQUFBOztBQTFDRixRQXdDQyxHQUtDO0FBN0NGLFFBd0NLLEdBS0g7QUE3Q0YsUUF3Q1MsR0FLUDtBQTdDRixRQXdDYSxHQUtYO0FBN0NGLFFBd0NpQixHQUtmO0FBN0NGLFFBd0NDLEdBS087QUE3Q1IsUUF3Q0ssR0FLRztBQTdDUixRQXdDUyxHQUtEO0FBN0NSLFFBd0NhLEdBS0w7QUE3Q1IsUUF3Q2lCLEdBS1Q7RUFDTCxrQkFBQTs7QUE5Q0gsUUF3Q0MsR0FVQyxFQUFDO0FBbERILFFBd0NLLEdBVUgsRUFBQztBQWxESCxRQXdDUyxHQVVQLEVBQUM7QUFsREgsUUF3Q2EsR0FVWCxFQUFDO0FBbERILFFBd0NpQixHQVVmLEVBQUM7RUFDQSxnQkFBQTtFQUNBLHNCQUFBO0VBQ0EsVUFBQTtFQUNBLFNBQUE7O0FBR0QsUUFqQkQsR0FpQkUsTUFDQSxFQUFDO0FBREYsUUFqQkcsR0FpQkYsTUFDQSxFQUFDO0FBREYsUUFqQk8sR0FpQk4sTUFDQSxFQUFDO0FBREYsUUFqQlcsR0FpQlYsTUFDQSxFQUFDO0FBREYsUUFqQmUsR0FpQmQsTUFDQSxFQUFDO0VBQ0EsVUFBQTs7QUFJRixRQXZCRCxHQXVCRSxPQUNBO0FBREQsUUF2QkcsR0F1QkYsT0FDQTtBQURELFFBdkJPLEdBdUJOLE9BQ0E7QUFERCxRQXZCVyxHQXVCVixPQUNBO0FBREQsUUF2QmUsR0F1QmQsT0FDQTtFTDhERCwwREFBQTtFQUNBLHVEQUFBO0VBQ0EscURBQUE7RUFDQSxrREFBQTtFSy9ERSxVQUFBOztBQWxFSixRQXVFQztBQXZFRCxRQXVFUTtBQXZFUixRQXVFZ0IsU0FBUSxJQUFJO0VMK00xQiwwQkFBQTtFQUFpQyxvQ0FBQTtFQUNqQyx1QkFBQTtFQUE4Qiw2QkFBQTtFQUM5QixrQkFBQTtFQUF5Qiw0QkFBQTtFQW1CekIsdURBQUE7RUFDQSxvREFBQTtFQUNBLCtDQUFBO0VLbE9BLGFBQUE7RUFDQSxjQUFBO0VBRUEseUJBQUE7RUFDQSxrQkFBQTs7QUFFQSxRQVZELE1BVUU7QUFBRCxRQVZNLE9BVUw7QUFBRCxRQVZjLFNBQVEsSUFBSSxnQkFVekI7RUFDQSxxQkFBQTtFQUNBLFVBQUE7RUx3TkQsd0VBQUE7RUFDQSxxRUFBQTtFQUNBLGdFQUFBOztBSzdTRixRQThGQztFQUNDLDhCQUFBO0VBQ0EsZUFBQTs7QUFoR0YsUUFtR0M7RUFDQyxrQkFBQTtFQUNBLDZCUm5HMkMsd0JRbUczQztFUjdFRCxlQUFBO0VBQ0EsZUFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7O0FRM0JELFFBeUdDO0VBQ0Msa0JBQUE7O0FBMUdGLFFBNkdDO0VSckZBLGVBQUE7RUFDQSxrQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RVFvRkMsbUJBQUE7O0FBL0dGLFFBa0hDO0VSMUZBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VReUZDLGlCQUFBOztBQXBIRixRQXVIQztFUi9GQSxlQUFBO0VBQ0EsaUJBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VROEZDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBMUhGLFFBNkhDO0VSckdBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VRb0dDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBaElGLFFBbUlDO0VSM0dBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VRMEdDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBdElGLFFBeUlDO0VBQ0MsU0FBQTtFQUNBLDZCQUFBO0VBQ0EsZUFBQTs7QUFJQSxRQURELE1BQ0U7RUFDQSxhQUFBO0VBQ0Esa0JBQUE7O0FBR0QsUUFORCxNQU1FO0VMaURELDBCQUFBO0VBQ0EsdUJBQUE7RUFDQSxrQkFBQTs7QUt4TUYsUUE0SkM7RVJwSUEsZUFBQTtFQUNBLGtCQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFUW1JQyxvQlI3SjhCLHVDUTZKOUI7RUFDQSxnQkFBQTtFTDRJQSx1REFBQTtFQUNBLG9EQUFBO0VBQ0EsK0NBQUE7O0FLN1NGLFFBdUtDLEVBQ0M7RUFDQyxzQkFBQTs7QUF6S0gsUUF1S0MsRUFLQztFQUNDLGNBQUE7O0FBN0tILFFBaUxDO0VBQ0MsVUFBQTtFQUNBLFNBQUE7RUFFQSxXQUFBO0VBQ0EsY0FBQTtFQUNBLGdCQUFBOztBQXZMRixRQTBMQztBQTFMRCxRQTBMTTtFUmxLTCxrQkFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFUWtLQyxnSkFBQTs7QUE3TEYsUUEwTEMsSUFLQztBQS9MRixRQTBMTSxLQUtKO0VBQ0MsU0FBQTs7QUFoTUgsUUFxTUMsSUFBSTtFQUNILGVBQUE7RUFDQSxjQUFBOztBQXZNRixRQTBNQztFQUNDLFdBQUE7O0FBM01GLFFBOE1DLEdBRUM7QUFoTkYsUUE4TUssR0FFSDtBQWhORixRQThNQyxHQUVLO0FBaE5OLFFBOE1LLEdBRUM7RUFDSCxnQkFBQTs7QUFqTkgsUUE4TUMsR0FNQztBQXBORixRQThNSyxHQU1IO0VSNUxELGVBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VBQ0Esb0JBQUE7O0FRM0JELFFBME5DLFNBQVEsSUFBSTtFQUNYLFdBQUE7O0FBM05GLFFBOE5DLElBQUc7RUFDRix1QkFBQTtFQUNBLGFBQUE7RUFDQSxxQkFBQTs7O0FBR0EsUUFORCxJQUFHLEtBTUQ7RUFDQSxTQUFTLE1BQVQ7RUFDQSxpQkFBQTs7QUNqT0QsSUFERCxFQUNFO0FBQUQsSUFERSxPQUNEO0FBQUQsSUFEVSxNQUNUO0VOaVJELDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VIaFExQixlQUFBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VTbkJFLFlBQUE7RUFDQSxpQkFBQTtFQUNBLGdCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxjQUFBO0VBQ0EsbUJBQUE7RUFDQSxxQkFBQTtFQUNBLHFCQUFBO0VBQ0EsZUFBQTtFQUNBLFNBQUE7RUFDQSxzQkFBQTtFQUlBLGFBQUE7RUFHQSx1QkFBQTs7QUFFQSxJQXZCRixFQUNFLFNBc0JDO0FBQUQsSUF2QkMsT0FDRCxTQXNCQztBQUFELElBdkJTLE1BQ1QsU0FzQkM7RUFDQSxrQkFBQTs7QUFHRCxJQTNCRixFQUNFLFNBMEJDO0FBQUQsSUEzQkMsT0FDRCxTQTBCQztBQUFELElBM0JTLE1BQ1QsU0EwQkM7RUFDQSxtQkFBQTs7QUFvQkQsSUFoREYsRUFDRSxTQStDQztBQUFELElBaERDLE9BQ0QsU0ErQ0M7QUFBRCxJQWhEUyxNQUNULFNBK0NDO0VOa09GLDRCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHlCQUFBO0VBQThCLDZCQUFBO0VBQzlCLG9CQUFBO0VBQXlCLDRCQUFBO0VNblB2QixXQUFBO0VBQ0EsVUFBQTtFQUNBLG1CQUFBO0VBQ0EsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLGtCQUFBOztBQUVBLElBeENILEVBQ0UsU0ErQ0MsaUJBUkM7QUFBRCxJQXhDQSxPQUNELFNBK0NDLGlCQVJDO0FBQUQsSUF4Q1EsTUFDVCxTQStDQyxpQkFSQztFQUNBLGtCQUFBO0VBQ0EsU0FBQTtFQUNBLFFBQUE7RUFDQSxxQkFBQTs7QVRHTCxRQUhpQztFQTZDakMsSVN6RkMsRUFDRSxTQW1EQztFVHFDSixJU3pGSSxPQUNELFNBbURDO0VUcUNKLElTekZZLE1BQ1QsU0FtREM7SU44TkYsNEJBQUE7SUFBaUMsb0NBQUE7SUFDakMseUJBQUE7SUFBOEIsNkJBQUE7SUFDOUIsb0JBQUE7SUFBeUIsNEJBQUE7SU1uUHZCLFdBQUE7SUFDQSxVQUFBO0lBQ0EsbUJBQUE7SUFDQSxnQkFBQTtJQUNBLGtCQUFBO0lBQ0Esa0JBQUE7O0VBRUEsSUF4Q0gsRUFDRSxTQW1EQywwQkFaQztFQUFELElBeENBLE9BQ0QsU0FtREMsMEJBWkM7RUFBRCxJQXhDUSxNQUNULFNBbURDLDBCQVpDO0lBQ0Esa0JBQUE7SUFDQSxTQUFBO0lBQ0EsUUFBQTtJQUNBLHFCQUFBOztFQUpELElBeENILEVBQ0UsU0FtREMsMEJBWkM7RUFBRCxJQXhDQSxPQUNELFNBbURDLDBCQVpDO0VBQUQsSUF4Q1EsTUFDVCxTQW1EQywwQkFaQztJQUNBLGtCQUFBO0lBQ0EsU0FBQTtJQUNBLFFBQUE7SUFDQSxxQkFBQTs7O0FBY0YsSUExREYsRUFDRSxTQXlEQztBQUFELElBMURDLE9BQ0QsU0F5REM7QUFBRCxJQTFEUyxNQUNULFNBeURDO0FBQ0QsSUEzREYsRUFDRSxTQTBEQztBQUFELElBM0RDLE9BQ0QsU0EwREM7QUFBRCxJQTNEUyxNQUNULFNBMERDO0VBQ0EsV0FBQTtFQUNBLG1CQUFBOztBQUdELElBaEVGLEVBQ0UsU0ErREM7QUFBRCxJQWhFQyxPQUNELFNBK0RDO0FBQUQsSUFoRVMsTUFDVCxTQStEQztFQUNBLHFCQUFBO0VBQ0EsVUFBQTtFTnFPRix5RUFBQTtFQUNBLHNFQUFBO0VBQ0EsaUVBQUE7O0FNNU5BLElBN0VELEVBNkVFO0FBQUQsSUE3RUUsT0E2RUQ7QUFBRCxJQTdFVSxNQTZFVDtFQUNBLG1CQUFBOztBQUVBLElBaEZGLEVBNkVFLGNBR0M7QUFBRCxJQWhGQyxPQTZFRCxjQUdDO0FBQUQsSUFoRlMsTUE2RVQsY0FHQztBQUNELElBakZGLEVBNkVFLGNBSUM7QUFBRCxJQWpGQyxPQTZFRCxjQUlDO0FBQUQsSUFqRlMsTUE2RVQsY0FJQztFQUNBLGNBQUE7RUFDQSxtQkFBQTs7QUFJRixJQXZGRCxFQXVGRTtBQUFELElBdkZFLE9BdUZEO0FBQUQsSUF2RlUsTUF1RlQ7QUFBRCxJQXZGRCxFSGlERyxhQXhDSCxHQWdCQyxHQWFDLEVBV0U7QUdzQ0gsSUF2RkUsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFO0FHc0NILElBdkZVLE1IaURSLGFBeENILEdBZ0JDLEdBYUMsRUFXRTtFR3VDRixXQUFBO0VBQ0EsbUJBQUE7O0FBRUEsSUEzRkYsRUF1RkUsb0JBSUM7QUFBRCxJQTNGQyxPQXVGRCxvQkFJQztBQUFELElBM0ZTLE1BdUZULG9CQUlDO0FBQ0QsSUE1RkYsRUF1RkUsb0JBS0M7QUFBRCxJQTVGQyxPQXVGRCxvQkFLQztBQUFELElBNUZTLE1BdUZULG9CQUtDO0FBREQsSUEzRkYsRUhpREcsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQUQsSUEzRkMsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQUQsSUEzRlMsTUhpRFIsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQ0QsSUE1RkYsRUhpREcsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0FBQUQsSUE1RkMsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0FBQUQsSUE1RlMsTUhpRFIsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0VBQ0EsV0FBQTtFQUNBLG1CQUFBOztBQ2hHSjtFVnNCQyxlQUFBO0VBQ0Esa0JBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VHMlBDLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VPblIxQixnQ0FBQTtFQUVBLG1CQUFBO0VBQ0EscUJBQUE7RUFDQSxtQkFBQTtFQUNBLHdCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLGFBQUE7RUFDQSxvQkFBQTtFQUNBLGNBQUE7O0FBRUEsVUFBQztFQUNBLGNBQUE7O0FBR0QsVUFBQztFQUNBLFNBQVMsRUFBVDtFQUNBLFFBQUE7RUFDQSxTQUFBO0VBQ0EsbUJBQUE7RUFDQSxrQkFBQTs7QUFNRCxhQUFDO0FBQUQsYUFBQztFQUNBLFVBQUE7RUFDQSw4QkFBQTtFQUNBLHlEQUFBOztBQU1ELGFBQUM7QUFBRCxhQUFDO0VBQ0EsYUFBQTtFQUNBLDhCQUFBO0VBQ0EseURBQUE7O0FBTUQsYUFBQztBQUFELGFBQUM7RUFDQSxVQUFBOztBQU1ELGFBQUM7QUFBRCxhQUFDO0VBQ0EsV0FBQTs7QUN2REYsY0FBYztBQUNkLGVBQWU7RUFDZCxTQUFTLEVBQVQ7RUFDQSxxQkFBQTtFQUNBLFdBQUE7RUFDQSxZQUFBO0VBQ0Esc0JBQUE7RUFDQSw0QkFBQTs7QUFHRCxjQUFjO0VBQ2Isa0JBQUE7O0FBR0QsZUFBZTtFQUNkLGlCQUFBOztBQUlBLGNBQUM7QUFBUyxjQUFDO0VBQ1Ysc0JBQWtCLDZjQUFsQjs7QUFLRCxtQkFBQztBQUFTLG1CQUFDO0VBQ1Ysc0JBQWtCLDZpQkFBbEI7O0FBS0QsV0FBQztBQUFTLFdBQUM7RUFDVixzQkFBa0IsNmlCQUFsQjs7QUM1QkYsSUFBSyxRQUVKO0VBQ0Msc0JBQUE7O0FBSEYsSUFBSyxRQU1KLE1BQUs7RUFDSixnQkFBQTtFQUNBLHFCQUFBOztBQVJGLElBQUssUUFXSjtFQUNDLHlCQUFBO0VBQ0EsMEJBQUE7O0FBRUEsSUFmRyxRQVdKLE1BSUU7RUFDQSxXQUFBOztBQUdELElBbkJHLFFBV0osTUFRRTtFQUNBLFlBQUE7O0FBcEJILElBQUssUUF3Qko7RUFDQyxhQUFBOztBQUlGO0VaWkMsZUFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFWVdBLGlCQUFBO0VBQ0EseUJBQUE7RUFDQSxnQkFBQTtFQUNBLHFCQUFBO0VBQ0Esc0JBQUE7RUFDQSxXQUFBO0VUMk9DLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VTM08xQixrQkFBQTs7QUFURCxPQVdDLE1BQUs7RUFDSixhQUFBOztBQVpGLE9BZUM7RUFDQyxrQkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBO0VBQ0EsZUFBQTtFQUNBLGlCQUFBOztBQUVBLE9BUEQsTUFPRTtFQUNBLDBCQUFBOztBQXZCSCxPQTJCQztFQUNDLFdBQUE7RUFDQSxzQkFBQTtFQUNBLGFBQUE7RUFDQSxjQUFBO0VBQ0EsWUFBQTtFQUNBLGdCQUFBO0VUaU5BLDRCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHlCQUFBO0VBQThCLDZCQUFBO0VBQzlCLG9CQUFBO0VBQXlCLDRCQUFBOztBU3BQM0IsT0EyQkMsY0FTQztFQUNDLGdCQUFBO0VBQ0Esa0JBQUE7RUFDQSxjQUFBO0VBQ0EsYUFBQTtFQUNBLFlBQUE7RUFDQSxtQkFBQTtFVHdNRCw0QkFBQTtFQUFpQyxvQ0FBQTtFQUNqQyx5QkFBQTtFQUE4Qiw2QkFBQTtFQUM5QixvQkFBQTtFQUF5Qiw0QkFBQTs7QVN2TXhCLE9BbEJGLGNBU0MsU0FTRTtFQUNBLFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxrQkFBQTtFQUNBLE1BQUE7RUFDQSxRQUFBO0VBQ0EsV0FBQTtFQUNBLE9BQUE7RUFFQSx5QkFBQTtFVHNLRix3Q0FBQTtFQUNBLG9DQUFBO0VBQ0EsZ0NBQUE7RUFLQSx5Q0FBQTtFQUE4QyxvQ0FBQTtFQUM5QyxxQ0FBQTtFQUEwQyw2QkFBQTtFQUMxQyxpQ0FBQTtFQUFzQyw0QkFBQTs7QVN2S3ZDLE9BQUMsTUFDQSxjQUFjLFNBQVE7RUFDckIsbUJBQUE7O0FBaEVILE9Bb0VDLE1BQUssY0FBZ0IsUUFFcEIsZ0JBQWdCO0VBQ2YsaUJBQUE7O0FBdkVILE9Bb0VDLE1BQUssY0FBZ0IsUUFTcEIsUUFBTztFQUNOLHNCQUFBO0VBQ0Esc0JBQUE7O0FBL0VILE9BbUZDLE1BQUssY0FBZ0IsUUFBUyxRQUFPO0VBQ3BDLHFCQUFBO0VBQ0EscUJBQUE7O0FDekhGO0VWazNCRSx5QkFBQTtFQUNBLHNCQUFBO0VBQ0EscUJBQUE7RUFDQSxpQkFBQTs7QVVyM0JGLFFBR0M7RUFDQyxlQUFBOztBQUpGLFFBTUM7RUFDQyxnQkFBQTs7QUFQRixRQVVDO0VBQ0MsYUFBQTs7QUFHRCxRQUFDLFVBQ0E7RUFDQyxhQUFBOztBQUZGLFFBQUMsVUFLQTtFQUNDLGdCQUFBOztBQUtIO0VBQ0MsZ0JBQUE7O0FBRUEsa0JBQUM7RUFDQSxTQUFBOztBQU1ELHNCQUFDO0FBQUQsdUJBQUM7QUFBUyxzQkFBQztBQUFELHVCQUFDO0VBQ1Ysc0JBQWtCLHlzQkFBbEI7O0FBSUEsc0JBREEsV0FDQztBQUFELHVCQURBLFdBQ0M7QUFBUyxzQkFEVixXQUNXO0FBQUQsdUJBRFYsV0FDVztFQUNWLHNCQUFrQixxdEJBQWxCOztBQU1GLHNCQUFDO0FBQ0Qsc0JBQUM7RUFDQSw2QkFBQTs7QUFLRCx1QkFBQztBQUNELHVCQUFDO0VBQ0EsZ0NBQUE7O0FDdERGO0VBQ0MsYUFBQTtFQUNBLGtCQUFBO0VBQ0EsdUJBQUE7RUFDQSxnQkFBQTtFWDRTQyw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7RVd6U0QscUJBQUE7RUFDQSxtQkFBQTtFWGd2QkMsd0NBQUE7RUFDQSxxQ0FBQTtFQUNBLG1DQUFBO0VBQ0Esb0NBQUE7RUFDQSxnQ0FBQTs7QVdqdkJELE1BQUM7RVh1UUEsNEJBQUE7RUFBaUMsb0NBQUE7RUFDakMseUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsb0JBQUE7RUFBeUIsNEJBQUE7RVd2UXpCLGVBQUE7RUFDQSxZQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBO0VBQ0EsU0FBQTtFQUNBLFdBQUE7RUFDQSxlQUFBO0VBQ0Esa0JBQUE7RUFDQSxpQkFBQTtFQUNBLG1CQUFBOztBQ3pCRixJQUFLO0FBQ0wsTUFBTztBQUNQLGFBQWM7QUFDZCxNQUFPO0VBQ04sZ0JBQUE7O0FBSUQ7RUFDQyxnQkFBQTs7QUFHRDtFQUNDLDZCQUFBOztBQ1hBLFNBQUM7RUFDQSx5QkFBQTtFQUNBLFdBQUE7O0FBRkQsU0FBQyxJQUlBLFNBQ0M7QUFMRixTQUFDLElBSUEsU0FDSztBQUxOLFNBQUMsSUFJQSxTQUNTO0FBTFYsU0FBQyxJQUlBLFNBQ2E7QUFMZCxTQUFDLElBSUEsU0FDaUI7RUFDZixXQUFBOztBQU5ILFNBQUMsSUFJQSxTQUtDO0VoQllGLGVBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RWdCYkcsZ0JBQUE7O0FBWEgsU0FBQyxJQUlBLFNBS0MsRUFJQztFQUNDLHFCQUFBO0VBQ0EsOEJBQUE7RUFDQSxjQUFBOztBQUVBLFNBbEJILElBSUEsU0FLQyxFQUlDLEVBS0U7RUFDQSxjQUFBOztBQW5CTCxTQUFDLElBSUEsU0FvQkM7RUFDQyxXQUFBOztBQXpCSCxTQUFDLElBSUEsU0F3QkM7RUFDQyxXQUFBOztBQTdCSCxTQUFDLElBSUEsU0E0QkM7RUFDQyxrQkFBQTtFQUNBLGNBQUE7O0FBS0gsU0FBQztFQUNBLGtCQUFBOztBQUVBLFNBSEEsT0FHQztFQUNBLFdBQUE7RUFDQSxTQUFTLEVBQVQ7RUFDQSxtQkFBQTtFQUNBLGtCQUFBO0VBQ0EsTUFBQTtFQUNBLE9BQUE7RUFDQSxRQUFBO0VBQ0EsV0FBQTs7QUN4REgsSUFBSztBQUNMLE1BQU87QUFDUCxhQUFjO0FBQ2QsTUFBTztFQUNOLGlCQUFBOztBQUdELElBQUssZ0JBQWU7RUFDbkIsZUFBQTs7QUFHRDtFQUNDLG1CQUFBO0VBQ0EsWUFBQTtFQUNBLGlCQUFBOztBQUhELE9BTUM7RUFFQyxrQkFBQTtFQUNBLFVBQUE7RUFDQSxVQUFBO0VBQ0EsbUJBQUE7RUFHQSxtQkFBQTtFQUNBLDRCQUFBOztBQUVBLE9BWEQsV0FXRTtFQUNBLHlEQUFBOztBQUtILFFBQVM7RUFDUixnQkFBQTtFQUNBLFNBQUE7RUFDQSx3QkFBQTs7QUFFQSxRQUxRLG1CQUtQO0VBQ0EsWUFBQTs7QUFLRixLQUFNO0VBQ0wsZ0JBQUE7RUFDQSxjQUFBO0VBQ0EsMEJBQUE7O0FBR0QsS0FBTSxjQUFhO0VBQ2xCLGFBQUE7O0FBSUEsUUFEUSxjQUNQO0VBQ0EsYUFBQTs7QUFGRixRQUFTLGNBS1I7RUFDQyxhQUFBOztBQUlGLFFBQ0M7RUFDQyxpQkFBQTs7QUFJRjtFQUNDLGlCQUFBOztBQURELFNBR0M7RUFDQyxXQUFBO0VBQ0EsaUJBQUE7O0FBTEYsU0FHQyxNQUlDO0VBQ0MsZ0JBQUE7O0FBRUEsU0FQRixNQUlDLFNBR0U7RUFDQSx1QkFBQTtFQUNBLFdBQUE7O0FBRkQsU0FQRixNQUlDLFNBR0UsTUFJQTtFQUNDLDBCQUFBOztBQWZMLFNBR0MsTUFpQkM7RUFDQyxXQUFBO0VBQ0EsYUFBQTs7QUFHRCxTQXRCRCxNQXNCRTtFQUNBLGdCQUFBOztBQUtIO0VBQ0MsZ0JBQUE7RUFDQSxTQUFBO0VBQ0EsVUFBQTtFQUNBLHdCQUFBOztBQUVBLHVCQUFDO0VBQ0EsWUFBQTtFQUNBLFVBQUE7O0FBS0Y7RUFDQyxpQkFBQTs7QUFERCxNQUdDLElBQUc7RUFDRixpQkFBQTs7QUFKRixNQU9DO0VBQ0MsaUJBQUE7O0FBUkYsTUFPQyxjQUdDO0VBQ0MsaUJBQUE7O0FBWEgsTUFPQyxjQU9DO0VBRUMsa0JBQUE7O0FBaEJILE1Bb0JDO0VBQ0Msa0JBQUE7RUFDQSxTQUFBO0VBRUEsU0FBQTtFQUNBLGtCQUFBOztBakJ0RkYsUUFIaUM7RUE2Q2pDLE1pQnVDQztJQVVFLFVBQUE7SUFDQSxpQkFBQTtJQUVBLFVBQUE7SUFDQSxtQkFBQTs7RUFFQSxNQWhCRixXQWdCRztJQUNBLFVBQUE7SUFDQSxXQUFBOzs7QWpCbkdKLFFBSGlDO0VBNkNqQyxNaUJ1Q0M7SUF3QkUsYUFBQTs7O0FDOUlILFFBQVM7RUFDUixvQkFBQTtFZm0yQkMseUJBQUE7RUFDQSxzQkFBQTtFQUNBLHFCQUFBO0VBQ0EsaUJBQUE7RWVwMkJELGVBQUE7O0FBSUQsb0JBQXFCO0VmNmVsQixPQUFBO0VBQVMseUJBQUE7RUFDVixvQkFBQTtFQUNBLGlCQUFBO0VBQ0EsWUFBQTs7QWU1ZUYsWUFBWTtFQUNYLGtCQUFBO0Vmd2VFLE9BQUE7RUFBUywwQkFBQTtFQUNWLGtCQUFBO0VBQ0EsZUFBQTtFQUNBLFVBQUE7O0FldGVELFlBTlcsT0FNVjtFQUNBLFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxrQkFBQTtFQUNBLE1BQUE7RUFDQSxVQUFBO0VBQ0EsV0FBQTtFQUNBLE9BQUE7RWZnUEEsMEJBQUE7RUFBaUMsb0NBQUE7RUFDakMsdUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsa0JBQUE7RUFBeUIsNEJBQUE7RUFtQnpCLDRDQUFBO0VBQ0EseUNBQUE7RUFDQSxvQ0FBQTs7QWVwUkYsWUFBWSxPQWtCWDtFZmdRQyx3QkFBQTtFQUNBLHFCQUFBO0VBQ0EsZ0JBQUE7RWVoUUEscUJBQUE7O0FBcEJGLFlBQVksT0F1Qlg7QUF2QkQsWUFBWSxPQXdCWDtFQUNDLGtCQUFBO0VBQ0EsVUFBQTs7QUExQkYsWUFBWSxPQTZCWDtFZnFQQyx3QkFBQTtFQUNBLHFCQUFBO0VBQ0EsZ0JBQUE7O0FlbFBGO0VmdXpCRSx5QkFBQTtFQUNBLHNCQUFBO0VBQ0EscUJBQUE7RUFDQSxpQkFBQTs7QWV2ekJGO0VBQ0MsY0FBQTtFQUNBLG9CQUFBO0VBQ0EsZ0JBQUE7RUFDQSxnQkFBQTs7QUFHQyxRQURELE9BQU0sU0FDSjtFQUNBLGVBQUE7RUFFQSxxQkFBQTtFQUNBLGdCQUFBO0VBQ0EsVUFBQTtFQUNBLHlCQUFBOztBQUdELFFBVkQsT0FBTSxTQVVKO0VBQ0EsYUFBQTs7QUFHRCxRQWRELE9BQU0sU0FjSjtFQUNBLFdBQUE7RUFDQSxpQkFBQTs7QUFHRCxRQW5CRCxPQUFNLFNBbUJKO0VBQ0EsWUFBQTtFQUNBLGdCQUFBOztBQTNCSCxRQU1DLE9BQU0sU0F3Qkw7RUFDQyxjQUFBOztBQU1ILGdCQUFnQjtBQUNoQixnQkFBZ0I7QUFDaEIsc0JBQXNCO0VBQ3JCLGFBQUE7O0FBR0QsZ0JBQWlCO0FBQ2pCLFFBQVMsT0FBTTtBQUNmLGdCQUFpQixTQUFRLFdBQVc7RUFDbkMsYUFBQTs7QUFHRCxHQUFHO0VBQ0YsVUFBQTtFQUNBLGdCQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBO0VBQ0EsY0FBQTtFQUNBLHlCQUFBOztBQU5ELEdBQUcsZ0JBUUY7RUFDQyxTQUFBOztBQVRGLEdBQUcsZ0JBWUY7RUFDQyxhQUFBOztBQUdELEdBaEJFLGdCQWdCRCxjQUFlO0VBQ2Ysa0JBQUE7RWZrWUMsT0FBQTtFQUFTLHlCQUFBO0VBQ1Ysb0JBQUE7RUFDQSxpQkFBQTtFQUNBLFlBQUE7O0FldFpGLEdBQUcsZ0JBdUJGLE9BQU87RUFDTixpQkFBQTs7QUFJRCxHQTVCRSxnQkE0QkE7RUFDRCxVQUFBO0VBQ0EsU0FBQTtFQUNBLDBCQUFBO0VBQ0EsV0FBQTs7QUFFQSxHQWxDQyxnQkE0QkEsS0FNQTtFQUNBLDJCQUFBOztBQUdELEdBdENDLGdCQTRCQSxLQVVBO0VBQ0Esd0JBQUE7O0FBWEYsR0E1QkUsZ0JBNEJBLEtBZUQ7RUFDQyxVQUFBO0VBQ0EsU0FBQTs7QUFJRCxHQWpEQyxnQkE0QkEsS0FxQkM7RUFDRCxrQkFBQTs7QUFFQSxHQXBEQSxnQkE0QkEsS0FxQkMsS0FHQTtFQUNBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxlQUFBOztBQUdELEdBMURBLGdCQTRCQSxLQXFCQyxLQVNBO0FBQ0QsR0EzREEsZ0JBNEJBLEtBcUJDLEtBVUE7RUFDQSw2QkFBQTs7QUFHRCxHQS9EQSxnQkE0QkEsS0FxQkMsS0FjQTtFQUNBLDBCQUFBOztBQUVBLEdBbEVELGdCQTRCQSxLQXFCQyxLQWNBLHNCQUdDO0VBQ0EsZ0JBQUE7O0FBSUYsR0F2RUEsZ0JBNEJBLEtBcUJDLEtBc0JBLG1CQUFtQjtBQUNwQixHQXhFQSxnQkE0QkEsS0FxQkMsS0F1QkEsbUJBQW1CO0FBQ3BCLEdBekVBLGdCQTRCQSxLQXFCQyxLQXdCQSx1QkFBdUI7QUFDeEIsR0ExRUEsZ0JBNEJBLEtBcUJDLEtBeUJBLHVCQUF1QjtFQUN2QixnQkFBQTtFQUNBLFVBQUE7O0FBR0QsR0EvRUEsZ0JBNEJBLEtBcUJDLEtBOEJBLG1CQUFtQjtBQUNwQixHQWhGQSxnQkE0QkEsS0FxQkMsS0ErQkEsdUJBQXVCO0FBQ3hCLEdBakZBLGdCQTRCQSxLQXFCQyxLQWdDQSxtQkFBbUIsT0FBTztBQUMzQixHQWxGQSxnQkE0QkEsS0FxQkMsS0FpQ0EsdUJBQXVCLE9BQU87RUFDOUIsbUJBQUE7O0FBR0QsR0F0RkEsZ0JBNEJBLEtBcUJDLEtBcUNBLG1CQUFtQjtBQUNwQixHQXZGQSxnQkE0QkEsS0FxQkMsS0FzQ0EsdUJBQXVCO0VBQ3ZCLG1CQUFBOztBQUdELEdBM0ZBLGdCQTRCQSxLQXFCQyxLQTBDQTtFQU1BLG1CQUFBOztBQUxBLEdBNUZELGdCQTRCQSxLQXFCQyxLQTBDQSx1QkFDQztFQUNBLFNBQVMsRUFBVDtFQUNBLFdBQUE7O0FBS0QsR0FuR0QsZ0JBNEJBLEtBcUJDLEtBMENBLHVCQVFFO0VBQ0QsZ0JBQUE7O0FBSUYsR0F4R0EsZ0JBNEJBLEtBcUJDLEtBdURDO0FBQUssR0F4R1AsZ0JBNEJBLEtBcUJDLEtBdURRO0VBQ1IsbUJBQUE7RUFDQSxzQkFBQTs7QUF6REYsR0FqREMsZ0JBNEJBLEtBcUJDLEtBNkREO0VBQ0MsaUJBQUE7RUFDQSxnQkFBQTs7QUEvREYsR0FqREMsZ0JBNEJBLEtBcUJDLEtBNkRELEVBSUM7RUFDQyxtQkFBQTtFQUNBLGVBQUE7O0FBbkVILEdBakRDLGdCQTRCQSxLQXFCQyxLQTZERCxFQUlDLEtBSUM7RUFDQyxtQkFBQTtFQUNBLGlCQUFBO0VBQ0EsZUFBQTtFQUNBLGdCQUFBO0VmNkNKLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VlN0NyQixzQkFBQTtFQUNBLGNBQUE7RUFDQSxpQkFBQTtFQUNBLFlBQUE7O0FBR0MsR0FsSUosZ0JBNEJBLEtBcUJDLEtBNkRELEVBSUMsS0FJQyxPQVdFLElBQUksV0FDSDtBQUNELEdBbklKLGdCQTRCQSxLQXFCQyxLQTZERCxFQUlDLEtBSUMsT0FXRSxJQUFJLFdBRUg7RUFDQSxXQUFBO0VBQ0EseUJBQUE7RUFDQSx5QkFBQTs7QUFJRixHQTFJSCxnQkE0QkEsS0FxQkMsS0E2REQsRUFJQyxLQUlDLE9Bb0JFLEtBQUs7RUFDTCxlQUFBO0Vmd1FKLE9BQUE7RUFBUyx5QkFBQTtFQUNWLG9CQUFBO0VBQ0EsaUJBQUE7RUFDQSxZQUFBOztBZXJXQSxHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0Q7RUFDQyx5QkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBOztBQXJHRixHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQztFQUNDLGtCQUFBO0VBQ0EscUJBQUE7RUFHQSxjQUFBOztBQUVBLEdBaEtGLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBT0U7RUFDQSwwQkFBQTs7QUFFQSxHQW5LSCxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQUdDO0VBQ0EsYUFBQTs7QUFKRixHQWhLRixnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQU9BO0VmQUosMEJBQUE7RUFBaUMsb0NBQUE7RUFDakMsdUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsa0JBQUE7RUFBeUIsNEJBQUE7RWVBcEIsY0FBQTs7QUFFQSxHQTNLSixnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQU9BLHFCQUlFO0VBQ0EsK0JBQUE7O0FBWkgsR0FoS0YsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0FPRSxzQkFPQSxxQkFRQztFQUNDLHNCQUFBOztBQUtILEdBckxGLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBNEJHO0FBQUssR0FyTFQsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0E0QlU7RUFDUixtQkFBQTtFQUNBLHNCQUFBOztBQXRJSixHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQWtDQztFQUNDLFVBQUE7O0FBM0lKLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUM7RUFDQyxVQUFBO0VBQ0EscUJBQUE7RUFDQSxlQUFBO0VBQ0EscUJBQUE7O0FBbEpMLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUMsR0FPQztFQUNDLGVBQUE7RUFDQSxtQkFBQTs7QUF2Sk4sR0FqREMsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0FrQ0MsR0FJQyxHQVlDO0FBMUpMLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUMsR0FhQztFQUNDLGVBQUE7RUFDQSxTQUFBO0VBQ0Esc0JBQUE7RUFDQSxzQkFBQTtFQ2xTUCxrQkFBQTtFQUNBLG1CQUFBO0VBRUEsb0JBQUE7RUFDQSxvQkFBQTs7QUR3U0EsR0ExTkUsZ0JBME5BO0VBQ0QsZ0JBQUE7O0FBSUQsR0EvTkUsZ0JBK05EO0VBQ0EsWUFBQTtFQUNBLFlBQUE7RUFDQSxnQkFBQTtFQUNBLGdCQUFBO0VBQ0Esa0JBQUE7O0FBTEQsR0EvTkUsZ0JBK05ELE1BT0E7RUN4VEQsa0JBQUE7RUFDQSxrQkFBQTtFQUVBLG9CQUFBO0VBQ0Esb0JBQUE7RURzVEUscUJBQUE7RUFDQSxtQkFBQTtFQUNBLDZCQUFBO0VBQ0EsYUFBQTtFQUNBLG9CQUFBOztBQWJGLEdBL05FLGdCQStORCxNQWdCQTtFQUVDLG9CQUFBO0VBQ0EsZ0JBQUE7O0FBbkJGLEdBL05FLGdCQStORCxNQWdCQSxHQUtDO0VBQ0MsaUJBQUE7RUFDQSxTQUFBO0VBQ0EscUJBQUE7O0FBR0QsR0ExUEEsZ0JBK05ELE1BZ0JBLEdBV0c7RUFDRCxrQkFBQTs7QUE1QkgsR0EvTkUsZ0JBK05ELE1BZ0JBLEdBZUM7RUFDQyxXQUFBO0VBQ0EsVUFBQTtFQUNBLFdBQUE7RUFDQSxpQkFBQTtFQUNBLDBCQUFBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFZmxFRiw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7O0FlMEJELEdBL05FLGdCQStORCxNQWdCQSxHQWVDLEdBVUM7RUFDQyxnQkFBQTtFQUNBLFlBQUE7RUFDQSxzQkFBQTs7QUE1Q0osR0EvTkUsZ0JBK05ELE1BZ0JBLEdBZ0NDO0VBQ0MsaUJBQUE7RUFDQSxZQUFBO0VBQ0Esb0JBQUE7O0FBbkRILEdBL05FLGdCQStORCxNQWdCQSxHQWdDQyxHQUtDO0VBQ0Msa0JBQUE7O0FBR0QsR0F4UkQsZ0JBK05ELE1BZ0JBLEdBZ0NDLEdBU0U7RUFDQSxTQUFTLE9BQVQ7RUFDQSxjQUFBO0VBQ0EsV0FBQTtFQUNBLFlBQUE7RUFDQSxTQUFBO0VBQ0EsUUFBQTs7QUFPTDtBQUNBLGdCQUFpQixTQUFRO0FBQ3pCO0VmaElFLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VlZ0kxQixzQkFBQTtFQzNYQSxrQkFBQTtFQUNBLG1CQUFBO0VBRUEsb0JBQUE7RUFDQSxvQkFBQTs7QUQyWEQsZ0JBQWlCLFNBQVE7QUFDekIsV0FBWTtBQUNaO0VDallDLGtCQUFBO0VBQ0EsbUJBQUE7RUFFQSxvQkFBQTtFQUNBLG9CQUFBO0VEK1hBLGdKQUFBOztBQUdELFdBQVk7RUFDWCxZQUFBO0VBQ0EsVUFBQTtFQUNBLFNBQUE7O0FBR0QsZ0JBQWlCLFNBQVE7RWZ2SHZCLDhCQUFBO0VBQ0EsMkJBQUE7RUFDQSxzQkFBQTtFZXVIRCxjQUFBO0VBQ0EsYUFBQTtFQUNBLFdBQUE7RUFDQSxpQkFBQTtFQUNBLFNBQUE7RUFDQSxZQUFBO0VBQ0EsYUFBQTtFQUNBLGdCQUFBO0VBQ0EsV0FBQTtFQUNBLGdCQUFBO0VBQ0EsaUJBQUE7RUFDQSxjQUFBOztBQUdELGlCQUFpQjtFQUNoQixVQUFBO0VBQ0EsY0FBQTtFQzlaQSxlQUFBO0VBQ0EsbUJBQUE7RUFFQSxtQkFBQTtFQUNBLG9CQUFBO0VEa2FBLGdKQUFBOztBQVZELGlCQUFpQixpQkFJaEI7RUFDQyxjQUFBO0VBQ0EsbUJBQUE7O0FBTUQsaUJBWmdCLGlCQVlkLEtBQUk7RUFDTCxtQkFBQTs7O0FBS0Y7RUFDQyxvQkFBQTs7QUFERCx1QkFHQyxTQUFTO0VBQ1IsbUJBQUE7RUFDQSxpQkFBQTs7QUFMRix1QkFRQztFQUVDLFlBQUE7RUFHQSxnQkFBQTs7QUFJRjtFQUNDLGVBQUE7RUFDQSxNQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7O0FBSkQsZ0JBTUM7RUFDQyxpQkFBQTs7QUFQRixnQkFNQyxrQkFHQztFQUNDLGdCQUFBOztBQVZILGdCQU1DLGtCQUdDLE9BR0M7RUFDQyxnQkFBQTs7QUFPSjtFQUNDLGtCQUFBO0VBQ0EsVUFBQTtFQUNBLFVBQUE7O0FBRUEsS0FBQztFQUNBLGFBQUEifQ== */\r
diff --git a/release/samples/img/github-top.png b/release/samples/img/github-top.png
new file mode 100644 (file)
index 0000000..7b9cbb1
Binary files /dev/null and b/release/samples/img/github-top.png differ
diff --git a/release/samples/img/header-bg.png b/release/samples/img/header-bg.png
new file mode 100644 (file)
index 0000000..a14166a
Binary files /dev/null and b/release/samples/img/header-bg.png differ
diff --git a/release/samples/img/header-separator.png b/release/samples/img/header-separator.png
new file mode 100644 (file)
index 0000000..8c4fb9b
Binary files /dev/null and b/release/samples/img/header-separator.png differ
diff --git a/release/samples/img/logo.png b/release/samples/img/logo.png
new file mode 100644 (file)
index 0000000..96d86e2
Binary files /dev/null and b/release/samples/img/logo.png differ
diff --git a/release/samples/img/navigation-tip.png b/release/samples/img/navigation-tip.png
new file mode 100644 (file)
index 0000000..2286114
Binary files /dev/null and b/release/samples/img/navigation-tip.png differ
diff --git a/release/samples/index.html b/release/samples/index.html
new file mode 100644 (file)
index 0000000..3fe8960
--- /dev/null
@@ -0,0 +1,128 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>CKEditor Sample</title>\r
+       <script src="../ckeditor.js"></script>\r
+       <script src="js/sample.js"></script>\r
+       <link rel="stylesheet" href="css/samples.css">\r
+       <link rel="stylesheet" href="toolbarconfigurator/lib/codemirror/neo.css">\r
+</head>\r
+<body id="main">\r
+\r
+<nav class="navigation-a">\r
+       <div class="grid-container">\r
+               <ul class="navigation-a-left grid-width-70">\r
+                       <li><a href="http://ckeditor.com">Project Homepage</a></li>\r
+                       <li><a href="http://dev.ckeditor.com/">I found a bug</a></li>\r
+                       <li><a href="http://github.com/ckeditor/ckeditor-dev" class="icon-pos-right icon-navigation-a-github">Fork CKEditor on GitHub</a></li>\r
+               </ul>\r
+               <ul class="navigation-a-right grid-width-30">\r
+                       <li><a href="http://ckeditor.com/blog-list">CKEditor Blog</a></li>\r
+               </ul>\r
+       </div>\r
+</nav>\r
+\r
+<header class="header-a">\r
+       <div class="grid-container">\r
+               <h1 class="header-a-logo grid-width-30">\r
+                       <a href="index.html"><img src="img/logo.png" alt="CKEditor Sample"></a>\r
+               </h1>\r
+\r
+               <nav class="navigation-b grid-width-70">\r
+                       <ul>\r
+                               <li><a href="index.html" class="button-a button-a-background">Start</a></li>\r
+                               <li><a href="toolbarconfigurator/index.html" class="button-a">Toolbar configurator <span class="balloon-a balloon-a-nw">Edit your toolbar now!</span></a></li>\r
+                       </ul>\r
+               </nav>\r
+       </div>\r
+</header>\r
+\r
+<main>\r
+       <div class="adjoined-top">\r
+               <div class="grid-container">\r
+                       <div class="content grid-width-100">\r
+                               <h1>Congratulations!</h1>\r
+                               <p>\r
+                                       If you can see CKEditor below, it means that the installation succeeded.\r
+                                       You can now try out your new editor version, see its features, and when you are ready to move on, check some of the <a href="#sample-customize">most useful resources</a> recommended below.\r
+                               </p>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+       <div class="adjoined-bottom">\r
+               <div class="grid-container">\r
+                       <div class="grid-width-100">\r
+                               <div id="editor">\r
+                                       <h1>Hello world!</h1>\r
+                                       <p>I'm an instance of <a href="http://ckeditor.com">CKEditor</a>.</p>\r
+                               </div>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+\r
+       <div class="grid-container">\r
+               <div class="content grid-width-100">\r
+                       <section id="sample-customize">\r
+                               <h2>Customize Your Editor</h2>\r
+                               <p>Modular build and <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">numerous configuration options</a> give you nearly endless possibilities to customize CKEditor. Replace the content of your <code><a href="../config.js">config.js</a></code> file with the following code and refresh this page (<strong>remember to clear the browser cache</strong>)!</p>\r
+               <pre class="cm-s-neo CodeMirror"><code><span style="padding-right: 0.1px;"><span class="cm-variable">CKEDITOR</span>.<span class="cm-property">editorConfig</span> <span class="cm-operator">=</span> <span class="cm-keyword">function</span>( <span class="cm-def">config</span> ) {</span>\r
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">language</span> <span class="cm-operator">=</span> <span class="cm-string">'es'</span>;</span>\r
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">uiColor</span> <span class="cm-operator">=</span> <span class="cm-string">'#F7B42C'</span>;</span>\r
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">height</span> <span class="cm-operator">=</span> <span class="cm-number">300</span>;</span>\r
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">toolbarCanCollapse</span> <span class="cm-operator">=</span> <span class="cm-atom">true</span>;</span>\r
+<span style="padding-right: 0.1px;">};</span></code></pre>\r
+                       </section>\r
+\r
+                       <section>\r
+                               <h2>Toolbar Configuration</h2>\r
+                               <p>If you want to reorder toolbar buttons or remove some of them, check <a href="toolbarconfigurator/index.html">this handy tool</a>!</p>\r
+                       </section>\r
+\r
+                       <section>\r
+                               <h2>More Samples!</h2>\r
+                               <p>Visit the <a href="http://sdk.ckeditor.com">CKEditor SDK</a> for a huge collection of samples showcasing editor features, with source code readily available to copy and use in your own implementation.</p>\r
+                       </section>\r
+\r
+                       <section>\r
+                               <h2>Developer's Guide</h2>\r
+                               <p>The most important resource for all developers working with CKEditor, integrating it with their websites and applications, and customizing to their needs. You can start from here:</p>\r
+                               <ul>\r
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_installation">Getting Started</a> &ndash; Explains most crucial editor concepts and practices as well as the installation process and integration with your website.</li>\r
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_advanced_installation">Advanced Installation Concepts</a> &ndash; Describes how to upgrade, install additional components (plugins, skins), or create a custom build.</li>\r
+                               </ul>\r
+                                       <p>When you have the basics sorted out, feel free to browse some more advanced sections like:</p>\r
+                               <ul>\r
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_features">Functionality Overview</a> &ndash; Descriptions and samples of various editor features.</li>\r
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/plugin_sdk_intro">Plugin SDK</a>, <a href="http://docs.ckeditor.com/#!/guide/widget_sdk_intro">Widget SDK</a>, and <a href="http://docs.ckeditor.com/#!/guide/skin_sdk_intro">Skin SDK</a> &ndash; Useful when you want to create your own editor components.</li>\r
+                               </ul>\r
+                       </section>\r
+\r
+                       <section>\r
+                               <h2>CKEditor JavaScript API</h2>\r
+                               <p>CKEditor boasts a rich <a href="http://docs.ckeditor.com/#!/api">JavaScript API</a> that you can use to adjust the editor to your needs and integrate it with your website or application.</p>\r
+                       </section>\r
+               </div>\r
+       </div>\r
+</main>\r
+\r
+<footer class="footer-a grid-container">\r
+       <div class="grid-container">\r
+               <p class="grid-width-100">\r
+                       CKEditor &ndash; The text editor for the Internet &ndash; <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p class="grid-width-100" id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> &ndash; Frederico Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</footer>\r
+<script>\r
+       initSample();\r
+</script>\r
+\r
+</body>\r
+</html>\r
diff --git a/release/samples/js/sample.js b/release/samples/js/sample.js
new file mode 100644 (file)
index 0000000..f0cd939
--- /dev/null
@@ -0,0 +1,53 @@
+/**\r
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/* exported initSample */\r
+\r
+if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+       CKEDITOR.tools.enableHtml5Elements( document );\r
+\r
+// The trick to keep the editor in the sample quite small\r
+// unless user specified own height.\r
+CKEDITOR.config.height = 150;\r
+CKEDITOR.config.width = 'auto';\r
+\r
+var initSample = ( function() {\r
+       var wysiwygareaAvailable = isWysiwygareaAvailable(),\r
+               isBBCodeBuiltIn = !!CKEDITOR.plugins.get( 'bbcode' );\r
+\r
+       return function() {\r
+               var editorElement = CKEDITOR.document.getById( 'editor' );\r
+\r
+               // :(((\r
+               if ( isBBCodeBuiltIn ) {\r
+                       editorElement.setHtml(\r
+                               'Hello world!\n\n' +\r
+                               'I\'m an instance of [url=http://ckeditor.com]CKEditor[/url].'\r
+                       );\r
+               }\r
+\r
+               // Depending on the wysiwygare plugin availability initialize classic or inline editor.\r
+               if ( wysiwygareaAvailable ) {\r
+                       CKEDITOR.replace( 'editor' );\r
+               } else {\r
+                       editorElement.setAttribute( 'contenteditable', 'true' );\r
+                       CKEDITOR.inline( 'editor' );\r
+\r
+                       // TODO we can consider displaying some info box that\r
+                       // without wysiwygarea the classic editor may not work.\r
+               }\r
+       };\r
+\r
+       function isWysiwygareaAvailable() {\r
+               // If in development mode, then the wysiwygarea must be available.\r
+               // Split REV into two strings so builder does not replace it :D.\r
+               if ( CKEDITOR.revision == ( '%RE' + 'V%' ) ) {\r
+                       return true;\r
+               }\r
+\r
+               return !!CKEDITOR.plugins.get( 'wysiwygarea' );\r
+       }\r
+} )();\r
+\r
diff --git a/release/samples/js/sf.js b/release/samples/js/sf.js
new file mode 100644 (file)
index 0000000..69dd77d
--- /dev/null
@@ -0,0 +1,17 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+var SF=function(){function d(a){return(a=a.attributes?a.attributes.getNamedItem("class"):null)?a.value.split(" "):[]}function c(a){var e=document.createAttribute("class");e.value=a.join(" ");return e}var b={attachListener:function(a,e,b){if(a.addEventListener)a.addEventListener(e,b,!1);else if(a.attachEvent)a.attachEvent("on"+e,function(){b.apply(a,arguments)});else throw Error("Could not attach event.");}};b.indexOf=function(){var a=Array.prototype.indexOf;return"function"===a?function(e,b){return a.call(e,
+b)}:function(a,b){for(var c=a.length,d=0;d<c;d++)if(a[d]===b)return d;return-1}}();b.accept=function(a,e){var c;a.children?(c=a.children,e(a)):"number"===typeof a.length&&(c=a);for(var d=c?c.length||0:0;d--;)b.accept(c[d],e)};b.getByClass=function(){var a=document.getElementsByClassName;return"function"===typeof a?function(e,b){"string"===typeof e&&(b=e,e=document);return a.call(e,b)}:function(a,c){"string"===typeof a&&(c=a,a=document.getElementsByTagName("html")[0]);var d=[];b.accept(a,function(a){b.classList.contains(a,
+c)&&d.push(a)});return d}}();b.classList={};b.classList.add=function(a,b){var f=d(a);f.push(b);a.attributes.setNamedItem(c(f))};b.classList.remove=function(a,e){var f=d(a,e),n=b.indexOf(f,e);-1!==n&&(f.splice(n,1),a.attributes.setNamedItem(c(f)))};b.classList.contains=function(a,c){return-1!==b.indexOf(d(a),c)};b.classList.toggle=function(a,b){this.contains(a,b)?this.remove(a,b):this.add(a,b)};return b}();"use strict";
+(function(){function d(c){for(var b in c)delete c[b]}SF.modal=function(c){function b(a){27==a.keyCode&&f.close()}c.modalClass="modal content";c.closeClass="modal-close";c.modalStyles=d;c.closeStyles=d;var a=c.afterCreate,e=c.afterClose;c.afterCreate=function(c){a&&a(c);window.addEventListener("keydown",b)};c.afterClose=function(a){e&&e(a);window.removeEventListener("keydown",b)};var f=(new picoModal(c)).afterCreate(c.afterCreate).afterClose(c.afterClose);return f}})();"use strict";
+(function(){for(var d=SF.getByClass("toggler"),c=d.length;c--;)SF.attachListener(d[c],"click",function(){var b=SF.classList.contains(this,"icon-toggler-expanded")||SF.classList.contains(this,"icon-toggler-collapsed"),a=document.getElementById(this.getAttribute("data-for"));SF.classList.toggle(this,"collapsed");SF.classList.contains(this,"collapsed")?(SF.classList.add(a,"collapsed"),b&&(SF.classList.remove(this,"icon-toggler-expanded"),SF.classList.add(this,"icon-toggler-collapsed"))):(SF.classList.remove(a,
+"collapsed"),b&&(SF.classList.remove(this,"icon-toggler-collapsed"),SF.classList.add(this,"icon-toggler-expanded")))})})();"use strict";(function(){for(var d=SF.getByClass("tree-a"),c=d.length;c--;)SF.attachListener(d[c],"click",function(b){b=b.target||b.srcElement;"H2"!==b.nodeName||SF.classList.contains(b,"tree-a-no-sub")||SF.classList.toggle(b,"tree-a-active")})})();
+(function(d,c){function b(a){return"object"===typeof Node?a instanceof Node:a&&"object"===typeof a&&"number"===typeof a.nodeType}function a(){var a=[];return{watch:a.push.bind(a),trigger:function(b){for(var c=!0,d={preventDefault:function(){c=!1}},e=0;e<a.length;e++)a[e](b,d);return c}}}function e(a){this.elem=a}function f(a,b){return e.div().clazz("pico-overlay").clazz(a("overlayClass","")).stylize({display:"block",position:"fixed",top:"0px",left:"0px",height:"100%",width:"100%",zIndex:1E4}).stylize(a("overlayStyles",
+{opacity:.5,background:"#000"})).onClick(function(){a("overlayClose",!0)&&b()})}function n(a,b){var c=a("width","auto");"number"===typeof c&&(c=""+c+"px");return e.div().clazz("pico-content").clazz(a("modalClass","")).stylize({display:"block",position:"fixed",zIndex:10001,left:"50%",top:"50px",width:c,"-ms-transform":"translateX(-50%)","-moz-transform":"translateX(-50%)","-webkit-transform":"translateX(-50%)","-o-transform":"translateX(-50%)",transform:"translateX(-50%)"}).stylize(a("modalStyles",
+{backgroundColor:"white",padding:"20px",borderRadius:"5px"})).html(a("content")).attr("role","dialog").onClick(function(a){(new e(a.target)).anyAncestor(function(a){return/\bpico-close\b/.test(a.elem.className)})&&b()})}function p(a){return function(){return a().elem}}function k(c){function e(a,b){var d=c[a];"function"===typeof d&&(d=d(b));return void 0===d?b:d}function k(){l().hide();m().hide();v.trigger(h)}function q(){w.trigger(h)&&k()}function g(a){return function(){a.apply(this,arguments);return h}}
+function r(a){if(!t){var c=n(e,q),b=f(e,q),d;d=e("closeButton",!0)?c.child().html(e("closeHtml","\x26#xD7;")).clazz("pico-close").clazz(e("closeClass")).stylize(e("closeStyles",{borderRadius:"2px",cursor:"pointer",height:"15px",width:"15px",position:"absolute",top:"5px",right:"5px",fontSize:"16px",textAlign:"center",lineHeight:"15px",background:"#CCC"})):void 0;t={modal:c,overlay:b,close:d};x.trigger(h)}return t[a]}if("string"===typeof c||b(c))c={content:c};var x=a(),y=a(),z=a(),w=a(),v=a(),t,m=r.bind(d,
+"modal"),l=r.bind(d,"overlay"),u=r.bind(d,"close"),h={modalElem:p(m),closeElem:p(u),overlayElem:p(l),show:function(){y.trigger(h)&&(l().show(),u(),m().show(),z.trigger(h));return this},close:g(q),forceClose:g(k),destroy:function(){m=m().destroy();l=l().destroy();u=void 0},options:function(a){c=a},afterCreate:g(x.watch),beforeShow:g(y.watch),afterShow:g(z.watch),beforeClose:g(w.watch),afterClose:g(v.watch)};return h}e.div=function(a){var b=c.createElement("div");(a||c.body).appendChild(b);return new e(b)};
+e.prototype={child:function(){return e.div(this.elem)},stylize:function(a){a=a||{};"undefined"!==typeof a.opacity&&(a.filter="alpha(opacity\x3d"+100*a.opacity+")");for(var b in a)a.hasOwnProperty(b)&&(this.elem.style[b]=a[b]);return this},clazz:function(a){this.elem.className+=" "+a;return this},html:function(a){b(a)?this.elem.appendChild(a):this.elem.innerHTML=a;return this},onClick:function(a){this.elem.addEventListener("click",a);return this},destroy:function(){c.body.removeChild(this.elem)},hide:function(){this.elem.style.display=
+"none"},show:function(){this.elem.style.display="block"},attr:function(a,b){this.elem.setAttribute(a,b);return this},anyAncestor:function(a){for(var b=this.elem;b;){if(a(new e(b)))return!0;b=b.parentNode}return!1}};"function"===typeof d.define&&d.define.amd?d.define(function(){return k}):d.picoModal=k})(window,document);
\ No newline at end of file
diff --git a/release/samples/old/ajax.html b/release/samples/old/ajax.html
new file mode 100644 (file)
index 0000000..3ca07c2
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Ajax &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+       <script>\r
+\r
+               var editor, html = '';\r
+\r
+               function createEditor() {\r
+                       if ( editor )\r
+                               return;\r
+\r
+                       // Create a new editor inside the <div id="editor">, setting its value to html\r
+                       var config = {};\r
+                       editor = CKEDITOR.appendTo( 'editor', config, html );\r
+               }\r
+\r
+               function removeEditor() {\r
+                       if ( !editor )\r
+                               return;\r
+\r
+                       // Retrieve the editor contents. In an Ajax application, this data would be\r
+                       // sent to the server or used in any other way.\r
+                       document.getElementById( 'editorcontents' ).innerHTML = html = editor.getData();\r
+                       document.getElementById( 'contents' ).style.display = '';\r
+\r
+                       // Destroy the editor.\r
+                       editor.destroy();\r
+                       editor = null;\r
+               }\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Create and Destroy Editor Instances for Ajax Applications\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/saveajax.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to create and destroy CKEditor instances on the fly. After the removal of CKEditor the content created inside the editing\r
+                       area will be displayed in a <code>&lt;div&gt;</code> element.\r
+               </p>\r
+               <p>\r
+                       For details of how to create this setup check the source code of this sample page\r
+                       for JavaScript code responsible for the creation and destruction of a CKEditor instance.\r
+               </p>\r
+       </div>\r
+       <p>Click the buttons to create and remove a CKEditor instance.</p>\r
+       <p>\r
+               <input onclick="createEditor();" type="button" value="Create Editor">\r
+               <input onclick="removeEditor();" type="button" value="Remove Editor">\r
+       </p>\r
+       <!-- This div will hold the editor. -->\r
+       <div id="editor">\r
+       </div>\r
+       <div id="contents" style="display: none">\r
+               <p>\r
+                       Edited Contents:\r
+               </p>\r
+               <!-- This div will be used to display the editor contents. -->\r
+               <div id="editorcontents">\r
+               </div>\r
+       </div>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/api.html b/release/samples/old/api.html
new file mode 100644 (file)
index 0000000..88a4b06
--- /dev/null
@@ -0,0 +1,210 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>API Usage &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <script>\r
+\r
+// The instanceReady event is fired, when an instance of CKEditor has finished\r
+// its initialization.\r
+CKEDITOR.on( 'instanceReady', function( ev ) {\r
+       // Show the editor name and description in the browser status bar.\r
+       document.getElementById( 'eMessage' ).innerHTML = 'Instance <code>' + ev.editor.name + '<\/code> loaded.';\r
+\r
+       // Show this sample buttons.\r
+       document.getElementById( 'eButtons' ).style.display = 'block';\r
+});\r
+\r
+function InsertHTML() {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+       var value = document.getElementById( 'htmlArea' ).value;\r
+\r
+       // Check the active editing mode.\r
+       if ( editor.mode == 'wysiwyg' )\r
+       {\r
+               // Insert HTML code.\r
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml\r
+               editor.insertHtml( value );\r
+       }\r
+       else\r
+               alert( 'You must be in WYSIWYG mode!' );\r
+}\r
+\r
+function InsertText() {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+       var value = document.getElementById( 'txtArea' ).value;\r
+\r
+       // Check the active editing mode.\r
+       if ( editor.mode == 'wysiwyg' )\r
+       {\r
+               // Insert as plain text.\r
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText\r
+               editor.insertText( value );\r
+       }\r
+       else\r
+               alert( 'You must be in WYSIWYG mode!' );\r
+}\r
+\r
+function SetContents() {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+       var value = document.getElementById( 'htmlArea' ).value;\r
+\r
+       // Set editor contents (replace current contents).\r
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData\r
+       editor.setData( value );\r
+}\r
+\r
+function GetContents() {\r
+       // Get the editor instance that you want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+\r
+       // Get editor contents\r
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData\r
+       alert( editor.getData() );\r
+}\r
+\r
+function ExecuteCommand( commandName ) {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+\r
+       // Check the active editing mode.\r
+       if ( editor.mode == 'wysiwyg' )\r
+       {\r
+               // Execute the command.\r
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand\r
+               editor.execCommand( commandName );\r
+       }\r
+       else\r
+               alert( 'You must be in WYSIWYG mode!' );\r
+}\r
+\r
+function CheckDirty() {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+       // Checks whether the current editor contents present changes when compared\r
+       // to the contents loaded into the editor at startup\r
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty\r
+       alert( editor.checkDirty() );\r
+}\r
+\r
+function ResetDirty() {\r
+       // Get the editor instance that we want to interact with.\r
+       var editor = CKEDITOR.instances.editor1;\r
+       // Resets the "dirty state" of the editor (see CheckDirty())\r
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-resetDirty\r
+       editor.resetDirty();\r
+       alert( 'The "IsDirty" status has been reset' );\r
+}\r
+\r
+function Focus() {\r
+       CKEDITOR.instances.editor1.focus();\r
+}\r
+\r
+function onFocus() {\r
+       document.getElementById( 'eMessage' ).innerHTML = '<b>' + this.name + ' is focused </b>';\r
+}\r
+\r
+function onBlur() {\r
+       document.getElementById( 'eMessage' ).innerHTML = this.name + ' lost focus';\r
+}\r
+\r
+       </script>\r
+\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Using CKEditor JavaScript API\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/api.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+       <p>\r
+               This sample shows how to use the\r
+               <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.editor">CKEditor JavaScript API</a>\r
+               to interact with the editor at runtime.\r
+       </p>\r
+       <p>\r
+               For details on how to create this setup check the source code of this sample page.\r
+       </p>\r
+       </div>\r
+\r
+       <!-- This <div> holds alert messages to be display in the sample page. -->\r
+       <div id="alerts">\r
+               <noscript>\r
+                       <p>\r
+                               <strong>CKEditor requires JavaScript to run</strong>. In a browser with no JavaScript\r
+                               support, like yours, you should still see the contents (HTML data) and you should\r
+                               be able to edit it normally, without a rich editor interface.\r
+                       </p>\r
+               </noscript>\r
+       </div>\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <textarea cols="100" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+\r
+               <script>\r
+                       // Replace the <textarea id="editor1"> with an CKEditor instance.\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               on: {\r
+                                       focus: onFocus,\r
+                                       blur: onBlur,\r
+\r
+                                       // Check for availability of corresponding plugins.\r
+                                       pluginsLoaded: function( evt ) {\r
+                                               var doc = CKEDITOR.document, ed = evt.editor;\r
+                                               if ( !ed.getCommand( 'bold' ) )\r
+                                                       doc.getById( 'exec-bold' ).hide();\r
+                                               if ( !ed.getCommand( 'link' ) )\r
+                                                       doc.getById( 'exec-link' ).hide();\r
+                                       }\r
+                               }\r
+                       });\r
+               </script>\r
+\r
+               <p id="eMessage">\r
+               </p>\r
+\r
+               <div id="eButtons" style="display: none">\r
+                       <input id="exec-bold" onclick="ExecuteCommand('bold');" type="button" value="Execute &quot;bold&quot; Command">\r
+                       <input id="exec-link" onclick="ExecuteCommand('link');" type="button" value="Execute &quot;link&quot; Command">\r
+                       <input onclick="Focus();" type="button" value="Focus">\r
+                       <br><br>\r
+                       <input onclick="InsertHTML();" type="button" value="Insert HTML">\r
+                       <input onclick="SetContents();" type="button" value="Set Editor Contents">\r
+                       <input onclick="GetContents();" type="button" value="Get Editor Contents (HTML)">\r
+                       <br>\r
+                       <textarea cols="100" id="htmlArea" rows="3">&lt;h2&gt;Test&lt;/h2&gt;&lt;p&gt;This is some &lt;a href="/Test1.html"&gt;sample&lt;/a&gt; HTML code.&lt;/p&gt;</textarea>\r
+                       <br>\r
+                       <br>\r
+                       <input onclick="InsertText();" type="button" value="Insert Text">\r
+                       <br>\r
+                       <textarea cols="100" id="txtArea" rows="3">   First line with some leading whitespaces.\r
+\r
+Second line of text preceded by two line breaks.</textarea>\r
+                       <br>\r
+                       <br>\r
+                       <input onclick="CheckDirty();" type="button" value="checkDirty()">\r
+                       <input onclick="ResetDirty();" type="button" value="resetDirty()">\r
+               </div>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/appendto.html b/release/samples/old/appendto.html
new file mode 100644 (file)
index 0000000..dbabf75
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Append To Page Element Using JavaScript Code &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Append To Page Element Using JavaScript Code\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div id="section1">\r
+               <div class="description">\r
+                       <p>\r
+                               The <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR-method-appendTo">CKEDITOR.appendTo()</a></code> method serves to to place editors inside existing DOM elements. Unlike <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR-method-replace">CKEDITOR.replace()</a></code>,\r
+                               a target container to be replaced is no longer necessary. A new editor\r
+                               instance is inserted directly wherever it is desired.\r
+                       </p>\r
+<pre class="samples">CKEDITOR.appendTo( '<em>container_id</em>',\r
+       { /* Configuration options to be used. */ }\r
+       'Editor content to be used.'\r
+);</pre>\r
+               </div>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // DOM element to append CKEditor to or inside the <head><script>\r
+                       // in a window.onload event handler.\r
+\r
+                       // Append a CKEditor instance using the default configuration and the\r
+                       // provided content to the <div> element of ID "section1".\r
+                       CKEDITOR.appendTo( 'section1',\r
+                               null,\r
+                               '<p>This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.</p>'\r
+                       );\r
+\r
+               </script>\r
+       </div>\r
+       <br>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/assets/inlineall/logo.png b/release/samples/old/assets/inlineall/logo.png
new file mode 100644 (file)
index 0000000..b4d5979
Binary files /dev/null and b/release/samples/old/assets/inlineall/logo.png differ
diff --git a/release/samples/old/assets/outputxhtml/outputxhtml.css b/release/samples/old/assets/outputxhtml/outputxhtml.css
new file mode 100644 (file)
index 0000000..fbcc767
--- /dev/null
@@ -0,0 +1,204 @@
+/*\r
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ *\r
+ * Styles used by the XHTML 1.1 sample page (xhtml.html).\r
+ */\r
+\r
+/**\r
+ * Basic definitions for the editing area.\r
+ */\r
+body\r
+{\r
+       font-family: Arial, Verdana, sans-serif;\r
+       font-size: 80%;\r
+       color: #000000;\r
+       background-color: #ffffff;\r
+       padding: 5px;\r
+       margin: 0px;\r
+}\r
+\r
+/**\r
+ * Core styles.\r
+ */\r
+\r
+.Bold\r
+{\r
+       font-weight: bold;\r
+}\r
+\r
+.Italic\r
+{\r
+       font-style: italic;\r
+}\r
+\r
+.Underline\r
+{\r
+       text-decoration: underline;\r
+}\r
+\r
+.StrikeThrough\r
+{\r
+       text-decoration: line-through;\r
+}\r
+\r
+.Subscript\r
+{\r
+       vertical-align: sub;\r
+       font-size: smaller;\r
+}\r
+\r
+.Superscript\r
+{\r
+       vertical-align: super;\r
+       font-size: smaller;\r
+}\r
+\r
+/**\r
+ * Font faces.\r
+ */\r
+\r
+.FontComic\r
+{\r
+       font-family: 'Comic Sans MS';\r
+}\r
+\r
+.FontCourier\r
+{\r
+       font-family: 'Courier New';\r
+}\r
+\r
+.FontTimes\r
+{\r
+       font-family: 'Times New Roman';\r
+}\r
+\r
+/**\r
+ * Font sizes.\r
+ */\r
+\r
+.FontSmaller\r
+{\r
+       font-size: smaller;\r
+}\r
+\r
+.FontLarger\r
+{\r
+       font-size: larger;\r
+}\r
+\r
+.FontSmall\r
+{\r
+       font-size: 8pt;\r
+}\r
+\r
+.FontBig\r
+{\r
+       font-size: 14pt;\r
+}\r
+\r
+.FontDouble\r
+{\r
+       font-size: 200%;\r
+}\r
+\r
+/**\r
+ * Font colors.\r
+ */\r
+.FontColor1\r
+{\r
+       color: #ff9900;\r
+}\r
+\r
+.FontColor2\r
+{\r
+       color: #0066cc;\r
+}\r
+\r
+.FontColor3\r
+{\r
+       color: #ff0000;\r
+}\r
+\r
+.FontColor1BG\r
+{\r
+       background-color: #ff9900;\r
+}\r
+\r
+.FontColor2BG\r
+{\r
+       background-color: #0066cc;\r
+}\r
+\r
+.FontColor3BG\r
+{\r
+       background-color: #ff0000;\r
+}\r
+\r
+/**\r
+ * Indentation.\r
+ */\r
+\r
+.Indent1\r
+{\r
+       margin-left: 40px;\r
+}\r
+\r
+.Indent2\r
+{\r
+       margin-left: 80px;\r
+}\r
+\r
+.Indent3\r
+{\r
+       margin-left: 120px;\r
+}\r
+\r
+/**\r
+ * Alignment.\r
+ */\r
+\r
+.JustifyLeft\r
+{\r
+       text-align: left;\r
+}\r
+\r
+.JustifyRight\r
+{\r
+       text-align: right;\r
+}\r
+\r
+.JustifyCenter\r
+{\r
+       text-align: center;\r
+}\r
+\r
+.JustifyFull\r
+{\r
+       text-align: justify;\r
+}\r
+\r
+/**\r
+ * Other.\r
+ */\r
+\r
+code\r
+{\r
+       font-family: courier, monospace;\r
+       background-color: #eeeeee;\r
+       padding-left: 1px;\r
+       padding-right: 1px;\r
+       border: #c0c0c0 1px solid;\r
+}\r
+\r
+kbd\r
+{\r
+       padding: 0px 1px 0px 1px;\r
+       border-width: 1px 2px 2px 1px;\r
+       border-style: solid;\r
+}\r
+\r
+blockquote\r
+{\r
+       color: #808080;\r
+}\r
diff --git a/release/samples/old/assets/posteddata.php b/release/samples/old/assets/posteddata.php
new file mode 100644 (file)
index 0000000..bb4dd94
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>\r
+<?php\r
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+?>\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Sample &mdash; CKEditor</title>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               CKEditor &mdash; Posted Data\r
+       </h1>\r
+       <table border="1" cellspacing="0" id="outputSample">\r
+               <colgroup><col width="120"></colgroup>\r
+               <thead>\r
+                       <tr>\r
+                               <th>Field&nbsp;Name</th>\r
+                               <th>Value</th>\r
+                       </tr>\r
+               </thead>\r
+<?php\r
+\r
+if (!empty($_POST))\r
+{\r
+       foreach ( $_POST as $key => $value )\r
+       {\r
+               if ( ( !is_string($value) && !is_numeric($value) ) || !is_string($key) )\r
+                       continue;\r
+\r
+               if ( get_magic_quotes_gpc() )\r
+                       $value = htmlspecialchars( stripslashes((string)$value) );\r
+               else\r
+                       $value = htmlspecialchars( (string)$value );\r
+?>\r
+               <tr>\r
+                       <th style="vertical-align: top"><?php echo htmlspecialchars( (string)$key ); ?></th>\r
+                       <td><pre class="samples"><?php echo $value; ?></pre></td>\r
+               </tr>\r
+       <?php\r
+       }\r
+}\r
+?>\r
+       </table>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/assets/sample.jpg b/release/samples/old/assets/sample.jpg
new file mode 100644 (file)
index 0000000..9498271
Binary files /dev/null and b/release/samples/old/assets/sample.jpg differ
diff --git a/release/samples/old/assets/uilanguages/languages.js b/release/samples/old/assets/uilanguages/languages.js
new file mode 100644 (file)
index 0000000..df904e1
--- /dev/null
@@ -0,0 +1,7 @@
+/*
+ Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+var CKEDITOR_LANGS=function(){var c={af:"Afrikaans",ar:"Arabic",az:"Azerbaijani",bg:"Bulgarian",bn:"Bengali/Bangla",bs:"Bosnian",ca:"Catalan",cs:"Czech",cy:"Welsh",da:"Danish",de:"German","de-ch":"German (Switzerland)",el:"Greek",en:"English","en-au":"English (Australia)","en-ca":"English (Canadian)","en-gb":"English (United Kingdom)",eo:"Esperanto",es:"Spanish",et:"Estonian",eu:"Basque",fa:"Persian",fi:"Finnish",fo:"Faroese",fr:"French","fr-ca":"French (Canada)",gl:"Galician",gu:"Gujarati",he:"Hebrew",
+hi:"Hindi",hr:"Croatian",hu:"Hungarian",id:"Indonesian",is:"Icelandic",it:"Italian",ja:"Japanese",ka:"Georgian",km:"Khmer",ko:"Korean",ku:"Kurdish",lt:"Lithuanian",lv:"Latvian",mk:"Macedonian",mn:"Mongolian",ms:"Malay",nb:"Norwegian Bokmal",nl:"Dutch",no:"Norwegian",oc:"Occitan",pl:"Polish",pt:"Portuguese (Portugal)","pt-br":"Portuguese (Brazil)",ro:"Romanian",ru:"Russian",si:"Sinhala",sk:"Slovak",sq:"Albanian",sl:"Slovenian",sr:"Serbian (Cyrillic)","sr-latn":"Serbian (Latin)",sv:"Swedish",th:"Thai",
+tr:"Turkish",tt:"Tatar",ug:"Uighur",uk:"Ukrainian",vi:"Vietnamese",zh:"Chinese Traditional","zh-cn":"Chinese Simplified"},b=[],a;for(a in CKEDITOR.lang.languages)b.push({code:a,name:c[a]||a});b.sort(function(a,b){return a.name<b.name?-1:1});return b}();
\ No newline at end of file
diff --git a/release/samples/old/datafiltering.html b/release/samples/old/datafiltering.html
new file mode 100644 (file)
index 0000000..637c17b
--- /dev/null
@@ -0,0 +1,508 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Data Filtering &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+       <script>\r
+               // Remove advanced tabs for all editors.\r
+               CKEDITOR.config.removeDialogTabs = 'image:advanced;link:advanced;flash:advanced;creatediv:advanced;editdiv:advanced';\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Data Filtering and Features Activation\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/acf.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample page demonstrates the idea of Advanced Content Filter\r
+                       (<abbr title="Advanced Content Filter">ACF</abbr>), a sophisticated\r
+                       tool that takes control over what kind of data is accepted by the editor and what\r
+                       kind of output is produced.\r
+               </p>\r
+               <h2>When and what is being filtered?</h2>\r
+               <p>\r
+                       <abbr title="Advanced Content Filter">ACF</abbr> controls\r
+                       <strong>every single source of data</strong> that comes to the editor.\r
+                       It process both HTML that is inserted manually (i.e. pasted by the user)\r
+                       and programmatically like:\r
+               </p>\r
+<pre class="samples">\r
+editor.setData( '&lt;p&gt;Hello world!&lt;/p&gt;' );\r
+</pre>\r
+               <p>\r
+                       <abbr title="Advanced Content Filter">ACF</abbr> discards invalid,\r
+                       useless HTML tags and attributes so the editor remains "clean" during\r
+                       runtime. <abbr title="Advanced Content Filter">ACF</abbr> behaviour\r
+                       can be configured and adjusted for a particular case to prevent the\r
+                       output HTML (i.e. in CMS systems) from being polluted.\r
+\r
+                       This kind of filtering is a first, client-side line of defense\r
+                       against "<a href="http://en.wikipedia.org/wiki/Tag_soup">tag soups</a>",\r
+                       the tool that precisely restricts which tags, attributes and styles\r
+                       are allowed (desired). When properly configured, <abbr title="Advanced Content Filter">ACF</abbr>\r
+                       is an easy and fast way to produce a high-quality, intentionally filtered HTML.\r
+               </p>\r
+\r
+               <h3>How to configure or disable ACF?</h3>\r
+               <p>\r
+                       Advanced Content Filter is enabled by default, working in "automatic mode", yet\r
+                       it provides a set of easy rules that allow adjusting filtering rules\r
+                       and disabling the entire feature when necessary. The config property\r
+                       responsible for this feature is <code><a class="samples"\r
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">config.allowedContent</a></code>.\r
+               </p>\r
+               <p>\r
+                       By "automatic mode" is meant that loaded plugins decide which kind\r
+                       of content is enabled and which is not. For example, if the link\r
+                       plugin is loaded it implies that <code>&lt;a&gt;</code> tag is\r
+                       automatically allowed. Each plugin is given a set\r
+                       of predefined <abbr title="Advanced Content Filter">ACF</abbr> rules\r
+                       that control the editor until <code><a class="samples"\r
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">\r
+                       config.allowedContent</a></code>\r
+                       is defined manually.\r
+               </p>\r
+               <p>\r
+                       Let's assume our intention is to restrict the editor to accept (produce) <strong>paragraphs\r
+                       only: no attributes, no styles, no other tags</strong>.\r
+                       With <abbr title="Advanced Content Filter">ACF</abbr>\r
+                       this is very simple. Basically set <code><a class="samples"\r
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">\r
+                       config.allowedContent</a></code> to <code>'p'</code>:\r
+               </p>\r
+<pre class="samples">\r
+var editor = CKEDITOR.replace( <em>textarea_id</em>, {\r
+       <strong>allowedContent: 'p'</strong>\r
+} );\r
+</pre>\r
+               <p>\r
+                       Now try to play with allowed content:\r
+               </p>\r
+<pre class="samples">\r
+// Trying to insert disallowed tag and attribute.\r
+editor.setData( '&lt;p <strong>style="color: red"</strong>&gt;Hello <strong>&lt;em&gt;world&lt;/em&gt;</strong>!&lt;/p&gt;' );\r
+alert( editor.getData() );\r
+\r
+// Filtered data is returned.\r
+"&lt;p&gt;Hello world!&lt;/p&gt;"\r
+</pre>\r
+               <p>\r
+                       What happened? Since <code>config.allowedContent: 'p'</code> is set the editor assumes\r
+                       that only plain <code>&lt;p&gt;</code> are accepted. Nothing more. This is why\r
+                       <code>style</code> attribute and <code>&lt;em&gt;</code> tag are gone. The same\r
+                       filtering would happen if we pasted disallowed HTML into this editor.\r
+               </p>\r
+               <p>\r
+                       This is just a small sample of what <abbr title="Advanced Content Filter">ACF</abbr>\r
+                       can do. To know more, please refer to the sample section below and\r
+                       <a href="http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter">the official Advanced Content Filter guide</a>.\r
+               </p>\r
+               <p>\r
+                       You may, of course, want CKEditor to avoid filtering of any kind.\r
+                       To get rid of <abbr title="Advanced Content Filter">ACF</abbr>,\r
+                       basically set <code><a class="samples"\r
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">\r
+                       config.allowedContent</a></code> to <code>true</code> like this:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( <em>textarea_id</em>, {\r
+       <strong>allowedContent: true</strong>\r
+} );\r
+</pre>\r
+\r
+               <h2>Beyond data flow: Features activation</h2>\r
+               <p>\r
+                       <abbr title="Advanced Content Filter">ACF</abbr> is far more than\r
+                       <abbr title="Input/Output">I/O</abbr> control: the entire\r
+                       <abbr title="User Interface">UI</abbr> of the editor is adjusted to what\r
+                       filters restrict. For example: if <code>&lt;a&gt;</code> tag is\r
+                       <strong>disallowed</strong>\r
+                       by <abbr title="Advanced Content Filter">ACF</abbr>,\r
+                       then accordingly <code>link</code> command, toolbar button and link dialog\r
+                       are also disabled. Editor is smart: it knows which features must be\r
+                       removed from the interface to match filtering rules.\r
+               </p>\r
+               <p>\r
+                       CKEditor can be far more specific. If <code>&lt;a&gt;</code> tag is\r
+                       <strong>allowed</strong> by filtering rules to be used but it is restricted\r
+                       to have only one attribute (<code>href</code>)\r
+                       <code>config.allowedContent = 'a[!href]'</code>, then\r
+                       "Target" tab of the link dialog is automatically disabled as <code>target</code>\r
+                       attribute isn't included in <abbr title="Advanced Content Filter">ACF</abbr> rules\r
+                       for <code>&lt;a&gt;</code>. This behaviour applies to dialog fields, context\r
+                       menus and toolbar buttons.\r
+               </p>\r
+\r
+               <h2>Sample configurations</h2>\r
+               <p>\r
+                       There are several editor instances below that present different\r
+                       <abbr title="Advanced Content Filter">ACF</abbr> setups. <strong>All of them,\r
+                       except the inline instance, share the same HTML content</strong> to visualize\r
+                       how different filtering rules affect the same input data.\r
+               </p>\r
+       </div>\r
+\r
+       <div>\r
+               <label for="editor1">\r
+                       Editor 1:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using default configuration ("automatic mode"). It means that\r
+                               <code><a class="samples"\r
+                               href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">\r
+                               config.allowedContent</a></code> is defined by loaded plugins.\r
+                               Each plugin extends filtering rules to make it's own associated content\r
+                               available for the user.\r
+                       </p>\r
+               </div>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor1' );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor2">\r
+                       Editor 2:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a custom configuration for\r
+                               <abbr title="Advanced Content Filter">ACF</abbr>:\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor2', {\r
+       allowedContent:\r
+               'h1 h2 h3 p blockquote strong em;' +\r
+               'a[!href];' +\r
+               'img(left,right)[!src,alt,width,height];' +\r
+               'table tr th td caption;' +\r
+               'span{!font-family};' +'\r
+               'span{!color};' +\r
+               'span(!marker);' +\r
+               'del ins'\r
+} );\r
+</pre>\r
+                       <p>\r
+                               The following rules may require additional explanation:\r
+                       </p>\r
+                       <ul>\r
+                               <li>\r
+                                       <code>h1 h2 h3 p blockquote strong em</code> - These tags\r
+                                       are accepted by the editor. Any tag attributes will be discarded.\r
+                               </li>\r
+                               <li>\r
+                                       <code>a[!href]</code> - <code>href</code> attribute is obligatory\r
+                                       for <code>&lt;a&gt;</code> tag. Tags without this attribute\r
+                                       are disarded. No other attribute will be accepted.\r
+                               </li>\r
+                               <li>\r
+                                       <code>img(left,right)[!src,alt,width,height]</code> - <code>src</code>\r
+                                       attribute is obligatory for <code>&lt;img&gt;</code> tag.\r
+                                       <code>alt</code>, <code>width</code>, <code>height</code>\r
+                                       and <code>class</code> attributes are accepted but\r
+                                       <code>class</code> must be either <code>class="left"</code>\r
+                                       or <code>class="right"</code>\r
+                               </li>\r
+                               <li>\r
+                                       <code>table tr th td caption</code> - These tags\r
+                                       are accepted by the editor. Any tag attributes will be discarded.\r
+                               </li>\r
+                               <li>\r
+                                       <code>span{!font-family}</code>, <code>span{!color}</code>,\r
+                                       <code>span(!marker)</code> - <code>&lt;span&gt;</code> tags\r
+                                       will be accepted if either <code>font-family</code> or\r
+                                       <code>color</code> style is set or <code>class="marker"</code>\r
+                                       is present.\r
+                               </li>\r
+                               <li>\r
+                                       <code>del ins</code> - These tags\r
+                                       are accepted by the editor. Any tag attributes will be discarded.\r
+                               </li>\r
+                       </ul>\r
+                       <p>\r
+                               Please note that <strong><abbr title="User Interface">UI</abbr> of the\r
+                               editor is different</strong>. It's a response to what happened to the filters.\r
+                               Since <code>text-align</code> isn't allowed, the align toolbar is gone.\r
+                               The same thing happened to subscript/superscript, strike, underline\r
+                               (<code>&lt;u&gt;</code>, <code>&lt;sub&gt;</code>, <code>&lt;sup&gt;</code>\r
+                               are disallowed by <code><a class="samples"\r
+                               href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">\r
+                               config.allowedContent</a></code>) and many other buttons.\r
+                       </p>\r
+               </div>\r
+               <textarea cols="80" id="editor2" name="editor2" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor2', {\r
+                               allowedContent:\r
+                                       'h1 h2 h3 p blockquote strong em;' +\r
+                                       'a[!href];' +\r
+                                       'img(left,right)[!src,alt,width,height];' +\r
+                                       'table tr th td caption;' +\r
+                                       'span{!font-family};' +\r
+                                       'span{!color};' +\r
+                                       'span(!marker);' +\r
+                                       'del ins'\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor3">\r
+                       Editor 3:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a custom configuration for\r
+                               <abbr title="Advanced Content Filter">ACF</abbr>.\r
+                               Note that filters can be configured as an object literal\r
+                               as an alternative to a string-based definition.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor3', {\r
+       allowedContent: {\r
+               'b i ul ol big small': true,\r
+               'h1 h2 h3 p blockquote li': {\r
+                       styles: 'text-align'\r
+               },\r
+               a: { attributes: '!href,target' },\r
+               img: {\r
+                       attributes: '!src,alt',\r
+                       styles: 'width,height',\r
+                       classes: 'left,right'\r
+               }\r
+       }\r
+} );\r
+</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor3" name="editor3" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor3', {\r
+                               allowedContent: {\r
+                                       'b i ul ol big small': true,\r
+                                       'h1 h2 h3 p blockquote li': {\r
+                                               styles: 'text-align'\r
+                                       },\r
+                                       a: { attributes: '!href,target' },\r
+                                       img: {\r
+                                               attributes: '!src,alt',\r
+                                               styles: 'width,height',\r
+                                               classes: 'left,right'\r
+                                       }\r
+                               }\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor4">\r
+                       Editor 4:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a custom set of plugins and buttons.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor4', {\r
+       removePlugins: 'bidi,font,forms,flash,horizontalrule,iframe,justify,table,tabletools,smiley',\r
+       removeButtons: 'Anchor,Underline,Strike,Subscript,Superscript,Image',\r
+       format_tags: 'p;h1;h2;h3;pre;address'\r
+} );\r
+</pre>\r
+                       <p>\r
+                               As you can see, removing plugins and buttons implies filtering.\r
+                               Several tags are not allowed in the editor because there's no\r
+                               plugin/button that is responsible for creating and editing this\r
+                               kind of content (for example: the image is missing because\r
+                               of <code>removeButtons: 'Image'</code>). The conclusion is that\r
+                               <abbr title="Advanced Content Filter">ACF</abbr> works "backwards"\r
+                               as well: <strong>modifying <abbr title="User Interface">UI</abbr>\r
+                               elements is changing allowed content rules</strong>.\r
+                       </p>\r
+               </div>\r
+               <textarea cols="80" id="editor4" name="editor4" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor4', {\r
+                               removePlugins: 'bidi,div,font,forms,flash,horizontalrule,iframe,justify,table,tabletools,smiley',\r
+                               removeButtons: 'Anchor,Underline,Strike,Subscript,Superscript,Image',\r
+                               format_tags: 'p;h1;h2;h3;pre;address'\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor5">\r
+                       Editor 5:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is built on editable <code>&lt;h1&gt;</code> element.\r
+                               <abbr title="Advanced Content Filter">ACF</abbr> takes care of\r
+                               what can be included in <code>&lt;h1&gt;</code>. Note that there\r
+                               are no block styles in Styles combo. Also why lists, indentation,\r
+                               blockquote, div, form and other buttons are missing.\r
+                       </p>\r
+                       <p>\r
+                               <abbr title="Advanced Content Filter">ACF</abbr> makes sure that\r
+                               no disallowed tags will come to <code>&lt;h1&gt;</code> so the final\r
+                               markup is valid. If the user tried to paste some invalid HTML\r
+                               into this editor (let's say a list), it would be automatically\r
+                               converted into plain text.\r
+                       </p>\r
+               </div>\r
+               <h1 id="editor5" contenteditable="true">\r
+                       <em>Apollo 11</em> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC.\r
+               </h1>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor3">\r
+                       Editor 6:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a custom configuration for <abbr title="Advanced Content Filter">ACF</abbr>.\r
+                               It's using the <a href="http://docs.ckeditor.com/#!/guide/dev_disallowed_content" rel="noopener noreferrer" target="_blank">\r
+                               Disallowed Content</a> property of the filter to eliminate all <code>title</code> attributes.\r
+                       </p>\r
+\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor6', {\r
+       allowedContent: {\r
+               'b i ul ol big small': true,\r
+               'h1 h2 h3 p blockquote li': {\r
+                       styles: 'text-align'\r
+               },\r
+               a: {attributes: '!href,target'},\r
+               img: {\r
+                       attributes: '!src,alt',\r
+                       styles: 'width,height',\r
+                       classes: 'left,right'\r
+               }\r
+       },\r
+       disallowedContent: '*{title*}'\r
+} );\r
+</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor6" name="editor6" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor6', {\r
+                               allowedContent: {\r
+                                       'b i ul ol big small': true,\r
+                                       'h1 h2 h3 p blockquote li': {\r
+                                               styles: 'text-align'\r
+                                       },\r
+                                       a: {attributes: '!href,target'},\r
+                                       img: {\r
+                                               attributes: '!src,alt',\r
+                                               styles: 'width,height',\r
+                                               classes: 'left,right'\r
+                                       }\r
+                               },\r
+                               disallowedContent: '*{title*}'\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <br>\r
+\r
+       <div>\r
+               <label for="editor7">\r
+                       Editor 7:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a custom configuration for <abbr title="Advanced Content Filter">ACF</abbr>.\r
+                               It's using the <a href="http://docs.ckeditor.com/#!/guide/dev_disallowed_content" rel="noopener noreferrer" target="_blank">\r
+                               Disallowed Content</a> property of the filter to eliminate all <code>a</code> and <code>img</code> tags,\r
+                               while allowing all other tags.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor7', {\r
+       allowedContent: {\r
+               // Allow all content.\r
+               $1: {\r
+                       elements: CKEDITOR.dtd,\r
+                       attributes: true,\r
+                       styles: true,\r
+                       classes: true\r
+               }\r
+       },\r
+       disallowedContent: 'img a'\r
+} );\r
+</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor7" name="editor7" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor7', {\r
+                               allowedContent: {\r
+                                       // allow all content\r
+                                       $1: {\r
+                                               elements: CKEDITOR.dtd,\r
+                                               attributes: true,\r
+                                               styles: true,\r
+                                               classes: true\r
+                                       }\r
+                               },\r
+                               disallowedContent: 'img a'\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/dialog/assets/my_dialog.js b/release/samples/old/dialog/assets/my_dialog.js
new file mode 100644 (file)
index 0000000..fcd1a43
--- /dev/null
@@ -0,0 +1,48 @@
+/**\r
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.dialog.add( 'myDialog', function() {\r
+       return {\r
+               title: 'My Dialog',\r
+               minWidth: 400,\r
+               minHeight: 200,\r
+               contents: [\r
+                       {\r
+                               id: 'tab1',\r
+                               label: 'First Tab',\r
+                               title: 'First Tab',\r
+                               elements: [\r
+                                       {\r
+                                               id: 'input1',\r
+                                               type: 'text',\r
+                                               label: 'Text Field'\r
+                                       },\r
+                                       {\r
+                                               id: 'select1',\r
+                                               type: 'select',\r
+                                               label: 'Select Field',\r
+                                               items: [\r
+                                                       [ 'option1', 'value1' ],\r
+                                                       [ 'option2', 'value2' ]\r
+                                               ]\r
+                                       }\r
+                               ]\r
+                       },\r
+                       {\r
+                               id: 'tab2',\r
+                               label: 'Second Tab',\r
+                               title: 'Second Tab',\r
+                               elements: [\r
+                                       {\r
+                                               id: 'button1',\r
+                                               type: 'button',\r
+                                               label: 'Button Field'\r
+                                       }\r
+                               ]\r
+                       }\r
+               ]\r
+       };\r
+} );\r
+\r
diff --git a/release/samples/old/dialog/dialog.html b/release/samples/old/dialog/dialog.html
new file mode 100644 (file)
index 0000000..0f22a1a
--- /dev/null
@@ -0,0 +1,190 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Using API to Customize Dialog Windows &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-name" content="Using the JavaScript API to customize dialog windows">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Using the dialog windows API to customize dialog windows without changing the original editor code.">\r
+       <style>\r
+\r
+               .cke_button__mybutton_icon\r
+               {\r
+                       display: none !important;\r
+               }\r
+\r
+               .cke_button__mybutton_label\r
+               {\r
+                       display: inline !important;\r
+               }\r
+\r
+       </style>\r
+       <script>\r
+\r
+               CKEDITOR.on( 'instanceCreated', function( ev ){\r
+                       var editor = ev.editor;\r
+\r
+                       // Listen for the "pluginsLoaded" event, so we are sure that the\r
+                       // "dialog" plugin has been loaded and we are able to do our\r
+                       // customizations.\r
+                       editor.on( 'pluginsLoaded', function() {\r
+\r
+                               // If our custom dialog has not been registered, do that now.\r
+                               if ( !CKEDITOR.dialog.exists( 'myDialog' ) ) {\r
+                                       // We need to do the following trick to find out the dialog\r
+                                       // definition file URL path. In the real world, you would simply\r
+                                       // point to an absolute path directly, like "/mydir/mydialog.js".\r
+                                       var href = document.location.href.split( '/' );\r
+                                       href.pop();\r
+                                       href.push( 'assets/my_dialog.js' );\r
+                                       href = href.join( '/' );\r
+\r
+                                       // Finally, register the dialog.\r
+                                       CKEDITOR.dialog.add( 'myDialog', href );\r
+                               }\r
+\r
+                               // Register the command used to open the dialog.\r
+                               editor.addCommand( 'myDialogCmd', new CKEDITOR.dialogCommand( 'myDialog' ) );\r
+\r
+                               // Add the a custom toolbar buttons, which fires the above\r
+                               // command..\r
+                               editor.ui.add( 'MyButton', CKEDITOR.UI_BUTTON, {\r
+                                       label: 'My Dialog',\r
+                                       command: 'myDialogCmd'\r
+                               });\r
+                       });\r
+               });\r
+\r
+               // When opening a dialog, its "definition" is created for it, for\r
+               // each editor instance. The "dialogDefinition" event is then\r
+               // fired. We should use this event to make customizations to the\r
+               // definition of existing dialogs.\r
+               CKEDITOR.on( 'dialogDefinition', function( ev ) {\r
+                       // Take the dialog name and its definition from the event data.\r
+                       var dialogName = ev.data.name;\r
+                       var dialogDefinition = ev.data.definition;\r
+\r
+                       // Check if the definition is from the dialog we're\r
+                       // interested on (the "Link" dialog).\r
+                       if ( dialogName == 'myDialog' && ev.editor.name == 'editor2' ) {\r
+                               // Get a reference to the "Link Info" tab.\r
+                               var infoTab = dialogDefinition.getContents( 'tab1' );\r
+\r
+                               // Add a new text field to the "tab1" tab page.\r
+                               infoTab.add( {\r
+                                       type: 'text',\r
+                                       label: 'My Custom Field',\r
+                                       id: 'customField',\r
+                                       'default': 'Sample!',\r
+                                       validate: function() {\r
+                                               if ( ( /\d/ ).test( this.getValue() ) )\r
+                                                       return 'My Custom Field must not contain digits';\r
+                                       }\r
+                               });\r
+\r
+                               // Remove the "select1" field from the "tab1" tab.\r
+                               infoTab.remove( 'select1' );\r
+\r
+                               // Set the default value for "input1" field.\r
+                               var input1 = infoTab.get( 'input1' );\r
+                               input1[ 'default' ] = 'www.example.com';\r
+\r
+                               // Remove the "tab2" tab page.\r
+                               dialogDefinition.removeContents( 'tab2' );\r
+\r
+                               // Add a new tab to the "Link" dialog.\r
+                               dialogDefinition.addContents( {\r
+                                       id: 'customTab',\r
+                                       label: 'My Tab',\r
+                                       accessKey: 'M',\r
+                                       elements: [\r
+                                               {\r
+                                                       id: 'myField1',\r
+                                                       type: 'text',\r
+                                                       label: 'My Text Field'\r
+                                               },\r
+                                               {\r
+                                                       id: 'myField2',\r
+                                                       type: 'text',\r
+                                                       label: 'Another Text Field'\r
+                                               }\r
+                                       ]\r
+                               });\r
+\r
+                               // Provide the focus handler to start initial focus in "customField" field.\r
+                               dialogDefinition.onFocus = function() {\r
+                                       var urlField = this.getContentElement( 'tab1', 'customField' );\r
+                                       urlField.select();\r
+                               };\r
+                       }\r
+               });\r
+\r
+               var config = {\r
+                       extraPlugins: 'dialog',\r
+                       toolbar: [ [ 'MyButton' ] ]\r
+               };\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Using CKEditor Dialog API\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to use the\r
+                       <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.dialog">CKEditor Dialog API</a>\r
+                       to customize CKEditor dialog windows without changing the original editor code.\r
+                       The following customizations are being done in the example below:\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <p>A custom dialog is added to the editors using the <code>pluginsLoaded</code> event, from an external <a target="_blank" href="assets/my_dialog.js">dialog definition file</a>:</p>\r
+       <ol>\r
+               <li><strong>Creating a custom dialog window</strong> &ndash; "My Dialog" dialog window opened with the "My Dialog" toolbar button.</li>\r
+               <li><strong>Creating a custom button</strong> &ndash; Add button to open the dialog with "My Dialog" toolbar button.</li>\r
+       </ol>\r
+       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+       <script>\r
+               // Replace the <textarea id="editor1"> with an CKEditor instance.\r
+               CKEDITOR.replace( 'editor1', config );\r
+       </script>\r
+       <p>The below editor modify the dialog definition of the above added dialog using the <code>dialogDefinition</code> event:</p>\r
+       <ol>\r
+               <li><strong>Adding dialog tab</strong> &ndash; Add new tab "My Tab" to dialog window.</li>\r
+               <li><strong>Removing a dialog window tab</strong> &ndash; Remove "Second Tab" page from the dialog window.</li>\r
+               <li><strong>Adding dialog window fields</strong> &ndash; Add "My Custom Field" to the dialog window.</li>\r
+               <li><strong>Removing dialog window field</strong> &ndash; Remove "Select Field" selection field from the dialog window.</li>\r
+               <li><strong>Setting default values for dialog window fields</strong> &ndash; Set default value of "Text Field" text field. </li>\r
+               <li><strong>Setup initial focus for dialog window</strong> &ndash; Put initial focus on "My Custom Field" text field. </li>\r
+       </ol>\r
+       <textarea cols="80" id="editor2" name="editor2" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+       <script>\r
+\r
+               // Replace the <textarea id="editor1"> with an CKEditor instance.\r
+               CKEDITOR.replace( 'editor2', config );\r
+\r
+       </script>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/divreplace.html b/release/samples/old/divreplace.html
new file mode 100644 (file)
index 0000000..c6724f0
--- /dev/null
@@ -0,0 +1,144 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Replace DIV &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               div.editable\r
+               {\r
+                       border: solid 2px transparent;\r
+                       padding-left: 15px;\r
+                       padding-right: 15px;\r
+               }\r
+\r
+               div.editable:hover\r
+               {\r
+                       border-color: black;\r
+               }\r
+\r
+       </style>\r
+       <script>\r
+\r
+               // Uncomment the following code to test the "Timeout Loading Method".\r
+               // CKEDITOR.loadFullCoreTimeout = 5;\r
+\r
+               window.onload = function() {\r
+                       // Listen to the double click event.\r
+                       if ( window.addEventListener )\r
+                               document.body.addEventListener( 'dblclick', onDoubleClick, false );\r
+                       else if ( window.attachEvent )\r
+                               document.body.attachEvent( 'ondblclick', onDoubleClick );\r
+\r
+               };\r
+\r
+               function onDoubleClick( ev ) {\r
+                       // Get the element which fired the event. This is not necessarily the\r
+                       // element to which the event has been attached.\r
+                       var element = ev.target || ev.srcElement;\r
+\r
+                       // Find out the div that holds this element.\r
+                       var name;\r
+\r
+                       do {\r
+                               element = element.parentNode;\r
+                       }\r
+                       while ( element && ( name = element.nodeName.toLowerCase() ) &&\r
+                               ( name != 'div' || element.className.indexOf( 'editable' ) == -1 ) && name != 'body' );\r
+\r
+                       if ( name == 'div' && element.className.indexOf( 'editable' ) != -1 )\r
+                               replaceDiv( element );\r
+               }\r
+\r
+               var editor;\r
+\r
+               function replaceDiv( div ) {\r
+                       if ( editor )\r
+                               editor.destroy();\r
+\r
+                       editor = CKEDITOR.replace( div );\r
+               }\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace DIV with CKEditor on the Fly\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to automatically replace <code>&lt;div&gt;</code> elements\r
+                       with a CKEditor instance on the fly, following user's doubleclick. The content\r
+                       that was previously placed inside the <code>&lt;div&gt;</code> element will now\r
+                       be moved into CKEditor editing area.\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <p>\r
+               Double-click any of the following <code>&lt;div&gt;</code> elements to transform them into\r
+               editor instances.\r
+       </p>\r
+       <div class="editable">\r
+               <h3>\r
+                       Part 1\r
+               </h3>\r
+               <p>\r
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi\r
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna\r
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla\r
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce\r
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.\r
+               </p>\r
+       </div>\r
+       <div class="editable">\r
+               <h3>\r
+                       Part 2\r
+               </h3>\r
+               <p>\r
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi\r
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna\r
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla\r
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce\r
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.\r
+               </p>\r
+               <p>\r
+                       Donec velit. Mauris massa. Vestibulum non nulla. Nam suscipit arcu nec elit. Phasellus\r
+                       sollicitudin iaculis ante. Ut non mauris et sapien tincidunt adipiscing. Vestibulum\r
+                       vitae leo. Suspendisse nec mi tristique nulla laoreet vulputate.\r
+               </p>\r
+       </div>\r
+       <div class="editable">\r
+               <h3>\r
+                       Part 3\r
+               </h3>\r
+               <p>\r
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi\r
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna\r
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla\r
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce\r
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.\r
+               </p>\r
+       </div>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/enterkey/enterkey.html b/release/samples/old/enterkey/enterkey.html
new file mode 100644 (file)
index 0000000..79afee3
--- /dev/null
@@ -0,0 +1,106 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>ENTER Key Configuration &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-name" content="Using the &quot;Enter&quot; key in CKEditor">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring the behavior of &lt;em&gt;Enter&lt;/em&gt; and &lt;em&gt;Shift+Enter&lt;/em&gt; keys.">\r
+       <script>\r
+\r
+               var editor;\r
+\r
+               function changeEnter() {\r
+                       // If we already have an editor, let's destroy it first.\r
+                       if ( editor )\r
+                               editor.destroy( true );\r
+\r
+                       // Create the editor again, with the appropriate settings.\r
+                       editor = CKEDITOR.replace( 'editor1', {\r
+                               extraPlugins: 'enterkey',\r
+                               enterMode: Number( document.getElementById( 'xEnter' ).value ),\r
+                               shiftEnterMode: Number( document.getElementById( 'xShiftEnter' ).value )\r
+                       });\r
+               }\r
+\r
+               window.onload = changeEnter;\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; ENTER Key Configuration\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/enterkey.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure the <em>Enter</em> and <em>Shift+Enter</em> keys\r
+                       to perform actions specified in the\r
+                       <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode"><code>enterMode</code></a>\r
+                       and <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode"><code>shiftEnterMode</code></a>\r
+                       parameters, respectively.\r
+                       You can choose from the following options:\r
+               </p>\r
+               <ul class="samples">\r
+                       <li><strong><code>ENTER_P</code></strong> &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li>\r
+                       <li><strong><code>ENTER_BR</code></strong> &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li>\r
+                       <li><strong><code>ENTER_DIV</code></strong> &ndash; new <code>&lt;div&gt;</code> blocks are created.</li>\r
+               </ul>\r
+               <p>\r
+                       The sample code below shows how to configure CKEditor to create a <code>&lt;div&gt;</code> block when <em>Enter</em> key is pressed.\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       <strong>enterMode: CKEDITOR.ENTER_DIV</strong>\r
+});</pre>\r
+               <p>\r
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+                       the <code>&lt;textarea&gt;</code> element to be replaced.\r
+               </p>\r
+       </div>\r
+       <div style="float: left; margin-right: 20px">\r
+               When <em>Enter</em> is pressed:<br>\r
+               <select id="xEnter" onchange="changeEnter();">\r
+                       <option selected="selected" value="1">Create a new &lt;P&gt; (recommended)</option>\r
+                       <option value="3">Create a new &lt;DIV&gt;</option>\r
+                       <option value="2">Break the line with a &lt;BR&gt;</option>\r
+               </select>\r
+       </div>\r
+       <div style="float: left">\r
+               When <em>Shift+Enter</em> is pressed:<br>\r
+               <select id="xShiftEnter" onchange="changeEnter();">\r
+                       <option value="1">Create a new &lt;P&gt;</option>\r
+                       <option value="3">Create a new &lt;DIV&gt;</option>\r
+                       <option selected="selected" value="2">Break the line with a &lt;BR&gt; (recommended)</option>\r
+               </select>\r
+       </div>\r
+       <br style="clear: both">\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <p>\r
+                       <br>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.</textarea>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla b/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla
new file mode 100644 (file)
index 0000000..27e68cc
Binary files /dev/null and b/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.fla differ
diff --git a/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf b/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf
new file mode 100644 (file)
index 0000000..dbe17b6
Binary files /dev/null and b/release/samples/old/htmlwriter/assets/outputforflash/outputforflash.swf differ
diff --git a/release/samples/old/htmlwriter/assets/outputforflash/swfobject.js b/release/samples/old/htmlwriter/assets/outputforflash/swfobject.js
new file mode 100644 (file)
index 0000000..0700921
--- /dev/null
@@ -0,0 +1,19 @@
+var swfobject=function(){function w(){if(!u){try{var a=d.getElementsByTagName("body")[0].appendChild(d.createElement("span"));a.parentNode.removeChild(a)}catch(b){return}u=!0;for(var a=z.length,c=0;c<a;c++)z[c]()}}function M(a){u?a():z[z.length]=a}function N(a){if("undefined"!=typeof n.addEventListener)n.addEventListener("load",a,!1);else if("undefined"!=typeof d.addEventListener)d.addEventListener("load",a,!1);else if("undefined"!=typeof n.attachEvent)U(n,"onload",a);else if("function"==typeof n.onload){var b=
+n.onload;n.onload=function(){b();a()}}else n.onload=a}function V(){var a=d.getElementsByTagName("body")[0],b=d.createElement("object");b.setAttribute("type","application/x-shockwave-flash");var c=a.appendChild(b);if(c){var f=0;(function(){if("undefined"!=typeof c.GetVariable){var g=c.GetVariable("$version");g&&(g=g.split(" ")[1].split(","),e.pv=[parseInt(g[0],10),parseInt(g[1],10),parseInt(g[2],10)])}else if(10>f){f++;setTimeout(arguments.callee,10);return}a.removeChild(b);c=null;E()})()}else E()}
+function E(){var a=r.length;if(0<a)for(var b=0;b<a;b++){var c=r[b].id,f=r[b].callbackFn,g={success:!1,id:c};if(0<e.pv[0]){var d=p(c);if(d)if(!A(r[b].swfVersion)||e.wk&&312>e.wk)if(r[b].expressInstall&&F()){g={};g.data=r[b].expressInstall;g.width=d.getAttribute("width")||"0";g.height=d.getAttribute("height")||"0";d.getAttribute("class")&&(g.styleclass=d.getAttribute("class"));d.getAttribute("align")&&(g.align=d.getAttribute("align"));for(var h={},d=d.getElementsByTagName("param"),k=d.length,l=0;l<
+k;l++)"movie"!=d[l].getAttribute("name").toLowerCase()&&(h[d[l].getAttribute("name")]=d[l].getAttribute("value"));G(g,h,c,f)}else W(d),f&&f(g);else v(c,!0),f&&(g.success=!0,g.ref=H(c),f(g))}else v(c,!0),f&&((c=H(c))&&"undefined"!=typeof c.SetVariable&&(g.success=!0,g.ref=c),f(g))}}function H(a){var b=null;(a=p(a))&&"OBJECT"==a.nodeName&&("undefined"!=typeof a.SetVariable?b=a:(a=a.getElementsByTagName("object")[0])&&(b=a));return b}function F(){return!B&&A("6.0.65")&&(e.win||e.mac)&&!(e.wk&&312>e.wk)}
+function G(a,b,c,f){B=!0;I=f||null;O={success:!1,id:c};var g=p(c);if(g){"OBJECT"==g.nodeName?(y=J(g),C=null):(y=g,C=c);a.id="SWFObjectExprInst";if("undefined"==typeof a.width||!/%$/.test(a.width)&&310>parseInt(a.width,10))a.width="310";if("undefined"==typeof a.height||!/%$/.test(a.height)&&137>parseInt(a.height,10))a.height="137";d.title=d.title.slice(0,47)+" - Flash Player Installation";f=e.ie&&e.win?"ActiveX":"PlugIn";f="MMredirectURL\x3d"+n.location.toString().replace(/&/g,"%26")+"\x26MMplayerType\x3d"+
+f+"\x26MMdoctitle\x3d"+d.title;b.flashvars="undefined"!=typeof b.flashvars?b.flashvars+("\x26"+f):f;e.ie&&e.win&&4!=g.readyState&&(f=d.createElement("div"),c+="SWFObjectNew",f.setAttribute("id",c),g.parentNode.insertBefore(f,g),g.style.display="none",function(){4==g.readyState?g.parentNode.removeChild(g):setTimeout(arguments.callee,10)}());K(a,b,c)}}function W(a){if(e.ie&&e.win&&4!=a.readyState){var b=d.createElement("div");a.parentNode.insertBefore(b,a);b.parentNode.replaceChild(J(a),b);a.style.display=
+"none";(function(){4==a.readyState?a.parentNode.removeChild(a):setTimeout(arguments.callee,10)})()}else a.parentNode.replaceChild(J(a),a)}function J(a){var b=d.createElement("div");if(e.win&&e.ie)b.innerHTML=a.innerHTML;else if(a=a.getElementsByTagName("object")[0])if(a=a.childNodes)for(var c=a.length,f=0;f<c;f++)1==a[f].nodeType&&"PARAM"==a[f].nodeName||8==a[f].nodeType||b.appendChild(a[f].cloneNode(!0));return b}function K(a,b,c){var f,g=p(c);if(e.wk&&312>e.wk)return f;if(g)if("undefined"==typeof a.id&&
+(a.id=c),e.ie&&e.win){var q="",h;for(h in a)a[h]!=Object.prototype[h]&&("data"==h.toLowerCase()?b.movie=a[h]:"styleclass"==h.toLowerCase()?q+=' class\x3d"'+a[h]+'"':"classid"!=h.toLowerCase()&&(q+=" "+h+'\x3d"'+a[h]+'"'));h="";for(var k in b)b[k]!=Object.prototype[k]&&(h+='\x3cparam name\x3d"'+k+'" value\x3d"'+b[k]+'" /\x3e');g.outerHTML='\x3cobject classid\x3d"clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+q+"\x3e"+h+"\x3c/object\x3e";D[D.length]=a.id;f=p(a.id)}else{k=d.createElement("object");k.setAttribute("type",
+"application/x-shockwave-flash");for(var l in a)a[l]!=Object.prototype[l]&&("styleclass"==l.toLowerCase()?k.setAttribute("class",a[l]):"classid"!=l.toLowerCase()&&k.setAttribute(l,a[l]));for(q in b)b[q]!=Object.prototype[q]&&"movie"!=q.toLowerCase()&&(a=k,h=q,l=b[q],c=d.createElement("param"),c.setAttribute("name",h),c.setAttribute("value",l),a.appendChild(c));g.parentNode.replaceChild(k,g);f=k}return f}function P(a){var b=p(a);b&&"OBJECT"==b.nodeName&&(e.ie&&e.win?(b.style.display="none",function(){if(4==
+b.readyState){var c=p(a);if(c){for(var f in c)"function"==typeof c[f]&&(c[f]=null);c.parentNode.removeChild(c)}}else setTimeout(arguments.callee,10)}()):b.parentNode.removeChild(b))}function p(a){var b=null;try{b=d.getElementById(a)}catch(c){}return b}function U(a,b,c){a.attachEvent(b,c);x[x.length]=[a,b,c]}function A(a){var b=e.pv;a=a.split(".");a[0]=parseInt(a[0],10);a[1]=parseInt(a[1],10)||0;a[2]=parseInt(a[2],10)||0;return b[0]>a[0]||b[0]==a[0]&&b[1]>a[1]||b[0]==a[0]&&b[1]==a[1]&&b[2]>=a[2]?!0:
+!1}function Q(a,b,c,f){if(!e.ie||!e.mac){var g=d.getElementsByTagName("head")[0];g&&(c=c&&"string"==typeof c?c:"screen",f&&(L=m=null),m&&L==c||(f=d.createElement("style"),f.setAttribute("type","text/css"),f.setAttribute("media",c),m=g.appendChild(f),e.ie&&e.win&&"undefined"!=typeof d.styleSheets&&0<d.styleSheets.length&&(m=d.styleSheets[d.styleSheets.length-1]),L=c),e.ie&&e.win?m&&"object"==typeof m.addRule&&m.addRule(a,b):m&&"undefined"!=typeof d.createTextNode&&m.appendChild(d.createTextNode(a+
+" {"+b+"}")))}}function v(a,b){if(R){var c=b?"visible":"hidden";u&&p(a)?p(a).style.visibility=c:Q("#"+a,"visibility:"+c)}}function S(a){return null!=/[\\\"<>\.;]/.exec(a)&&"undefined"!=typeof encodeURIComponent?encodeURIComponent(a):a}var n=window,d=document,t=navigator,T=!1,z=[function(){T?V():E()}],r=[],D=[],x=[],y,C,I,O,u=!1,B=!1,m,L,R=!0,e=function(){var a="undefined"!=typeof d.getElementById&&"undefined"!=typeof d.getElementsByTagName&&"undefined"!=typeof d.createElement,b=t.userAgent.toLowerCase(),
+c=t.platform.toLowerCase(),f=c?/win/.test(c):/win/.test(b),c=c?/mac/.test(c):/mac/.test(b),b=/webkit/.test(b)?parseFloat(b.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):!1,g=!+"\v1",e=[0,0,0],h=null;if("undefined"!=typeof t.plugins&&"object"==typeof t.plugins["Shockwave Flash"])!(h=t.plugins["Shockwave Flash"].description)||"undefined"!=typeof t.mimeTypes&&t.mimeTypes["application/x-shockwave-flash"]&&!t.mimeTypes["application/x-shockwave-flash"].enabledPlugin||(T=!0,g=!1,h=h.replace(/^.*\s+(\S+\s+\S+$)/,
+"$1"),e[0]=parseInt(h.replace(/^(.*)\..*$/,"$1"),10),e[1]=parseInt(h.replace(/^.*\.(.*)\s.*$/,"$1"),10),e[2]=/[a-zA-Z]/.test(h)?parseInt(h.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0);else if("undefined"!=typeof n.ActiveXObject)try{var k=new ActiveXObject("ShockwaveFlash.ShockwaveFlash");k&&(h=k.GetVariable("$version"))&&(g=!0,h=h.split(" ")[1].split(","),e=[parseInt(h[0],10),parseInt(h[1],10),parseInt(h[2],10)])}catch(l){}return{w3:a,pv:e,wk:b,ie:g,win:f,mac:c}}();(function(){e.w3&&(("undefined"!=typeof d.readyState&&
+"complete"==d.readyState||"undefined"==typeof d.readyState&&(d.getElementsByTagName("body")[0]||d.body))&&w(),u||("undefined"!=typeof d.addEventListener&&d.addEventListener("DOMContentLoaded",w,!1),e.ie&&e.win&&(d.attachEvent("onreadystatechange",function(){"complete"==d.readyState&&(d.detachEvent("onreadystatechange",arguments.callee),w())}),n==top&&function(){if(!u){try{d.documentElement.doScroll("left")}catch(a){setTimeout(arguments.callee,0);return}w()}}()),e.wk&&function(){u||(/loaded|complete/.test(d.readyState)?
+w():setTimeout(arguments.callee,0))}(),N(w)))})();(function(){e.ie&&e.win&&window.attachEvent("onunload",function(){for(var a=x.length,b=0;b<a;b++)x[b][0].detachEvent(x[b][1],x[b][2]);a=D.length;for(b=0;b<a;b++)P(D[b]);for(var c in e)e[c]=null;e=null;for(var f in swfobject)swfobject[f]=null;swfobject=null})})();return{registerObject:function(a,b,c,f){if(e.w3&&a&&b){var d={};d.id=a;d.swfVersion=b;d.expressInstall=c;d.callbackFn=f;r[r.length]=d;v(a,!1)}else f&&f({success:!1,id:a})},getObjectById:function(a){if(e.w3)return H(a)},
+embedSWF:function(a,b,c,d,g,q,h,k,l,n){var p={success:!1,id:b};e.w3&&!(e.wk&&312>e.wk)&&a&&b&&c&&d&&g?(v(b,!1),M(function(){c+="";d+="";var e={};if(l&&"object"===typeof l)for(var m in l)e[m]=l[m];e.data=a;e.width=c;e.height=d;m={};if(k&&"object"===typeof k)for(var r in k)m[r]=k[r];if(h&&"object"===typeof h)for(var t in h)m.flashvars="undefined"!=typeof m.flashvars?m.flashvars+("\x26"+t+"\x3d"+h[t]):t+"\x3d"+h[t];if(A(g))r=K(e,m,b),e.id==b&&v(b,!0),p.success=!0,p.ref=r;else{if(q&&F()){e.data=q;G(e,
+m,b,n);return}v(b,!0)}n&&n(p)})):n&&n(p)},switchOffAutoHideShow:function(){R=!1},ua:e,getFlashPlayerVersion:function(){return{major:e.pv[0],minor:e.pv[1],release:e.pv[2]}},hasFlashPlayerVersion:A,createSWF:function(a,b,c){if(e.w3)return K(a,b,c)},showExpressInstall:function(a,b,c,d){e.w3&&F()&&G(a,b,c,d)},removeSWF:function(a){e.w3&&P(a)},createCSS:function(a,b,c,d){e.w3&&Q(a,b,c,d)},addDomLoadEvent:M,addLoadEvent:N,getQueryParamValue:function(a){var b=d.location.search||d.location.hash;if(b){/\?/.test(b)&&
+(b=b.split("?")[1]);if(null==a)return S(b);for(var b=b.split("\x26"),c=0;c<b.length;c++)if(b[c].substring(0,b[c].indexOf("\x3d"))==a)return S(b[c].substring(b[c].indexOf("\x3d")+1))}return""},expressInstallCallback:function(){if(B){var a=p("SWFObjectExprInst");a&&y&&(a.parentNode.replaceChild(y,a),C&&(v(C,!0),e.ie&&e.win&&(y.style.display="block")),I&&I(O));B=!1}}}}();
\ No newline at end of file
diff --git a/release/samples/old/htmlwriter/outputforflash.html b/release/samples/old/htmlwriter/outputforflash.html
new file mode 100644 (file)
index 0000000..f72616d
--- /dev/null
@@ -0,0 +1,283 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Output for Flash &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <script src="assets/outputforflash/swfobject.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Output for Flash">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to produce HTML code that can be used with Adobe Flash.">\r
+       <style>\r
+\r
+               .alert\r
+               {\r
+                       background: #ffa84c;\r
+                       padding: 10px 15px;\r
+                       font-weight: bold;\r
+                       display: block;\r
+                       margin-bottom: 20px;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Producing Flash Compliant HTML Output\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to output\r
+                       HTML code that can be used with\r
+                       <a class="samples" href="http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00000922.html">\r
+                       Adobe Flash</a>.\r
+                       The code will contain a subset of standard HTML elements like <code>&lt;b&gt;</code>,\r
+                       <code>&lt;i&gt;</code>, and <code>&lt;p&gt;</code> as well as HTML attributes.\r
+               </p>\r
+               <p>\r
+                       To add a CKEditor instance outputting Flash compliant HTML code, load the editor using a standard\r
+                       JavaScript call, and define CKEditor features to use HTML elements and attributes.\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <p>\r
+               To see how it works, create some content in the editing area of CKEditor on the left\r
+               and send it to the Flash object on the right side of the page by using the\r
+               <strong>Send to Flash</strong> button.\r
+       </p>\r
+       <table style="width: 100%; border-spacing: 0; border-collapse:collapse;">\r
+               <tr>\r
+                       <td style="width: 100%">\r
+                               <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;&lt;b&gt;&lt;font size=&quot;18&quot; style=&quot;font-size:18px;&quot;&gt;Flash and HTML&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;It is possible to have &lt;a href=&quot;http://ckeditor.com&quot;&gt;CKEditor&lt;/a&gt; creating content that will be later loaded inside &lt;b&gt;Flash&lt;/b&gt; objects and animations.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Flash has a few limitations when dealing with HTML:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It has limited support on tags.&lt;/li&gt;&lt;li&gt;There is no margin between block elements, like paragraphs.&lt;/li&gt;&lt;/ul&gt;</textarea>\r
+                               <script>\r
+\r
+                                       if ( document.location.protocol == 'file:' )\r
+                                               alert( 'Warning: This samples does not work when loaded from local filesystem' +\r
+                                                       'due to security restrictions implemented in Flash.' +\r
+                                                       '\n\nPlease load the sample from a web server instead.' );\r
+\r
+                                       var editor = CKEDITOR.replace( 'editor1', {\r
+                                               /*\r
+                                                * Ensure that htmlwriter plugin, which is required for this sample, is loaded.\r
+                                                */\r
+                                               extraPlugins: 'htmlwriter',\r
+\r
+                                               height: 290,\r
+                                               width: '100%',\r
+                                               toolbar: [\r
+                                                       [ 'Source', '-', 'Bold', 'Italic', 'Underline', '-', 'BulletedList', '-', 'Link', 'Unlink' ],\r
+                                                       [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ],\r
+                                                       '/',\r
+                                                       [ 'Font', 'FontSize' ],\r
+                                                       [ 'TextColor', '-', 'About' ]\r
+                                               ],\r
+\r
+                                               /*\r
+                                                * Style sheet for the contents\r
+                                                */\r
+                                               contentsCss: 'body {color:#000; background-color#FFF; font-family: Arial; font-size:80%;} p, ol, ul {margin-top: 0px; margin-bottom: 0px;}',\r
+\r
+                                               /*\r
+                                                * Quirks doctype\r
+                                                */\r
+                                               docType: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',\r
+\r
+                                               /*\r
+                                                * Core styles.\r
+                                                */\r
+                                               coreStyles_bold: { element: 'b' },\r
+                                               coreStyles_italic: { element: 'i' },\r
+                                               coreStyles_underline: { element: 'u' },\r
+\r
+                                               /*\r
+                                                * Font face.\r
+                                                */\r
+\r
+                                               // Define the way font elements will be applied to the document. The "font"\r
+                                               // element will be used.\r
+                                               font_style: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'face': '#(family)' }\r
+                                               },\r
+\r
+                                               /*\r
+                                                * Font sizes.\r
+                                                */\r
+\r
+                                               // The CSS part of the font sizes isn't used by Flash, it is there to get the\r
+                                               // font rendered correctly in CKEditor.\r
+                                               fontSize_sizes: '8px/8;9px/9;10px/10;11px/11;12px/12;14px/14;16px/16;18px/18;20px/20;22px/22;24px/24;26px/26;28px/28;36px/36;48px/48;72px/72',\r
+                                               fontSize_style: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'size': '#(size)' },\r
+                                                       styles: { 'font-size': '#(size)px' }\r
+                                               } ,\r
+\r
+                                               /*\r
+                                                * Font colors.\r
+                                                */\r
+                                               colorButton_enableMore: true,\r
+\r
+                                               colorButton_foreStyle: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'color': '#(color)' }\r
+                                               },\r
+\r
+                                               colorButton_backStyle: {\r
+                                                       element: 'font',\r
+                                                       styles: { 'background-color': '#(color)' }\r
+                                               },\r
+\r
+                                               on: { 'instanceReady': configureFlashOutput }\r
+                                       });\r
+\r
+                                       /*\r
+                                        * Adjust the behavior of the dataProcessor to match the\r
+                                        * requirements of Flash\r
+                                        */\r
+                                       function configureFlashOutput( ev ) {\r
+                                               var editor = ev.editor,\r
+                                                       dataProcessor = editor.dataProcessor,\r
+                                                       htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
+                                               // Out self closing tags the HTML4 way, like <br>.\r
+                                               dataProcessor.writer.selfClosingEnd = '>';\r
+\r
+                                               // Make output formatting match Flash expectations\r
+                                               var dtd = CKEDITOR.dtd;\r
+                                               for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {\r
+                                                       dataProcessor.writer.setRules( e, {\r
+                                                               indent: false,\r
+                                                               breakBeforeOpen: false,\r
+                                                               breakAfterOpen: false,\r
+                                                               breakBeforeClose: false,\r
+                                                               breakAfterClose: false\r
+                                                       });\r
+                                               }\r
+                                               dataProcessor.writer.setRules( 'br', {\r
+                                                       indent: false,\r
+                                                       breakBeforeOpen: false,\r
+                                                       breakAfterOpen: false,\r
+                                                       breakBeforeClose: false,\r
+                                                       breakAfterClose: false\r
+                                               });\r
+\r
+                                               // Output properties as attributes, not styles.\r
+                                               htmlFilter.addRules( {\r
+                                                       elements: {\r
+                                                               $: function( element ) {\r
+                                                                       var style, match, width, height, align;\r
+\r
+                                                                       // Output dimensions of images as width and height\r
+                                                                       if ( element.name == 'img' ) {\r
+                                                                               style = element.attributes.style;\r
+\r
+                                                                               if ( style ) {\r
+                                                                                       // Get the width from the style.\r
+                                                                                       match = ( /(?:^|\s)width\s*:\s*(\d+)px/i ).exec( style );\r
+                                                                                       width = match && match[1];\r
+\r
+                                                                                       // Get the height from the style.\r
+                                                                                       match = ( /(?:^|\s)height\s*:\s*(\d+)px/i ).exec( style );\r
+                                                                                       height = match && match[1];\r
+\r
+                                                                                       if ( width ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)width\s*:\s*(\d+)px;?/i , '' );\r
+                                                                                               element.attributes.width = width;\r
+                                                                                       }\r
+\r
+                                                                                       if ( height ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)height\s*:\s*(\d+)px;?/i , '' );\r
+                                                                                               element.attributes.height = height;\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       // Output alignment of paragraphs using align\r
+                                                                       if ( element.name == 'p' ) {\r
+                                                                               style = element.attributes.style;\r
+\r
+                                                                               if ( style ) {\r
+                                                                                       // Get the align from the style.\r
+                                                                                       match = ( /(?:^|\s)text-align\s*:\s*(\w*);?/i ).exec( style );\r
+                                                                                       align = match && match[1];\r
+\r
+                                                                                       if ( align ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)text-align\s*:\s*(\w*);?/i , '' );\r
+                                                                                               element.attributes.align = align;\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       if ( element.attributes.style === '' )\r
+                                                                               delete element.attributes.style;\r
+\r
+                                                                       return element;\r
+                                                               }\r
+                                                       }\r
+                                               });\r
+                                       }\r
+\r
+                                       function sendToFlash() {\r
+                                               var html = CKEDITOR.instances.editor1.getData() ;\r
+\r
+                                               // Quick fix for link color.\r
+                                               html = html.replace( /<a /g, '<font color="#0000FF"><u><a ' )\r
+                                               html = html.replace( /<\/a>/g, '</a></u></font>' )\r
+\r
+                                               var flash = document.getElementById( 'ckFlashContainer' ) ;\r
+                                               flash.setData( html ) ;\r
+                                       }\r
+\r
+                                       CKEDITOR.domReady( function() {\r
+                                               if ( !swfobject.hasFlashPlayerVersion( '8' ) ) {\r
+                                                       CKEDITOR.dom.element.createFromHtml( '<span class="alert">' +\r
+                                                                       'At least Adobe Flash Player 8 is required to run this sample. ' +\r
+                                                                       'You can download it from <a href="http://get.adobe.com/flashplayer">Adobe\'s website</a>.' +\r
+                                                               '</span>' ).insertBefore( editor.element );\r
+                                               }\r
+\r
+                                               swfobject.embedSWF(\r
+                                                       'assets/outputforflash/outputforflash.swf',\r
+                                                       'ckFlashContainer',\r
+                                                       '550',\r
+                                                       '400',\r
+                                                       '8',\r
+                                                       { wmode: 'transparent' }\r
+                                               );\r
+                                       });\r
+\r
+                               </script>\r
+                               <p>\r
+                                       <input type="button" value="Send to Flash" onclick="sendToFlash();">\r
+                               </p>\r
+                       </td>\r
+                       <td style="vertical-align: top; padding-left: 20px">\r
+                               <div id="ckFlashContainer"></div>\r
+                       </td>\r
+               </tr>\r
+       </table>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/htmlwriter/outputhtml.html b/release/samples/old/htmlwriter/outputhtml.html
new file mode 100644 (file)
index 0000000..a433025
--- /dev/null
@@ -0,0 +1,224 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>HTML Compliant Output &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Output HTML">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to produce legacy HTML 4 code.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Producing HTML Compliant Output\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to output valid\r
+                       <a class="samples" href="http://www.w3.org/TR/html401/">HTML 4.01</a> code.\r
+                       Traditional HTML elements like <code>&lt;b&gt;</code>,\r
+                       <code>&lt;i&gt;</code>, and <code>&lt;font&gt;</code> are used in place of\r
+                       <code>&lt;strong&gt;</code>, <code>&lt;em&gt;</code>, and CSS styles.\r
+               </p>\r
+               <p>\r
+                       To add a CKEditor instance outputting legacy HTML 4.01 code, load the editor using a standard\r
+                       JavaScript call, and define CKEditor features to use the HTML compliant elements and attributes.\r
+               </p>\r
+               <p>\r
+                       A snippet of the configuration code can be seen below; check the source of this page for\r
+                       full definition:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       coreStyles_bold: { element: 'b' },\r
+       coreStyles_italic: { element: 'i' },\r
+\r
+       fontSize_style: {\r
+               element: 'font',\r
+               attributes: { 'size': '#(size)' }\r
+       }\r
+\r
+       ...\r
+});</pre>\r
+       </div>\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <p>\r
+                       <label for="editor1">\r
+                               Editor 1:\r
+                       </label>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;b&gt;sample text&lt;/b&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+                       <script>\r
+\r
+                               CKEDITOR.replace( 'editor1', {\r
+                                       /*\r
+                                        * Ensure that htmlwriter plugin, which is required for this sample, is loaded.\r
+                                        */\r
+                                       extraPlugins: 'htmlwriter',\r
+\r
+                                       /*\r
+                                        * Style sheet for the contents\r
+                                        */\r
+                                       contentsCss: 'body {color:#000; background-color#:FFF;}',\r
+\r
+                                       /*\r
+                                        * Simple HTML5 doctype\r
+                                        */\r
+                                       docType: '<!DOCTYPE HTML>',\r
+\r
+                                       /*\r
+                                        * Allowed content rules which beside limiting allowed HTML\r
+                                        * will also take care of transforming styles to attributes\r
+                                        * (currently only for img - see transformation rules defined below).\r
+                                        *\r
+                                        * Read more: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter\r
+                                        */\r
+                                       allowedContent:\r
+                                               'h1 h2 h3 p pre[align]; ' +\r
+                                               'blockquote code kbd samp var del ins cite q b i u strike ul ol li hr table tbody tr td th caption; ' +\r
+                                               'img[!src,alt,align,width,height]; font[!face]; font[!family]; font[!color]; font[!size]; font{!background-color}; a[!href]; a[!name]',\r
+\r
+                                       /*\r
+                                        * Core styles.\r
+                                        */\r
+                                       coreStyles_bold: { element: 'b' },\r
+                                       coreStyles_italic: { element: 'i' },\r
+                                       coreStyles_underline: { element: 'u' },\r
+                                       coreStyles_strike: { element: 'strike' },\r
+\r
+                                       /*\r
+                                        * Font face.\r
+                                        */\r
+\r
+                                       // Define the way font elements will be applied to the document.\r
+                                       // The "font" element will be used.\r
+                                       font_style: {\r
+                                               element: 'font',\r
+                                               attributes: { 'face': '#(family)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font sizes.\r
+                                        */\r
+                                       fontSize_sizes: 'xx-small/1;x-small/2;small/3;medium/4;large/5;x-large/6;xx-large/7',\r
+                                       fontSize_style: {\r
+                                               element: 'font',\r
+                                               attributes: { 'size': '#(size)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font colors.\r
+                                        */\r
+\r
+                                       colorButton_foreStyle: {\r
+                                               element: 'font',\r
+                                               attributes: { 'color': '#(color)' }\r
+                                       },\r
+\r
+                                       colorButton_backStyle: {\r
+                                               element: 'font',\r
+                                               styles: { 'background-color': '#(color)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Styles combo.\r
+                                        */\r
+                                       stylesSet: [\r
+                                               { name: 'Computer Code', element: 'code' },\r
+                                               { name: 'Keyboard Phrase', element: 'kbd' },\r
+                                               { name: 'Sample Text', element: 'samp' },\r
+                                               { name: 'Variable', element: 'var' },\r
+                                               { name: 'Deleted Text', element: 'del' },\r
+                                               { name: 'Inserted Text', element: 'ins' },\r
+                                               { name: 'Cited Work', element: 'cite' },\r
+                                               { name: 'Inline Quotation', element: 'q' }\r
+                                       ],\r
+\r
+                                       on: {\r
+                                               pluginsLoaded: configureTransformations,\r
+                                               loaded: configureHtmlWriter\r
+                                       }\r
+                               });\r
+\r
+                               /*\r
+                                * Add missing content transformations.\r
+                                */\r
+                               function configureTransformations( evt ) {\r
+                                       var editor = evt.editor;\r
+\r
+                                       editor.dataProcessor.htmlFilter.addRules( {\r
+                                               attributes: {\r
+                                                       style: function( value, element ) {\r
+                                                               // Return #RGB for background and border colors\r
+                                                               return CKEDITOR.tools.convertRgbToHex( value );\r
+                                                       }\r
+                                               }\r
+                                       } );\r
+\r
+                                       // Default automatic content transformations do not yet take care of\r
+                                       // align attributes on blocks, so we need to add our own transformation rules.\r
+                                       function alignToAttribute( element ) {\r
+                                               if ( element.styles[ 'text-align' ] ) {\r
+                                                       element.attributes.align = element.styles[ 'text-align' ];\r
+                                                       delete element.styles[ 'text-align' ];\r
+                                               }\r
+                                       }\r
+                                       editor.filter.addTransformations( [\r
+                                               [ { element: 'p',       right: alignToAttribute } ],\r
+                                               [ { element: 'h1',      right: alignToAttribute } ],\r
+                                               [ { element: 'h2',      right: alignToAttribute } ],\r
+                                               [ { element: 'h3',      right: alignToAttribute } ],\r
+                                               [ { element: 'pre',     right: alignToAttribute } ]\r
+                                       ] );\r
+                               }\r
+\r
+                               /*\r
+                                * Adjust the behavior of htmlWriter to make it output HTML like FCKeditor.\r
+                                */\r
+                               function configureHtmlWriter( evt ) {\r
+                                       var editor = evt.editor,\r
+                                               dataProcessor = editor.dataProcessor;\r
+\r
+                                       // Out self closing tags the HTML4 way, like <br>.\r
+                                       dataProcessor.writer.selfClosingEnd = '>';\r
+\r
+                                       // Make output formatting behave similar to FCKeditor.\r
+                                       var dtd = CKEDITOR.dtd;\r
+                                       for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {\r
+                                               dataProcessor.writer.setRules( e, {\r
+                                                       indent: true,\r
+                                                       breakBeforeOpen: true,\r
+                                                       breakAfterOpen: false,\r
+                                                       breakBeforeClose: !dtd[ e ][ '#' ],\r
+                                                       breakAfterClose: true\r
+                                               });\r
+                                       }\r
+                               }\r
+\r
+                       </script>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/index.html b/release/samples/old/index.html
new file mode 100644 (file)
index 0000000..f4f795b
--- /dev/null
@@ -0,0 +1,131 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>CKEditor Samples</title>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               CKEditor Samples\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               These samples are not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="twoColumns">\r
+               <div class="twoColumnsLeft">\r
+                       <h2 class="samples">\r
+                               Basic Samples\r
+                       </h2>\r
+                       <dl class="samples">\r
+                               <dt><a class="samples" href="replacebyclass.html">Replace textarea elements by class name</a></dt>\r
+                               <dd>Automatic replacement of all textarea elements of a given class with a CKEditor instance.</dd>\r
+\r
+                               <dt><a class="samples" href="replacebycode.html">Replace textarea elements by code</a></dt>\r
+                               <dd>Replacement of textarea elements with CKEditor instances by using a JavaScript call.</dd>\r
+\r
+                               <dt><a class="samples" href="jquery.html">Create editors with jQuery</a></dt>\r
+                               <dd>Creating standard and inline CKEditor instances with jQuery adapter.</dd>\r
+                       </dl>\r
+\r
+                       <h2 class="samples">\r
+                               Basic Customization\r
+                       </h2>\r
+                       <dl class="samples">\r
+                               <dt><a class="samples" href="uicolor.html">User Interface color</a></dt>\r
+                               <dd>Changing CKEditor User Interface color and adding a toolbar button that lets the user set the UI color.</dd>\r
+\r
+                               <dt><a class="samples" href="uilanguages.html">User Interface languages</a></dt>\r
+                               <dd>Changing CKEditor User Interface language and adding a drop-down list that lets the user choose the UI language.</dd>\r
+                       </dl>\r
+\r
+\r
+                       <h2 class="samples">Plugins</h2>
+<dl class="samples">
+<dt><a class="samples" href="magicline/magicline.html">Magicline plugin</a></dt>
+<dd>Using the Magicline plugin to access difficult focus spaces.</dd>
+
+<dt><a class="samples" href="wysiwygarea/fullpage.html">Full page support</a></dt>
+<dd>CKEditor inserted with a JavaScript call and used to edit the whole page from &lt;html&gt; to &lt;/html&gt;.</dd>
+</dl>\r
+               </div>\r
+               <div class="twoColumnsRight">\r
+                       <h2 class="samples">\r
+                               Inline Editing\r
+                       </h2>\r
+                       <dl class="samples">\r
+                               <dt><a class="samples" href="inlineall.html">Massive inline editor creation</a></dt>\r
+                               <dd>Turn all elements with <code>contentEditable = true</code> attribute into inline editors.</dd>\r
+\r
+                               <dt><a class="samples" href="inlinebycode.html">Convert element into an inline editor by code</a></dt>\r
+                               <dd>Conversion of DOM elements into inline CKEditor instances by using a JavaScript call.</dd>\r
+\r
+                               <dt><a class="samples" href="inlinetextarea.html">Replace textarea with inline editor</a> <span class="new">New!</span></dt>\r
+                               <dd>A form with a textarea that is replaced by an inline editor at runtime.</dd>\r
+\r
+                               \r
+                       </dl>\r
+\r
+                       <h2 class="samples">\r
+                               Advanced Samples\r
+                       </h2>\r
+                       <dl class="samples">\r
+                               <dt><a class="samples" href="datafiltering.html">Data filtering and features activation</a> <span class="new">New!</span></dt>\r
+                               <dd>Data filtering and automatic features activation basing on configuration.</dd>\r
+\r
+                               <dt><a class="samples" href="divreplace.html">Replace DIV elements on the fly</a></dt>\r
+                               <dd>Transforming a <code>div</code> element into an instance of CKEditor with a mouse click.</dd>\r
+\r
+                               <dt><a class="samples" href="appendto.html">Append editor instances</a></dt>\r
+                               <dd>Appending editor instances to existing DOM elements.</dd>\r
+\r
+                               <dt><a class="samples" href="ajax.html">Create and destroy editor instances for Ajax applications</a></dt>\r
+                               <dd>Creating and destroying CKEditor instances on the fly and saving the contents entered into the editor window.</dd>\r
+\r
+                               <dt><a class="samples" href="api.html">Basic usage of the API</a></dt>\r
+                               <dd>Using the CKEditor JavaScript API to interact with the editor at runtime.</dd>\r
+\r
+                               <dt><a class="samples" href="xhtmlstyle.html">XHTML-compliant style</a></dt>\r
+                               <dd>Configuring CKEditor to produce XHTML 1.1 compliant attributes and styles.</dd>\r
+\r
+                               <dt><a class="samples" href="readonly.html">Read-only mode</a></dt>\r
+                               <dd>Using the readOnly API to block introducing changes to the editor contents.</dd>\r
+\r
+                               <dt><a class="samples" href="tabindex.html">"Tab" key-based navigation</a></dt>\r
+                               <dd>Navigating among editor instances with tab key.</dd>\r
+\r
+\r
+                               
+<dt><a class="samples" href="dialog/dialog.html">Using the JavaScript API to customize dialog windows</a></dt>
+<dd>Using the dialog windows API to customize dialog windows without changing the original editor code.</dd>
+
+<dt><a class="samples" href="enterkey/enterkey.html">Using the &quot;Enter&quot; key in CKEditor</a></dt>
+<dd>Configuring the behavior of <em>Enter</em> and <em>Shift+Enter</em> keys.</dd>
+
+<dt><a class="samples" href="htmlwriter/outputforflash.html">Output for Flash</a></dt>
+<dd>Configuring CKEditor to produce HTML code that can be used with Adobe Flash.</dd>
+
+<dt><a class="samples" href="htmlwriter/outputhtml.html">Output HTML</a></dt>
+<dd>Configuring CKEditor to produce legacy HTML 4 code.</dd>
+
+<dt><a class="samples" href="toolbar/toolbar.html">Toolbar Configurations</a></dt>
+<dd>Configuring CKEditor to display full or custom toolbar layout.</dd>
+\r
+                       </dl>\r
+               </div>\r
+       </div>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/inlineall.html b/release/samples/old/inlineall.html
new file mode 100644 (file)
index 0000000..e0241e8
--- /dev/null
@@ -0,0 +1,314 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Massive inline editing &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <script>\r
+\r
+               // This code is generally not necessary, but it is here to demonstrate\r
+               // how to customize specific editor instances on the fly. This fits well\r
+               // this demo because we have editable elements (like headers) that\r
+               // require less features.\r
+\r
+               // The "instanceCreated" event is fired for every editor instance created.\r
+               CKEDITOR.on( 'instanceCreated', function( event ) {\r
+                       var editor = event.editor,\r
+                               element = editor.element;\r
+\r
+                       // Customize editors for headers and tag list.\r
+                       // These editors don't need features like smileys, templates, iframes etc.\r
+                       if ( element.is( 'h1', 'h2', 'h3' ) || element.getAttribute( 'id' ) == 'taglist' ) {\r
+                               // Customize the editor configurations on "configLoaded" event,\r
+                               // which is fired after the configuration file loading and\r
+                               // execution. This makes it possible to change the\r
+                               // configurations before the editor initialization takes place.\r
+                               editor.on( 'configLoaded', function() {\r
+\r
+                                       // Remove unnecessary plugins to make the editor simpler.\r
+                                       editor.config.removePlugins = 'colorbutton,find,flash,font,' +\r
+                                               'forms,iframe,image,newpage,removeformat,' +\r
+                                               'smiley,specialchar,stylescombo,templates';\r
+\r
+                                       // Rearrange the layout of the toolbar.\r
+                                       editor.config.toolbarGroups = [\r
+                                               { name: 'editing',              groups: [ 'basicstyles', 'links' ] },\r
+                                               { name: 'undo' },\r
+                                               { name: 'clipboard',    groups: [ 'selection', 'clipboard' ] },\r
+                                               { name: 'about' }\r
+                                       ];\r
+                               });\r
+                       }\r
+               });\r
+\r
+       </script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               /* The following styles are just to make the page look nice. */\r
+\r
+               /* Workaround to show Arial Black in Firefox. */\r
+               @font-face\r
+               {\r
+                       font-family: 'arial-black';\r
+                       src: local('Arial Black');\r
+               }\r
+\r
+               *[contenteditable="true"]\r
+               {\r
+                       padding: 10px;\r
+               }\r
+\r
+               #container\r
+               {\r
+                       width: 960px;\r
+                       margin: 30px auto 0;\r
+               }\r
+\r
+               #header\r
+               {\r
+                       overflow: hidden;\r
+                       padding: 0 0 30px;\r
+                       border-bottom: 5px solid #05B2D2;\r
+                       position: relative;\r
+               }\r
+\r
+               #headerLeft,\r
+               #headerRight\r
+               {\r
+                       width: 49%;\r
+                       overflow: hidden;\r
+               }\r
+\r
+               #headerLeft\r
+               {\r
+                       float: left;\r
+                       padding: 10px 1px 1px;\r
+               }\r
+\r
+               #headerLeft h2,\r
+               #headerLeft h3\r
+               {\r
+                       text-align: right;\r
+                       margin: 0;\r
+                       overflow: hidden;\r
+                       font-weight: normal;\r
+               }\r
+\r
+               #headerLeft h2\r
+               {\r
+                       font-family: "Arial Black",arial-black;\r
+                       font-size: 4.6em;\r
+                       line-height: 1.1;\r
+                       text-transform: uppercase;\r
+               }\r
+\r
+               #headerLeft h3\r
+               {\r
+                       font-size: 2.3em;\r
+                       line-height: 1.1;\r
+                       margin: .2em 0 0;\r
+                       color: #666;\r
+               }\r
+\r
+               #headerRight\r
+               {\r
+                       float: right;\r
+                       padding: 1px;\r
+               }\r
+\r
+               #headerRight p\r
+               {\r
+                       line-height: 1.8;\r
+                       text-align: justify;\r
+                       margin: 0;\r
+               }\r
+\r
+               #headerRight p + p\r
+               {\r
+                       margin-top: 20px;\r
+               }\r
+\r
+               #headerRight > div\r
+               {\r
+                       padding: 20px;\r
+                       margin: 0 0 0 30px;\r
+                       font-size: 1.4em;\r
+                       color: #666;\r
+               }\r
+\r
+               #columns\r
+               {\r
+                       color: #333;\r
+                       overflow: hidden;\r
+                       padding: 20px 0;\r
+               }\r
+\r
+               #columns > div\r
+               {\r
+                       float: left;\r
+                       width: 33.3%;\r
+               }\r
+\r
+               #columns #column1 > div\r
+               {\r
+                       margin-left: 1px;\r
+               }\r
+\r
+               #columns #column3 > div\r
+               {\r
+                       margin-right: 1px;\r
+               }\r
+\r
+               #columns > div > div\r
+               {\r
+                       margin: 0px 10px;\r
+                       padding: 10px 20px;\r
+               }\r
+\r
+               #columns blockquote\r
+               {\r
+                       margin-left: 15px;\r
+               }\r
+\r
+               #tagLine\r
+               {\r
+                       border-top: 5px solid #05B2D2;\r
+                       padding-top: 20px;\r
+               }\r
+\r
+               #taglist {\r
+                       display: inline-block;\r
+                       margin-left: 20px;\r
+                       font-weight: bold;\r
+                       margin: 0 0 0 20px;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+<div>\r
+       <h1 class="samples"><a href="index.html">CKEditor Samples</a> &raquo; Massive inline editing</h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>This sample page demonstrates the inline editing feature - CKEditor instances will be created automatically from page elements with <strong>contentEditable</strong> attribute set to value <strong>true</strong>:</p>\r
+               <pre class="samples">&lt;div <strong>contenteditable="true</strong>" &gt; ... &lt;/div&gt;</pre>\r
+               <p>Click inside of any element below to start editing.</p>\r
+       </div>\r
+</div>\r
+<div id="container">\r
+       <div id="header">\r
+               <div id="headerLeft">\r
+                       <h2 id="sampleTitle" contenteditable="true">\r
+                               CKEditor<br> Goes Inline!\r
+                       </h2>\r
+                       <h3 contenteditable="true">\r
+                               Lorem ipsum dolor sit amet dolor duis blandit vestibulum faucibus a, tortor.\r
+                       </h3>\r
+               </div>\r
+               <div id="headerRight">\r
+                       <div contenteditable="true">\r
+                               <p>\r
+                                       Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies.\r
+                               </p>\r
+                               <p>\r
+                                       Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac.\r
+                               </p>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+       <div id="columns">\r
+               <div id="column1">\r
+                       <div contenteditable="true">\r
+                               <h3>\r
+                                       Fusce vitae porttitor\r
+                               </h3>\r
+                               <p>\r
+                                       <strong>\r
+                                               Lorem ipsum dolor sit amet dolor. Duis blandit vestibulum faucibus a, tortor.\r
+                                       </strong>\r
+                               </p>\r
+                               <p>\r
+                                       Proin nunc justo felis mollis tincidunt, risus risus pede, posuere cubilia Curae, Nullam euismod, enim. Etiam nibh ultricies dolor ac dignissim erat volutpat. Vivamus fermentum <a href="http://ckeditor.com/">nisl nulla sem in</a> metus. Maecenas wisi. Donec nec erat volutpat.\r
+                               </p>\r
+                               <blockquote>\r
+                                       <p>\r
+                                               Fusce vitae porttitor a, euismod convallis nisl, blandit risus tortor, pretium.\r
+                                               Vehicula vitae, imperdiet vel, ornare enim vel sodales rutrum\r
+                                       </p>\r
+                               </blockquote>\r
+                               <blockquote>\r
+                                       <p>\r
+                                               Libero nunc, rhoncus ante ipsum non ipsum. Nunc eleifend pede turpis id sollicitudin fringilla. Phasellus ultrices, velit ac arcu.\r
+                                       </p>\r
+                               </blockquote>\r
+                               <p>Pellentesque nunc. Donec suscipit erat. Pellentesque habitant morbi tristique ullamcorper.</p>\r
+                               <p><s>Mauris mattis feugiat lectus nec mauris. Nullam vitae ante.</s></p>\r
+                       </div>\r
+               </div>\r
+               <div id="column2">\r
+                       <div contenteditable="true">\r
+                               <h3>\r
+                                       Integer condimentum sit amet\r
+                               </h3>\r
+                               <p>\r
+                                       <strong>Aenean nonummy a, mattis varius. Cras aliquet.</strong>\r
+                                       Praesent <a href="http://ckeditor.com/">magna non mattis ac, rhoncus nunc</a>, rhoncus eget, cursus pulvinar mollis.</p>\r
+                               <p>Proin id nibh. Sed eu libero posuere sed, lectus. Phasellus dui gravida gravida feugiat mattis ac, felis.</p>\r
+                               <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>\r
+                       </div>\r
+                       <div contenteditable="true">\r
+                               <h3>\r
+                                       Praesent wisi accumsan sit amet nibh\r
+                               </h3>\r
+                               <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>\r
+                               <p style="margin-left: 40px; ">Integer faucibus scelerisque. Proin faucibus at, aliquet vulputate, odio at eros. Fusce <a href="http://ckeditor.com/">gravida, erat vitae augue</a>. Fusce urna fringilla gravida.</p>\r
+                               <p>In hac habitasse platea dictumst. Praesent wisi accumsan sit amet nibh. Maecenas orci luctus a, lacinia quam sem, posuere commodo, odio condimentum tempor, pede semper risus. Suspendisse pede. In hac habitasse platea dictumst. Nam sed laoreet sit amet erat. Integer.</p>\r
+                       </div>\r
+               </div>\r
+               <div id="column3">\r
+                       <div contenteditable="true">\r
+                               <p>\r
+                                       <img src="assets/inlineall/logo.png" alt="CKEditor logo" style="float:left">\r
+                               </p>\r
+                               <p>Quisque justo neque, mattis sed, fermentum ultrices <strong>posuere cubilia Curae</strong>, Vestibulum elit metus, quis placerat ut, lectus. Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis. Fusce porttitor, nulla quis turpis. Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi. Donec odio nec velit ac nunc sit amet, accumsan cursus aliquet. Vestibulum ante sit amet sagittis mi.</p>\r
+                               <h3>\r
+                                       Nullam laoreet vel consectetuer tellus suscipit\r
+                               </h3>\r
+                               <ul>\r
+                                       <li>Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis.</li>\r
+                                       <li>Fusce porttitor, nulla quis turpis. Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi.</li>\r
+                                       <li>Mauris eget tellus. Donec non felis. Nam eget dolor. Vestibulum enim. Donec.</li>\r
+                               </ul>\r
+                               <p>Quisque justo neque, mattis sed, <a href="http://ckeditor.com/">fermentum ultrices posuere cubilia</a> Curae, Vestibulum elit metus, quis placerat ut, lectus.</p>\r
+                               <p>Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi. Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis. Fusce porttitor, nulla quis turpis.</p>\r
+                               <p>Donec odio nec velit ac nunc sit amet, accumsan cursus aliquet. Vestibulum ante sit amet sagittis mi. Sed in nonummy faucibus turpis. Mauris eget tellus. Donec non felis. Nam eget dolor. Vestibulum enim. Donec.</p>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+       <div id="tagLine">\r
+               Tags of this article:\r
+               <p id="taglist" contenteditable="true">\r
+                       inline, editing, floating, CKEditor\r
+               </p>\r
+       </div>\r
+</div>\r
+<div id="footer">\r
+       <hr>\r
+       <p>\r
+               CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">\r
+                       http://ckeditor.com</a>\r
+       </p>\r
+       <p id="copy">\r
+               Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>\r
+               - Frederico Knabben. All rights reserved.\r
+       </p>\r
+</div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/inlinebycode.html b/release/samples/old/inlinebycode.html
new file mode 100644 (file)
index 0000000..339be0c
--- /dev/null
@@ -0,0 +1,124 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Inline Editing by Code &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               #editable\r
+               {\r
+                       padding: 10px;\r
+                       float: left;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Inline Editing by Code\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to create an inline editor instance of CKEditor. It is created\r
+                       with a JavaScript call using the following code:\r
+               </p>\r
+<pre class="samples">\r
+// This property tells CKEditor to not activate every element with contenteditable=true element.\r
+CKEDITOR.disableAutoInline = true;\r
+\r
+var editor = CKEDITOR.inline( document.getElementById( 'editable' ) );\r
+</pre>\r
+               <p>\r
+                       Note that <code>editable</code> in the code above is the <code>id</code>\r
+                       attribute of the <code>&lt;div&gt;</code> element to be converted into an inline instance.\r
+               </p>\r
+       </div>\r
+       <div id="editable" contenteditable="true">\r
+               <h1><img alt="Saturn V carrying Apollo 11" class="right" src="assets/sample.jpg" /> Apollo 11</h1>\r
+\r
+               <p><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>\r
+\r
+               <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>\r
+\r
+               <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>\r
+\r
+               <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+\r
+               <blockquote>\r
+                       <p>One small step for [a] man, one giant leap for mankind.</p>\r
+               </blockquote>\r
+\r
+               <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>\r
+\r
+               <blockquote>\r
+                       <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>\r
+               </blockquote>\r
+\r
+               <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>\r
+\r
+               <table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;">\r
+                       <caption><strong>Mission crew</strong></caption>\r
+                       <thead>\r
+                       <tr>\r
+                               <th scope="col">Position</th>\r
+                               <th scope="col">Astronaut</th>\r
+                       </tr>\r
+                       </thead>\r
+                       <tbody>\r
+                       <tr>\r
+                               <td>Commander</td>\r
+                               <td>Neil A. Armstrong</td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>Command Module Pilot</td>\r
+                               <td>Michael Collins</td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>Lunar Module Pilot</td>\r
+                               <td>Edwin &quot;Buzz&quot; E. Aldrin, Jr.</td>\r
+                       </tr>\r
+                       </tbody>\r
+               </table>\r
+\r
+               <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>\r
+\r
+               <ol>\r
+                       <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>\r
+                       <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>\r
+                       <li><strong>Lunar Module</strong> for landing on the Moon.</li>\r
+               </ol>\r
+\r
+               <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>\r
+\r
+               <hr />\r
+               <p style="text-align: right;"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p>\r
+       </div>\r
+\r
+       <script>\r
+               // We need to turn off the automatic editor creation first.\r
+               CKEDITOR.disableAutoInline = true;\r
+\r
+               var editor = CKEDITOR.inline( 'editable' );\r
+       </script>\r
+       <div id="footer">\r
+               <hr>\r
+               <p contenteditable="true">\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">\r
+                               http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>\r
+                       - Frederico Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/inlinetextarea.html b/release/samples/old/inlinetextarea.html
new file mode 100644 (file)
index 0000000..504d181
--- /dev/null
@@ -0,0 +1,113 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Replace Textarea with Inline Editor &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               /* Style the CKEditor element to look like a textfield */\r
+               .cke_textarea_inline\r
+               {\r
+                       padding: 10px;\r
+                       height: 200px;\r
+                       overflow: auto;\r
+\r
+                       border: 1px solid gray;\r
+                       -webkit-appearance: textfield;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea with Inline Editor\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       You can also create an inline editor from a <code>textarea</code>\r
+                       element. In this case the <code>textarea</code> will be replaced\r
+                       by a <code>div</code> element with inline editing enabled.\r
+               </p>\r
+<pre class="samples">\r
+// "article-body" is the name of a textarea element.\r
+var editor = CKEDITOR.inline( 'article-body' );\r
+</pre>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <h2>This is a sample form with some fields</h2>\r
+               <p>\r
+                       Title:<br>\r
+                       <input type="text" name="title" value="Sample Form"></p>\r
+               <p>\r
+                       Article Body (Textarea converted to CKEditor):<br>\r
+                       <textarea name="article-body" style="height: 200px">\r
+                               &lt;h2&gt;Technical details &lt;a id="tech-details" name="tech-details"&gt;&lt;/a&gt;&lt;/h2&gt;\r
+\r
+                               &lt;table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;"&gt;\r
+                                       &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt;\r
+                                       &lt;thead&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;th scope="col"&gt;Position&lt;/th&gt;\r
+                                               &lt;th scope="col"&gt;Astronaut&lt;/th&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;/thead&gt;\r
+                                       &lt;tbody&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;Commander&lt;/td&gt;\r
+                                               &lt;td&gt;Neil A. Armstrong&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;Command Module Pilot&lt;/td&gt;\r
+                                               &lt;td&gt;Michael Collins&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;Lunar Module Pilot&lt;/td&gt;\r
+                                               &lt;td&gt;Edwin &quot;Buzz&quot; E. Aldrin, Jr.&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;/tbody&gt;\r
+                               &lt;/table&gt;\r
+\r
+                               &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center"&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href="http://en.wikipedia.org/wiki/NASA" title="NASA"&gt;NASA&lt;/a&gt;&#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt;\r
+\r
+                               &lt;ol&gt;\r
+                                       &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt;\r
+                                       &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt;\r
+                                       &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt;\r
+                               &lt;/ol&gt;\r
+\r
+                               &lt;p&gt;After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis"&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean"&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt;\r
+\r
+                               &lt;hr /&gt;\r
+                               &lt;p style="text-align: right;"&gt;&lt;small&gt;Source: &lt;a href="http://en.wikipedia.org/wiki/Apollo_11"&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+                       </textarea>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+\r
+       <script>\r
+               CKEDITOR.inline( 'article-body' );\r
+       </script>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">\r
+                               http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>\r
+                       - Frederico Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/jquery.html b/release/samples/old/jquery.html
new file mode 100644 (file)
index 0000000..95e43ea
--- /dev/null
@@ -0,0 +1,103 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>jQuery Adapter &mdash; CKEditor Sample</title>\r
+       <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>\r
+       <script src="../../ckeditor.js"></script>\r
+       <script src="../../adapters/jquery.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               #editable\r
+               {\r
+                       padding: 10px;\r
+                       float: left;\r
+               }\r
+\r
+       </style>\r
+       <script>\r
+\r
+               CKEDITOR.disableAutoInline = true;\r
+\r
+               $( document ).ready( function() {\r
+                       $( '#editor1' ).ckeditor(); // Use CKEDITOR.replace() if element is <textarea>.\r
+                       $( '#editable' ).ckeditor(); // Use CKEDITOR.inline().\r
+               } );\r
+\r
+               function setValue() {\r
+                       $( '#editor1' ).val( $( 'input#val' ).val() );\r
+               }\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html" id="a-test">CKEditor Samples</a> &raquo; Create Editors with jQuery\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <div class="description">\r
+                       <p>\r
+                               This sample shows how to use the <a href="http://docs.ckeditor.com/#!/guide/dev_jquery">jQuery adapter</a>.\r
+                               Note that you have to include both CKEditor and jQuery scripts before including the adapter.\r
+                       </p>\r
+\r
+<pre class="samples">\r
+&lt;script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"&gt;&lt;/script&gt;\r
+&lt;script src="/ckedit../../ckeditor.js"&gt;&lt;/script&gt;\r
+&lt;script src="/ckeditor/adapters/jquery.js"&gt;&lt;/script&gt;\r
+</pre>\r
+\r
+                       <p>Then you can replace HTML elements with a CKEditor instance using the <code>ckeditor()</code> method.</p>\r
+\r
+<pre class="samples">\r
+$( document ).ready( function() {\r
+       $( 'textarea#editor1' ).ckeditor();\r
+} );\r
+</pre>\r
+               </div>\r
+\r
+               <h2 class="samples">Inline Example</h2>\r
+\r
+               <div id="editable" contenteditable="true">\r
+                       <p><img alt="Saturn V carrying Apollo 11" class="right" src="assets/sample.jpg"/><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>\r
+                       <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.\r
+                       <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+                       <blockquote><p>One small step for [a] man, one giant leap for mankind.</p></blockquote> <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p> <blockquote><p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p></blockquote>\r
+               </div>\r
+\r
+               <br style="clear: both">\r
+\r
+               <h2 class="samples">Classic (iframe-based) Example</h2>\r
+\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+\r
+               <p style="overflow: hidden">\r
+                       <input style="float: left" type="submit" value="Submit">\r
+                       <span style="float: right">\r
+                               <input type="text" id="val" value="I'm using jQuery val()!" size="30">\r
+                               <input onclick="setValue();" type="button" value="Set value">\r
+                       </span>\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/magicline/magicline.html b/release/samples/old/magicline/magicline.html
new file mode 100644 (file)
index 0000000..8fff40e
--- /dev/null
@@ -0,0 +1,209 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Using Magicline plugin &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-name" content="Magicline plugin">\r
+       <meta name="ckeditor-sample-group" content="Plugins">\r
+       <meta name="ckeditor-sample-description" content="Using the Magicline plugin to access difficult focus spaces.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Using Magicline plugin\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/magicline.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows the advantages of <strong>Magicline</strong> plugin\r
+                       which is to enhance the editing process. Thanks to this plugin,\r
+                       a number of difficult focus spaces which are inaccessible due to\r
+                       browser issues can now be focused.\r
+               </p>\r
+               <p>\r
+                       <strong>Magicline</strong> plugin shows a red line with a handler\r
+                       which, when clicked, inserts a paragraph and allows typing. To see this,\r
+                       focus an editor and move your mouse above the focus space you want\r
+                       to access. The plugin is enabled by default so no additional\r
+                       configuration is necessary.\r
+               </p>\r
+       </div>\r
+       <div>\r
+               <label for="editor1">\r
+                       Editor 1:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor uses a default <strong>Magicline</strong> setup.\r
+                       </p>\r
+               </div>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                               &lt;tbody&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;This table&lt;/td&gt;\r
+                                               &lt;td&gt;is the&lt;/td&gt;\r
+                                               &lt;td&gt;very first&lt;/td&gt;\r
+                                               &lt;td&gt;element of the document.&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;We are still&lt;/td&gt;\r
+                                               &lt;td&gt;able to acces&lt;/td&gt;\r
+                                               &lt;td&gt;the space before it.&lt;/td&gt;\r
+                                               &lt;td&gt;\r
+                                               &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                                                       &lt;tbody&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;This table is inside of a cell of another table.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;We can type&amp;nbsp;either before or after it though.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                       &lt;/tbody&gt;\r
+                                               &lt;/table&gt;\r
+                                               &lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                               &lt;/tbody&gt;\r
+                       &lt;/table&gt;\r
+\r
+                       &lt;p&gt;Two succesive horizontal lines (&lt;tt&gt;HR&lt;/tt&gt; tags). We can access the space in between:&lt;/p&gt;\r
+\r
+                       &lt;hr /&gt;\r
+                       &lt;hr /&gt;\r
+                       &lt;ol&gt;\r
+                               &lt;li&gt;This numbered list...&lt;/li&gt;\r
+                               &lt;li&gt;...is a neighbour of a horizontal line...&lt;/li&gt;\r
+                               &lt;li&gt;...and another list.&lt;/li&gt;\r
+                       &lt;/ol&gt;\r
+\r
+                       &lt;ul&gt;\r
+                               &lt;li&gt;We can type between the lists...&lt;/li&gt;\r
+                               &lt;li&gt;...thanks to &lt;strong&gt;Magicline&lt;/strong&gt;.&lt;/li&gt;\r
+                       &lt;/ul&gt;\r
+\r
+                       &lt;p&gt;Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.&lt;/p&gt;\r
+\r
+                       &lt;div style=&quot;border: 2px dashed green; background: #ddd; text-align: center;&quot;&gt;\r
+                       &lt;p&gt;This text is wrapped in a&amp;nbsp;&lt;tt&gt;DIV&lt;/tt&gt;&amp;nbsp;element. We can type after this element though.&lt;/p&gt;\r
+                       &lt;/div&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // <textarea>, or inside a <head><script> in a\r
+                       // window.onload event handler.\r
+\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               extraPlugins: 'magicline',      // Ensure that magicline plugin, which is required for this sample, is loaded.\r
+                               allowedContent: true            // Switch off the ACF, so very complex content created to\r
+                                                                                       // show magicline's power isn't filtered.\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+       <br>\r
+       <div>\r
+               <label for="editor2">\r
+                       Editor 2:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a blue line.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor2', {\r
+       magicline_color: 'blue'\r
+});</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor2" name="editor2" rows="10">\r
+                       &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                               &lt;tbody&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;This table&lt;/td&gt;\r
+                                               &lt;td&gt;is the&lt;/td&gt;\r
+                                               &lt;td&gt;very first&lt;/td&gt;\r
+                                               &lt;td&gt;element of the document.&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;We are still&lt;/td&gt;\r
+                                               &lt;td&gt;able to acces&lt;/td&gt;\r
+                                               &lt;td&gt;the space before it.&lt;/td&gt;\r
+                                               &lt;td&gt;\r
+                                               &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                                                       &lt;tbody&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;This table is inside of a cell of another table.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;We can type&amp;nbsp;either before or after it though.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                       &lt;/tbody&gt;\r
+                                               &lt;/table&gt;\r
+                                               &lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                               &lt;/tbody&gt;\r
+                       &lt;/table&gt;\r
+\r
+                       &lt;p&gt;Two succesive horizontal lines (&lt;tt&gt;HR&lt;/tt&gt; tags). We can access the space in between:&lt;/p&gt;\r
+\r
+                       &lt;hr /&gt;\r
+                       &lt;hr /&gt;\r
+                       &lt;ol&gt;\r
+                               &lt;li&gt;This numbered list...&lt;/li&gt;\r
+                               &lt;li&gt;...is a neighbour of a horizontal line...&lt;/li&gt;\r
+                               &lt;li&gt;...and another list.&lt;/li&gt;\r
+                       &lt;/ol&gt;\r
+\r
+                       &lt;ul&gt;\r
+                               &lt;li&gt;We can type between the lists...&lt;/li&gt;\r
+                               &lt;li&gt;...thanks to &lt;strong&gt;Magicline&lt;/strong&gt;.&lt;/li&gt;\r
+                       &lt;/ul&gt;\r
+\r
+                       &lt;p&gt;Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.&lt;/p&gt;\r
+\r
+                       &lt;div style=&quot;border: 2px dashed green; background: #ddd; text-align: center;&quot;&gt;\r
+                       &lt;p&gt;This text is wrapped in a&amp;nbsp;&lt;tt&gt;DIV&lt;/tt&gt;&amp;nbsp;element. We can type after this element though.&lt;/p&gt;\r
+                       &lt;/div&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // <textarea>, or inside a <head><script> in a\r
+                       // window.onload event handler.\r
+\r
+                       CKEDITOR.replace( 'editor2', {\r
+                               extraPlugins: 'magicline',      // Ensure that magicline plugin, which is required for this sample, is loaded.\r
+                               magicline_color: 'blue',        // Blue line\r
+                               allowedContent: true            // Switch off the ACF, so very complex content created to\r
+                                                                                       // show magicline's power isn't filtered.\r
+                       });\r
+\r
+               </script>\r
+       </div>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/readonly.html b/release/samples/old/readonly.html
new file mode 100644 (file)
index 0000000..edd1118
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Using the CKEditor Read-Only API &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+       <script>\r
+\r
+               var editor;\r
+\r
+               // The instanceReady event is fired, when an instance of CKEditor has finished\r
+               // its initialization.\r
+               CKEDITOR.on( 'instanceReady', function( ev ) {\r
+                       editor = ev.editor;\r
+\r
+                       // Show this "on" button.\r
+                       document.getElementById( 'readOnlyOn' ).style.display = '';\r
+\r
+                       // Event fired when the readOnly property changes.\r
+                       editor.on( 'readOnly', function() {\r
+                               document.getElementById( 'readOnlyOn' ).style.display = this.readOnly ? 'none' : '';\r
+                               document.getElementById( 'readOnlyOff' ).style.display = this.readOnly ? '' : 'none';\r
+                       });\r
+               });\r
+\r
+               function toggleReadOnly( isReadOnly ) {\r
+                       // Change the read-only state of the editor.\r
+                       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly\r
+                       editor.setReadOnly( isReadOnly );\r
+               }\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Using the CKEditor Read-Only API\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/readonly.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to use the\r
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly">setReadOnly</a></code>\r
+                       API to put editor into the read-only state that makes it impossible for users to change the editor contents.\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <p>\r
+                       <textarea class="ckeditor" id="editor1" name="editor1" cols="100" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               </p>\r
+               <p>\r
+                       <input id="readOnlyOn" onclick="toggleReadOnly();" type="button" value="Make it read-only" style="display:none">\r
+                       <input id="readOnlyOff" onclick="toggleReadOnly( false );" type="button" value="Make it editable again" style="display:none">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/replacebyclass.html b/release/samples/old/replacebyclass.html
new file mode 100644 (file)
index 0000000..2edbf49
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Replace Textareas by Class Name &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea Elements by Class Name\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to automatically replace all <code>&lt;textarea&gt;</code> elements\r
+                       of a given class with a CKEditor instance.\r
+               </p>\r
+               <p>\r
+                       To replace a <code>&lt;textarea&gt;</code> element, simply assign it the <code>ckeditor</code>\r
+                       class, as in the code below:\r
+               </p>\r
+<pre class="samples">\r
+&lt;textarea <strong>class="ckeditor</strong>" name="editor1"&gt;&lt;/textarea&gt;\r
+</pre>\r
+               <p>\r
+                       Note that other <code>&lt;textarea&gt;</code> attributes (like <code>id</code> or <code>name</code>) need to be adjusted to your document.\r
+               </p>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <p>\r
+                       <label for="editor1">\r
+                               Editor 1:\r
+                       </label>\r
+                       <textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10">\r
+                               &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+                       </textarea>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/replacebycode.html b/release/samples/old/replacebycode.html
new file mode 100644 (file)
index 0000000..36ace8b
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Replace Textarea by Code &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea Elements Using JavaScript Code\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/classic.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using an <code>&lt;iframe&gt;</code> element-based editing area, provided by the <strong>Wysiwygarea</strong> plugin.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>' )\r
+</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // <textarea>, or inside a <head><script> in a\r
+                       // window.onload event handler.\r
+\r
+                       // Replace the <textarea id="editor"> with an CKEditor\r
+                       // instance, using default configurations.\r
+\r
+                       CKEDITOR.replace( 'editor1' );\r
+\r
+               </script>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/sample.css b/release/samples/old/sample.css
new file mode 100644 (file)
index 0000000..af866fe
--- /dev/null
@@ -0,0 +1,357 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+html, body, h1, h2, h3, h4, h5, h6, div, span, blockquote, p, address, form, fieldset, img, ul, ol, dl, dt, dd, li, hr, table, td, th, strong, em, sup, sub, dfn, ins, del, q, cite, var, samp, code, kbd, tt, pre\r
+{\r
+       line-height: 1.5;\r
+}\r
+\r
+body\r
+{\r
+       padding: 10px 30px;\r
+}\r
+\r
+input, textarea, select, option, optgroup, button, td, th\r
+{\r
+       font-size: 100%;\r
+}\r
+\r
+pre\r
+{\r
+       -moz-tab-size: 4;\r
+       tab-size: 4;\r
+}\r
+\r
+pre, code, kbd, samp, tt\r
+{\r
+       font-family: monospace,monospace;\r
+       font-size: 1em;\r
+}\r
+\r
+body {\r
+       width: 960px;\r
+       margin: 0 auto;\r
+}\r
+\r
+code\r
+{\r
+       background: #f3f3f3;\r
+       border: 1px solid #ddd;\r
+       padding: 1px 4px;\r
+       border-radius: 3px;\r
+}\r
+\r
+abbr\r
+{\r
+       border-bottom: 1px dotted #555;\r
+       cursor: pointer;\r
+}\r
+\r
+.new, .beta\r
+{\r
+       text-transform: uppercase;\r
+       font-size: 10px;\r
+       font-weight: bold;\r
+       padding: 1px 4px;\r
+       margin: 0 0 0 5px;\r
+       color: #fff;\r
+       float: right;\r
+       border-radius: 3px;\r
+}\r
+\r
+.new\r
+{\r
+       background: #FF7E00;\r
+       border: 1px solid #DA8028;\r
+       text-shadow: 0 1px 0 #C97626;\r
+\r
+       box-shadow: 0 2px 3px 0 #FFA54E inset;\r
+}\r
+\r
+.beta\r
+{\r
+       background: #18C0DF;\r
+       border: 1px solid #19AAD8;\r
+       text-shadow: 0 1px 0 #048CAD;\r
+       font-style: italic;\r
+\r
+       box-shadow: 0 2px 3px 0 #50D4FD inset;\r
+}\r
+\r
+h1.samples\r
+{\r
+       color: #0782C1;\r
+       font-size: 200%;\r
+       font-weight: normal;\r
+       margin: 0;\r
+       padding: 0;\r
+}\r
+\r
+h1.samples a\r
+{\r
+       color: #0782C1;\r
+       text-decoration: none;\r
+       border-bottom: 1px dotted #0782C1;\r
+}\r
+\r
+.samples a:hover\r
+{\r
+       border-bottom: 1px dotted #0782C1;\r
+}\r
+\r
+h2.samples\r
+{\r
+       color: #000000;\r
+       font-size: 130%;\r
+       margin: 15px 0 0 0;\r
+       padding: 0;\r
+}\r
+\r
+p, blockquote, address, form, pre, dl, h1.samples, h2.samples\r
+{\r
+       margin-bottom: 15px;\r
+}\r
+\r
+ul.samples\r
+{\r
+       margin-bottom: 15px;\r
+}\r
+\r
+.clear\r
+{\r
+       clear: both;\r
+}\r
+\r
+fieldset\r
+{\r
+       margin: 0;\r
+       padding: 10px;\r
+}\r
+\r
+body, input, textarea\r
+{\r
+       color: #333333;\r
+       font-family: Arial, Helvetica, sans-serif;\r
+}\r
+\r
+body\r
+{\r
+       font-size: 75%;\r
+}\r
+\r
+a.samples\r
+{\r
+       color: #189DE1;\r
+       text-decoration: none;\r
+}\r
+\r
+form\r
+{\r
+       margin: 0;\r
+       padding: 0;\r
+}\r
+\r
+pre.samples\r
+{\r
+       background-color: #F7F7F7;\r
+       border: 1px solid #D7D7D7;\r
+       overflow: auto;\r
+       padding: 0.25em;\r
+       white-space: pre-wrap; /* CSS 2.1 */\r
+       word-wrap: break-word; /* IE7 */\r
+}\r
+\r
+#footer\r
+{\r
+       clear: both;\r
+       padding-top: 10px;\r
+}\r
+\r
+#footer hr\r
+{\r
+       margin: 10px 0 15px 0;\r
+       height: 1px;\r
+       border: solid 1px gray;\r
+       border-bottom: none;\r
+}\r
+\r
+#footer p\r
+{\r
+       margin: 0 10px 10px 10px;\r
+       float: left;\r
+}\r
+\r
+#footer #copy\r
+{\r
+       float: right;\r
+}\r
+\r
+#outputSample\r
+{\r
+       width: 100%;\r
+       table-layout: fixed;\r
+}\r
+\r
+#outputSample thead th\r
+{\r
+       color: #dddddd;\r
+       background-color: #999999;\r
+       padding: 4px;\r
+       white-space: nowrap;\r
+}\r
+\r
+#outputSample tbody th\r
+{\r
+       vertical-align: top;\r
+       text-align: left;\r
+}\r
+\r
+#outputSample pre\r
+{\r
+       margin: 0;\r
+       padding: 0;\r
+}\r
+\r
+.description\r
+{\r
+       border: 1px dotted #B7B7B7;\r
+       margin-bottom: 10px;\r
+       padding: 10px 10px 0;\r
+       overflow: hidden;\r
+}\r
+\r
+label\r
+{\r
+       display: block;\r
+       margin-bottom: 6px;\r
+}\r
+\r
+/**\r
+ *     CKEditor editables are automatically set with the "cke_editable" class\r
+ *     plus cke_editable_(inline|themed) depending on the editor type.\r
+ */\r
+\r
+/* Style a bit the inline editables. */\r
+.cke_editable.cke_editable_inline\r
+{\r
+       cursor: pointer;\r
+}\r
+\r
+/* Once an editable element gets focused, the "cke_focus" class is\r
+   added to it, so we can style it differently. */\r
+.cke_editable.cke_editable_inline.cke_focus\r
+{\r
+       box-shadow: inset 0px 0px 20px 3px #ddd, inset 0 0 1px #000;\r
+       outline: none;\r
+       background: #eee;\r
+       cursor: text;\r
+}\r
+\r
+/* Avoid pre-formatted overflows inline editable. */\r
+.cke_editable_inline pre\r
+{\r
+       white-space: pre-wrap;\r
+       word-wrap: break-word;\r
+}\r
+\r
+/**\r
+ *     Samples index styles.\r
+ */\r
+\r
+.twoColumns,\r
+.twoColumnsLeft,\r
+.twoColumnsRight\r
+{\r
+       overflow: hidden;\r
+}\r
+\r
+.twoColumnsLeft,\r
+.twoColumnsRight\r
+{\r
+       width: 45%;\r
+}\r
+\r
+.twoColumnsLeft\r
+{\r
+       float: left;\r
+}\r
+\r
+.twoColumnsRight\r
+{\r
+       float: right;\r
+}\r
+\r
+dl.samples\r
+{\r
+       padding: 0 0 0 40px;\r
+}\r
+dl.samples > dt\r
+{\r
+       display: list-item;\r
+       list-style-type: disc;\r
+       list-style-position: outside;\r
+       margin: 0 0 3px;\r
+}\r
+dl.samples > dd\r
+{\r
+       margin: 0 0 3px;\r
+}\r
+.warning\r
+{\r
+       color: #ff0000;\r
+       background-color: #FFCCBA;\r
+       border: 2px dotted #ff0000;\r
+       padding: 15px 10px;\r
+       margin: 10px 0;\r
+}\r
+\r
+.warning.deprecated {\r
+       font-size: 1.3em;\r
+}\r
+\r
+/* Used on inline samples */\r
+\r
+blockquote\r
+{\r
+       font-style: italic;\r
+       font-family: Georgia, Times, "Times New Roman", serif;\r
+       padding: 2px 0;\r
+       border-style: solid;\r
+       border-color: #ccc;\r
+       border-width: 0;\r
+}\r
+\r
+.cke_contents_ltr blockquote\r
+{\r
+       padding-left: 20px;\r
+       padding-right: 8px;\r
+       border-left-width: 5px;\r
+}\r
+\r
+.cke_contents_rtl blockquote\r
+{\r
+       padding-left: 8px;\r
+       padding-right: 20px;\r
+       border-right-width: 5px;\r
+}\r
+\r
+img.right {\r
+       border: 1px solid #ccc;\r
+       float: right;\r
+       margin-left: 15px;\r
+       padding: 5px;\r
+}\r
+\r
+img.left {\r
+       border: 1px solid #ccc;\r
+       float: left;\r
+       margin-right: 15px;\r
+       padding: 5px;\r
+}\r
+\r
+.marker\r
+{\r
+       background-color: Yellow;\r
+}\r
diff --git a/release/samples/old/sample.js b/release/samples/old/sample.js
new file mode 100644 (file)
index 0000000..59b64ee
--- /dev/null
@@ -0,0 +1,50 @@
+/**\r
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+// Tool scripts for the sample pages.\r
+// This file can be ignored and is not required to make use of CKEditor.\r
+\r
+( function() {\r
+       CKEDITOR.on( 'instanceReady', function( ev ) {\r
+               // Check for sample compliance.\r
+               var editor = ev.editor,\r
+                       meta = CKEDITOR.document.$.getElementsByName( 'ckeditor-sample-required-plugins' ),\r
+                       requires = meta.length ? CKEDITOR.dom.element.get( meta[ 0 ] ).getAttribute( 'content' ).split( ',' ) : [],\r
+                       missing = [],\r
+                       i;\r
+\r
+               if ( requires.length ) {\r
+                       for ( i = 0; i < requires.length; i++ ) {\r
+                               if ( !editor.plugins[ requires[ i ] ] )\r
+                                       missing.push( '<code>' + requires[ i ] + '</code>' );\r
+                       }\r
+\r
+                       if ( missing.length ) {\r
+                               var warn = CKEDITOR.dom.element.createFromHtml(\r
+                                       '<div class="warning">' +\r
+                                               '<span>To fully experience this demo, the ' + missing.join( ', ' ) + ' plugin' + ( missing.length > 1 ? 's are' : ' is' ) + ' required.</span>' +\r
+                                       '</div>'\r
+                               );\r
+                               warn.insertBefore( editor.container );\r
+                       }\r
+               }\r
+\r
+               // Set icons.\r
+               var doc = new CKEDITOR.dom.document( document ),\r
+                       icons = doc.find( '.button_icon' );\r
+\r
+               for ( i = 0; i < icons.count(); i++ ) {\r
+                       var icon = icons.getItem( i ),\r
+                               name = icon.getAttribute( 'data-icon' ),\r
+                               style = CKEDITOR.skin.getIconStyle( name, ( CKEDITOR.lang.dir == 'rtl' ) );\r
+\r
+                       icon.addClass( 'cke_button_icon' );\r
+                       icon.addClass( 'cke_button__' + name + '_icon' );\r
+                       icon.setAttribute( 'style', style );\r
+                       icon.setStyle( 'float', 'none' );\r
+\r
+               }\r
+       } );\r
+} )();\r
diff --git a/release/samples/old/sample_posteddata.php b/release/samples/old/sample_posteddata.php
new file mode 100644 (file)
index 0000000..866867e
--- /dev/null
@@ -0,0 +1,16 @@
+<?php /* <body><pre>\r
+\r
+-------------------------------------------------------------------------------------------\r
+  CKEditor - Posted Data\r
+\r
+  We are sorry, but your Web server does not support the PHP language used in this script.\r
+\r
+  Please note that CKEditor can be used with any other server-side language than just PHP.\r
+  To save the content created with CKEditor you need to read the POST data on the server\r
+  side and write it to a file or the database.\r
+\r
+  Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+  For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-------------------------------------------------------------------------------------------\r
+\r
+</pre><div style="display:none"></body> */ include "assets/posteddata.php"; ?>\r
diff --git a/release/samples/old/tabindex.html b/release/samples/old/tabindex.html
new file mode 100644 (file)
index 0000000..82ed647
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>TAB Key-Based Navigation &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+       <style>\r
+\r
+               .cke_focused,\r
+               .cke_editable.cke_focused\r
+               {\r
+                       outline: 3px dotted blue !important;\r
+                       *border: 3px dotted blue !important;    /* For IE7 */\r
+               }\r
+\r
+       </style>\r
+       <script>\r
+\r
+               CKEDITOR.on( 'instanceReady', function( evt ) {\r
+                       var editor = evt.editor;\r
+                       editor.setData( 'This editor has it\'s tabIndex set to <strong>' + editor.tabIndex + '</strong>' );\r
+\r
+                       // Apply focus class name.\r
+                       editor.on( 'focus', function() {\r
+                               editor.container.addClass( 'cke_focused' );\r
+                       });\r
+                       editor.on( 'blur', function() {\r
+                               editor.container.removeClass( 'cke_focused' );\r
+                       });\r
+\r
+                       // Put startup focus on the first editor in tab order.\r
+                       if ( editor.tabIndex == 1 )\r
+                               editor.focus();\r
+               });\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; TAB Key-Based Navigation\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/tabindex.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how tab key navigation among editor instances is\r
+                       affected by the <code>tabIndex</code> attribute from\r
+                       the original page element. Use TAB key to move between the editors.\r
+               </p>\r
+       </div>\r
+       <p>\r
+               <textarea class="ckeditor" cols="80" id="editor4" rows="10" tabindex="1"></textarea>\r
+       </p>\r
+       <div class="ckeditor" contenteditable="true" id="editor1" tabindex="4"></div>\r
+       <p>\r
+               <textarea class="ckeditor" cols="80" id="editor2" rows="10" tabindex="2"></textarea>\r
+       </p>\r
+       <p>\r
+               <textarea class="ckeditor" cols="80" id="editor3" rows="10" tabindex="3"></textarea>\r
+       </p>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/toolbar/toolbar.html b/release/samples/old/toolbar/toolbar.html
new file mode 100644 (file)
index 0000000..e40d2a1
--- /dev/null
@@ -0,0 +1,235 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Toolbar Configuration &mdash; CKEditor Sample</title>\r
+       <meta name="ckeditor-sample-name" content="Toolbar Configurations">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to display full or custom toolbar layout.">\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Toolbar Configuration\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="../../../samples/toolbarconfigurator/index.html#basic">brand new CKEditor Toolbar Configurator</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample page demonstrates editor with loaded <a href="#fullToolbar">full toolbar</a> (all registered buttons) and, if\r
+                       current editor's configuration modifies default settings, also editor with <a href="#currentToolbar">modified toolbar</a>.\r
+               </p>\r
+\r
+               <p>Since CKEditor 4 there are two ways to configure toolbar buttons.</p>\r
+\r
+               <h2 class="samples">By <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbar">config.toolbar</a></h2>\r
+\r
+               <p>\r
+                       You can explicitly define which buttons are displayed in which groups and in which order.\r
+                       This is the more precise setting, but less flexible. If newly added plugin adds its\r
+                       own button you'll have to add it manually to your <code>config.toolbar</code> setting as well.\r
+               </p>\r
+\r
+               <p>To add a CKEditor instance with custom toolbar setting, insert the following JavaScript call to your code:</p>\r
+\r
+               <pre class="samples">\r
+CKEDITOR.replace( <em>'textarea_id'</em>, {\r
+       <strong>toolbar:</strong> [\r
+               { name: 'document', items: [ 'Source', '-', 'NewPage', 'Preview', '-', 'Templates' ] }, // Defines toolbar group with name (used to create voice label) and items in 3 subgroups.\r
+               [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ],                  // Defines toolbar group without name.\r
+               '/',                                                                                                                                                                    // Line break - next group will be placed in new line.\r
+               { name: 'basicstyles', items: [ 'Bold', 'Italic' ] }\r
+       ]\r
+});</pre>\r
+\r
+               <h2 class="samples">By <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbarGroups">config.toolbarGroups</a></h2>\r
+\r
+               <p>\r
+                       You can define which groups of buttons (like e.g. <code>basicstyles</code>, <code>clipboard</code>\r
+                       and <code>forms</code>) are displayed and in which order. Registered buttons are associated\r
+                       with toolbar groups by <code>toolbar</code> property in their definition.\r
+                       This setting's advantage is that you don't have to modify toolbar configuration\r
+                       when adding/removing plugins which register their own buttons.\r
+               </p>\r
+\r
+               <p>To add a CKEditor instance with custom toolbar groups setting, insert the following JavaScript call to your code:</p>\r
+\r
+               <pre class="samples">\r
+CKEDITOR.replace( <em>'textarea_id'</em>, {\r
+       <strong>toolbarGroups:</strong> [\r
+               { name: 'document',        groups: [ 'mode', 'document' ] },                    // Displays document group with its two subgroups.\r
+               { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },                       // Group's name will be used to create voice label.\r
+               '/',                                                                                                                            // Line break - next group will be placed in new line.\r
+               { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },\r
+               { name: 'links' }\r
+       ]\r
+\r
+       // NOTE: Remember to leave 'toolbar' property with the default value (null).\r
+});</pre>\r
+       </div>\r
+\r
+       <div id="currentToolbar" style="display: none">\r
+               <h2 class="samples">Current toolbar configuration</h2>\r
+               <p>Below you can see editor with current toolbar definition.</p>\r
+               <textarea cols="80" id="editorCurrent" name="editorCurrent" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               <pre id="editorCurrentCfg" class="samples"></pre>\r
+       </div>\r
+\r
+       <div id="fullToolbar">\r
+               <h2 class="samples">Full toolbar configuration</h2>\r
+               <p>Below you can see editor with full toolbar, generated automatically by the editor.</p>\r
+               <p>\r
+                       <strong>Note</strong>: To create editor instance with full toolbar you don't have to set anything.\r
+                       Just leave <code>toolbar</code> and <code>toolbarGroups</code> with the default, <code>null</code> values.\r
+               </p>\r
+               <textarea cols="80" id="editorFull" name="editorFull" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               <pre id="editorFullCfg" class="samples"></pre>\r
+       </div>\r
+\r
+       <script>\r
+\r
+(function() {\r
+       'use strict';\r
+\r
+       var buttonsNames;\r
+\r
+       CKEDITOR.config.extraPlugins = 'toolbar';\r
+\r
+       CKEDITOR.on( 'instanceReady', function( evt ) {\r
+               var editor = evt.editor,\r
+                       editorCurrent = editor.name == 'editorCurrent',\r
+                       defaultToolbar = !( editor.config.toolbar || editor.config.toolbarGroups || editor.config.removeButtons ),\r
+                       pre = CKEDITOR.document.getById( editor.name + 'Cfg' ),\r
+                       output = '';\r
+\r
+               if ( editorCurrent ) {\r
+                       // If default toolbar configuration has been modified, show "current toolbar" section.\r
+                       if ( !defaultToolbar )\r
+                               CKEDITOR.document.getById( 'currentToolbar' ).show();\r
+                       else\r
+                               return;\r
+               }\r
+\r
+               if ( !buttonsNames )\r
+                       buttonsNames = createButtonsNamesHash( editor.ui.items );\r
+\r
+               // Toolbar isn't set explicitly, so it was created automatically from toolbarGroups.\r
+               if ( !editor.config.toolbar ) {\r
+                       output +=\r
+                               '// Toolbar configuration generated automatically by the editor based on config.toolbarGroups.\n' +\r
+                               dumpToolbarConfiguration( editor ) +\r
+                               '\n\n' +\r
+                               '// Toolbar groups configuration.\n' +\r
+                               dumpToolbarConfiguration( editor, true )\r
+               }\r
+               // Toolbar groups doesn't count in this case - print only toolbar.\r
+               else {\r
+                       output += '// Toolbar configuration.\n' +\r
+                               dumpToolbarConfiguration( editor );\r
+               }\r
+\r
+               // Recreate to avoid old IE from loosing whitespaces on filling <pre> content.\r
+               var preOutput = pre.getOuterHtml().replace( /(?=<\/)/, output );\r
+               CKEDITOR.dom.element.createFromHtml( preOutput ).replace( pre );\r
+       } );\r
+\r
+       CKEDITOR.replace( 'editorCurrent', { height: 100 } );\r
+       CKEDITOR.replace( 'editorFull', {\r
+               // Reset toolbar settings, so full toolbar will be generated automatically.\r
+               toolbar: null,\r
+               toolbarGroups: null,\r
+               removeButtons: null,\r
+               height: 100\r
+       } );\r
+\r
+       function dumpToolbarConfiguration( editor, printGroups ) {\r
+               var output = [],\r
+                       toolbar = editor.toolbar;\r
+\r
+               for ( var i = 0; i < toolbar.length; ++i ) {\r
+                       var group = dumpToolbarGroup( toolbar[ i ], printGroups );\r
+                       if ( group )\r
+                               output.push( group );\r
+               }\r
+\r
+               return 'config.toolbar' + ( printGroups ? 'Groups' : '' ) + ' = [\n\t' + output.join( ',\n\t' ) + '\n];';\r
+       }\r
+\r
+       function dumpToolbarGroup( group, printGroups ) {\r
+               var output = [];\r
+\r
+               if ( typeof group == 'string' )\r
+                       return '\'' + group + '\'';\r
+               if ( CKEDITOR.tools.isArray( group ) )\r
+                       return dumpToolbarItems( group );\r
+               // Skip group when printing entire toolbar configuration and there are no items in this group.\r
+               if ( !printGroups && !group.items )\r
+                       return;\r
+\r
+               if ( group.name )\r
+                       output.push( 'name: \'' + group.name + '\'' );\r
+\r
+               if ( group.groups )\r
+                       output.push( 'groups: ' + dumpToolbarItems( group.groups ) );\r
+\r
+               if ( !printGroups )\r
+                       output.push( 'items: ' + dumpToolbarItems( group.items ) );\r
+\r
+               return '{ ' + output.join( ', ' ) + ' }';\r
+       }\r
+\r
+       function dumpToolbarItems( items ) {\r
+               if ( typeof items == 'string' )\r
+                       return '\'' + items + '\'';\r
+\r
+               var names = [],\r
+                       i, item;\r
+\r
+               for ( var i = 0; i < items.length; ++i ) {\r
+                       item = items[ i ];\r
+                       if ( typeof item == 'string' )\r
+                               names.push( item );\r
+                       else {\r
+                               if ( item.type == CKEDITOR.UI_SEPARATOR )\r
+                                       names.push( '-' );\r
+                               else\r
+                                       names.push( buttonsNames[ item.name ] );\r
+                       }\r
+               }\r
+\r
+               return '[ \'' + names.join( '\', \'' ) + '\' ]';\r
+       }\r
+\r
+       // Creates { 'lowercased': 'LowerCased' } buttons names hash.\r
+       function createButtonsNamesHash( items ) {\r
+               var hash = {},\r
+                       name;\r
+\r
+               for ( name in items ) {\r
+                       hash[ items[ name ].name ] = name;\r
+               }\r
+\r
+               return hash;\r
+       }\r
+\r
+})();\r
+       </script>\r
+\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/uicolor.html b/release/samples/old/uicolor.html
new file mode 100644 (file)
index 0000000..bff1b96
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>UI Color Picker &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; UI Color\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/uicolor.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to automatically replace <code>&lt;textarea&gt;</code> elements\r
+                       with a CKEditor instance with an option to change the color of its user interface.<br>\r
+                       <strong>Note:</strong>The UI skin color feature depends on the CKEditor skin\r
+                       compatibility. The Moono and Kama skins are examples of skins that work with it.\r
+               </p>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+       <p>\r
+               This editor instance has a UI color value defined in configuration to change the skin color,\r
+               To specify the color of the user interface, set the <code>uiColor</code> property:\r
+       </p>\r
+       <pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       <strong>uiColor: '#14B8C4'</strong>\r
+});</pre>\r
+       <p>\r
+               Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+               the <code>&lt;textarea&gt;</code> element to be replaced.\r
+       </p>\r
+       <p>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               <script>\r
+\r
+                       // Replace the <textarea id="editor"> with an CKEditor\r
+                       // instance, using default configurations.\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               uiColor: '#14B8C4',\r
+                               toolbar: [\r
+                                       [ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],\r
+                                       [ 'FontSize', 'TextColor', 'BGColor' ]\r
+                               ]\r
+                       });\r
+\r
+               </script>\r
+       </p>\r
+       <p>\r
+               <input type="submit" value="Submit">\r
+       </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/uilanguages.html b/release/samples/old/uilanguages.html
new file mode 100644 (file)
index 0000000..9c1d0b8
--- /dev/null
@@ -0,0 +1,122 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>User Interface Globalization &mdash; CKEditor Sample</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <script src="assets/uilanguages/languages.js"></script>\r
+       <link rel="stylesheet" href="sample.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; User Interface Languages\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/uilanguages.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to automatically replace <code>&lt;textarea&gt;</code> elements\r
+                       with a CKEditor instance with an option to change the language of its user interface.\r
+               </p>\r
+               <p>\r
+                       It pulls the language list from CKEditor <code>_languages.js</code> file that contains the list of supported languages and creates\r
+                       a drop-down list that lets the user change the UI language.\r
+               </p>\r
+               <p>\r
+                       By default, CKEditor automatically localizes the editor to the language of the user.\r
+                       The UI language can be controlled with two configuration options:\r
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-language">language</a></code> and\r
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-defaultLanguage">\r
+                       defaultLanguage</a></code>. The <code>defaultLanguage</code> setting specifies the\r
+                       default CKEditor language to be used when a localization suitable for user's settings is not available.\r
+               </p>\r
+               <p>\r
+                       To specify the user interface language that will be used no matter what language is\r
+                       specified in user's browser or operating system, set the <code>language</code> property:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       // Load the German interface.\r
+       <strong>language: 'de'</strong>\r
+});</pre>\r
+               <p>\r
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+                       the <code>&lt;textarea&gt;</code> element to be replaced.\r
+               </p>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <p>\r
+                       Available languages (<span id="count"> </span> languages!):<br>\r
+                       <script>\r
+\r
+                               document.write( '<select disabled="disabled" id="languages" onchange="createEditor( this.value );">' );\r
+\r
+                               // Get the language list from the _languages.js file.\r
+                               for ( var i = 0 ; i < window.CKEDITOR_LANGS.length ; i++ ) {\r
+                                       document.write(\r
+                                               '<option value="' + window.CKEDITOR_LANGS[i].code + '">' +\r
+                                                       window.CKEDITOR_LANGS[i].name +\r
+                                               '</option>' );\r
+                               }\r
+\r
+                               document.write( '</select>' );\r
+\r
+                       </script>\r
+                       <br>\r
+                       <span style="color: #888888">\r
+                               (You may see strange characters if your system does not support the selected language)\r
+                       </span>\r
+               </p>\r
+               <p>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+                       <script>\r
+\r
+                               // Set the number of languages.\r
+                               document.getElementById( 'count' ).innerHTML = window.CKEDITOR_LANGS.length;\r
+\r
+                               var editor;\r
+\r
+                               function createEditor( languageCode ) {\r
+                                       if ( editor )\r
+                                               editor.destroy();\r
+\r
+                                       // Replace the <textarea id="editor"> with an CKEditor\r
+                                       // instance, using default configurations.\r
+                                       editor = CKEDITOR.replace( 'editor1', {\r
+                                               language: languageCode,\r
+\r
+                                               on: {\r
+                                                       instanceReady: function() {\r
+                                                               // Wait for the editor to be ready to set\r
+                                                               // the language combo.\r
+                                                               var languages = document.getElementById( 'languages' );\r
+                                                               languages.value = this.langCode;\r
+                                                               languages.disabled = false;\r
+                                                       }\r
+                                               }\r
+                                       });\r
+                               }\r
+\r
+                               // At page startup, load the default language:\r
+                               createEditor( '' );\r
+\r
+                       </script>\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/wysiwygarea/fullpage.html b/release/samples/old/wysiwygarea/fullpage.html
new file mode 100644 (file)
index 0000000..bb3193a
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Full Page Editing &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Full page support">\r
+       <meta name="ckeditor-sample-group" content="Plugins">\r
+       <meta name="ckeditor-sample-description" content="CKEditor inserted with a JavaScript call and used to edit the whole page from &lt;html&gt; to &lt;/html&gt;.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Full Page Editing\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/fullpage.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to edit entire HTML pages, from the\r
+                       <code>&lt;html&gt;</code> tag to the <code>&lt;/html&gt;</code> tag.\r
+               </p>\r
+               <p>\r
+                       The CKEditor instance below is inserted with a JavaScript call using the following code:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       <strong>fullPage: true</strong>,\r
+       <strong>allowedContent: true</strong>\r
+});\r
+</pre>\r
+               <p>\r
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+                       the <code>&lt;textarea&gt;</code> element to be replaced.\r
+               </p>\r
+               <p>\r
+                       The <code><em>allowedContent</em></code> in the code above is set to <code>true</code> to disable content filtering.\r
+                       Setting this option is not obligatory, but in full page mode there is a strong chance that one may want be able to freely enter any HTML content in source mode without any limitations.\r
+               </p>\r
+       </div>\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <label for="editor1">\r
+                       CKEditor output the entire page including content outside of\r
+                       <code>&lt;body&gt;</code> element, so content like meta and title can be changed:\r
+               </label>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;h1&gt;&lt;img align=&quot;right&quot; alt=&quot;Saturn V carrying Apollo 11&quot; src=&quot;../../../samples/old/assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               fullPage: true,\r
+                               allowedContent: true,\r
+                               extraPlugins: 'wysiwygarea'\r
+                       });\r
+\r
+               </script>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/old/xhtmlstyle.html b/release/samples/old/xhtmlstyle.html
new file mode 100644 (file)
index 0000000..daf5879
--- /dev/null
@@ -0,0 +1,234 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>XHTML Compliant Output &mdash; CKEditor Sample</title>\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <script src="../../ckeditor.js"></script>\r
+       <script src="sample.js"></script>\r
+       <link href="sample.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="index.html">CKEditor Samples</a> &raquo; Producing XHTML Compliant Output\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/basicstyles.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to output valid\r
+                       <a class="samples" href="http://www.w3.org/TR/xhtml11/">XHTML 1.1</a> code.\r
+                       Deprecated elements (<code>&lt;font&gt;</code>, <code>&lt;u&gt;</code>) or attributes\r
+                       (<code>size</code>, <code>face</code>) will be replaced with XHTML compliant code.\r
+               </p>\r
+               <p>\r
+                       To add a CKEditor instance outputting valid XHTML code, load the editor using a standard\r
+                       JavaScript call and define CKEditor features to use the XHTML compliant elements and styles.\r
+               </p>\r
+               <p>\r
+                       A snippet of the configuration code can be seen below; check the source of this page for\r
+                       full definition:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       contentsCss: 'assets/outputxhtml.css',\r
+\r
+       coreStyles_bold: {\r
+               element: 'span',\r
+               attributes: { 'class': 'Bold' }\r
+       },\r
+       coreStyles_italic: {\r
+               element: 'span',\r
+               attributes: { 'class': 'Italic' }\r
+       },\r
+\r
+       ...\r
+});</pre>\r
+       </div>\r
+       <form action="sample_posteddata.php" method="post">\r
+               <p>\r
+                       <label for="editor1">\r
+                               Editor 1:\r
+                       </label>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;span class="Bold"&gt;sample text&lt;/span&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+                       <script>\r
+\r
+                               CKEDITOR.replace( 'editor1', {\r
+                                       /*\r
+                                        * Style sheet for the contents\r
+                                        */\r
+                                       contentsCss: 'assets/outputxhtml/outputxhtml.css',\r
+\r
+                                       /*\r
+                                        * Special allowed content rules for spans used by\r
+                                        * font face, size, and color buttons.\r
+                                        *\r
+                                        * Note: all rules have been written separately so\r
+                                        * it was possible to specify required classes.\r
+                                        */\r
+                                       extraAllowedContent: 'span(!FontColor1);span(!FontColor2);span(!FontColor3);' +\r
+                                               'span(!FontColor1BG);span(!FontColor2BG);span(!FontColor3BG);' +\r
+                                               'span(!FontComic);span(!FontCourier);span(!FontTimes);' +\r
+                                               'span(!FontSmaller);span(!FontLarger);span(!FontSmall);span(!FontBig);span(!FontDouble)',\r
+\r
+                                       /*\r
+                                        * Core styles.\r
+                                        */\r
+                                       coreStyles_bold: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'Bold' }\r
+                                       },\r
+                                       coreStyles_italic: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'Italic' }\r
+                                       },\r
+                                       coreStyles_underline: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'Underline' }\r
+                                       },\r
+                                       coreStyles_strike: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'StrikeThrough' },\r
+                                               overrides: 'strike'\r
+                                       },\r
+                                       coreStyles_subscript: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'Subscript' },\r
+                                               overrides: 'sub'\r
+                                       },\r
+                                       coreStyles_superscript: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': 'Superscript' },\r
+                                               overrides: 'sup'\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font face.\r
+                                        */\r
+\r
+                                       // List of fonts available in the toolbar combo. Each font definition is\r
+                                       // separated by a semi-colon (;). We are using class names here, so each font\r
+                                       // is defined by {Combo Label}/{Class Name}.\r
+                                       font_names: 'Comic Sans MS/FontComic;Courier New/FontCourier;Times New Roman/FontTimes',\r
+\r
+                                       // Define the way font elements will be applied to the document. The "span"\r
+                                       // element will be used. When a font is selected, the font name defined in the\r
+                                       // above list is passed to this definition with the name "Font", being it\r
+                                       // injected in the "class" attribute.\r
+                                       // We must also instruct the editor to replace span elements that are used to\r
+                                       // set the font (Overrides).\r
+                                       font_style: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': '#(family)' },\r
+                                               overrides: [\r
+                                                       {\r
+                                                               element: 'span',\r
+                                                               attributes: {\r
+                                                                       'class': /^Font(?:Comic|Courier|Times)$/\r
+                                                               }\r
+                                                       }\r
+                                               ]\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font sizes.\r
+                                        */\r
+                                       fontSize_sizes: 'Smaller/FontSmaller;Larger/FontLarger;8pt/FontSmall;14pt/FontBig;Double Size/FontDouble',\r
+                                       fontSize_style: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': '#(size)' },\r
+                                               overrides: [\r
+                                                       {\r
+                                                               element: 'span',\r
+                                                               attributes: {\r
+                                                                       'class': /^Font(?:Smaller|Larger|Small|Big|Double)$/\r
+                                                               }\r
+                                                       }\r
+                                               ]\r
+                                       } ,\r
+\r
+                                       /*\r
+                                        * Font colors.\r
+                                        */\r
+                                       colorButton_enableMore: false,\r
+\r
+                                       colorButton_colors: 'FontColor1/FF9900,FontColor2/0066CC,FontColor3/F00',\r
+                                       colorButton_foreStyle: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': '#(color)' },\r
+                                               overrides: [\r
+                                                       {\r
+                                                               element: 'span',\r
+                                                               attributes: {\r
+                                                                       'class': /^FontColor(?:1|2|3)$/\r
+                                                               }\r
+                                                       }\r
+                                               ]\r
+                                       },\r
+\r
+                                       colorButton_backStyle: {\r
+                                               element: 'span',\r
+                                               attributes: { 'class': '#(color)BG' },\r
+                                               overrides: [\r
+                                                       {\r
+                                                               element: 'span',\r
+                                                               attributes: {\r
+                                                                       'class': /^FontColor(?:1|2|3)BG$/\r
+                                                               }\r
+                                                       }\r
+                                               ]\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Indentation.\r
+                                        */\r
+                                       indentClasses: [ 'Indent1', 'Indent2', 'Indent3' ],\r
+\r
+                                       /*\r
+                                        * Paragraph justification.\r
+                                        */\r
+                                       justifyClasses: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyFull' ],\r
+\r
+                                       /*\r
+                                        * Styles combo.\r
+                                        */\r
+                                       stylesSet: [\r
+                                               { name: 'Strong Emphasis', element: 'strong' },\r
+                                               { name: 'Emphasis', element: 'em' },\r
+\r
+                                               { name: 'Computer Code', element: 'code' },\r
+                                               { name: 'Keyboard Phrase', element: 'kbd' },\r
+                                               { name: 'Sample Text', element: 'samp' },\r
+                                               { name: 'Variable', element: 'var' },\r
+\r
+                                               { name: 'Deleted Text', element: 'del' },\r
+                                               { name: 'Inserted Text', element: 'ins' },\r
+\r
+                                               { name: 'Cited Work', element: 'cite' },\r
+                                               { name: 'Inline Quotation', element: 'q' }\r
+                                       ]\r
+                               });\r
+\r
+                       </script>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/release/samples/toolbarconfigurator/css/fontello.css b/release/samples/toolbarconfigurator/css/fontello.css
new file mode 100644 (file)
index 0000000..d983707
--- /dev/null
@@ -0,0 +1,55 @@
+@font-face {\r
+  font-family: 'fontello';\r
+  src: url('../font/fontello.eot?89024372');\r
+  src: url('../font/fontello.eot?89024372#iefix') format('embedded-opentype'),\r
+       url('../font/fontello.woff?89024372') format('woff'),\r
+       url('../font/fontello.ttf?89024372') format('truetype'),\r
+       url('../font/fontello.svg?89024372#fontello') format('svg');\r
+  font-weight: normal;\r
+  font-style: normal;\r
+}\r
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */\r
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */\r
+/*\r
+@media screen and (-webkit-min-device-pixel-ratio:0) {\r
+  @font-face {\r
+    font-family: 'fontello';\r
+    src: url('../font/fontello.svg?89024372#fontello') format('svg');\r
+  }\r
+}\r
+*/\r
+\r
+ [class^="icon-"]:before, [class*=" icon-"]:before {\r
+  font-family: "fontello";\r
+  font-style: normal;\r
+  font-weight: normal;\r
+  speak: none;\r
+\r
+  display: inline-block;\r
+  text-decoration: inherit;\r
+  width: 1em;\r
+  margin-right: .2em;\r
+  text-align: center;\r
+  /* opacity: .8; */\r
+\r
+  /* For safety - reset parent styles, that can break glyph codes*/\r
+  font-variant: normal;\r
+  text-transform: none;\r
+\r
+  /* fix buttons height, for twitter bootstrap */\r
+  line-height: 1em;\r
+\r
+  /* Animation center compensation - margins should be symmetric */\r
+  /* remove if not needed */\r
+  margin-left: .2em;\r
+\r
+  /* you can be more comfortable with increased icons size */\r
+  /* font-size: 120%; */\r
+\r
+  /* Uncomment for 3D effect */\r
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */\r
+}\r
+\r
+.icon-trash:before { content: '\e802'; } /* '' */\r
+.icon-down-big:before { content: '\e800'; } /* '' */\r
+.icon-up-big:before { content: '\e801'; } /* '' */\r
diff --git a/release/samples/toolbarconfigurator/font/LICENSE.txt b/release/samples/toolbarconfigurator/font/LICENSE.txt
new file mode 100644 (file)
index 0000000..4a73f6c
--- /dev/null
@@ -0,0 +1,10 @@
+Font license info\r
+\r
+\r
+## Font Awesome\r
+\r
+   Copyright (C) 2012 by Dave Gandy\r
+\r
+   Author:    Dave Gandy\r
+   License:   SIL ()\r
+   Homepage:  http://fortawesome.github.com/Font-Awesome/\r
diff --git a/release/samples/toolbarconfigurator/font/config.json b/release/samples/toolbarconfigurator/font/config.json
new file mode 100644 (file)
index 0000000..94809d7
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "name": "",
+  "css_prefix_text": "icon-",
+  "css_use_suffix": false,
+  "hinting": true,
+  "units_per_em": 1000,
+  "ascent": 850,
+  "glyphs": [
+    {
+      "uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
+      "css": "trash-empty",
+      "code": 59392,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "1c4068ed75209e21af36017df8871802",
+      "css": "down-big",
+      "code": 59393,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "95376bf082bfec6ce06ea1cda7bd7ead",
+      "css": "up-big",
+      "code": 59394,
+      "src": "fontawesome"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/font/fontello.eot b/release/samples/toolbarconfigurator/font/fontello.eot
new file mode 100644 (file)
index 0000000..2732fad
Binary files /dev/null and b/release/samples/toolbarconfigurator/font/fontello.eot differ
diff --git a/release/samples/toolbarconfigurator/font/fontello.svg b/release/samples/toolbarconfigurator/font/fontello.svg
new file mode 100644 (file)
index 0000000..33d14ac
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
+<defs>
+<font id="fontello" horiz-adv-x="1000" >
+<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="trash" unicode="&#xe802;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15t6-5h464q2 0 6 5t8 15t4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
+<glyph glyph-name="down-big" unicode="&#xe800;" d="m899 386q0-30-21-50l-363-364q-22-21-51-21q-29 0-50 21l-363 364q-21 20-21 50q0 29 21 51l41 41q22 21 51 21q29 0 50-21l164-164v393q0 29 21 50t51 22h71q29 0 50-22t21-50v-393l164 164q21 21 51 21q29 0 50-21l42-42q21-21 21-50z" horiz-adv-x="928.6" />
+<glyph glyph-name="up-big" unicode="&#xe801;" d="m899 308q0-28-21-50l-42-42q-21-21-50-21q-30 0-51 21l-164 164v-393q0-29-20-47t-51-19h-71q-30 0-51 19t-21 47v393l-164-164q-20-21-50-21t-50 21l-42 42q-21 21-21 50q0 30 21 51l363 363q20 21 50 21q30 0 51-21l363-363q21-22 21-51z" horiz-adv-x="928.6" />
+</font>
+</defs>
+</svg>
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/font/fontello.ttf b/release/samples/toolbarconfigurator/font/fontello.ttf
new file mode 100644 (file)
index 0000000..fbcbf06
Binary files /dev/null and b/release/samples/toolbarconfigurator/font/fontello.ttf differ
diff --git a/release/samples/toolbarconfigurator/font/fontello.woff b/release/samples/toolbarconfigurator/font/fontello.woff
new file mode 100644 (file)
index 0000000..e1d5647
Binary files /dev/null and b/release/samples/toolbarconfigurator/font/fontello.woff differ
diff --git a/release/samples/toolbarconfigurator/index.html b/release/samples/toolbarconfigurator/index.html
new file mode 100644 (file)
index 0000000..1dac0b4
--- /dev/null
@@ -0,0 +1,446 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<!--[if IE 8]><html class="ie8"><![endif]-->\r
+<!--[if gt IE 8]><html><![endif]-->\r
+<!--[if !IE]><!--><html><!--<![endif]-->\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Toolbar Configurator</title>\r
+       <script src="../../ckeditor.js"></script>\r
+       <script>\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+                       CKEDITOR.tools.enableHtml5Elements( document );\r
+       </script>\r
+       <link rel="stylesheet" href="lib/codemirror/codemirror.css">\r
+       <link rel="stylesheet" href="lib/codemirror/show-hint.css">\r
+       <link rel="stylesheet" href="lib/codemirror/neo.css">\r
+       <link rel="stylesheet" href="css/fontello.css">\r
+       <link rel="stylesheet" href="../css/samples.css">\r
+</head>\r
+<body id="toolbar">\r
+\r
+<nav class="navigation-a">\r
+       <div class="grid-container">\r
+               <ul class="navigation-a-left grid-width-70">\r
+                       <li><a href="http://ckeditor.com">Project Homepage</a></li>\r
+                       <li><a href="http://dev.ckeditor.com/">I found a bug</a></li>\r
+                       <li><a href="http://github.com/ckeditor/ckeditor-dev" class="icon-pos-right icon-navigation-a-github">Fork CKEditor on GitHub</a></li>\r
+               </ul>\r
+               <ul class="navigation-a-right grid-width-30">\r
+                       <li><a href="http://ckeditor.com/blog-list">CKEditor Blog</a></li>\r
+               </ul>\r
+       </div>\r
+</nav>\r
+\r
+<header class="header-a">\r
+       <div class="grid-container">\r
+               <h1 class="header-a-logo grid-width-30">\r
+                       <a href="../index.html"><img src="../img/logo.png" alt="CKEditor Logo"></a>\r
+               </h1>\r
+               <nav class="navigation-b grid-width-70">\r
+                       <ul>\r
+                               <li><a href="../index.html"  class="button-a">Start</a></li>\r
+                               <li><a href="index.html"  class="button-a button-a-background">Toolbar configurator</a></li>\r
+                       </ul>\r
+               </nav>\r
+       </div>\r
+</header>\r
+\r
+<main>\r
+       <div class="adjoined-top">\r
+               <div class="grid-container">\r
+                       <div class="content grid-width-100">\r
+                               <div class="grid-container-nested">\r
+                                       <h1 class="grid-width-60">\r
+                                               Toolbar Configurator\r
+                                               <a href="#help-content" type="button" title="Configurator help" id="help" class="button-a button-a-background button-a-no-text icon-pos-left icon-question-mark">Help</a>\r
+                                       </h1>\r
+\r
+                                       <div class="grid-width-40 grid-switch-magic">\r
+                                               <div class="switch">\r
+                                                       <span class="balloon-a balloon-a-se">Select configurator type</span>\r
+                                                       <input type="radio" name="radio" data-num="1" id="radio-basic" />\r
+                                                       <input type="radio" name="radio" data-num="2" id="radio-advanced" />\r
+                                                       <label data-for="1" for="radio-basic">Basic</label>\r
+                                                       <span class="switch-inner">\r
+                                                               <span class="handler"></span>\r
+                                                       </span>\r
+                                                       <label data-for="2" for="radio-advanced">Advanced</label>\r
+                                               </div>\r
+                                       </div>\r
+                               </div>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+       <div class="adjoined-bottom">\r
+               <div class="grid-container">\r
+                       <div class="grid-width-100">\r
+                               <div class="editors-container">\r
+                                       <div id="editor-basic"></div>\r
+                                       <div id="editor-advanced"></div>\r
+                               </div>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+\r
+       <div class="grid-container configurator">\r
+               <div class="content grid-width-100">\r
+                       <div class="configurator">\r
+                               <div>\r
+                                       <div id="toolbarModifierWrapper"></div>\r
+                               </div>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+\r
+       <div id="help-content">\r
+               <div class="grid-container">\r
+                       <div class="grid-width-100">\r
+                               <h2>What Am I Doing Here?</h2>\r
+\r
+                               <div class="grid-container grid-container-nested">\r
+                                       <div class="basic">\r
+                                               <div class="grid-width-50">\r
+                                                       <p>Arrange <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbarGroups">toolbar groups</a>, toggle <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons">button visibility</a> according to your needs and get your toolbar configuration.</p>\r
+                                                       <p>You can replace the content of the <a href="../../config.js"><code>config.js</code></a> file with the generated configuration. If you already set some configuration options you will need to merge both configurations.</p>\r
+                                               </div>\r
+                                               <div class="grid-width-50">\r
+                                                       <p>Read more about different ways of <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">setting configuration</a> and do not forget about <strong>clearing browser cache</strong>.</p>\r
+                                                       <p>Arranging toolbar groups is the recommended way of configuring the toolbar, but if you need more freedom you can use the <a href="#advanced">advanced configurator</a>.</p>\r
+                                               </div>\r
+                                       </div>\r
+                                       <div class="advanced" style="display: none;">\r
+                                               <div class="grid-width-50">\r
+                                                       <p>With this code editor you can edit your <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbar">toolbar configuration</a> live.</p>\r
+                                                       <p>You can replace the content of the <a href="../../config.js"><code>config.js</code></a> file with the generated configuration. If you already set some configuration options you will need to merge both configurations.</p>\r
+                                               </div>\r
+                                               <div class="grid-width-50">\r
+                                                       <p>Read more about different ways of <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">setting configuration</a> and do not forget about <strong>clearing browser cache</strong>.</p>\r
+                                               </div>\r
+                                       </div>\r
+                               </div>\r
+\r
+                               <p class="grid-container grid-container-nested">\r
+                                       <button type="button" class="help-content-close grid-width-100 button-a button-a-background">Got it. Let's play!</button>\r
+                               </p>\r
+                       </div>\r
+               </div>\r
+       </div>\r
+</main>\r
+\r
+<footer class="footer-a grid-container">\r
+       <p class="grid-width-100">\r
+               CKEditor &ndash; The text editor for the Internet &ndash; <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+       </p>\r
+       <p class="grid-width-100" id="copy">\r
+               Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> &ndash; Frederico Knabben. All rights reserved.\r
+       </p>\r
+</footer>\r
+\r
+<script src="lib/codemirror/codemirror.js"></script>\r
+<script src="lib/codemirror/javascript.js"></script>\r
+<script src="lib/codemirror/show-hint.js"></script>\r
+\r
+<script src="js/fulltoolbareditor.js"></script>\r
+<script src="js/abstracttoolbarmodifier.js"></script>\r
+<script src="js/toolbarmodifier.js"></script>\r
+<script src="js/toolbartextmodifier.js"></script>\r
+<script src="../js/sf.js"></script>\r
+\r
+<script>\r
+       ( function() {\r
+               'use strict';\r
+\r
+               var mode = ( window.location.hash.substr( 1 ) === 'advanced' ) ? 'advanced' : 'basic',\r
+                       configuratorSection = CKEDITOR.document.findOne( 'main > .grid-container.configurator' ),\r
+                       basicInstruction = CKEDITOR.document.findOne( '#help-content .basic' ),\r
+                       advancedInstruction = CKEDITOR.document.findOne( '#help-content .advanced' ),\r
+\r
+                       // Configurator mode switcher.\r
+                       modeSwitchBasic = CKEDITOR.document.getById( 'radio-basic' ),\r
+                       modeSwitchAdvanced = CKEDITOR.document.getById( 'radio-advanced' );\r
+\r
+               // Initial setup\r
+               function updateSwitcher() {\r
+                       if ( mode === 'advanced' ) {\r
+                               modeSwitchAdvanced.$.checked = true;\r
+                       } else {\r
+                               modeSwitchBasic.$.checked = true;\r
+                       }\r
+               }\r
+\r
+               updateSwitcher();\r
+\r
+               CKEDITOR.document.getWindow().on( 'hashchange', function( e ) {\r
+                       var hash = window.location.hash.substr( 1 );\r
+                       if ( !( hash === 'advanced' || hash === 'basic' ) ) {\r
+                               return;\r
+                       }\r
+                       mode = hash;\r
+                       onToolbarsDone( mode );\r
+               } );\r
+\r
+               CKEDITOR.document.getWindow().on( 'resize', function() {\r
+                       updateToolbar( ( mode === 'basic' ? toolbarModifier : toolbarTextModifier )[ 'editorInstance' ] );\r
+               } );\r
+\r
+               function onRefresh( modifier ) {\r
+                       modifier = modifier || this;\r
+\r
+                       if ( mode === 'basic' && modifier instanceof ToolbarConfigurator.ToolbarTextModifier ) {\r
+                               return;\r
+                       }\r
+\r
+                       // CodeMirror container becomes visible, so we need to refresh and to avoid rendering problems.\r
+                       if ( mode === 'advanced' && modifier instanceof ToolbarConfigurator.ToolbarTextModifier ) {\r
+                               modifier.codeContainer.refresh();\r
+                       }\r
+\r
+                       updateToolbar( modifier.editorInstance );\r
+               }\r
+\r
+               function updateToolbar( editor ) {\r
+                       var editorContainer = editor.container;\r
+\r
+                       // Not always editor is loaded.\r
+                       if ( !editorContainer ) {\r
+                               return;\r
+                       }\r
+\r
+                       var displayStyle = editorContainer.getStyle( 'display' );\r
+\r
+                       editorContainer.setStyle( 'display', 'block' );\r
+\r
+                       var newHeight = editorContainer.getSize( 'height' );\r
+\r
+                       var newMarginTop = parseInt( editorContainer.getComputedStyle( 'margin-top' ), 10 );\r
+                       newMarginTop = ( isNaN( newMarginTop ) ? 0 : Number( newMarginTop ) );\r
+\r
+                       var newMarginBottom = parseInt( editorContainer.getComputedStyle( 'margin-bottom' ), 10 );\r
+                       newMarginBottom = ( isNaN( newMarginBottom ) ? 0 : Number( newMarginBottom ) );\r
+\r
+                       var result = newHeight + newMarginTop + newMarginBottom;\r
+\r
+                       editorContainer.setStyle( 'display', displayStyle );\r
+\r
+                       editor.container.getAscendant( 'div' ).setStyle( 'height', result + 'px' );\r
+               }\r
+\r
+               var toolbarModifier = new ToolbarConfigurator.ToolbarModifier( 'editor-basic' );\r
+\r
+               var done = 0;\r
+               toolbarModifier.init( onToolbarInit );\r
+               toolbarModifier.onRefresh = onRefresh;\r
+\r
+               CKEDITOR.document.getById( 'toolbarModifierWrapper' ).append( toolbarModifier.mainContainer );\r
+\r
+               var toolbarTextModifier = new ToolbarConfigurator.ToolbarTextModifier( 'editor-advanced' );\r
+               toolbarTextModifier.init( onToolbarInit );\r
+               toolbarTextModifier.onRefresh = onRefresh;\r
+\r
+               function onToolbarInit() {\r
+                       if ( ++done === 2 ) {\r
+                               onToolbarsDone();\r
+\r
+                               positionSticky.watch( CKEDITOR.document.findOne( '.toolbar' ), function() {\r
+                                       return mode === 'advanced';\r
+                               } );\r
+                       }\r
+               }\r
+\r
+               function onToolbarsDone() {\r
+                       if ( mode === 'basic' ) {\r
+                               toggleModeBasic( false );\r
+                       } else {\r
+                               toggleModeAdvanced( false );\r
+                       }\r
+\r
+                       updateSwitcher();\r
+\r
+                       setTimeout( function() {\r
+                               CKEDITOR.document.findOne( '.editors-container' ).addClass( 'active' );\r
+                               CKEDITOR.document.findOne( '#toolbarModifierWrapper' ).addClass( 'active' );\r
+                       }, 200 );\r
+               }\r
+\r
+               CKEDITOR.document.getById( 'toolbarModifierWrapper' ).append( toolbarTextModifier.mainContainer );\r
+\r
+               function toogleModeSwitch( onElement, offElement, onModifier, offModifier ) {\r
+                       onElement.addClass( 'fancy-button-active' );\r
+                       offElement.removeClass( 'fancy-button-active' );\r
+\r
+                       onModifier.showUI();\r
+                       offModifier.hideUI();\r
+               }\r
+\r
+               function toggleModeBasic( callOnRefresh ) {\r
+                       callOnRefresh = ( callOnRefresh !== false );\r
+                       mode = 'basic';\r
+                       window.location.hash = '#basic';\r
+                       toogleModeSwitch( modeSwitchBasic, modeSwitchAdvanced, toolbarModifier, toolbarTextModifier );\r
+\r
+                       configuratorSection.removeClass( 'freed-width' );\r
+                       basicInstruction.show();\r
+                       advancedInstruction.hide();\r
+\r
+                       callOnRefresh && onRefresh( toolbarModifier );\r
+               }\r
+\r
+               function toggleModeAdvanced( callOnRefresh ) {\r
+                       callOnRefresh = ( callOnRefresh !== false );\r
+                       mode = 'advanced';\r
+                       window.location.hash = '#advanced';\r
+                       toogleModeSwitch( modeSwitchAdvanced, modeSwitchBasic, toolbarTextModifier, toolbarModifier );\r
+\r
+                       configuratorSection.addClass( 'freed-width' );\r
+                       advancedInstruction.show();\r
+                       basicInstruction.hide();\r
+\r
+                       callOnRefresh && onRefresh( toolbarTextModifier );\r
+               }\r
+\r
+               modeSwitchBasic.on( 'click', toggleModeBasic );\r
+               modeSwitchAdvanced.on( 'click', toggleModeAdvanced );\r
+\r
+               //\r
+               // Position:sticky for the toolbar.\r
+               //\r
+\r
+               // Will make elements behave like they were styled with position:sticky.\r
+               var positionSticky = {\r
+                       // Store object: {\r
+                       //              element: CKEDITOR.dom.element, // Element which will float.\r
+                       //              placeholder: CKEDITOR.dom.element, // Placeholder which is place to prevent page bounce.\r
+                       //              isFixed: boolean // Whether element float now.\r
+                       // }\r
+                       watched: [],\r
+\r
+                       active: [],\r
+\r
+                       staticContainer: null,\r
+\r
+                       init: function() {\r
+                               var element = CKEDITOR.dom.element.createFromHtml(\r
+                                       '<div class="staticContainer">' +\r
+                                               '<div class="grid-container" >' +\r
+                                                       '<div class="grid-width-100">' +\r
+                                                               '<div class="inner"></div>' +\r
+                                                       '</div>' +\r
+                                               '</div>' +\r
+                                       '</div>' );\r
+\r
+                               this.staticContainer = element.findOne( '.inner' );\r
+\r
+                               CKEDITOR.document.getBody().append( element );\r
+                       },\r
+\r
+                       watch: function( element, preventFunc ) {\r
+                               this.watched.push( {\r
+                                       element: element,\r
+                                       placeholder: new CKEDITOR.dom.element( 'div' ),\r
+                                       isFixed: false,\r
+                                       preventFunc: preventFunc\r
+                               } );\r
+                       },\r
+\r
+                       checkAll: function() {\r
+                               for ( var i = 0; i < this.watched.length; i++ ) {\r
+                                       this.check( this.watched[ i ] );\r
+                               }\r
+                       },\r
+\r
+                       check: function( element ) {\r
+                               var isFixed = element.isFixed;\r
+                               var shouldBeFixed = this.shouldBeFixed( element );\r
+\r
+                               // Nothing to be done.\r
+                               if ( isFixed === shouldBeFixed ) {\r
+                                       return;\r
+                               }\r
+\r
+                               var placeholder = element.placeholder;\r
+\r
+                               if ( isFixed ) {\r
+                                       // Unfixing.\r
+\r
+                                       element.element.insertBefore( placeholder );\r
+                                       placeholder.remove();\r
+\r
+                                       element.element.removeStyle( 'margin' );\r
+\r
+                                       this.active.splice( CKEDITOR.tools.indexOf( this.active, element ), 1 );\r
+\r
+                               } else {\r
+                                       // Fixing.\r
+                                       placeholder.setStyle( 'width', element.element.getSize( 'width' ) + 'px' );\r
+                                       placeholder.setStyle( 'height', element.element.getSize( 'height' ) + 'px' );\r
+                                       placeholder.setStyle( 'margin-bottom', element.element.getComputedStyle( 'margin-bottom' ) );\r
+                                       placeholder.setStyle( 'display', element.element.getComputedStyle( 'display' ) );\r
+                                       placeholder.insertAfter( element.element );\r
+\r
+                                       this.staticContainer.append( element.element );\r
+\r
+                                       this.active.push( element );\r
+                               }\r
+\r
+                               element.isFixed = !element.isFixed;\r
+                       },\r
+\r
+                       shouldBeFixed: function( element ) {\r
+                               if ( element.preventFunc && element.preventFunc() ) {\r
+                                       return false;\r
+                               }\r
+\r
+                               // If element is already fixed we are checking it's placeholder.\r
+                               var related = ( element.isFixed ? element.placeholder : element.element ),\r
+                                       clientRect = related.$.getBoundingClientRect(),\r
+                                       staticHeight = this.staticContainer.getSize('height' ),\r
+                                       elemHeight = element.element.getSize( 'height' );\r
+\r
+                               if ( element.isFixed ) {\r
+                                       return ( clientRect.top + elemHeight < staticHeight );\r
+                               } else {\r
+                                       return ( clientRect.top < staticHeight );\r
+                               }\r
+                       }\r
+               };\r
+\r
+               positionSticky.init();\r
+\r
+               CKEDITOR.document.getWindow().on( 'scroll',\r
+                       new CKEDITOR.tools.eventsBuffer( 100, positionSticky.checkAll, positionSticky ).input\r
+               );\r
+\r
+               // Make the toolbar sticky.\r
+               positionSticky.watch( CKEDITOR.document.findOne( '.editors-container' ) );\r
+\r
+               // Help button and help-content.\r
+               ( function() {\r
+                       var helpButton = CKEDITOR.document.getById( 'help' ),\r
+                               helpContent = CKEDITOR.document.getById( 'help-content' );\r
+\r
+                       // Don't show help button on IE8 because it's unsupported by Pico Modal.\r
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version == 8 ) {\r
+                               helpButton.hide();\r
+                       } else {\r
+                               // Display help modal when the button is clicked.\r
+                               helpButton.on( 'click', function( evt ) {\r
+                                       SF.modal( {\r
+                                               // Clone modal content from DOM.\r
+                                               content: helpContent.getHtml(),\r
+\r
+                                               afterCreate: function( modal ) {\r
+                                                       // Enable modal content button to close the modal.\r
+                                                       new CKEDITOR.dom.element( modal.modalElem() ).findOne( '.help-content-close' ).once( 'click', modal.close );\r
+                                               }\r
+                                       } ).show();\r
+                               } );\r
+                       }\r
+               } )();\r
+       } )();\r
+</script>\r
+</body>\r
+</html>\r
diff --git a/release/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js b/release/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js
new file mode 100644 (file)
index 0000000..65f0b87
--- /dev/null
@@ -0,0 +1,13 @@
+"function"!=typeof Object.create&&function(){var a=function(){};Object.create=function(b){if(1<arguments.length)throw Error("Second argument not supported");if(null===b)throw Error("Cannot set a null [[Prototype]]");if("object"!=typeof b)throw TypeError("Argument must be an object");a.prototype=b;return new a}}();
+CKEDITOR.plugins.add("toolbarconfiguratorarea",{afterInit:function(a){a.addMode("wysiwyg",function(b){var c=CKEDITOR.dom.element.createFromHtml('\x3cdiv class\x3d"cke_wysiwyg_div cke_reset" hidefocus\x3d"true"\x3e\x3c/div\x3e');a.ui.space("contents").append(c);c=a.editable(c);c.detach=CKEDITOR.tools.override(c.detach,function(b){return function(){b.apply(this,arguments);this.remove()}});a.setData(a.getData(1),b);a.fire("contentDom")});a.dataProcessor.toHtml=function(b){return b};a.dataProcessor.toDataFormat=
+function(b){return b}}});Object.keys||(Object.keys=function(){var a=Object.prototype.hasOwnProperty,b=!{toString:null}.propertyIsEnumerable("toString"),c="toString toLocaleString valueOf hasOwnProperty isPrototypeOf propertyIsEnumerable constructor".split(" "),e=c.length;return function(d){if("object"!==typeof d&&("function"!==typeof d||null===d))throw new TypeError("Object.keys called on non-object");var g=[],f;for(f in d)a.call(d,f)&&g.push(f);if(b)for(f=0;f<e;f++)a.call(d,c[f])&&g.push(c[f]);return g}}());
+(function(){function a(b,c){this.cfg=c||{};this.hidden=!1;this.editorId=b;this.fullToolbarEditor=new ToolbarConfigurator.FullToolbarEditor;this.actualConfig=this.originalConfig=this.mainContainer=null;this.isEditableVisible=this.waitForReady=!1;this.toolbarContainer=null;this.toolbarButtons=[]}ToolbarConfigurator.AbstractToolbarModifier=a;a.prototype.setConfig=function(b){this._onInit(void 0,b,!0)};a.prototype.init=function(b){var c=this;this.mainContainer=new CKEDITOR.dom.element("div");if(null!==
+this.fullToolbarEditor.editorInstance)throw"Only one instance of ToolbarModifier is allowed";this.editorInstance||this._createEditor(!1);this.editorInstance.once("loaded",function(){c.fullToolbarEditor.init(function(){c._onInit(b);if("function"==typeof c.onRefresh)c.onRefresh()},c.editorInstance.config)});return this.mainContainer};a.prototype._onInit=function(b,c){this.originalConfig=this.editorInstance.config;this.actualConfig=c?JSON.parse(c):JSON.parse(JSON.stringify(this.originalConfig));if(!this.actualConfig.toolbarGroups&&
+!this.actualConfig.toolbar){for(var a=this.actualConfig,d=this.editorInstance.toolbar,g=[],f=d.length,k=0;k<f;k++){var h=d[k];"string"==typeof h?g.push(h):g.push({name:h.name,groups:h.groups?h.groups.slice():[]})}a.toolbarGroups=g}"function"===typeof b&&b(this.mainContainer)};a.prototype._createModifier=function(){this.mainContainer.addClass("unselectable");this.modifyContainer&&this.modifyContainer.remove();this.modifyContainer=new CKEDITOR.dom.element("div");this.modifyContainer.addClass("toolbarModifier");
+this.mainContainer.append(this.modifyContainer);return this.mainContainer};a.prototype.getEditableArea=function(){return this.editorInstance.container.findOne("#"+this.editorInstance.id+"_contents")};a.prototype._hideEditable=function(){var b=this.getEditableArea();this.isEditableVisible=!1;this.lastEditableAreaHeight=b.getStyle("height");b.setStyle("height","0")};a.prototype._showEditable=function(){this.isEditableVisible=!0;this.getEditableArea().setStyle("height",this.lastEditableAreaHeight||"auto")};
+a.prototype._toggleEditable=function(){this.isEditableVisible?this._hideEditable():this._showEditable()};a.prototype._refreshEditor=function(){function b(){c.editorInstance.destroy();c._createEditor(!0,c.getActualConfig());c.waitForReady=!1}var c=this,a=this.editorInstance.status;this.waitForReady||("unloaded"==a||"loaded"==a?(this.waitForReady=!0,this.editorInstance.once("instanceReady",function(){b()},this)):b())};a.prototype._createEditor=function(b,c){function e(){}var d=this;this.editorInstance=
+CKEDITOR.replace(this.editorId);this.editorInstance.on("configLoaded",function(){var b=d.editorInstance.config;c&&CKEDITOR.tools.extend(b,c,!0);a.extendPluginsConfig(b)});this.editorInstance.on("uiSpace",function(b){"top"!=b.data.space&&b.stop()},null,null,-999);this.editorInstance.once("loaded",function(){var c=d.editorInstance.ui.instances,a;for(a in c)c[a]&&(c[a].click=e,c[a].onClick=e);d.isEditableVisible||d._hideEditable();d.currentActive&&d.currentActive.name&&d._highlightGroup(d.currentActive.name);
+d.hidden?d.hideUI():d.showUI();if(b&&"function"===typeof d.onRefresh)d.onRefresh()})};a.prototype.getActualConfig=function(){return JSON.parse(JSON.stringify(this.actualConfig))};a.prototype._createToolbar=function(){if(this.toolbarButtons.length){this.toolbarContainer=new CKEDITOR.dom.element("div");this.toolbarContainer.addClass("toolbar");for(var b=this.toolbarButtons.length,c=0;c<b;c+=1)this._createToolbarBtn(this.toolbarButtons[c])}};a.prototype._createToolbarBtn=function(b){var c=ToolbarConfigurator.FullToolbarEditor.createButton("string"===
+typeof b.text?b.text:b.text.inactive,b.cssClass);this.toolbarContainer.append(c);c.data("group",b.group);c.addClass(b.position);c.on("click",function(){b.clickCallback.call(this,c,b)},this);return c};a.prototype._fixGroups=function(b){b=b.toolbarGroups||[];for(var c=b.length,a=0;a<c;a+=1){var d=b[a];"/"==d?(d=b[a]={},d.type="separator",d.name="separator"+CKEDITOR.tools.getNextNumber()):(d.groups=d.groups||[],-1==CKEDITOR.tools.indexOf(d.groups,d.name)&&(this.editorInstance.ui.addToolbarGroup(d.name,
+d.groups[d.groups.length-1],d.name),d.groups.push(d.name)),this._fixSubgroups(d))}};a.prototype._fixSubgroups=function(b){b=b.groups;for(var c=b.length,a=0;a<c;a+=1){var d=b[a];b[a]={name:d,totalBtns:ToolbarConfigurator.ToolbarModifier.getTotalSubGroupButtonsNumber(d,this.fullToolbarEditor)}}};a.stringifyJSONintoOneLine=function(b,a){a=a||{};var e=JSON.stringify(b,null,""),e=e.replace(/\n/g,"");a.addSpaces&&(e=e.replace(/(\{|:|,|\[|\])/g,function(a){return a+" "}),e=e.replace(/(\])/g,function(a){return" "+
+a}));a.noQuotesOnKey&&(e=e.replace(/"(\w*)":/g,function(a,b){return b+":"}));a.singleQuotes&&(e=e.replace(/\"/g,"'"));return e};a.prototype.hideUI=function(){this.hidden=!0;this.mainContainer.hide();this.editorInstance.container&&this.editorInstance.container.hide()};a.prototype.showUI=function(){this.hidden=!1;this.mainContainer.show();this.editorInstance.container&&this.editorInstance.container.show()};a.extendPluginsConfig=function(a){var c=a.extraPlugins;a.extraPlugins=(c?c+",":"")+"toolbarconfiguratorarea"}})();
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/js/fulltoolbareditor.js b/release/samples/toolbarconfigurator/js/fulltoolbareditor.js
new file mode 100644 (file)
index 0000000..dc19bee
--- /dev/null
@@ -0,0 +1,9 @@
+window.ToolbarConfigurator={};
+(function(){function e(){this.instanceid="fte"+CKEDITOR.tools.getNextId();this.textarea=new CKEDITOR.dom.element("textarea");this.textarea.setAttributes({id:this.instanceid,name:this.instanceid,contentEditable:!0});this.editorInstance=this.buttons=null}ToolbarConfigurator.FullToolbarEditor=e;e.prototype.init=function(b){var a=this;document.body.appendChild(this.textarea.$);CKEDITOR.replace(this.instanceid);this.editorInstance=CKEDITOR.instances[this.instanceid];this.editorInstance.once("configLoaded",function(d){var c=
+d.editor.config;delete c.removeButtons;delete c.toolbarGroups;delete c.toolbar;ToolbarConfigurator.AbstractToolbarModifier.extendPluginsConfig(c);d.editor.once("loaded",function(){a.buttons=e.toolbarToButtons(a.editorInstance.toolbar);a.buttonsByGroup=e.groupButtons(a.buttons);a.buttonNamesByGroup=a.groupButtonNamesByGroup(a.buttons);d.editor.container.hide();"function"===typeof b&&b(a.buttons)})})};e.prototype.groupButtonNamesByGroup=function(b){var a=this;b=e.groupButtons(b);for(var d in b)b[d]=
+e.map(b[d],function(b){return a.getCamelCasedButtonName(b.name)});return b};e.prototype.getGroupByName=function(b){for(var a=this.editorInstance.config.toolbarGroups||this.getFullToolbarGroupsConfig(),d=a.length,c=0;c<d;c+=1)if(a[c].name===b)return a[c];return null};e.prototype.getCamelCasedButtonName=function(b){var a=this.editorInstance.ui.items,d;for(d in a)if(a[d].name==b)return d;return null};e.prototype.getFullToolbarGroupsConfig=function(b){b=!0===b?!0:!1;for(var a=[],d=this.editorInstance.toolbar,
+c=d.length,f=0;f<c;f+=1){var e=d[f],g={};"string"!=typeof e.name?b&&a.push("/"):(g.name=e.name,e.groups&&(g.groups=Array.prototype.slice.call(e.groups)),a.push(g))}return a};e.filter=function(b,a){for(var d=b&&b.length?b.length:0,c=[],f=0;f<d;f+=1)a(b[f])&&c.push(b[f]);return c};e.map=function(b,a){var d;if(CKEDITOR.tools.isArray(b)){d=[];for(var c=b.length,f=0;f<c;f+=1)d.push(a(b[f]))}else for(c in d={},b)d[c]=a(b[c]);return d};e.groupButtons=function(b){for(var a={},d=b.length,c=0;c<d;c+=1){var f=
+b[c],e=f.toolbar.split(",")[0];a[e]=a[e]||[];a[e].push(f)}return a};e.toolbarToButtons=function(b){for(var a=[],d=b.length,c=0;c<d;c+=1)"object"==typeof b[c]&&(a=a.concat(e.groupToButtons(b[c])));return a};e.createToolbarButton=function(b){var a=new CKEDITOR.dom.element("a"),d=e.createIcon(b.name,b.icon,b.command);a.setStyle("float","none");a.addClass("cke_"+("rtl"==CKEDITOR.lang.dir?"rtl":"ltr"));if(b instanceof CKEDITOR.ui.button)a.addClass("cke_button"),a.addClass("cke_toolgroup"),a.append(d);
+else if(CKEDITOR.ui.richCombo&&b instanceof CKEDITOR.ui.richCombo){var d=new CKEDITOR.dom.element("span"),c=new CKEDITOR.dom.element("span"),f=new CKEDITOR.dom.element("span");a.addClass("cke_combo_button");d.addClass("cke_combo_text");d.addClass("cke_combo_inlinelabel");d.setText(b.label);c.addClass("cke_combo_open");f.addClass("cke_combo_arrow");c.append(f);a.append(d);a.append(c)}return a};e.createIcon=function(b,a,d){var c=CKEDITOR.skin.getIconStyle(b,"rtl"==CKEDITOR.lang.dir),c=(c=c||CKEDITOR.skin.getIconStyle(a,
+"rtl"==CKEDITOR.lang.dir))||CKEDITOR.skin.getIconStyle(d,"rtl"==CKEDITOR.lang.dir);a=new CKEDITOR.dom.element("span");a.addClass("cke_button_icon");a.addClass("cke_button__"+b+"_icon");a.setAttribute("style",c);a.setStyle("float","none");return a};e.createButton=function(b,a){var d=new CKEDITOR.dom.element("button");d.addClass("button-a");d.setAttribute("type","button");if("string"==typeof a){a=a.split(" ");for(var c=a.length;c--;)d.addClass(a[c])}d.setHtml(b);return d};e.groupToButtons=function(b){for(var a=
+[],d=(b=b.items)?b.length:0,c=0;c<d;c+=1){var f=b[c];if(f instanceof CKEDITOR.ui.button||CKEDITOR.ui.richCombo&&f instanceof CKEDITOR.ui.richCombo)f.$=e.createToolbarButton(f),a.push(f)}return a}})();
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/js/toolbarmodifier.js b/release/samples/toolbarconfigurator/js/toolbarmodifier.js
new file mode 100644 (file)
index 0000000..9731818
--- /dev/null
@@ -0,0 +1,33 @@
+(function(){function d(a,b){l.call(this,a,b);this.actualConfig=this.originalConfig=this.removedButtons=null;this.emptyVisible=!1;this.state="edit";this.toolbarButtons=[{text:{active:"Hide empty toolbar groups",inactive:"Show empty toolbar groups"},group:"edit",position:"left",cssClass:"button-a-soft",clickCallback:function(a,b){a[a.hasClass("button-a-background")?"removeClass":"addClass"]("button-a-background");this._toggleVisibilityEmptyElements();this.emptyVisible?a.setText(b.text.active):a.setText(b.text.inactive)}},
+{text:"Add row separator",group:"edit",position:"left",cssClass:"button-a-soft",clickCallback:function(){this._addSeparator()}},{text:"Select config",group:"config",position:"left",cssClass:"button-a-soft",clickCallback:function(){this.configContainer.findOne("textarea").$.select()}},{text:"Back to configurator",group:"config",position:"right",cssClass:"button-a-background",clickCallback:function(){if("paste"===this.state){var a=this.configContainer.findOne("textarea").getValue();(a=d.evaluateToolbarGroupsConfig(a))?
+this.setConfig(a):alert("Your pasted config is wrong.")}this.state="edit";this._showConfigurationTool();this.showToolbarBtnsByGroupName(this.state)}},{text:'Get toolbar \x3cspan class\x3d"highlight"\x3econfig\x3c/span\x3e',group:"edit",position:"right",cssClass:"button-a-background icon-pos-left icon-download",clickCallback:function(){this.state="config";this._showConfig();this.showToolbarBtnsByGroupName(this.state)}}];this.cachedActiveElement=null}var l=ToolbarConfigurator.AbstractToolbarModifier;
+ToolbarConfigurator.ToolbarModifier=d;d.prototype=Object.create(ToolbarConfigurator.AbstractToolbarModifier.prototype);d.prototype.getActualConfig=function(){var a=l.prototype.getActualConfig.call(this);if(a.toolbarGroups)for(var b=a.toolbarGroups.length,c=0;c<b;c+=1)a.toolbarGroups[c]=d.parseGroupToConfigValue(a.toolbarGroups[c]);return a};d.prototype._onInit=function(a,b,c){c=!0===c;l.prototype._onInit.call(this,void 0,b);this.removedButtons=[];c?this.removedButtons=this.actualConfig.removeButtons?
+this.actualConfig.removeButtons.split(","):[]:"removeButtons"in this.originalConfig?this.removedButtons=this.originalConfig.removeButtons?this.originalConfig.removeButtons.split(","):[]:(this.originalConfig.removeButtons="",this.removedButtons=[]);this.actualConfig.toolbarGroups||(this.actualConfig.toolbarGroups=this.fullToolbarEditor.getFullToolbarGroupsConfig());this._fixGroups(this.actualConfig);this._calculateTotalBtns();this._createModifier();this._refreshMoveBtnsAvalibility();this._refreshBtnTabIndexes();
+"function"===typeof a&&a(this.mainContainer)};d.prototype._showConfigurationTool=function(){this.configContainer.addClass("hidden");this.modifyContainer.removeClass("hidden")};d.prototype._showConfig=function(){var a=this.getActualConfig(),b,c;if(a.toolbarGroups){b=a.toolbarGroups;for(var e=this.cfg.trimEmptyGroups,f=[],g=b.length,m=0;m<g;m++){var h=b[m];if("/"===h)f.push("'/'");else{if(e)for(var k=h.groups.length;k--;)0===d.getTotalSubGroupButtonsNumber(h.groups[k],this.fullToolbarEditor)&&h.groups.splice(k,
+1);e&&0===h.groups.length||f.push(l.stringifyJSONintoOneLine(h,{addSpaces:!0,noQuotesOnKey:!0,singleQuotes:!0}))}}b="\n\t\t"+f.join(",\n\t\t")}a.removeButtons&&(c=a.removeButtons);a=['\x3ctextarea class\x3d"configCode" readonly\x3eCKEDITOR.editorConfig \x3d function( config ) {\n',b?"\tconfig.toolbarGroups \x3d ["+b+"\n\t];":"",c?"\n\n":"",c?"\tconfig.removeButtons \x3d '"+c+"';":"","\n};\x3c/textarea\x3e"].join("");this.modifyContainer.addClass("hidden");this.configContainer.removeClass("hidden");
+this.configContainer.setHtml(a)};d.prototype._toggleVisibilityEmptyElements=function(){this.modifyContainer.hasClass("empty-visible")?(this.modifyContainer.removeClass("empty-visible"),this.emptyVisible=!1):(this.modifyContainer.addClass("empty-visible"),this.emptyVisible=!0);this._refreshMoveBtnsAvalibility()};d.prototype._createModifier=function(){function a(){b._highlightGroup(this.data("name"))}var b=this;l.prototype._createModifier.call(this);this.modifyContainer.setHtml(this._toolbarConfigToListString());
+var c=this.modifyContainer.find('li[data-type\x3d"group"]');this.modifyContainer.on("mouseleave",function(){this._dehighlightActiveToolGroup()},this);for(var e=c.count(),f=0;f<e;f+=1)c.getItem(f).on("mouseenter",a);CKEDITOR.document.on("keypress",function(a){a=a.data.$.keyCode;a=32===a||13===a;var c=new CKEDITOR.dom.element(CKEDITOR.document.$.activeElement);c.getAscendant(function(a){return a.$===b.mainContainer.$})&&a&&"button"===c.data("type")&&c.findOne("input").$.click()});this.modifyContainer.on("click",
+function(a){var c=a.data.$,e=new CKEDITOR.dom.element(c.target||c.srcElement);if(a=d.getGroupOrSeparatorLiAncestor(e)){b.cachedActiveElement=document.activeElement;if(e.$ instanceof HTMLInputElement)b._handleCheckboxClicked(e);else if(e.$ instanceof HTMLButtonElement&&(c.preventDefault?c.preventDefault():c.returnValue=!1,(c=b._handleAnchorClicked(e.$))&&"remove"==c.action))return;c=a.data("type");a=a.data("name");b._setActiveElement(c,a);b.cachedActiveElement&&b.cachedActiveElement.focus()}});this.toolbarContainer||
+(this._createToolbar(),this.toolbarContainer.insertBefore(this.mainContainer.getChildren().getItem(0)));this.showToolbarBtnsByGroupName("edit");this.configContainer||(this.configContainer=new CKEDITOR.dom.element("div"),this.configContainer.addClass("configContainer"),this.configContainer.addClass("hidden"),this.mainContainer.append(this.configContainer));return this.mainContainer};d.prototype.showToolbarBtnsByGroupName=function(a){if(this.toolbarContainer)for(var b=this.toolbarContainer.find("button"),
+c=b.count(),e=0;e<c;e+=1){var d=b.getItem(e);d.data("group")==a?d.removeClass("hidden"):d.addClass("hidden")}};d.parseGroupToConfigValue=function(a){if("separator"==a.type)return"/";var b=a.groups,c=b.length;delete a.totalBtns;for(var e=0;e<c;e+=1)b[e]=b[e].name;return a};d.getGroupOrSeparatorLiAncestor=function(a){return a.$ instanceof HTMLLIElement&&"group"==a.data("type")?a:d.getFirstAncestor(a,function(a){a=a.data("type");return"group"==a||"separator"==a})};d.prototype._setActiveElement=function(a,
+b){this.currentActive&&this.currentActive.elem.removeClass("active");if(null===a)this._dehighlightActiveToolGroup(),this.currentActive=null;else{var c=this.mainContainer.findOne('ul[data-type\x3dtable-body] li[data-type\x3d"'+a+'"][data-name\x3d"'+b+'"]');c.addClass("active");this.currentActive={type:a,name:b,elem:c};"group"==a&&this._highlightGroup(b);"separator"==a&&this._dehighlightActiveToolGroup()}};d.prototype.getActiveToolGroup=function(){return this.editorInstance.container?this.editorInstance.container.findOne(".cke_toolgroup.active, .cke_toolbar.active"):
+null};d.prototype._dehighlightActiveToolGroup=function(){var a=this.getActiveToolGroup();a&&a.removeClass("active");this.editorInstance.container&&this.editorInstance.container.removeClass("some-toolbar-active")};d.prototype._highlightGroup=function(a){this.editorInstance.container&&(a=this.getFirstEnabledButtonInGroup(a),a=this.editorInstance.container.findOne(".cke_button__"+a+", .cke_combo__"+a),this._dehighlightActiveToolGroup(),this.editorInstance.container&&this.editorInstance.container.addClass("some-toolbar-active"),
+a&&(a=d.getFirstAncestor(a,function(a){return a.hasClass("cke_toolbar")}))&&a.addClass("active"))};d.prototype.getFirstEnabledButtonInGroup=function(a){var b=this.actualConfig.toolbarGroups;a=this.getGroupIndex(a);b=b[a];if(-1===a)return null;a=b.groups?b.groups.length:0;for(var c=0;c<a;c+=1){var e=this.getFirstEnabledButtonInSubgroup(b.groups[c].name);if(e)return e}return null};d.prototype.getFirstEnabledButtonInSubgroup=function(a){for(var b=(a=this.fullToolbarEditor.buttonsByGroup[a])?a.length:
+0,c=0;c<b;c+=1){var e=a[c].name;if(!this.isButtonRemoved(e))return e}return null};d.prototype._handleCheckboxClicked=function(a){var b=a.getAscendant("li").data("name");a.$.checked?this._removeButtonFromRemoved(b):this._addButtonToRemoved(b)};d.prototype._handleAnchorClicked=function(a){a=new CKEDITOR.dom.element(a);var b=a.getAscendant("li"),c=b.getAscendant("ul"),e=b.data("type"),d=b.data("name"),g=a.data("direction"),m="up"===g?b.getPrevious():b.getNext(),h;if(a.hasClass("disabled"))return null;
+if(a.hasClass("remove"))return b.remove(),this._removeSeparator(b.data("name")),this._setActiveElement(null),{action:"remove"};if(!a.hasClass("move")||!m)return{action:null};if("group"===e||"separator"===e)h=this._moveGroup(g,d);"subgroup"===e&&(h=b.getAscendant("li").data("name"),h=this._moveSubgroup(g,h,d));"up"===g&&b.insertBefore(c.getChild(h));"down"===g&&b.insertAfter(c.getChild(h));for(var k;b="up"===g?b.getPrevious():b.getNext();)if(this.emptyVisible||!b.hasClass("empty")){k=b;break}k||(k=
+'[data-direction\x3d"'+("up"===g?"down":"up")+'"]',this.cachedActiveElement=a.getParent().findOne(k));this._refreshMoveBtnsAvalibility();this._refreshBtnTabIndexes();return{action:"move"}};d.prototype._refreshMoveBtnsAvalibility=function(){function a(a){var c=a.count();for(d=0;d<c;d+=1)b._disableElementsInList(a.getItem(d))}for(var b=this,c=this.mainContainer.find("ul[data-type\x3dtable-body] li \x3e p \x3e span \x3e button.move.disabled"),e=c.count(),d=0;d<e;d+=1)c.getItem(d).removeClass("disabled");
+a(this.mainContainer.find("ul[data-type\x3dtable-body]"));a(this.mainContainer.find("ul[data-type\x3dtable-body] \x3e li \x3e ul"))};d.prototype._refreshBtnTabIndexes=function(){for(var a=this.mainContainer.find('[data-tab\x3d"true"]'),b=a.count(),c=0;c<b;c++){var e=a.getItem(c),d=e.hasClass("disabled");e.setAttribute("tabindex",d?-1:c)}};d.prototype._disableElementsInList=function(a){function b(a){return!a.hasClass("empty")}if(a.getChildren().count()){var c;this.emptyVisible?(c=a.getFirst(),a=a.getLast()):
+(c=a.getFirst(b),a=a.getLast(b));if(c)var e=c.findOne('p button[data-direction\x3d"up"]');if(a)var d=a.findOne('p button[data-direction\x3d"down"]');e&&(e.addClass("disabled"),e.setAttribute("tabindex","-1"));d&&(d.addClass("disabled"),d.setAttribute("tabindex","-1"))}};d.prototype.getGroupIndex=function(a){for(var b=this.actualConfig.toolbarGroups,c=b.length,d=0;d<c;d+=1)if(b[d].name===a)return d;return-1};d.prototype._addSeparator=function(){var a=this._determineSeparatorToAddIndex(),b=d.createSeparatorLiteral(),
+c=CKEDITOR.dom.element.createFromHtml(d.getToolbarSeparatorString(b));this.actualConfig.toolbarGroups.splice(a,0,b);c.insertBefore(this.modifyContainer.findOne("ul[data-type\x3dtable-body]").getChild(a));this._setActiveElement("separator",b.name);this._refreshMoveBtnsAvalibility();this._refreshBtnTabIndexes();this._refreshEditor()};d.prototype._removeSeparator=function(a){var b=CKEDITOR.tools.indexOf(this.actualConfig.toolbarGroups,function(b){return"separator"==b.type&&b.name==a});this.actualConfig.toolbarGroups.splice(b,
+1);this._refreshMoveBtnsAvalibility();this._refreshBtnTabIndexes();this._refreshEditor()};d.prototype._determineSeparatorToAddIndex=function(){return this.currentActive?("group"==this.currentActive.elem.data("type")||"separator"==this.currentActive.elem.data("type")?this.currentActive.elem:this.currentActive.elem.getAscendant("li")).getIndex():0};d.prototype._moveElement=function(a,b,c){function e(a){return a.totalBtns||"separator"==a.type}c=this.emptyVisible?"down"==c?b+1:b-1:d.getFirstElementIndexWith(a,
+b,c,e);return d.moveTo(c-b,a,b)};d.prototype._moveGroup=function(a,b){var c=this.getGroupIndex(b),c=this._moveElement(this.actualConfig.toolbarGroups,c,a);this._refreshMoveBtnsAvalibility();this._refreshBtnTabIndexes();this._refreshEditor();return c};d.prototype._moveSubgroup=function(a,b,c){b=this.getGroupIndex(b);b=this.actualConfig.toolbarGroups[b];var d=CKEDITOR.tools.indexOf(b.groups,function(a){return a.name==c});a=this._moveElement(b.groups,d,a);this._refreshEditor();return a};d.prototype._calculateTotalBtns=
+function(){for(var a=this.actualConfig.toolbarGroups,b=a.length;b--;){var c=a[b],e=d.getTotalGroupButtonsNumber(c,this.fullToolbarEditor);"separator"!=c.type&&(c.totalBtns=e)}};d.prototype._addButtonToRemoved=function(a){if(-1!=CKEDITOR.tools.indexOf(this.removedButtons,a))throw"Button already added to removed";this.removedButtons.push(a);this.actualConfig.removeButtons=this.removedButtons.join(",");this._refreshEditor()};d.prototype._removeButtonFromRemoved=function(a){a=CKEDITOR.tools.indexOf(this.removedButtons,
+a);if(-1===a)throw"Trying to remove button from removed, but not found";this.removedButtons.splice(a,1);this.actualConfig.removeButtons=this.removedButtons.join(",");this._refreshEditor()};d.parseGroupToConfigValue=function(a){if("separator"==a.type)return"/";var b=a.groups,c=b.length;delete a.totalBtns;for(var d=0;d<c;d+=1)b[d]=b[d].name;return a};d.getGroupOrSeparatorLiAncestor=function(a){return a.$ instanceof HTMLLIElement&&"group"==a.data("type")?a:d.getFirstAncestor(a,function(a){a=a.data("type");
+return"group"==a||"separator"==a})};d.createSeparatorLiteral=function(){return{type:"separator",name:"separator"+CKEDITOR.tools.getNextNumber()}};d.prototype._toolbarConfigToListString=function(){for(var a=this.actualConfig.toolbarGroups||[],b='\x3cul data-type\x3d"table-body"\x3e',c=a.length,e=0;e<c;e+=1)var f=a[e],b="separator"===f.type?b+d.getToolbarSeparatorString(f):b+this._getToolbarGroupString(f);b+="\x3c/ul\x3e";return d.getToolbarHeaderString()+b};d.prototype._getToolbarGroupString=function(a){var b=
+a.groups,c;c=""+['\x3cli data-type\x3d"group" data-name\x3d"',a.name,'" ',a.totalBtns?"":'class\x3d"empty"',"\x3e"].join("");c+=d.getToolbarElementPreString(a)+"\x3cul\x3e";a=b.length;for(var e=0;e<a;e+=1){var f=b[e];c+=this._getToolbarSubgroupString(f,this.fullToolbarEditor.buttonsByGroup[f.name])}return c+"\x3c/ul\x3e\x3c/li\x3e"};d.getToolbarSeparatorString=function(a){return['\x3cli data-type\x3d"',a.type,'" data-name\x3d"',a.name,'"\x3e',d.getToolbarElementPreString("row separator"),"\x3c/li\x3e"].join("")};
+d.getToolbarHeaderString=function(){return'\x3cul data-type\x3d"table-header"\x3e\x3cli data-type\x3d"header"\x3e\x3cp\x3eToolbars\x3c/p\x3e\x3cul\x3e\x3cli\x3e\x3cp\x3eToolbar groups\x3c/p\x3e\x3cp\x3eToolbar group items\x3c/p\x3e\x3c/li\x3e\x3c/ul\x3e\x3c/li\x3e\x3c/ul\x3e'};d.getFirstAncestor=function(a,b){for(var c=a.getParents(),d=c.length;d--;)if(b(c[d]))return c[d];return null};d.getFirstElementIndexWith=function(a,b,c,d){for(;"up"===c?b--:++b<a.length;)if(d(a[b]))return b;return-1};d.moveTo=
+function(a,b,c){var d;-1!==c&&(d=b.splice(c,1)[0]);a=c+a;b.splice(a,0,d);return a};d.getTotalSubGroupButtonsNumber=function(a,b){var c=b.buttonsByGroup["string"==typeof a?a:a.name];return c?c.length:0};d.getTotalGroupButtonsNumber=function(a,b){for(var c=0,e=a.groups,f=e?e.length:0,g=0;g<f;g+=1)c+=d.getTotalSubGroupButtonsNumber(e[g],b);return c};d.prototype._getToolbarSubgroupString=function(a,b){var c;c=""+['\x3cli data-type\x3d"subgroup" data-name\x3d"',a.name,'" ',a.totalBtns?"":'class\x3d"empty" ',
+"\x3e"].join("");c+=d.getToolbarElementPreString(a.name);c+="\x3cul\x3e";for(var e=b?b.length:0,f=0;f<e;f+=1)c+=this.getButtonString(b[f]);return c+="\x3c/ul\x3e\x3c/li\x3e"};d.prototype._getConfigButtonName=function(a){var b=this.fullToolbarEditor.editorInstance.ui.items,c;for(c in b)if(b[c].name==a)return c;return null};d.prototype.isButtonRemoved=function(a){return-1!=CKEDITOR.tools.indexOf(this.removedButtons,this._getConfigButtonName(a))};d.prototype.getButtonString=function(a){var b=this.isButtonRemoved(a.name)?
+"":'checked\x3d"checked"';return['\x3cli data-tab\x3d"true" data-type\x3d"button" data-name\x3d"',this._getConfigButtonName(a.name),'"\x3e\x3clabel title\x3d"',a.label,'" \x3e\x3cinput tabindex\x3d"-1"type\x3d"checkbox"',b,"/\x3e",a.$.getOuterHtml(),"\x3c/label\x3e\x3c/li\x3e"].join("")};d.getToolbarElementPreString=function(a){a=a.name?a.name:a;return['\x3cp\x3e\x3cspan\x3e\x3cbutton title\x3d"Move element upward" data-tab\x3d"true" data-direction\x3d"up" class\x3d"move icon-up-big"\x3e\x3c/button\x3e\x3cbutton title\x3d"Move element downward" data-tab\x3d"true" data-direction\x3d"down" class\x3d"move icon-down-big"\x3e\x3c/button\x3e',
+"row separator"==a?'\x3cbutton title\x3d"Remove element" data-tab\x3d"true" class\x3d"remove icon-trash"\x3e\x3c/button\x3e':"",a,"\x3c/span\x3e\x3c/p\x3e"].join("")};d.evaluateToolbarGroupsConfig=function(a){return a=function(a){var c={},d;try{d=eval("("+a+")")}catch(f){try{d=eval(a)}catch(g){return null}}return c.toolbarGroups&&"number"===typeof c.toolbarGroups.length?JSON.stringify(c):d&&"number"===typeof d.length?JSON.stringify({toolbarGroups:d}):d&&d.toolbarGroups?JSON.stringify(d):null}(a)};
+return d})();
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/js/toolbartextmodifier.js b/release/samples/toolbarconfigurator/js/toolbartextmodifier.js
new file mode 100644 (file)
index 0000000..b9ef46b
--- /dev/null
@@ -0,0 +1,14 @@
+(function(){function e(a){l.call(this,a);this.hintContainer=this.codeContainer=null}var l=ToolbarConfigurator.AbstractToolbarModifier,g=ToolbarConfigurator.FullToolbarEditor;ToolbarConfigurator.ToolbarTextModifier=e;e.prototype=Object.create(l.prototype);e.prototype._onInit=function(a,d){l.prototype._onInit.call(this,void 0,d);this._createModifier(d?this.actualConfig:void 0);"function"===typeof a&&a(this.mainContainer)};e.prototype._createModifier=function(a){function d(a){var b=c(a);if(null!==b.charsBetween){var d=
+k.getUnusedButtonsArray(k.actualConfig.toolbar,!0,b.charsBetween),e=a.getCursor(),b=CodeMirror.Pos(e.line,e.ch-b.charsBetween.length),h=a.getTokenAt(e);"{"===a.getTokenAt({line:e.line,ch:h.start}).string&&(d=["name"]);if(0!==d.length)return new f(b,e,d)}}function f(a,c,b){this.from=a;this.to=c;this.list=b;this._handlers=[]}function c(a,c){var b={};b.cur=a.getCursor();b.tok=a.getTokenAt(b.cur);b["char"]=c||b.tok.string.charAt(b.tok.string.length-1);var d=a.getRange(CodeMirror.Pos(b.cur.line,0),b.cur).split("").reverse().join(""),
+d=d.replace(/(['|"]\w*['|"])/g,"");b.charsBetween=d.match(/(^\w*)(['|"])/);b.charsBetween&&(b.endChar=b.charsBetween[2],b.charsBetween=b.charsBetween[1].split("").reverse().join(""));return b}function b(a){setTimeout(function(){a.state.completionActive||CodeMirror.showHint(a,d,{hintsClass:"toolbar-modifier",completeSingle:!1})},100);return CodeMirror.Pass}var k=this;this._createToolbar();this.toolbarContainer&&this.mainContainer.append(this.toolbarContainer);l.prototype._createModifier.call(this);
+this._setupActualConfig(a);a=this.actualConfig.toolbar;a=CKEDITOR.tools.isArray(a)?"\tconfig.toolbar \x3d "+("[\n\t\t"+g.map(a,function(a){return l.stringifyJSONintoOneLine(a,{addSpaces:!0,noQuotesOnKey:!0,singleQuotes:!0})}).join(",\n\t\t")+"\n\t]")+";":"config.toolbar \x3d [];";a=["CKEDITOR.editorConfig \x3d function( config ) {\n",a,"\n};"].join("");var e=new CKEDITOR.dom.element("div");e.addClass("codemirror-wrapper");this.modifyContainer.append(e);this.codeContainer=CodeMirror(e.$,{mode:{name:"javascript",
+json:!0},lineNumbers:!1,lineWrapping:!0,viewportMargin:Infinity,value:a,smartIndent:!1,indentWithTabs:!0,indentUnit:4,tabSize:4,theme:"neo",extraKeys:{Left:b,Right:b,"'''":b,"'\"'":b,Backspace:b,Delete:b,"Shift-Tab":"indentLess"}});this.codeContainer.on("endCompletion",function(a,b){var d=c(a);void 0!==b&&a.replaceSelection(d.endChar)});this.codeContainer.on("change",function(){var a=k.codeContainer.getValue(),a=k._evaluateValue(a);null!==a?(k.actualConfig.toolbar=a.toolbar?a.toolbar:k.actualConfig.toolbar,
+k._fillHintByUnusedElements(),k._refreshEditor(),k.mainContainer.removeClass("invalid")):k.mainContainer.addClass("invalid")});this.hintContainer=new CKEDITOR.dom.element("div");this.hintContainer.addClass("toolbarModifier-hints");this._fillHintByUnusedElements();this.hintContainer.insertBefore(e)};e.prototype._fillHintByUnusedElements=function(){var a=this.getUnusedButtonsArray(this.actualConfig.toolbar,!0),a=this.groupButtonNamesByGroup(a),d=g.map(a,function(a){var b=g.map(a.buttons,function(a){return"\x3ccode\x3e"+
+a+"\x3c/code\x3e "}).join("");return["\x3cdt\x3e\x3ccode\x3e",a.name,"\x3c/code\x3e\x3c/dt\x3e\x3cdd\x3e",b,"\x3c/dd\x3e"].join("")}).join(" "),f='\x3cdt class\x3d"list-header"\x3eToolbar group\x3c/dt\x3e\x3cdd class\x3d"list-header"\x3eUnused items\x3c/dd\x3e';a.length||(f="\x3cp\x3eAll items are in use.\x3c/p\x3e");this.codeContainer.refresh();this.hintContainer.setHtml("\x3ch3\x3eUnused toolbar items\x3c/h3\x3e\x3cdl\x3e"+f+d+"\x3c/dl\x3e")};e.prototype.getToolbarGroupByButtonName=function(a){var d=
+this.fullToolbarEditor.buttonNamesByGroup,f;for(f in d)for(var c=d[f],b=c.length;b--;)if(a===c[b])return f;return null};e.prototype.getUnusedButtonsArray=function(a,d,f){d=!0===d?!0:!1;var c=e.mapToolbarCfgToElementsList(a);a=Object.keys(this.fullToolbarEditor.editorInstance.ui.items);a=g.filter(a,function(a){var d="-"===a;a=void 0===f||0===a.toLowerCase().indexOf(f.toLowerCase());return!d&&a});a=g.filter(a,function(a){return-1==CKEDITOR.tools.indexOf(c,a)});d&&a.sort();return a};e.prototype.groupButtonNamesByGroup=
+function(a){var d=[],f=JSON.parse(JSON.stringify(this.fullToolbarEditor.buttonNamesByGroup)),c;for(c in f){var b=f[c],b=g.filter(b,function(b){return-1!==CKEDITOR.tools.indexOf(a,b)});b.length&&d.push({name:c,buttons:b})}return d};e.mapToolbarCfgToElementsList=function(a){function d(a){return"-"!==a}for(var f=[],c=a.length,b=0;b<c;b+=1)a[b]&&"string"!==typeof a[b]&&(f=f.concat(g.filter(a[b].items,d)));return f};e.prototype._setupActualConfig=function(a){a=a||this.editorInstance.config;CKEDITOR.tools.isArray(a.toolbar)||
+(a.toolbarGroups||(a.toolbarGroups=this.fullToolbarEditor.getFullToolbarGroupsConfig(!0)),this._fixGroups(a),a.toolbar=this._mapToolbarGroupsToToolbar(a.toolbarGroups,this.actualConfig.removeButtons),this.actualConfig.toolbar=a.toolbar,this.actualConfig.removeButtons="")};e.prototype._mapToolbarGroupsToToolbar=function(a,d){d=d||this.editorInstance.config.removedBtns;d="string"==typeof d?d.split(","):[];for(var f=a.length;f--;){var c=this._mapToolbarSubgroup(a[f],d);"separator"===a[f].type?a[f]="/":
+CKEDITOR.tools.isArray(c)&&0===c.length?a.splice(f,1):a[f]="string"==typeof c?c:{name:a[f].name,items:c}}return a};e.prototype._mapToolbarSubgroup=function(a,d){if("string"==typeof a)return a;for(var f=a.groups?a.groups.length:0,c=[],b=0;b<f;b+=1){var e=a.groups[b],e=this.fullToolbarEditor.buttonsByGroup["string"===typeof e?e:e.name]||[],e=this._mapButtonsToButtonsNames(e,d),g=e.length,c=c.concat(e);g&&c.push("-")}"-"==c[c.length-1]&&c.pop();return c};e.prototype._mapButtonsToButtonsNames=function(a,
+d){for(var f=a.length;f--;){var c=a[f],c="string"===typeof c?c:this.fullToolbarEditor.getCamelCasedButtonName(c.name);-1!==CKEDITOR.tools.indexOf(d,c)?a.splice(f,1):a[f]=c}return a};e.prototype._evaluateValue=function(a){var d;try{var f={};Function("var CKEDITOR \x3d {}; "+a+"; return CKEDITOR;")().editorConfig(f);d=f;for(var c=d.toolbar.length;c--;)d.toolbar[c]||d.toolbar.splice(c,1)}catch(b){d=null}return d};e.prototype.mapToolbarToToolbarGroups=function(a){function d(a,b){a=a.slice();for(var d=
+b.length;d--;){var c=a.indexOf(b[d]);-1!==c&&a.splice(c,1)}return a}for(var f={},c=[],b=[],c=a.length,e=0;e<c;e++)if("/"===a[e])b.push("/");else{var g=a[e].items,m={};m.name=a[e].name;m.groups=[];for(var l=g.length,p=0;p<l;p++){var n=g[p];if("-"!==n){var h=this.getToolbarGroupByButtonName(n);-1===m.groups.indexOf(h)&&m.groups.push(h);f[h]=f[h]||{};h=f[h].buttons=f[h].buttons||{};h[n]=h[n]||{used:0,origin:m.name};h[n].used++}}b.push(m)}c=function(a,b){var c=[],e;for(e in a)var f=a[e],g=b[e].slice(),
+c=c.concat(d(g,Object.keys(f.buttons)));return c}(f,this.fullToolbarEditor.buttonNamesByGroup);return{toolbarGroups:b,removeButtons:c.join(",")}};return e})();
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/LICENSE b/release/samples/toolbarconfigurator/lib/codemirror/LICENSE
new file mode 100644 (file)
index 0000000..d21bbea
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/codemirror.css b/release/samples/toolbarconfigurator/lib/codemirror/codemirror.css
new file mode 100644 (file)
index 0000000..2fe9d0f
--- /dev/null
@@ -0,0 +1,325 @@
+/* BASICS */\r
+\r
+.CodeMirror {\r
+  /* Set height, width, borders, and global font properties here */\r
+  font-family: monospace;\r
+  height: 300px;\r
+  color: black;\r
+}\r
+\r
+/* PADDING */\r
+\r
+.CodeMirror-lines {\r
+  padding: 4px 0; /* Vertical padding around content */\r
+}\r
+.CodeMirror pre {\r
+  padding: 0 4px; /* Horizontal padding of content */\r
+}\r
+\r
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\r
+  background-color: white; /* The little square between H and V scrollbars */\r
+}\r
+\r
+/* GUTTER */\r
+\r
+.CodeMirror-gutters {\r
+  border-right: 1px solid #ddd;\r
+  background-color: #f7f7f7;\r
+  white-space: nowrap;\r
+}\r
+.CodeMirror-linenumbers {}\r
+.CodeMirror-linenumber {\r
+  padding: 0 3px 0 5px;\r
+  min-width: 20px;\r
+  text-align: right;\r
+  color: #999;\r
+  white-space: nowrap;\r
+}\r
+\r
+.CodeMirror-guttermarker { color: black; }\r
+.CodeMirror-guttermarker-subtle { color: #999; }\r
+\r
+/* CURSOR */\r
+\r
+.CodeMirror div.CodeMirror-cursor {\r
+  border-left: 1px solid black;\r
+}\r
+/* Shown when moving in bi-directional text */\r
+.CodeMirror div.CodeMirror-secondarycursor {\r
+  border-left: 1px solid silver;\r
+}\r
+.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {\r
+  width: auto;\r
+  border: 0;\r
+  background: #7e7;\r
+}\r
+.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {\r
+  z-index: 1;\r
+}\r
+\r
+.cm-animate-fat-cursor {\r
+  width: auto;\r
+  border: 0;\r
+  -webkit-animation: blink 1.06s steps(1) infinite;\r
+  -moz-animation: blink 1.06s steps(1) infinite;\r
+  animation: blink 1.06s steps(1) infinite;\r
+}\r
+@-moz-keyframes blink {\r
+  0% { background: #7e7; }\r
+  50% { background: none; }\r
+  100% { background: #7e7; }\r
+}\r
+@-webkit-keyframes blink {\r
+  0% { background: #7e7; }\r
+  50% { background: none; }\r
+  100% { background: #7e7; }\r
+}\r
+@keyframes blink {\r
+  0% { background: #7e7; }\r
+  50% { background: none; }\r
+  100% { background: #7e7; }\r
+}\r
+\r
+/* Can style cursor different in overwrite (non-insert) mode */\r
+div.CodeMirror-overwrite div.CodeMirror-cursor {}\r
+\r
+.cm-tab { display: inline-block; text-decoration: inherit; }\r
+\r
+.CodeMirror-ruler {\r
+  border-left: 1px solid #ccc;\r
+  position: absolute;\r
+}\r
+\r
+/* DEFAULT THEME */\r
+\r
+.cm-s-default .cm-keyword {color: #708;}\r
+.cm-s-default .cm-atom {color: #219;}\r
+.cm-s-default .cm-number {color: #164;}\r
+.cm-s-default .cm-def {color: #00f;}\r
+.cm-s-default .cm-variable,\r
+.cm-s-default .cm-punctuation,\r
+.cm-s-default .cm-property,\r
+.cm-s-default .cm-operator {}\r
+.cm-s-default .cm-variable-2 {color: #05a;}\r
+.cm-s-default .cm-variable-3 {color: #085;}\r
+.cm-s-default .cm-comment {color: #a50;}\r
+.cm-s-default .cm-string {color: #a11;}\r
+.cm-s-default .cm-string-2 {color: #f50;}\r
+.cm-s-default .cm-meta {color: #555;}\r
+.cm-s-default .cm-qualifier {color: #555;}\r
+.cm-s-default .cm-builtin {color: #30a;}\r
+.cm-s-default .cm-bracket {color: #997;}\r
+.cm-s-default .cm-tag {color: #170;}\r
+.cm-s-default .cm-attribute {color: #00c;}\r
+.cm-s-default .cm-header {color: blue;}\r
+.cm-s-default .cm-quote {color: #090;}\r
+.cm-s-default .cm-hr {color: #999;}\r
+.cm-s-default .cm-link {color: #00c;}\r
+\r
+.cm-negative {color: #d44;}\r
+.cm-positive {color: #292;}\r
+.cm-header, .cm-strong {font-weight: bold;}\r
+.cm-em {font-style: italic;}\r
+.cm-link {text-decoration: underline;}\r
+.cm-strikethrough {text-decoration: line-through;}\r
+\r
+.cm-s-default .cm-error {color: #f00;}\r
+.cm-invalidchar {color: #f00;}\r
+\r
+.CodeMirror-composing { border-bottom: 2px solid; }\r
+\r
+/* Default styles for common addons */\r
+\r
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}\r
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}\r
+.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }\r
+.CodeMirror-activeline-background {background: #e8f2ff;}\r
+\r
+/* STOP */\r
+\r
+/* The rest of this file contains styles related to the mechanics of\r
+   the editor. You probably shouldn't touch them. */\r
+\r
+.CodeMirror {\r
+  position: relative;\r
+  overflow: hidden;\r
+  background: white;\r
+}\r
+\r
+.CodeMirror-scroll {\r
+  overflow: scroll !important; /* Things will break if this is overridden */\r
+  /* 30px is the magic margin used to hide the element's real scrollbars */\r
+  /* See overflow: hidden in .CodeMirror */\r
+  margin-bottom: -30px; margin-right: -30px;\r
+  padding-bottom: 30px;\r
+  height: 100%;\r
+  outline: none; /* Prevent dragging from highlighting the element */\r
+  position: relative;\r
+}\r
+.CodeMirror-sizer {\r
+  position: relative;\r
+  border-right: 30px solid transparent;\r
+}\r
+\r
+/* The fake, visible scrollbars. Used to force redraw during scrolling\r
+   before actuall scrolling happens, thus preventing shaking and\r
+   flickering artifacts. */\r
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {\r
+  position: absolute;\r
+  z-index: 6;\r
+  display: none;\r
+}\r
+.CodeMirror-vscrollbar {\r
+  right: 0; top: 0;\r
+  overflow-x: hidden;\r
+  overflow-y: scroll;\r
+}\r
+.CodeMirror-hscrollbar {\r
+  bottom: 0; left: 0;\r
+  overflow-y: hidden;\r
+  overflow-x: scroll;\r
+}\r
+.CodeMirror-scrollbar-filler {\r
+  right: 0; bottom: 0;\r
+}\r
+.CodeMirror-gutter-filler {\r
+  left: 0; bottom: 0;\r
+}\r
+\r
+.CodeMirror-gutters {\r
+  position: absolute; left: 0; top: 0;\r
+  z-index: 3;\r
+}\r
+.CodeMirror-gutter {\r
+  white-space: normal;\r
+  height: 100%;\r
+  display: inline-block;\r
+  margin-bottom: -30px;\r
+  /* Hack to make IE7 behave */\r
+  *zoom:1;\r
+  *display:inline;\r
+}\r
+.CodeMirror-gutter-wrapper {\r
+  position: absolute;\r
+  z-index: 4;\r
+  height: 100%;\r
+}\r
+.CodeMirror-gutter-elt {\r
+  position: absolute;\r
+  cursor: default;\r
+  z-index: 4;\r
+}\r
+.CodeMirror-gutter-wrapper {\r
+  -webkit-user-select: none;\r
+  -moz-user-select: none;\r
+  user-select: none;\r
+}\r
+\r
+.CodeMirror-lines {\r
+  cursor: text;\r
+  min-height: 1px; /* prevents collapsing before first draw */\r
+}\r
+.CodeMirror pre {\r
+  /* Reset some styles that the rest of the page might have set */\r
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;\r
+  border-width: 0;\r
+  background: transparent;\r
+  font-family: inherit;\r
+  font-size: inherit;\r
+  margin: 0;\r
+  white-space: pre;\r
+  word-wrap: normal;\r
+  line-height: inherit;\r
+  color: inherit;\r
+  z-index: 2;\r
+  position: relative;\r
+  overflow: visible;\r
+  -webkit-tap-highlight-color: transparent;\r
+}\r
+.CodeMirror-wrap pre {\r
+  word-wrap: break-word;\r
+  white-space: pre-wrap;\r
+  word-break: normal;\r
+}\r
+\r
+.CodeMirror-linebackground {\r
+  position: absolute;\r
+  left: 0; right: 0; top: 0; bottom: 0;\r
+  z-index: 0;\r
+}\r
+\r
+.CodeMirror-linewidget {\r
+  position: relative;\r
+  z-index: 2;\r
+  overflow: auto;\r
+}\r
+\r
+.CodeMirror-widget {}\r
+\r
+.CodeMirror-code {\r
+  outline: none;\r
+}\r
+\r
+/* Force content-box sizing for the elements where we expect it */\r
+.CodeMirror-scroll,\r
+.CodeMirror-sizer,\r
+.CodeMirror-gutter,\r
+.CodeMirror-gutters,\r
+.CodeMirror-linenumber {\r
+  -moz-box-sizing: content-box;\r
+  box-sizing: content-box;\r
+}\r
+\r
+.CodeMirror-measure {\r
+  position: absolute;\r
+  width: 100%;\r
+  height: 0;\r
+  overflow: hidden;\r
+  visibility: hidden;\r
+}\r
+.CodeMirror-measure pre { position: static; }\r
+\r
+.CodeMirror div.CodeMirror-cursor {\r
+  position: absolute;\r
+  border-right: none;\r
+  width: 0;\r
+}\r
+\r
+div.CodeMirror-cursors {\r
+  visibility: hidden;\r
+  position: relative;\r
+  z-index: 3;\r
+}\r
+.CodeMirror-focused div.CodeMirror-cursors {\r
+  visibility: visible;\r
+}\r
+\r
+.CodeMirror-selected { background: #d9d9d9; }\r
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }\r
+.CodeMirror-crosshair { cursor: crosshair; }\r
+.CodeMirror ::selection { background: #d7d4f0; }\r
+.CodeMirror ::-moz-selection { background: #d7d4f0; }\r
+\r
+.cm-searching {\r
+  background: #ffa;\r
+  background: rgba(255, 255, 0, .4);\r
+}\r
+\r
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */\r
+.CodeMirror span { *vertical-align: text-bottom; }\r
+\r
+/* Used to force a border model for a node */\r
+.cm-force-border { padding-right: .1px; }\r
+\r
+@media print {\r
+  /* Hide the cursor when printing */\r
+  .CodeMirror div.CodeMirror-cursors {\r
+    visibility: hidden;\r
+  }\r
+}\r
+\r
+/* See issue #2901 */\r
+.cm-tab-wrap-hack:after { content: ''; }\r
+\r
+/* Help users use markselection to safely style text background */\r
+span.CodeMirror-selectedtext { background: none; }\r
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/codemirror.js b/release/samples/toolbarconfigurator/lib/codemirror/codemirror.js
new file mode 100644 (file)
index 0000000..538493f
--- /dev/null
@@ -0,0 +1,288 @@
+(function(q){if("object"==typeof exports&&"object"==typeof module)module.exports=q();else{if("function"==typeof define&&define.amd)return define([],q);this.CodeMirror=q()}})(function(){function q(a,b){if(!(this instanceof q))return new q(a,b);this.options=b=b?V(b):{};V(qf,b,!1);wc(b);var c=b.value;"string"==typeof c&&(c=new P(c,b.mode));this.doc=c;var d=new q.inputStyles[b.inputStyle](this),d=this.display=new rf(a,c,d);d.wrapper.CodeMirror=this;Ad(this);Bd(this);b.lineWrapping&&(this.display.wrapper.className+=
+" CodeMirror-wrap");b.autofocus&&!ab&&d.input.focus();Cd(this);this.state={keyMaps:[],overlays:[],modeGen:0,overwrite:!1,delayingBlurEvent:!1,focused:!1,suppressEdits:!1,pasteIncoming:!1,cutIncoming:!1,draggingText:!1,highlight:new bb,keySeq:null,specialChars:null};var e=this;B&&11>C&&setTimeout(function(){e.display.input.reset(!0)},20);sf(this);Dd||(tf(),Dd=!0);Ja(this);this.curOp.forceUpdate=!0;Ed(this,c);b.autofocus&&!ab||e.hasFocus()?setTimeout(cb(xc,this),20):db(this);for(var f in Ka)if(Ka.hasOwnProperty(f))Ka[f](this,
+b[f],Fd);Gd(this);b.finishInit&&b.finishInit(this);for(c=0;c<yc.length;++c)yc[c](this);La(this);J&&b.lineWrapping&&"optimizelegibility"==getComputedStyle(d.lineDiv).textRendering&&(d.lineDiv.style.textRendering="auto")}function rf(a,b,c){this.input=c;this.scrollbarFiller=t("div",null,"CodeMirror-scrollbar-filler");this.scrollbarFiller.setAttribute("cm-not-content","true");this.gutterFiller=t("div",null,"CodeMirror-gutter-filler");this.gutterFiller.setAttribute("cm-not-content","true");this.lineDiv=
+t("div",null,"CodeMirror-code");this.selectionDiv=t("div",null,null,"position: relative; z-index: 1");this.cursorDiv=t("div",null,"CodeMirror-cursors");this.measure=t("div",null,"CodeMirror-measure");this.lineMeasure=t("div",null,"CodeMirror-measure");this.lineSpace=t("div",[this.measure,this.lineMeasure,this.selectionDiv,this.cursorDiv,this.lineDiv],null,"position: relative; outline: none");this.mover=t("div",[t("div",[this.lineSpace],"CodeMirror-lines")],null,"position: relative");this.sizer=t("div",
+[this.mover],"CodeMirror-sizer");this.sizerWidth=null;this.heightForcer=t("div",null,null,"position: absolute; height: "+Hd+"px; width: 1px;");this.gutters=t("div",null,"CodeMirror-gutters");this.lineGutter=null;this.scroller=t("div",[this.sizer,this.heightForcer,this.gutters],"CodeMirror-scroll");this.scroller.setAttribute("tabIndex","-1");this.wrapper=t("div",[this.scrollbarFiller,this.gutterFiller,this.scroller],"CodeMirror");B&&8>C&&(this.gutters.style.zIndex=-1,this.scroller.style.paddingRight=
+0);J||wa&&ab||(this.scroller.draggable=!0);a&&(a.appendChild?a.appendChild(this.wrapper):a(this.wrapper));this.reportedViewFrom=this.reportedViewTo=this.viewFrom=this.viewTo=b.first;this.view=[];this.externalMeasured=this.renderedView=null;this.lastWrapHeight=this.lastWrapWidth=this.viewOffset=0;this.updateLineNumbers=null;this.nativeBarWidth=this.barHeight=this.barWidth=0;this.scrollbarsClipped=!1;this.lineNumWidth=this.lineNumInnerWidth=this.lineNumChars=null;this.alignWidgets=!1;this.maxLine=this.cachedCharWidth=
+this.cachedTextHeight=this.cachedPaddingH=null;this.maxLineLength=0;this.maxLineChanged=!1;this.wheelDX=this.wheelDY=this.wheelStartX=this.wheelStartY=null;this.shift=!1;this.activeTouch=this.selForContextMenu=null;c.init(this)}function zc(a){a.doc.mode=q.getMode(a.options,a.doc.modeOption);eb(a)}function eb(a){a.doc.iter(function(a){a.stateAfter&&(a.stateAfter=null);a.styles&&(a.styles=null)});a.doc.frontier=a.doc.first;fb(a,100);a.state.modeGen++;a.curOp&&Q(a)}function Id(a){var b=xa(a.display),
+c=a.options.lineWrapping,d=c&&Math.max(5,a.display.scroller.clientWidth/gb(a.display)-3);return function(e){if(ya(a.doc,e))return 0;var f=0;if(e.widgets)for(var g=0;g<e.widgets.length;g++)e.widgets[g].height&&(f+=e.widgets[g].height);return c?f+(Math.ceil(e.text.length/d)||1)*b:f+b}}function Ac(a){var b=a.doc,c=Id(a);b.iter(function(a){var b=c(a);b!=a.height&&ca(a,b)})}function Bd(a){a.display.wrapper.className=a.display.wrapper.className.replace(/\s*cm-s-\S+/g,"")+a.options.theme.replace(/(^|\s)\s*/g,
+" cm-s-");hb(a)}function ib(a){Ad(a);Q(a);setTimeout(function(){Bc(a)},20)}function Ad(a){var b=a.display.gutters,c=a.options.gutters;za(b);for(var d=0;d<c.length;++d){var e=c[d],f=b.appendChild(t("div",null,"CodeMirror-gutter "+e));"CodeMirror-linenumbers"==e&&(a.display.lineGutter=f,f.style.width=(a.display.lineNumWidth||1)+"px")}b.style.display=d?"":"none";Cc(a)}function Cc(a){a.display.sizer.style.marginLeft=a.display.gutters.offsetWidth+"px"}function Kb(a){if(0==a.height)return 0;for(var b=a.text.length,
+c,d=a;c=Aa(d,!0);)c=c.find(0,!0),d=c.from.line,b+=c.from.ch-c.to.ch;for(d=a;c=Aa(d,!1);)c=c.find(0,!0),b-=d.text.length-c.from.ch,d=c.to.line,b+=d.text.length-c.to.ch;return b}function Dc(a){var b=a.display;a=a.doc;b.maxLine=u(a,a.first);b.maxLineLength=Kb(b.maxLine);b.maxLineChanged=!0;a.iter(function(a){var d=Kb(a);d>b.maxLineLength&&(b.maxLineLength=d,b.maxLine=a)})}function wc(a){var b=D(a.gutters,"CodeMirror-linenumbers");-1==b&&a.lineNumbers?a.gutters=a.gutters.concat(["CodeMirror-linenumbers"]):
+-1<b&&!a.lineNumbers&&(a.gutters=a.gutters.slice(0),a.gutters.splice(b,1))}function jb(a){var b=a.display,c=b.gutters.offsetWidth,d=Math.round(a.doc.height+Ec(a.display));return{clientHeight:b.scroller.clientHeight,viewHeight:b.wrapper.clientHeight,scrollWidth:b.scroller.scrollWidth,clientWidth:b.scroller.clientWidth,viewWidth:b.wrapper.clientWidth,barLeft:a.options.fixedGutter?c:0,docHeight:d,scrollHeight:d+da(a)+b.barHeight,nativeBarWidth:b.nativeBarWidth,gutterWidth:c}}function Fc(a,b,c){this.cm=
+c;var d=this.vert=t("div",[t("div",null,null,"min-width: 1px")],"CodeMirror-vscrollbar"),e=this.horiz=t("div",[t("div",null,null,"height: 100%; min-height: 1px")],"CodeMirror-hscrollbar");a(d);a(e);v(d,"scroll",function(){d.clientHeight&&b(d.scrollTop,"vertical")});v(e,"scroll",function(){e.clientWidth&&b(e.scrollLeft,"horizontal")});this.checkedOverlay=!1;B&&8>C&&(this.horiz.style.minHeight=this.vert.style.minWidth="18px")}function Gc(){}function Cd(a){a.display.scrollbars&&(a.display.scrollbars.clear(),
+a.display.scrollbars.addClass&&kb(a.display.wrapper,a.display.scrollbars.addClass));a.display.scrollbars=new q.scrollbarModel[a.options.scrollbarStyle](function(b){a.display.wrapper.insertBefore(b,a.display.scrollbarFiller);v(b,"mousedown",function(){a.state.focused&&setTimeout(function(){a.display.input.focus()},0)});b.setAttribute("cm-not-content","true")},function(b,c){"horizontal"==c?Ma(a,b):lb(a,b)},a);a.display.scrollbars.addClass&&mb(a.display.wrapper,a.display.scrollbars.addClass)}function Na(a,
+b){b||(b=jb(a));var c=a.display.barWidth,d=a.display.barHeight;Jd(a,b);for(var e=0;4>e&&c!=a.display.barWidth||d!=a.display.barHeight;e++)c!=a.display.barWidth&&a.options.lineWrapping&&Lb(a),Jd(a,jb(a)),c=a.display.barWidth,d=a.display.barHeight}function Jd(a,b){var c=a.display,d=c.scrollbars.update(b);c.sizer.style.paddingRight=(c.barWidth=d.right)+"px";c.sizer.style.paddingBottom=(c.barHeight=d.bottom)+"px";d.right&&d.bottom?(c.scrollbarFiller.style.display="block",c.scrollbarFiller.style.height=
+d.bottom+"px",c.scrollbarFiller.style.width=d.right+"px"):c.scrollbarFiller.style.display="";d.bottom&&a.options.coverGutterNextToScrollbar&&a.options.fixedGutter?(c.gutterFiller.style.display="block",c.gutterFiller.style.height=d.bottom+"px",c.gutterFiller.style.width=b.gutterWidth+"px"):c.gutterFiller.style.display=""}function Hc(a,b,c){var d=c&&null!=c.top?Math.max(0,c.top):a.scroller.scrollTop,d=Math.floor(d-a.lineSpace.offsetTop),e=c&&null!=c.bottom?c.bottom:d+a.wrapper.clientHeight,d=Ba(b,d),
+e=Ba(b,e);if(c&&c.ensure){var f=c.ensure.from.line;c=c.ensure.to.line;f<d?(d=f,e=Ba(b,ea(u(b,f))+a.wrapper.clientHeight)):Math.min(c,b.lastLine())>=e&&(d=Ba(b,ea(u(b,c))-a.wrapper.clientHeight),e=c)}return{from:d,to:Math.max(e,d+1)}}function Bc(a){var b=a.display,c=b.view;if(b.alignWidgets||b.gutters.firstChild&&a.options.fixedGutter){for(var d=Ic(b)-b.scroller.scrollLeft+a.doc.scrollLeft,e=b.gutters.offsetWidth,f=d+"px",g=0;g<c.length;g++)if(!c[g].hidden){a.options.fixedGutter&&c[g].gutter&&(c[g].gutter.style.left=
+f);var h=c[g].alignable;if(h)for(var k=0;k<h.length;k++)h[k].style.left=f}a.options.fixedGutter&&(b.gutters.style.left=d+e+"px")}}function Gd(a){if(!a.options.lineNumbers)return!1;var b=a.doc,b=Jc(a.options,b.first+b.size-1),c=a.display;if(b.length!=c.lineNumChars){var d=c.measure.appendChild(t("div",[t("div",b)],"CodeMirror-linenumber CodeMirror-gutter-elt")),e=d.firstChild.offsetWidth,d=d.offsetWidth-e;c.lineGutter.style.width="";c.lineNumInnerWidth=Math.max(e,c.lineGutter.offsetWidth-d)+1;c.lineNumWidth=
+c.lineNumInnerWidth+d;c.lineNumChars=c.lineNumInnerWidth?b.length:-1;c.lineGutter.style.width=c.lineNumWidth+"px";Cc(a);return!0}return!1}function Jc(a,b){return String(a.lineNumberFormatter(b+a.firstLineNumber))}function Ic(a){return a.scroller.getBoundingClientRect().left-a.sizer.getBoundingClientRect().left}function Mb(a,b,c){var d=a.display;this.viewport=b;this.visible=Hc(d,a.doc,b);this.editorIsHidden=!d.wrapper.offsetWidth;this.wrapperHeight=d.wrapper.clientHeight;this.wrapperWidth=d.wrapper.clientWidth;
+this.oldDisplayWidth=pa(a);this.force=c;this.dims=Kc(a);this.events=[]}function Lc(a,b){var c=a.display,d=a.doc;if(b.editorIsHidden)return qa(a),!1;if(!b.force&&b.visible.from>=c.viewFrom&&b.visible.to<=c.viewTo&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo)&&c.renderedView==c.view&&0==Kd(a))return!1;Gd(a)&&(qa(a),b.dims=Kc(a));var e=d.first+d.size,f=Math.max(b.visible.from-a.options.viewportMargin,d.first),g=Math.min(e,b.visible.to+a.options.viewportMargin);c.viewFrom<f&&20>f-c.viewFrom&&
+(f=Math.max(d.first,c.viewFrom));c.viewTo>g&&20>c.viewTo-g&&(g=Math.min(e,c.viewTo));ra&&(f=Mc(a.doc,f),g=Ld(a.doc,g));d=f!=c.viewFrom||g!=c.viewTo||c.lastWrapHeight!=b.wrapperHeight||c.lastWrapWidth!=b.wrapperWidth;e=a.display;0==e.view.length||f>=e.viewTo||g<=e.viewFrom?(e.view=Nb(a,f,g),e.viewFrom=f):(e.viewFrom>f?e.view=Nb(a,f,e.viewFrom).concat(e.view):e.viewFrom<f&&(e.view=e.view.slice(Ca(a,f))),e.viewFrom=f,e.viewTo<g?e.view=e.view.concat(Nb(a,e.viewTo,g)):e.viewTo>g&&(e.view=e.view.slice(0,
+Ca(a,g))));e.viewTo=g;c.viewOffset=ea(u(a.doc,c.viewFrom));a.display.mover.style.top=c.viewOffset+"px";g=Kd(a);if(!d&&0==g&&!b.force&&c.renderedView==c.view&&(null==c.updateLineNumbers||c.updateLineNumbers>=c.viewTo))return!1;f=fa();4<g&&(c.lineDiv.style.display="none");uf(a,c.updateLineNumbers,b.dims);4<g&&(c.lineDiv.style.display="");c.renderedView=c.view;f&&fa()!=f&&f.offsetHeight&&f.focus();za(c.cursorDiv);za(c.selectionDiv);c.gutters.style.height=0;d&&(c.lastWrapHeight=b.wrapperHeight,c.lastWrapWidth=
+b.wrapperWidth,fb(a,400));c.updateLineNumbers=null;return!0}function Md(a,b){for(var c=b.viewport,d=!0;;d=!1){if(!d||!a.options.lineWrapping||b.oldDisplayWidth==pa(a))if(c&&null!=c.top&&(c={top:Math.min(a.doc.height+Ec(a.display)-Nc(a),c.top)}),b.visible=Hc(a.display,a.doc,c),b.visible.from>=a.display.viewFrom&&b.visible.to<=a.display.viewTo)break;if(!Lc(a,b))break;Lb(a);d=jb(a);nb(a);Oc(a,d);Na(a,d)}b.signal(a,"update",a);if(a.display.viewFrom!=a.display.reportedViewFrom||a.display.viewTo!=a.display.reportedViewTo)b.signal(a,
+"viewportChange",a,a.display.viewFrom,a.display.viewTo),a.display.reportedViewFrom=a.display.viewFrom,a.display.reportedViewTo=a.display.viewTo}function Pc(a,b){var c=new Mb(a,b);if(Lc(a,c)){Lb(a);Md(a,c);var d=jb(a);nb(a);Oc(a,d);Na(a,d);c.finish()}}function Oc(a,b){a.display.sizer.style.minHeight=b.docHeight+"px";var c=b.docHeight+a.display.barHeight;a.display.heightForcer.style.top=c+"px";a.display.gutters.style.height=Math.max(c+da(a),b.clientHeight)+"px"}function Lb(a){a=a.display;for(var b=
+a.lineDiv.offsetTop,c=0;c<a.view.length;c++){var d=a.view[c],e;if(!d.hidden){if(B&&8>C){var f=d.node.offsetTop+d.node.offsetHeight;e=f-b;b=f}else e=d.node.getBoundingClientRect(),e=e.bottom-e.top;f=d.line.height-e;2>e&&(e=xa(a));if(.001<f||-.001>f)if(ca(d.line,e),Nd(d.line),d.rest)for(e=0;e<d.rest.length;e++)Nd(d.rest[e])}}}function Nd(a){if(a.widgets)for(var b=0;b<a.widgets.length;++b)a.widgets[b].height=a.widgets[b].node.offsetHeight}function Kc(a){for(var b=a.display,c={},d={},e=b.gutters.clientLeft,
+f=b.gutters.firstChild,g=0;f;f=f.nextSibling,++g)c[a.options.gutters[g]]=f.offsetLeft+f.clientLeft+e,d[a.options.gutters[g]]=f.clientWidth;return{fixedPos:Ic(b),gutterTotalWidth:b.gutters.offsetWidth,gutterLeft:c,gutterWidth:d,wrapperWidth:b.wrapper.clientWidth}}function uf(a,b,c){function d(b){var c=b.nextSibling;J&&W&&a.display.currentWheelTarget==b?b.style.display="none":b.parentNode.removeChild(b);return c}for(var e=a.display,f=a.options.lineNumbers,g=e.lineDiv,h=g.firstChild,k=e.view,e=e.viewFrom,
+l=0;l<k.length;l++){var m=k[l];if(!m.hidden)if(m.node&&m.node.parentNode==g){for(;h!=m.node;)h=d(h);h=f&&null!=b&&b<=e&&m.lineNumber;m.changes&&(-1<D(m.changes,"gutter")&&(h=!1),Od(a,m,e,c));h&&(za(m.lineNumber),m.lineNumber.appendChild(document.createTextNode(Jc(a.options,e))));h=m.node.nextSibling}else{var p=vf(a,m,e,c);g.insertBefore(p,h)}e+=m.size}for(;h;)h=d(h)}function Od(a,b,c,d){for(var e=0;e<b.changes.length;e++){var f=b.changes[e];if("text"==f){var f=b,g=f.text.className,h=Pd(a,f);f.text==
+f.node&&(f.node=h.pre);f.text.parentNode.replaceChild(h.pre,f.text);f.text=h.pre;h.bgClass!=f.bgClass||h.textClass!=f.textClass?(f.bgClass=h.bgClass,f.textClass=h.textClass,Qc(f)):g&&(f.text.className=g)}else if("gutter"==f)Qd(a,b,c,d);else if("class"==f)Qc(b);else if("widget"==f){f=a;g=b;h=d;g.alignable&&(g.alignable=null);for(var k=g.node.firstChild,l=void 0;k;k=l)l=k.nextSibling,"CodeMirror-linewidget"==k.className&&g.node.removeChild(k);Rd(f,g,h)}}b.changes=null}function Ob(a){a.node==a.text&&
+(a.node=t("div",null,null,"position: relative"),a.text.parentNode&&a.text.parentNode.replaceChild(a.node,a.text),a.node.appendChild(a.text),B&&8>C&&(a.node.style.zIndex=2));return a.node}function Pd(a,b){var c=a.display.externalMeasured;return c&&c.line==b.line?(a.display.externalMeasured=null,b.measure=c.measure,c.built):Sd(a,b)}function Qc(a){var b=a.bgClass?a.bgClass+" "+(a.line.bgClass||""):a.line.bgClass;b&&(b+=" CodeMirror-linebackground");if(a.background)b?a.background.className=b:(a.background.parentNode.removeChild(a.background),
+a.background=null);else if(b){var c=Ob(a);a.background=c.insertBefore(t("div",null,b),c.firstChild)}a.line.wrapClass?Ob(a).className=a.line.wrapClass:a.node!=a.text&&(a.node.className="");a.text.className=(a.textClass?a.textClass+" "+(a.line.textClass||""):a.line.textClass)||""}function Qd(a,b,c,d){b.gutter&&(b.node.removeChild(b.gutter),b.gutter=null);var e=b.line.gutterMarkers;if(a.options.lineNumbers||e){var f=Ob(b),g=b.gutter=t("div",null,"CodeMirror-gutter-wrapper","left: "+(a.options.fixedGutter?
+d.fixedPos:-d.gutterTotalWidth)+"px; width: "+d.gutterTotalWidth+"px");a.display.input.setUneditable(g);f.insertBefore(g,b.text);b.line.gutterClass&&(g.className+=" "+b.line.gutterClass);!a.options.lineNumbers||e&&e["CodeMirror-linenumbers"]||(b.lineNumber=g.appendChild(t("div",Jc(a.options,c),"CodeMirror-linenumber CodeMirror-gutter-elt","left: "+d.gutterLeft["CodeMirror-linenumbers"]+"px; width: "+a.display.lineNumInnerWidth+"px")));if(e)for(b=0;b<a.options.gutters.length;++b)c=a.options.gutters[b],
+(f=e.hasOwnProperty(c)&&e[c])&&g.appendChild(t("div",[f],"CodeMirror-gutter-elt","left: "+d.gutterLeft[c]+"px; width: "+d.gutterWidth[c]+"px"))}}function vf(a,b,c,d){var e=Pd(a,b);b.text=b.node=e.pre;e.bgClass&&(b.bgClass=e.bgClass);e.textClass&&(b.textClass=e.textClass);Qc(b);Qd(a,b,c,d);Rd(a,b,d);return b.node}function Rd(a,b,c){Td(a,b.line,b,c,!0);if(b.rest)for(var d=0;d<b.rest.length;d++)Td(a,b.rest[d],b,c,!1)}function Td(a,b,c,d,e){if(b.widgets){var f=Ob(c),g=0;for(b=b.widgets;g<b.length;++g){var h=
+b[g],k=t("div",[h.node],"CodeMirror-linewidget");h.handleMouseEvents||k.setAttribute("cm-ignore-events","true");var l=h,m=k,p=d;if(l.noHScroll){(c.alignable||(c.alignable=[])).push(m);var n=p.wrapperWidth;m.style.left=p.fixedPos+"px";l.coverGutter||(n-=p.gutterTotalWidth,m.style.paddingLeft=p.gutterTotalWidth+"px");m.style.width=n+"px"}l.coverGutter&&(m.style.zIndex=5,m.style.position="relative",l.noHScroll||(m.style.marginLeft=-p.gutterTotalWidth+"px"));a.display.input.setUneditable(k);e&&h.above?
+f.insertBefore(k,c.gutter||c.text):f.appendChild(k);L(h,"redraw")}}}function Rc(a){return r(a.line,a.ch)}function Pb(a,b){return 0>y(a,b)?b:a}function Qb(a,b){return 0>y(a,b)?a:b}function Ud(a){a.state.focused||(a.display.input.focus(),xc(a))}function Rb(a){return a.options.readOnly||a.doc.cantEdit}function Sc(a,b,c,d,e){var f=a.doc;a.display.shift=!1;d||(d=f.sel);var g=sa(b),h=null;a.state.pasteIncoming&&1<d.ranges.length&&(X&&X.join("\n")==b?h=0==d.ranges.length%X.length&&ob(X,sa):g.length==d.ranges.length&&
+(h=ob(g,function(a){return[a]})));for(var k=d.ranges.length-1;0<=k;k--){var l=d.ranges[k],m=l.from(),p=l.to();l.empty()&&(c&&0<c?m=r(m.line,m.ch-c):a.state.overwrite&&!a.state.pasteIncoming&&(p=r(p.line,Math.min(u(f,p.line).text.length,p.ch+A(g).length))));var n=a.curOp.updateInput,m={from:m,to:p,text:h?h[k%h.length]:g,origin:e||(a.state.pasteIncoming?"paste":a.state.cutIncoming?"cut":"+input")};Oa(a.doc,m);L(a,"inputRead",a,m);if(b&&!a.state.pasteIncoming&&a.options.electricChars&&a.options.smartIndent&&
+100>l.head.ch&&(!k||d.ranges[k-1].head.line!=l.head.line)){l=a.getModeAt(l.head);m=ta(m);p=!1;if(l.electricChars)for(var E=0;E<l.electricChars.length;E++){if(-1<b.indexOf(l.electricChars.charAt(E))){p=pb(a,m.line,"smart");break}}else l.electricInput&&l.electricInput.test(u(f,m.line).text.slice(0,m.ch))&&(p=pb(a,m.line,"smart"));p&&L(a,"electricInput",a,m.line)}}Pa(a);a.curOp.updateInput=n;a.curOp.typing=!0;a.state.pasteIncoming=a.state.cutIncoming=!1}function Vd(a){for(var b=[],c=[],d=0;d<a.doc.sel.ranges.length;d++){var e=
+a.doc.sel.ranges[d].head.line,e={anchor:r(e,0),head:r(e+1,0)};c.push(e);b.push(a.getRange(e.anchor,e.head))}return{text:b,ranges:c}}function Wd(a){a.setAttribute("autocorrect","off");a.setAttribute("autocapitalize","off");a.setAttribute("spellcheck","false")}function Tc(a){this.cm=a;this.prevInput="";this.pollingFast=!1;this.polling=new bb;this.hasSelection=this.inaccurateSelection=!1;this.composing=null}function Xd(){var a=t("textarea",null,null,"position: absolute; padding: 0; width: 1px; height: 1em; outline: none"),
+b=t("div",[a],null,"overflow: hidden; position: relative; width: 3px; height: 0px;");J?a.style.width="1000px":a.setAttribute("wrap","off");Qa&&(a.style.border="1px solid black");Wd(a);return b}function Uc(a){this.cm=a;this.lastAnchorNode=this.lastAnchorOffset=this.lastFocusNode=this.lastFocusOffset=null;this.polling=new bb;this.gracePeriod=!1}function Yd(a,b){var c=Vc(a,b.line);if(!c||c.hidden)return null;var d=u(a.doc,b.line),c=Zd(c,d,b.line);(d=Y(d))&&Sb(d,b.ch);d=$d(c.map,b.ch,"left");d.offset=
+"right"==d.collapse?d.end:d.start;return d}function Ra(a,b){b&&(a.bad=!0);return a}function Tb(a,b,c){var d;if(b==a.display.lineDiv){d=a.display.lineDiv.childNodes[c];if(!d)return Ra(a.clipPos(r(a.display.viewTo-1)),!0);b=null;c=0}else for(d=b;;d=d.parentNode){if(!d||d==a.display.lineDiv)return null;if(d.parentNode&&d.parentNode==a.display.lineDiv)break}for(var e=0;e<a.display.view.length;e++){var f=a.display.view[e];if(f.node==d)return wf(f,b,c)}}function wf(a,b,c){function d(b,c,d){for(var e=-1;e<
+(l?l.length:0);e++)for(var f=0>e?k.map:l[e],g=0;g<f.length;g+=3){var h=f[g+2];if(h==b||h==c){c=F(0>e?a.line:a.rest[e]);e=f[g]+d;if(0>d||h!=b)e=f[g+(d?1:0)];return r(c,e)}}}var e=a.text.firstChild,f=!1;if(!b||!Wc(e,b))return Ra(r(F(a.line),0),!0);if(b==e&&(f=!0,b=e.childNodes[c],c=0,!b))return c=a.rest?A(a.rest):a.line,Ra(r(F(c),c.text.length),f);var g=3==b.nodeType?b:null,h=b;g||1!=b.childNodes.length||3!=b.firstChild.nodeType||(g=b.firstChild,c&&(c=g.nodeValue.length));for(;h.parentNode!=e;)h=h.parentNode;
+var k=a.measure,l=k.maps;if(b=d(g,h,c))return Ra(b,f);e=h.nextSibling;for(g=g?g.nodeValue.length-c:0;e;e=e.nextSibling){if(b=d(e,e.firstChild,0))return Ra(r(b.line,b.ch-g),f);g+=e.textContent.length}h=h.previousSibling;for(g=c;h;h=h.previousSibling){if(b=d(h,h.firstChild,-1))return Ra(r(b.line,b.ch+g),f);g+=e.textContent.length}}function xf(a,b,c,d,e){function f(a){return function(b){return b.id==a}}function g(b){if(1==b.nodeType){var c=b.getAttribute("cm-text");if(null!=c)""==c&&(c=b.textContent.replace(/\u200b/g,
+"")),h+=c;else{var c=b.getAttribute("cm-marker"),p;if(c)b=a.findMarks(r(d,0),r(e+1,0),f(+c)),b.length&&(p=b[0].find())&&(h+=Da(a.doc,p.from,p.to).join("\n"));else if("false"!=b.getAttribute("contenteditable")){for(p=0;p<b.childNodes.length;p++)g(b.childNodes[p]);/^(pre|div|p)$/i.test(b.nodeName)&&(k=!0)}}}else 3==b.nodeType&&(b=b.nodeValue)&&(k&&(h+="\n",k=!1),h+=b)}for(var h="",k=!1;;){g(b);if(b==c)break;b=b.nextSibling}return h}function la(a,b){this.ranges=a;this.primIndex=b}function z(a,b){this.anchor=
+a;this.head=b}function Z(a,b){var c=a[b];a.sort(function(a,b){return y(a.from(),b.from())});b=D(a,c);for(c=1;c<a.length;c++){var d=a[c],e=a[c-1];if(0<=y(e.to(),d.from())){var f=Qb(e.from(),d.from()),g=Pb(e.to(),d.to()),d=e.empty()?d.from()==d.head:e.from()==e.head;c<=b&&--b;a.splice(--c,2,new z(d?g:f,d?f:g))}}return new la(a,b)}function ga(a,b){return new la([new z(a,b||a)],0)}function w(a,b){if(b.line<a.first)return r(a.first,0);var c=a.first+a.size-1;if(b.line>c)return r(c,u(a,c).text.length);var c=
+u(a,b.line).text.length,d=b.ch,c=null==d||d>c?r(b.line,c):0>d?r(b.line,0):b;return c}function qb(a,b){return b>=a.first&&b<a.first+a.size}function rb(a,b,c,d){return a.cm&&a.cm.display.shift||a.extend?(a=b.anchor,d&&(b=0>y(c,a),b!=0>y(d,a)?(a=c,c=d):b!=0>y(c,d)&&(c=d)),new z(a,c)):new z(d||c,c)}function Ub(a,b,c,d){H(a,new la([rb(a,a.sel.primary(),b,c)],0),d)}function ae(a,b,c){for(var d=[],e=0;e<a.sel.ranges.length;e++)d[e]=rb(a,a.sel.ranges[e],b[e],null);b=Z(d,a.sel.primIndex);H(a,b,c)}function Xc(a,
+b,c,d){var e=a.sel.ranges.slice(0);e[b]=c;H(a,Z(e,a.sel.primIndex),d)}function yf(a,b){var c={ranges:b.ranges,update:function(b){this.ranges=[];for(var c=0;c<b.length;c++)this.ranges[c]=new z(w(a,b[c].anchor),w(a,b[c].head))}};K(a,"beforeSelectionChange",a,c);a.cm&&K(a.cm,"beforeSelectionChange",a.cm,c);return c.ranges!=b.ranges?Z(c.ranges,c.ranges.length-1):b}function be(a,b,c){var d=a.history.done,e=A(d);e&&e.ranges?(d[d.length-1]=b,Vb(a,b,c)):H(a,b,c)}function H(a,b,c){Vb(a,b,c);b=a.sel;var d=
+a.cm?a.cm.curOp.id:NaN,e=a.history,f=c&&c.origin,g;if(!(g=d==e.lastSelOp)&&(g=f&&e.lastSelOrigin==f)&&!(g=e.lastModTime==e.lastSelTime&&e.lastOrigin==f)){g=A(e.done);var h=f.charAt(0);g="*"==h||"+"==h&&g.ranges.length==b.ranges.length&&g.somethingSelected()==b.somethingSelected()&&new Date-a.history.lastSelTime<=(a.cm?a.cm.options.historyEventDelay:500)}g?e.done[e.done.length-1]=b:Wb(b,e.done);e.lastSelTime=+new Date;e.lastSelOrigin=f;e.lastSelOp=d;c&&!1!==c.clearRedo&&ce(e.undone)}function Vb(a,
+b,c){if(S(a,"beforeSelectionChange")||a.cm&&S(a.cm,"beforeSelectionChange"))b=yf(a,b);var d=c&&c.bias||(0>y(b.primary().head,a.sel.primary().head)?-1:1);de(a,ee(a,b,d,!0));c&&!1===c.scroll||!a.cm||Pa(a.cm)}function de(a,b){b.equals(a.sel)||(a.sel=b,a.cm&&(a.cm.curOp.updateInput=a.cm.curOp.selectionChanged=!0,fe(a.cm)),L(a,"cursorActivity",a))}function ge(a){de(a,ee(a,a.sel,null,!1),ha)}function ee(a,b,c,d){for(var e,f=0;f<b.ranges.length;f++){var g=b.ranges[f],h=Xb(a,g.anchor,c,d),k=Xb(a,g.head,c,
+d);if(e||h!=g.anchor||k!=g.head)e||(e=b.ranges.slice(0,f)),e[f]=new z(h,k)}return e?Z(e,b.primIndex):b}function Xb(a,b,c,d){var e=!1,f=b,g=c||1;a.cantEdit=!1;a:for(;;){var h=u(a,f.line);if(h.markedSpans)for(var k=0;k<h.markedSpans.length;++k){var l=h.markedSpans[k],m=l.marker;if((null==l.from||(m.inclusiveLeft?l.from<=f.ch:l.from<f.ch))&&(null==l.to||(m.inclusiveRight?l.to>=f.ch:l.to>f.ch))){if(d&&(K(m,"beforeCursorEnter"),m.explicitlyCleared))if(h.markedSpans){--k;continue}else break;if(m.atomic){k=
+m.find(0>g?-1:1);if(0==y(k,f)&&(k.ch+=g,0>k.ch?k=k.line>a.first?w(a,r(k.line-1)):null:k.ch>h.text.length&&(k=k.line<a.first+a.size-1?r(k.line+1,0):null),!k)){if(e){if(!d)return Xb(a,b,c,!0);a.cantEdit=!0;return r(a.first,0)}e=!0;k=b;g=-g}f=k;continue a}}}return f}}function nb(a){a.display.input.showSelection(a.display.input.prepareSelection())}function he(a,b){for(var c=a.doc,d={},e=d.cursors=document.createDocumentFragment(),f=d.selection=document.createDocumentFragment(),g=0;g<c.sel.ranges.length;g++)if(!1!==
+b||g!=c.sel.primIndex){var h=c.sel.ranges[g],k=h.empty();if(k||a.options.showCursorWhenSelecting){var l=a,m=e,p=ma(l,h.head,"div",null,null,!l.options.singleCursorHeightPerLine),n=m.appendChild(t("div"," ","CodeMirror-cursor"));n.style.left=p.left+"px";n.style.top=p.top+"px";n.style.height=Math.max(0,p.bottom-p.top)*l.options.cursorHeight+"px";p.other&&(l=m.appendChild(t("div"," ","CodeMirror-cursor CodeMirror-secondarycursor")),l.style.display="",l.style.left=p.other.left+"px",l.style.top=p.other.top+
+"px",l.style.height=.85*(p.other.bottom-p.other.top)+"px")}k||zf(a,h,f)}return d}function zf(a,b,c){function d(a,b,c,d){0>b&&(b=0);b=Math.round(b);d=Math.round(d);h.appendChild(t("div",null,"CodeMirror-selected","position: absolute; left: "+a+"px; top: "+b+"px; width: "+(null==c?m-a:c)+"px; height: "+(d-b)+"px"))}function e(b,c,e){var f=u(g,b),h=f.text.length,k,p;Af(Y(f),c||0,null==e?h:e,function(g,q,t){var u=Yb(a,r(b,g),"div",f,"left"),v,w;g==q?(v=u,t=w=u.left):(v=Yb(a,r(b,q-1),"div",f,"right"),
+"rtl"==t&&(t=u,u=v,v=t),t=u.left,w=v.right);null==c&&0==g&&(t=l);3<v.top-u.top&&(d(t,u.top,null,u.bottom),t=l,u.bottom<v.top&&d(t,u.bottom,null,v.top));null==e&&q==h&&(w=m);if(!k||u.top<k.top||u.top==k.top&&u.left<k.left)k=u;if(!p||v.bottom>p.bottom||v.bottom==p.bottom&&v.right>p.right)p=v;t<l+1&&(t=l);d(t,v.top,w-t,v.bottom)});return{start:k,end:p}}var f=a.display,g=a.doc,h=document.createDocumentFragment(),k=ie(a.display),l=k.left,m=Math.max(f.sizerWidth,pa(a)-f.sizer.offsetLeft)-k.right,f=b.from();
+b=b.to();if(f.line==b.line)e(f.line,f.ch,b.ch);else{var p=u(g,f.line),k=u(g,b.line),k=ia(p)==ia(k),f=e(f.line,f.ch,k?p.text.length+1:null).end;b=e(b.line,k?0:null,b.ch).start;k&&(f.top<b.top-2?(d(f.right,f.top,null,f.bottom),d(l,b.top,b.left,b.bottom)):d(f.right,f.top,b.left-f.right,f.bottom));f.bottom<b.top&&d(l,f.bottom,null,b.top)}c.appendChild(h)}function Yc(a){if(a.state.focused){var b=a.display;clearInterval(b.blinker);var c=!0;b.cursorDiv.style.visibility="";0<a.options.cursorBlinkRate?b.blinker=
+setInterval(function(){b.cursorDiv.style.visibility=(c=!c)?"":"hidden"},a.options.cursorBlinkRate):0>a.options.cursorBlinkRate&&(b.cursorDiv.style.visibility="hidden")}}function fb(a,b){a.doc.mode.startState&&a.doc.frontier<a.display.viewTo&&a.state.highlight.set(b,cb(Bf,a))}function Bf(a){var b=a.doc;b.frontier<b.first&&(b.frontier=b.first);if(!(b.frontier>=a.display.viewTo)){var c=+new Date+a.options.workTime,d=Sa(b.mode,sb(a,b.frontier)),e=[];b.iter(b.frontier,Math.min(b.first+b.size,a.display.viewTo+
+500),function(f){if(b.frontier>=a.display.viewFrom){var g=f.styles,h=je(a,f,d,!0);f.styles=h.styles;var k=f.styleClasses;(h=h.classes)?f.styleClasses=h:k&&(f.styleClasses=null);k=!g||g.length!=f.styles.length||k!=h&&(!k||!h||k.bgClass!=h.bgClass||k.textClass!=h.textClass);for(h=0;!k&&h<g.length;++h)k=g[h]!=f.styles[h];k&&e.push(b.frontier);f.stateAfter=Sa(b.mode,d)}else Zc(a,f.text,d),f.stateAfter=0==b.frontier%5?Sa(b.mode,d):null;++b.frontier;if(+new Date>c)return fb(a,a.options.workDelay),!0});
+e.length&&T(a,function(){for(var b=0;b<e.length;b++)na(a,e[b],"text")})}}function Cf(a,b,c){for(var d,e,f=a.doc,g=c?-1:b-(a.doc.mode.innerMode?1E3:100);b>g;--b){if(b<=f.first)return f.first;var h=u(f,b-1);if(h.stateAfter&&(!c||b<=f.frontier))return b;h=aa(h.text,null,a.options.tabSize);if(null==e||d>h)e=b-1,d=h}return e}function sb(a,b,c){var d=a.doc,e=a.display;if(!d.mode.startState)return!0;var f=Cf(a,b,c),g=f>d.first&&u(d,f-1).stateAfter,g=g?Sa(d.mode,g):Df(d.mode);d.iter(f,b,function(c){Zc(a,
+c.text,g);c.stateAfter=f==b-1||0==f%5||f>=e.viewFrom&&f<e.viewTo?Sa(d.mode,g):null;++f});c&&(d.frontier=f);return g}function Ec(a){return a.mover.offsetHeight-a.lineSpace.offsetHeight}function ie(a){if(a.cachedPaddingH)return a.cachedPaddingH;var b=U(a.measure,t("pre","x")),b=window.getComputedStyle?window.getComputedStyle(b):b.currentStyle,b={left:parseInt(b.paddingLeft),right:parseInt(b.paddingRight)};isNaN(b.left)||isNaN(b.right)||(a.cachedPaddingH=b);return b}function da(a){return Hd-a.display.nativeBarWidth}
+function pa(a){return a.display.scroller.clientWidth-da(a)-a.display.barWidth}function Nc(a){return a.display.scroller.clientHeight-da(a)-a.display.barHeight}function Zd(a,b,c){if(a.line==b)return{map:a.measure.map,cache:a.measure.cache};for(var d=0;d<a.rest.length;d++)if(a.rest[d]==b)return{map:a.measure.maps[d],cache:a.measure.caches[d]};for(d=0;d<a.rest.length;d++)if(F(a.rest[d])>c)return{map:a.measure.maps[d],cache:a.measure.caches[d],before:!0}}function Vc(a,b){if(b>=a.display.viewFrom&&b<a.display.viewTo)return a.display.view[Ca(a,
+b)];var c=a.display.externalMeasured;if(c&&b>=c.lineN&&b<c.lineN+c.size)return c}function Zb(a,b){var c=F(b),d=Vc(a,c);d&&!d.text?d=null:d&&d.changes&&Od(a,d,c,Kc(a));if(!d){var e;e=ia(b);d=F(e);e=a.display.externalMeasured=new ke(a.doc,e,d);e.lineN=d;d=e.built=Sd(a,e);e.text=d.pre;U(a.display.lineMeasure,d.pre);d=e}c=Zd(d,b,c);return{line:b,view:d,rect:null,map:c.map,cache:c.cache,before:c.before,hasHeights:!1}}function $c(a,b,c,d,e){b.before&&(c=-1);var f=c+(d||"");if(b.cache.hasOwnProperty(f))a=
+b.cache[f];else{b.rect||(b.rect=b.view.text.getBoundingClientRect());if(!b.hasHeights){var g=b.view,h=b.rect,k=a.options.lineWrapping,l=k&&pa(a);if(!g.measure.heights||k&&g.measure.width!=l){var m=g.measure.heights=[];if(k)for(g.measure.width=l,g=g.text.firstChild.getClientRects(),k=0;k<g.length-1;k++){var l=g[k],p=g[k+1];2<Math.abs(l.bottom-p.bottom)&&m.push((l.bottom+p.top)/2-h.top)}m.push(h.bottom-h.top)}b.hasHeights=!0}g=d;k=$d(b.map,c,g);d=k.node;h=k.start;l=k.end;c=k.collapse;var n;if(3==d.nodeType){for(m=
+0;4>m;m++){for(;h&&tb(b.line.text.charAt(k.coverStart+h));)--h;for(;k.coverStart+l<k.coverEnd&&tb(b.line.text.charAt(k.coverStart+l));)++l;if(B&&9>C&&0==h&&l==k.coverEnd-k.coverStart)n=d.parentNode.getBoundingClientRect();else if(B&&a.options.lineWrapping){var E=Ea(d,h,l).getClientRects();n=E.length?E["right"==g?E.length-1:0]:ad}else n=Ea(d,h,l).getBoundingClientRect()||ad;if(n.left||n.right||0==h)break;l=h;--h;c="right"}B&&11>C&&((E=!window.screen||null==screen.logicalXDPI||screen.logicalXDPI==screen.deviceXDPI)||
+(null!=bd?E=bd:(m=U(a.display.measure,t("span","x")),E=m.getBoundingClientRect(),m=Ea(m,0,1).getBoundingClientRect(),E=bd=1<Math.abs(E.left-m.left)),E=!E),E||(E=screen.logicalXDPI/screen.deviceXDPI,m=screen.logicalYDPI/screen.deviceYDPI,n={left:n.left*E,right:n.right*E,top:n.top*m,bottom:n.bottom*m}))}else 0<h&&(c=g="right"),n=a.options.lineWrapping&&1<(E=d.getClientRects()).length?E["right"==g?E.length-1:0]:d.getBoundingClientRect();!(B&&9>C)||h||n&&(n.left||n.right)||(n=(n=d.parentNode.getClientRects()[0])?
+{left:n.left,right:n.left+gb(a.display),top:n.top,bottom:n.bottom}:ad);E=n.top-b.rect.top;d=n.bottom-b.rect.top;h=(E+d)/2;g=b.view.measure.heights;for(m=0;m<g.length-1&&!(h<g[m]);m++);c={left:("right"==c?n.right:n.left)-b.rect.left,right:("left"==c?n.left:n.right)-b.rect.left,top:m?g[m-1]:0,bottom:g[m]};n.left||n.right||(c.bogus=!0);a.options.singleCursorHeightPerLine||(c.rtop=E,c.rbottom=d);a=c;a.bogus||(b.cache[f]=a)}return{left:a.left,right:a.right,top:e?a.rtop:a.top,bottom:e?a.rbottom:a.bottom}}
+function $d(a,b,c){for(var d,e,f,g,h=0;h<a.length;h+=3){var k=a[h],l=a[h+1];if(b<k)e=0,f=1,g="left";else if(b<l)e=b-k,f=e+1;else if(h==a.length-3||b==l&&a[h+3]>b)f=l-k,e=f-1,b>=l&&(g="right");if(null!=e){d=a[h+2];k==l&&c==(d.insertLeft?"left":"right")&&(g=c);if("left"==c&&0==e)for(;h&&a[h-2]==a[h-3]&&a[h-1].insertLeft;)d=a[(h-=3)+2],g="left";if("right"==c&&e==l-k)for(;h<a.length-3&&a[h+3]==a[h+4]&&!a[h+5].insertLeft;)d=a[(h+=3)+2],g="right";break}}return{node:d,start:e,end:f,collapse:g,coverStart:k,
+coverEnd:l}}function le(a){if(a.measure&&(a.measure.cache={},a.measure.heights=null,a.rest))for(var b=0;b<a.rest.length;b++)a.measure.caches[b]={}}function me(a){a.display.externalMeasure=null;za(a.display.lineMeasure);for(var b=0;b<a.display.view.length;b++)le(a.display.view[b])}function hb(a){me(a);a.display.cachedCharWidth=a.display.cachedTextHeight=a.display.cachedPaddingH=null;a.options.lineWrapping||(a.display.maxLineChanged=!0);a.display.lineNumChars=null}function cd(a,b,c,d){if(b.widgets)for(var e=
+0;e<b.widgets.length;++e)if(b.widgets[e].above){var f=ub(b.widgets[e]);c.top+=f;c.bottom+=f}if("line"==d)return c;d||(d="local");b=ea(b);b="local"==d?b+a.display.lineSpace.offsetTop:b-a.display.viewOffset;if("page"==d||"window"==d)a=a.display.lineSpace.getBoundingClientRect(),b+=a.top+("window"==d?0:window.pageYOffset||(document.documentElement||document.body).scrollTop),d=a.left+("window"==d?0:window.pageXOffset||(document.documentElement||document.body).scrollLeft),c.left+=d,c.right+=d;c.top+=b;
+c.bottom+=b;return c}function ne(a,b,c){if("div"==c)return b;var d=b.left;b=b.top;"page"==c?(d-=window.pageXOffset||(document.documentElement||document.body).scrollLeft,b-=window.pageYOffset||(document.documentElement||document.body).scrollTop):"local"!=c&&c||(c=a.display.sizer.getBoundingClientRect(),d+=c.left,b+=c.top);a=a.display.lineSpace.getBoundingClientRect();return{left:d-a.left,top:b-a.top}}function Yb(a,b,c,d,e){d||(d=u(a.doc,b.line));var f=d;b=b.ch;d=$c(a,Zb(a,d),b,e);return cd(a,f,d,c)}
+function ma(a,b,c,d,e,f){function g(b,g){var h=$c(a,e,b,g?"right":"left",f);g?h.left=h.right:h.right=h.left;return cd(a,d,h,c)}function h(a,b){var c=k[b],d=c.level%2;a==dd(c)&&b&&c.level<k[b-1].level?(c=k[--b],a=ed(c)-(c.level%2?0:1),d=!0):a==ed(c)&&b<k.length-1&&c.level<k[b+1].level&&(c=k[++b],a=dd(c)-c.level%2,d=!1);return d&&a==c.to&&a>c.from?g(a-1):g(a,d)}d=d||u(a.doc,b.line);e||(e=Zb(a,d));var k=Y(d);b=b.ch;if(!k)return g(b);var l=Sb(k,b),l=h(b,l);null!=vb&&(l.other=h(b,vb));return l}function oe(a,
+b){var c=0;b=w(a.doc,b);a.options.lineWrapping||(c=gb(a.display)*b.ch);var d=u(a.doc,b.line),e=ea(d)+a.display.lineSpace.offsetTop;return{left:c,right:c,top:e,bottom:e+d.height}}function $b(a,b,c,d){a=r(a,b);a.xRel=d;c&&(a.outside=!0);return a}function fd(a,b,c){var d=a.doc;c+=a.display.viewOffset;if(0>c)return $b(d.first,0,!0,-1);var e=Ba(d,c),f=d.first+d.size-1;if(e>f)return $b(d.first+d.size-1,u(d,f).text.length,!0,1);0>b&&(b=0);for(d=u(d,e);;)if(e=Ef(a,d,e,b,c),f=(d=Aa(d,!1))&&d.find(0,!0),d&&
+(e.ch>f.from.ch||e.ch==f.from.ch&&0<e.xRel))e=F(d=f.to.line);else return e}function Ef(a,b,c,d,e){function f(d){d=ma(a,r(c,d),"line",b,l);h=!0;if(g>d.bottom)return d.left-k;if(g<d.top)return d.left+k;h=!1;return d.left}var g=e-ea(b),h=!1,k=2*a.display.wrapper.clientWidth,l=Zb(a,b),m=Y(b),p=b.text.length;e=ac(b);var n=bc(b),E=f(e),q=h,t=f(n),u=h;if(d>t)return $b(c,n,u,1);for(;;){if(m?n==e||n==gd(b,e,1):1>=n-e){m=d<E||d-E<=t-d?e:n;for(d-=m==e?E:t;tb(b.text.charAt(m));)++m;return $b(c,m,m==e?q:u,-1>
+d?-1:1<d?1:0)}var v=Math.ceil(p/2),w=e+v;if(m)for(var w=e,x=0;x<v;++x)w=gd(b,w,1);x=f(w);if(x>d){n=w;t=x;if(u=h)t+=1E3;p=v}else e=w,E=x,q=h,p-=v}}function xa(a){if(null!=a.cachedTextHeight)return a.cachedTextHeight;if(null==Fa){Fa=t("pre");for(var b=0;49>b;++b)Fa.appendChild(document.createTextNode("x")),Fa.appendChild(t("br"));Fa.appendChild(document.createTextNode("x"))}U(a.measure,Fa);b=Fa.offsetHeight/50;3<b&&(a.cachedTextHeight=b);za(a.measure);return b||1}function gb(a){if(null!=a.cachedCharWidth)return a.cachedCharWidth;
+var b=t("span","xxxxxxxxxx"),c=t("pre",[b]);U(a.measure,c);b=b.getBoundingClientRect();b=(b.right-b.left)/10;2<b&&(a.cachedCharWidth=b);return b||10}function Ja(a){a.curOp={cm:a,viewChanged:!1,startHeight:a.doc.height,forceUpdate:!1,updateInput:null,typing:!1,changeObjs:null,cursorActivityHandlers:null,cursorActivityCalled:0,selectionChanged:!1,updateMaxLine:!1,scrollLeft:null,scrollTop:null,scrollToPos:null,focus:!1,id:++Ff};Ta?Ta.ops.push(a.curOp):a.curOp.ownsGroup=Ta={ops:[a.curOp],delayedCallbacks:[]}}
+function La(a){if(a=a.curOp.ownsGroup)try{var b=a.delayedCallbacks,c=0;do{for(;c<b.length;c++)b[c]();for(var d=0;d<a.ops.length;d++){var e=a.ops[d];if(e.cursorActivityHandlers)for(;e.cursorActivityCalled<e.cursorActivityHandlers.length;)e.cursorActivityHandlers[e.cursorActivityCalled++](e.cm)}}while(c<b.length)}finally{Ta=null;for(b=0;b<a.ops.length;b++)a.ops[b].cm.curOp=null;a=a.ops;for(b=0;b<a.length;b++){var e=a[b],c=e.cm,f=d=c.display;!f.scrollbarsClipped&&f.scroller.offsetWidth&&(f.nativeBarWidth=
+f.scroller.offsetWidth-f.scroller.clientWidth,f.heightForcer.style.height=da(c)+"px",f.sizer.style.marginBottom=-f.nativeBarWidth+"px",f.sizer.style.borderRightWidth=da(c)+"px",f.scrollbarsClipped=!0);e.updateMaxLine&&Dc(c);e.mustUpdate=e.viewChanged||e.forceUpdate||null!=e.scrollTop||e.scrollToPos&&(e.scrollToPos.from.line<d.viewFrom||e.scrollToPos.to.line>=d.viewTo)||d.maxLineChanged&&c.options.lineWrapping;e.update=e.mustUpdate&&new Mb(c,e.mustUpdate&&{top:e.scrollTop,ensure:e.scrollToPos},e.forceUpdate)}for(b=
+0;b<a.length;b++)e=a[b],e.updatedDisplay=e.mustUpdate&&Lc(e.cm,e.update);for(b=0;b<a.length;b++)if(e=a[b],c=e.cm,d=c.display,e.updatedDisplay&&Lb(c),e.barMeasure=jb(c),d.maxLineChanged&&!c.options.lineWrapping&&(f=void 0,f=d.maxLine.text.length,f=$c(c,Zb(c,d.maxLine),f,void 0),e.adjustWidthTo=f.left+3,c.display.sizerWidth=e.adjustWidthTo,e.barMeasure.scrollWidth=Math.max(d.scroller.clientWidth,d.sizer.offsetLeft+e.adjustWidthTo+da(c)+c.display.barWidth),e.maxScrollLeft=Math.max(0,d.sizer.offsetLeft+
+e.adjustWidthTo-pa(c))),e.updatedDisplay||e.selectionChanged)e.preparedSelection=d.input.prepareSelection();for(b=0;b<a.length;b++)e=a[b],c=e.cm,null!=e.adjustWidthTo&&(c.display.sizer.style.minWidth=e.adjustWidthTo+"px",e.maxScrollLeft<c.doc.scrollLeft&&Ma(c,Math.min(c.display.scroller.scrollLeft,e.maxScrollLeft),!0),c.display.maxLineChanged=!1),e.preparedSelection&&c.display.input.showSelection(e.preparedSelection),e.updatedDisplay&&Oc(c,e.barMeasure),(e.updatedDisplay||e.startHeight!=c.doc.height)&&
+Na(c,e.barMeasure),e.selectionChanged&&Yc(c),c.state.focused&&e.updateInput&&c.display.input.reset(e.typing),e.focus&&e.focus==fa()&&Ud(e.cm);for(b=0;b<a.length;b++){e=a[b];c=e.cm;d=c.display;f=c.doc;e.updatedDisplay&&Md(c,e.update);null==d.wheelStartX||null==e.scrollTop&&null==e.scrollLeft&&!e.scrollToPos||(d.wheelStartX=d.wheelStartY=null);null==e.scrollTop||d.scroller.scrollTop==e.scrollTop&&!e.forceScroll||(f.scrollTop=Math.max(0,Math.min(d.scroller.scrollHeight-d.scroller.clientHeight,e.scrollTop)),
+d.scrollbars.setScrollTop(f.scrollTop),d.scroller.scrollTop=f.scrollTop);null==e.scrollLeft||d.scroller.scrollLeft==e.scrollLeft&&!e.forceScroll||(f.scrollLeft=Math.max(0,Math.min(d.scroller.scrollWidth-pa(c),e.scrollLeft)),d.scrollbars.setScrollLeft(f.scrollLeft),d.scroller.scrollLeft=f.scrollLeft,Bc(c));if(e.scrollToPos){var g=void 0,h=w(f,e.scrollToPos.from),g=w(f,e.scrollToPos.to),k=e.scrollToPos.margin;null==k&&(k=0);for(var l=0;5>l;l++){var m=!1,p=ma(c,h),n=g&&g!=h?ma(c,g):p,n=cc(c,Math.min(p.left,
+n.left),Math.min(p.top,n.top)-k,Math.max(p.left,n.left),Math.max(p.bottom,n.bottom)+k),q=c.doc.scrollTop,r=c.doc.scrollLeft;null!=n.scrollTop&&(lb(c,n.scrollTop),1<Math.abs(c.doc.scrollTop-q)&&(m=!0));null!=n.scrollLeft&&(Ma(c,n.scrollLeft),1<Math.abs(c.doc.scrollLeft-r)&&(m=!0));if(!m)break}g=p;e.scrollToPos.isCursor&&c.state.focused&&(ja(c,"scrollCursorIntoView")||(k=c.display,l=k.sizer.getBoundingClientRect(),h=null,0>g.top+l.top?h=!0:g.bottom+l.top>(window.innerHeight||document.documentElement.clientHeight)&&
+(h=!1),null==h||Gf||(g=t("div","​",null,"position: absolute; top: "+(g.top-k.viewOffset-c.display.lineSpace.offsetTop)+"px; height: "+(g.bottom-g.top+da(c)+k.barHeight)+"px; left: "+g.left+"px; width: 2px;"),c.display.lineSpace.appendChild(g),g.scrollIntoView(h),c.display.lineSpace.removeChild(g))))}h=e.maybeHiddenMarkers;g=e.maybeUnhiddenMarkers;if(h)for(k=0;k<h.length;++k)h[k].lines.length||K(h[k],"hide");if(g)for(k=0;k<g.length;++k)g[k].lines.length&&K(g[k],"unhide");d.wrapper.offsetHeight&&(f.scrollTop=
+c.display.scroller.scrollTop);e.changeObjs&&K(c,"changes",c,e.changeObjs);e.update&&e.update.finish()}}}function T(a,b){if(a.curOp)return b();Ja(a);try{return b()}finally{La(a)}}function G(a,b){return function(){if(a.curOp)return b.apply(a,arguments);Ja(a);try{return b.apply(a,arguments)}finally{La(a)}}}function M(a){return function(){if(this.curOp)return a.apply(this,arguments);Ja(this);try{return a.apply(this,arguments)}finally{La(this)}}}function N(a){return function(){var b=this.cm;if(!b||b.curOp)return a.apply(this,
+arguments);Ja(b);try{return a.apply(this,arguments)}finally{La(b)}}}function ke(a,b,c){for(var d=this.line=b,e;d=Aa(d,!1);)d=d.find(1,!0).line,(e||(e=[])).push(d);this.size=(this.rest=e)?F(A(this.rest))-c+1:1;this.node=this.text=null;this.hidden=ya(a,b)}function Nb(a,b,c){var d=[],e;for(e=b;e<c;)b=new ke(a.doc,u(a.doc,e),e),e+=b.size,d.push(b);return d}function Q(a,b,c,d){null==b&&(b=a.doc.first);null==c&&(c=a.doc.first+a.doc.size);d||(d=0);var e=a.display;d&&c<e.viewTo&&(null==e.updateLineNumbers||
+e.updateLineNumbers>b)&&(e.updateLineNumbers=b);a.curOp.viewChanged=!0;if(b>=e.viewTo)ra&&Mc(a.doc,b)<e.viewTo&&qa(a);else if(c<=e.viewFrom)ra&&Ld(a.doc,c+d)>e.viewFrom?qa(a):(e.viewFrom+=d,e.viewTo+=d);else if(b<=e.viewFrom&&c>=e.viewTo)qa(a);else if(b<=e.viewFrom){var f=dc(a,c,c+d,1);f?(e.view=e.view.slice(f.index),e.viewFrom=f.lineN,e.viewTo+=d):qa(a)}else if(c>=e.viewTo)(f=dc(a,b,b,-1))?(e.view=e.view.slice(0,f.index),e.viewTo=f.lineN):qa(a);else{var f=dc(a,b,b,-1),g=dc(a,c,c+d,1);f&&g?(e.view=
+e.view.slice(0,f.index).concat(Nb(a,f.lineN,g.lineN)).concat(e.view.slice(g.index)),e.viewTo+=d):qa(a)}if(a=e.externalMeasured)c<a.lineN?a.lineN+=d:b<a.lineN+a.size&&(e.externalMeasured=null)}function na(a,b,c){a.curOp.viewChanged=!0;var d=a.display,e=a.display.externalMeasured;e&&b>=e.lineN&&b<e.lineN+e.size&&(d.externalMeasured=null);b<d.viewFrom||b>=d.viewTo||(a=d.view[Ca(a,b)],null!=a.node&&(a=a.changes||(a.changes=[]),-1==D(a,c)&&a.push(c)))}function qa(a){a.display.viewFrom=a.display.viewTo=
+a.doc.first;a.display.view=[];a.display.viewOffset=0}function Ca(a,b){if(b>=a.display.viewTo)return null;b-=a.display.viewFrom;if(0>b)return null;for(var c=a.display.view,d=0;d<c.length;d++)if(b-=c[d].size,0>b)return d}function dc(a,b,c,d){var e=Ca(a,b),f=a.display.view;if(!ra||c==a.doc.first+a.doc.size)return{index:e,lineN:c};for(var g=0,h=a.display.viewFrom;g<e;g++)h+=f[g].size;if(h!=b){if(0<d){if(e==f.length-1)return null;b=h+f[e].size-b;e++}else b=h-b;c+=b}for(;Mc(a.doc,c)!=c;){if(e==(0>d?0:f.length-
+1))return null;c+=d*f[e-(0>d?1:0)].size;e+=d}return{index:e,lineN:c}}function Kd(a){a=a.display.view;for(var b=0,c=0;c<a.length;c++){var d=a[c];d.hidden||d.node&&!d.changes||++b}return b}function sf(a){function b(){d.activeTouch&&(e=setTimeout(function(){d.activeTouch=null},1E3),f=d.activeTouch,f.end=+new Date)}function c(a,b){if(null==b.left)return!0;var c=b.left-a.left,d=b.top-a.top;return 400<c*c+d*d}var d=a.display;v(d.scroller,"mousedown",G(a,pe));B&&11>C?v(d.scroller,"dblclick",G(a,function(b){if(!ja(a,
+b)){var c=Ua(a,b);!c||hd(a,b,"gutterClick",!0,L)||oa(a.display,b)||(O(b),b=a.findWordAt(c),Ub(a.doc,b.anchor,b.head))}})):v(d.scroller,"dblclick",function(b){ja(a,b)||O(b)});id||v(d.scroller,"contextmenu",function(b){qe(a,b)});var e,f={end:0};v(d.scroller,"touchstart",function(a){var b;1!=a.touches.length?b=!1:(b=a.touches[0],b=1>=b.radiusX&&1>=b.radiusY);b||(clearTimeout(e),b=+new Date,d.activeTouch={start:b,moved:!1,prev:300>=b-f.end?f:null},1==a.touches.length&&(d.activeTouch.left=a.touches[0].pageX,
+d.activeTouch.top=a.touches[0].pageY))});v(d.scroller,"touchmove",function(){d.activeTouch&&(d.activeTouch.moved=!0)});v(d.scroller,"touchend",function(e){var f=d.activeTouch;if(f&&!oa(d,e)&&null!=f.left&&!f.moved&&300>new Date-f.start){var g=a.coordsChar(d.activeTouch,"page"),f=!f.prev||c(f,f.prev)?new z(g,g):!f.prev.prev||c(f,f.prev.prev)?a.findWordAt(g):new z(r(g.line,0),w(a.doc,r(g.line+1,0)));a.setSelection(f.anchor,f.head);a.focus();O(e)}b()});v(d.scroller,"touchcancel",b);v(d.scroller,"scroll",
+function(){d.scroller.clientHeight&&(lb(a,d.scroller.scrollTop),Ma(a,d.scroller.scrollLeft,!0),K(a,"scroll",a))});v(d.scroller,"mousewheel",function(b){re(a,b)});v(d.scroller,"DOMMouseScroll",function(b){re(a,b)});v(d.wrapper,"scroll",function(){d.wrapper.scrollTop=d.wrapper.scrollLeft=0});d.dragFunctions={simple:function(b){ja(a,b)||jd(b)},start:function(b){if(B&&(!a.state.draggingText||100>+new Date-se))jd(b);else if(!ja(a,b)&&!oa(a.display,b)&&(b.dataTransfer.setData("Text",a.getSelection()),b.dataTransfer.setDragImage&&
+!te)){var c=t("img",null,null,"position: fixed; left: 0; top: 0;");c.src="data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw\x3d\x3d";ba&&(c.width=c.height=1,a.display.wrapper.appendChild(c),c._top=c.offsetTop);b.dataTransfer.setDragImage(c,0,0);ba&&c.parentNode.removeChild(c)}},drop:G(a,Hf)};var g=d.input.getField();v(g,"keyup",function(b){ue.call(a,b)});v(g,"keydown",G(a,ve));v(g,"keypress",G(a,we));v(g,"focus",cb(xc,a));v(g,"blur",cb(db,a))}function If(a){var b=a.display;
+if(b.lastWrapHeight!=b.wrapper.clientHeight||b.lastWrapWidth!=b.wrapper.clientWidth)b.cachedCharWidth=b.cachedTextHeight=b.cachedPaddingH=null,b.scrollbarsClipped=!1,a.setSize()}function oa(a,b){for(var c=b.target||b.srcElement;c!=a.wrapper;c=c.parentNode)if(!c||1==c.nodeType&&"true"==c.getAttribute("cm-ignore-events")||c.parentNode==a.sizer&&c!=a.mover)return!0}function Ua(a,b,c,d){var e=a.display;if(!c&&"true"==(b.target||b.srcElement).getAttribute("cm-not-content"))return null;var f,g;c=e.lineSpace.getBoundingClientRect();
+try{f=b.clientX-c.left,g=b.clientY-c.top}catch(h){return null}b=fd(a,f,g);var k;d&&1==b.xRel&&(k=u(a.doc,b.line).text).length==b.ch&&(d=aa(k,k.length,a.options.tabSize)-k.length,b=r(b.line,Math.max(0,Math.round((f-ie(a.display).left)/gb(a.display))-d)));return b}function pe(a){var b=this.display;if(!(b.activeTouch&&b.input.supportsTouch()||ja(this,a)))if(b.shift=a.shiftKey,oa(b,a))J||(b.scroller.draggable=!1,setTimeout(function(){b.scroller.draggable=!0},100));else if(!hd(this,a,"gutterClick",!0,
+L)){var c=Ua(this,a);window.focus();switch(xe(a)){case 1:c?Jf(this,a,c):(a.target||a.srcElement)==b.scroller&&O(a);break;case 2:J&&(this.state.lastMiddleDown=+new Date);c&&Ub(this.doc,c);setTimeout(function(){b.input.focus()},20);O(a);break;case 3:id?qe(this,a):Kf(this)}}}function Jf(a,b,c){B?setTimeout(cb(Ud,a),0):a.curOp.focus=fa();var d=+new Date,e;ec&&ec.time>d-400&&0==y(ec.pos,c)?e="triple":fc&&fc.time>d-400&&0==y(fc.pos,c)?(e="double",ec={time:d,pos:c}):(e="single",fc={time:d,pos:c});var d=
+a.doc.sel,f=W?b.metaKey:b.ctrlKey,g;a.options.dragDrop&&Lf&&!Rb(a)&&"single"==e&&-1<(g=d.contains(c))&&!d.ranges[g].empty()?Mf(a,b,c,f):Nf(a,b,c,e,f)}function Mf(a,b,c,d){var e=a.display,f=+new Date,g=G(a,function(h){J&&(e.scroller.draggable=!1);a.state.draggingText=!1;ka(document,"mouseup",g);ka(e.scroller,"drop",g);10>Math.abs(b.clientX-h.clientX)+Math.abs(b.clientY-h.clientY)&&(O(h),!d&&+new Date-200<f&&Ub(a.doc,c),J||B&&9==C?setTimeout(function(){document.body.focus();e.input.focus()},20):e.input.focus())});
+J&&(e.scroller.draggable=!0);a.state.draggingText=g;e.scroller.dragDrop&&e.scroller.dragDrop();v(document,"mouseup",g);v(e.scroller,"drop",g)}function Nf(a,b,c,d,e){function f(b){if(0!=y(x,b))if(x=b,"rect"==d){for(var e=[],f=a.options.tabSize,g=aa(u(l,c.line).text,c.ch,f),h=aa(u(l,b.line).text,b.ch,f),k=Math.min(g,h),g=Math.max(g,h),h=Math.min(c.line,b.line),q=Math.min(a.lastLine(),Math.max(c.line,b.line));h<=q;h++){var E=u(l,h).text,t=ye(E,k,f);k==g?e.push(new z(r(h,t),r(h,t))):E.length>t&&e.push(new z(r(h,
+t),r(h,ye(E,g,f))))}e.length||e.push(new z(c,c));H(l,Z(n.ranges.slice(0,p).concat(e),p),{origin:"*mouse",scroll:!1});a.scrollIntoView(b)}else e=m,f=e.anchor,k=b,"single"!=d&&(b="double"==d?a.findWordAt(b):new z(r(b.line,0),w(l,r(b.line+1,0))),0<y(b.anchor,f)?(k=b.head,f=Qb(e.from(),b.anchor)):(k=b.anchor,f=Pb(e.to(),b.head))),e=n.ranges.slice(0),e[p]=new z(w(l,f),k),H(l,Z(e,p),kd)}function g(b){var c=++A,e=Ua(a,b,!0,"rect"==d);if(e)if(0!=y(e,x)){a.curOp.focus=fa();f(e);var h=Hc(k,l);(e.line>=h.to||
+e.line<h.from)&&setTimeout(G(a,function(){A==c&&g(b)}),150)}else{var m=b.clientY<B.top?-20:b.clientY>B.bottom?20:0;m&&setTimeout(G(a,function(){A==c&&(k.scroller.scrollTop+=m,g(b))}),50)}}function h(a){A=Infinity;O(a);k.input.focus();ka(document,"mousemove",F);ka(document,"mouseup",C);l.history.lastSelOrigin=null}var k=a.display,l=a.doc;O(b);var m,p,n=l.sel,q=n.ranges;e&&!b.shiftKey?(p=l.sel.contains(c),m=-1<p?q[p]:new z(c,c)):(m=l.sel.primary(),p=l.sel.primIndex);if(b.altKey)d="rect",e||(m=new z(c,
+c)),c=Ua(a,b,!0,!0),p=-1;else if("double"==d){var t=a.findWordAt(c);m=a.display.shift||l.extend?rb(l,m,t.anchor,t.head):t}else"triple"==d?(t=new z(r(c.line,0),w(l,r(c.line+1,0))),m=a.display.shift||l.extend?rb(l,m,t.anchor,t.head):t):m=rb(l,m,c);e?-1==p?(p=q.length,H(l,Z(q.concat([m]),p),{scroll:!1,origin:"*mouse"})):1<q.length&&q[p].empty()&&"single"==d&&!b.shiftKey?(H(l,Z(q.slice(0,p).concat(q.slice(p+1)),0)),n=l.sel):Xc(l,p,m,kd):(p=0,H(l,new la([m],0),kd),n=l.sel);var x=c,B=k.wrapper.getBoundingClientRect(),
+A=0,F=G(a,function(a){xe(a)?g(a):h(a)}),C=G(a,h);v(document,"mousemove",F);v(document,"mouseup",C)}function hd(a,b,c,d,e){try{var f=b.clientX,g=b.clientY}catch(h){return!1}if(f>=Math.floor(a.display.gutters.getBoundingClientRect().right))return!1;d&&O(b);d=a.display;var k=d.lineDiv.getBoundingClientRect();if(g>k.bottom||!S(a,c))return ld(b);g-=k.top-d.viewOffset;for(k=0;k<a.options.gutters.length;++k){var l=d.gutters.childNodes[k];if(l&&l.getBoundingClientRect().right>=f)return f=Ba(a.doc,g),e(a,
+c,a,f,a.options.gutters[k],b),ld(b)}}function Hf(a){var b=this;if(!ja(b,a)&&!oa(b.display,a)){O(a);B&&(se=+new Date);var c=Ua(b,a,!0),d=a.dataTransfer.files;if(c&&!Rb(b))if(d&&d.length&&window.FileReader&&window.File){var e=d.length,f=Array(e),g=0;a=function(a,d){var h=new FileReader;h.onload=G(b,function(){f[d]=h.result;if(++g==e){c=w(b.doc,c);var a={from:c,to:c,text:sa(f.join("\n")),origin:"paste"};Oa(b.doc,a);be(b.doc,ga(c,ta(a)))}});h.readAsText(a)};for(var h=0;h<e;++h)a(d[h],h)}else if(b.state.draggingText&&
+-1<b.doc.sel.contains(c))b.state.draggingText(a),setTimeout(function(){b.display.input.focus()},20);else try{if(f=a.dataTransfer.getData("Text")){if(b.state.draggingText&&(W?!a.altKey:!a.ctrlKey))var k=b.listSelections();Vb(b.doc,ga(c,c));if(k)for(h=0;h<k.length;++h)wb(b.doc,"",k[h].anchor,k[h].head,"drag");b.replaceSelection(f,"around","paste");b.display.input.focus()}}catch(l){}}}function lb(a,b){2>Math.abs(a.doc.scrollTop-b)||(a.doc.scrollTop=b,wa||Pc(a,{top:b}),a.display.scroller.scrollTop!=b&&
+(a.display.scroller.scrollTop=b),a.display.scrollbars.setScrollTop(b),wa&&Pc(a),fb(a,100))}function Ma(a,b,c){(c?b==a.doc.scrollLeft:2>Math.abs(a.doc.scrollLeft-b))||(b=Math.min(b,a.display.scroller.scrollWidth-a.display.scroller.clientWidth),a.doc.scrollLeft=b,Bc(a),a.display.scroller.scrollLeft!=b&&(a.display.scroller.scrollLeft=b),a.display.scrollbars.setScrollLeft(b))}function re(a,b){var c=ze(b),d=c.x,c=c.y,e=a.display,f=e.scroller;if(d&&f.scrollWidth>f.clientWidth||c&&f.scrollHeight>f.clientHeight){if(c&&
+W&&J){var g=b.target,h=e.view;a:for(;g!=f;g=g.parentNode)for(var k=0;k<h.length;k++)if(h[k].node==g){a.display.currentWheelTarget=g;break a}}!d||wa||ba||null==R?(c&&null!=R&&(g=c*R,h=a.doc.scrollTop,k=h+e.wrapper.clientHeight,0>g?h=Math.max(0,h+g-50):k=Math.min(a.doc.height,k+g+50),Pc(a,{top:h,bottom:k})),20>gc&&(null==e.wheelStartX?(e.wheelStartX=f.scrollLeft,e.wheelStartY=f.scrollTop,e.wheelDX=d,e.wheelDY=c,setTimeout(function(){if(null!=e.wheelStartX){var a=f.scrollLeft-e.wheelStartX,b=f.scrollTop-
+e.wheelStartY,a=b&&e.wheelDY&&b/e.wheelDY||a&&e.wheelDX&&a/e.wheelDX;e.wheelStartX=e.wheelStartY=null;a&&(R=(R*gc+a)/(gc+1),++gc)}},200)):(e.wheelDX+=d,e.wheelDY+=c))):(c&&lb(a,Math.max(0,Math.min(f.scrollTop+c*R,f.scrollHeight-f.clientHeight))),Ma(a,Math.max(0,Math.min(f.scrollLeft+d*R,f.scrollWidth-f.clientWidth))),O(b),e.wheelStartX=null)}}function hc(a,b,c){if("string"==typeof b&&(b=ic[b],!b))return!1;a.display.input.ensurePolled();var d=a.display.shift,e=!1;try{Rb(a)&&(a.state.suppressEdits=
+!0),c&&(a.display.shift=!1),e=b(a)!=Ae}finally{a.display.shift=d,a.state.suppressEdits=!1}return e}function Of(a,b,c){for(var d=0;d<a.state.keyMaps.length;d++){var e=xb(b,a.state.keyMaps[d],c,a);if(e)return e}return a.options.extraKeys&&xb(b,a.options.extraKeys,c,a)||xb(b,a.options.keyMap,c,a)}function jc(a,b,c,d){var e=a.state.keySeq;if(e){if(Pf(b))return"handled";Qf.set(50,function(){a.state.keySeq==e&&(a.state.keySeq=null,a.display.input.reset())});b=e+" "+b}d=Of(a,b,d);"multi"==d&&(a.state.keySeq=
+b);"handled"==d&&L(a,"keyHandled",a,b,c);if("handled"==d||"multi"==d)O(c),Yc(a);return e&&!d&&/\'$/.test(b)?(O(c),!0):!!d}function Be(a,b){var c=Rf(b,!0);return c?b.shiftKey&&!a.state.keySeq?jc(a,"Shift-"+c,b,function(b){return hc(a,b,!0)})||jc(a,c,b,function(b){if("string"==typeof b?/^go[A-Z]/.test(b):b.motion)return hc(a,b)}):jc(a,c,b,function(b){return hc(a,b)}):!1}function Sf(a,b,c){return jc(a,"'"+c+"'",b,function(b){return hc(a,b,!0)})}function ve(a){this.curOp.focus=fa();if(!ja(this,a)){B&&
+11>C&&27==a.keyCode&&(a.returnValue=!1);var b=a.keyCode;this.display.shift=16==b||a.shiftKey;var c=Be(this,a);ba&&(md=c?b:null,!c&&88==b&&!Ce&&(W?a.metaKey:a.ctrlKey)&&this.replaceSelection("",null,"cut"));18!=b||/\bCodeMirror-crosshair\b/.test(this.display.lineDiv.className)||Tf(this)}}function Tf(a){function b(a){18!=a.keyCode&&a.altKey||(kb(c,"CodeMirror-crosshair"),ka(document,"keyup",b),ka(document,"mouseover",b))}var c=a.display.lineDiv;mb(c,"CodeMirror-crosshair");v(document,"keyup",b);v(document,
+"mouseover",b)}function ue(a){16==a.keyCode&&(this.doc.sel.shift=!1);ja(this,a)}function we(a){if(!(oa(this.display,a)||ja(this,a)||a.ctrlKey&&!a.altKey||W&&a.metaKey)){var b=a.keyCode,c=a.charCode;if(ba&&b==md)md=null,O(a);else if(!ba||a.which&&!(10>a.which)||!Be(this,a))if(b=String.fromCharCode(null==c?b:c),!Sf(this,a,b))this.display.input.onKeyPress(a)}}function Kf(a){a.state.delayingBlurEvent=!0;setTimeout(function(){a.state.delayingBlurEvent&&(a.state.delayingBlurEvent=!1,db(a))},100)}function xc(a){a.state.delayingBlurEvent&&
+(a.state.delayingBlurEvent=!1);"nocursor"!=a.options.readOnly&&(a.state.focused||(K(a,"focus",a),a.state.focused=!0,mb(a.display.wrapper,"CodeMirror-focused"),a.curOp||a.display.selForContextMenu==a.doc.sel||(a.display.input.reset(),J&&setTimeout(function(){a.display.input.reset(!0)},20)),a.display.input.receivedFocus()),Yc(a))}function db(a){a.state.delayingBlurEvent||(a.state.focused&&(K(a,"blur",a),a.state.focused=!1,kb(a.display.wrapper,"CodeMirror-focused")),clearInterval(a.display.blinker),
+setTimeout(function(){a.state.focused||(a.display.shift=!1)},150))}function qe(a,b){var c;(c=oa(a.display,b))||(c=S(a,"gutterContextMenu")?hd(a,b,"gutterContextMenu",!1,K):!1);if(!c)a.display.input.onContextMenu(b)}function De(a,b){if(0>y(a,b.from))return a;if(0>=y(a,b.to))return ta(b);var c=a.line+b.text.length-(b.to.line-b.from.line)-1,d=a.ch;a.line==b.to.line&&(d+=ta(b).ch-b.to.ch);return r(c,d)}function nd(a,b){for(var c=[],d=0;d<a.sel.ranges.length;d++){var e=a.sel.ranges[d];c.push(new z(De(e.anchor,
+b),De(e.head,b)))}return Z(c,a.sel.primIndex)}function Ee(a,b,c){return a.line==b.line?r(c.line,a.ch-b.ch+c.ch):r(c.line+(a.line-b.line),a.ch)}function Fe(a,b,c){b={canceled:!1,from:b.from,to:b.to,text:b.text,origin:b.origin,cancel:function(){this.canceled=!0}};c&&(b.update=function(b,c,f,g){b&&(this.from=w(a,b));c&&(this.to=w(a,c));f&&(this.text=f);void 0!==g&&(this.origin=g)});K(a,"beforeChange",a,b);a.cm&&K(a.cm,"beforeChange",a.cm,b);return b.canceled?null:{from:b.from,to:b.to,text:b.text,origin:b.origin}}
+function Oa(a,b,c){if(a.cm){if(!a.cm.curOp)return G(a.cm,Oa)(a,b,c);if(a.cm.state.suppressEdits)return}if(S(a,"beforeChange")||a.cm&&S(a.cm,"beforeChange"))if(b=Fe(a,b,!0),!b)return;if(c=Ge&&!c&&Uf(a,b.from,b.to))for(var d=c.length-1;0<=d;--d)He(a,{from:c[d].from,to:c[d].to,text:d?[""]:b.text});else He(a,b)}function He(a,b){if(1!=b.text.length||""!=b.text[0]||0!=y(b.from,b.to)){var c=nd(a,b);Ie(a,b,c,a.cm?a.cm.curOp.id:NaN);yb(a,b,c,od(a,b));var d=[];Ga(a,function(a,c){c||-1!=D(d,a.history)||(Je(a.history,
+b),d.push(a.history));yb(a,b,null,od(a,b))})}}function kc(a,b,c){if(!a.cm||!a.cm.state.suppressEdits){for(var d=a.history,e,f=a.sel,g="undo"==b?d.done:d.undone,h="undo"==b?d.undone:d.done,k=0;k<g.length&&(e=g[k],c?!e.ranges||e.equals(a.sel):e.ranges);k++);if(k!=g.length){for(d.lastOrigin=d.lastSelOrigin=null;;)if(e=g.pop(),e.ranges){Wb(e,h);if(c&&!e.equals(a.sel)){H(a,e,{clearRedo:!1});return}f=e}else break;c=[];Wb(f,h);h.push({changes:c,generation:d.generation});d.generation=e.generation||++d.maxGeneration;
+d=S(a,"beforeChange")||a.cm&&S(a.cm,"beforeChange");for(k=e.changes.length-1;0<=k;--k){var l=e.changes[k];l.origin=b;if(d&&!Fe(a,l,!1)){g.length=0;break}c.push(pd(a,l));f=k?nd(a,l):A(g);yb(a,l,f,Ke(a,l));!k&&a.cm&&a.cm.scrollIntoView({from:l.from,to:ta(l)});var m=[];Ga(a,function(a,b){b||-1!=D(m,a.history)||(Je(a.history,l),m.push(a.history));yb(a,l,null,Ke(a,l))})}}}}function Le(a,b){if(0!=b&&(a.first+=b,a.sel=new la(ob(a.sel.ranges,function(a){return new z(r(a.anchor.line+b,a.anchor.ch),r(a.head.line+
+b,a.head.ch))}),a.sel.primIndex),a.cm)){Q(a.cm,a.first,a.first-b,b);for(var c=a.cm.display,d=c.viewFrom;d<c.viewTo;d++)na(a.cm,d,"gutter")}}function yb(a,b,c,d){if(a.cm&&!a.cm.curOp)return G(a.cm,yb)(a,b,c,d);if(b.to.line<a.first)Le(a,b.text.length-1-(b.to.line-b.from.line));else if(!(b.from.line>a.lastLine())){if(b.from.line<a.first){var e=b.text.length-1-(a.first-b.from.line);Le(a,e);b={from:r(a.first,0),to:r(b.to.line+e,b.to.ch),text:[A(b.text)],origin:b.origin}}e=a.lastLine();b.to.line>e&&(b=
+{from:b.from,to:r(e,u(a,e).text.length),text:[b.text[0]],origin:b.origin});b.removed=Da(a,b.from,b.to);c||(c=nd(a,b));a.cm?Vf(a.cm,b,d):qd(a,b,d);Vb(a,c,ha)}}function Vf(a,b,c){var d=a.doc,e=a.display,f=b.from,g=b.to,h=!1,k=f.line;a.options.lineWrapping||(k=F(ia(u(d,f.line))),d.iter(k,g.line+1,function(a){if(a==e.maxLine)return h=!0}));-1<d.sel.contains(b.from,b.to)&&fe(a);qd(d,b,c,Id(a));a.options.lineWrapping||(d.iter(k,f.line+b.text.length,function(a){var b=Kb(a);b>e.maxLineLength&&(e.maxLine=
+a,e.maxLineLength=b,e.maxLineChanged=!0,h=!1)}),h&&(a.curOp.updateMaxLine=!0));d.frontier=Math.min(d.frontier,f.line);fb(a,400);c=b.text.length-(g.line-f.line)-1;b.full?Q(a):f.line!=g.line||1!=b.text.length||Me(a.doc,b)?Q(a,f.line,g.line+1,c):na(a,f.line,"text");c=S(a,"changes");if((d=S(a,"change"))||c)b={from:f,to:g,text:b.text,removed:b.removed,origin:b.origin},d&&L(a,"change",a,b),c&&(a.curOp.changeObjs||(a.curOp.changeObjs=[])).push(b);a.display.selForContextMenu=null}function wb(a,b,c,d,e){d||
+(d=c);if(0>y(d,c)){var f=d;d=c;c=f}"string"==typeof b&&(b=sa(b));Oa(a,{from:c,to:d,text:b,origin:e})}function cc(a,b,c,d,e){var f=a.display,g=xa(a.display);0>c&&(c=0);var h=a.curOp&&null!=a.curOp.scrollTop?a.curOp.scrollTop:f.scroller.scrollTop,k=Nc(a),l={};e-c>k&&(e=c+k);var m=a.doc.height+Ec(f),p=c<g,g=e>m-g;c<h?l.scrollTop=p?0:c:e>h+k&&(c=Math.min(c,(g?m:e)-k),c!=h&&(l.scrollTop=c));h=a.curOp&&null!=a.curOp.scrollLeft?a.curOp.scrollLeft:f.scroller.scrollLeft;a=pa(a)-(a.options.fixedGutter?f.gutters.offsetWidth:
+0);(f=d-b>a)&&(d=b+a);10>b?l.scrollLeft=0:b<h?l.scrollLeft=Math.max(0,b-(f?0:10)):d>a+h-3&&(l.scrollLeft=d+(f?0:10)-a);return l}function lc(a,b,c){null==b&&null==c||mc(a);null!=b&&(a.curOp.scrollLeft=(null==a.curOp.scrollLeft?a.doc.scrollLeft:a.curOp.scrollLeft)+b);null!=c&&(a.curOp.scrollTop=(null==a.curOp.scrollTop?a.doc.scrollTop:a.curOp.scrollTop)+c)}function Pa(a){mc(a);var b=a.getCursor(),c=b,d=b;a.options.lineWrapping||(c=b.ch?r(b.line,b.ch-1):b,d=r(b.line,b.ch+1));a.curOp.scrollToPos={from:c,
+to:d,margin:a.options.cursorScrollMargin,isCursor:!0}}function mc(a){var b=a.curOp.scrollToPos;if(b){a.curOp.scrollToPos=null;var c=oe(a,b.from),d=oe(a,b.to),b=cc(a,Math.min(c.left,d.left),Math.min(c.top,d.top)-b.margin,Math.max(c.right,d.right),Math.max(c.bottom,d.bottom)+b.margin);a.scrollTo(b.scrollLeft,b.scrollTop)}}function pb(a,b,c,d){var e=a.doc,f;null==c&&(c="add");"smart"==c&&(e.mode.indent?f=sb(a,b):c="prev");var g=a.options.tabSize,h=u(e,b),k=aa(h.text,null,g);h.stateAfter&&(h.stateAfter=
+null);var l=h.text.match(/^\s*/)[0],m;if(!d&&!/\S/.test(h.text))m=0,c="not";else if("smart"==c&&(m=e.mode.indent(f,h.text.slice(l.length),h.text),m==Ae||150<m)){if(!d)return;c="prev"}"prev"==c?m=b>e.first?aa(u(e,b-1).text,null,g):0:"add"==c?m=k+a.options.indentUnit:"subtract"==c?m=k-a.options.indentUnit:"number"==typeof c&&(m=k+c);m=Math.max(0,m);c="";d=0;if(a.options.indentWithTabs)for(a=Math.floor(m/g);a;--a)d+=g,c+="\t";d<m&&(c+=Ne(m-d));if(c!=l)return wb(e,c,r(b,0),r(b,l.length),"+input"),h.stateAfter=
+null,!0;for(a=0;a<e.sel.ranges.length;a++)if(g=e.sel.ranges[a],g.head.line==b&&g.head.ch<l.length){d=r(b,l.length);Xc(e,a,new z(d,d));break}}function nc(a,b,c,d){var e=b,f=b;"number"==typeof b?f=u(a,Math.max(a.first,Math.min(b,a.first+a.size-1))):e=F(b);if(null==e)return null;d(f,e)&&a.cm&&na(a.cm,e,c);return f}function Va(a,b){for(var c=a.doc.sel.ranges,d=[],e=0;e<c.length;e++){for(var f=b(c[e]);d.length&&0>=y(f.from,A(d).to);){var g=d.pop();if(0>y(g.from,f.from)){f.from=g.from;break}}d.push(f)}T(a,
+function(){for(var b=d.length-1;0<=b;b--)wb(a.doc,"",d[b].from,d[b].to,"+delete");Pa(a)})}function rd(a,b,c,d,e){function f(b){var d=(e?gd:Oe)(l,h,c,!0);if(null==d){if(b=!b)b=g+c,b<a.first||b>=a.first+a.size?b=m=!1:(g=b,b=l=u(a,b));if(b)h=e?(0>c?bc:ac)(l):0>c?l.text.length:0;else return m=!1}else h=d;return!0}var g=b.line,h=b.ch,k=c,l=u(a,g),m=!0;if("char"==d)f();else if("column"==d)f(!0);else if("word"==d||"group"==d){var p=null;d="group"==d;b=a.cm&&a.cm.getHelper(b,"wordChars");for(var n=!0;!(0>
+c)||f(!n);n=!1){var q=l.text.charAt(h)||"\n",q=oc(q,b)?"w":d&&"\n"==q?"n":!d||/\s/.test(q)?null:"p";!d||n||q||(q="s");if(p&&p!=q){0>c&&(c=1,f());break}q&&(p=q);if(0<c&&!f(!n))break}}k=Xb(a,r(g,h),k,!0);m||(k.hitSide=!0);return k}function Pe(a,b,c,d){var e=a.doc,f=b.left,g;"page"==d?(g=Math.min(a.display.wrapper.clientHeight,window.innerHeight||document.documentElement.clientHeight),g=b.top+c*(g-(0>c?1.5:.5)*xa(a.display))):"line"==d&&(g=0<c?b.bottom+3:b.top-3);for(;;){b=fd(a,f,g);if(!b.outside)break;
+if(0>c?0>=g:g>=e.height){b.hitSide=!0;break}g+=5*c}return b}function x(a,b,c,d){q.defaults[a]=b;c&&(Ka[a]=d?function(a,b,d){d!=Fd&&c(a,b,d)}:c)}function Wf(a){var b=a.split(/-(?!$)/);a=b[b.length-1];for(var c,d,e,f,g=0;g<b.length-1;g++){var h=b[g];if(/^(cmd|meta|m)$/i.test(h))f=!0;else if(/^a(lt)?$/i.test(h))c=!0;else if(/^(c|ctrl|control)$/i.test(h))d=!0;else if(/^s(hift)$/i.test(h))e=!0;else throw Error("Unrecognized modifier name: "+h);}c&&(a="Alt-"+a);d&&(a="Ctrl-"+a);f&&(a="Cmd-"+a);e&&(a="Shift-"+
+a);return a}function pc(a){return"string"==typeof a?ua[a]:a}function Wa(a,b,c,d,e){if(d&&d.shared)return Xf(a,b,c,d,e);if(a.cm&&!a.cm.curOp)return G(a.cm,Wa)(a,b,c,d,e);var f=new Ha(a,e);e=y(b,c);d&&V(d,f,!1);if(0<e||0==e&&!1!==f.clearWhenEmpty)return f;f.replacedWith&&(f.collapsed=!0,f.widgetNode=t("span",[f.replacedWith],"CodeMirror-widget"),d.handleMouseEvents||f.widgetNode.setAttribute("cm-ignore-events","true"),d.insertLeft&&(f.widgetNode.insertLeft=!0));if(f.collapsed){if(Qe(a,b.line,b,c,f)||
+b.line!=c.line&&Qe(a,c.line,b,c,f))throw Error("Inserting collapsed marker partially overlapping an existing one");ra=!0}f.addToHistory&&Ie(a,{from:b,to:c,origin:"markText"},a.sel,NaN);var g=b.line,h=a.cm,k;a.iter(g,c.line+1,function(a){h&&f.collapsed&&!h.options.lineWrapping&&ia(a)==h.display.maxLine&&(k=!0);f.collapsed&&g!=b.line&&ca(a,0);var d=new qc(f,g==b.line?b.ch:null,g==c.line?c.ch:null);a.markedSpans=a.markedSpans?a.markedSpans.concat([d]):[d];d.marker.attachLine(a);++g});f.collapsed&&a.iter(b.line,
+c.line+1,function(b){ya(a,b)&&ca(b,0)});f.clearOnEnter&&v(f,"beforeCursorEnter",function(){f.clear()});f.readOnly&&(Ge=!0,(a.history.done.length||a.history.undone.length)&&a.clearHistory());f.collapsed&&(f.id=++sd,f.atomic=!0);if(h){k&&(h.curOp.updateMaxLine=!0);if(f.collapsed)Q(h,b.line,c.line+1);else if(f.className||f.title||f.startStyle||f.endStyle||f.css)for(d=b.line;d<=c.line;d++)na(h,d,"text");f.atomic&&ge(h.doc);L(h,"markerAdded",h,f)}return f}function Xf(a,b,c,d,e){d=V(d);d.shared=!1;var f=
+[Wa(a,b,c,d,e)],g=f[0],h=d.widgetNode;Ga(a,function(a){h&&(d.widgetNode=h.cloneNode(!0));f.push(Wa(a,w(a,b),w(a,c),d,e));for(var l=0;l<a.linked.length;++l)if(a.linked[l].isParent)return;g=A(f)});return new rc(f,g)}function Re(a){return a.findMarks(r(a.first,0),a.clipPos(r(a.lastLine())),function(a){return a.parent})}function Yf(a){for(var b=0;b<a.length;b++){var c=a[b],d=[c.primary.doc];Ga(c.primary.doc,function(a){d.push(a)});for(var e=0;e<c.markers.length;e++){var f=c.markers[e];-1==D(d,f.doc)&&
+(f.parent=null,c.markers.splice(e--,1))}}}function qc(a,b,c){this.marker=a;this.from=b;this.to=c}function zb(a,b){if(a)for(var c=0;c<a.length;++c){var d=a[c];if(d.marker==b)return d}}function od(a,b){if(b.full)return null;var c=qb(a,b.from.line)&&u(a,b.from.line).markedSpans,d=qb(a,b.to.line)&&u(a,b.to.line).markedSpans;if(!c&&!d)return null;var e=b.from.ch,f=b.to.ch,g=0==y(b.from,b.to);if(c)for(var h=0,k;h<c.length;++h){var l=c[h],m=l.marker;if(null==l.from||(m.inclusiveLeft?l.from<=e:l.from<e)||
+!(l.from!=e||"bookmark"!=m.type||g&&l.marker.insertLeft)){var p=null==l.to||(m.inclusiveRight?l.to>=e:l.to>e);(k||(k=[])).push(new qc(m,l.from,p?null:l.to))}}c=k;if(d)for(var h=0,n;h<d.length;++h)if(k=d[h],l=k.marker,null==k.to||(l.inclusiveRight?k.to>=f:k.to>f)||k.from==f&&"bookmark"==l.type&&(!g||k.marker.insertLeft))m=null==k.from||(l.inclusiveLeft?k.from<=f:k.from<f),(n||(n=[])).push(new qc(l,m?null:k.from-f,null==k.to?null:k.to-f));d=n;g=1==b.text.length;n=A(b.text).length+(g?e:0);if(c)for(f=
+0;f<c.length;++f)if(h=c[f],null==h.to)(k=zb(d,h.marker),k)?g&&(h.to=null==k.to?null:k.to+n):h.to=e;if(d)for(f=0;f<d.length;++f)h=d[f],null!=h.to&&(h.to+=n),null==h.from?(k=zb(c,h.marker),k||(h.from=n,g&&(c||(c=[])).push(h))):(h.from+=n,g&&(c||(c=[])).push(h));c&&(c=Se(c));d&&d!=c&&(d=Se(d));e=[c];if(!g){var g=b.text.length-2,q;if(0<g&&c)for(f=0;f<c.length;++f)null==c[f].to&&(q||(q=[])).push(new qc(c[f].marker,null,null));for(f=0;f<g;++f)e.push(q);e.push(d)}return e}function Se(a){for(var b=0;b<a.length;++b){var c=
+a[b];null!=c.from&&c.from==c.to&&!1!==c.marker.clearWhenEmpty&&a.splice(b--,1)}return a.length?a:null}function Ke(a,b){var c;if(c=b["spans_"+a.id]){for(var d=0,e=[];d<b.text.length;++d)e.push(Zf(c[d]));c=e}else c=null;d=od(a,b);if(!c)return d;if(!d)return c;for(e=0;e<c.length;++e){var f=c[e],g=d[e];if(f&&g){var h=0;a:for(;h<g.length;++h){for(var k=g[h],l=0;l<f.length;++l)if(f[l].marker==k.marker)continue a;f.push(k)}}else g&&(c[e]=g)}return c}function Uf(a,b,c){var d=null;a.iter(b.line,c.line+1,function(a){if(a.markedSpans)for(var b=
+0;b<a.markedSpans.length;++b){var c=a.markedSpans[b].marker;!c.readOnly||d&&-1!=D(d,c)||(d||(d=[])).push(c)}});if(!d)return null;a=[{from:b,to:c}];for(b=0;b<d.length;++b){c=d[b];for(var e=c.find(0),f=0;f<a.length;++f){var g=a[f];if(!(0>y(g.to,e.from)||0<y(g.from,e.to))){var h=[f,1],k=y(g.from,e.from),l=y(g.to,e.to);(0>k||!c.inclusiveLeft&&!k)&&h.push({from:g.from,to:e.from});(0<l||!c.inclusiveRight&&!l)&&h.push({from:e.to,to:g.to});a.splice.apply(a,h);f+=h.length-1}}}return a}function Te(a){var b=
+a.markedSpans;if(b){for(var c=0;c<b.length;++c)b[c].marker.detachLine(a);a.markedSpans=null}}function Ue(a,b){if(b){for(var c=0;c<b.length;++c)b[c].marker.attachLine(a);a.markedSpans=b}}function Ve(a,b){var c=a.lines.length-b.lines.length;if(0!=c)return c;var c=a.find(),d=b.find(),e=y(c.from,d.from)||(a.inclusiveLeft?-1:0)-(b.inclusiveLeft?-1:0);return e?-e:(c=y(c.to,d.to)||(a.inclusiveRight?1:0)-(b.inclusiveRight?1:0))?c:b.id-a.id}function Aa(a,b){var c=ra&&a.markedSpans,d;if(c)for(var e,f=0;f<c.length;++f)e=
+c[f],e.marker.collapsed&&null==(b?e.from:e.to)&&(!d||0>Ve(d,e.marker))&&(d=e.marker);return d}function Qe(a,b,c,d,e){a=u(a,b);if(a=ra&&a.markedSpans)for(b=0;b<a.length;++b){var f=a[b];if(f.marker.collapsed){var g=f.marker.find(0),h=y(g.from,c)||(f.marker.inclusiveLeft?-1:0)-(e.inclusiveLeft?-1:0),k=y(g.to,d)||(f.marker.inclusiveRight?1:0)-(e.inclusiveRight?1:0);if(!(0<=h&&0>=k||0>=h&&0<=k)&&(0>=h&&(0<y(g.to,c)||f.marker.inclusiveRight&&e.inclusiveLeft)||0<=h&&(0>y(g.from,d)||f.marker.inclusiveLeft&&
+e.inclusiveRight)))return!0}}}function ia(a){for(var b;b=Aa(a,!0);)a=b.find(-1,!0).line;return a}function Mc(a,b){var c=u(a,b),d=ia(c);return c==d?b:F(d)}function Ld(a,b){if(b>a.lastLine())return b;var c=u(a,b),d;if(!ya(a,c))return b;for(;d=Aa(c,!1);)c=d.find(1,!0).line;return F(c)+1}function ya(a,b){var c=ra&&b.markedSpans;if(c)for(var d,e=0;e<c.length;++e)if(d=c[e],d.marker.collapsed&&(null==d.from||!d.marker.widgetNode&&0==d.from&&d.marker.inclusiveLeft&&td(a,b,d)))return!0}function td(a,b,c){if(null==
+c.to)return b=c.marker.find(1,!0),td(a,b.line,zb(b.line.markedSpans,c.marker));if(c.marker.inclusiveRight&&c.to==b.text.length)return!0;for(var d,e=0;e<b.markedSpans.length;++e)if(d=b.markedSpans[e],d.marker.collapsed&&!d.marker.widgetNode&&d.from==c.to&&(null==d.to||d.to!=c.from)&&(d.marker.inclusiveLeft||c.marker.inclusiveRight)&&td(a,b,d))return!0}function ub(a){if(null!=a.height)return a.height;var b=a.doc.cm;if(!b)return 0;if(!Wc(document.body,a.node)){var c="position: relative;";a.coverGutter&&
+(c+="margin-left: -"+b.display.gutters.offsetWidth+"px;");a.noHScroll&&(c+="width: "+b.display.wrapper.clientWidth+"px;");U(b.display.measure,t("div",[a.node],null,c))}return a.height=a.node.offsetHeight}function $f(a,b,c,d){var e=new sc(a,c,d),f=a.cm;f&&e.noHScroll&&(f.display.alignWidgets=!0);nc(a,b,"widget",function(b){var c=b.widgets||(b.widgets=[]);null==e.insertAt?c.push(e):c.splice(Math.min(c.length-1,Math.max(0,e.insertAt)),0,e);e.line=b;f&&!ya(a,b)&&(c=ea(b)<a.scrollTop,ca(b,b.height+ub(e)),
+c&&lc(f,null,e.height),f.curOp.forceUpdate=!0);return!0});return e}function We(a,b){if(a)for(;;){var c=a.match(/(?:^|\s+)line-(background-)?(\S+)/);if(!c)break;a=a.slice(0,c.index)+a.slice(c.index+c[0].length);var d=c[1]?"bgClass":"textClass";null==b[d]?b[d]=c[2]:(new RegExp("(?:^|s)"+c[2]+"(?:$|s)")).test(b[d])||(b[d]+=" "+c[2])}return a}function Xe(a,b){if(a.blankLine)return a.blankLine(b);if(a.innerMode){var c=q.innerMode(a,b);if(c.mode.blankLine)return c.mode.blankLine(c.state)}}function ud(a,
+b,c,d){for(var e=0;10>e;e++){d&&(d[0]=q.innerMode(a,c).mode);var f=a.token(b,c);if(b.pos>b.start)return f}throw Error("Mode "+a.name+" failed to advance stream.");}function Ye(a,b,c,d){function e(a){return{start:m.start,end:m.pos,string:m.current(),type:h||null,state:a?Sa(f.mode,l):l}}var f=a.doc,g=f.mode,h;b=w(f,b);var k=u(f,b.line),l=sb(a,b.line,c),m=new tc(k.text,a.options.tabSize),p;for(d&&(p=[]);(d||m.pos<b.ch)&&!m.eol();)m.start=m.pos,h=ud(g,m,l),d&&p.push(e(!0));return d?p:e()}function Ze(a,
+b,c,d,e,f,g){var h=c.flattenSpans;null==h&&(h=a.options.flattenSpans);var k=0,l=null,m=new tc(b,a.options.tabSize),p,n=a.options.addModeClass&&[null];for(""==b&&We(Xe(c,d),f);!m.eol();){m.pos>a.options.maxHighlightLength?(h=!1,g&&Zc(a,b,d,m.pos),m.pos=b.length,p=null):p=We(ud(c,m,d,n),f);if(n){var q=n[0].name;q&&(p="m-"+(p?q+" "+p:q))}if(!h||l!=p){for(;k<m.start;)k=Math.min(m.start,k+5E4),e(k,l);l=p}m.start=m.pos}for(;k<m.pos;)a=Math.min(m.pos,k+5E4),e(a,l),k=a}function je(a,b,c,d){var e=[a.state.modeGen],
+f={};Ze(a,b.text,a.doc.mode,c,function(a,b){e.push(a,b)},f,d);for(c=0;c<a.state.overlays.length;++c){var g=a.state.overlays[c],h=1,k=0;Ze(a,b.text,g.mode,!0,function(a,b){for(var c=h;k<a;){var d=e[h];d>a&&e.splice(h,1,a,e[h+1],d);h+=2;k=Math.min(a,d)}if(b)if(g.opaque)e.splice(c,h-c,a,"cm-overlay "+b),h=c+2;else for(;c<h;c+=2)d=e[c+1],e[c+1]=(d?d+" ":"")+"cm-overlay "+b},f)}return{styles:e,classes:f.bgClass||f.textClass?f:null}}function $e(a,b,c){if(!b.styles||b.styles[0]!=a.state.modeGen){var d=je(a,
+b,b.stateAfter=sb(a,F(b)));b.styles=d.styles;d.classes?b.styleClasses=d.classes:b.styleClasses&&(b.styleClasses=null);c===a.doc.frontier&&a.doc.frontier++}return b.styles}function Zc(a,b,c,d){var e=a.doc.mode,f=new tc(b,a.options.tabSize);f.start=f.pos=d||0;for(""==b&&Xe(e,c);!f.eol()&&f.pos<=a.options.maxHighlightLength;)ud(e,f,c),f.start=f.pos}function af(a,b){if(!a||/^\s*$/.test(a))return null;var c=b.addModeClass?ag:bg;return c[a]||(c[a]=a.replace(/\S+/g,"cm-$\x26"))}function Sd(a,b){var c=t("span",
+null,null,J?"padding-right: .1px":null),c={pre:t("pre",[c]),content:c,col:0,pos:0,cm:a,splitSpaces:(B||J)&&a.getOption("lineWrapping")};b.measure={};for(var d=0;d<=(b.rest?b.rest.length:0);d++){var e=d?b.rest[d-1]:b.line,f;c.pos=0;c.addToken=cg;var g;if(null!=vd)g=vd;else{g=U(a.display.measure,document.createTextNode("AخA"));var h=Ea(g,0,1).getBoundingClientRect();g=h&&h.left!=h.right?vd=3>Ea(g,1,2).getBoundingClientRect().right-h.right:!1}g&&(f=Y(e))&&(c.addToken=dg(c.addToken,f));c.map=[];h=b!=
+a.display.externalMeasured&&F(e);a:{g=c;var h=$e(a,e,h),k=e.markedSpans,l=e.text,m=0;if(k)for(var p=l.length,n=0,q=1,r="",u=void 0,v=void 0,w=0,x=void 0,y=void 0,A=void 0,C=void 0,z=void 0;;){if(w==n){for(var x=y=A=C=v="",z=null,w=Infinity,G=[],H=0;H<k.length;++H){var I=k[H],D=I.marker;"bookmark"==D.type&&I.from==n&&D.widgetNode?G.push(D):I.from<=n&&(null==I.to||I.to>n||D.collapsed&&I.to==n&&I.from==n)?(null!=I.to&&I.to!=n&&w>I.to&&(w=I.to,y=""),D.className&&(x+=" "+D.className),D.css&&(v=D.css),
+D.startStyle&&I.from==n&&(A+=" "+D.startStyle),D.endStyle&&I.to==w&&(y+=" "+D.endStyle),D.title&&!C&&(C=D.title),D.collapsed&&(!z||0>Ve(z.marker,D))&&(z=I)):I.from>n&&w>I.from&&(w=I.from)}if(z&&(z.from||0)==n){bf(g,(null==z.to?p+1:z.to)-n,z.marker,null==z.from);if(null==z.to)break a;z.to==n&&(z=!1)}if(!z&&G.length)for(H=0;H<G.length;++H)bf(g,0,G[H])}if(n>=p)break;for(G=Math.min(p,w);;){if(r){H=n+r.length;z||(I=H>G?r.slice(0,G-n):r,g.addToken(g,I,u?u+x:x,A,n+I.length==w?y:"",C,v));if(H>=G){r=r.slice(G-
+n);n=G;break}n=H;A=""}r=l.slice(m,m=h[q++]);u=af(h[q++],g.cm.options)}}else for(var q=1;q<h.length;q+=2)g.addToken(g,l.slice(m,m=h[q]),af(h[q+1],g.cm.options))}e.styleClasses&&(e.styleClasses.bgClass&&(c.bgClass=wd(e.styleClasses.bgClass,c.bgClass||"")),e.styleClasses.textClass&&(c.textClass=wd(e.styleClasses.textClass,c.textClass||"")));0==c.map.length&&c.map.push(0,0,c.content.appendChild(eg(a.display.measure)));0==d?(b.measure.map=c.map,b.measure.cache={}):((b.measure.maps||(b.measure.maps=[])).push(c.map),
+(b.measure.caches||(b.measure.caches=[])).push({}))}J&&/\bcm-tab\b/.test(c.content.lastChild.className)&&(c.content.className="cm-tab-wrap-hack");K(a,"renderLine",a,b.line,c.pre);c.pre.className&&(c.textClass=wd(c.pre.className,c.textClass||""));return c}function cg(a,b,c,d,e,f,g){if(b){var h=a.splitSpaces?b.replace(/ {3,}/g,fg):b,k=a.cm.state.specialChars,l=!1;if(k.test(b))for(var m=document.createDocumentFragment(),p=0;;){k.lastIndex=p;var n=k.exec(b),q=n?n.index-p:b.length-p;if(q){var r=document.createTextNode(h.slice(p,
+p+q));B&&9>C?m.appendChild(t("span",[r])):m.appendChild(r);a.map.push(a.pos,a.pos+q,r);a.col+=q;a.pos+=q}if(!n)break;p+=q+1;"\t"==n[0]?(r=a.cm.options.tabSize,n=r-a.col%r,r=m.appendChild(t("span",Ne(n),"cm-tab")),r.setAttribute("role","presentation"),r.setAttribute("cm-text","\t"),a.col+=n):(r=a.cm.options.specialCharPlaceholder(n[0]),r.setAttribute("cm-text",n[0]),B&&9>C?m.appendChild(t("span",[r])):m.appendChild(r),a.col+=1);a.map.push(a.pos,a.pos+1,r);a.pos++}else{a.col+=b.length;var m=document.createTextNode(h);
+a.map.push(a.pos,a.pos+b.length,m);B&&9>C&&(l=!0);a.pos+=b.length}if(c||d||e||l||g)return b=c||"",d&&(b+=d),e&&(b+=e),d=t("span",[m],b,g),f&&(d.title=f),a.content.appendChild(d);a.content.appendChild(m)}}function fg(a){for(var b=" ",c=0;c<a.length-2;++c)b+=c%2?" ":" ";return b+" "}function dg(a,b){return function(c,d,e,f,g,h,k){e=e?e+" cm-force-border":"cm-force-border";for(var l=c.pos,m=l+d.length;;){for(var p=0;p<b.length;p++){var n=b[p];if(n.to>l&&n.from<=l)break}if(n.to>=m)return a(c,d,e,f,g,
+h,k);a(c,d.slice(0,n.to-l),e,f,null,h,k);f=null;d=d.slice(n.to-l);l=n.to}}}function bf(a,b,c,d){var e=!d&&c.widgetNode;e&&a.map.push(a.pos,a.pos+b,e);!d&&a.cm.display.input.needsContentAttribute&&(e||(e=a.content.appendChild(document.createElement("span"))),e.setAttribute("cm-marker",c.id));e&&(a.cm.display.input.setUneditable(e),a.content.appendChild(e));a.pos+=b}function Me(a,b){return 0==b.from.ch&&0==b.to.ch&&""==A(b.text)&&(!a.cm||a.cm.options.wholeLineUpdateBefore)}function qd(a,b,c,d){function e(a,
+c,e){a.text=c;a.stateAfter&&(a.stateAfter=null);a.styles&&(a.styles=null);null!=a.order&&(a.order=null);Te(a);Ue(a,e);c=d?d(a):1;c!=a.height&&ca(a,c);L(a,"change",a,b)}function f(a,b){for(var e=a,f=[];e<b;++e)f.push(new Ab(k[e],c?c[e]:null,d));return f}var g=b.from,h=b.to,k=b.text,l=u(a,g.line),m=u(a,h.line),p=A(k),n=c?c[k.length-1]:null,q=h.line-g.line;if(b.full)a.insert(0,f(0,k.length)),a.remove(k.length,a.size-k.length);else if(Me(a,b)){var r=f(0,k.length-1);e(m,m.text,n);q&&a.remove(g.line,q);
+r.length&&a.insert(g.line,r)}else l==m?1==k.length?e(l,l.text.slice(0,g.ch)+p+l.text.slice(h.ch),n):(r=f(1,k.length-1),r.push(new Ab(p+l.text.slice(h.ch),n,d)),e(l,l.text.slice(0,g.ch)+k[0],c?c[0]:null),a.insert(g.line+1,r)):1==k.length?(e(l,l.text.slice(0,g.ch)+k[0]+m.text.slice(h.ch),c?c[0]:null),a.remove(g.line+1,q)):(e(l,l.text.slice(0,g.ch)+k[0],c?c[0]:null),e(m,p+m.text.slice(h.ch),n),r=f(1,k.length-1),1<q&&a.remove(g.line+1,q-1),a.insert(g.line+1,r));L(a,"change",a,b)}function Bb(a){this.lines=
+a;this.parent=null;for(var b=0,c=0;b<a.length;++b)a[b].parent=this,c+=a[b].height;this.height=c}function Cb(a){this.children=a;for(var b=0,c=0,d=0;d<a.length;++d){var e=a[d],b=b+e.chunkSize(),c=c+e.height;e.parent=this}this.size=b;this.height=c;this.parent=null}function Ga(a,b,c){function d(a,f,g){if(a.linked)for(var h=0;h<a.linked.length;++h){var k=a.linked[h];if(k.doc!=f){var l=g&&k.sharedHist;if(!c||l)b(k.doc,l),d(k.doc,a,l)}}}d(a,null,!0)}function Ed(a,b){if(b.cm)throw Error("This document is already in use.");
+a.doc=b;b.cm=a;Ac(a);zc(a);a.options.lineWrapping||Dc(a);a.options.mode=b.modeOption;Q(a)}function u(a,b){b-=a.first;if(0>b||b>=a.size)throw Error("There is no line "+(b+a.first)+" in the document.");for(var c=a;!c.lines;)for(var d=0;;++d){var e=c.children[d],f=e.chunkSize();if(b<f){c=e;break}b-=f}return c.lines[b]}function Da(a,b,c){var d=[],e=b.line;a.iter(b.line,c.line+1,function(a){a=a.text;e==c.line&&(a=a.slice(0,c.ch));e==b.line&&(a=a.slice(b.ch));d.push(a);++e});return d}function xd(a,b,c){var d=
+[];a.iter(b,c,function(a){d.push(a.text)});return d}function ca(a,b){var c=b-a.height;if(c)for(var d=a;d;d=d.parent)d.height+=c}function F(a){if(null==a.parent)return null;var b=a.parent;a=D(b.lines,a);for(var c=b.parent;c;b=c,c=c.parent)for(var d=0;c.children[d]!=b;++d)a+=c.children[d].chunkSize();return a+b.first}function Ba(a,b){var c=a.first;a:do{for(var d=0;d<a.children.length;++d){var e=a.children[d],f=e.height;if(b<f){a=e;continue a}b-=f;c+=e.chunkSize()}return c}while(!a.lines);for(d=0;d<
+a.lines.length;++d){e=a.lines[d].height;if(b<e)break;b-=e}return c+d}function ea(a){a=ia(a);for(var b=0,c=a.parent,d=0;d<c.lines.length;++d){var e=c.lines[d];if(e==a)break;else b+=e.height}for(a=c.parent;a;c=a,a=c.parent)for(d=0;d<a.children.length&&(e=a.children[d],e!=c);++d)b+=e.height;return b}function Y(a){var b=a.order;null==b&&(b=a.order=gg(a.text));return b}function uc(a){this.done=[];this.undone=[];this.undoDepth=Infinity;this.lastModTime=this.lastSelTime=0;this.lastOrigin=this.lastSelOrigin=
+this.lastOp=this.lastSelOp=null;this.generation=this.maxGeneration=a||1}function pd(a,b){var c={from:Rc(b.from),to:ta(b),text:Da(a,b.from,b.to)};cf(a,c,b.from.line,b.to.line+1);Ga(a,function(a){cf(a,c,b.from.line,b.to.line+1)},!0);return c}function ce(a){for(;a.length;)if(A(a).ranges)a.pop();else break}function Ie(a,b,c,d){var e=a.history;e.undone.length=0;var f=+new Date,g,h;if(h=e.lastOp==d||e.lastOrigin==b.origin&&b.origin&&("+"==b.origin.charAt(0)&&a.cm&&e.lastModTime>f-a.cm.options.historyEventDelay||
+"*"==b.origin.charAt(0)))e.lastOp==d?(ce(e.done),g=A(e.done)):e.done.length&&!A(e.done).ranges?g=A(e.done):1<e.done.length&&!e.done[e.done.length-2].ranges?(e.done.pop(),g=A(e.done)):g=void 0,h=g;if(h){var k=A(g.changes);0==y(b.from,b.to)&&0==y(b.from,k.to)?k.to=ta(b):g.changes.push(pd(a,b))}else for((g=A(e.done))&&g.ranges||Wb(a.sel,e.done),g={changes:[pd(a,b)],generation:e.generation},e.done.push(g);e.done.length>e.undoDepth;)e.done.shift(),e.done[0].ranges||e.done.shift();e.done.push(c);e.generation=
+++e.maxGeneration;e.lastModTime=e.lastSelTime=f;e.lastOp=e.lastSelOp=d;e.lastOrigin=e.lastSelOrigin=b.origin;k||K(a,"historyAdded")}function Wb(a,b){var c=A(b);c&&c.ranges&&c.equals(a)||b.push(a)}function cf(a,b,c,d){var e=b["spans_"+a.id],f=0;a.iter(Math.max(a.first,c),Math.min(a.first+a.size,d),function(c){c.markedSpans&&((e||(e=b["spans_"+a.id]={}))[f]=c.markedSpans);++f})}function Zf(a){if(!a)return null;for(var b=0,c;b<a.length;++b)a[b].marker.explicitlyCleared?c||(c=a.slice(0,b)):c&&c.push(a[b]);
+return c?c.length?c:null:a}function Xa(a,b,c){for(var d=0,e=[];d<a.length;++d){var f=a[d];if(f.ranges)e.push(c?la.prototype.deepCopy.call(f):f);else{var f=f.changes,g=[];e.push({changes:g});for(var h=0;h<f.length;++h){var k=f[h],l;g.push({from:k.from,to:k.to,text:k.text});if(b)for(var m in k)(l=m.match(/^spans_(\d+)$/))&&-1<D(b,Number(l[1]))&&(A(g)[m]=k[m],delete k[m])}}}return e}function df(a,b,c,d){c<a.line?a.line+=d:b<a.line&&(a.line=b,a.ch=0)}function ef(a,b,c,d){for(var e=0;e<a.length;++e){var f=
+a[e],g=!0;if(f.ranges){f.copied||(f=a[e]=f.deepCopy(),f.copied=!0);for(var h=0;h<f.ranges.length;h++)df(f.ranges[h].anchor,b,c,d),df(f.ranges[h].head,b,c,d)}else{for(h=0;h<f.changes.length;++h){var k=f.changes[h];if(c<k.from.line)k.from=r(k.from.line+d,k.from.ch),k.to=r(k.to.line+d,k.to.ch);else if(b<=k.to.line){g=!1;break}}g||(a.splice(0,e+1),e=0)}}}function Je(a,b){var c=b.from.line,d=b.to.line,e=b.text.length-(d-c)-1;ef(a.done,c,d,e);ef(a.undone,c,d,e)}function ld(a){return null!=a.defaultPrevented?
+a.defaultPrevented:0==a.returnValue}function xe(a){var b=a.which;null==b&&(a.button&1?b=1:a.button&2?b=3:a.button&4&&(b=2));W&&a.ctrlKey&&1==b&&(b=3);return b}function L(a,b){function c(a){return function(){a.apply(null,e)}}var d=a._handlers&&a._handlers[b];if(d){var e=Array.prototype.slice.call(arguments,2),f;Ta?f=Ta.delayedCallbacks:Db?f=Db:(f=Db=[],setTimeout(hg,0));for(var g=0;g<d.length;++g)f.push(c(d[g]))}}function hg(){var a=Db;Db=null;for(var b=0;b<a.length;++b)a[b]()}function ja(a,b,c){"string"==
+typeof b&&(b={type:b,preventDefault:function(){this.defaultPrevented=!0}});K(a,c||b.type,a,b);return ld(b)||b.codemirrorIgnore}function fe(a){var b=a._handlers&&a._handlers.cursorActivity;if(b){a=a.curOp.cursorActivityHandlers||(a.curOp.cursorActivityHandlers=[]);for(var c=0;c<b.length;++c)-1==D(a,b[c])&&a.push(b[c])}}function S(a,b){var c=a._handlers&&a._handlers[b];return c&&0<c.length}function Ya(a){a.prototype.on=function(a,c){v(this,a,c)};a.prototype.off=function(a,c){ka(this,a,c)}}function bb(){this.id=
+null}function ye(a,b,c){for(var d=0,e=0;;){var f=a.indexOf("\t",d);-1==f&&(f=a.length);var g=f-d;if(f==a.length||e+g>=b)return d+Math.min(g,b-e);e+=f-d;e+=c-e%c;d=f+1;if(e>=b)return d}}function Ne(a){for(;vc.length<=a;)vc.push(A(vc)+" ");return vc[a]}function A(a){return a[a.length-1]}function D(a,b){for(var c=0;c<a.length;++c)if(a[c]==b)return c;return-1}function ob(a,b){for(var c=[],d=0;d<a.length;d++)c[d]=b(a[d],d);return c}function Eb(){}function ff(a,b){var c;Object.create?c=Object.create(a):
+(Eb.prototype=a,c=new Eb);b&&V(b,c);return c}function V(a,b,c){b||(b={});for(var d in a)!a.hasOwnProperty(d)||!1===c&&b.hasOwnProperty(d)||(b[d]=a[d]);return b}function cb(a){var b=Array.prototype.slice.call(arguments,1);return function(){return a.apply(null,b)}}function oc(a,b){return b?-1<b.source.indexOf("\\w")&&gf(a)?!0:b.test(a):gf(a)}function hf(a){for(var b in a)if(a.hasOwnProperty(b)&&a[b])return!1;return!0}function tb(a){return 768<=a.charCodeAt(0)&&ig.test(a)}function t(a,b,c,d){a=document.createElement(a);
+c&&(a.className=c);d&&(a.style.cssText=d);if("string"==typeof b)a.appendChild(document.createTextNode(b));else if(b)for(c=0;c<b.length;++c)a.appendChild(b[c]);return a}function za(a){for(var b=a.childNodes.length;0<b;--b)a.removeChild(a.firstChild);return a}function U(a,b){return za(a).appendChild(b)}function fa(){return document.activeElement}function Fb(a){return new RegExp("(^|\\s)"+a+"(?:$|\\s)\\s*")}function wd(a,b){for(var c=a.split(" "),d=0;d<c.length;d++)c[d]&&!Fb(c[d]).test(b)&&(b+=" "+c[d]);
+return b}function jf(a){if(document.body.getElementsByClassName)for(var b=document.body.getElementsByClassName("CodeMirror"),c=0;c<b.length;c++){var d=b[c].CodeMirror;d&&a(d)}}function tf(){var a;v(window,"resize",function(){null==a&&(a=setTimeout(function(){a=null;jf(If)},100))});v(window,"blur",function(){jf(db)})}function eg(a){if(null==yd){var b=t("span","​");U(a,t("span",[b,document.createTextNode("x")]));0!=a.firstChild.offsetHeight&&(yd=1>=b.offsetWidth&&2<b.offsetHeight&&!(B&&8>C))}a=yd?t("span",
+"​"):t("span"," ",null,"display: inline-block; width: 1px; margin-right: -1px");a.setAttribute("cm-text","");return a}function Af(a,b,c,d){if(!a)return d(b,c,"ltr");for(var e=!1,f=0;f<a.length;++f){var g=a[f];if(g.from<c&&g.to>b||b==c&&g.to==b)d(Math.max(g.from,b),Math.min(g.to,c),1==g.level?"rtl":"ltr"),e=!0}e||d(b,c,"ltr")}function dd(a){return a.level%2?a.to:a.from}function ed(a){return a.level%2?a.from:a.to}function ac(a){return(a=Y(a))?dd(a[0]):0}function bc(a){var b=Y(a);return b?ed(A(b)):a.text.length}
+function kf(a,b){var c=u(a.doc,b),d=ia(c);d!=c&&(b=F(d));d=(c=Y(d))?c[0].level%2?bc(d):ac(d):0;return r(b,d)}function lf(a,b){var c=kf(a,b.line),d=u(a.doc,c.line),e=Y(d);return e&&0!=e[0].level?c:(d=Math.max(0,d.text.search(/\S/)),r(c.line,b.line==c.line&&b.ch<=d&&b.ch?0:d))}function Sb(a,b){vb=null;for(var c=0,d;c<a.length;++c){var e=a[c];if(e.from<b&&e.to>b)return c;if(e.from==b||e.to==b)if(null==d)d=c;else{var f;f=e.level;var g=a[d].level,h=a[0].level;f=f==h?!0:g==h?!1:f<g;if(f)return e.from!=
+e.to&&(vb=d),c;e.from!=e.to&&(vb=c);break}}return d}function zd(a,b,c,d){if(!d)return b+c;do b+=c;while(0<b&&tb(a.text.charAt(b)));return b}function gd(a,b,c,d){var e=Y(a);if(!e)return Oe(a,b,c,d);var f=Sb(e,b),g=e[f];for(b=zd(a,b,g.level%2?-c:c,d);;){if(b>g.from&&b<g.to)return b;if(b==g.from||b==g.to){if(Sb(e,b)==f)return b;g=e[f+c];return 0<c==g.level%2?g.to:g.from}g=e[f+=c];if(!g)return null;b=0<c==g.level%2?zd(a,g.to,-1,d):zd(a,g.from,1,d)}}function Oe(a,b,c,d){b+=c;if(d)for(;0<b&&tb(a.text.charAt(b));)b+=
+c;return 0>b||b>a.text.length?null:b}var wa=/gecko\/\d/i.test(navigator.userAgent),mf=/MSIE \d/.test(navigator.userAgent),nf=/Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),B=mf||nf,C=B&&(mf?document.documentMode||6:nf[1]),J=/WebKit\//.test(navigator.userAgent),jg=J&&/Qt\/\d+\.\d+/.test(navigator.userAgent),kg=/Chrome\//.test(navigator.userAgent),ba=/Opera\//.test(navigator.userAgent),te=/Apple Computer/.test(navigator.vendor),lg=/Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent),
+Gf=/PhantomJS/.test(navigator.userAgent),Qa=/AppleWebKit/.test(navigator.userAgent)&&/Mobile\/\w+/.test(navigator.userAgent),ab=Qa||/Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent),W=Qa||/Mac/.test(navigator.platform),mg=/win/i.test(navigator.platform),Ia=ba&&navigator.userAgent.match(/Version\/(\d*\.\d*)/);Ia&&(Ia=Number(Ia[1]));Ia&&15<=Ia&&(ba=!1,J=!0);var of=W&&(jg||ba&&(null==Ia||12.11>Ia)),id=wa||B&&9<=C,Ge=!1,ra=!1;Fc.prototype=V({update:function(a){var b=
+a.scrollWidth>a.clientWidth+1,c=a.scrollHeight>a.clientHeight+1,d=a.nativeBarWidth;c?(this.vert.style.display="block",this.vert.style.bottom=b?d+"px":"0",this.vert.firstChild.style.height=Math.max(0,a.scrollHeight-a.clientHeight+(a.viewHeight-(b?d:0)))+"px"):(this.vert.style.display="",this.vert.firstChild.style.height="0");b?(this.horiz.style.display="block",this.horiz.style.right=c?d+"px":"0",this.horiz.style.left=a.barLeft+"px",this.horiz.firstChild.style.width=a.scrollWidth-a.clientWidth+(a.viewWidth-
+a.barLeft-(c?d:0))+"px"):(this.horiz.style.display="",this.horiz.firstChild.style.width="0");!this.checkedOverlay&&0<a.clientHeight&&(0==d&&this.overlayHack(),this.checkedOverlay=!0);return{right:c?d:0,bottom:b?d:0}},setScrollLeft:function(a){this.horiz.scrollLeft!=a&&(this.horiz.scrollLeft=a)},setScrollTop:function(a){this.vert.scrollTop!=a&&(this.vert.scrollTop=a)},overlayHack:function(){this.horiz.style.minHeight=this.vert.style.minWidth=W&&!lg?"12px":"18px";var a=this,b=function(b){(b.target||
+b.srcElement)!=a.vert&&(b.target||b.srcElement)!=a.horiz&&G(a.cm,pe)(b)};v(this.vert,"mousedown",b);v(this.horiz,"mousedown",b)},clear:function(){var a=this.horiz.parentNode;a.removeChild(this.horiz);a.removeChild(this.vert)}},Fc.prototype);Gc.prototype=V({update:function(){return{bottom:0,right:0}},setScrollLeft:function(){},setScrollTop:function(){},clear:function(){}},Gc.prototype);q.scrollbarModel={"native":Fc,"null":Gc};Mb.prototype.signal=function(a,b){S(a,b)&&this.events.push(arguments)};Mb.prototype.finish=
+function(){for(var a=0;a<this.events.length;a++)K.apply(null,this.events[a])};var r=q.Pos=function(a,b){if(!(this instanceof r))return new r(a,b);this.line=a;this.ch=b},y=q.cmpPos=function(a,b){return a.line-b.line||a.ch-b.ch},X=null;Tc.prototype=V({init:function(a){function b(a){if(d.somethingSelected())X=d.getSelections(),c.inaccurateSelection&&(c.prevInput="",c.inaccurateSelection=!1,f.value=X.join("\n"),Za(f));else if(d.options.lineWiseCopyCut){var b=Vd(d);X=b.text;"cut"==a.type?d.setSelections(b.ranges,
+null,ha):(c.prevInput="",f.value=b.text.join("\n"),Za(f))}else return;"cut"==a.type&&(d.state.cutIncoming=!0)}var c=this,d=this.cm,e=this.wrapper=Xd(),f=this.textarea=e.firstChild;a.wrapper.insertBefore(e,a.wrapper.firstChild);Qa&&(f.style.width="0px");v(f,"input",function(){B&&9<=C&&c.hasSelection&&(c.hasSelection=null);c.poll()});v(f,"paste",function(){if(J&&!d.state.fakedLastChar&&!(200>new Date-d.state.lastMiddleDown)){var a=f.selectionStart,b=f.selectionEnd;f.value+="$";f.selectionEnd=b;f.selectionStart=
+a;d.state.fakedLastChar=!0}d.state.pasteIncoming=!0;c.fastPoll()});v(f,"cut",b);v(f,"copy",b);v(a.scroller,"paste",function(b){oa(a,b)||(d.state.pasteIncoming=!0,c.focus())});v(a.lineSpace,"selectstart",function(b){oa(a,b)||O(b)});v(f,"compositionstart",function(){var a=d.getCursor("from");c.composing={start:a,range:d.markText(a,d.getCursor("to"),{className:"CodeMirror-composing"})}});v(f,"compositionend",function(){c.composing&&(c.poll(),c.composing.range.clear(),c.composing=null)})},prepareSelection:function(){var a=
+this.cm,b=a.display,c=a.doc,d=he(a);if(a.options.moveInputWithCursor){var a=ma(a,c.sel.primary().head,"div"),c=b.wrapper.getBoundingClientRect(),e=b.lineDiv.getBoundingClientRect();d.teTop=Math.max(0,Math.min(b.wrapper.clientHeight-10,a.top+e.top-c.top));d.teLeft=Math.max(0,Math.min(b.wrapper.clientWidth-10,a.left+e.left-c.left))}return d},showSelection:function(a){var b=this.cm.display;U(b.cursorDiv,a.cursors);U(b.selectionDiv,a.selection);null!=a.teTop&&(this.wrapper.style.top=a.teTop+"px",this.wrapper.style.left=
+a.teLeft+"px")},reset:function(a){if(!this.contextMenuPending){var b,c,d=this.cm,e=d.doc;d.somethingSelected()?(this.prevInput="",b=e.sel.primary(),c=(b=Ce&&(100<b.to().line-b.from().line||1E3<(c=d.getSelection()).length))?"-":c||d.getSelection(),this.textarea.value=c,d.state.focused&&Za(this.textarea),B&&9<=C&&(this.hasSelection=c)):a||(this.prevInput=this.textarea.value="",B&&9<=C&&(this.hasSelection=null));this.inaccurateSelection=b}},getField:function(){return this.textarea},supportsTouch:function(){return!1},
+focus:function(){if("nocursor"!=this.cm.options.readOnly&&(!ab||fa()!=this.textarea))try{this.textarea.focus()}catch(a){}},blur:function(){this.textarea.blur()},resetPosition:function(){this.wrapper.style.top=this.wrapper.style.left=0},receivedFocus:function(){this.slowPoll()},slowPoll:function(){var a=this;a.pollingFast||a.polling.set(this.cm.options.pollInterval,function(){a.poll();a.cm.state.focused&&a.slowPoll()})},fastPoll:function(){function a(){c.poll()||b?(c.pollingFast=!1,c.slowPoll()):(b=
+!0,c.polling.set(60,a))}var b=!1,c=this;c.pollingFast=!0;c.polling.set(20,a)},poll:function(){var a=this.cm,b=this.textarea,c=this.prevInput;if(!a.state.focused||ng(b)&&!c||Rb(a)||a.options.disableInput||a.state.keySeq)return!1;a.state.pasteIncoming&&a.state.fakedLastChar&&(b.value=b.value.substring(0,b.value.length-1),a.state.fakedLastChar=!1);var d=b.value;if(d==c&&!a.somethingSelected())return!1;if(B&&9<=C&&this.hasSelection===d||W&&/[\uf700-\uf7ff]/.test(d))return a.display.input.reset(),!1;if(a.doc.sel==
+a.display.selForContextMenu){var e=d.charCodeAt(0);8203!=e||c||(c="​");if(8666==e)return this.reset(),this.cm.execCommand("undo")}for(var f=0,e=Math.min(c.length,d.length);f<e&&c.charCodeAt(f)==d.charCodeAt(f);)++f;var g=this;T(a,function(){Sc(a,d.slice(f),c.length-f,null,g.composing?"*compose":null);1E3<d.length||-1<d.indexOf("\n")?b.value=g.prevInput="":g.prevInput=d;g.composing&&(g.composing.range.clear(),g.composing.range=a.markText(g.composing.start,a.getCursor("to"),{className:"CodeMirror-composing"}))});
+return!0},ensurePolled:function(){this.pollingFast&&this.poll()&&(this.pollingFast=!1)},onKeyPress:function(){B&&9<=C&&(this.hasSelection=null);this.fastPoll()},onContextMenu:function(a){function b(){if(null!=g.selectionStart){var a=e.somethingSelected(),b="​"+(a?g.value:"");g.value="⇚";g.value=b;d.prevInput=a?"":"​";g.selectionStart=1;g.selectionEnd=b.length;f.selForContextMenu=e.doc.sel}}function c(){d.contextMenuPending=!1;d.wrapper.style.position="relative";g.style.cssText=l;B&&9>C&&f.scrollbars.setScrollTop(f.scroller.scrollTop=
+k);if(null!=g.selectionStart){(!B||B&&9>C)&&b();var a=0,c=function(){f.selForContextMenu==e.doc.sel&&0==g.selectionStart&&0<g.selectionEnd&&"​"==d.prevInput?G(e,ic.selectAll)(e):10>a++?f.detectingSelectAll=setTimeout(c,500):f.input.reset()};f.detectingSelectAll=setTimeout(c,200)}}var d=this,e=d.cm,f=e.display,g=d.textarea,h=Ua(e,a),k=f.scroller.scrollTop;if(h&&!ba){e.options.resetSelectionOnContextMenu&&-1==e.doc.sel.contains(h)&&G(e,H)(e.doc,ga(h),ha);var l=g.style.cssText;d.wrapper.style.position=
+"absolute";g.style.cssText="position: fixed; width: 30px; height: 30px; top: "+(a.clientY-5)+"px; left: "+(a.clientX-5)+"px; z-index: 1000; background: "+(B?"rgba(255, 255, 255, .05)":"transparent")+"; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity\x3d5);";if(J)var m=window.scrollY;f.input.focus();J&&window.scrollTo(null,m);f.input.reset();e.somethingSelected()||(g.value=d.prevInput=" ");d.contextMenuPending=!0;f.selForContextMenu=e.doc.sel;clearTimeout(f.detectingSelectAll);
+B&&9<=C&&b();if(id){jd(a);var p=function(){ka(window,"mouseup",p);setTimeout(c,20)};v(window,"mouseup",p)}else setTimeout(c,50)}},setUneditable:Eb,needsContentAttribute:!1},Tc.prototype);Uc.prototype=V({init:function(a){function b(a){if(d.somethingSelected())X=d.getSelections(),"cut"==a.type&&d.replaceSelection("",null,"cut");else if(d.options.lineWiseCopyCut){var b=Vd(d);X=b.text;"cut"==a.type&&d.operation(function(){d.setSelections(b.ranges,0,ha);d.replaceSelection("",null,"cut")})}else return;
+if(a.clipboardData&&!Qa)a.preventDefault(),a.clipboardData.clearData(),a.clipboardData.setData("text/plain",X.join("\n"));else{var c=Xd();a=c.firstChild;d.display.lineSpace.insertBefore(c,d.display.lineSpace.firstChild);a.value=X.join("\n");var h=document.activeElement;Za(a);setTimeout(function(){d.display.lineSpace.removeChild(c);h.focus()},50)}}var c=this,d=c.cm;a=c.div=a.lineDiv;a.contentEditable="true";Wd(a);v(a,"paste",function(a){var b=a.clipboardData&&a.clipboardData.getData("text/plain");
+b&&(a.preventDefault(),d.replaceSelection(b,null,"paste"))});v(a,"compositionstart",function(a){a=a.data;c.composing={sel:d.doc.sel,data:a,startData:a};if(a){var b=d.doc.sel.primary(),g=d.getLine(b.head.line).indexOf(a,Math.max(0,b.head.ch-a.length));-1<g&&g<=b.head.ch&&(c.composing.sel=ga(r(b.head.line,g),r(b.head.line,g+a.length)))}});v(a,"compositionupdate",function(a){c.composing.data=a.data});v(a,"compositionend",function(a){var b=c.composing;b&&(a.data==b.startData||/\u200b/.test(a.data)||(b.data=
+a.data),setTimeout(function(){b.handled||c.applyComposition(b);c.composing==b&&(c.composing=null)},50))});v(a,"touchstart",function(){c.forceCompositionEnd()});v(a,"input",function(){c.composing||c.pollContent()||T(c.cm,function(){Q(d)})});v(a,"copy",b);v(a,"cut",b)},prepareSelection:function(){var a=he(this.cm,!1);a.focus=this.cm.state.focused;return a},showSelection:function(a){a&&this.cm.display.view.length&&(a.focus&&this.showPrimarySelection(),this.showMultipleSelections(a))},showPrimarySelection:function(){var a=
+window.getSelection(),b=this.cm.doc.sel.primary(),c=Tb(this.cm,a.anchorNode,a.anchorOffset),d=Tb(this.cm,a.focusNode,a.focusOffset);if(!c||c.bad||!d||d.bad||0!=y(Qb(c,d),b.from())||0!=y(Pb(c,d),b.to()))if(c=Yd(this.cm,b.from()),d=Yd(this.cm,b.to()),c||d){var e=this.cm.display.view,b=a.rangeCount&&a.getRangeAt(0);c?d||(d=e[e.length-1].measure,d=d.maps?d.maps[d.maps.length-1]:d.map,d={node:d[d.length-1],offset:d[d.length-2]-d[d.length-3]}):c={node:e[0].measure.map[2],offset:0};try{var f=Ea(c.node,c.offset,
+d.offset,d.node)}catch(g){}f&&(a.removeAllRanges(),a.addRange(f),b&&null==a.anchorNode?a.addRange(b):wa&&this.startGracePeriod());this.rememberSelection()}},startGracePeriod:function(){var a=this;clearTimeout(this.gracePeriod);this.gracePeriod=setTimeout(function(){a.gracePeriod=!1;a.selectionChanged()&&a.cm.operation(function(){a.cm.curOp.selectionChanged=!0})},20)},showMultipleSelections:function(a){U(this.cm.display.cursorDiv,a.cursors);U(this.cm.display.selectionDiv,a.selection)},rememberSelection:function(){var a=
+window.getSelection();this.lastAnchorNode=a.anchorNode;this.lastAnchorOffset=a.anchorOffset;this.lastFocusNode=a.focusNode;this.lastFocusOffset=a.focusOffset},selectionInEditor:function(){var a=window.getSelection();if(!a.rangeCount)return!1;a=a.getRangeAt(0).commonAncestorContainer;return Wc(this.div,a)},focus:function(){"nocursor"!=this.cm.options.readOnly&&this.div.focus()},blur:function(){this.div.blur()},getField:function(){return this.div},supportsTouch:function(){return!0},receivedFocus:function(){function a(){b.cm.state.focused&&
+(b.pollSelection(),b.polling.set(b.cm.options.pollInterval,a))}var b=this;this.selectionInEditor()?this.pollSelection():T(this.cm,function(){b.cm.curOp.selectionChanged=!0});this.polling.set(this.cm.options.pollInterval,a)},selectionChanged:function(){var a=window.getSelection();return a.anchorNode!=this.lastAnchorNode||a.anchorOffset!=this.lastAnchorOffset||a.focusNode!=this.lastFocusNode||a.focusOffset!=this.lastFocusOffset},pollSelection:function(){if(!this.composing&&!this.gracePeriod&&this.selectionChanged()){var a=
+window.getSelection(),b=this.cm;this.rememberSelection();var c=Tb(b,a.anchorNode,a.anchorOffset),d=Tb(b,a.focusNode,a.focusOffset);c&&d&&T(b,function(){H(b.doc,ga(c,d),ha);if(c.bad||d.bad)b.curOp.selectionChanged=!0})}},pollContent:function(){var a=this.cm,b=a.display,c=a.doc.sel.primary(),d=c.from(),c=c.to();if(d.line<b.viewFrom||c.line>b.viewTo-1)return!1;var e;d.line==b.viewFrom||0==(e=Ca(a,d.line))?(d=F(b.view[0].line),e=b.view[0].node):(d=F(b.view[e].line),e=b.view[e-1].node.nextSibling);var f=
+Ca(a,c.line);f==b.view.length-1?(c=b.viewTo-1,b=b.view[f].node):(c=F(b.view[f+1].line)-1,b=b.view[f+1].node.previousSibling);b=sa(xf(a,e,b,d,c));for(e=Da(a.doc,r(d,0),r(c,u(a.doc,c).text.length));1<b.length&&1<e.length;)if(A(b)==A(e))b.pop(),e.pop(),c--;else if(b[0]==e[0])b.shift(),e.shift(),d++;else break;for(var g=0,f=0,h=b[0],k=e[0],l=Math.min(h.length,k.length);g<l&&h.charCodeAt(g)==k.charCodeAt(g);)++g;h=A(b);k=A(e);for(l=Math.min(h.length-(1==b.length?g:0),k.length-(1==e.length?g:0));f<l&&h.charCodeAt(h.length-
+f-1)==k.charCodeAt(k.length-f-1);)++f;b[b.length-1]=h.slice(0,h.length-f);b[0]=b[0].slice(g);d=r(d,g);c=r(c,e.length?A(e).length-f:0);if(1<b.length||b[0]||y(d,c))return wb(a.doc,b,d,c,"+input"),!0},ensurePolled:function(){this.forceCompositionEnd()},reset:function(){this.forceCompositionEnd()},forceCompositionEnd:function(){this.composing&&!this.composing.handled&&(this.applyComposition(this.composing),this.composing.handled=!0,this.div.blur(),this.div.focus())},applyComposition:function(a){a.data&&
+a.data!=a.startData&&G(this.cm,Sc)(this.cm,a.data,0,a.sel)},setUneditable:function(a){a.setAttribute("contenteditable","false")},onKeyPress:function(a){a.preventDefault();G(this.cm,Sc)(this.cm,String.fromCharCode(null==a.charCode?a.keyCode:a.charCode),0)},onContextMenu:Eb,resetPosition:Eb,needsContentAttribute:!0},Uc.prototype);q.inputStyles={textarea:Tc,contenteditable:Uc};la.prototype={primary:function(){return this.ranges[this.primIndex]},equals:function(a){if(a==this)return!0;if(a.primIndex!=
+this.primIndex||a.ranges.length!=this.ranges.length)return!1;for(var b=0;b<this.ranges.length;b++){var c=this.ranges[b],d=a.ranges[b];if(0!=y(c.anchor,d.anchor)||0!=y(c.head,d.head))return!1}return!0},deepCopy:function(){for(var a=[],b=0;b<this.ranges.length;b++)a[b]=new z(Rc(this.ranges[b].anchor),Rc(this.ranges[b].head));return new la(a,this.primIndex)},somethingSelected:function(){for(var a=0;a<this.ranges.length;a++)if(!this.ranges[a].empty())return!0;return!1},contains:function(a,b){b||(b=a);
+for(var c=0;c<this.ranges.length;c++){var d=this.ranges[c];if(0<=y(b,d.from())&&0>=y(a,d.to()))return c}return-1}};z.prototype={from:function(){return Qb(this.anchor,this.head)},to:function(){return Pb(this.anchor,this.head)},empty:function(){return this.head.line==this.anchor.line&&this.head.ch==this.anchor.ch}};var ad={left:0,right:0,top:0,bottom:0},Fa,Ta=null,Ff=0,fc,ec,se=0,gc=0,R=null;B?R=-.53:wa?R=15:kg?R=-.7:te&&(R=-1/3);var ze=function(a){var b=a.wheelDeltaX,c=a.wheelDeltaY;null==b&&a.detail&&
+a.axis==a.HORIZONTAL_AXIS&&(b=a.detail);null==c&&a.detail&&a.axis==a.VERTICAL_AXIS?c=a.detail:null==c&&(c=a.wheelDelta);return{x:b,y:c}};q.wheelEventPixels=function(a){a=ze(a);a.x*=R;a.y*=R;return a};var Qf=new bb,md=null,ta=q.changeEnd=function(a){return a.text?r(a.from.line+a.text.length-1,A(a.text).length+(1==a.text.length?a.from.ch:0)):a.to};q.prototype={constructor:q,focus:function(){window.focus();this.display.input.focus()},setOption:function(a,b){var c=this.options,d=c[a];if(c[a]!=b||"mode"==
+a)c[a]=b,Ka.hasOwnProperty(a)&&G(this,Ka[a])(this,b,d)},getOption:function(a){return this.options[a]},getDoc:function(){return this.doc},addKeyMap:function(a,b){this.state.keyMaps[b?"push":"unshift"](pc(a))},removeKeyMap:function(a){for(var b=this.state.keyMaps,c=0;c<b.length;++c)if(b[c]==a||b[c].name==a)return b.splice(c,1),!0},addOverlay:M(function(a,b){var c=a.token?a:q.getMode(this.options,a);if(c.startState)throw Error("Overlays may not be stateful.");this.state.overlays.push({mode:c,modeSpec:a,
+opaque:b&&b.opaque});this.state.modeGen++;Q(this)}),removeOverlay:M(function(a){for(var b=this.state.overlays,c=0;c<b.length;++c){var d=b[c].modeSpec;if(d==a||"string"==typeof a&&d.name==a){b.splice(c,1);this.state.modeGen++;Q(this);break}}}),indentLine:M(function(a,b,c){"string"!=typeof b&&"number"!=typeof b&&(b=null==b?this.options.smartIndent?"smart":"prev":b?"add":"subtract");qb(this.doc,a)&&pb(this,a,b,c)}),indentSelection:M(function(a){for(var b=this.doc.sel.ranges,c=-1,d=0;d<b.length;d++){var e=
+b[d];if(e.empty())e.head.line>c&&(pb(this,e.head.line,a,!0),c=e.head.line,d==this.doc.sel.primIndex&&Pa(this));else{for(var f=e.from(),e=e.to(),g=Math.max(c,f.line),c=Math.min(this.lastLine(),e.line-(e.ch?0:1))+1,e=g;e<c;++e)pb(this,e,a);e=this.doc.sel.ranges;0==f.ch&&b.length==e.length&&0<e[d].from().ch&&Xc(this.doc,d,new z(f,e[d].to()),ha)}}}),getTokenAt:function(a,b){return Ye(this,a,b)},getLineTokens:function(a,b){return Ye(this,r(a),b,!0)},getTokenTypeAt:function(a){a=w(this.doc,a);var b=$e(this,
+u(this.doc,a.line)),c=0,d=(b.length-1)/2;a=a.ch;if(0==a)b=b[2];else for(;;){var e=c+d>>1;if((e?b[2*e-1]:0)>=a)d=e;else if(b[2*e+1]<a)c=e+1;else{b=b[2*e+2];break}}c=b?b.indexOf("cm-overlay "):-1;return 0>c?b:0==c?null:b.slice(0,c-1)},getModeAt:function(a){var b=this.doc.mode;return b.innerMode?q.innerMode(b,this.getTokenAt(a).state).mode:b},getHelper:function(a,b){return this.getHelpers(a,b)[0]},getHelpers:function(a,b){var c=[];if(!$a.hasOwnProperty(b))return c;var d=$a[b],e=this.getModeAt(a);if("string"==
+typeof e[b])d[e[b]]&&c.push(d[e[b]]);else if(e[b])for(var f=0;f<e[b].length;f++){var g=d[e[b][f]];g&&c.push(g)}else e.helperType&&d[e.helperType]?c.push(d[e.helperType]):d[e.name]&&c.push(d[e.name]);for(f=0;f<d._global.length;f++)g=d._global[f],g.pred(e,this)&&-1==D(c,g.val)&&c.push(g.val);return c},getStateAfter:function(a,b){var c=this.doc;a=Math.max(c.first,Math.min(null==a?c.first+c.size-1:a,c.first+c.size-1));return sb(this,a+1,b)},cursorCoords:function(a,b){var c;c=this.doc.sel.primary();c=
+null==a?c.head:"object"==typeof a?w(this.doc,a):a?c.from():c.to();return ma(this,c,b||"page")},charCoords:function(a,b){return Yb(this,w(this.doc,a),b||"page")},coordsChar:function(a,b){a=ne(this,a,b||"page");return fd(this,a.left,a.top)},lineAtHeight:function(a,b){a=ne(this,{top:a,left:0},b||"page").top;return Ba(this.doc,a+this.display.viewOffset)},heightAtLine:function(a,b){var c=!1,d;"number"==typeof a?(d=this.doc.first+this.doc.size-1,a<this.doc.first?a=this.doc.first:a>d&&(a=d,c=!0),d=u(this.doc,
+a)):d=a;return cd(this,d,{top:0,left:0},b||"page").top+(c?this.doc.height-ea(d):0)},defaultTextHeight:function(){return xa(this.display)},defaultCharWidth:function(){return gb(this.display)},setGutterMarker:M(function(a,b,c){return nc(this.doc,a,"gutter",function(a){var e=a.gutterMarkers||(a.gutterMarkers={});e[b]=c;!c&&hf(e)&&(a.gutterMarkers=null);return!0})}),clearGutter:M(function(a){var b=this,c=b.doc,d=c.first;c.iter(function(c){c.gutterMarkers&&c.gutterMarkers[a]&&(c.gutterMarkers[a]=null,
+na(b,d,"gutter"),hf(c.gutterMarkers)&&(c.gutterMarkers=null));++d})}),lineInfo:function(a){if("number"==typeof a){if(!qb(this.doc,a))return null;var b=a;a=u(this.doc,a);if(!a)return null}else if(b=F(a),null==b)return null;return{line:b,handle:a,text:a.text,gutterMarkers:a.gutterMarkers,textClass:a.textClass,bgClass:a.bgClass,wrapClass:a.wrapClass,widgets:a.widgets}},getViewport:function(){return{from:this.display.viewFrom,to:this.display.viewTo}},addWidget:function(a,b,c,d,e){var f=this.display;a=
+ma(this,w(this.doc,a));var g=a.bottom,h=a.left;b.style.position="absolute";b.setAttribute("cm-ignore-events","true");this.display.input.setUneditable(b);f.sizer.appendChild(b);if("over"==d)g=a.top;else if("above"==d||"near"==d){var k=Math.max(f.wrapper.clientHeight,this.doc.height),l=Math.max(f.sizer.clientWidth,f.lineSpace.clientWidth);("above"==d||a.bottom+b.offsetHeight>k)&&a.top>b.offsetHeight?g=a.top-b.offsetHeight:a.bottom+b.offsetHeight<=k&&(g=a.bottom);h+b.offsetWidth>l&&(h=l-b.offsetWidth)}b.style.top=
+g+"px";b.style.left=b.style.right="";"right"==e?(h=f.sizer.clientWidth-b.offsetWidth,b.style.right="0px"):("left"==e?h=0:"middle"==e&&(h=(f.sizer.clientWidth-b.offsetWidth)/2),b.style.left=h+"px");c&&(a=cc(this,h,g,h+b.offsetWidth,g+b.offsetHeight),null!=a.scrollTop&&lb(this,a.scrollTop),null!=a.scrollLeft&&Ma(this,a.scrollLeft))},triggerOnKeyDown:M(ve),triggerOnKeyPress:M(we),triggerOnKeyUp:ue,execCommand:function(a){if(ic.hasOwnProperty(a))return ic[a](this)},findPosH:function(a,b,c,d){var e=1;
+0>b&&(e=-1,b=-b);var f=0;for(a=w(this.doc,a);f<b&&(a=rd(this.doc,a,e,c,d),!a.hitSide);++f);return a},moveH:M(function(a,b){var c=this;c.extendSelectionsBy(function(d){return c.display.shift||c.doc.extend||d.empty()?rd(c.doc,d.head,a,b,c.options.rtlMoveVisually):0>a?d.from():d.to()},Gb)}),deleteH:M(function(a,b){var c=this.doc;this.doc.sel.somethingSelected()?c.replaceSelection("",null,"+delete"):Va(this,function(d){var e=rd(c,d.head,a,b,!1);return 0>a?{from:e,to:d.head}:{from:d.head,to:e}})}),findPosV:function(a,
+b,c,d){var e=1;0>b&&(e=-1,b=-b);var f=0;for(a=w(this.doc,a);f<b&&(a=ma(this,a,"div"),null==d?d=a.left:a.left=d,a=Pe(this,a,e,c),!a.hitSide);++f);return a},moveV:M(function(a,b){var c=this,d=this.doc,e=[],f=!c.display.shift&&!d.extend&&d.sel.somethingSelected();d.extendSelectionsBy(function(g){if(f)return 0>a?g.from():g.to();var k=ma(c,g.head,"div");null!=g.goalColumn&&(k.left=g.goalColumn);e.push(k.left);var l=Pe(c,k,a,b);"page"==b&&g==d.sel.primary()&&lc(c,null,Yb(c,l,"div").top-k.top);return l},
+Gb);if(e.length)for(var g=0;g<d.sel.ranges.length;g++)d.sel.ranges[g].goalColumn=e[g]}),findWordAt:function(a){var b=u(this.doc,a.line).text,c=a.ch,d=a.ch;if(b){var e=this.getHelper(a,"wordChars");(0>a.xRel||d==b.length)&&c?--c:++d;for(var f=b.charAt(c),f=oc(f,e)?function(a){return oc(a,e)}:/\s/.test(f)?function(a){return/\s/.test(a)}:function(a){return!/\s/.test(a)&&!oc(a)};0<c&&f(b.charAt(c-1));)--c;for(;d<b.length&&f(b.charAt(d));)++d}return new z(r(a.line,c),r(a.line,d))},toggleOverwrite:function(a){if(null==
+a||a!=this.state.overwrite)(this.state.overwrite=!this.state.overwrite)?mb(this.display.cursorDiv,"CodeMirror-overwrite"):kb(this.display.cursorDiv,"CodeMirror-overwrite"),K(this,"overwriteToggle",this,this.state.overwrite)},hasFocus:function(){return this.display.input.getField()==fa()},scrollTo:M(function(a,b){null==a&&null==b||mc(this);null!=a&&(this.curOp.scrollLeft=a);null!=b&&(this.curOp.scrollTop=b)}),getScrollInfo:function(){var a=this.display.scroller;return{left:a.scrollLeft,top:a.scrollTop,
+height:a.scrollHeight-da(this)-this.display.barHeight,width:a.scrollWidth-da(this)-this.display.barWidth,clientHeight:Nc(this),clientWidth:pa(this)}},scrollIntoView:M(function(a,b){null==a?(a={from:this.doc.sel.primary().head,to:null},null==b&&(b=this.options.cursorScrollMargin)):"number"==typeof a?a={from:r(a,0),to:null}:null==a.from&&(a={from:a,to:null});a.to||(a.to=a.from);a.margin=b||0;if(null!=a.from.line)mc(this),this.curOp.scrollToPos=a;else{var c=cc(this,Math.min(a.from.left,a.to.left),Math.min(a.from.top,
+a.to.top)-a.margin,Math.max(a.from.right,a.to.right),Math.max(a.from.bottom,a.to.bottom)+a.margin);this.scrollTo(c.scrollLeft,c.scrollTop)}}),setSize:M(function(a,b){function c(a){return"number"==typeof a||/^\d+$/.test(String(a))?a+"px":a}var d=this;null!=a&&(d.display.wrapper.style.width=c(a));null!=b&&(d.display.wrapper.style.height=c(b));d.options.lineWrapping&&me(this);var e=d.display.viewFrom;d.doc.iter(e,d.display.viewTo,function(a){if(a.widgets)for(var b=0;b<a.widgets.length;b++)if(a.widgets[b].noHScroll){na(d,
+e,"widget");break}++e});d.curOp.forceUpdate=!0;K(d,"refresh",this)}),operation:function(a){return T(this,a)},refresh:M(function(){var a=this.display.cachedTextHeight;Q(this);this.curOp.forceUpdate=!0;hb(this);this.scrollTo(this.doc.scrollLeft,this.doc.scrollTop);Cc(this);(null==a||.5<Math.abs(a-xa(this.display)))&&Ac(this);K(this,"refresh",this)}),swapDoc:M(function(a){var b=this.doc;b.cm=null;Ed(this,a);hb(this);this.display.input.reset();this.scrollTo(a.scrollLeft,a.scrollTop);this.curOp.forceScroll=
+!0;L(this,"swapDoc",this,b);return b}),getInputField:function(){return this.display.input.getField()},getWrapperElement:function(){return this.display.wrapper},getScrollerElement:function(){return this.display.scroller},getGutterElement:function(){return this.display.gutters}};Ya(q);var qf=q.defaults={},Ka=q.optionHandlers={},Fd=q.Init={toString:function(){return"CodeMirror.Init"}};x("value","",function(a,b){a.setValue(b)},!0);x("mode",null,function(a,b){a.doc.modeOption=b;zc(a)},!0);x("indentUnit",
+2,zc,!0);x("indentWithTabs",!1);x("smartIndent",!0);x("tabSize",4,function(a){eb(a);hb(a);Q(a)},!0);x("specialChars",/[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g,function(a,b,c){a.state.specialChars=new RegExp(b.source+(b.test("\t")?"":"|\t"),"g");c!=q.Init&&a.refresh()});x("specialCharPlaceholder",function(a){var b=t("span","•","cm-invalidchar");b.title="\\u"+a.charCodeAt(0).toString(16);b.setAttribute("aria-label",b.title);return b},function(a){a.refresh()},!0);x("electricChars",!0);
+x("inputStyle",ab?"contenteditable":"textarea",function(){throw Error("inputStyle can not (yet) be changed in a running editor");},!0);x("rtlMoveVisually",!mg);x("wholeLineUpdateBefore",!0);x("theme","default",function(a){Bd(a);ib(a)},!0);x("keyMap","default",function(a,b,c){b=pc(b);(c=c!=q.Init&&pc(c))&&c.detach&&c.detach(a,b);b.attach&&b.attach(a,c||null)});x("extraKeys",null);x("lineWrapping",!1,function(a){a.options.lineWrapping?(mb(a.display.wrapper,"CodeMirror-wrap"),a.display.sizer.style.minWidth=
+"",a.display.sizerWidth=null):(kb(a.display.wrapper,"CodeMirror-wrap"),Dc(a));Ac(a);Q(a);hb(a);setTimeout(function(){Na(a)},100)},!0);x("gutters",[],function(a){wc(a.options);ib(a)},!0);x("fixedGutter",!0,function(a,b){a.display.gutters.style.left=b?Ic(a.display)+"px":"0";a.refresh()},!0);x("coverGutterNextToScrollbar",!1,function(a){Na(a)},!0);x("scrollbarStyle","native",function(a){Cd(a);Na(a);a.display.scrollbars.setScrollTop(a.doc.scrollTop);a.display.scrollbars.setScrollLeft(a.doc.scrollLeft)},
+!0);x("lineNumbers",!1,function(a){wc(a.options);ib(a)},!0);x("firstLineNumber",1,ib,!0);x("lineNumberFormatter",function(a){return a},ib,!0);x("showCursorWhenSelecting",!1,nb,!0);x("resetSelectionOnContextMenu",!0);x("lineWiseCopyCut",!0);x("readOnly",!1,function(a,b){"nocursor"==b?(db(a),a.display.input.blur(),a.display.disabled=!0):(a.display.disabled=!1,b||a.display.input.reset())});x("disableInput",!1,function(a,b){b||a.display.input.reset()},!0);x("dragDrop",!0,function(a,b,c){!b!=!(c&&c!=q.Init)&&
+(c=a.display.dragFunctions,b=b?v:ka,b(a.display.scroller,"dragstart",c.start),b(a.display.scroller,"dragenter",c.simple),b(a.display.scroller,"dragover",c.simple),b(a.display.scroller,"drop",c.drop))});x("cursorBlinkRate",530);x("cursorScrollMargin",0);x("cursorHeight",1,nb,!0);x("singleCursorHeightPerLine",!0,nb,!0);x("workTime",100);x("workDelay",100);x("flattenSpans",!0,eb,!0);x("addModeClass",!1,eb,!0);x("pollInterval",100);x("undoDepth",200,function(a,b){a.doc.history.undoDepth=b});x("historyEventDelay",
+1250);x("viewportMargin",10,function(a){a.refresh()},!0);x("maxHighlightLength",1E4,eb,!0);x("moveInputWithCursor",!0,function(a,b){b||a.display.input.resetPosition()});x("tabindex",null,function(a,b){a.display.input.getField().tabIndex=b||""});x("autofocus",null);var pf=q.modes={},Hb=q.mimeModes={};q.defineMode=function(a,b){q.defaults.mode||"null"==a||(q.defaults.mode=a);2<arguments.length&&(b.dependencies=Array.prototype.slice.call(arguments,2));pf[a]=b};q.defineMIME=function(a,b){Hb[a]=b};q.resolveMode=
+function(a){if("string"==typeof a&&Hb.hasOwnProperty(a))a=Hb[a];else if(a&&"string"==typeof a.name&&Hb.hasOwnProperty(a.name)){var b=Hb[a.name];"string"==typeof b&&(b={name:b});a=ff(b,a);a.name=b.name}else if("string"==typeof a&&/^[\w\-]+\/[\w\-]+\+xml$/.test(a))return q.resolveMode("application/xml");return"string"==typeof a?{name:a}:a||{name:"null"}};q.getMode=function(a,b){b=q.resolveMode(b);var c=pf[b.name];if(!c)return q.getMode(a,"text/plain");c=c(a,b);if(Ib.hasOwnProperty(b.name)){var d=Ib[b.name],
+e;for(e in d)d.hasOwnProperty(e)&&(c.hasOwnProperty(e)&&(c["_"+e]=c[e]),c[e]=d[e])}c.name=b.name;b.helperType&&(c.helperType=b.helperType);if(b.modeProps)for(e in b.modeProps)c[e]=b.modeProps[e];return c};q.defineMode("null",function(){return{token:function(a){a.skipToEnd()}}});q.defineMIME("text/plain","null");var Ib=q.modeExtensions={};q.extendMode=function(a,b){var c=Ib.hasOwnProperty(a)?Ib[a]:Ib[a]={};V(b,c)};q.defineExtension=function(a,b){q.prototype[a]=b};q.defineDocExtension=function(a,b){P.prototype[a]=
+b};q.defineOption=x;var yc=[];q.defineInitHook=function(a){yc.push(a)};var $a=q.helpers={};q.registerHelper=function(a,b,c){$a.hasOwnProperty(a)||($a[a]=q[a]={_global:[]});$a[a][b]=c};q.registerGlobalHelper=function(a,b,c,d){q.registerHelper(a,b,d);$a[a]._global.push({pred:c,val:d})};var Sa=q.copyState=function(a,b){if(!0===b)return b;if(a.copyState)return a.copyState(b);var c={},d;for(d in b){var e=b[d];e instanceof Array&&(e=e.concat([]));c[d]=e}return c},Df=q.startState=function(a,b,c){return a.startState?
+a.startState(b,c):!0};q.innerMode=function(a,b){for(;a.innerMode;){var c=a.innerMode(b);if(!c||c.mode==a)break;b=c.state;a=c.mode}return c||{mode:a,state:b}};var ic=q.commands={selectAll:function(a){a.setSelection(r(a.firstLine(),0),r(a.lastLine()),ha)},singleSelection:function(a){a.setSelection(a.getCursor("anchor"),a.getCursor("head"),ha)},killLine:function(a){Va(a,function(b){if(b.empty()){var c=u(a.doc,b.head.line).text.length;return b.head.ch==c&&b.head.line<a.lastLine()?{from:b.head,to:r(b.head.line+
+1,0)}:{from:b.head,to:r(b.head.line,c)}}return{from:b.from(),to:b.to()}})},deleteLine:function(a){Va(a,function(b){return{from:r(b.from().line,0),to:w(a.doc,r(b.to().line+1,0))}})},delLineLeft:function(a){Va(a,function(a){return{from:r(a.from().line,0),to:a.from()}})},delWrappedLineLeft:function(a){Va(a,function(b){var c=a.charCoords(b.head,"div").top+5;return{from:a.coordsChar({left:0,top:c},"div"),to:b.from()}})},delWrappedLineRight:function(a){Va(a,function(b){var c=a.charCoords(b.head,"div").top+
+5,c=a.coordsChar({left:a.display.lineDiv.offsetWidth+100,top:c},"div");return{from:b.from(),to:c}})},undo:function(a){a.undo()},redo:function(a){a.redo()},undoSelection:function(a){a.undoSelection()},redoSelection:function(a){a.redoSelection()},goDocStart:function(a){a.extendSelection(r(a.firstLine(),0))},goDocEnd:function(a){a.extendSelection(r(a.lastLine()))},goLineStart:function(a){a.extendSelectionsBy(function(b){return kf(a,b.head.line)},{origin:"+move",bias:1})},goLineStartSmart:function(a){a.extendSelectionsBy(function(b){return lf(a,
+b.head)},{origin:"+move",bias:1})},goLineEnd:function(a){a.extendSelectionsBy(function(b){b=b.head.line;for(var c,d=u(a.doc,b);c=Aa(d,!1);)d=c.find(1,!0).line,b=null;c=(c=Y(d))?c[0].level%2?ac(d):bc(d):d.text.length;return r(null==b?F(d):b,c)},{origin:"+move",bias:-1})},goLineRight:function(a){a.extendSelectionsBy(function(b){b=a.charCoords(b.head,"div").top+5;return a.coordsChar({left:a.display.lineDiv.offsetWidth+100,top:b},"div")},Gb)},goLineLeft:function(a){a.extendSelectionsBy(function(b){b=
+a.charCoords(b.head,"div").top+5;return a.coordsChar({left:0,top:b},"div")},Gb)},goLineLeftSmart:function(a){a.extendSelectionsBy(function(b){var c=a.charCoords(b.head,"div").top+5,c=a.coordsChar({left:0,top:c},"div");return c.ch<a.getLine(c.line).search(/\S/)?lf(a,b.head):c},Gb)},goLineUp:function(a){a.moveV(-1,"line")},goLineDown:function(a){a.moveV(1,"line")},goPageUp:function(a){a.moveV(-1,"page")},goPageDown:function(a){a.moveV(1,"page")},goCharLeft:function(a){a.moveH(-1,"char")},goCharRight:function(a){a.moveH(1,
+"char")},goColumnLeft:function(a){a.moveH(-1,"column")},goColumnRight:function(a){a.moveH(1,"column")},goWordLeft:function(a){a.moveH(-1,"word")},goGroupRight:function(a){a.moveH(1,"group")},goGroupLeft:function(a){a.moveH(-1,"group")},goWordRight:function(a){a.moveH(1,"word")},delCharBefore:function(a){a.deleteH(-1,"char")},delCharAfter:function(a){a.deleteH(1,"char")},delWordBefore:function(a){a.deleteH(-1,"word")},delWordAfter:function(a){a.deleteH(1,"word")},delGroupBefore:function(a){a.deleteH(-1,
+"group")},delGroupAfter:function(a){a.deleteH(1,"group")},indentAuto:function(a){a.indentSelection("smart")},indentMore:function(a){a.indentSelection("add")},indentLess:function(a){a.indentSelection("subtract")},insertTab:function(a){a.replaceSelection("\t")},insertSoftTab:function(a){for(var b=[],c=a.listSelections(),d=a.options.tabSize,e=0;e<c.length;e++){var f=c[e].from(),f=aa(a.getLine(f.line),f.ch,d);b.push(Array(d-f%d+1).join(" "))}a.replaceSelections(b)},defaultTab:function(a){a.somethingSelected()?
+a.indentSelection("add"):a.execCommand("insertTab")},transposeChars:function(a){T(a,function(){for(var b=a.listSelections(),c=[],d=0;d<b.length;d++){var e=b[d].head,f=u(a.doc,e.line).text;if(f)if(e.ch==f.length&&(e=new r(e.line,e.ch-1)),0<e.ch)e=new r(e.line,e.ch+1),a.replaceRange(f.charAt(e.ch-1)+f.charAt(e.ch-2),r(e.line,e.ch-2),e,"+transpose");else if(e.line>a.doc.first){var g=u(a.doc,e.line-1).text;g&&a.replaceRange(f.charAt(0)+"\n"+g.charAt(g.length-1),r(e.line-1,g.length-1),r(e.line,1),"+transpose")}c.push(new z(e,
+e))}a.setSelections(c)})},newlineAndIndent:function(a){T(a,function(){for(var b=a.listSelections().length,c=0;c<b;c++){var d=a.listSelections()[c];a.replaceRange("\n",d.anchor,d.head,"+input");a.indentLine(d.from().line+1,null,!0);Pa(a)}})},toggleOverwrite:function(a){a.toggleOverwrite()}},ua=q.keyMap={};ua.basic={Left:"goCharLeft",Right:"goCharRight",Up:"goLineUp",Down:"goLineDown",End:"goLineEnd",Home:"goLineStartSmart",PageUp:"goPageUp",PageDown:"goPageDown",Delete:"delCharAfter",Backspace:"delCharBefore",
+"Shift-Backspace":"delCharBefore",Tab:"defaultTab","Shift-Tab":"indentAuto",Enter:"newlineAndIndent",Insert:"toggleOverwrite",Esc:"singleSelection"};ua.pcDefault={"Ctrl-A":"selectAll","Ctrl-D":"deleteLine","Ctrl-Z":"undo","Shift-Ctrl-Z":"redo","Ctrl-Y":"redo","Ctrl-Home":"goDocStart","Ctrl-End":"goDocEnd","Ctrl-Up":"goLineUp","Ctrl-Down":"goLineDown","Ctrl-Left":"goGroupLeft","Ctrl-Right":"goGroupRight","Alt-Left":"goLineStart","Alt-Right":"goLineEnd","Ctrl-Backspace":"delGroupBefore","Ctrl-Delete":"delGroupAfter",
+"Ctrl-S":"save","Ctrl-F":"find","Ctrl-G":"findNext","Shift-Ctrl-G":"findPrev","Shift-Ctrl-F":"replace","Shift-Ctrl-R":"replaceAll","Ctrl-[":"indentLess","Ctrl-]":"indentMore","Ctrl-U":"undoSelection","Shift-Ctrl-U":"redoSelection","Alt-U":"redoSelection",fallthrough:"basic"};ua.emacsy={"Ctrl-F":"goCharRight","Ctrl-B":"goCharLeft","Ctrl-P":"goLineUp","Ctrl-N":"goLineDown","Alt-F":"goWordRight","Alt-B":"goWordLeft","Ctrl-A":"goLineStart","Ctrl-E":"goLineEnd","Ctrl-V":"goPageDown","Shift-Ctrl-V":"goPageUp",
+"Ctrl-D":"delCharAfter","Ctrl-H":"delCharBefore","Alt-D":"delWordAfter","Alt-Backspace":"delWordBefore","Ctrl-K":"killLine","Ctrl-T":"transposeChars"};ua.macDefault={"Cmd-A":"selectAll","Cmd-D":"deleteLine","Cmd-Z":"undo","Shift-Cmd-Z":"redo","Cmd-Y":"redo","Cmd-Home":"goDocStart","Cmd-Up":"goDocStart","Cmd-End":"goDocEnd","Cmd-Down":"goDocEnd","Alt-Left":"goGroupLeft","Alt-Right":"goGroupRight","Cmd-Left":"goLineLeft","Cmd-Right":"goLineRight","Alt-Backspace":"delGroupBefore","Ctrl-Alt-Backspace":"delGroupAfter",
+"Alt-Delete":"delGroupAfter","Cmd-S":"save","Cmd-F":"find","Cmd-G":"findNext","Shift-Cmd-G":"findPrev","Cmd-Alt-F":"replace","Shift-Cmd-Alt-F":"replaceAll","Cmd-[":"indentLess","Cmd-]":"indentMore","Cmd-Backspace":"delWrappedLineLeft","Cmd-Delete":"delWrappedLineRight","Cmd-U":"undoSelection","Shift-Cmd-U":"redoSelection","Ctrl-Up":"goDocStart","Ctrl-Down":"goDocEnd",fallthrough:["basic","emacsy"]};ua["default"]=W?ua.macDefault:ua.pcDefault;q.normalizeKeyMap=function(a){var b={},c;for(c in a)if(a.hasOwnProperty(c)){var d=
+a[c];if(!/^(name|fallthrough|(de|at)tach)$/.test(c)){if("..."!=d)for(var e=ob(c.split(" "),Wf),f=0;f<e.length;f++){var g,h;f==e.length-1?(h=c,g=d):(h=e.slice(0,f+1).join(" "),g="...");var k=b[h];if(!k)b[h]=g;else if(k!=g)throw Error("Inconsistent bindings for "+h);}delete a[c]}}for(var l in b)a[l]=b[l];return a};var xb=q.lookupKey=function(a,b,c,d){b=pc(b);var e=b.call?b.call(a,d):b[a];if(!1===e)return"nothing";if("..."===e)return"multi";if(null!=e&&c(e))return"handled";if(b.fallthrough){if("[object Array]"!=
+Object.prototype.toString.call(b.fallthrough))return xb(a,b.fallthrough,c,d);for(e=0;e<b.fallthrough.length;e++){var f=xb(a,b.fallthrough[e],c,d);if(f)return f}}},Pf=q.isModifierKey=function(a){a="string"==typeof a?a:va[a.keyCode];return"Ctrl"==a||"Alt"==a||"Shift"==a||"Mod"==a},Rf=q.keyName=function(a,b){if(ba&&34==a.keyCode&&a["char"])return!1;var c=va[a.keyCode],d=c;if(null==d||a.altGraphKey)return!1;a.altKey&&"Alt"!=c&&(d="Alt-"+d);(of?a.metaKey:a.ctrlKey)&&"Ctrl"!=c&&(d="Ctrl-"+d);(of?a.ctrlKey:
+a.metaKey)&&"Cmd"!=c&&(d="Cmd-"+d);!b&&a.shiftKey&&"Shift"!=c&&(d="Shift-"+d);return d};q.fromTextArea=function(a,b){function c(){a.value=k.getValue()}b=b?V(b):{};b.value=a.value;!b.tabindex&&a.tabIndex&&(b.tabindex=a.tabIndex);!b.placeholder&&a.placeholder&&(b.placeholder=a.placeholder);if(null==b.autofocus){var d=fa();b.autofocus=d==a||null!=a.getAttribute("autofocus")&&d==document.body}if(a.form&&(v(a.form,"submit",c),!b.leaveSubmitMethodAlone)){var e=a.form,f=e.submit;try{var g=e.submit=function(){c();
+e.submit=f;e.submit();e.submit=g}}catch(h){}}b.finishInit=function(b){b.save=c;b.getTextArea=function(){return a};b.toTextArea=function(){b.toTextArea=isNaN;c();a.parentNode.removeChild(b.getWrapperElement());a.style.display="";a.form&&(ka(a.form,"submit",c),"function"==typeof a.form.submit&&(a.form.submit=f))}};a.style.display="none";var k=q(function(b){a.parentNode.insertBefore(b,a.nextSibling)},b);return k};var tc=q.StringStream=function(a,b){this.pos=this.start=0;this.string=a;this.tabSize=b||
+8;this.lineStart=this.lastColumnPos=this.lastColumnValue=0};tc.prototype={eol:function(){return this.pos>=this.string.length},sol:function(){return this.pos==this.lineStart},peek:function(){return this.string.charAt(this.pos)||void 0},next:function(){if(this.pos<this.string.length)return this.string.charAt(this.pos++)},eat:function(a){var b=this.string.charAt(this.pos);if("string"==typeof a?b==a:b&&(a.test?a.test(b):a(b)))return++this.pos,b},eatWhile:function(a){for(var b=this.pos;this.eat(a););return this.pos>
+b},eatSpace:function(){for(var a=this.pos;/[\s\u00a0]/.test(this.string.charAt(this.pos));)++this.pos;return this.pos>a},skipToEnd:function(){this.pos=this.string.length},skipTo:function(a){a=this.string.indexOf(a,this.pos);if(-1<a)return this.pos=a,!0},backUp:function(a){this.pos-=a},column:function(){this.lastColumnPos<this.start&&(this.lastColumnValue=aa(this.string,this.start,this.tabSize,this.lastColumnPos,this.lastColumnValue),this.lastColumnPos=this.start);return this.lastColumnValue-(this.lineStart?
+aa(this.string,this.lineStart,this.tabSize):0)},indentation:function(){return aa(this.string,null,this.tabSize)-(this.lineStart?aa(this.string,this.lineStart,this.tabSize):0)},match:function(a,b,c){if("string"==typeof a){var d=function(a){return c?a.toLowerCase():a},e=this.string.substr(this.pos,a.length);if(d(e)==d(a))return!1!==b&&(this.pos+=a.length),!0}else{if((a=this.string.slice(this.pos).match(a))&&0<a.index)return null;a&&!1!==b&&(this.pos+=a[0].length);return a}},current:function(){return this.string.slice(this.start,
+this.pos)},hideFirstChars:function(a,b){this.lineStart+=a;try{return b()}finally{this.lineStart-=a}}};var sd=0,Ha=q.TextMarker=function(a,b){this.lines=[];this.type=b;this.doc=a;this.id=++sd};Ya(Ha);Ha.prototype.clear=function(){if(!this.explicitlyCleared){var a=this.doc.cm,b=a&&!a.curOp;b&&Ja(a);if(S(this,"clear")){var c=this.find();c&&L(this,"clear",c.from,c.to)}for(var d=c=null,e=0;e<this.lines.length;++e){var f=this.lines[e],g=zb(f.markedSpans,this);a&&!this.collapsed?na(a,F(f),"text"):a&&(null!=
+g.to&&(d=F(f)),null!=g.from&&(c=F(f)));for(var h=f,k=f.markedSpans,l=g,m=void 0,p=0;p<k.length;++p)k[p]!=l&&(m||(m=[])).push(k[p]);h.markedSpans=m;null==g.from&&this.collapsed&&!ya(this.doc,f)&&a&&ca(f,xa(a.display))}if(a&&this.collapsed&&!a.options.lineWrapping)for(e=0;e<this.lines.length;++e)f=ia(this.lines[e]),g=Kb(f),g>a.display.maxLineLength&&(a.display.maxLine=f,a.display.maxLineLength=g,a.display.maxLineChanged=!0);null!=c&&a&&this.collapsed&&Q(a,c,d+1);this.lines.length=0;this.explicitlyCleared=
+!0;this.atomic&&this.doc.cantEdit&&(this.doc.cantEdit=!1,a&&ge(a.doc));a&&L(a,"markerCleared",a,this);b&&La(a);this.parent&&this.parent.clear()}};Ha.prototype.find=function(a,b){null==a&&"bookmark"==this.type&&(a=1);for(var c,d,e=0;e<this.lines.length;++e){var f=this.lines[e],g=zb(f.markedSpans,this);if(null!=g.from&&(c=r(b?f:F(f),g.from),-1==a))return c;if(null!=g.to&&(d=r(b?f:F(f),g.to),1==a))return d}return c&&{from:c,to:d}};Ha.prototype.changed=function(){var a=this.find(-1,!0),b=this,c=this.doc.cm;
+a&&c&&T(c,function(){var d=a.line,e=F(a.line);if(e=Vc(c,e))le(e),c.curOp.selectionChanged=c.curOp.forceUpdate=!0;c.curOp.updateMaxLine=!0;ya(b.doc,d)||null==b.height||(e=b.height,b.height=null,(e=ub(b)-e)&&ca(d,d.height+e))})};Ha.prototype.attachLine=function(a){if(!this.lines.length&&this.doc.cm){var b=this.doc.cm.curOp;b.maybeHiddenMarkers&&-1!=D(b.maybeHiddenMarkers,this)||(b.maybeUnhiddenMarkers||(b.maybeUnhiddenMarkers=[])).push(this)}this.lines.push(a)};Ha.prototype.detachLine=function(a){this.lines.splice(D(this.lines,
+a),1);!this.lines.length&&this.doc.cm&&(a=this.doc.cm.curOp,(a.maybeHiddenMarkers||(a.maybeHiddenMarkers=[])).push(this))};var sd=0,rc=q.SharedTextMarker=function(a,b){this.markers=a;this.primary=b;for(var c=0;c<a.length;++c)a[c].parent=this};Ya(rc);rc.prototype.clear=function(){if(!this.explicitlyCleared){this.explicitlyCleared=!0;for(var a=0;a<this.markers.length;++a)this.markers[a].clear();L(this,"clear")}};rc.prototype.find=function(a,b){return this.primary.find(a,b)};var sc=q.LineWidget=function(a,
+b,c){if(c)for(var d in c)c.hasOwnProperty(d)&&(this[d]=c[d]);this.doc=a;this.node=b};Ya(sc);sc.prototype.clear=function(){var a=this.doc.cm,b=this.line.widgets,c=this.line,d=F(c);if(null!=d&&b){for(var e=0;e<b.length;++e)b[e]==this&&b.splice(e--,1);b.length||(c.widgets=null);var f=ub(this);ca(c,Math.max(0,c.height-f));a&&T(a,function(){var b=-f;ea(c)<(a.curOp&&a.curOp.scrollTop||a.doc.scrollTop)&&lc(a,null,b);na(a,d,"widget")})}};sc.prototype.changed=function(){var a=this.height,b=this.doc.cm,c=this.line;
+this.height=null;var d=ub(this)-a;d&&(ca(c,c.height+d),b&&T(b,function(){b.curOp.forceUpdate=!0;ea(c)<(b.curOp&&b.curOp.scrollTop||b.doc.scrollTop)&&lc(b,null,d)}))};var Ab=q.Line=function(a,b,c){this.text=a;Ue(this,b);this.height=c?c(this):1};Ya(Ab);Ab.prototype.lineNo=function(){return F(this)};var bg={},ag={};Bb.prototype={chunkSize:function(){return this.lines.length},removeInner:function(a,b){for(var c=a,d=a+b;c<d;++c){var e=this.lines[c];this.height-=e.height;var f=e;f.parent=null;Te(f);L(e,
+"delete")}this.lines.splice(a,b)},collapse:function(a){a.push.apply(a,this.lines)},insertInner:function(a,b,c){this.height+=c;this.lines=this.lines.slice(0,a).concat(b).concat(this.lines.slice(a));for(a=0;a<b.length;++a)b[a].parent=this},iterN:function(a,b,c){for(b=a+b;a<b;++a)if(c(this.lines[a]))return!0}};Cb.prototype={chunkSize:function(){return this.size},removeInner:function(a,b){this.size-=b;for(var c=0;c<this.children.length;++c){var d=this.children[c],e=d.chunkSize();if(a<e){var f=Math.min(b,
+e-a),g=d.height;d.removeInner(a,f);this.height-=g-d.height;e==f&&(this.children.splice(c--,1),d.parent=null);if(0==(b-=f))break;a=0}else a-=e}25>this.size-b&&(1<this.children.length||!(this.children[0]instanceof Bb))&&(c=[],this.collapse(c),this.children=[new Bb(c)],this.children[0].parent=this)},collapse:function(a){for(var b=0;b<this.children.length;++b)this.children[b].collapse(a)},insertInner:function(a,b,c){this.size+=b.length;this.height+=c;for(var d=0;d<this.children.length;++d){var e=this.children[d],
+f=e.chunkSize();if(a<=f){e.insertInner(a,b,c);if(e.lines&&50<e.lines.length){for(;50<e.lines.length;)a=e.lines.splice(e.lines.length-25,25),a=new Bb(a),e.height-=a.height,this.children.splice(d+1,0,a),a.parent=this;this.maybeSpill()}break}a-=f}},maybeSpill:function(){if(!(10>=this.children.length)){var a=this;do{var b=a.children.splice(a.children.length-5,5),b=new Cb(b);if(a.parent){a.size-=b.size;a.height-=b.height;var c=D(a.parent.children,a);a.parent.children.splice(c+1,0,b)}else c=new Cb(a.children),
+c.parent=a,a.children=[c,b],a=c;b.parent=a.parent}while(10<a.children.length);a.parent.maybeSpill()}},iterN:function(a,b,c){for(var d=0;d<this.children.length;++d){var e=this.children[d],f=e.chunkSize();if(a<f){f=Math.min(b,f-a);if(e.iterN(a,f,c))return!0;if(0==(b-=f))break;a=0}else a-=f}}};var og=0,P=q.Doc=function(a,b,c){if(!(this instanceof P))return new P(a,b,c);null==c&&(c=0);Cb.call(this,[new Bb([new Ab("",null)])]);this.first=c;this.scrollTop=this.scrollLeft=0;this.cantEdit=!1;this.cleanGeneration=
+1;this.frontier=c;c=r(c,0);this.sel=ga(c);this.history=new uc(null);this.id=++og;this.modeOption=b;"string"==typeof a&&(a=sa(a));qd(this,{from:c,to:c,text:a});H(this,ga(c),ha)};P.prototype=ff(Cb.prototype,{constructor:P,iter:function(a,b,c){c?this.iterN(a-this.first,b-a,c):this.iterN(this.first,this.first+this.size,a)},insert:function(a,b){for(var c=0,d=0;d<b.length;++d)c+=b[d].height;this.insertInner(a-this.first,b,c)},remove:function(a,b){this.removeInner(a-this.first,b)},getValue:function(a){var b=
+xd(this,this.first,this.first+this.size);return!1===a?b:b.join(a||"\n")},setValue:N(function(a){var b=r(this.first,0),c=this.first+this.size-1;Oa(this,{from:b,to:r(c,u(this,c).text.length),text:sa(a),origin:"setValue",full:!0},!0);H(this,ga(b))}),replaceRange:function(a,b,c,d){b=w(this,b);c=c?w(this,c):b;wb(this,a,b,c,d)},getRange:function(a,b,c){a=Da(this,w(this,a),w(this,b));return!1===c?a:a.join(c||"\n")},getLine:function(a){return(a=this.getLineHandle(a))&&a.text},getLineHandle:function(a){if(qb(this,
+a))return u(this,a)},getLineNumber:function(a){return F(a)},getLineHandleVisualStart:function(a){"number"==typeof a&&(a=u(this,a));return ia(a)},lineCount:function(){return this.size},firstLine:function(){return this.first},lastLine:function(){return this.first+this.size-1},clipPos:function(a){return w(this,a)},getCursor:function(a){var b=this.sel.primary();return null==a||"head"==a?b.head:"anchor"==a?b.anchor:"end"==a||"to"==a||!1===a?b.to():b.from()},listSelections:function(){return this.sel.ranges},
+somethingSelected:function(){return this.sel.somethingSelected()},setCursor:N(function(a,b,c){a=w(this,"number"==typeof a?r(a,b||0):a);H(this,ga(a,null),c)}),setSelection:N(function(a,b,c){var d=w(this,a);a=w(this,b||a);H(this,ga(d,a),c)}),extendSelection:N(function(a,b,c){Ub(this,w(this,a),b&&w(this,b),c)}),extendSelections:N(function(a,b){for(var c=[],d=0;d<a.length;d++)c[d]=w(this,a[d]);ae(this,c)}),extendSelectionsBy:N(function(a,b){ae(this,ob(this.sel.ranges,a),b)}),setSelections:N(function(a,
+b,c){if(a.length){for(var d=0,e=[];d<a.length;d++)e[d]=new z(w(this,a[d].anchor),w(this,a[d].head));null==b&&(b=Math.min(a.length-1,this.sel.primIndex));H(this,Z(e,b),c)}}),addSelection:N(function(a,b,c){var d=this.sel.ranges.slice(0);d.push(new z(w(this,a),w(this,b||a)));H(this,Z(d,d.length-1),c)}),getSelection:function(a){for(var b=this.sel.ranges,c,d=0;d<b.length;d++){var e=Da(this,b[d].from(),b[d].to());c=c?c.concat(e):e}return!1===a?c:c.join(a||"\n")},getSelections:function(a){for(var b=[],c=
+this.sel.ranges,d=0;d<c.length;d++){var e=Da(this,c[d].from(),c[d].to());!1!==a&&(e=e.join(a||"\n"));b[d]=e}return b},replaceSelection:function(a,b,c){for(var d=[],e=0;e<this.sel.ranges.length;e++)d[e]=a;this.replaceSelections(d,b,c||"+input")},replaceSelections:N(function(a,b,c){for(var d=[],e=this.sel,f=0;f<e.ranges.length;f++){var g=e.ranges[f];d[f]={from:g.from(),to:g.to(),text:sa(a[f]),origin:c}}if(f=b&&"end"!=b){f=[];c=a=r(this.first,0);for(e=0;e<d.length;e++){var h=d[e],g=Ee(h.from,a,c),k=
+Ee(ta(h),a,c);a=h.to;c=k;"around"==b?(h=this.sel.ranges[e],h=0>y(h.head,h.anchor),f[e]=new z(h?k:g,h?g:k)):f[e]=new z(g,g)}f=new la(f,this.sel.primIndex)}b=f;for(f=d.length-1;0<=f;f--)Oa(this,d[f]);b?be(this,b):this.cm&&Pa(this.cm)}),undo:N(function(){kc(this,"undo")}),redo:N(function(){kc(this,"redo")}),undoSelection:N(function(){kc(this,"undo",!0)}),redoSelection:N(function(){kc(this,"redo",!0)}),setExtending:function(a){this.extend=a},getExtending:function(){return this.extend},historySize:function(){for(var a=
+this.history,b=0,c=0,d=0;d<a.done.length;d++)a.done[d].ranges||++b;for(d=0;d<a.undone.length;d++)a.undone[d].ranges||++c;return{undo:b,redo:c}},clearHistory:function(){this.history=new uc(this.history.maxGeneration)},markClean:function(){this.cleanGeneration=this.changeGeneration(!0)},changeGeneration:function(a){a&&(this.history.lastOp=this.history.lastSelOp=this.history.lastOrigin=null);return this.history.generation},isClean:function(a){return this.history.generation==(a||this.cleanGeneration)},
+getHistory:function(){return{done:Xa(this.history.done),undone:Xa(this.history.undone)}},setHistory:function(a){var b=this.history=new uc(this.history.maxGeneration);b.done=Xa(a.done.slice(0),null,!0);b.undone=Xa(a.undone.slice(0),null,!0)},addLineClass:N(function(a,b,c){return nc(this,a,"gutter"==b?"gutter":"class",function(a){var e="text"==b?"textClass":"background"==b?"bgClass":"gutter"==b?"gutterClass":"wrapClass";if(a[e]){if(Fb(c).test(a[e]))return!1;a[e]+=" "+c}else a[e]=c;return!0})}),removeLineClass:N(function(a,
+b,c){return nc(this,a,"gutter"==b?"gutter":"class",function(a){var e="text"==b?"textClass":"background"==b?"bgClass":"gutter"==b?"gutterClass":"wrapClass",f=a[e];if(f)if(null==c)a[e]=null;else{var g=f.match(Fb(c));if(!g)return!1;var h=g.index+g[0].length;a[e]=f.slice(0,g.index)+(g.index&&h!=f.length?" ":"")+f.slice(h)||null}else return!1;return!0})}),addLineWidget:N(function(a,b,c){return $f(this,a,b,c)}),removeLineWidget:function(a){a.clear()},markText:function(a,b,c){return Wa(this,w(this,a),w(this,
+b),c,"range")},setBookmark:function(a,b){var c={replacedWith:b&&(null==b.nodeType?b.widget:b),insertLeft:b&&b.insertLeft,clearWhenEmpty:!1,shared:b&&b.shared,handleMouseEvents:b&&b.handleMouseEvents};a=w(this,a);return Wa(this,a,a,c,"bookmark")},findMarksAt:function(a){a=w(this,a);var b=[],c=u(this,a.line).markedSpans;if(c)for(var d=0;d<c.length;++d){var e=c[d];(null==e.from||e.from<=a.ch)&&(null==e.to||e.to>=a.ch)&&b.push(e.marker.parent||e.marker)}return b},findMarks:function(a,b,c){a=w(this,a);
+b=w(this,b);var d=[],e=a.line;this.iter(a.line,b.line+1,function(f){if(f=f.markedSpans)for(var g=0;g<f.length;g++){var h=f[g];e==a.line&&a.ch>h.to||null==h.from&&e!=a.line||e==b.line&&h.from>b.ch||c&&!c(h.marker)||d.push(h.marker.parent||h.marker)}++e});return d},getAllMarks:function(){var a=[];this.iter(function(b){if(b=b.markedSpans)for(var c=0;c<b.length;++c)null!=b[c].from&&a.push(b[c].marker)});return a},posFromIndex:function(a){var b,c=this.first;this.iter(function(d){d=d.text.length+1;if(d>
+a)return b=a,!0;a-=d;++c});return w(this,r(c,b))},indexFromPos:function(a){a=w(this,a);var b=a.ch;if(a.line<this.first||0>a.ch)return 0;this.iter(this.first,a.line,function(a){b+=a.text.length+1});return b},copy:function(a){var b=new P(xd(this,this.first,this.first+this.size),this.modeOption,this.first);b.scrollTop=this.scrollTop;b.scrollLeft=this.scrollLeft;b.sel=this.sel;b.extend=!1;a&&(b.history.undoDepth=this.history.undoDepth,b.setHistory(this.getHistory()));return b},linkedDoc:function(a){a||
+(a={});var b=this.first,c=this.first+this.size;null!=a.from&&a.from>b&&(b=a.from);null!=a.to&&a.to<c&&(c=a.to);b=new P(xd(this,b,c),a.mode||this.modeOption,b);a.sharedHist&&(b.history=this.history);(this.linked||(this.linked=[])).push({doc:b,sharedHist:a.sharedHist});b.linked=[{doc:this,isParent:!0,sharedHist:a.sharedHist}];a=Re(this);for(c=0;c<a.length;c++){var d=a[c],e=d.find(),f=b.clipPos(e.from),e=b.clipPos(e.to);y(f,e)&&(f=Wa(b,f,e,d.primary,d.primary.type),d.markers.push(f),f.parent=d)}return b},
+unlinkDoc:function(a){a instanceof q&&(a=a.doc);if(this.linked)for(var b=0;b<this.linked.length;++b)if(this.linked[b].doc==a){this.linked.splice(b,1);a.unlinkDoc(this);Yf(Re(this));break}if(a.history==this.history){var c=[a.id];Ga(a,function(a){c.push(a.id)},!0);a.history=new uc(null);a.history.done=Xa(this.history.done,c);a.history.undone=Xa(this.history.undone,c)}},iterLinkedDocs:function(a){Ga(this,a)},getMode:function(){return this.mode},getEditor:function(){return this.cm}});P.prototype.eachLine=
+P.prototype.iter;var pg=["iter","insert","remove","copy","getEditor"],Jb;for(Jb in P.prototype)P.prototype.hasOwnProperty(Jb)&&0>D(pg,Jb)&&(q.prototype[Jb]=function(a){return function(){return a.apply(this.doc,arguments)}}(P.prototype[Jb]));Ya(P);var O=q.e_preventDefault=function(a){a.preventDefault?a.preventDefault():a.returnValue=!1},qg=q.e_stopPropagation=function(a){a.stopPropagation?a.stopPropagation():a.cancelBubble=!0},jd=q.e_stop=function(a){O(a);qg(a)},v=q.on=function(a,b,c){a.addEventListener?
+a.addEventListener(b,c,!1):a.attachEvent?a.attachEvent("on"+b,c):(a=a._handlers||(a._handlers={}),(a[b]||(a[b]=[])).push(c))},ka=q.off=function(a,b,c){if(a.removeEventListener)a.removeEventListener(b,c,!1);else if(a.detachEvent)a.detachEvent("on"+b,c);else if(a=a._handlers&&a._handlers[b])for(b=0;b<a.length;++b)if(a[b]==c){a.splice(b,1);break}},K=q.signal=function(a,b){var c=a._handlers&&a._handlers[b];if(c)for(var d=Array.prototype.slice.call(arguments,2),e=0;e<c.length;++e)c[e].apply(null,d)},Db=
+null,Hd=30,Ae=q.Pass={toString:function(){return"CodeMirror.Pass"}},ha={scroll:!1},kd={origin:"*mouse"},Gb={origin:"+move"};bb.prototype.set=function(a,b){clearTimeout(this.id);this.id=setTimeout(b,a)};var aa=q.countColumn=function(a,b,c,d,e){null==b&&(b=a.search(/[^\s\u00a0]/),-1==b&&(b=a.length));d=d||0;for(e=e||0;;){var f=a.indexOf("\t",d);if(0>f||f>=b)return e+(b-d);e+=f-d;e+=c-e%c;d=f+1}},vc=[""],Za=function(a){a.select()};Qa?Za=function(a){a.selectionStart=0;a.selectionEnd=a.value.length}:B&&
+(Za=function(a){try{a.select()}catch(b){}});var rg=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/,gf=q.isWordChar=function(a){return/\w/.test(a)||"\80"<a&&(a.toUpperCase()!=a.toLowerCase()||rg.test(a))},ig=/[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/,
+Ea;Ea=document.createRange?function(a,b,c,d){var e=document.createRange();e.setEnd(d||a,c);e.setStart(a,b);return e}:function(a,b,c){var d=document.body.createTextRange();try{d.moveToElementText(a.parentNode)}catch(e){return d}d.collapse(!0);d.moveEnd("character",c);d.moveStart("character",b);return d};var Wc=q.contains=function(a,b){3==b.nodeType&&(b=b.parentNode);if(a.contains)return a.contains(b);do if(11==b.nodeType&&(b=b.host),b==a)return!0;while(b=b.parentNode)};B&&11>C&&(fa=function(){try{return document.activeElement}catch(a){return document.body}});
+var kb=q.rmClass=function(a,b){var c=a.className,d=Fb(b).exec(c);if(d){var e=c.slice(d.index+d[0].length);a.className=c.slice(0,d.index)+(e?d[1]+e:"")}},mb=q.addClass=function(a,b){var c=a.className;Fb(b).test(c)||(a.className+=(c?" ":"")+b)},Dd=!1,Lf=function(){if(B&&9>C)return!1;var a=t("div");return"draggable"in a||"dragDrop"in a}(),yd,vd,sa=q.splitLines=3!="\n\nb".split(/\n/).length?function(a){for(var b=0,c=[],d=a.length;b<=d;){var e=a.indexOf("\n",b);-1==e&&(e=a.length);var f=a.slice(b,"\r"==
+a.charAt(e-1)?e-1:e),g=f.indexOf("\r");-1!=g?(c.push(f.slice(0,g)),b+=g+1):(c.push(f),b=e+1)}return c}:function(a){return a.split(/\r\n?|\n/)},ng=window.getSelection?function(a){try{return a.selectionStart!=a.selectionEnd}catch(b){return!1}}:function(a){try{var b=a.ownerDocument.selection.createRange()}catch(c){}return b&&b.parentElement()==a?0!=b.compareEndPoints("StartToEnd",b):!1},Ce=function(){var a=t("div");if("oncopy"in a)return!0;a.setAttribute("oncopy","return;");return"function"==typeof a.oncopy}(),
+bd=null,va={3:"Enter",8:"Backspace",9:"Tab",13:"Enter",16:"Shift",17:"Ctrl",18:"Alt",19:"Pause",20:"CapsLock",27:"Esc",32:"Space",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"Left",38:"Up",39:"Right",40:"Down",44:"PrintScrn",45:"Insert",46:"Delete",59:";",61:"\x3d",91:"Mod",92:"Mod",93:"Mod",107:"\x3d",109:"-",127:"Delete",173:"-",186:";",187:"\x3d",188:",",189:"-",190:".",191:"/",192:"`",219:"[",220:"\\",221:"]",222:"'",63232:"Up",63233:"Down",63234:"Left",63235:"Right",63272:"Delete",63273:"Home",
+63275:"End",63276:"PageUp",63277:"PageDown",63302:"Insert"};q.keyNames=va;(function(){for(var a=0;10>a;a++)va[a+48]=va[a+96]=String(a);for(a=65;90>=a;a++)va[a]=String.fromCharCode(a);for(a=1;12>=a;a++)va[a+111]=va[a+63235]="F"+a})();var vb,gg=function(){function a(a){return 247>=a?"bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN".charAt(a):
+1424<=a&&1524>=a?"R":1536<=a&&1773>=a?"rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm".charAt(a-1536):1774<=a&&2220>=a?"r":8192<=a&&8203>=a?"w":8204==a?"b":"L"}function b(a,b,c){this.level=a;this.from=b;this.to=c}var c=/[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/,d=/[stwN]/,e=/[LRr]/,f=/[Lb1n]/,g=/[1n]/;return function(h){if(!c.test(h))return!1;
+for(var k=h.length,l=[],m=0,p;m<k;++m)l.push(a(h.charCodeAt(m)));for(var m=0,n="L";m<k;++m)p=l[m],"m"==p?l[m]=n:n=p;m=0;for(n="L";m<k;++m)p=l[m],"1"==p&&"r"==n?l[m]="n":e.test(p)&&(n=p,"r"==p&&(l[m]="R"));m=1;for(n=l[0];m<k-1;++m)p=l[m],"+"==p&&"1"==n&&"1"==l[m+1]?l[m]="1":","!=p||n!=l[m+1]||"1"!=n&&"n"!=n||(l[m]=n),n=p;for(m=0;m<k;++m)if(p=l[m],","==p)l[m]="N";else if("%"==p){for(n=m+1;n<k&&"%"==l[n];++n);var q=m&&"!"==l[m-1]||n<k&&"1"==l[n]?"1":"N";for(p=m;p<n;++p)l[p]=q;m=n-1}m=0;for(n="L";m<k;++m)p=
+l[m],"L"==n&&"1"==p?l[m]="L":e.test(p)&&(n=p);for(m=0;m<k;++m)if(d.test(l[m])){for(n=m+1;n<k&&d.test(l[n]);++n);p="L"==(n<k?l[n]:"L");q="L"==(m?l[m-1]:"L")||p?"L":"R";for(p=m;p<n;++p)l[p]=q;m=n-1}for(var n=[],r,m=0;m<k;)if(f.test(l[m])){p=m;for(++m;m<k&&f.test(l[m]);++m);n.push(new b(0,p,m))}else{var t=m,q=n.length;for(++m;m<k&&"L"!=l[m];++m);for(p=t;p<m;)if(g.test(l[p])){t<p&&n.splice(q,0,new b(1,t,p));t=p;for(++p;p<m&&g.test(l[p]);++p);n.splice(q,0,new b(2,t,p));t=p}else++p;t<m&&n.splice(q,0,new b(1,
+t,m))}1==n[0].level&&(r=h.match(/^\s+/))&&(n[0].from=r[0].length,n.unshift(new b(0,0,r[0].length)));1==A(n).level&&(r=h.match(/\s+$/))&&(A(n).to-=r[0].length,n.push(new b(0,k-r[0].length,k)));2==n[0].level&&n.unshift(new b(1,n[0].to,n[0].to));n[0].level!=A(n).level&&n.push(new b(n[0].level,k,k));return n}}();q.version="5.2.0";return q});
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/javascript.js b/release/samples/toolbarconfigurator/lib/codemirror/javascript.js
new file mode 100644 (file)
index 0000000..c76ab46
--- /dev/null
@@ -0,0 +1,25 @@
+(function(p){"object"==typeof exports&&"object"==typeof module?p(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],p):p(CodeMirror)})(function(p){p.defineMode("javascript",function(oa,t){function q(a,c,e){E=a;I=e;return c}function w(a,c){var e=a.next();if('"'==e||"'"==e)return c.tokenize=pa(e),c.tokenize(a,c);if("."==e&&a.match(/^\d+(?:[eE][+\-]?\d+)?/))return q("number","number");if("."==e&&a.match(".."))return q("spread","meta");if(/[\[\]{}\(\),;\:\.]/.test(e))return q(e);
+if("\x3d"==e&&a.eat("\x3e"))return q("\x3d\x3e","operator");if("0"==e&&a.eat(/x/i))return a.eatWhile(/[\da-f]/i),q("number","number");if(/\d/.test(e))return a.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/),q("number","number");if("/"==e){if(a.eat("*"))return c.tokenize=J,J(a,c);if(a.eat("/"))return a.skipToEnd(),q("comment","comment");if("operator"==c.lastType||"keyword c"==c.lastType||"sof"==c.lastType||/^[\[{}\(,;:]$/.test(c.lastType)){a:for(var e=!1,d,b=!1;null!=(d=a.next());){if(!e){if("/"==d&&!b)break a;
+"["==d?b=!0:b&&"]"==d&&(b=!1)}e=!e&&"\\"==d}a.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);return q("regexp","string-2")}a.eatWhile(K);return q("operator","operator",a.current())}if("`"==e)return c.tokenize=Q,Q(a,c);if("#"==e)return a.skipToEnd(),q("error","error");if(K.test(e))return a.eatWhile(K),q("operator","operator",a.current());if(R.test(e))return a.eatWhile(R),e=a.current(),(d=ba.propertyIsEnumerable(e)&&ba[e])&&"."!=c.lastType?q(d.type,d.style,e):q("variable","variable",e)}function pa(a){return function(c,
+e){var d=!1,b;if(L&&"@"==c.peek()&&c.match(qa))return e.tokenize=w,q("jsonld-keyword","meta");for(;null!=(b=c.next())&&(b!=a||d);)d=!d&&"\\"==b;d||(e.tokenize=w);return q("string","string")}}function J(a,c){for(var e=!1,d;d=a.next();){if("/"==d&&e){c.tokenize=w;break}e="*"==d}return q("comment","comment")}function Q(a,c){for(var e=!1,d;null!=(d=a.next());){if(!e&&("`"==d||"$"==d&&a.eat("{"))){c.tokenize=w;break}e=!e&&"\\"==d}return q("quasi","string-2",a.current())}function S(a,c){c.fatArrowAt&&(c.fatArrowAt=
+null);var e=a.string.indexOf("\x3d\x3e",a.start);if(!(0>e)){for(var d=0,b=!1,e=e-1;0<=e;--e){var f=a.string.charAt(e),g="([{}])".indexOf(f);if(0<=g&&3>g){if(!d){++e;break}if(0==--d)break}else if(3<=g&&6>g)++d;else if(R.test(f))b=!0;else{if(/["'\/]/.test(f))return;if(b&&!d){++e;break}}}b&&!d&&(c.fatArrowAt=e)}}function ca(a,c,b,d,f,h){this.indented=a;this.column=c;this.type=b;this.prev=f;this.info=h;null!=d&&(this.align=d)}function g(){for(var a=arguments.length-1;0<=a;a--)f.cc.push(arguments[a])}
+function b(){g.apply(null,arguments);return!0}function x(a){function c(c){for(;c;c=c.next)if(c.name==a)return!0;return!1}var b=f.state;b.context?(f.marked="def",c(b.localVars)||(b.localVars={name:a,next:b.localVars})):!c(b.globalVars)&&t.globalVars&&(b.globalVars={name:a,next:b.globalVars})}function y(){f.state.context={prev:f.state.context,vars:f.state.localVars};f.state.localVars=ra}function z(){f.state.localVars=f.state.context.vars;f.state.context=f.state.context.prev}function l(a,c){var b=function(){var b=
+f.state,e=b.indented;if("stat"==b.lexical.type)e=b.lexical.indented;else for(var h=b.lexical;h&&")"==h.type&&h.align;h=h.prev)e=h.indented;b.lexical=new ca(e,f.stream.column(),a,null,b.lexical,c)};b.lex=!0;return b}function k(){var a=f.state;a.lexical.prev&&(")"==a.lexical.type&&(a.indented=a.lexical.indented),a.lexical=a.lexical.prev)}function m(a){function c(e){return e==a?b():";"==a?g():b(c)}return c}function r(a,c){return"var"==a?b(l("vardef",c.length),T,m(";"),k):"keyword a"==a?b(l("form"),n,
+r,k):"keyword b"==a?b(l("form"),r,k):"{"==a?b(l("}"),U,k):";"==a?b():"if"==a?("else"==f.state.lexical.info&&f.state.cc[f.state.cc.length-1]==k&&f.state.cc.pop()(),b(l("form"),n,r,k,da)):"function"==a?b(v):"for"==a?b(l("form"),ea,r,k):"variable"==a?b(l("stat"),sa):"switch"==a?b(l("form"),n,l("}","switch"),m("{"),U,k,k):"case"==a?b(n,m(":")):"default"==a?b(m(":")):"catch"==a?b(l("form"),y,m("("),V,m(")"),r,k,z):"module"==a?b(l("form"),y,ta,z,k):"class"==a?b(l("form"),ua,k):"export"==a?b(l("form"),va,
+k):"import"==a?b(l("form"),wa,k):g(l("stat"),n,m(";"),k)}function n(a){return fa(a,!1)}function u(a){return fa(a,!0)}function fa(a,c){if(f.state.fatArrowAt==f.stream.start){var e=c?ga:ha;if("("==a)return b(y,l(")"),F(A,")"),k,m("\x3d\x3e"),e,z);if("variable"==a)return g(y,A,m("\x3d\x3e"),e,z)}e=c?W:M;return xa.hasOwnProperty(a)?b(e):"function"==a?b(v,e):"keyword c"==a?b(c?ia:X):"("==a?b(l(")"),X,N,m(")"),k,e):"operator"==a||"spread"==a?b(c?u:n):"["==a?b(l("]"),ya,k,e):"{"==a?G(za,"}",null,e):"quasi"==
+a?g(O,e):b()}function X(a){return a.match(/[;\}\)\],]/)?g():g(n)}function ia(a){return a.match(/[;\}\)\],]/)?g():g(u)}function M(a,c){return","==a?b(n):W(a,c,!1)}function W(a,c,e){var d=0==e?M:W,f=0==e?n:u;if("\x3d\x3e"==a)return b(y,e?ga:ha,z);if("operator"==a)return/\+\+|--/.test(c)?b(d):"?"==c?b(n,m(":"),f):b(f);if("quasi"==a)return g(O,d);if(";"!=a){if("("==a)return G(u,")","call",d);if("."==a)return b(Aa,d);if("["==a)return b(l("]"),X,m("]"),k,d)}}function O(a,c){return"quasi"!=a?g():"${"!=c.slice(c.length-
+2)?b(O):b(n,Ba)}function Ba(a){if("}"==a)return f.marked="string-2",f.state.tokenize=Q,b(O)}function ha(a){S(f.stream,f.state);return g("{"==a?r:n)}function ga(a){S(f.stream,f.state);return g("{"==a?r:u)}function sa(a){return":"==a?b(k,r):g(M,m(";"),k)}function Aa(a){if("variable"==a)return f.marked="property",b()}function za(a,c){if("variable"==a||"keyword"==f.style)return f.marked="property","get"==c||"set"==c?b(Ca):b(H);if("number"==a||"string"==a)return f.marked=L?"property":f.style+" property",
+b(H);if("jsonld-keyword"==a)return b(H);if("["==a)return b(n,m("]"),H)}function Ca(a){if("variable"!=a)return g(H);f.marked="property";return b(v)}function H(a){if(":"==a)return b(u);if("("==a)return g(v)}function F(a,c){function e(d){return","==d?(d=f.state.lexical,"call"==d.info&&(d.pos=(d.pos||0)+1),b(a,e)):d==c?b():b(m(c))}return function(d){return d==c?b():g(a,e)}}function G(a,c,e){for(var d=3;d<arguments.length;d++)f.cc.push(arguments[d]);return b(l(c,e),F(a,c),k)}function U(a){return"}"==a?
+b():g(r,U)}function ja(a){if(ka&&":"==a)return b(Da)}function Da(a){if("variable"==a)return f.marked="variable-3",b()}function T(){return g(A,ja,Y,Ea)}function A(a,c){if("variable"==a)return x(c),b();if("["==a)return G(A,"]");if("{"==a)return G(Fa,"}")}function Fa(a,c){if("variable"==a&&!f.stream.match(/^\s*:/,!1))return x(c),b(Y);"variable"==a&&(f.marked="property");return b(m(":"),A,Y)}function Y(a,c){if("\x3d"==c)return b(u)}function Ea(a){if(","==a)return b(T)}function da(a,c){if("keyword b"==
+a&&"else"==c)return b(l("form","else"),r,k)}function ea(a){if("("==a)return b(l(")"),Ga,m(")"),k)}function Ga(a){return"var"==a?b(T,m(";"),P):";"==a?b(P):"variable"==a?b(Ha):g(n,m(";"),P)}function Ha(a,c){return"in"==c||"of"==c?(f.marked="keyword",b(n)):b(M,P)}function P(a,c){return";"==a?b(la):"in"==c||"of"==c?(f.marked="keyword",b(n)):g(n,m(";"),la)}function la(a){")"!=a&&b(n)}function v(a,c){if("*"==c)return f.marked="keyword",b(v);if("variable"==a)return x(c),b(v);if("("==a)return b(y,l(")"),
+F(V,")"),k,r,z)}function V(a){return"spread"==a?b(V):g(A,ja)}function ua(a,c){if("variable"==a)return x(c),b(ma)}function ma(a,c){if("extends"==c)return b(n,ma);if("{"==a)return b(l("}"),B,k)}function B(a,c){if("variable"==a||"keyword"==f.style){if("static"==c)return f.marked="keyword",b(B);f.marked="property";return"get"==c||"set"==c?b(Ia,v,B):b(v,B)}if("*"==c)return f.marked="keyword",b(B);if(";"==a)return b(B);if("}"==a)return b()}function Ia(a){if("variable"!=a)return g();f.marked="property";
+return b()}function ta(a,c){if("string"==a)return b(r);if("variable"==a)return x(c),b(Z)}function va(a,c){return"*"==c?(f.marked="keyword",b(Z,m(";"))):"default"==c?(f.marked="keyword",b(n,m(";"))):g(r)}function wa(a){return"string"==a?b():g(aa,Z)}function aa(a,c){if("{"==a)return G(aa,"}");"variable"==a&&x(c);"*"==c&&(f.marked="keyword");return b(Ja)}function Ja(a,c){if("as"==c)return f.marked="keyword",b(aa)}function Z(a,c){if("from"==c)return f.marked="keyword",b(n)}function ya(a){return"]"==a?
+b():g(u,Ka)}function Ka(a){return"for"==a?g(N,m("]")):","==a?b(F(ia,"]")):g(F(u,"]"))}function N(a){if("for"==a)return b(ea,N);if("if"==a)return b(n,N)}var C=oa.indentUnit,na=t.statementIndent,L=t.jsonld,D=t.json||L,ka=t.typescript,R=t.wordCharacters||/[\w$\xa1-\uffff]/,ba=function(){function a(a){return{type:a,style:"keyword"}}var c=a("keyword a"),b=a("keyword b"),d=a("keyword c"),f=a("operator"),h={type:"atom",style:"atom"},c={"if":a("if"),"while":c,"with":c,"else":b,"do":b,"try":b,"finally":b,
+"return":d,"break":d,"continue":d,"new":d,"delete":d,"throw":d,"debugger":d,"var":a("var"),"const":a("var"),let:a("var"),"function":a("function"),"catch":a("catch"),"for":a("for"),"switch":a("switch"),"case":a("case"),"default":a("default"),"in":f,"typeof":f,"instanceof":f,"true":h,"false":h,"null":h,undefined:h,NaN:h,Infinity:h,"this":a("this"),module:a("module"),"class":a("class"),"super":a("atom"),yield:d,"export":a("export"),"import":a("import"),"extends":d};if(ka){var b={type:"variable",style:"variable-3"},
+b={"interface":a("interface"),"extends":a("extends"),constructor:a("constructor"),"public":a("public"),"private":a("private"),"protected":a("protected"),"static":a("static"),string:b,number:b,bool:b,any:b},g;for(g in b)c[g]=b[g]}return c}(),K=/[+\-*&%=<>!?|~^]/,qa=/^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/,E,I,xa={atom:!0,number:!0,variable:!0,string:!0,regexp:!0,"this":!0,"jsonld-keyword":!0},f={state:null,column:null,marked:null,cc:null},ra={name:"this",
+next:{name:"arguments"}};k.lex=!0;return{startState:function(a){a={tokenize:w,lastType:"sof",cc:[],lexical:new ca((a||0)-C,0,"block",!1),localVars:t.localVars,context:t.localVars&&{vars:t.localVars},indented:0};t.globalVars&&"object"==typeof t.globalVars&&(a.globalVars=t.globalVars);return a},token:function(a,b){a.sol()&&(b.lexical.hasOwnProperty("align")||(b.lexical.align=!1),b.indented=a.indentation(),S(a,b));if(b.tokenize!=J&&a.eatSpace())return null;var e=b.tokenize(a,b);if("comment"==E)return e;
+b.lastType="operator"!=E||"++"!=I&&"--"!=I?E:"incdec";a:{var d=E,g=I,h=b.cc;f.state=b;f.stream=a;f.marked=null;f.cc=h;f.style=e;b.lexical.hasOwnProperty("align")||(b.lexical.align=!0);for(;;)if((h.length?h.pop():D?n:r)(d,g)){for(;h.length&&h[h.length-1].lex;)h.pop()();if(f.marked){e=f.marked;break a}if(d="variable"==d)b:{for(d=b.localVars;d;d=d.next)if(d.name==g){d=!0;break b}for(h=b.context;h;h=h.prev)for(d=h.vars;d;d=d.next)if(d.name==g){d=!0;break b}d=void 0}if(d){e="variable-2";break a}break a}}return e},
+indent:function(a,b){if(a.tokenize==J)return p.Pass;if(a.tokenize!=w)return 0;var e=b&&b.charAt(0),d=a.lexical;if(!/^\s*else\b/.test(b))for(var f=a.cc.length-1;0<=f;--f){var g=a.cc[f];if(g==k)d=d.prev;else if(g!=da)break}"stat"==d.type&&"}"==e&&(d=d.prev);na&&")"==d.type&&"stat"==d.prev.type&&(d=d.prev);f=d.type;g=e==f;return"vardef"==f?d.indented+("operator"==a.lastType||","==a.lastType?d.info+1:0):"form"==f&&"{"==e?d.indented:"form"==f?d.indented+C:"stat"==f?(e=d.indented,d="operator"==a.lastType||
+","==a.lastType||K.test(b.charAt(0))||/[,.]/.test(b.charAt(0)),e+(d?na||C:0)):"switch"!=d.info||g||0==t.doubleIndentSwitch?d.align?d.column+(g?0:1):d.indented+(g?0:C):d.indented+(/^(?:case|default)\b/.test(b)?C:2*C)},electricInput:/^\s*(?:case .*?:|default:|\{|\})$/,blockCommentStart:D?null:"/*",blockCommentEnd:D?null:"*/",lineComment:D?null:"//",fold:"brace",closeBrackets:"()[]{}''\"\"``",helperType:D?"json":"javascript",jsonldMode:L,jsonMode:D}});p.registerHelper("wordChars","javascript",/[\w$]/);
+p.defineMIME("text/javascript","javascript");p.defineMIME("text/ecmascript","javascript");p.defineMIME("application/javascript","javascript");p.defineMIME("application/x-javascript","javascript");p.defineMIME("application/ecmascript","javascript");p.defineMIME("application/json",{name:"javascript",json:!0});p.defineMIME("application/x-json",{name:"javascript",json:!0});p.defineMIME("application/ld+json",{name:"javascript",jsonld:!0});p.defineMIME("text/typescript",{name:"javascript",typescript:!0});
+p.defineMIME("application/typescript",{name:"javascript",typescript:!0})});
\ No newline at end of file
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/neo.css b/release/samples/toolbarconfigurator/lib/codemirror/neo.css
new file mode 100644 (file)
index 0000000..f932db0
--- /dev/null
@@ -0,0 +1,36 @@
+/* neo theme for codemirror */\r
+\r
+/* Color scheme */\r
+\r
+.cm-s-neo.CodeMirror {\r
+  background-color:#ffffff;\r
+  color:#2e383c;\r
+  line-height:1.4375;\r
+}\r
+.cm-s-neo .cm-comment {color:#75787b}\r
+.cm-s-neo .cm-keyword, .cm-s-neo .cm-property {color:#1d75b3}\r
+.cm-s-neo .cm-atom,.cm-s-neo .cm-number {color:#75438a}\r
+.cm-s-neo .cm-node,.cm-s-neo .cm-tag {color:#9c3328}\r
+.cm-s-neo .cm-string {color:#b35e14}\r
+.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier {color:#047d65}\r
+\r
+\r
+/* Editor styling */\r
+\r
+.cm-s-neo pre {\r
+  padding:0;\r
+}\r
+\r
+.cm-s-neo .CodeMirror-gutters {\r
+  border:none;\r
+  border-right:10px solid transparent;\r
+  background-color:transparent;\r
+}\r
+\r
+.cm-s-neo .CodeMirror-linenumber {\r
+  padding:0;\r
+  color:#e0e2e5;\r
+}\r
+\r
+.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }\r
+.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }\r
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/show-hint.css b/release/samples/toolbarconfigurator/lib/codemirror/show-hint.css
new file mode 100644 (file)
index 0000000..e38bfb6
--- /dev/null
@@ -0,0 +1,38 @@
+.CodeMirror-hints {\r
+  position: absolute;\r
+  z-index: 10;\r
+  overflow: hidden;\r
+  list-style: none;\r
+\r
+  margin: 0;\r
+  padding: 2px;\r
+\r
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);\r
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);\r
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);\r
+  border-radius: 3px;\r
+  border: 1px solid silver;\r
+\r
+  background: white;\r
+  font-size: 90%;\r
+  font-family: monospace;\r
+\r
+  max-height: 20em;\r
+  overflow-y: auto;\r
+}\r
+\r
+.CodeMirror-hint {\r
+  margin: 0;\r
+  padding: 0 4px;\r
+  border-radius: 2px;\r
+  max-width: 19em;\r
+  overflow: hidden;\r
+  white-space: pre;\r
+  color: black;\r
+  cursor: pointer;\r
+}\r
+\r
+li.CodeMirror-hint-active {\r
+  background: #08f;\r
+  color: white;\r
+}\r
diff --git a/release/samples/toolbarconfigurator/lib/codemirror/show-hint.js b/release/samples/toolbarconfigurator/lib/codemirror/show-hint.js
new file mode 100644 (file)
index 0000000..072359c
--- /dev/null
@@ -0,0 +1,16 @@
+(function(f){"object"==typeof exports&&"object"==typeof module?f(require("../../lib/codemirror")):"function"==typeof define&&define.amd?define(["../../lib/codemirror"],f):f(CodeMirror)})(function(f){function p(a,b){this.cm=a;this.options=this.buildOptions(b);this.widget=null;this.tick=this.debounce=0;this.startPos=this.cm.getCursor();this.startLen=this.cm.getLine(this.startPos.line).length;var c=this;a.on("cursorActivity",this.activityFunc=function(){c.cursorActivity()})}function w(a,b){function c(a,
+c){var d;d="string"!=typeof c?function(a){return c(a,b)}:e.hasOwnProperty(c)?e[c]:c;f[a]=d}var e={Up:function(){b.moveFocus(-1)},Down:function(){b.moveFocus(1)},PageUp:function(){b.moveFocus(-b.menuSize()+1,!0)},PageDown:function(){b.moveFocus(b.menuSize()-1,!0)},Home:function(){b.setFocus(0)},End:function(){b.setFocus(b.length-1)},Enter:b.pick,Tab:b.pick,Esc:b.close},d=a.options.customKeys,f=d?{}:e;if(d)for(var g in d)d.hasOwnProperty(g)&&c(g,d[g]);if(d=a.options.extraKeys)for(g in d)d.hasOwnProperty(g)&&
+c(g,d[g]);return f}function v(a,b){for(;b&&b!=a;){if("LI"===b.nodeName.toUpperCase()&&b.parentNode==a)return b;b=b.parentNode}}function n(a,b){this.completion=a;this.data=b;this.picked=!1;var c=this,e=a.cm,d=this.hints=document.createElement("ul");d.className="CodeMirror-hints";this.selectedHint=b.selectedHint||0;for(var m=b.list,g=0;g<m.length;++g){var l=d.appendChild(document.createElement("li")),h=m[g],k="CodeMirror-hint"+(g!=this.selectedHint?"":" CodeMirror-hint-active");null!=h.className&&(k=
+h.className+" "+k);l.className=k;h.render?h.render(l,b,h):l.appendChild(document.createTextNode(h.displayText||("string"==typeof h?h:h.text)));l.hintId=g}var g=e.cursorCoords(a.options.alignWithWord?b.from:null),r=g.left,t=g.bottom,n=!0;d.style.left=r+"px";d.style.top=t+"px";l=window.innerWidth||Math.max(document.body.offsetWidth,document.documentElement.offsetWidth);k=window.innerHeight||Math.max(document.body.offsetHeight,document.documentElement.offsetHeight);(a.options.container||document.body).appendChild(d);
+h=d.getBoundingClientRect();if(0<h.bottom-k){var u=h.bottom-h.top;0<g.top-(g.bottom-h.top)-u?(d.style.top=(t=g.top-u)+"px",n=!1):u>k&&(d.style.height=k-5+"px",d.style.top=(t=g.bottom-h.top)+"px",k=e.getCursor(),b.from.ch!=k.ch&&(g=e.cursorCoords(k),d.style.left=(r=g.left)+"px",h=d.getBoundingClientRect()))}k=h.right-l;0<k&&(h.right-h.left>l&&(d.style.width=l-5+"px",k-=h.right-h.left-l),d.style.left=(r=g.left-k)+"px");e.addKeyMap(this.keyMap=w(a,{moveFocus:function(a,b){c.changeActive(c.selectedHint+
+a,b)},setFocus:function(a){c.changeActive(a)},menuSize:function(){return c.screenAmount()},length:m.length,close:function(){a.close()},pick:function(){c.pick()},data:b}));if(a.options.closeOnUnfocus){var p;e.on("blur",this.onBlur=function(){p=setTimeout(function(){a.close()},100)});e.on("focus",this.onFocus=function(){clearTimeout(p)})}var q=e.getScrollInfo();e.on("scroll",this.onScroll=function(){var c=e.getScrollInfo(),b=e.getWrapperElement().getBoundingClientRect(),f=t+q.top-c.top,g=f-(window.pageYOffset||
+(document.documentElement||document.body).scrollTop);n||(g+=d.offsetHeight);if(g<=b.top||g>=b.bottom)return a.close();d.style.top=f+"px";d.style.left=r+q.left-c.left+"px"});f.on(d,"dblclick",function(a){(a=v(d,a.target||a.srcElement))&&null!=a.hintId&&(c.changeActive(a.hintId),c.pick())});f.on(d,"click",function(b){(b=v(d,b.target||b.srcElement))&&null!=b.hintId&&(c.changeActive(b.hintId),a.options.completeOnSingleClick&&c.pick())});f.on(d,"mousedown",function(){setTimeout(function(){e.focus()},20)});
+f.signal(b,"select",m[0],d.firstChild);return!0}f.showHint=function(a,b,c){if(!b)return a.showHint(c);c&&c.async&&(b.async=!0);b={hint:b};if(c)for(var e in c)b[e]=c[e];return a.showHint(b)};f.defineExtension("showHint",function(a){1<this.listSelections().length||this.somethingSelected()||(this.state.completionActive&&this.state.completionActive.close(),a=this.state.completionActive=new p(this,a),a.options.hint&&(f.signal(this,"startCompletion",this),a.update()))});var x=window.requestAnimationFrame||
+function(a){return setTimeout(a,1E3/60)},y=window.cancelAnimationFrame||clearTimeout;p.prototype={close:function(){this.active()&&(this.tick=this.cm.state.completionActive=null,this.cm.off("cursorActivity",this.activityFunc),this.widget&&this.widget.close(),f.signal(this.cm,"endCompletion",this.cm))},active:function(){return this.cm.state.completionActive==this},pick:function(a,b){var c=a.list[b];c.hint?c.hint(this.cm,a,c):this.cm.replaceRange("string"==typeof c?c:c.text,c.from||a.from,c.to||a.to,
+"complete");f.signal(a,"pick",c);this.close()},showHints:function(a){if(!a||!a.list.length||!this.active())return this.close();this.options.completeSingle&&1==a.list.length?this.pick(a,0):this.showWidget(a)},cursorActivity:function(){this.debounce&&(y(this.debounce),this.debounce=0);var a=this.cm.getCursor(),b=this.cm.getLine(a.line);if(a.line!=this.startPos.line||b.length-a.ch!=this.startLen-this.startPos.ch||a.ch<this.startPos.ch||this.cm.somethingSelected()||a.ch&&this.options.closeCharacters.test(b.charAt(a.ch-
+1)))this.close();else{var c=this;this.debounce=x(function(){c.update()});this.widget&&this.widget.disable()}},update:function(){if(null!=this.tick)if(this.data&&f.signal(this.data,"update"),this.options.hint.async){var a=++this.tick,b=this;this.options.hint(this.cm,function(c){b.tick==a&&b.finishUpdate(c)},this.options)}else this.finishUpdate(this.options.hint(this.cm,this.options),a)},finishUpdate:function(a){this.data=a;var b=this.widget&&this.widget.picked;this.widget&&this.widget.close();a&&a.list.length&&
+(b&&1==a.list.length?this.pick(a,0):this.widget=new n(this,a))},showWidget:function(a){this.data=a;this.widget=new n(this,a);f.signal(a,"shown")},buildOptions:function(a){var b=this.cm.options.hintOptions,c={},e;for(e in q)c[e]=q[e];if(b)for(e in b)void 0!==b[e]&&(c[e]=b[e]);if(a)for(e in a)void 0!==a[e]&&(c[e]=a[e]);return c}};n.prototype={close:function(){if(this.completion.widget==this){this.completion.widget=null;this.hints.parentNode.removeChild(this.hints);this.completion.cm.removeKeyMap(this.keyMap);
+var a=this.completion.cm;this.completion.options.closeOnUnfocus&&(a.off("blur",this.onBlur),a.off("focus",this.onFocus));a.off("scroll",this.onScroll)}},disable:function(){this.completion.cm.removeKeyMap(this.keyMap);var a=this;this.keyMap={Enter:function(){a.picked=!0}};this.completion.cm.addKeyMap(this.keyMap)},pick:function(){this.completion.pick(this.data,this.selectedHint)},changeActive:function(a,b){a>=this.data.list.length?a=b?this.data.list.length-1:0:0>a&&(a=b?0:this.data.list.length-1);
+if(this.selectedHint!=a){var c=this.hints.childNodes[this.selectedHint];c.className=c.className.replace(" CodeMirror-hint-active","");c=this.hints.childNodes[this.selectedHint=a];c.className+=" CodeMirror-hint-active";c.offsetTop<this.hints.scrollTop?this.hints.scrollTop=c.offsetTop-3:c.offsetTop+c.offsetHeight>this.hints.scrollTop+this.hints.clientHeight&&(this.hints.scrollTop=c.offsetTop+c.offsetHeight-this.hints.clientHeight+3);f.signal(this.data,"select",this.data.list[this.selectedHint],c)}},
+screenAmount:function(){return Math.floor(this.hints.clientHeight/this.hints.firstChild.offsetHeight)||1}};f.registerHelper("hint","auto",function(a,b){var c=a.getHelpers(a.getCursor(),"hint");if(c.length)for(var e=0;e<c.length;e++){var d=c[e](a,b);if(d&&d.list.length)return d}else if(c=a.getHelper(a.getCursor(),"hintWords")){if(c)return f.hint.fromList(a,{words:c})}else if(f.hint.anyword)return f.hint.anyword(a,b)});f.registerHelper("hint","fromList",function(a,b){for(var c=a.getCursor(),e=a.getTokenAt(c),
+d=[],m=0;m<b.words.length;m++){var g=b.words[m];g.slice(0,e.string.length)==e.string&&d.push(g)}if(d.length)return{list:d,from:f.Pos(c.line,e.start),to:f.Pos(c.line,e.end)}});f.commands.autocomplete=f.showHint;var q={hint:f.hint.auto,completeSingle:!0,alignWithWord:!0,closeCharacters:/[\s()\[\]{};:>,]/,closeOnUnfocus:!0,completeOnSingleClick:!1,container:null,customKeys:null,extraKeys:null};f.defineOption("hintOptions",null)});
\ No newline at end of file
diff --git a/release/skins/moono/dialog.css b/release/skins/moono/dialog.css
new file mode 100644 (file)
index 0000000..e17ab78
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_spinner{border-radius:50%;width:12px;height:12px;overflow:hidden;text-indent:-9999em;border-top:2px solid rgba(102,102,102,0.2);border-right:2px solid rgba(102,102,102,0.2);border-bottom:2px solid rgba(102,102,102,0.2);border-left:2px solid rgba(102,102,102,1);-webkit-animation:dialog_spinner 1s infinite linear;animation:dialog_spinner 1s infinite linear}.cke_browser_ie8 .cke_dialog_spinner,.cke_browser_ie9 .cke_dialog_spinner{background:url(images/spinner.gif) center top no-repeat;width:16px;height:16px;border:0}@-webkit-keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:linear-gradient(to bottom,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover,a.cke_dialog_tab:focus{background:#ebebeb;background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover,a.cke_dialog_tab_selected:focus{background:#ededed;background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab:focus,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}a.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:4px;z-index:5;opacity:.8;filter:alpha(opacity = 80)}.cke_dialog_close_button:hover{opacity:1;filter:alpha(opacity = 100)}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;box-sizing:border-box;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:4px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 10px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:18px;padding:0 12px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:linear-gradient(to bottom,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button_ok.cke_disabled{border-color:#7d9f51;background:#8dad62;background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3d271),to(#8dad62));background-image:-webkit-linear-gradient(top,#b3d271,#8dad62);background-image:-o-linear-gradient(top,#b3d271,#8dad62);background-image:linear-gradient(to bottom,#b3d271,#8dad62);background-image:-moz-linear-gradient(top,#b3d271,#8dad62);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#B3D271',endColorstr='#8DAD62')}a.cke_dialog_ui_button_ok.cke_disabled span{color:#e0e8d1}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:3px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok.cke_disabled:focus,a.cke_dialog_ui_button_ok.cke_disabled:active{border-color:#6f8c49}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:25px;line-height:25px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:3px 3px 3px 6px;outline:0;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}
\ No newline at end of file
diff --git a/release/skins/moono/dialog_ie.css b/release/skins/moono/dialog_ie.css
new file mode 100644 (file)
index 0000000..41a8200
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_spinner{border-radius:50%;width:12px;height:12px;overflow:hidden;text-indent:-9999em;border-top:2px solid rgba(102,102,102,0.2);border-right:2px solid rgba(102,102,102,0.2);border-bottom:2px solid rgba(102,102,102,0.2);border-left:2px solid rgba(102,102,102,1);-webkit-animation:dialog_spinner 1s infinite linear;animation:dialog_spinner 1s infinite linear}.cke_browser_ie8 .cke_dialog_spinner,.cke_browser_ie9 .cke_dialog_spinner{background:url(images/spinner.gif) center top no-repeat;width:16px;height:16px;border:0}@-webkit-keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:linear-gradient(to bottom,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover,a.cke_dialog_tab:focus{background:#ebebeb;background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover,a.cke_dialog_tab_selected:focus{background:#ededed;background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab:focus,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}a.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:4px;z-index:5;opacity:.8;filter:alpha(opacity = 80)}.cke_dialog_close_button:hover{opacity:1;filter:alpha(opacity = 100)}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;box-sizing:border-box;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:4px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 10px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:18px;padding:0 12px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:linear-gradient(to bottom,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button_ok.cke_disabled{border-color:#7d9f51;background:#8dad62;background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3d271),to(#8dad62));background-image:-webkit-linear-gradient(top,#b3d271,#8dad62);background-image:-o-linear-gradient(top,#b3d271,#8dad62);background-image:linear-gradient(to bottom,#b3d271,#8dad62);background-image:-moz-linear-gradient(top,#b3d271,#8dad62);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#B3D271',endColorstr='#8DAD62')}a.cke_dialog_ui_button_ok.cke_disabled span{color:#e0e8d1}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:3px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok.cke_disabled:focus,a.cke_dialog_ui_button_ok.cke_disabled:active{border-color:#6f8c49}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:25px;line-height:25px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:3px 3px 3px 6px;outline:0;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}
\ No newline at end of file
diff --git a/release/skins/moono/dialog_ie7.css b/release/skins/moono/dialog_ie7.css
new file mode 100644 (file)
index 0000000..fdfe1d5
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_spinner{border-radius:50%;width:12px;height:12px;overflow:hidden;text-indent:-9999em;border-top:2px solid rgba(102,102,102,0.2);border-right:2px solid rgba(102,102,102,0.2);border-bottom:2px solid rgba(102,102,102,0.2);border-left:2px solid rgba(102,102,102,1);-webkit-animation:dialog_spinner 1s infinite linear;animation:dialog_spinner 1s infinite linear}.cke_browser_ie8 .cke_dialog_spinner,.cke_browser_ie9 .cke_dialog_spinner{background:url(images/spinner.gif) center top no-repeat;width:16px;height:16px;border:0}@-webkit-keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:linear-gradient(to bottom,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover,a.cke_dialog_tab:focus{background:#ebebeb;background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover,a.cke_dialog_tab_selected:focus{background:#ededed;background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab:focus,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}a.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:4px;z-index:5;opacity:.8;filter:alpha(opacity = 80)}.cke_dialog_close_button:hover{opacity:1;filter:alpha(opacity = 100)}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;box-sizing:border-box;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:4px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 10px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:18px;padding:0 12px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:linear-gradient(to bottom,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button_ok.cke_disabled{border-color:#7d9f51;background:#8dad62;background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3d271),to(#8dad62));background-image:-webkit-linear-gradient(top,#b3d271,#8dad62);background-image:-o-linear-gradient(top,#b3d271,#8dad62);background-image:linear-gradient(to bottom,#b3d271,#8dad62);background-image:-moz-linear-gradient(top,#b3d271,#8dad62);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#B3D271',endColorstr='#8DAD62')}a.cke_dialog_ui_button_ok.cke_disabled span{color:#e0e8d1}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:3px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok.cke_disabled:focus,a.cke_dialog_ui_button_ok.cke_disabled:active{border-color:#6f8c49}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:25px;line-height:25px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:3px 3px 3px 6px;outline:0;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_title{zoom:1}.cke_dialog_footer{border-top:1px solid #bfbfbf}.cke_dialog_footer_buttons{position:static}.cke_dialog_footer_buttons a.cke_dialog_ui_button{vertical-align:top}.cke_dialog .cke_resizer_ltr{padding-left:4px}.cke_dialog .cke_resizer_rtl{padding-right:4px}.cke_dialog_ui_input_text,.cke_dialog_ui_input_password,.cke_dialog_ui_input_textarea,.cke_dialog_ui_input_select{padding:0!important}.cke_dialog_ui_checkbox_input,.cke_dialog_ui_ratio_input,.cke_btn_reset,.cke_btn_locked,.cke_btn_unlocked{border:1px solid transparent!important}
\ No newline at end of file
diff --git a/release/skins/moono/dialog_ie8.css b/release/skins/moono/dialog_ie8.css
new file mode 100644 (file)
index 0000000..9cf4b57
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_spinner{border-radius:50%;width:12px;height:12px;overflow:hidden;text-indent:-9999em;border-top:2px solid rgba(102,102,102,0.2);border-right:2px solid rgba(102,102,102,0.2);border-bottom:2px solid rgba(102,102,102,0.2);border-left:2px solid rgba(102,102,102,1);-webkit-animation:dialog_spinner 1s infinite linear;animation:dialog_spinner 1s infinite linear}.cke_browser_ie8 .cke_dialog_spinner,.cke_browser_ie9 .cke_dialog_spinner{background:url(images/spinner.gif) center top no-repeat;width:16px;height:16px;border:0}@-webkit-keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:linear-gradient(to bottom,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover,a.cke_dialog_tab:focus{background:#ebebeb;background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover,a.cke_dialog_tab_selected:focus{background:#ededed;background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab:focus,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}a.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:4px;z-index:5;opacity:.8;filter:alpha(opacity = 80)}.cke_dialog_close_button:hover{opacity:1;filter:alpha(opacity = 100)}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;box-sizing:border-box;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:4px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 10px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:18px;padding:0 12px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:linear-gradient(to bottom,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button_ok.cke_disabled{border-color:#7d9f51;background:#8dad62;background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3d271),to(#8dad62));background-image:-webkit-linear-gradient(top,#b3d271,#8dad62);background-image:-o-linear-gradient(top,#b3d271,#8dad62);background-image:linear-gradient(to bottom,#b3d271,#8dad62);background-image:-moz-linear-gradient(top,#b3d271,#8dad62);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#B3D271',endColorstr='#8DAD62')}a.cke_dialog_ui_button_ok.cke_disabled span{color:#e0e8d1}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:3px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok.cke_disabled:focus,a.cke_dialog_ui_button_ok.cke_disabled:active{border-color:#6f8c49}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:25px;line-height:25px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:3px 3px 3px 6px;outline:0;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{display:block}
\ No newline at end of file
diff --git a/release/skins/moono/dialog_iequirks.css b/release/skins/moono/dialog_iequirks.css
new file mode 100644 (file)
index 0000000..661e8eb
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_dialog{visibility:visible}.cke_dialog_body{z-index:1;background:#eaeaea;border:1px solid #b2b2b2;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_dialog strong{font-weight:bold}.cke_dialog_title{font-weight:bold;font-size:13px;cursor:move;position:relative;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #999;padding:6px 10px;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_dialog_spinner{border-radius:50%;width:12px;height:12px;overflow:hidden;text-indent:-9999em;border-top:2px solid rgba(102,102,102,0.2);border-right:2px solid rgba(102,102,102,0.2);border-bottom:2px solid rgba(102,102,102,0.2);border-left:2px solid rgba(102,102,102,1);-webkit-animation:dialog_spinner 1s infinite linear;animation:dialog_spinner 1s infinite linear}.cke_browser_ie8 .cke_dialog_spinner,.cke_browser_ie9 .cke_dialog_spinner{background:url(images/spinner.gif) center top no-repeat;width:16px;height:16px;border:0}@-webkit-keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes dialog_spinner{0%{-webkit-transform:rotate(0deg);transform:rotate(0deg)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}.cke_dialog_contents{background-color:#fff;overflow:auto;padding:15px 10px 5px 10px;margin-top:30px;border-top:1px solid #bfbfbf;border-radius:0 0 3px 3px}.cke_dialog_contents_body{overflow:auto;padding:17px 10px 5px 10px;margin-top:22px}.cke_dialog_footer{text-align:right;position:relative;border:0;outline:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;border-radius:0 0 2px 2px;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_rtl .cke_dialog_footer{text-align:left}.cke_hc .cke_dialog_footer{outline:0;border-top:1px solid #fff}.cke_dialog .cke_resizer{margin-top:22px}.cke_dialog .cke_resizer_rtl{margin-left:5px}.cke_dialog .cke_resizer_ltr{margin-right:5px}.cke_dialog_tabs{height:24px;display:inline-block;margin:5px 0 0;position:absolute;z-index:2;left:10px}.cke_rtl .cke_dialog_tabs{right:10px}a.cke_dialog_tab{height:16px;padding:4px 8px;margin-right:3px;display:inline-block;cursor:pointer;line-height:16px;outline:0;color:#595959;border:1px solid #bfbfbf;border-radius:3px 3px 0 0;background:#d4d4d4;background-image:linear-gradient(to bottom,#fafafa,#ededed);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#fafafa',endColorstr='#ededed')}.cke_rtl a.cke_dialog_tab{margin-right:0;margin-left:3px}a.cke_dialog_tab:hover,a.cke_dialog_tab:focus{background:#ebebeb;background:linear-gradient(to bottom,#ebebeb 0,#dfdfdf 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ebebeb',endColorstr='#dfdfdf',GradientType=0)}a.cke_dialog_tab_selected{background:#fff;color:#383838;border-bottom-color:#fff;cursor:default;filter:none}a.cke_dialog_tab_selected:hover,a.cke_dialog_tab_selected:focus{background:#ededed;background:linear-gradient(to bottom,#ededed 0,#fff 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#ededed',endColorstr='#ffffff',GradientType=0)}.cke_hc a.cke_dialog_tab:hover,.cke_hc a.cke_dialog_tab:focus,.cke_hc a.cke_dialog_tab_selected{border:3px solid;padding:2px 6px}a.cke_dialog_tab_disabled{color:#bababa;cursor:default}.cke_single_page .cke_dialog_tabs{display:none}.cke_single_page .cke_dialog_contents{padding-top:5px;margin-top:0;border-top:0}a.cke_dialog_close_button{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:4px;z-index:5;opacity:.8;filter:alpha(opacity = 80)}.cke_dialog_close_button:hover{opacity:1;filter:alpha(opacity = 100)}.cke_hidpi .cke_dialog_close_button{background-image:url(images/hidpi/close.png);background-size:16px}.cke_dialog_close_button span{display:none}.cke_hc .cke_dialog_close_button span{display:inline;cursor:pointer;font-weight:bold;position:relative;top:3px}.cke_ltr .cke_dialog_close_button{right:5px}.cke_rtl .cke_dialog_close_button{left:6px}.cke_dialog_close_button{top:4px}div.cke_disabled .cke_dialog_ui_labeled_content div *{background-color:#ddd;cursor:default}.cke_dialog_ui_vbox table,.cke_dialog_ui_hbox table{margin:auto}.cke_dialog_ui_vbox_child{padding:5px 0}.cke_dialog_ui_hbox{width:100%}.cke_dialog_ui_hbox_first,.cke_dialog_ui_hbox_child,.cke_dialog_ui_hbox_last{vertical-align:top}.cke_ltr .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_ui_hbox_child{padding-right:10px}.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_child{padding-left:10px}.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-right:5px}.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child{padding-left:5px;padding-right:0}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:1px solid}textarea.cke_dialog_ui_input_textarea{overflow:auto;resize:none}input.cke_dialog_ui_input_text,input.cke_dialog_ui_input_password,textarea.cke_dialog_ui_input_textarea{background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:4px 6px;outline:0;width:100%;*width:95%;box-sizing:border-box;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}input.cke_dialog_ui_input_text:hover,input.cke_dialog_ui_input_password:hover,textarea.cke_dialog_ui_input_textarea:hover{border:1px solid #aeb3b9;border-top-color:#a0a6ad}input.cke_dialog_ui_input_text:focus,input.cke_dialog_ui_input_password:focus,textarea.cke_dialog_ui_input_textarea:focus,select.cke_dialog_ui_input_select:focus{outline:0;border:1px solid #139ff7;border-top-color:#1392e9}a.cke_dialog_ui_button{display:inline-block;*display:inline;*zoom:1;padding:4px 0;margin:0;text-align:center;color:#333;vertical-align:middle;cursor:pointer;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}span.cke_dialog_ui_button{padding:0 10px}a.cke_dialog_ui_button:hover{border-color:#9e9e9e;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}a.cke_dialog_ui_button:focus,a.cke_dialog_ui_button:active{border-color:#969696;outline:0;box-shadow:0 0 6px rgba(0,0,0,.4) inset}.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button:focus,.cke_hc a.cke_dialog_ui_button:active{border:3px solid;padding-top:1px;padding-bottom:1px}.cke_hc a.cke_dialog_ui_button:hover span,.cke_hc a.cke_dialog_ui_button:focus span,.cke_hc a.cke_dialog_ui_button:active span{padding-left:10px;padding-right:10px}.cke_dialog_footer_buttons a.cke_dialog_ui_button span{color:inherit;font-size:12px;font-weight:bold;line-height:18px;padding:0 12px}a.cke_dialog_ui_button_ok{color:#fff;text-shadow:0 -1px 0 #55830c;border-color:#62a60a #62a60a #4d9200;background:#69b10b;background-image:linear-gradient(to bottom,#9ad717,#69b10b);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#9ad717',endColorstr='#69b10b')}a.cke_dialog_ui_button_ok:hover{border-color:#5b9909 #5b9909 #478500;background:#88be14;background:linear-gradient(to bottom,#88be14 0,#5d9c0a 100%);filter:progid:DXImageTransform.Microsoft.gradient(startColorstr='#88be14',endColorstr='#5d9c0a',GradientType=0)}a.cke_dialog_ui_button_ok.cke_disabled{border-color:#7d9f51;background:#8dad62;background-image:-webkit-gradient(linear,0 0,0 100%,from(#b3d271),to(#8dad62));background-image:-webkit-linear-gradient(top,#b3d271,#8dad62);background-image:-o-linear-gradient(top,#b3d271,#8dad62);background-image:linear-gradient(to bottom,#b3d271,#8dad62);background-image:-moz-linear-gradient(top,#b3d271,#8dad62);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#B3D271',endColorstr='#8DAD62')}a.cke_dialog_ui_button_ok.cke_disabled span{color:#e0e8d1}a.cke_dialog_ui_button span{text-shadow:0 1px 0 #fff}a.cke_dialog_ui_button_ok span{text-shadow:0 -1px 0 #55830c}span.cke_dialog_ui_button{cursor:pointer}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active,a.cke_dialog_ui_button_cancel:focus,a.cke_dialog_ui_button_cancel:active{border-width:2px;padding:3px 0}a.cke_dialog_ui_button_ok:focus,a.cke_dialog_ui_button_ok:active{border-color:#568c0a}a.cke_dialog_ui_button_ok.cke_disabled:focus,a.cke_dialog_ui_button_ok.cke_disabled:active{border-color:#6f8c49}a.cke_dialog_ui_button_ok:focus span,a.cke_dialog_ui_button_ok:active span,a.cke_dialog_ui_button_cancel:focus span,a.cke_dialog_ui_button_cancel:active span{padding:0 11px}.cke_dialog_footer_buttons{display:inline-table;margin:5px;width:auto;position:relative;vertical-align:middle}div.cke_dialog_ui_input_select{display:table}select.cke_dialog_ui_input_select{height:25px;line-height:25px;background-color:#fff;border:1px solid #c9cccf;border-top-color:#aeb3b9;padding:3px 3px 3px 6px;outline:0;border-radius:3px;box-shadow:0 1px 2px rgba(0,0,0,.15) inset}.cke_dialog_ui_input_file{width:100%;height:25px}.cke_hc .cke_dialog_ui_labeled_content input:focus,.cke_hc .cke_dialog_ui_labeled_content select:focus,.cke_hc .cke_dialog_ui_labeled_content textarea:focus{outline:1px dotted}.cke_dialog .cke_dark_background{background-color:#dedede}.cke_dialog .cke_light_background{background-color:#ebebeb}.cke_dialog .cke_centered{text-align:center}.cke_dialog a.cke_btn_reset{float:right;background:url(images/refresh.png) top left no-repeat;width:16px;height:16px;border:1px none;font-size:1px}.cke_hidpi .cke_dialog a.cke_btn_reset{background-size:16px;background-image:url(images/hidpi/refresh.png)}.cke_rtl .cke_dialog a.cke_btn_reset{float:left}.cke_dialog a.cke_btn_locked,.cke_dialog a.cke_btn_unlocked{float:left;width:16px;height:16px;background-repeat:no-repeat;border:none 1px;font-size:1px}.cke_dialog a.cke_btn_locked .cke_icon{display:none}.cke_rtl .cke_dialog a.cke_btn_locked,.cke_rtl .cke_dialog a.cke_btn_unlocked{float:right}.cke_dialog a.cke_btn_locked{background-image:url(images/lock.png)}.cke_dialog a.cke_btn_unlocked{background-image:url(images/lock-open.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked,.cke_hidpi .cke_dialog a.cke_btn_locked{background-size:16px}.cke_hidpi .cke_dialog a.cke_btn_locked{background-image:url(images/hidpi/lock.png)}.cke_hidpi .cke_dialog a.cke_btn_unlocked{background-image:url(images/hidpi/lock-open.png)}.cke_dialog .cke_btn_over{border:outset 1px;cursor:pointer}.cke_dialog .ImagePreviewBox{border:2px ridge black;overflow:scroll;height:200px;width:300px;padding:2px;background-color:white}.cke_dialog .ImagePreviewBox table td{white-space:normal}.cke_dialog .ImagePreviewLoader{position:absolute;white-space:normal;overflow:hidden;height:160px;width:230px;margin:2px;padding:2px;opacity:.9;filter:alpha(opacity = 90);background-color:#e4e4e4}.cke_dialog .FlashPreviewBox{white-space:normal;border:2px ridge black;overflow:auto;height:160px;width:390px;padding:2px;background-color:white}.cke_dialog .cke_pastetext{width:346px;height:170px}.cke_dialog .cke_pastetext textarea{width:340px;height:170px;resize:none}.cke_dialog iframe.cke_pasteframe{width:346px;height:130px;background-color:white;border:1px solid #aeb3b9;border-radius:3px}.cke_dialog .cke_hand{cursor:pointer}.cke_disabled{color:#a0a0a0}.cke_dialog_body .cke_label{display:none}.cke_dialog_body label{display:inline;margin-bottom:auto;cursor:default}.cke_dialog_body label.cke_required{font-weight:bold}a.cke_smile{overflow:hidden;display:block;text-align:center;padding:.3em 0}a.cke_smile img{vertical-align:middle}a.cke_specialchar{cursor:inherit;display:block;height:1.25em;padding:.2em .3em;text-align:center}a.cke_smile,a.cke_specialchar{border:1px solid transparent}a.cke_smile:hover,a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:hover,a.cke_specialchar:focus,a.cke_specialchar:active{background:#fff;outline:0}a.cke_smile:hover,a.cke_specialchar:hover{border-color:#888}a.cke_smile:focus,a.cke_smile:active,a.cke_specialchar:focus,a.cke_specialchar:active{border-color:#139ff7}.cke_dialog_contents a.colorChooser{display:block;margin-top:6px;margin-left:10px;width:80px}.cke_rtl .cke_dialog_contents a.colorChooser{margin-right:10px}.cke_dialog_ui_checkbox_input:focus,.cke_dialog_ui_radio_input:focus,.cke_btn_over{outline:1px dotted #696969}.cke_iframe_shim{display:block;position:absolute;top:0;left:0;z-index:-1;filter:alpha(opacity = 0);width:100%;height:100%}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{padding-right:2px}.cke_rtl div.cke_dialog_ui_input_text,.cke_rtl div.cke_dialog_ui_input_password{padding-left:2px}.cke_rtl div.cke_dialog_ui_input_text{padding-right:1px}.cke_rtl .cke_dialog_ui_vbox_child,.cke_rtl .cke_dialog_ui_hbox_child,.cke_rtl .cke_dialog_ui_hbox_first,.cke_rtl .cke_dialog_ui_hbox_last{padding-right:2px!important}.cke_hc .cke_dialog_title,.cke_hc .cke_dialog_footer,.cke_hc a.cke_dialog_tab,.cke_hc a.cke_dialog_ui_button,.cke_hc a.cke_dialog_ui_button:hover,.cke_hc a.cke_dialog_ui_button_ok,.cke_hc a.cke_dialog_ui_button_ok:hover{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_hc div.cke_dialog_ui_input_text,.cke_hc div.cke_dialog_ui_input_password,.cke_hc div.cke_dialog_ui_input_textarea,.cke_hc div.cke_dialog_ui_input_select,.cke_hc div.cke_dialog_ui_input_file{border:0}.cke_dialog_footer{filter:""}
\ No newline at end of file
diff --git a/release/skins/moono/editor.css b/release/skins/moono/editor.css
new file mode 100644 (file)
index 0000000..8fe1935
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/editor_gecko.css b/release/skins/moono/editor_gecko.css
new file mode 100644 (file)
index 0000000..d13ffea
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}.cke_bottom{padding-bottom:3px}.cke_combo_text{margin-bottom:-1px;margin-top:1px}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/editor_ie.css b/release/skins/moono/editor_ie.css
new file mode 100644 (file)
index 0000000..79dd245
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/editor_ie7.css b/release/skins/moono/editor_ie7.css
new file mode 100644 (file)
index 0000000..cfa6849
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon{display:inline-block;vertical-align:top}.cke_toolbox{display:inline-block;padding-bottom:5px;height:100%}.cke_rtl .cke_toolbox{padding-bottom:0}.cke_toolbar{margin-bottom:5px}.cke_rtl .cke_toolbar{margin-bottom:0}.cke_toolgroup{height:26px}.cke_toolgroup,.cke_combo{position:relative}a.cke_button{float:none;vertical-align:top}.cke_toolbar_separator{display:inline-block;float:none;vertical-align:top;background-color:#c0c0c0}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_rtl .cke_button_arrow{padding-top:8px;margin-right:2px}.cke_rtl .cke_combo_inlinelabel{display:table-cell;vertical-align:middle}.cke_menubutton{display:block;height:24px}.cke_menubutton_inner{display:block;position:relative}.cke_menubutton_icon{height:16px;width:16px}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:inline-block}.cke_menubutton_label{width:auto;vertical-align:top;line-height:24px;height:24px;margin:0 10px 0 0}.cke_menuarrow{width:5px;height:6px;padding:0;position:absolute;right:8px;top:10px;background-position:0 0}.cke_rtl .cke_menubutton_icon{position:absolute;right:0;top:0}.cke_rtl .cke_menubutton_label{float:right;clear:both;margin:0 24px 0 10px}.cke_hc .cke_rtl .cke_menubutton_label{margin-right:0}.cke_rtl .cke_menuarrow{left:8px;right:auto;background-position:0 -24px}.cke_hc .cke_menuarrow{top:5px;padding:0 5px}.cke_rtl input.cke_dialog_ui_input_text,.cke_rtl input.cke_dialog_ui_input_password{position:relative}.cke_wysiwyg_div{padding-top:0!important;padding-bottom:0!important}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/editor_ie8.css b/release/skins/moono/editor_ie8.css
new file mode 100644 (file)
index 0000000..4843ff0
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_toolbox_collapser .cke_arrow{border-width:4px}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{border-width:3px}.cke_toolbox_collapser .cke_arrow{margin-top:0}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/editor_iequirks.css b/release/skins/moono/editor_iequirks.css
new file mode 100644 (file)
index 0000000..21ca3e2
--- /dev/null
@@ -0,0 +1,5 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+.cke_reset{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none}.cke_reset_all,.cke_reset_all *,.cke_reset_all a,.cke_reset_all textarea{margin:0;padding:0;border:0;background:transparent;text-decoration:none;width:auto;height:auto;vertical-align:baseline;box-sizing:content-box;position:static;transition:none;border-collapse:collapse;font:normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;color:#000;text-align:left;white-space:nowrap;cursor:auto;float:none}.cke_reset_all .cke_rtl *{text-align:right}.cke_reset_all iframe{vertical-align:inherit}.cke_reset_all textarea{white-space:pre-wrap}.cke_reset_all textarea,.cke_reset_all input[type="text"],.cke_reset_all input[type="password"]{cursor:text}.cke_reset_all textarea[disabled],.cke_reset_all input[type="text"][disabled],.cke_reset_all input[type="password"][disabled]{cursor:default}.cke_reset_all fieldset{padding:10px;border:2px groove #e0dfe3}.cke_reset_all select{box-sizing:border-box}.cke_reset_all table{table-layout:auto}.cke_chrome{display:block;border:1px solid #b6b6b6;padding:0;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_inner{display:block;-webkit-touch-callout:none;background:#fff;padding:0}.cke_float{border:0}.cke_float .cke_inner{padding-bottom:0}.cke_top,.cke_contents,.cke_bottom{display:block;overflow:hidden}.cke_top{border-bottom:1px solid #b6b6b6;padding:6px 8px 2px;white-space:normal;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_float .cke_top{border:1px solid #b6b6b6;border-bottom-color:#999}.cke_bottom{padding:6px 8px 2px;position:relative;border-top:1px solid #bfbfbf;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#ebebeb,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ebebeb',endColorstr='#cfd1cf')}.cke_browser_ios .cke_contents{overflow-y:auto;-webkit-overflow-scrolling:touch}.cke_resizer{width:0;height:0;overflow:hidden;width:0;height:0;overflow:hidden;border-width:10px 10px 0 0;border-color:transparent #666 transparent transparent;border-style:dashed solid dashed dashed;font-size:0;vertical-align:bottom;margin-top:6px;margin-bottom:2px;box-shadow:0 1px 0 rgba(255,255,255,.3)}.cke_hc .cke_resizer{font-size:15px;width:auto;height:auto;border-width:0}.cke_resizer_ltr{cursor:se-resize;float:right;margin-right:-4px}.cke_resizer_rtl{border-width:10px 0 0 10px;border-color:transparent transparent transparent #a5a5a5;border-style:dashed dashed dashed solid;cursor:sw-resize;float:left;margin-left:-4px;right:auto}.cke_wysiwyg_div{display:block;height:100%;overflow:auto;padding:0 8px;outline-style:none;box-sizing:border-box}.cke_panel{visibility:visible;width:120px;height:100px;overflow:hidden;background-color:#fff;border:1px solid #b6b6b6;border-bottom-color:#999;border-radius:3px;box-shadow:0 0 3px rgba(0,0,0,.15)}.cke_menu_panel{padding:0;margin:0}.cke_combopanel{width:150px;height:170px}.cke_panel_frame{width:100%;height:100%;font-size:12px;overflow:auto;overflow-x:hidden}.cke_panel_container{overflow-y:auto;overflow-x:hidden}.cke_panel_list{list-style-type:none;margin:3px;padding:0;white-space:nowrap}.cke_panel_listItem{margin:0;padding-bottom:1px}.cke_panel_listItem a{padding:3px 4px;display:block;border:1px solid #fff;color:inherit!important;text-decoration:none;overflow:hidden;text-overflow:ellipsis;border-radius:2px}* html .cke_panel_listItem a{width:100%;color:#000}*:first-child+html .cke_panel_listItem a{color:#000}.cke_panel_listItem.cke_selected a{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_panel_listItem a:hover,.cke_panel_listItem a:focus,.cke_panel_listItem a:active{border-color:#dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_hc .cke_panel_listItem a{border-style:none}.cke_hc .cke_panel_listItem a:hover,.cke_hc .cke_panel_listItem a:focus,.cke_hc .cke_panel_listItem a:active{border:2px solid;padding:1px 2px}.cke_panel_grouptitle{cursor:default;font-size:11px;font-weight:bold;white-space:nowrap;margin:0;padding:4px 6px;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.75);border-bottom:1px solid #b6b6b6;border-radius:2px 2px 0 0;box-shadow:0 1px 0 #fff inset;background:#cfd1cf;background-image:linear-gradient(to bottom,#f5f5f5,#cfd1cf);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f5f5f5',endColorstr='#cfd1cf')}.cke_panel_listItem p,.cke_panel_listItem h1,.cke_panel_listItem h2,.cke_panel_listItem h3,.cke_panel_listItem h4,.cke_panel_listItem h5,.cke_panel_listItem h6,.cke_panel_listItem pre{margin-top:0;margin-bottom:0}.cke_colorblock{padding:3px;font-size:11px;font-family:'Microsoft Sans Serif',Tahoma,Arial,Verdana,Sans-Serif}.cke_colorblock,.cke_colorblock a{text-decoration:none;color:#000}span.cke_colorbox{width:10px;height:10px;border:#808080 1px solid;float:left}.cke_rtl span.cke_colorbox{float:right}a.cke_colorbox{border:#fff 1px solid;padding:2px;float:left;width:12px;height:12px}.cke_rtl a.cke_colorbox{float:right}a:hover.cke_colorbox,a:focus.cke_colorbox,a:active.cke_colorbox{border:#b6b6b6 1px solid;background-color:#e5e5e5}a.cke_colorauto,a.cke_colormore{border:#fff 1px solid;padding:2px;display:block;cursor:pointer}a:hover.cke_colorauto,a:hover.cke_colormore,a:focus.cke_colorauto,a:focus.cke_colormore,a:active.cke_colorauto,a:active.cke_colormore{border:#b6b6b6 1px solid;background-color:#e5e5e5}.cke_toolbar{float:left}.cke_rtl .cke_toolbar{float:right}.cke_toolgroup{float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_hc .cke_toolgroup{border:0;margin-right:10px;margin-bottom:10px}.cke_rtl .cke_toolgroup{float:right;margin-left:6px;margin-right:0}a.cke_button{display:inline-block;height:18px;padding:4px 6px;outline:0;cursor:default;float:left;border:0}.cke_ltr .cke_button:last-child,.cke_rtl .cke_button:first-child{border-radius:0 2px 2px 0}.cke_ltr .cke_button:first-child,.cke_rtl .cke_button:last-child{border-radius:2px 0 0 2px}.cke_rtl .cke_button{float:right}.cke_hc .cke_button{border:1px solid black;padding:3px 5px;margin:-2px 4px 0 -2px}a.cke_button_on{box-shadow:0 1px 5px rgba(0,0,0,.6) inset,0 1px 0 rgba(0,0,0,.2);background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc a.cke_button_disabled:hover,.cke_hc a.cke_button_disabled:focus,.cke_hc a.cke_button_disabled:active{border-width:3px;padding:1px 3px}.cke_button_disabled .cke_button_icon{opacity:.3}.cke_hc .cke_button_disabled{opacity:.5}a.cke_button_on:hover,a.cke_button_on:focus,a.cke_button_on:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}a.cke_button_off:hover,a.cke_button_off:focus,a.cke_button_off:active,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{box-shadow:0 0 1px rgba(0,0,0,.3) inset;background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_button_icon{cursor:inherit;background-repeat:no-repeat;margin-top:1px;width:16px;height:16px;float:left;display:inline-block}.cke_rtl .cke_button_icon{float:right}.cke_hc .cke_button_icon{display:none}.cke_button_label{display:none;padding-left:3px;margin-top:1px;line-height:17px;vertical-align:middle;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5)}.cke_rtl .cke_button_label{padding-right:3px;padding-left:0;float:right}.cke_hc .cke_button_label{padding:0;display:inline-block;font-size:12px}.cke_button_arrow{display:inline-block;margin:8px 0 0 1px;width:0;height:0;cursor:default;vertical-align:top;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_rtl .cke_button_arrow{margin-right:5px;margin-left:0}.cke_hc .cke_button_arrow{font-size:10px;margin:3px -2px 0 3px;width:auto;border:0}.cke_toolbar_separator{float:left;background-color:#c0c0c0;background-color:rgba(0,0,0,.2);margin:5px 2px 0;height:18px;width:1px;box-shadow:1px 0 1px rgba(255,255,255,.5)}.cke_rtl .cke_toolbar_separator{float:right;box-shadow:-1px 0 1px rgba(255,255,255,.1)}.cke_hc .cke_toolbar_separator{width:0;border-left:1px solid;margin:1px 5px 0 0}.cke_toolbar_break{display:block;clear:left}.cke_rtl .cke_toolbar_break{clear:right}a.cke_toolbox_collapser{width:12px;height:11px;float:right;margin:11px 0 0;font-size:0;cursor:default;text-align:center;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_toolbox_collapser:hover{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc')}.cke_toolbox_collapser.cke_toolbox_collapser_min{margin:0 2px 4px}.cke_rtl .cke_toolbox_collapser{float:left}.cke_toolbox_collapser .cke_arrow{display:inline-block;height:0;width:0;font-size:0;margin-top:1px;border-left:3px solid transparent;border-right:3px solid transparent;border-bottom:3px solid #474747;border-top:3px solid transparent}.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow{margin-top:4px;border-bottom-color:transparent;border-top-color:#474747}.cke_hc .cke_toolbox_collapser .cke_arrow{font-size:8px;width:auto;border:0;margin-top:0;margin-right:2px}.cke_menubutton{display:block}.cke_menuitem span{cursor:default}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#d3d3d3;display:block}.cke_hc .cke_menubutton{padding:2px}.cke_hc .cke_menubutton:hover,.cke_hc .cke_menubutton:focus,.cke_hc .cke_menubutton:active{border:2px solid;padding:0}.cke_menubutton_inner{display:table-row}.cke_menubutton_icon,.cke_menubutton_label,.cke_menuarrow{display:table-cell}.cke_menubutton_icon{background-color:#d7d8d7;opacity:.70;filter:alpha(opacity=70);padding:4px}.cke_hc .cke_menubutton_icon{height:16px;width:0;padding:4px 0}.cke_menubutton:hover .cke_menubutton_icon,.cke_menubutton:focus .cke_menubutton_icon,.cke_menubutton:active .cke_menubutton_icon{background-color:#d0d2d0}.cke_menubutton_disabled:hover .cke_menubutton_icon,.cke_menubutton_disabled:focus .cke_menubutton_icon,.cke_menubutton_disabled:active .cke_menubutton_icon{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_label{padding:0 5px;background-color:transparent;width:100%;vertical-align:middle}.cke_menubutton_shortcut{color:#979797}.cke_menubutton_disabled .cke_menubutton_label{opacity:.3;filter:alpha(opacity=30)}.cke_menubutton_on{border:1px solid #dedede;background-color:#f2f2f2;box-shadow:0 0 2px rgba(0,0,0,.1) inset}.cke_menubutton_on .cke_menubutton_icon{padding-right:3px}.cke_menubutton:hover,.cke_menubutton:focus,.cke_menubutton:active{background-color:#eff0ef}.cke_panel_frame .cke_menubutton_label{display:none}.cke_menuseparator{background-color:#d3d3d3;height:1px;filter:alpha(opacity=70);opacity:.70}.cke_menuarrow{background-image:url(images/arrow.png);background-position:0 10px;background-repeat:no-repeat;padding:0 5px}.cke_rtl .cke_menuarrow{background-position:5px -13px;background-repeat:no-repeat}.cke_menuarrow span{display:none}.cke_hc .cke_menuarrow span{vertical-align:middle;display:inline}.cke_combo{display:inline-block;float:left}.cke_rtl .cke_combo{float:right}.cke_hc .cke_combo{margin-top:-2px}.cke_combo_label{display:none;float:left;line-height:26px;vertical-align:top;margin-right:5px}.cke_rtl .cke_combo_label{float:right;margin-left:5px;margin-right:0}a.cke_combo_button{cursor:default;display:inline-block;float:left;margin:0 6px 5px 0;border:1px solid #a6a6a6;border-bottom-color:#979797;border-radius:3px;box-shadow:0 1px 0 rgba(255,255,255,.5),0 0 2px rgba(255,255,255,.15) inset,0 1px 0 rgba(255,255,255,.15) inset;background:#e4e4e4;background-image:linear-gradient(to bottom,#fff,#e4e4e4);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#ffffff',endColorstr='#e4e4e4')}.cke_combo_off a.cke_combo_button:hover,.cke_combo_off a.cke_combo_button:focus{background:#ccc;background-image:linear-gradient(to bottom,#f2f2f2,#ccc);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#f2f2f2',endColorstr='#cccccc');outline:0}.cke_combo_off a.cke_combo_button:active,.cke_combo_on a.cke_combo_button{border:1px solid #777;box-shadow:0 1px 0 rgba(255,255,255,.5),0 1px 5px rgba(0,0,0,.6) inset;background:#b5b5b5;background-image:linear-gradient(to bottom,#aaa,#cacaca);filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr='#aaaaaa',endColorstr='#cacaca')}.cke_combo_on a.cke_combo_button:hover,.cke_combo_on a.cke_combo_button:focus,.cke_combo_on a.cke_combo_button:active{box-shadow:0 1px 6px rgba(0,0,0,.7) inset,0 1px 0 rgba(0,0,0,.2)}.cke_rtl .cke_combo_button{float:right;margin-left:5px;margin-right:0}.cke_hc a.cke_combo_button{padding:3px}.cke_hc .cke_combo_on a.cke_combo_button,.cke_hc .cke_combo_off a.cke_combo_button:hover,.cke_hc .cke_combo_off a.cke_combo_button:focus,.cke_hc .cke_combo_off a.cke_combo_button:active{border-width:3px;padding:1px}.cke_combo_text{line-height:26px;padding-left:10px;text-overflow:ellipsis;overflow:hidden;float:left;cursor:default;color:#474747;text-shadow:0 1px 0 rgba(255,255,255,.5);width:60px}.cke_rtl .cke_combo_text{float:right;text-align:right;padding-left:0;padding-right:10px}.cke_hc .cke_combo_text{line-height:18px;font-size:12px}.cke_combo_open{cursor:default;display:inline-block;font-size:0;height:19px;line-height:17px;margin:1px 7px 1px;width:5px}.cke_hc .cke_combo_open{height:12px}.cke_combo_arrow{cursor:default;margin:11px 0 0;float:left;height:0;width:0;font-size:0;border-left:3px solid transparent;border-right:3px solid transparent;border-top:3px solid #474747}.cke_hc .cke_combo_arrow{font-size:10px;width:auto;border:0;margin-top:3px}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{opacity:.3}.cke_path{float:left;margin:-2px 0 2px}a.cke_path_item,span.cke_path_empty{display:inline-block;float:left;padding:3px 4px;margin-right:2px;cursor:default;text-decoration:none;outline:0;border:0;color:#4c4c4c;text-shadow:0 1px 0 #fff;font-weight:bold;font-size:11px}.cke_rtl .cke_path,.cke_rtl .cke_path_item,.cke_rtl .cke_path_empty{float:right}a.cke_path_item:hover,a.cke_path_item:focus,a.cke_path_item:active{background-color:#bfbfbf;color:#333;text-shadow:0 1px 0 rgba(255,255,255,.5);border-radius:2px;box-shadow:0 0 4px rgba(0,0,0,.5) inset,0 1px 0 rgba(255,255,255,.5)}.cke_hc a.cke_path_item:hover,.cke_hc a.cke_path_item:focus,.cke_hc a.cke_path_item:active{border:2px solid;padding:1px 2px}.cke_button__source_label,.cke_button__sourcedialog_label{display:inline}.cke_combo__fontsize .cke_combo_text{width:30px}.cke_combopanel__fontsize{width:120px}textarea.cke_source{font-family:'Courier New',Monospace;font-size:small;background-color:#fff;white-space:pre-wrap;border:0;padding:0;margin:0;display:block}.cke_wysiwyg_frame,.cke_wysiwyg_div{background-color:#fff}.cke_notifications_area{pointer-events:none}.cke_notification{pointer-events:auto;position:relative;margin:10px;width:300px;color:white;border-radius:3px;text-align:center;opacity:.95;filter:alpha(opacity = 95);box-shadow:2px 2px 3px 0 rgba(50,50,50,0.3);-webkit-animation:fadeIn .7s;animation:fadeIn .7s}.cke_notification_message a{color:#12306f}@-webkit-keyframes fadeIn{from{opacity:.4}to{opacity:.95}}@keyframes fadeIn{from{opacity:.4}to{opacity:.95}}.cke_notification_success{background:#72b572;border:1px solid #63a563}.cke_notification_warning{background:#c83939;border:1px solid #902b2b}.cke_notification_info{background:#2e9ad0;border:1px solid #0f74a8}.cke_notification_info span.cke_notification_progress{background-color:#0f74a8;display:block;padding:0;margin:0;height:100%;overflow:hidden;position:absolute;z-index:1}.cke_notification_message{position:relative;margin:4px 23px 3px;font-family:Arial,Helvetica,sans-serif;font-size:12px;line-height:18px;z-index:4;text-overflow:ellipsis;overflow:hidden}.cke_notification_close{background-image:url(images/close.png);background-repeat:no-repeat;background-position:50%;position:absolute;cursor:pointer;text-align:center;height:20px;width:20px;top:1px;right:1px;padding:0;margin:0;z-index:5;opacity:.6;filter:alpha(opacity = 60)}.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_notification_close span{display:none}.cke_notification_warning a.cke_notification_close{opacity:.8;filter:alpha(opacity = 80)}.cke_notification_warning a.cke_notification_close:hover{opacity:1;filter:alpha(opacity = 100)}.cke_chrome{visibility:inherit}.cke_voice_label{display:none}legend.cke_voice_label{display:none}a.cke_button_disabled,a.cke_button_disabled:hover,a.cke_button_disabled:focus,a.cke_button_disabled:active{filter:alpha(opacity = 30)}.cke_button_disabled .cke_button_icon{filter:progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff,endColorstr=#00ffffff)}.cke_button_off:hover,.cke_button_off:focus,.cke_button_off:active{filter:alpha(opacity = 100)}.cke_combo_disabled .cke_combo_inlinelabel,.cke_combo_disabled .cke_combo_open{filter:alpha(opacity = 30)}.cke_toolbox_collapser{border:1px solid #a6a6a6}.cke_toolbox_collapser .cke_arrow{margin-top:1px}.cke_hc .cke_top,.cke_hc .cke_bottom,.cke_hc .cke_combo_button,.cke_hc a.cke_combo_button:hover,.cke_hc a.cke_combo_button:focus,.cke_hc .cke_toolgroup,.cke_hc .cke_button_on,.cke_hc a.cke_button_off:hover,.cke_hc a.cke_button_off:focus,.cke_hc a.cke_button_off:active,.cke_hc .cke_toolbox_collapser,.cke_hc .cke_toolbox_collapser:hover,.cke_hc .cke_panel_grouptitle{filter:progid:DXImageTransform.Microsoft.gradient(enabled=false)}.cke_top,.cke_contents,.cke_bottom{width:100%}.cke_button_arrow{font-size:0}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_button,.cke_rtl .cke_button *,.cke_rtl .cke_combo,.cke_rtl .cke_combo *,.cke_rtl .cke_path_item,.cke_rtl .cke_path_item *,.cke_rtl .cke_path_empty{float:none}.cke_rtl .cke_toolgroup,.cke_rtl .cke_toolbar_separator,.cke_rtl .cke_combo_button,.cke_rtl .cke_combo_button *,.cke_rtl .cke_button,.cke_rtl .cke_button_icon{display:inline-block;vertical-align:top}.cke_rtl .cke_button_icon{float:none}.cke_resizer{width:10px}.cke_source{white-space:normal}.cke_bottom{position:static}.cke_colorbox{font-size:0}.cke_button__bold_icon {background: url(icons.png?t=20af917) no-repeat 0 -0px !important;}.cke_button__italic_icon {background: url(icons.png?t=20af917) no-repeat 0 -24px !important;}.cke_button__strike_icon {background: url(icons.png?t=20af917) no-repeat 0 -48px !important;}.cke_button__subscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -72px !important;}.cke_button__superscript_icon {background: url(icons.png?t=20af917) no-repeat 0 -96px !important;}.cke_button__underline_icon {background: url(icons.png?t=20af917) no-repeat 0 -120px !important;}.cke_button__horizontalrule_icon {background: url(icons.png?t=20af917) no-repeat 0 -144px !important;}.cke_button__iframe_icon {background: url(icons.png?t=20af917) no-repeat 0 -168px !important;}.cke_button__image_icon {background: url(icons.png?t=20af917) no-repeat 0 -192px !important;}.cke_rtl .cke_button__indent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -216px !important;}.cke_ltr .cke_button__indent_icon {background: url(icons.png?t=20af917) no-repeat 0 -240px !important;}.cke_rtl .cke_button__outdent_icon, .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -264px !important;}.cke_ltr .cke_button__outdent_icon {background: url(icons.png?t=20af917) no-repeat 0 -288px !important;}.cke_button__justifyblock_icon {background: url(icons.png?t=20af917) no-repeat 0 -312px !important;}.cke_button__justifycenter_icon {background: url(icons.png?t=20af917) no-repeat 0 -336px !important;}.cke_button__justifyleft_icon {background: url(icons.png?t=20af917) no-repeat 0 -360px !important;}.cke_button__justifyright_icon {background: url(icons.png?t=20af917) no-repeat 0 -384px !important;}.cke_rtl .cke_button__anchor_icon, .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -408px !important;}.cke_ltr .cke_button__anchor_icon {background: url(icons.png?t=20af917) no-repeat 0 -432px !important;}.cke_button__link_icon {background: url(icons.png?t=20af917) no-repeat 0 -456px !important;}.cke_button__unlink_icon {background: url(icons.png?t=20af917) no-repeat 0 -480px !important;}.cke_rtl .cke_button__bulletedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -504px !important;}.cke_ltr .cke_button__bulletedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -528px !important;}.cke_rtl .cke_button__numberedlist_icon, .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -552px !important;}.cke_ltr .cke_button__numberedlist_icon {background: url(icons.png?t=20af917) no-repeat 0 -576px !important;}.cke_button__maximize_icon {background: url(icons.png?t=20af917) no-repeat 0 -600px !important;}.cke_button__removeformat_icon {background: url(icons.png?t=20af917) no-repeat 0 -624px !important;}.cke_rtl .cke_button__source_icon, .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -648px !important;}.cke_ltr .cke_button__source_icon {background: url(icons.png?t=20af917) no-repeat 0 -672px !important;}.cke_rtl .cke_button__copy_icon, .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -696px !important;}.cke_ltr .cke_button__copy_icon {background: url(icons.png?t=20af917) no-repeat 0 -720px !important;}.cke_rtl .cke_button__cut_icon, .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -744px !important;}.cke_ltr .cke_button__cut_icon {background: url(icons.png?t=20af917) no-repeat 0 -768px !important;}.cke_rtl .cke_button__paste_icon, .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -792px !important;}.cke_ltr .cke_button__paste_icon {background: url(icons.png?t=20af917) no-repeat 0 -816px !important;}.cke_button__oembed_icon {background: url(icons.png?t=20af917) no-repeat 0 -840px !important;}.cke_hidpi .cke_button__bold_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -0px !important;background-size: 16px !important;}.cke_hidpi .cke_button__italic_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -24px !important;background-size: 16px !important;}.cke_hidpi .cke_button__strike_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -48px !important;background-size: 16px !important;}.cke_hidpi .cke_button__subscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -72px !important;background-size: 16px !important;}.cke_hidpi .cke_button__superscript_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -96px !important;background-size: 16px !important;}.cke_hidpi .cke_button__underline_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -120px !important;background-size: 16px !important;}.cke_hidpi .cke_button__horizontalrule_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -144px !important;background-size: 16px !important;}.cke_hidpi .cke_button__iframe_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -168px !important;background-size: 16px !important;}.cke_hidpi .cke_button__image_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -192px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__indent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -216px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__indent_icon,.cke_ltr.cke_hidpi .cke_button__indent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -240px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__outdent_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -264px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__outdent_icon,.cke_ltr.cke_hidpi .cke_button__outdent_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -288px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyblock_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -312px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifycenter_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -336px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyleft_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -360px !important;background-size: 16px !important;}.cke_hidpi .cke_button__justifyright_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -384px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__anchor_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -408px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__anchor_icon,.cke_ltr.cke_hidpi .cke_button__anchor_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -432px !important;background-size: 16px !important;}.cke_hidpi .cke_button__link_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -456px !important;background-size: 16px !important;}.cke_hidpi .cke_button__unlink_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -480px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__bulletedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -504px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__bulletedlist_icon,.cke_ltr.cke_hidpi .cke_button__bulletedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -528px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__numberedlist_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -552px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__numberedlist_icon,.cke_ltr.cke_hidpi .cke_button__numberedlist_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -576px !important;background-size: 16px !important;}.cke_hidpi .cke_button__maximize_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -600px !important;background-size: 16px !important;}.cke_hidpi .cke_button__removeformat_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -624px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__source_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -648px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__source_icon,.cke_ltr.cke_hidpi .cke_button__source_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -672px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__copy_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -696px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__copy_icon,.cke_ltr.cke_hidpi .cke_button__copy_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -720px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__cut_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -744px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__cut_icon,.cke_ltr.cke_hidpi .cke_button__cut_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -768px !important;background-size: 16px !important;}.cke_rtl.cke_hidpi .cke_button__paste_icon, .cke_hidpi .cke_mixed_dir_content .cke_rtl .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -792px !important;background-size: 16px !important;}.cke_hidpi .cke_ltr .cke_button__paste_icon,.cke_ltr.cke_hidpi .cke_button__paste_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -816px !important;background-size: 16px !important;}.cke_hidpi .cke_button__oembed_icon {background: url(icons_hidpi.png?t=20af917) no-repeat 0 -840px !important;background-size: 16px !important;}
\ No newline at end of file
diff --git a/release/skins/moono/icons.png b/release/skins/moono/icons.png
new file mode 100644 (file)
index 0000000..f63816f
Binary files /dev/null and b/release/skins/moono/icons.png differ
diff --git a/release/skins/moono/icons_hidpi.png b/release/skins/moono/icons_hidpi.png
new file mode 100644 (file)
index 0000000..be1b71b
Binary files /dev/null and b/release/skins/moono/icons_hidpi.png differ
diff --git a/release/skins/moono/images/anchor.png b/release/skins/moono/images/anchor.png
new file mode 100644 (file)
index 0000000..1c802f5
Binary files /dev/null and b/release/skins/moono/images/anchor.png differ
diff --git a/release/skins/moono/images/arrow.png b/release/skins/moono/images/arrow.png
new file mode 100644 (file)
index 0000000..d72b5f3
Binary files /dev/null and b/release/skins/moono/images/arrow.png differ
diff --git a/release/skins/moono/images/close.png b/release/skins/moono/images/close.png
new file mode 100644 (file)
index 0000000..2d02977
Binary files /dev/null and b/release/skins/moono/images/close.png differ
diff --git a/release/skins/moono/images/hidpi/anchor.png b/release/skins/moono/images/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..17cca97
Binary files /dev/null and b/release/skins/moono/images/hidpi/anchor.png differ
diff --git a/release/skins/moono/images/hidpi/close.png b/release/skins/moono/images/hidpi/close.png
new file mode 100644 (file)
index 0000000..de4eedf
Binary files /dev/null and b/release/skins/moono/images/hidpi/close.png differ
diff --git a/release/skins/moono/images/hidpi/lock-open.png b/release/skins/moono/images/hidpi/lock-open.png
new file mode 100644 (file)
index 0000000..594f0d3
Binary files /dev/null and b/release/skins/moono/images/hidpi/lock-open.png differ
diff --git a/release/skins/moono/images/hidpi/lock.png b/release/skins/moono/images/hidpi/lock.png
new file mode 100644 (file)
index 0000000..1e23a0b
Binary files /dev/null and b/release/skins/moono/images/hidpi/lock.png differ
diff --git a/release/skins/moono/images/hidpi/refresh.png b/release/skins/moono/images/hidpi/refresh.png
new file mode 100644 (file)
index 0000000..42d94a9
Binary files /dev/null and b/release/skins/moono/images/hidpi/refresh.png differ
diff --git a/release/skins/moono/images/lock-open.png b/release/skins/moono/images/lock-open.png
new file mode 100644 (file)
index 0000000..7d24c5f
Binary files /dev/null and b/release/skins/moono/images/lock-open.png differ
diff --git a/release/skins/moono/images/lock.png b/release/skins/moono/images/lock.png
new file mode 100644 (file)
index 0000000..8baeaa4
Binary files /dev/null and b/release/skins/moono/images/lock.png differ
diff --git a/release/skins/moono/images/refresh.png b/release/skins/moono/images/refresh.png
new file mode 100644 (file)
index 0000000..d8106b0
Binary files /dev/null and b/release/skins/moono/images/refresh.png differ
diff --git a/release/skins/moono/images/spinner.gif b/release/skins/moono/images/spinner.gif
new file mode 100644 (file)
index 0000000..d898d41
Binary files /dev/null and b/release/skins/moono/images/spinner.gif differ
diff --git a/release/skins/moono/readme.md b/release/skins/moono/readme.md
new file mode 100644 (file)
index 0000000..4a4ed6b
--- /dev/null
@@ -0,0 +1,49 @@
+"Moono" Skin\r
+====================\r
+\r
+This skin has been chosen for the **default skin** of CKEditor 4.x (replaced by "Moono-lisa" skin since CKEditor 4.6.0),\r
+elected from the CKEditor [skin contest](http://ckeditor.com/blog/new_ckeditor_4_skin) and further shaped by\r
+the CKEditor team. "Moono" is maintained by the core developers.\r
+\r
+For more information about skins, please check the [CKEditor Skin SDK](http://docs.cksource.com/CKEditor_4.x/Skin_SDK)\r
+documentation.\r
+\r
+Features\r
+-------------------\r
+"Moono" is a monochromatic skin, which offers a modern look coupled with gradients and transparency.\r
+It comes with the following features:\r
+\r
+- Chameleon feature with brightness,\r
+- high-contrast compatibility,\r
+- graphics source provided in SVG.\r
+\r
+Directory Structure\r
+-------------------\r
+\r
+CSS parts:\r
+- **editor.css**: the main CSS file. It's simply loading several other files, for easier maintenance,\r
+- **mainui.css**: the file contains styles of entire editor outline structures,\r
+- **toolbar.css**: the file contains styles of the editor toolbar space (top),\r
+- **richcombo.css**: the file contains styles of the rich combo ui elements on toolbar,\r
+- **panel.css**: the file contains styles of the rich combo drop-down, it's not loaded\r
+until the first panel open up,\r
+- **elementspath.css**: the file contains styles of the editor elements path bar (bottom),\r
+- **menu.css**: the file contains styles of all editor menus including context menu and button drop-down,\r
+it's not loaded until the first menu open up,\r
+- **dialog.css**: the CSS files for the dialog UI, it's not loaded until the first dialog open,\r
+- **reset.css**: the file defines the basis of style resets among all editor UI spaces,\r
+- **preset.css**: the file defines the default styles of some UI elements reflecting the skin preference,\r
+- **editor_XYZ.css** and **dialog_XYZ.css**: browser specific CSS hacks.\r
+\r
+Other parts:\r
+- **skin.js**: the only JavaScript part of the skin that registers the skin, its browser specific files and its icons and defines the Chameleon feature,\r
+- **icons/**: contains all skin defined icons,\r
+- **images/**: contains a fill general used images,\r
+- **dev/**: contains SVG source of the skin icons.\r
+\r
+License\r
+-------\r
+\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+\r
+For licensing, see LICENSE.md or [http://ckeditor.com/license](http://ckeditor.com/license)\r
diff --git a/release/styles.js b/release/styles.js
new file mode 100644 (file)
index 0000000..287e633
--- /dev/null
@@ -0,0 +1,137 @@
+/**\r
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+// This file contains style definitions that can be used by CKEditor plugins.\r
+//\r
+// The most common use for it is the "stylescombo" plugin which shows the Styles drop-down\r
+// list containing all styles in the editor toolbar. Other plugins, like\r
+// the "div" plugin, use a subset of the styles for their features.\r
+//\r
+// If you do not have plugins that depend on this file in your editor build, you can simply\r
+// ignore it. Otherwise it is strongly recommended to customize this file to match your\r
+// website requirements and design properly.\r
+//\r
+// For more information refer to: http://docs.ckeditor.com/#!/guide/dev_styles-section-style-rules\r
+\r
+CKEDITOR.stylesSet.add( 'default', [\r
+       /* Block styles */\r
+\r
+       // These styles are already available in the "Format" drop-down list ("format" plugin),\r
+       // so they are not needed here by default. You may enable them to avoid\r
+       // placing the "Format" combo in the toolbar, maintaining the same features.\r
+       /*\r
+       { name: 'Paragraph',            element: 'p' },\r
+       { name: 'Heading 1',            element: 'h1' },\r
+       { name: 'Heading 2',            element: 'h2' },\r
+       { name: 'Heading 3',            element: 'h3' },\r
+       { name: 'Heading 4',            element: 'h4' },\r
+       { name: 'Heading 5',            element: 'h5' },\r
+       { name: 'Heading 6',            element: 'h6' },\r
+       { name: 'Preformatted Text',element: 'pre' },\r
+       { name: 'Address',                      element: 'address' },\r
+       */\r
+\r
+       { name: 'Italic Title',         element: 'h2', styles: { 'font-style': 'italic' } },\r
+       { name: 'Subtitle',                     element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },\r
+       {\r
+               name: 'Special Container',\r
+               element: 'div',\r
+               styles: {\r
+                       padding: '5px 10px',\r
+                       background: '#eee',\r
+                       border: '1px solid #ccc'\r
+               }\r
+       },\r
+\r
+       /* Inline styles */\r
+\r
+       // These are core styles available as toolbar buttons. You may opt enabling\r
+       // some of them in the Styles drop-down list, removing them from the toolbar.\r
+       // (This requires the "stylescombo" plugin.)\r
+       /*\r
+       { name: 'Strong',                       element: 'strong', overrides: 'b' },\r
+       { name: 'Emphasis',                     element: 'em'   , overrides: 'i' },\r
+       { name: 'Underline',            element: 'u' },\r
+       { name: 'Strikethrough',        element: 'strike' },\r
+       { name: 'Subscript',            element: 'sub' },\r
+       { name: 'Superscript',          element: 'sup' },\r
+       */\r
+\r
+       { name: 'Marker',                       element: 'span', attributes: { 'class': 'marker' } },\r
+\r
+       { name: 'Big',                          element: 'big' },\r
+       { name: 'Small',                        element: 'small' },\r
+       { name: 'Typewriter',           element: 'tt' },\r
+\r
+       { name: 'Computer Code',        element: 'code' },\r
+       { name: 'Keyboard Phrase',      element: 'kbd' },\r
+       { name: 'Sample Text',          element: 'samp' },\r
+       { name: 'Variable',                     element: 'var' },\r
+\r
+       { name: 'Deleted Text',         element: 'del' },\r
+       { name: 'Inserted Text',        element: 'ins' },\r
+\r
+       { name: 'Cited Work',           element: 'cite' },\r
+       { name: 'Inline Quotation',     element: 'q' },\r
+\r
+       { name: 'Language: RTL',        element: 'span', attributes: { 'dir': 'rtl' } },\r
+       { name: 'Language: LTR',        element: 'span', attributes: { 'dir': 'ltr' } },\r
+\r
+       /* Object styles */\r
+\r
+       {\r
+               name: 'Styled Image (left)',\r
+               element: 'img',\r
+               attributes: { 'class': 'left' }\r
+       },\r
+\r
+       {\r
+               name: 'Styled Image (right)',\r
+               element: 'img',\r
+               attributes: { 'class': 'right' }\r
+       },\r
+\r
+       {\r
+               name: 'Compact Table',\r
+               element: 'table',\r
+               attributes: {\r
+                       cellpadding: '5',\r
+                       cellspacing: '0',\r
+                       border: '1',\r
+                       bordercolor: '#ccc'\r
+               },\r
+               styles: {\r
+                       'border-collapse': 'collapse'\r
+               }\r
+       },\r
+\r
+       { name: 'Borderless Table',             element: 'table',       styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },\r
+       { name: 'Square Bulleted List', element: 'ul',          styles: { 'list-style-type': 'square' } },\r
+\r
+       /* Widget styles */\r
+\r
+       { name: 'Clean Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-clean' } },\r
+       { name: 'Grayscale Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-grayscale' } },\r
+\r
+       { name: 'Featured Snippet', type: 'widget', widget: 'codeSnippet', attributes: { 'class': 'code-featured' } },\r
+\r
+       { name: 'Featured Formula', type: 'widget', widget: 'mathjax', attributes: { 'class': 'math-featured' } },\r
+\r
+       { name: '240p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-240p' }, group: 'size' },\r
+       { name: '360p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-360p' }, group: 'size' },\r
+       { name: '480p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-480p' }, group: 'size' },\r
+       { name: '720p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-720p' }, group: 'size' },\r
+       { name: '1080p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-1080p' }, group: 'size' },\r
+\r
+       // Adding space after the style name is an intended workaround. For now, there\r
+       // is no option to create two styles with the same name for different widget types. See #16664.\r
+       { name: '240p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-240p' }, group: 'size' },\r
+       { name: '360p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-360p' }, group: 'size' },\r
+       { name: '480p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-480p' }, group: 'size' },\r
+       { name: '720p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-720p' }, group: 'size' },\r
+       { name: '1080p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-1080p' }, group: 'size' }\r
+\r
+] );\r
+\r
diff --git a/sources/CHANGES.md b/sources/CHANGES.md
new file mode 100644 (file)
index 0000000..1419e55
--- /dev/null
@@ -0,0 +1,1219 @@
+CKEditor 4 Changelog
+====================
+
+## CKEditor 4.6.2
+
+New Features:
+
+* [#16733](http://dev.ckeditor.com/ticket/16733): Added a new pastel color palette for the [Color Button](http://ckeditor.com/addon/colorbutton) plugin and a new [`config.colorButton_colorsPerRow`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_colorsPerRow) configuration option for setting the number of rows in the color selector.
+* [#16752](http://dev.ckeditor.com/ticket/16752): Added a new Azerbaijani localization. Thanks to the [Azerbaijani language team](https://www.transifex.com/ckeditor/teams/11143/az/)!
+* [#13818](http://dev.ckeditor.com/ticket/13818): It is now possible to group [Widget](http://ckeditor.com/addon/widget) [style definitions](http://docs.ckeditor.com/#!/guide/dev_styles-section-widget-styles), so applying one style disables the other.
+
+Fixed Issues:
+
+* [#13446](http://dev.ckeditor.com/ticket/13446): [Chrome] Fixed: It is possible to type in an unfocused inline editor.
+* [#14856](http://dev.ckeditor.com/ticket/14856): Fixed: [Font size and font family](http://ckeditor.com/addon/font) reset each other when modified at certain positions.
+* [#16745](http://dev.ckeditor.com/ticket/16745): [Edge] Fixed: List items are lost when [pasted from Word](http://ckeditor.com/addon/pastefromword).
+* [#16682](http://dev.ckeditor.com/ticket/16682): [Edge] Fixed: A list gets [pasted from Word](http://ckeditor.com/addon/pastefromword) as a set of paragraphs. Added the [`config.pasteFromWord_heuristicsEdgeList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWord_heuristicsEdgeList) configuration option.
+* [#10373](http://dev.ckeditor.com/ticket/10373): Fixed: Context menu items can be dragged into the editor.
+* [#16728](http://dev.ckeditor.com/ticket/16728): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Quirks Mode.
+* [#16795](http://dev.ckeditor.com/ticket/16795): [IE] Fixed: [Copy Formatting](http://ckeditor.com/addon/copyformatting) breaks the editor in Compatibility Mode.
+* [#16675](http://dev.ckeditor.com/ticket/16675): Fixed: Styles applied with [Copy Formatting](http://ckeditor.com/addon/copyformatting) to a single table cell are applied to the whole table.
+* [#16753](http://dev.ckeditor.com/ticket/16753): Fixed: [`element.setSize`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-setSize) sets incorrect editor dimensions if the border width is represented as a fraction of pixels.
+* [#16705](http://dev.ckeditor.com/ticket/16705): [Firefox] Fixed: Unable to paste images as Base64 strings when using [Clipboard](http://ckeditor.com/addon/clipboard).
+* [#14869](http://dev.ckeditor.com/ticket/14869): Fixed: JavaScript error is thrown when trying to use [Find](http://ckeditor.com/addon/find) in a [`<div>`-based editor](http://ckeditor.com/addon/divarea).
+
+## CKEditor 4.6.1
+
+New Features:
+
+* [#16639](http://dev.ckeditor.com/ticket/16639): The `callback` parameter in the [CKEDITOR.ajax.post](http://docs.ckeditor.com/#!/api/CKEDITOR.ajax-method-post) method became optional.
+
+Fixed Issues:
+
+* [#11064](http://dev.ckeditor.com/ticket/11064): [Blink, WebKit] Fixed: Cannot select all editor content when a widget or a non-editable element is the first or last element of the content. Also fixes this issue in the [Select All](http://ckeditor.com/addon/selectall) plugin.
+* [#14755](http://dev.ckeditor.com/ticket/14755): [Blink, WebKit, IE8] Fixed: Browser hangs when a table is inserted in the place of a selected list with an empty last item.
+* [#16624](http://dev.ckeditor.com/ticket/16624): Fixed: Improved the [Color Button](http://ckeditor.com/addon/colorbutton) plugin which will now normalize the CSS `background` property if it only contains a color value. This fixes missing background colors when using [Paste from Word](http://ckeditor.com/addon/pastefromword).
+* [#16600](http://dev.ckeditor.com/ticket/16600): [Blink, WebKit] Fixed: Error thrown occasionally by an uninitialized editable for multiple CKEditor instances on the same page.
+
+## CKEditor 4.6
+
+New Features:
+
+* [#14569](http://dev.ckeditor.com/ticket/14569): Added a new, flat, default CKEditor skin called [Moono-Lisa](http://ckeditor.com/addon/moono-lisa). Refreshed default colors available in the [Color Button](http://ckeditor.com/addon/colorbutton) plugin ([Text Color and Background Color](http://docs.ckeditor.com/#!/guide/dev_colorbutton) feature).
+* [#14707](http://dev.ckeditor.com/ticket/14707): Added a new [Copy Formatting](http://ckeditor.com/addon/copyformatting) feature to enable easy copying of styles between your document parts.
+* Introduced the completely rewritten [Paste from Word](http://ckeditor.com/addon/pastefromword) plugin:
+       * Backward incompatibility: The [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) option now defaults to `false`. This option will be deprecated in the future. Use [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) to replicate the effect of setting it to `true`.
+       * Backward incompatibility: The [`config.pasteFromWordNumberedHeadingToList`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordNumberedHeadingToList) and [`config.pasteFromWordRemoveStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveStyles) options were dropped and no longer have any effect on pasted content.
+       * Major improvements in preservation of list numbering, styling and indentation (nested lists with multiple levels).
+       * Major improvements in document structure parsing that fix plenty of issues with distorted or missing content after paste.
+* Added new translation: Occitan. Thanks to [Cédric Valmary](https://totenoc.eu/)!
+* [#10015](http://dev.ckeditor.com/ticket/10015): Keyboard shortcuts (relevant to the operating system in use) will now be displayed in tooltips and context menus.
+* [#13794](http://dev.ckeditor.com/ticket/13794): The [Upload Image](http://ckeditor.com/addon/uploadimage) feature now uses `uploaded.width/height` if set.
+* [#12541](http://dev.ckeditor.com/ticket/12541): Added the [Upload File](http://ckeditor.com/addon/uploadfile) plugin that lets you upload a file by drag&amp;dropping it into the editor content.
+* [#14449](http://dev.ckeditor.com/ticket/14449): Introduced the [Balloon Panel](http://ckeditor.com/addon/balloonpanel) plugin that lets you create stylish floating UI elements for the editor.
+* [#12077](https://dev.ckeditor.com/ticket/12077): Added support for the HTML5 `download` attribute in link (`<a>`) elements. Selecting the "Force Download" checkbox in the [Link](http://ckeditor.com/addon/link) dialog will cause the linked file to be downloaded automatically. Thanks to [sbusse](https://github.com/sbusse)!
+* [#13518](http://dev.ckeditor.com/ticket/13518): Introduced the [`additionalRequestParameters`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition-property-additionalRequestParameters) property for file uploads to make it possible to send additional information about the uploaded file to the server.
+* [#14889](http://dev.ckeditor.com/ticket/14889): Added the [`config.image2_altRequired`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_altRequired) option for the [Enhanced Image](http://ckeditor.com/addon/image2) plugin to allow making alternative text a mandatory field. Thanks to [Andrey Fedoseev](https://github.com/andreyfedoseev)!
+
+Fixed Issues:
+
+* [#9991](http://dev.ckeditor.com/ticket/9991): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) should only normalize input data.
+* [#7209](http://dev.ckeditor.com/ticket/7209): Fixed: Lists with 3 levels not [pasted from Word](http://ckeditor.com/addon/pastefromword) correctly.
+* [#14335](http://dev.ckeditor.com/ticket/14335): Fixed: Pasting a numbered list starting with a value different from "1" from Microsoft Word does not work correctly.
+* [#14542](http://dev.ckeditor.com/ticket/14542): Fixed: Copying a numbered list from Microsoft Word does not preserve list formatting.
+* [#14544](http://dev.ckeditor.com/ticket/14544): Fixed: Copying a nested list from Microsoft Word results in an empty list.
+* [#14660](http://dev.ckeditor.com/ticket/14660): Fixed: [Pasting text from  Word](http://ckeditor.com/addon/pastefromword) breaks the styling in some cases.
+* [#14867](http://dev.ckeditor.com/ticket/14867): [Firefox] Fixed: Text gets stripped when [pasting content from Word](http://ckeditor.com/addon/pastefromword).
+* [#2507](http://dev.ckeditor.com/ticket/2507): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) does not detect pasting a part of a paragraph.
+* [#3336](http://dev.ckeditor.com/ticket/3336): Fixed: Extra blank row added on top of the content [pasted from Word](http://ckeditor.com/addon/pastefromword).
+* [#6115](http://dev.ckeditor.com/ticket/6115): Fixed: When Right-to-Left text direction is applied to a table [pasted from Word](http://ckeditor.com/addon/pastefromword), borders are missing on one side.
+* [#6342](http://dev.ckeditor.com/ticket/6342): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filters out a basic text style when it is [configured to use attributes](http://docs.ckeditor.com/#!/guide/dev_basicstyles-section-custom-basic-text-style-definition).
+* [#6457](http://dev.ckeditor.com/ticket/6457): [IE] Fixed: [Pasting from Word](http://ckeditor.com/addon/pastefromword) is extremely slow.
+* [#6789](http://dev.ckeditor.com/ticket/6789): Fixed: The `mso-list: ignore` style is not handled properly when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#7262](http://dev.ckeditor.com/ticket/7262): Fixed: Lists in preformatted body disappear when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#7662](http://dev.ckeditor.com/ticket/7662): [Opera] Fixed: Extra empty number/bullet shown in the editor body when editing a multi-level list [pasted from Word](http://ckeditor.com/addon/pastefromword).
+* [#7807](http://dev.ckeditor.com/ticket/7807): Fixed: Last item in a list not converted to a `<li>` element after [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#7950](http://dev.ckeditor.com/ticket/7950): [IE] Fixed: Content [from Word pasted](http://ckeditor.com/addon/pastefromword) differently than in other browsers.
+* [#7982](http://dev.ckeditor.com/ticket/7982): Fixed: Multi-level lists get split into smaller ones when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#8231](http://dev.ckeditor.com/ticket/8231): [WebKit, Opera] Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts empty paragraphs.
+* [#8266](http://dev.ckeditor.com/ticket/8266): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) inserts a blank line at the top.
+* [#8341](http://dev.ckeditor.com/ticket/8341), [#7646](http://dev.ckeditor.com/ticket/7646): Fixed: Faulty removal of empty `<span>` elements in [Paste from Word](http://ckeditor.com/addon/pastefromword) content cleanup breaking content formatting.
+* [#8754](http://dev.ckeditor.com/ticket/8754): [Firefox] Fixed: Incorrect pasting of multiple nested lists in [Paste from Word](http://ckeditor.com/addon/pastefromword).
+* [#8983](http://dev.ckeditor.com/ticket/8983): Fixed: Alignment lost when [pasting from Word](http://ckeditor.com/addon/pastefromword) with [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) set to [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).
+* [#9331](http://dev.ckeditor.com/ticket/9331): [IE] Fixed: [Pasting text from Word](http://ckeditor.com/addon/pastefromword) creates a simple Caesar cipher.
+* [#9422](http://dev.ckeditor.com/ticket/9422): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) leaves an unwanted `color:windowtext` style.
+* [#10011](http://dev.ckeditor.com/ticket/10011): [IE9-10] Fixed: [`config.pasteFromWordRemoveFontStyles`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordRemoveFontStyles) is ignored under certain conditions.
+* [#10643](http://dev.ckeditor.com/ticket/10643): Fixed: Differences between using <kbd>Ctrl+V</kbd> and pasting from the [Paste from Word](http://ckeditor.com/addon/pastefromword) dialog.
+* [#10784](http://dev.ckeditor.com/ticket/10784): Fixed: Lines missing when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#11294](http://dev.ckeditor.com/ticket/11294): [IE10] Fixed: Font size is not preserved when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#11627](http://dev.ckeditor.com/ticket/11627): Fixed: Missing words when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#12784](http://dev.ckeditor.com/ticket/12784): Fixed: Bulleted list with custom bullets gets changed to a numbered list when [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#13174](http://dev.ckeditor.com/ticket/13174): Fixed: Data loss after [pasting from Word](http://ckeditor.com/addon/pastefromword).
+* [#13828](http://dev.ckeditor.com/ticket/13828): Fixed: Widget classes should be added to the wrapper rather than the widget element.
+* [#13829](http://dev.ckeditor.com/ticket/13829): Fixed: No class in [Widget](http://ckeditor.com/addon/widget) wrapper to identify the widget type.
+* [#13519](http://dev.ckeditor.com/ticket/13519): Server response received when uploading files should be more flexible.
+
+Other Changes:
+
+* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type) and [WebSpellChecker](http://ckeditor.com/addon/wsc) plugins:
+       * Support for the new default Moono-Lisa skin.
+       * [#121](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/121): Fixed: [Basic Styles](http://ckeditor.com/addon/basicstyles) do not work when SCAYT is enabled.
+       * [#125](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/125): Fixed: Inline styles are not continued when writing multiple lines of styled text with SCAYT enabled.
+       * [#127](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/127): Fixed: Uncaught TypeError after enabling SCAYT in the CKEditor `<div>` element.
+       * [#128](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/128): Fixed: Error thrown after enabling SCAYT caused by conflicts with RequireJS.
+
+## CKEditor 4.5.11
+
+**Security Updates:**
+
+* [Severity: minor] Fixed the `target="_blank"` vulnerability reported by James Gaskell.
+
+       Issue summary: If a victim had access to a spoofed version of ckeditor.com via HTTP (e.g. due to DNS spoofing, using a hacked public network or mailicious hotspot), then when using a link to the ckeditor.com website it was possible for the attacker to change the current URL of the opening page, even if the opening page was protected with SSL.
+
+  An upgrade is recommended.
+
+New Features:
+
+* [#14747](http://dev.ckeditor.com/ticket/14747): The [Enhanced Image](http://ckeditor.com/addon/image2) caption now supports the link `target` attribute.
+* [#7154](http://dev.ckeditor.com/ticket/7154): Added support for the "Display Text" field to the [Link](http://ckeditor.com/addon/link) dialog. Thanks to [Ryan Guill](https://github.com/ryanguill)!
+
+Fixed Issues:
+
+* [#13362](http://dev.ckeditor.com/ticket/13362): [Blink, WebKit] Fixed: Active widget element is not cached when it is losing focus and it is inside an editable element.
+* [#13755](http://dev.ckeditor.com/ticket/13755): [Edge] Fixed: Pasting images does not work.
+* [#13548](http://dev.ckeditor.com/ticket/13548): [IE] Fixed: Clicking the [elements path](http://ckeditor.com/addon/elementspath) disables Cut and Copy icons.
+* [#13812](http://dev.ckeditor.com/ticket/13812): Fixed: When aborting file upload the placeholder for image is left.
+* [#14659](http://dev.ckeditor.com/ticket/14659): [Blink] Fixed: Content scrolled to the top after closing the dialog in a [`<div>`-based editor](http://ckeditor.com/addon/divarea).
+* [#14825](http://dev.ckeditor.com/ticket/14825): [Edge] Fixed: Focusing the editor causes unwanted scrolling due to dropped support for the `setActive` method.
+
+## CKEditor 4.5.10
+
+Fixed Issues:
+
+* [#10750](http://dev.ckeditor.com/ticket/10750): Fixed: The editor does not escape the `font-style` family property correctly, removing quotes and whitespace from font names.
+* [#14413](http://dev.ckeditor.com/ticket/14413): Fixed: The [Auto Grow](http://ckeditor.com/addon/autogrow) plugin with the [`config.autoGrow_onStartup`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoGrow_onStartup) option set to `true` does not work properly for an editor that is not visible.
+* [#14451](http://dev.ckeditor.com/ticket/14451): Fixed: Numeric element ID not escaped properly. Thanks to [Jakub Chalupa](https://github.com/chaluja7)!
+* [#14590](http://dev.ckeditor.com/ticket/14590): Fixed: Additional line break appearing after inline elements when switching modes. Thanks to [dpidcock](https://github.com/dpidcock)!
+* [#14539](https://dev.ckeditor.com/ticket/14539): Fixed: JAWS reads "selected Blank" instead of "selected <widget name>" when selecting a widget.
+* [#14701](http://dev.ckeditor.com/ticket/14701): Fixed: More precise labels for [Enhanced Image](http://ckeditor.com/addon/image2) and [Placeholder](http://ckeditor.com/addon/placeholder) widgets.
+* [#14667](http://dev.ckeditor.com/ticket/14667): [IE] Fixed: Removing background color from selected text removes background color from the whole paragraph.
+* [#14252](http://dev.ckeditor.com/ticket/14252): [IE] Fixed: Styles drop-down list does not always reflect the current style of the text line.
+* [#14275](http://dev.ckeditor.com/ticket/14275): [IE9+] Fixed: `onerror` and `onload` events are not used in browsers it could have been used when loading scripts dynamically.
+
+## CKEditor 4.5.9
+
+Fixed Issues:
+
+* [#10685](http://dev.ckeditor.com/ticket/10685): Fixed: Unreadable toolbar icons after updating to the new editor version. Fixed with [6876179](https://github.com/ckeditor/ckeditor-dev/commit/6876179db4ee97e786b07b8fd72e6b4120732185) in [ckeditor-dev](https://github.com/ckeditor/ckeditor-dev) and [6c9189f4](https://github.com/ckeditor/ckeditor-presets/commit/6c9189f46392d2c126854fe8889b820b8c76d291) in [ckeditor-presets](https://github.com/ckeditor/ckeditor-presets).
+* [#14573](https://dev.ckeditor.com/ticket/14573): Fixed: Missing [Widget](http://ckeditor.com/addon/widget) drag handler CSS when there are multiple editor instances.
+* [#14620](https://dev.ckeditor.com/ticket/14620): Fixed: Setting both the `min-height` style for the `<body>` element and the `height` style for the `<html>` element breaks the [Auto Grow](http://ckeditor.com/addon/autogrow) plugin.
+* [#14538](http://dev.ckeditor.com/ticket/14538): Fixed: Keyboard focus goes into an embedded `<iframe>` element.
+* [#14602](http://dev.ckeditor.com/ticket/14602): Fixed: The [`dom.element.removeAttribute()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeAttribute) method does not remove all attributes if no parameter is given.
+* [#8679](http://dev.ckeditor.com/ticket/8679): Fixed: Better focus indication and ability to style the selected color in the [color picker dialog](http://ckeditor.com/addon/colordialog).
+* [#11697](http://dev.ckeditor.com/ticket/11697): Fixed: Content is replaced ignoring the letter case setting in the [Find and Replace](http://ckeditor.com/addon/find) dialog window.
+* [#13886](http://dev.ckeditor.com/ticket/13886): Fixed: Invalid handling of the [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) instance with the `styles` property by [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).
+* [#14535](http://dev.ckeditor.com/ticket/14535): Fixed: CSS syntax corrections. Thanks to [mdjdenormandie](https://github.com/mdjdenormandie)!
+
+## CKEditor 4.5.8
+
+New Features:
+
+* [#12440](http://dev.ckeditor.com/ticket/12440): Added the [`config.colorButton_enableAutomatic`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-colorButton_enableAutomatic) option to allow hiding the "Automatic" option in the [color picker](http://ckeditor.com/addon/colorbutton).
+
+Fixed Issues:
+
+* [#10448](http://dev.ckeditor.com/ticket/10448): Fixed: Lack of scrollbar in the [right-to-left text direction](http://ckeditor.com/addon/bidi).
+* [#12707](http://dev.ckeditor.com/ticket/12707): Fixed: The order of table elements does not comply with the HTML specification.
+* [#13756](http://dev.ckeditor.com/ticket/13756): [Edge] Fixed: Context menus are cut-off.
+
+## CKEditor 4.5.7
+
+New Features:
+
+* [#14327](http://dev.ckeditor.com/ticket/14327): Added Swiss German localization. Thanks to [Miro Grenda](https://twitter.com/mirogrenda)!
+
+Fixed Issues:
+
+* [#13816](http://dev.ckeditor.com/ticket/13816): Introduced a new strategy for Filling Character handling to avoid changes in DOM. This fixes the following issues:
+       * [#12727](http://dev.ckeditor.com/ticket/12727): [Blink] `IndexSizeError` when using the [Div Editing Area](http://ckeditor.com/addon/divarea) and [Content Templates](http://ckeditor.com/addon/templates) plugins.
+       * [#13377](http://dev.ckeditor.com/ticket/13377): [Widget](http://ckeditor.com/addon/widget) plugin issue when typing in Korean.
+       * [#13389](http://dev.ckeditor.com/ticket/13389): [Blink] [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) fails when the cursor is next to an `<hr>` tag.
+       * [#13513](http://dev.ckeditor.com/ticket/13513): [Blink, WebKit] [Div Editing Area](http://ckeditor.com/addon/divarea) and [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) throw an error when an image is the only data in the editor.
+* [#13884](http://dev.ckeditor.com/ticket/13884): [Firefox] Fixed: Copying and pasting a table results in just the first cell being pasted.
+* [#14234](http://dev.ckeditor.com/ticket/14234): Fixed: URL input field is not marked as required in the [Media Embed](http://ckeditor.com/addon/embed) dialog.
+
+## CKEditor 4.5.6
+
+New Features:
+
+* Introduced the [`CKEDITOR.tools.getCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCookie) and [`CKEDITOR.tools.setCookie()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-setCookie) methods for accessing cookies.
+* Introduced the [`CKEDITOR.tools.getCsrfToken()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-getCsrfToken) method. The CSRF token is now automatically sent by the [File Browser](http://ckeditor.com/addon/filebrowser) and [File Tools](http://ckeditor.com/addon/filetools) plugins during file uploads. The server-side upload handlers may check it and use it to additionally secure the communication.
+
+Other Changes:
+
+* Updated [SCAYT](http://ckeditor.com/addon/scayt) (Spell Check As You Type):
+       - New features:
+               - CKEditor [Language](http://ckeditor.com/addon/language) plugin support.
+               - CKEditor [Placeholder](http://ckeditor.com/addon/placeholder) plugin support.
+               - [Drag&Drop](http://sdk.ckeditor.com/samples/fileupload.html) support.
+               - **Experimental** [GRAYT](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-grayt_autoStartup) (Grammar As You Type) functionality.
+       - Fixed issues:
+               * [#98](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/98): SCAYT affects dialog double-click. Fixed in SCAYT core.
+               * [#102](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/102): SCAYT core performance enhancements.
+               * [#104](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/104): SCAYT's spans leak into the clipboard and after pasting.
+               * [#105](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/105): A JavaScript error fired in case of multiple instances of CKEditor on one page.
+               * [#107](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/107): SCAYT should not check non-editable parts of content.
+               * [#108](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/108): Latest SCAYT copies the ID of the editor element to the iframe.
+               * SCAYT stops working when CKEditor [Undo plugin](http://ckeditor.com/addon/undo) not enabled.
+               * Issue with pasting SCAYT markup in CKEditor.
+               * SCAYT stops working after pressing the *Cancel* button in the WSC dialog.
+
+## CKEditor 4.5.5
+
+Fixed Issues:
+
+* [#13887](https://dev.ckeditor.com/ticket/13887): Fixed: [Link](http://ckeditor.com/addon/link) plugin alters the `target` attribute value. Thanks to [SamZiemer](https://github.com/SamZiemer)!
+* [#12189](http://dev.ckeditor.com/ticket/12189): Fixed: The [Link](http://ckeditor.com/addon/link) plugin dialog does not display the subject of email links if the subject parameter is not lowercase.
+* [#9192](http://dev.ckeditor.com/ticket/9192): Fixed: An `undefined` string is appended to an email address added with the [Link](http://ckeditor.com/addon/link) plugin if subject and email body are empty and [`config.emailProtection`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-emailProtection) is set to `encode`.
+* [#13790](https://dev.ckeditor.com/ticket/13790): Fixed: It is not possible to destroy the editor `<iframe>` after the editor was detached from DOM. Thanks to [Stefan Rijnhart](https://github.com/StefanRijnhart)!
+* [#13803](https://dev.ckeditor.com/ticket/13803): Fixed: The editor cannot be destroyed before being fully initialized. Thanks to [Cyril Fluck](https://github.com/cyril-sf)!
+* [#13867](http://dev.ckeditor.com/ticket/13867): Fixed: CKEditor does not work when the `classList` polyfill is used.
+* [#13885](http://dev.ckeditor.com/ticket/13885): Fixed: [Enhanced Image](http://ckeditor.com/addon/image2) requires the [Link](http://ckeditor.com/addon/link) plugin to link an image.
+* [#13883](http://dev.ckeditor.com/ticket/13883): Fixed: Copying a table using the context menu strips off styles.
+* [#13872](http://dev.ckeditor.com/ticket/13872): Fixed: Cutting is possible in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode.
+* [#12848](http://dev.ckeditor.com/ticket/12848): [Blink] Fixed: Opening the [Find and Replace](http://ckeditor.com/addon/find) dialog window in the [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode throws an exception.
+* [#13879](http://dev.ckeditor.com/ticket/13879): Fixed: It is not possible to prevent the [`editor.drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop) event.
+* [#13361](http://dev.ckeditor.com/ticket/13361): Fixed: Skin images fail when the site path includes parentheses because the `background-image` path needs single quotes around the URL value.
+* [#13771](http://dev.ckeditor.com/ticket/13771): Fixed: The `contents.css` style is not used if the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin is missing.
+* [#13782](http://dev.ckeditor.com/ticket/13782): Fixed: Unclear log messages.
+* [#13919](http://dev.ckeditor.com/ticket/13919): [Edge] Fixed: Browser window crashes when accessing the `isContentEditable` property of an `<input>` DOM element.
+
+Other Changes:
+
+* [#13859](http://dev.ckeditor.com/ticket/13859): Test cases created with `bender.tools.createTestsForEditors` will also receive editor bot as a second parameter.
+
+## CKEditor 4.5.4
+
+New Features:
+
+* [#13632](http://dev.ckeditor.com/ticket/13632): Introduce error logging mechanism.
+* [#13730](http://dev.ckeditor.com/ticket/13730): Switch to the new error logging mechanism.
+
+Fixed Issues:
+
+* [#9856](http://dev.ckeditor.com/ticket/9856): Fixed: Cannot use the native context menu together with the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Mark Wade](https://github.com/mark-wade)!
+* [#12733](http://dev.ckeditor.com/ticket/12733): [IE9+] Fixed: Radio button `onChange` does not work. Thanks to [Iliya Kostadinov](https://github.com/iliyakostadinov)!
+* [#13142](http://dev.ckeditor.com/ticket/13142): [Edge] Fixed: *Ctrl+A* and then *Backspace* result in an empty `<div>` element.
+* [#13599](http://dev.ckeditor.com/ticket/13599): Fixed: Cross-editor drag and drop of an inline widget results in error/artifacts.
+* [#13640](http://dev.ckeditor.com/ticket/13640): [IE] Fixed: Dropping a widget outside the `<body>` element is not handled correctly.
+* [#13533](http://dev.ckeditor.com/ticket/13533): Fixed: No progress during upload.
+* [#13680](http://dev.ckeditor.com/ticket/13680): Fixed: The parser should allow the `<h1-6>` element to be a child of the `<summary>` element.
+* [#11724](http://dev.ckeditor.com/ticket/11724): [Touch devices] Fixed: Drop-downs often hide right after opening them.
+* [#13690](http://dev.ckeditor.com/ticket/13690): Fixed: Copying content from IE to Chrome adds an extra paragraph.
+* [#13284](http://dev.ckeditor.com/ticket/13284): Fixed: Cannot drag and drop a widget if the text caret is placed just after the widget instance.
+* [#13516](http://dev.ckeditor.com/ticket/13516): Fixed: CKEditor removes empty HTML5 anchors without the `name` attribute.
+* [#13765](http://dev.ckeditor.com/ticket/13765): [Safari 9] Fixed: Problems with rendering samples.
+
+Other Changes:
+
+* [#11725](http://dev.ckeditor.com/ticket/11725): Marked [`CKEDITOR.env.mobile`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-mobile) as deprecated. The reason is that it is no longer clear what "mobile" means.
+* [#13737](http://dev.ckeditor.com/ticket/13737): Upgraded [Bender.js](https://github.com/benderjs/benderjs) to 0.4.1.
+
+## CKEditor 4.5.3
+
+New Features:
+
+* [#13501](http://dev.ckeditor.com/ticket/13501): Added the [`config.fileTools_defaultFileName`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fileTools_defaultFileName) option to allow setting a default file name for paste uploads.
+* [#13603](http://dev.ckeditor.com/ticket/13603): Added support for uploading dropped BMP images.
+
+Fixed Issues:
+
+* [#13590](http://dev.ckeditor.com/ticket/13590): Fixed: Various issues related to the [Paste from Word](http://ckeditor.com/addon/pastefromword) feature. Fixes also:
+  * [#11215](http://dev.ckeditor.com/ticket/11215),
+  * [#8780](http://dev.ckeditor.com/ticket/8780),
+  * [#12762](http://dev.ckeditor.com/ticket/12762).
+* [#13386](http://dev.ckeditor.com/ticket/13386): [Edge] Fixed: Issues with selecting and editing images.
+* [#13568](http://dev.ckeditor.com/ticket/13568): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method returns invalid results for entire content selection.
+* [#13453](http://dev.ckeditor.com/ticket/13453): Fixed: Drag&drop of entire editor content throws an error.
+* [#13465](http://dev.ckeditor.com/ticket/13465): Fixed: Error is thrown and the widget is lost on drag&drop if it is the only content of the editor.
+* [#13414](http://dev.ckeditor.com/ticket/13414): Fixed: Content auto paragraphing in a nested editable despite editor configuration.
+* [#13429](http://dev.ckeditor.com/ticket/13429): Fixed: Incorrect selection after content insertion by the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.
+* [#13388](http://dev.ckeditor.com/ticket/13388): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) integration with [Undo](http://ckeditor.com/addon/undo) is broken.
+
+Other Changes:
+
+* [#13637](https://dev.ckeditor.com/ticket/13637): Several icons were refactored.
+* Updated [Bender.js](https://github.com/benderjs/benderjs) to 0.3.0 and introduced the ability to run tests via HTTPs ([#13265](https://dev.ckeditor.com/ticket/13265)).
+
+## CKEditor 4.5.2
+
+Fixed Issues:
+
+* [#13609](http://dev.ckeditor.com/ticket/13609): [Edge] Fixed: The browser crashes when switching to the source mode. Thanks to [Andrew Williams and Mark Smeed](http://webxsolution.com/)!
+* [PR#201](https://github.com/ckeditor/ckeditor-dev/pull/201): Fixed: Buttons in the toolbar configurator cause form submission. Thanks to [colemanw](https://github.com/colemanw)!
+* [#13422](http://dev.ckeditor.com/ticket/13422): Fixed: A monospaced font should be used in the `<textarea>` element storing editor configuration in the toolbar configurator.
+* [#13494](http://dev.ckeditor.com/ticket/13494): Fixed: Error thrown in the toolbar configurator if plugin requirements are not met.
+* [#13409](http://dev.ckeditor.com/ticket/13409): Fixed: List elements incorrectly merged when pressing *Backspace* or *Delete*.
+* [#13434](http://dev.ckeditor.com/ticket/13434): Fixed: Dialog state indicator broken in Right–To–Left environments.
+* [#13460](http://dev.ckeditor.com/ticket/13460): [IE8] Fixed: Copying inline widgets is broken when [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf) is disabled.
+* [#13495](http://dev.ckeditor.com/ticket/13495): [Firefox, IE] Fixed: Text is not word-wrapped in the Paste dialog window.
+* [#13528](http://dev.ckeditor.com/ticket/13528): [Firefox@Windows] Fixed: Content copied from Microsoft Word and other external applications is pasted as a plain text. Removed the `CKEDITOR.plugins.clipboard.isHtmlInExternalDataTransfer` property as the check must be dynamic.
+* [#13583](http://dev.ckeditor.com/ticket/13583): Fixed: [`DataTransfer.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer-method-getData) should work consistently in all browsers and should not strip valuable content. Fixed pasting tables from Microsoft Excel on Chrome.
+* [#13468](http://dev.ckeditor.com/ticket/13468): [IE] Fixed: Binding drag&drop `dataTransfer` does not work if `text` data was set in the meantime.
+* [#13451](http://dev.ckeditor.com/ticket/13451): [IE8-9] Fixed: One drag&drop operation may affect following ones.
+* [#13184](http://dev.ckeditor.com/ticket/13184): Fixed: Web page reloaded after a drop on editor UI.
+* [#13129](http://dev.ckeditor.com/ticket/13129) Fixed: Block widget blurred after a drop followed by an undo.
+* [#13397](http://dev.ckeditor.com/ticket/13397): Fixed: Drag&drop of a widget inside its nested widget crashes the editor.
+* [#13385](http://dev.ckeditor.com/ticket/13385): Fixed: [`editor.getSnapshot()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSnapshot) may return a non-string value.
+* [#13419](http://dev.ckeditor.com/ticket/13419): Fixed: The [Auto Link](http://ckeditor.com/addon/autolink) plugin does not encode double quotes in URLs.
+* [#13420](http://dev.ckeditor.com/ticket/13420): Fixed: The [Auto Embed](http://ckeditor.com/addon/autoembed) plugin ignores encoded characters in URL parameters.
+* [#13410](http://dev.ckeditor.com/ticket/13410): Fixed: Error thrown in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin when undoing right after pasting a link.
+* [#13566](http://dev.ckeditor.com/ticket/13566): Fixed: Suppressed notifications in the [Media Embed Base](http://ckeditor.com/addon/embedbase) plugin.
+* [#11616](http://dev.ckeditor.com/ticket/11616): [Chrome] Fixed: Resizing the editor while it is not displayed breaks the editable. Fixes also [#9160](http://dev.ckeditor.com/ticket/9160) and [#9715](http://dev.ckeditor.com/ticket/9715).
+* [#11376](http://dev.ckeditor.com/ticket/11376): [IE11] Fixed: Loss of text when pasting bulleted lists from Microsoft Word.
+* [#13143](http://dev.ckeditor.com/ticket/13143): [Edge] Fixed: Focus lost when opening the panel.
+* [#13387](http://dev.ckeditor.com/ticket/13387): [Edge] Fixed: "Permission denied" error thrown when loading the editor with developer tools open.
+* [#13574](http://dev.ckeditor.com/ticket/13574): [Edge] Fixed: "Permission denied" error thrown when opening editor dialog windows.
+* [#13441](http://dev.ckeditor.com/ticket/13441): [Edge] Fixed: The [Clipboard](http://ckeditor.com/addon/clipboard) plugin breaks the state of [Undo](http://ckeditor.com/addon/undo) commands after a paste.
+* [#13554](http://dev.ckeditor.com/ticket/13554): [Edge] Fixed: Paste dialog's iframe does not receive focus on show.
+* [#13440](http://dev.ckeditor.com/ticket/13440): [Edge] Fixed: Unable to paste a widget.
+
+Other Changes:
+
+* [#13421](http://dev.ckeditor.com/ticket/13421): UX improvements to notifications in the [Auto Embed](http://ckeditor.com/addon/autoembed) plugin.
+
+## CKEditor 4.5.1
+
+Fixed Issues:
+
+* [#13486](http://dev.ckeditor.com/ticket/13486): Fixed: The [Upload Image](http://ckeditor.com/addon/uploadimage) plugin should log an error, not throw an error when upload URL is not set.
+
+## CKEditor 4.5
+
+New Features:
+
+* [#13304](http://dev.ckeditor.com/ticket/13304): Added support for passing DOM elements to [`config.sharedSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-sharedSpaces). Thanks to [Undergrounder](https://github.com/Undergrounder)!
+* [#13215](http://dev.ckeditor.com/ticket/13215): Added ability to cancel fetching a resource by the Embed plugins.
+* [#13213](http://dev.ckeditor.com/ticket/13213): Added the [`dialog#setState()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-method-setState) method and used it in the [Embed](http://ckeditor.com/addon/embed) dialog to indicate that a resource is being loaded.
+* [#13337](http://dev.ckeditor.com/ticket/13337): Added the [`repository.onWidget()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-onWidget) method &mdash; a convenient way to listen to [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) events through the [repository](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository).
+* [#13214](http://dev.ckeditor.com/ticket/13214): Added support for pasting links that convert into embeddable resources on the fly.
+
+Fixed Issues:
+
+* [#13334](http://dev.ckeditor.com/ticket/13334): Fixed: Error after nesting widgets and playing with undo/redo.
+* [#13118](http://dev.ckeditor.com/ticket/13118): Fixed: The [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) method throws an error when called in the source mode.
+* [#13158](http://dev.ckeditor.com/ticket/13158): Fixed: Error after canceling a dialog when creating a widget.
+* [#13197](http://dev.ckeditor.com/ticket/13197): Fixed: Linked inline [Enhanced Image](http://ckeditor.com/addon/image2) alignment class is not transferred to the widget wrapper.
+* [#13199](http://dev.ckeditor.com/ticket/13199): Fixed: [Semantic Embed](http://ckeditor.com/addon/embedsemantic) does not support widget classes.
+* [#13003](http://dev.ckeditor.com/ticket/13003): Fixed: Anchors are uploaded when moving them by drag and drop.
+* [#13032](http://dev.ckeditor.com/ticket/13032): Fixed: When upload is done, notification update should be marked as important.
+* [#13300](http://dev.ckeditor.com/ticket/13300): Fixed: The `internalCommit` argument in the [Image](http://ckeditor.com/addon/image) dialog seems to be never used.
+* [#13036](http://dev.ckeditor.com/ticket/13036): Fixed: Notifications are moved 10px to the right.
+* [#13280](http://dev.ckeditor.com/ticket/13280): [IE8] Fixed: Undo after inline widget drag&drop throws an error.
+* [#13186](http://dev.ckeditor.com/ticket/13186): Fixed: Content dropped into a nested editable is not filtered by [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_acf).
+* [#13140](http://dev.ckeditor.com/ticket/13140): Fixed: Error thrown when dropping a block widget right after itself.
+* [#13176](http://dev.ckeditor.com/ticket/13176): [IE8] Fixed: Errors on drag&drop of embed widgets.
+* [#13015](http://dev.ckeditor.com/ticket/13015): Fixed: Dropping an image file on [Enhanced Image](http://ckeditor.com/addon/image2) causes a page reload.
+* [#13080](http://dev.ckeditor.com/ticket/13080): Fixed: Ugly notification shown when the response contains HTML content.
+* [#13011](http://dev.ckeditor.com/ticket/13011): [IE8] Fixed: Anchors are duplicated on drag&drop in specific locations.
+* [#13105](http://dev.ckeditor.com/ticket/13105): Fixed: Various issues related to [`CKEDITOR.tools.htmlEncode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlEncode) and [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode) methods.
+* [#11976](http://dev.ckeditor.com/ticket/11976): [Chrome] Fixed: Copy&paste and drag&drop lists from Microsoft Word.
+* [#13128](http://dev.ckeditor.com/ticket/13128): Fixed: Various issues with cloning element IDs:
+  * Fixed the default behavior of [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) and [`range.extractContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-extractContents) methods which now clone IDs similarly to their native counterparts.
+  * Added `cloneId` arguments to the above methods, [`range.splitBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-splitBlock) and [`element.breakParent()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-breakParent). Mind the default values and special behavior in the `extractContents()` method!
+  * Fixed issues where IDs were lost on copy&paste and drag&drop.
+* Toolbar configurators:
+  * [#13185](http://dev.ckeditor.com/ticket/13185): Fixed: Wrong position of the suggestion box if there is not enough space below the caret.
+  * [#13138](http://dev.ckeditor.com/ticket/13138): Fixed: The "Toggle empty elements" button label is unclear.
+  * [#13136](http://dev.ckeditor.com/ticket/13136): Fixed: Autocompleter is far too intrusive.
+  * [#13133](http://dev.ckeditor.com/ticket/13133): Fixed: Tab leaves the editor.
+  * [#13173](http://dev.ckeditor.com/ticket/13173): Fixed: [`config.removeButtons`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons) is ignored by the advanced toolbar configurator.
+
+Other Changes:
+
+* [#13119](http://dev.ckeditor.com/ticket/13119): Improved compatibility of editor skins ([Moono](http://ckeditor.com/addon/moono) and [Kama](http://ckeditor.com/addon/kama)) with external web page style sheets.
+* Toolbar configurators:
+  * [#13147](http://dev.ckeditor.com/ticket/13147): Added buttons to the sticky toolbar.
+  * [#13207](http://dev.ckeditor.com/ticket/13207): Used modal window to display toolbar configurator help.
+* [#13316](http://dev.ckeditor.com/ticket/13316): Made [`CKEDITOR.env.isCompatible`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-isCompatible) a blacklist rather than a whitelist. More about the change in the [Browser Compatibility](http://docs.ckeditor.com/#!/guide/dev_browsers) guide.
+* [#13398](http://dev.ckeditor.com/ticket/13398): Renamed `CKEDITOR.fileTools.UploadsRepository` to [`CKEDITOR.fileTools.UploadRepository`](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadRepository) and changed all related properties.
+* [#13279](http://dev.ckeditor.com/ticket/13279): Reviewed CSS vendor prefixes.
+* [#13454](http://dev.ckeditor.com/ticket/13454): Removed unused `lang.image.alertUrl` token from the [Image](http://ckeditor.com/addon/image) plugin.
+
+## CKEditor 4.5 Beta
+
+New Features:
+
+* Clipboard (copy&paste, drag&drop) and file uploading features and improvements ([#11437](http://dev.ckeditor.com/ticket/11437)).
+
+  * Major features:
+    * Support for dropping and pasting files into the editor was introduced. Through a set of new facades for native APIs it is now possible to easily intercept and process inserted files.
+    * [File upload tools](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools) were introduced in order to simplify controlling the loading, uploading and handling server response, properly handle [new upload configuration](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uploadUrl) options, etc.
+    * [Upload Image](http://ckeditor.com/addon/uploadimage) widget was introduced to upload dropped images. A base class for the [upload widget](http://docs.ckeditor.com/#!/api/CKEDITOR.fileTools.uploadWidgetDefinition) was exposed, too, to make it simple to create new types of upload widgets which can handle any type of dropped file, show the upload progress and update the content when the process is done. It also handles editing and undo/redo operations when a file is being uploaded and integrates with the [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) to show progress and success or error.
+    * All drag and drop operations were integrated with the editor. All dropped content is passed through the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event and a set of new editor events was introduced &mdash; [`dragstart`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragstart), [`drop`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-drop), [`dragend`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-dragend).
+    * The [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) facade was introduced to unify access to data in various types and files. [Data Transfer](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.clipboard.dataTransfer) is now always available in the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.
+    * Switched from the pastebin to using the native clipboard access whenever possible. This solved many issues related to pastebin such as unnecessary scrolling or data loss. Additionally, on copy and cut from the editor the clipboard data is set. Therefore, on paste the editor has access to clean data, undisturbed by the browsers.
+    * Drag and drop of inline and block widgets was integrated with the standard clipboard APIs. By listening to drag events you will thus be notified about widgets, too. This opens a possibility to filter pasted and dropped widgets.
+    * The [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event can have the `range` parameter so it is possible to change the paste position in the listener or paste in the not selectable position. Also the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method now accepts `range` as an additional parameter.
+    * [#11621](http://dev.ckeditor.com/ticket/11621): A configurable [paste filter](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFilter) was introduced. The filter is by default turned to `'semantic-content'` on Webkit and Blink for all pasted content coming from external sources because of the low quality of HTML that these engines put into the clipboard. Internal and cross-editor paste is safe due to the change explained in the previous point.
+
+  * Other changes and related fixes:
+    * [#12095](http://dev.ckeditor.com/ticket/12095): On drag and copy of widgets [the same method](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) is used to get selected HTML as in the normal case. Thanks to that styles applied to inline widgets are not lost.
+    * [#11219](http://dev.ckeditor.com/ticket/11219): Fixed: Dragging a [captioned image](http://ckeditor.com/addon/image2) does not fire the [`editor#paste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-paste) event.
+    * [#9554](http://dev.ckeditor.com/ticket/9554): [Webkit Mac] Fixed: Editor scrolls on paste.
+    * [#9898](http://dev.ckeditor.com/ticket/9898): [Webkit&Divarea] Fixed: Pasting causes undesirable scrolling.
+    * [#11993](http://dev.ckeditor.com/ticket/11993): [Chrome] Fixed: Pasting content scrolls the document.
+    * [#12613](http://dev.ckeditor.com/ticket/12613): Show the user that they can not drop on editor UI (toolbar, bottom bar).
+    * [#12851](http://dev.ckeditor.com/ticket/12851): [Blink/Webkit] Fixed: Formatting disappears when pasting content into cells.
+    * [#12914](http://dev.ckeditor.com/ticket/12914): Fixed: Copy/Paste of table broken in `div`-based editor.
+
+  * Browser support.<br>Browser support for related features varies significantly (see http://caniuse.com/clipboard).
+    * File APIs needed to operate and file upload is not supported in Internet Explorer 9 and below.
+    * Only Chrome and Safari on Mac OS support setting custom data items in the clipboard, so currently it is possible to recognize the origin of the copied content in these browsers only. All drag and drop operations can be identified thanks to the new Data Transfer facade.
+    * No Internet Explorer browser supports the standard clipboard API which results in small glitches like where only plain text can be dropped from outside the editor. Thanks to the new Data Transfer facade, internal and cross-editor drag and drop supports the full range of data.
+    * Direct access to clipboard could only be implemented in Chrome, Safari on Mac OS, Opera and Firefox. In other browsers the pastebin must still be used.
+
+* [#12875](http://dev.ckeditor.com/ticket/12875): Samples and toolbar configuration tools.
+  * The old set of samples shipped with every CKEditor package was replaced with a shiny new single-page sample. This change concluded a long term plan which started from introducing the [CKEditor SDK](http://sdk.ckeditor.com/) and [CKEditor Functionality Overview](http://docs.ckeditor.com/#!/guide/dev_features) section in the documentation which essentially redefined the old samples.
+  * Toolbar configurators with live previews were introduced. They will be shipped with every CKEditor package and are meant to help in configuring toolbar layouts.
+
+* [#10925](http://dev.ckeditor.com/ticket/10925): The [Media Embed](http://ckeditor.com/addon/embed) and [Semantic Media Embed](http://ckeditor.com/addon/embedsemantic) plugins were introduced. Read more about the new features in the [Embedding Content](http://docs.ckeditor.com/#!/guide/dev_media_embed) article.
+* [#10931](http://dev.ckeditor.com/ticket/10931): Added support for nesting widgets. It is now possible to insert one widget into another widget's nested editable. Note that unless nested editable's [allowed content](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.nestedEditable.definition-property-allowedContent) is defined precisely, starting from CKEditor 4.5 some widget buttons may become enabled. This feature is not supported in IE8. Included issues:
+  * [#12018](http://dev.ckeditor.com/ticket/12018): Fixed and reviewed: Nested widgets garbage collection.
+  * [#12024](http://dev.ckeditor.com/ticket/12024): [Firefox] Fixed: Outline is extended to the left by unpositioned drag handlers.
+  * [#12006](http://dev.ckeditor.com/ticket/12006): Fixed: Drag and drop of nested block widgets.
+  * [#12008](http://dev.ckeditor.com/ticket/12008): Fixed various cases of inserting a single non-editable element using the [`editor.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml) method. Fixes pasting a widget with a nested editable inside another widget's nested editable.
+
+* Notification system:
+  * [#11580](http://dev.ckeditor.com/ticket/11580): Introduced the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification).
+  * [#12810](http://dev.ckeditor.com/ticket/12810): Introduced a [notification aggregator](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notificationAggregator) for the [notification system](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.notification) which simplifies displaying progress of many concurrent tasks.
+* [#11636](http://dev.ckeditor.com/ticket/11636): Introduced new, UX-focused, methods for getting selected HTML and deleting it &mdash; [`editor.getSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml) and [`editor.deleteSelectedHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getSelectedHtml).
+* [#12416](http://dev.ckeditor.com/ticket/12416): Added the [`widget.definition.upcastPriority`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-upcastPriority) property which gives more control over widget upcasting order to the widget author.
+* [#12036](http://dev.ckeditor.com/ticket/12036): Initialize the editor in [read-only](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) mode when the `<textarea>` element has a `readonly` attribute.
+* [#11905](http://dev.ckeditor.com/ticket/11905): The [`resize` event](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-resize) passes the current dimensions in its data.
+* [#12126](http://dev.ckeditor.com/ticket/12126): Introduced [`config.image_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image_prefillDimensions) and [`config.image2_prefillDimensions`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_prefillDimensions) to make pre-filling `width` and `height` configurable for the [Enhanced Image](http://ckeditor.com/addon/image2).
+* [#12746](http://dev.ckeditor.com/ticket/12746): Added a new configuration option to hide the [Enhanced Image](http://ckeditor.com/addon/image2) resizer.
+* [#12150](http://dev.ckeditor.com/ticket/12150): Exposed the [`getNestedEditable()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-static-method-getNestedEditable) and `is*` [widget helper](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) functions (see the static methods).
+* [#12448](http://dev.ckeditor.com/ticket/12448): Introduced the [`editable.insertHtmlIntoRange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertHtmlIntoRange) method.
+* [#12143](http://dev.ckeditor.com/ticket/12143): Added the [`config.floatSpacePreferRight`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-floatSpacePreferRight) configuration option that switches the alignment of the floating toolbar. Thanks to [InvisibleBacon](http://github.com/InvisibleBacon)!
+* [#10986](http://dev.ckeditor.com/ticket/10986): Added support for changing dialog input and textarea text directions by using the *Shift+Alt+Home/End* keystrokes. The direction is stored in the value of the input by prepending the [`\u202A`](http://unicode.org/cldr/utility/character.jsp?a=202A) or [`\u202B`](http://unicode.org/cldr/utility/character.jsp?a=202B) marker to it. Read more in the [documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog.definition.textInput-property-bidi). Thanks to [edithkk](https://github.com/edithkk)!
+* [#12770](http://dev.ckeditor.com/ticket/12770): Added support for passing [widget](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget)'s startup data as a widget command's argument. Thanks to [Rebrov Boris](https://github.com/zipp3r) and [Tieme van Veen](https://github.com/tiemevanveen)!
+* [#11583](http://dev.ckeditor.com/ticket/11583): Added support for the HTML5 `required` attribute in various form elements. Thanks to [Steven Busse](https://github.com/sbusse)!
+
+Changes:
+
+* [#12858](http://dev.ckeditor.com/ticket/12858): Basic [Spartan](http://blogs.windows.com/bloggingwindows/2015/03/30/introducing-project-spartan-the-new-browser-built-for-windows-10/) browser compatibility. Full compatibility will be introduced later, because at the moment Spartan is still too unstable to be used for tests and we see many changes from version to version.
+* [#12948](http://dev.ckeditor.com/ticket/12948): The [`config.mathJaxLibrary`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-mathJaxLib) option does not default to the MathJax CDN any more. It needs to be configured to enable the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin now.
+* [#13069](http://dev.ckeditor.com/ticket/13069): Fixed inconsistencies between [`editable.insertHtml()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) and [`editable.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElement) when the `range` parameter is used. Now, the `editor.insertElement()` method works on a higher level, which means that it saves undo snapshots and sets the selection after insertion. Use the [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange) method directly for the pre 4.5 behavior of `editable.insertElement()`.
+* [#12870](http://dev.ckeditor.com/ticket/12870): Use [`editor.showNotification()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-showNotification) instead of `alert()` directly whenever possible. When the [Notification plugin](http://ckeditor.com/addon/notification) is loaded, the notification system is used automatically. Otherwise, the native `alert()` is displayed.
+* [#8024](http://dev.ckeditor.com/ticket/8024): Swapped behavior of the Split Cell Vertically and Horizontally features of the [Table Tools](http://ckeditor.com/addon/tabletools) plugin to be more intuitive. Thanks to [kevinisagit](https://github.com/kevinisagit)!
+* [#10903](http://dev.ckeditor.com/ticket/10903): Performance improvements for the [`dom.element.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass), [`dom.element.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass) and [`dom.element.hasClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-hasClass) methods. Note: The previous implementation allowed passing multiple classes to `addClass()` although it was only a side effect of that implementation. The new implementation does not allow this.
+* [#11856](http://dev.ckeditor.com/ticket/11856): The jQuery adapter throws a meaningful error if CKEditor or jQuery are not loaded.
+
+Fixed issues:
+
+* [#11586](http://dev.ckeditor.com/ticket/11586): Fixed: [`range.cloneContents()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-cloneContents) should not change the DOM in order not to affect selection.
+* [#12148](http://dev.ckeditor.com/ticket/12148): Fixed: [`dom.element.getChild()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-getChild) should not modify a passed array.
+* [#12503](http://dev.ckeditor.com/ticket/12503): [Blink/Webkit] Fixed: Incorrect result of Select All and *Backspace* or *Delete*.
+* [#13001](http://dev.ckeditor.com/ticket/13001): [Firefox] Fixed: The `<br />` filler is placed in the wrong position by the [`range.fixBlock()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-fixBlock) method due to quirky Firefox behavior.
+* [#13101](http://dev.ckeditor.com/ticket/13101): [IE8] Fixed: Colons are prepended to HTML5 element names when cloning them.
+
+## CKEditor 4.4.8
+
+**Security Updates:**
+
+* Fixed XSS vulnerability in the HTML parser reported by [Dheeraj Joshi](https://twitter.com/dheerajhere) and [Prem Kumar](https://twitter.com/iAmPr3m).
+
+       Issue summary: It was possible to execute XSS inside CKEditor after persuading the victim to: (i) switch CKEditor to source mode, then (ii) paste a specially crafted HTML code, prepared by the attacker, into the opened CKEditor source area, and (iii) switch back to WYSIWYG mode.
+
+**An upgrade is highly recommended!**
+
+Fixed Issues:
+
+* [#12899](http://dev.ckeditor.com/ticket/12899): Fixed: Corrected wrong tag ending for horizontal box definition in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin. Thanks to [mizafish](https://github.com/mizafish)!
+* [#13254](http://dev.ckeditor.com/ticket/13254): Fixed: Cannot outdent block after indent when using the [Div Editing Area](http://ckeditor.com/addon/divarea) plugin. Thanks to [Jonathan Cottrill](https://github.com/jcttrll)!
+* [#13268](http://dev.ckeditor.com/ticket/13268): Fixed: Documentation for [`CKEDITOR.dom.text`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.text) is incorrect. Thanks to [Ben Kiefer](https://github.com/benkiefer)!
+* [#12739](http://dev.ckeditor.com/ticket/12739): Fixed: Link loses inline styles when edited without the [Advanced Tab for Dialogs](http://ckeditor.com/addon/dialogadvtab) plugin. Thanks to [Віталій Крутько](https://github.com/asmforce)!
+* [#13292](http://dev.ckeditor.com/ticket/13292): Fixed: Protection pattern does not work in attribute in self-closing elements with no space before `/>`. Thanks to [Віталій Крутько](https://github.com/asmforce)!
+* [PR#192](https://github.com/ckeditor/ckeditor-dev/pull/192): Fixed: Variable name typo in the [Dialog User Interface](http://ckeditor.com/addon/dialogui) plugin which caused [`CKEDITOR.ui.dialog.radio`](http://docs.ckeditor.com/#!/api/CKEDITOR.ui.dialog.radio) validation to not work. Thanks to [Florian Ludwig](https://github.com/FlorianLudwig)!
+* [#13232](http://dev.ckeditor.com/ticket/13232): [Safari] Fixed: The [`element.appendText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-appendText) method does not work properly for empty elements.
+* [#13233](http://dev.ckeditor.com/ticket/13233): Fixed: [HTMLDataProcessor](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) can process `foo:href` attributes.
+* [#12796](http://dev.ckeditor.com/ticket/12796): Fixed: The [Indent List](http://ckeditor.com/addon/indentlist) plugin unwraps parent `<li>` elements. Thanks to [Andrew Stucki](https://github.com/andrewstucki)!
+* [#12885](http://dev.ckeditor.com/ticket/12885): Added missing [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) parameter documentation.
+* [#11982](http://dev.ckeditor.com/ticket/11982): Fixed: Bullet added in a wrong position after the *Enter* key is pressed in a nested list.
+* [#13027](http://dev.ckeditor.com/ticket/13027): Fixed: Keyboard navigation in dialog windows with multiple tabs not following IBM CI 162 instructions or [ARIA Authoring Practices](http://www.w3.org/TR/2013/WD-wai-aria-practices-20130307/#tabpanel).
+* [#12256](http://dev.ckeditor.com/ticket/12256): Fixed: Basic styles classes are lost when pasting from Microsoft Word if [basic styles](http://ckeditor.com/addon/basicstyles) were configured to use classes.
+* [#12729](http://dev.ckeditor.com/ticket/12729): Fixed: Incorrect structure created when merging a block into a list item on *Backspace* and *Delete*.
+* [#13031](http://dev.ckeditor.com/ticket/13031): [Firefox] Fixed: No more line breaks in source view since Firefox 36.
+* [#13131](http://dev.ckeditor.com/ticket/13131): Fixed: The [Code Snippet](http://ckeditor.com/addon/codesnippet) plugin cannot be used without the [IFrame Editing Area](http://ckeditor.com/addon/wysiwygarea) plugin.
+* [#9086](http://dev.ckeditor.com/ticket/9086): Fixed: Invalid ARIA property used on paste area `<iframe>`.
+* [#13164](http://dev.ckeditor.com/ticket/13164): Fixed: Error when inserting a hidden field.
+* [#13155](http://dev.ckeditor.com/ticket/13155): Fixed: Incorrect [Line Utilities](http://ckeditor.com/addon/lineutils) positioning when `<body>` has a margin.
+* [#13351](http://dev.ckeditor.com/ticket/13351): Fixed: Link lost when editing a linked image with the Link tab disabled. This also fixed a bug when inserting an image into a fully selected link would throw an error ([#12847](https://dev.ckeditor.com/ticket/12847)).
+* [#13344](http://dev.ckeditor.com/ticket/13344): [WebKit/Blink] Fixed: It is possible to remove or change editor content in [read-only mode](http://docs.ckeditor.com/#!/guide/dev_readonly).
+
+Other Changes:
+
+* [#12844](http://dev.ckeditor.com/ticket/12844) and [#13103](http://dev.ckeditor.com/ticket/13103): Upgraded the [testing environment](http://docs.ckeditor.com/#!/guide/dev_tests) to [Bender.js](https://github.com/benderjs/benderjs) `0.2.3`.
+* [#12930](http://dev.ckeditor.com/ticket/12930): Because of licensing issues, `truncated-mathjax/` is now removed from the `tests/` directory. Now `bender.config.mathJaxLibPath` must be configured manually in order to run [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin tests.
+* [#13266](http://dev.ckeditor.com/ticket/13266): Added more shades of gray in the [Color Dialog](http://ckeditor.com/addon/colordialog) window. Thanks to [mizafish](https://github.com/mizafish)!
+
+
+## CKEditor 4.4.7
+
+Fixed Issues:
+
+* [#12825](http://dev.ckeditor.com/ticket/12825): Fixed: Preventing the [Table Resize](http://ckeditor.com/addon/tableresize) plugin from operating on elements outside the editor. Thanks to [Paul Martin](https://github.com/Paul-Martin)!
+* [#12157](http://dev.ckeditor.com/ticket/12157): Fixed: Lost text formatting on pressing *Tab* when the [`config.tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces) configuration option value was greater than zero.
+* [#12777](http://dev.ckeditor.com/ticket/12777): Fixed: The `table-layout` CSS property should be reset by skins. Thanks to [vita10gy](https://github.com/vita10gy)!
+* [#12812](http://dev.ckeditor.com/ticket/12812): Fixed: An uncaught security exception is thrown when [Line Utilities](http://ckeditor.com/addon/lineutils) are used in an inline editor loaded in a cross-domain `iframe`. Thanks to [Vitaliy Zurian](https://github.com/thecatontheflat)!
+* [#12735](http://dev.ckeditor.com/ticket/12735): Fixed: [`config.fillEmptyBlocks`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fillEmptyBlocks) should only apply when outputting data.
+* [#10032](http://dev.ckeditor.com/ticket/10032): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filter is executed for every paste after using the button.
+* [#12597](http://dev.ckeditor.com/ticket/12597): [Blink/WebKit] Fixed: Multi-byte Japanese characters entry not working properly after *Shift+Enter*.
+* [#12387](http://dev.ckeditor.com/ticket/12387): Fixed: An error is thrown if a skin does not have the [`chameleon`](http://docs.ckeditor.com/#!/api/CKEDITOR.skin-method-chameleon) property defined and [`config.uiColor`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-uiColor) is defined.
+* [#12747](http://dev.ckeditor.com/ticket/12747): [IE8-10] Fixed: Opening a drop-down for a specific selection when the editor is maximized results in incorrect drop-down panel position.
+* [#12850](http://dev.ckeditor.com/ticket/12850): [IEQM] Fixed: An error is thrown after focusing the editor.
+
+## CKEditor 4.4.6
+
+**Security Updates:**
+
+* Fixed XSS vulnerability in the HTML parser reported by [Maco Cortes](https://www.facebook.com/Maaacoooo).
+
+       Issue summary: It was possible to execute XSS inside CKEditor after persuading the victim to: (i) switch CKEditor to source mode, then (ii) paste a specially crafted HTML code, prepared by the attacker, into the opened CKEditor source area, and (iii) switch back to WYSIWYG mode.
+
+**An upgrade is highly recommended!**
+
+New Features:
+
+* [#12501](http://dev.ckeditor.com/ticket/12501): Allowed dashes in element names in the [string format of allowed content rules](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules-section-string-format).
+* [#12550](http://dev.ckeditor.com/ticket/12550): Added the `<main>` element to the [`CKEDITOR.dtd`](http://docs.ckeditor.com/#!/api/CKEDITOR.dtd).
+
+Fixed Issues:
+
+* [#12506](http://dev.ckeditor.com/ticket/12506): [Safari] Fixed: Cannot paste into inline editor if the page has `user-select: none` style. Thanks to [shaohua](https://github.com/shaohua)!
+* [#12683](http://dev.ckeditor.com/ticket/12683): Fixed: [Filter](http://docs.ckeditor.com/#!/guide/dev_acf) fails to remove custom tags. Thanks to [timselier](https://github.com/timselier)!
+* [#12489](http://dev.ckeditor.com/ticket/12489) and [#12491](http://dev.ckeditor.com/ticket/12491): Fixed: Various issues related to restoring the selection after performing operations on filler character. See the [fixed cases](http://dev.ckeditor.com/ticket/12491#comment:4).
+* [#12621](http://dev.ckeditor.com/ticket/12621): Fixed: Cannot remove inline styles (bold, italic, etc.) in empty lines.
+* [#12630](http://dev.ckeditor.com/ticket/12630): [Chrome] Fixed: Selection is placed outside the paragraph when the [New Page](http://ckeditor.com/addon/newpage) button is clicked. This patch significantly simplified the way how the initial selection (a selection after the content of the editable is overwritten) is being fixed. That might have fixed many related scenarios in all browsers.
+* [#11647](http://dev.ckeditor.com/ticket/11647): Fixed: The [`editor.blur`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-blur) event is not fired on first blur after initializing the inline editor on an already focused element.
+* [#12601](http://dev.ckeditor.com/ticket/12601): Fixed: [Strikethrough](http://ckeditor.com/addon/basicstyles) button tooltip spelling.
+* [#12546](http://dev.ckeditor.com/ticket/12546): Fixed: The Preview tab in the [Document Properties](http://ckeditor.com/addon/docprops) dialog window is always disabled.
+* [#12300](http://dev.ckeditor.com/ticket/12300): Fixed: The [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event fired on first navigation key press after typing.
+* [#12141](http://dev.ckeditor.com/ticket/12141): Fixed: List items are lost when indenting a list item with content wrapped with a block element.
+* [#12515](http://dev.ckeditor.com/ticket/12515): Fixed: Cursor is in the wrong position when undoing after adding an image and typing some text.
+* [#12484](http://dev.ckeditor.com/ticket/12484): [Blink/WebKit] Fixed: DOM is changed outside the editor area in a certain case.
+* [#12688](http://dev.ckeditor.com/ticket/12688): Improved the tests of the [styles system](http://docs.ckeditor.com/#!/api/CKEDITOR.style) and fixed two minor issues.
+* [#12403](http://dev.ckeditor.com/ticket/12403): Fixed: Changing the [font](http://ckeditor.com/addon/font) style should not lead to nesting it in the previous style element.
+* [#12609](http://dev.ckeditor.com/ticket/12609): Fixed: Incorrect `config.magicline_putEverywhere` name used for a [Magic Line](http://ckeditor.com/addon/magicline) all-encompassing [`config.magicline_everywhere`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-magicline_everywhere) configuration option.
+
+
+## CKEditor 4.4.5
+
+New Features:
+
+* [#12279](http://dev.ckeditor.com/ticket/12279): Added a possibility to pass a custom evaluator to [`node.getAscendant()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.node-method-getAscendant).
+
+Fixed Issues:
+
+* [#12423](http://dev.ckeditor.com/ticket/12423): [Safari7.1+] Fixed: *Enter* key moved cursor to a strange position.
+* [#12381](http://dev.ckeditor.com/ticket/12381): [iOS] Fixed: Selection issue. Thanks to [Remiremi](https://github.com/Remiremi)!
+* [#10804](http://dev.ckeditor.com/ticket/10804): Fixed: `CKEDITOR_GETURL` is not used with some plugins where it should be used. Thanks to [Thomas Andraschko](https://github.com/tandraschko)!
+* [#9137](http://dev.ckeditor.com/ticket/9137): Fixed: The `<base>` tag is not created when `<head>` has an attribute. Thanks to [naoki.fujikawa](https://github.com/naoki-fujikawa)!
+* [#12377](http://dev.ckeditor.com/ticket/12377): Fixed: Errors thrown in the [Image](http://ckeditor.com/addon/image) plugin when removing preview from the dialog window definition. Thanks to [Axinet](https://github.com/Axinet)!
+* [#12162](http://dev.ckeditor.com/ticket/12162): Fixed: Auto paragraphing and *Enter* key in nested editables.
+* [#12315](http://dev.ckeditor.com/ticket/12315): Fixed: Marked [`config.autoParagraph`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-autoParagraph) as deprecated.
+* [#12113](http://dev.ckeditor.com/ticket/12113): Fixed: A [code snippet](http://ckeditor.com/addon/codesnippet) should be presented in the [elements path](http://ckeditor.com/addon/elementspath) as "code snippet" (translatable).
+* [#12311](http://dev.ckeditor.com/ticket/12311): Fixed: [Remove Format](http://ckeditor.com/addon/removeformat) should also remove `<cite>` elements.
+* [#12261](http://dev.ckeditor.com/ticket/12261): Fixed: Filter has to be destroyed and removed from [`CKEDITOR.filter.instances`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-static-property-instances) on editor destroy.
+* [#12398](http://dev.ckeditor.com/ticket/12398): Fixed: [Maximize](http://ckeditor.com/addon/maximize) does not work on an instance without a [title](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title).
+* [#12097](http://dev.ckeditor.com/ticket/12097): Fixed: JAWS not reading the number of options correctly in the [Text Color and Background Color](http://ckeditor.com/addon/colorbutton) button menu.
+* [#12411](http://dev.ckeditor.com/ticket/12411): Fixed: [Page Break](http://ckeditor.com/addon/pagebreak) used directly in the editable breaks the editor.
+* [#12354](http://dev.ckeditor.com/ticket/12354): Fixed: Various issues in undo manager when holding keys.
+* [#12324](http://dev.ckeditor.com/ticket/12324): [IE8] Fixed: Undo steps are not recorded when changing the caret position by clicking below the body.
+* [#12332](http://dev.ckeditor.com/ticket/12332): Fixed: Lowered DOM events listeners' priorities in undo manager in order to avoid ambiguity.
+* [#12402](http://dev.ckeditor.com/ticket/12402): [Blink] Fixed: Workaround for Blink bug with `document.title` which breaks updating title in the full HTML mode.
+* [#12338](http://dev.ckeditor.com/ticket/12338): Fixed: The CKEditor package contains unoptimized images.
+
+
+## CKEditor 4.4.4
+
+Fixed Issues:
+
+* [#12268](http://dev.ckeditor.com/ticket/12268): Cleanup of [UI Color](http://ckeditor.com/addon/uicolor) YUI styles. Thanks to [CasherWest](https://github.com/CasherWest)!
+* [#12263](http://dev.ckeditor.com/ticket/12263): Fixed: [Paste from Word](http://ckeditor.com/addon/pastefromword) filter does not properly normalize semicolons style text. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!
+* [#12243](http://dev.ckeditor.com/ticket/12243): Fixed: Text formatting lost when pasting from Word. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!
+* [#111739](http://dev.ckeditor.com/ticket/11739): Fixed: `keypress` listeners should not be used in the undo manager. A complete rewrite of keyboard handling in the undo manager was made. Numerous smaller issues were fixed, among others:
+  * [#10926](http://dev.ckeditor.com/ticket/10926): [Chrome@Android] Fixed: Typing does not record snapshots and does not fire the [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.
+  * [#11611](http://dev.ckeditor.com/ticket/11611): [Firefox] Fixed: The [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event is fired when pressing Arrow keys.
+  * [#12219](http://dev.ckeditor.com/ticket/12219): [Safari] Fixed: Some modifications of the [`UndoManager.locked`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-property-locked) property violate strict mode in the [Undo](http://ckeditor.com/addon/undo) plugin.
+* [#10916](http://dev.ckeditor.com/ticket/10916): Fixed: [Magic Line](http://ckeditor.com/addon/magicline) icon in Right-To-Left environments.
+* [#11970](http://dev.ckeditor.com/ticket/11970): [IE] Fixed: CKEditor `paste` event is not fired when pasting with *Shift+Ins*.
+* [#12111](http://dev.ckeditor.com/ticket/12111): Fixed: Linked image attributes are not read when opening the image dialog window by doubleclicking.
+* [#10030](http://dev.ckeditor.com/ticket/10030): [IE] Fixed: Prevented "Unspecified Error" thrown in various cases when IE8-9 does not allow access to `document.activeElement`.
+* [#12273](http://dev.ckeditor.com/ticket/12273): Fixed: Applying block style in a description list breaks it.
+* [#12218](http://dev.ckeditor.com/ticket/12218): Fixed: Minor syntax issue in CSS files.
+* [#12178](http://dev.ckeditor.com/ticket/12178): [Blink/WebKit] Fixed: Iterator does not return the block if the selection is located at the end of it.
+* [#12185](http://dev.ckeditor.com/ticket/12185): [IE9QM] Fixed: Error thrown when moving the mouse over focused editor's scrollbar.
+* [#12215](http://dev.ckeditor.com/ticket/12215): Fixed: Basepath resolution does not recognize semicolon as a query separator.
+* [#12135](http://dev.ckeditor.com/ticket/12135): Fixed: [Remove Format](http://ckeditor.com/addon/removeformat) does not work on widgets.
+* [#12298](http://dev.ckeditor.com/ticket/12298): [IE11] Fixed: Clicking below `<body>` in Compatibility Mode will no longer reset selection to the first line.
+* [#12204](http://dev.ckeditor.com/ticket/12204): Fixed: Editor's voice label is not affected by [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title).
+* [#11915](http://dev.ckeditor.com/ticket/11915): Fixed: With [SCAYT](http://ckeditor.com/addon/scayt) enabled, cursor moves to the beginning of the first highlighted, misspelled word after typing or pasting into the editor.
+* [SCAYT](https://github.com/WebSpellChecker/ckeditor-plugin-scayt/issues/69): Fixed: Error thrown in the console after enabling [SCAYT](http://ckeditor.com/addon/scayt) and trying to add a new image.
+
+
+Other Changes:
+
+* [#12296](http://dev.ckeditor.com/ticket/12296): Merged `benderjs-ckeditor` into the main CKEditor repository.
+
+## CKEditor 4.4.3
+
+**Security Updates:**
+
+* Fixed XSS vulnerability in the Preview plugin reported by Mario Heiderich of [Cure53](https://cure53.de/).
+
+**An upgrade is highly recommended!**
+
+New Features:
+
+* [#12164](http://dev.ckeditor.com/ticket/12164): Added the "Justify" option to the "Horizontal Alignment" drop-down in the Table Cell Properties dialog window.
+
+Fixed Issues:
+
+* [#12110](http://dev.ckeditor.com/ticket/12110): Fixed: Editor crash after deleting a table. Thanks to [Alin Purcaru](https://github.com/mesmerizero)!
+* [#11897](http://dev.ckeditor.com/ticket/11897): Fixed: *Enter* key used in an empty list item creates a new line instead of breaking the list. Thanks to [noam-si](https://github.com/noam-si)!
+* [#12140](http://dev.ckeditor.com/ticket/12140): Fixed: Double-clicking linked widgets opens two dialog windows.
+* [#12132](http://dev.ckeditor.com/ticket/12132): Fixed: Image is inserted with `width` and `height` styles even when they are not allowed.
+* [#9317](http://dev.ckeditor.com/ticket/9317): [IE] Fixed: [`config.disableObjectResizing`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-disableObjectResizing) does not work on IE. **Note**: We were not able to fix this issue on IE11+ because necessary events stopped working. See a [last resort workaround](http://dev.ckeditor.com/ticket/9317#comment:16) and make sure to [support our complaint to Microsoft](https://connect.microsoft.com/IE/feedback/details/742593/please-respect-execcommand-enableobjectresizing-in-contenteditable-elements).
+* [#9638](http://dev.ckeditor.com/ticket/9638): Fixed: There should be no information about accessibility help available under the *Alt+0* keyboard shortcut if the [Accessibility Help](http://ckeditor.com/addon/a11yhelp) plugin is not available.
+* [#8117](http://dev.ckeditor.com/ticket/8117) and [#9186](http://dev.ckeditor.com/ticket/9186): Fixed: In HTML5 `<meta>` tags should be allowed everywhere, including inside the `<body>` element.
+* [#10422](http://dev.ckeditor.com/ticket/10422): Fixed: [`config.fillEmptyBlocks`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fillEmptyBlocks) not working properly if a function is specified.
+
+## CKEditor 4.4.2
+
+Important Notes:
+
+* The CKEditor testing environment is now publicly available. Read more about how to set up the environment and execute tests in the [CKEditor Testing Environment](http://docs.ckeditor.com/#!/guide/dev_tests) guide.
+       Please note that the [`tests/`](https://github.com/ckeditor/ckeditor-dev/tree/master/tests) directory which contains editor tests is not available in release packages. It can only be found in the development version of CKEditor on [GitHub](https://github.com/ckeditor/ckeditor-dev/).
+
+New Features:
+
+* [#11909](http://dev.ckeditor.com/ticket/11909): Introduced a parameter to prevent the [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData) method from recording undo snapshots.
+
+Fixed Issues:
+
+* [#11757](http://dev.ckeditor.com/ticket/11757): Fixed: Imperfections in the [Moono](http://ckeditor.com/addon/moono) skin. Thanks to [danyaPostfactum](https://github.com/danyaPostfactum)!
+* [#10091](http://dev.ckeditor.com/ticket/10091): Blockquote should be treated like an object by the styles system. Thanks to [dan-james-deeson](https://github.com/dan-james-deeson)!
+* [#11478](http://dev.ckeditor.com/ticket/11478): Fixed: Issue with passing jQuery objects to [adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) configuration.
+* [#10867](http://dev.ckeditor.com/ticket/10867): Fixed: Issue with setting encoded URI as image link.
+* [#11983](http://dev.ckeditor.com/ticket/11983): Fixed: Clicking a nested widget does not focus it. Additionally, performance of the [`widget.repository.getByElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-getByElement) method was improved.
+* [#12000](http://dev.ckeditor.com/ticket/12000): Fixed: Nested widgets should be initialized on [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData) and [`nestedEditable.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.nestedEditable-method-setData).
+* [#12022](http://dev.ckeditor.com/ticket/12022): Fixed: Outer widget's drag handler is not created at all if it has any nested widgets inside.
+* [#11960](http://dev.ckeditor.com/ticket/11960): [Blink/WebKit] Fixed: The caret should be scrolled into view on *Backspace* and *Delete* (covers only the merging blocks case).
+* [#11306](http://dev.ckeditor.com/ticket/11306): [OSX][Blink/WebKit] Fixed: No widget entries in the context menu on widget right-click.
+* [#11957](http://dev.ckeditor.com/ticket/11957): Fixed: Alignment labels in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window are not translated.
+* [#11980](http://dev.ckeditor.com/ticket/11980): [Blink/WebKit] Fixed: `<span>` elements created when joining adjacent elements (non-collapsed selection).
+* [#12009](http://dev.ckeditor.com/ticket/12009): [Nested widgets] Integration with the [Magic Line](http://ckeditor.com/addon/magicline) plugin.
+* [#11387](http://dev.ckeditor.com/ticket/11387): Fixed: `role="radiogroup"` should be applied only to radio inputs' container.
+* [#7975](http://dev.ckeditor.com/ticket/7975): [IE8] Fixed: Errors when trying to select an empty table cell.
+* [#11947](http://dev.ckeditor.com/ticket/11947): [Firefox+IE11] Fixed: *Shift+Enter* in lists produces two line breaks.
+* [#11972](http://dev.ckeditor.com/ticket/11972): Fixed: Feature detection in the [`element.setText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-setText) method should not trigger the layout engine.
+* [#7634](http://dev.ckeditor.com/ticket/7634): Fixed: The [Flash Dialog](http://ckeditor.com/addon/flash) plugin omits the `allowFullScreen` parameter in the editor data if set to `true`.
+* [#11910](http://dev.ckeditor.com/ticket/11910): Fixed: [Enhanced Image](http://ckeditor.com/addon/image2) does not take [`config.baseHref`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-baseHref) into account when updating image dimensions.
+* [#11753](http://dev.ckeditor.com/ticket/11753): Fixed: Wrong [`checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method value after focusing or blurring a widget.
+* [#11830](http://dev.ckeditor.com/ticket/11830): Fixed: Impossible to pass some arguments to [CKBuilder](https://github.com/ckeditor/ckbuilder) when using the `/dev/builder/build.sh` script.
+* [#11945](http://dev.ckeditor.com/ticket/11945): Fixed: [Form Elements](http://ckeditor.com/addon/forms) plugin should not change a core method.
+* [#11384](http://dev.ckeditor.com/ticket/11384): [IE9+] Fixed: `IndexSizeError` thrown when pasting into a non-empty selection anchored in one text node.
+
+## CKEditor 4.4.1
+
+New Features:
+
+* [#9661](http://dev.ckeditor.com/ticket/9661): Added the option to [configure](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-linkJavaScriptLinksAllowed) anchor tags with JavaScript code in the `href` attribute.
+
+Fixed Issues:
+
+* [#11861](http://dev.ckeditor.com/ticket/11861): [WebKit/Blink] Fixed: Span elements created while joining adjacent elements. **Note:** This patch only covers cases when *Backspace* or *Delete* is pressed on a collapsed (empty) selection. The remaining case, with a non-empty selection, will be fixed in the next release.
+* [#10714](http://dev.ckeditor.com/ticket/10714): [iOS] Fixed: Selection and drop-downs are broken if a touch event listener is used due to a [WebKit bug](https://bugs.webkit.org/show_bug.cgi?id=128924). Thanks to [Arty Gus](https://github.com/artygus)!
+* [#11911](http://dev.ckeditor.com/ticket/11911): Fixed setting the `dir` attribute for a preloaded language in [CKEDITOR.lang](http://docs.ckeditor.com/#!/api/CKEDITOR.lang). Thanks to [Akash Mohapatra](https://github.com/akashmohapatra)!
+* [#11926](http://dev.ckeditor.com/ticket/11926): Fixed: [Code Snippet](http://ckeditor.com/addon/codesnippet) does not decode HTML entities when loading code from the `<code>` element.
+* [#11223](http://dev.ckeditor.com/ticket/11223): Fixed: Issue when [Protected Source](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-protectedSource) was not working in the `<title>` element.
+* [#11859](http://dev.ckeditor.com/ticket/11859): Fixed: Removed the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin dependency from the [Code Snippet](http://ckeditor.com/addon/codesnippet) sample.
+* [#11754](http://dev.ckeditor.com/ticket/11754): [Chrome] Fixed: Infinite loop when content includes not closed attributes.
+* [#11848](http://dev.ckeditor.com/ticket/11848): [IE] Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) throwing an exception when there was no selection in the editor.
+* [#11801](http://dev.ckeditor.com/ticket/11801): Fixed: Editor anchors unavailable when linking the [Enhanced Image](http://ckeditor.com/addon/image2) widget.
+* [#11626](http://dev.ckeditor.com/ticket/11626): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) sets invalid column width.
+* [#11872](http://dev.ckeditor.com/ticket/11872): Made [`element.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-addClass) chainable symmetrically to [`element.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-removeClass).
+* [#11813](http://dev.ckeditor.com/ticket/11813): Fixed: Link lost while pasting a captioned image and restoring an undo snapshot ([Enhanced Image](http://ckeditor.com/addon/image2)).
+* [#11814](http://dev.ckeditor.com/ticket/11814): Fixed: _Link_ and _Unlink_ entries persistently displayed in the [Enhanced Image](http://ckeditor.com/addon/image2) context menu.
+* [#11839](http://dev.ckeditor.com/ticket/11839): [IE9] Fixed: The caret jumps out of the editable area when resizing the editor in the source mode.
+* [#11822](http://dev.ckeditor.com/ticket/11822): [WebKit] Fixed: Editing anchors by double-click is broken in some cases.
+* [#11823](http://dev.ckeditor.com/ticket/11823): [IE8] Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) throws an error over scrollbar.
+* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: It is not possible to change the language back to _Not set_ in the [Code Snippet](http://ckeditor.com/addon/codesnippet) dialog window.
+* [#11788](http://dev.ckeditor.com/ticket/11788): Fixed: [Filter](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied inside elements with the `contenteditable` attribute set to `true`.
+* [#11798](http://dev.ckeditor.com/ticket/11798): Fixed: Inserting a non-editable element inside a table cell breaks the table.
+* [#11793](http://dev.ckeditor.com/ticket/11793): Fixed: Drop-down is not "on" when clicking it while the editor is blurred.
+* [#11850](http://dev.ckeditor.com/ticket/11850): Fixed: Fake objects with the `contenteditable` attribute set to `false` are not downcasted properly.
+* [#11811](http://dev.ckeditor.com/ticket/11811): Fixed: Widget's data is not encoded correctly when passed to an attribute.
+* [#11777](http://dev.ckeditor.com/ticket/11777): Fixed encoding ampersand in the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin.
+* [#11880](http://dev.ckeditor.com/ticket/11880): [IE8-9] Fixed: Linked image has a default thick border.
+
+Other Changes:
+
+* [#11807](http://dev.ckeditor.com/ticket/11807): Updated jQuery version used in the sample to 1.11.0 and tested CKEditor jQuery Adapter with version 1.11.0 and 2.1.0.
+* [#9504](http://dev.ckeditor.com/ticket/9504): Stopped using deprecated `attribute.specified` in all browsers except Internet Explorer.
+* [#11809](http://dev.ckeditor.com/ticket/11809): Changed tab size in `<pre>` to 4 spaces.
+
+## CKEditor 4.4
+
+**Important Notes:**
+
+* Marked the [`editor.beforePaste`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-beforePaste) event as deprecated.
+* The default class of captioned images has changed to `image` (was: `caption`). Please note that once edited in CKEditor 4.4+, all existing images of the `caption` class (`<figure class="caption">`) will be [filtered out](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) unless the [`config.image2_captionedClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_captionedClass) option is set to `caption`. For backward compatibility (i.e. when upgrading), it is highly recommended to use this setting, which also helps prevent CSS conflicts, etc. This does not apply to new CKEditor integrations.
+* Widgets without defined buttons are no longer registered automatically to the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter). Before CKEditor 4.4 widgets were registered to the ACF which was an incorrect behavior ([#11567](http://dev.ckeditor.com/ticket/11567)). This change should not have any impact on standard scenarios, but if your button does not execute the widget command, you need to set [`allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.feature-property-allowedContent) and [`requiredContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.feature-property-requiredContent) properties for it manually, because the editor will not be able to find them.
+* The [Show Borders](http://ckeditor.com/addon/showborders) plugin was added to the Standard installation package in order to ensure that unstyled tables are still visible for the user ([#11665](http://dev.ckeditor.com/ticket/11665)).
+* Since CKEditor 4.4 the editor instance should be passed to [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) methods to ensure full compatibility with other features (e.g. applying styles to widgets requires that). We ensured backward compatibility though, so the [`CKEDITOR.style`](http://docs.ckeditor.com/#!/api/CKEDITOR.style) will work even when the editor instance is not provided.
+
+New Features:
+
+* [#11297](http://dev.ckeditor.com/ticket/11297): Styles can now be applied to widgets. The definition of a style which can be applied to a specific widget must contain two additional properties &mdash; `type` and `widget`. Read more in the [Widget Styles](http://docs.ckeditor.com/#!/guide/dev_styles-section-widget-styles) section of the "Syles Drop-down" guide. Note that by default, widgets support only classes and no other attributes or styles. Related changes and features:
+  * Introduced the [`CKEDITOR.style.addCustomHandler()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-static-method-addCustomHandler) method for registering custom style handlers.
+  * The [`CKEDITOR.style.apply()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-apply) and [`CKEDITOR.style.remove()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-remove) methods are now called with an editor instance instead of the document so they can be reused by the [`CKEDITOR.editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) and [`CKEDITOR.editor.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-removeStyle) methods. Backward compatibility was preserved, but from CKEditor 4.4 it is highly recommended to pass an editor instead of a document to these methods.
+  * Many new methods and properties were introduced in the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget) to make the handling of styles by widgets fully customizable. See: [`widget.definition.styleableElements`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-styleableElements), [`widget.definition.styleToAllowedContentRule`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-styleToAllowedContentRules), [`widget.addClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-addClass), [`widget.removeClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-removeClass), [`widget.getClasses()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-getClasses), [`widget.hasClass()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-hasClass), [`widget.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-applyStyle), [`widget.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-removeStyle), [`widget.checkStyleActive()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-method-checkStyleActive).
+  * Integration with the [Allowed Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) required an introduction of the [`CKEDITOR.style.toAllowedContent()`](http://docs.ckeditor.com/#!/api/CKEDITOR.style-method-toAllowedContentRules) method which can be implemented by the custom style handler and if exists, it is used by the [`CKEDITOR.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter) to translate a style to [allowed content rules](http://docs.ckeditor.com/#!/api/CKEDITOR.filter.allowedContentRules).
+* [#11300](http://dev.ckeditor.com/ticket/11300): Various changes in the [Enhanced Image](http://ckeditor.com/addon/image2) plugin:
+  * Introduced the [`config.image2_captionedClass`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_captionedClass) option to configure the class of captioned images.
+  * Introduced the [`config.image2_alignClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-image2_alignClasses) option to configure the way images are aligned with CSS classes.
+  If this setting is defined, the editor produces classes instead of inline styles for aligned images.
+  * Default image caption can be translated (customized) with the `editor.lang.image2.captionPlaceholder` string.
+* [#11341](http://dev.ckeditor.com/ticket/11341): [Enhanced Image](http://ckeditor.com/addon/image2) plugin: It is now possible to add a link to any image type.
+* [#10202](http://dev.ckeditor.com/ticket/10202): Introduced wildcard support in the [Allowed Content Rules](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) format.
+* [#10276](http://dev.ckeditor.com/ticket/10276): Introduced blacklisting in the [Allowed Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter).
+* [#10480](http://dev.ckeditor.com/ticket/10480): Introduced code snippets with code highlighting. There are two versions available so far &mdash; the default [Code Snippet](http://ckeditor.com/addon/codesnippet) which uses the [highlight.js](http://highlightjs.org) library and the [Code Snippet GeSHi](http://ckeditor.com/addon/codesnippetgeshi) which uses the [GeSHi](http://qbnz.com/highlighter/) library.
+* [#11737](http://dev.ckeditor.com/ticket/11737): Introduced an option to prevent [filtering](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) of an element that matches custom criteria (see [`filter.addElementCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-method-addElementCallback)).
+* [#11532](http://dev.ckeditor.com/ticket/11532): Introduced the [`editor.addContentsCss()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addContentsCss) method that can be used for [adding custom CSS files](http://docs.ckeditor.com/#!/guide/plugin_sdk_styles).
+* [#11536](http://dev.ckeditor.com/ticket/11536): Added the [`CKEDITOR.tools.htmlDecode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-htmlDecode) method for decoding HTML entities.
+* [#11225](http://dev.ckeditor.com/ticket/11225): Introduced the [`CKEDITOR.tools.transparentImageData`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-property-transparentImageData) property which contains transparent image data to be used in CSS or as image source.
+
+Other Changes:
+
+* [#11377](http://dev.ckeditor.com/ticket/11377): Unified internal representation of empty anchors using the [fake objects](http://ckeditor.com/addon/fakeobjects).
+* [#11422](http://dev.ckeditor.com/ticket/11422): Removed Firefox 3.x, Internet Explorer 6 and Opera 12.x leftovers in code.
+* [#5217](http://dev.ckeditor.com/ticket/5217): Setting data (including switching between modes) creates a new undo snapshot. Besides that:
+  * Introduced the [`editable.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-property-status) property.
+  * Introduced a new `forceUpdate` option for the [`editor.lockSnapshot`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-lockSnapshot) event.
+  * Fixed: Selection not being unlocked in inline editor after setting data ([#11500](http://dev.ckeditor.com/ticket/11500)).
+* The [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin was updated to the latest version.
+
+Fixed Issues:
+
+* [#10190](http://dev.ckeditor.com/ticket/10190): Fixed: Removing block style with [`editor.removeStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-removeStyle) should result in a paragraph and not a div.
+* [#11727](http://dev.ckeditor.com/ticket/11727): Fixed: The editor tries to select a non-editable image which was clicked.
+
+## CKEditor 4.3.5
+
+New Features:
+
+* Added new translation: Tatar.
+
+Fixed Issues:
+
+* [#11677](http://dev.ckeditor.com/ticket/11677): Fixed: Undo/Redo keystrokes are blocked in the source mode.
+* [#11717](http://dev.ckeditor.com/ticket/11717): [Document Properties](http://ckeditor.com/addon/docprops) plugin requires the [Color Dialog](http://ckeditor.com/addon/colordialog) plugin to work.
+
+## CKEditor 4.3.4
+
+Fixed Issues:
+
+* [#11597](http://dev.ckeditor.com/ticket/11597): [IE11] Fixed: Error thrown when trying to open the [preview](http://ckeditor.com/addon/preview) using the keyboard.
+* [#11544](http://dev.ckeditor.com/ticket/11544): [Placeholders](http://ckeditor.com/addon/placeholder) will no longer be upcasted in parents not accepting `<span>` elements.
+* [#8663](http://dev.ckeditor.com/ticket/8663): Fixed [`element.renameNode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-renameNode) not clearing the [`element.getName()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.element-method-getName) cache.
+* [#11574](http://dev.ckeditor.com/ticket/11574): Fixed: *Backspace* destroying the DOM structure if an inline editable is placed in a list item.
+* [#11603](http://dev.ckeditor.com/ticket/11603): Fixed: [Table Resize](http://ckeditor.com/addon/tableresize) attaches to tables outside the editable.
+* [#9205](http://dev.ckeditor.com/ticket/9205), [#7805](http://dev.ckeditor.com/ticket/7805), [#8216](http://dev.ckeditor.com/ticket/8216): Fixed: `{cke_protected_1}` appearing in data in various cases where HTML comments are placed next to `"` or `'`.
+* [#11635](http://dev.ckeditor.com/ticket/11635): Fixed: Some attributes are not protected before the content is passed through the fix bin.
+* [#11660](http://dev.ckeditor.com/ticket/11660): [IE] Fixed: Table content is lost when some extra markup is inside the table.
+* [#11641](http://dev.ckeditor.com/ticket/11641): Fixed: Switching between modes in the classic editor removes content styles for the inline editor.
+* [#11568](http://dev.ckeditor.com/ticket/11568): Fixed: [Styles](http://ckeditor.com/addon/stylescombo) drop-down list is not enabled on selection change.
+
+## CKEditor 4.3.3
+
+Fixed Issues:
+
+* [#11500](http://dev.ckeditor.com/ticket/11500): [WebKit/Blink] Fixed: Selection lost when setting data in another inline editor. Additionally, [`selection.removeAllRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-removeAllRanges) is now scoped to selection's [root](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-property-root).
+* [#11104](http://dev.ckeditor.com/ticket/11104): [IE] Fixed: Various issues with scrolling and selection when focusing widgets.
+* [#11487](http://dev.ckeditor.com/ticket/11487): Moving mouse over the [Enhanced Image](http://ckeditor.com/addon/image2) widget will no longer change the value returned by the [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) method.
+* [#8673](http://dev.ckeditor.com/ticket/8673): [WebKit] Fixed: Cannot select and remove the [Page Break](http://ckeditor.com/addon/pagebreak).
+* [#11413](http://dev.ckeditor.com/ticket/11413): Fixed: Incorrect [`editor.execCommand()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand) behavior.
+* [#11438](http://dev.ckeditor.com/ticket/11438): Splitting table cells vertically is no longer changing table structure.
+* [#8899](http://dev.ckeditor.com/ticket/8899): Fixed: Links in the [About CKEditor](http://ckeditor.com/addon/about) dialog window now open in a new browser window or tab.
+* [#11490](http://dev.ckeditor.com/ticket/11490): Fixed: [Menu button](http://ckeditor.com/addon/menubutton) panel not showing in the source mode.
+* [#11417](http://dev.ckeditor.com/ticket/11417): The [`widget.doubleclick`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget-event-doubleclick) event is not canceled anymore after editing was triggered.
+* [#11253](http://dev.ckeditor.com/ticket/11253): [IE] Fixed: Clipped upload button in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
+* [#11359](http://dev.ckeditor.com/ticket/11359): Standardized the way anchors are discovered by the [Link](http://ckeditor.com/addon/link) plugin.
+* [#11058](http://dev.ckeditor.com/ticket/11058): [IE8] Fixed: Error when deleting a table row.
+* [#11508](http://dev.ckeditor.com/ticket/11508): Fixed: [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor) discovering protected attributes within other attributes' values.
+* [#11533](http://dev.ckeditor.com/ticket/11533): Widgets: Avoid recurring upcasts if the DOM structure was modified during an upcast.
+* [#11400](http://dev.ckeditor.com/ticket/11400): Fixed: The [`domObject.removeAllListeners()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.domObject-method-removeAllListeners) method does not remove custom listeners completely.
+* [#11493](http://dev.ckeditor.com/ticket/11493): Fixed: The [`selection.getRanges()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-getRanges) method does not override cached ranges when used with the `onlyEditables` argument.
+* [#11390](http://dev.ckeditor.com/ticket/11390): [IE] All [XML](http://ckeditor.com/addon/xml) plugin [methods](http://docs.ckeditor.com/#!/api/CKEDITOR.xml) now work in IE10+.
+* [#11542](http://dev.ckeditor.com/ticket/11542): [IE11] Fixed: Blurry toolbar icons when Right-to-Left UI language is set.
+* [#11504](http://dev.ckeditor.com/ticket/11504): Fixed: When [`config.fullPage`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-fullPage) is set to `true`, entities are not encoded in editor output.
+* [#11004](http://dev.ckeditor.com/ticket/11004): Integrated [Enhanced Image](http://ckeditor.com/addon/image2) dialog window with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter).
+* [#11439](http://dev.ckeditor.com/ticket/11439): Fixed: Properties get cloned in the Cell Properties dialog window if multiple cells are selected.
+
+## CKEditor 4.3.2
+
+Fixed Issues:
+
+* [#11331](http://dev.ckeditor.com/ticket/11331): A menu button will have a changed label when selected instead of using the `aria-pressed` attribute.
+* [#11177](http://dev.ckeditor.com/ticket/11177): Widget drag handler improvements:
+  * [#11176](http://dev.ckeditor.com/ticket/11176): Fixed: Initial position is not updated when the widget data object is empty.
+  * [#11001](http://dev.ckeditor.com/ticket/11001): Fixed: Multiple synchronous layout recalculations are caused by initial drag handler positioning causing performance issues.
+  * [#11161](http://dev.ckeditor.com/ticket/11161): Fixed: Drag handler is not repositioned in various situations.
+  * [#11281](http://dev.ckeditor.com/ticket/11281): Fixed: Drag handler and mask are duplicated after widget reinitialization.
+* [#11207](http://dev.ckeditor.com/ticket/11207): [Firefox] Fixed: Misplaced [Enhanced Image](http://ckeditor.com/addon/image2) resizer in the inline editor.
+* [#11102](http://dev.ckeditor.com/ticket/11102): `CKEDITOR.template` improvements:
+  * [#11102](http://dev.ckeditor.com/ticket/11102): Added newline character support.
+  * [#11216](http://dev.ckeditor.com/ticket/11216): Added "\\'" substring support.
+* [#11121](http://dev.ckeditor.com/ticket/11121): [Firefox] Fixed: High Contrast mode is enabled when the editor is loaded in a hidden iframe.
+* [#11350](http://dev.ckeditor.com/ticket/11350): The default value of [`config.contentsCss`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-contentsCss) is affected by [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl).
+* [#11097](http://dev.ckeditor.com/ticket/11097): Improved the [Autogrow](http://ckeditor.com/addon/autogrow) plugin performance when dealing with very big tables.
+* [#11290](http://dev.ckeditor.com/ticket/11290): Removed redundant code in the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin.
+* [#11133](http://dev.ckeditor.com/ticket/11133): [Page Break](http://ckeditor.com/addon/pagebreak) becomes editable if pasted.
+* [#11126](http://dev.ckeditor.com/ticket/11126): Fixed: Native Undo executed once the bottom of the snapshot stack is reached.
+* [#11131](http://dev.ckeditor.com/ticket/11131): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Error thrown when switching to source mode if the selection was in widget's nested editable.
+* [#11139](http://dev.ckeditor.com/ticket/11139): [Div Editing Area](http://ckeditor.com/addon/divarea): Fixed: Elements Path is not cleared after switching to source mode.
+* [#10778](http://dev.ckeditor.com/ticket/10778): Fixed a bug with range enlargement. The range no longer expands to visible whitespace.
+* [#11146](http://dev.ckeditor.com/ticket/11146): [IE] Fixed: Preview window switches Internet Explorer to Quirks Mode.
+* [#10762](http://dev.ckeditor.com/ticket/10762): [IE] Fixed: JavaScript code displayed in preview window's URL bar.
+* [#11186](http://dev.ckeditor.com/ticket/11186): Introduced the [`widgets.repository.addUpcastCallback()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-addUpcastCallback) method that allows to block upcasting given element to a widget.
+* [#11307](http://dev.ckeditor.com/ticket/11307): Fixed: Paste as Plain Text conflict with the [MooTools](http://mootools.net) library.
+* [#11140](http://dev.ckeditor.com/ticket/11140): [IE11] Fixed: Anchors are not draggable.
+* [#11379](http://dev.ckeditor.com/ticket/11379): Changed default contents `line-height` to unitless values to avoid huge text overlapping (like in [#9696](http://dev.ckeditor.com/ticket/9696)).
+* [#10787](http://dev.ckeditor.com/ticket/10787): [Firefox] Fixed: Broken replacement of text while pasting into `div`-based editor.
+* [#10884](http://dev.ckeditor.com/ticket/10884): Widgets integration with the [Show Blocks](http://ckeditor.com/addon/showblocks) plugin.
+* [#11021](http://dev.ckeditor.com/ticket/11021): Fixed: An error thrown when selecting entire editable contents while fake selection is on.
+* [#11086](http://dev.ckeditor.com/ticket/11086): [IE8] Re-enable inline widgets drag&drop in Internet Explorer 8.
+* [#11372](http://dev.ckeditor.com/ticket/11372): Widgets: Special characters encoded twice in nested editables.
+* [#10068](http://dev.ckeditor.com/ticket/10068): Fixed: Support for protocol-relative URLs.
+* [#11283](http://dev.ckeditor.com/ticket/11283): [Enhanced Image](http://ckeditor.com/addon/image2): A `<div>` element with `text-align: center` and an image inside is not recognised correctly.
+* [#11196](http://dev.ckeditor.com/ticket/11196): [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp): Allowed additional keyboard button labels to be translated in the dialog window.
+
+## CKEditor 4.3.1
+
+**Important Notes:**
+
+* To match the naming convention, the `language` button is now `Language` ([#11201](http://dev.ckeditor.com/ticket/11201)).
+* [Enhanced Image](http://ckeditor.com/addon/image2) button, context menu, command, and icon names match those of the [Image](http://ckeditor.com/addon/image) plugin ([#11222](http://dev.ckeditor.com/ticket/11222)).
+
+Fixed Issues:
+
+* [#11244](http://dev.ckeditor.com/ticket/11244): Changed: The [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method now fires the [`widget.repository.checkWidgets`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-event-checkWidgets) event, so from CKEditor 4.3.1 it is preferred to use the method rather than fire the event.
+* [#11171](http://dev.ckeditor.com/ticket/11171): Fixed: [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) and [`editor.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText) methods do not call the [`widget.repository.checkWidgets()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.repository-method-checkWidgets) method.
+* [#11085](http://dev.ckeditor.com/ticket/11085): [IE8] Replaced preview generated by the [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget with a placeholder.
+* [#11044](http://dev.ckeditor.com/ticket/11044): Enhanced WAI-ARIA support for the [Language](http://ckeditor.com/addon/language) plugin drop-down menu.
+* [#11075](http://dev.ckeditor.com/ticket/11075): With drop-down menu button focused, pressing the *Down Arrow* key will now open the menu and focus its first option.
+* [#11165](http://dev.ckeditor.com/ticket/11165): Fixed: The [File Browser](http://ckeditor.com/addon/filebrowser) plugin cannot be removed from the editor.
+* [#11159](http://dev.ckeditor.com/ticket/11159): [IE9-10] [Enhanced Image](http://ckeditor.com/addon/image2): Fixed buggy discovery of image dimensions.
+* [#11101](http://dev.ckeditor.com/ticket/11101): Drop-down lists no longer break when given double quotes.
+* [#11077](http://dev.ckeditor.com/ticket/11077): [Enhanced Image](http://ckeditor.com/addon/image2): Empty undo step recorded when resizing the image.
+* [#10853](http://dev.ckeditor.com/ticket/10853): [Enhanced Image](http://ckeditor.com/addon/image2): Widget has paragraph wrapper when de-captioning unaligned image.
+* [#11198](http://dev.ckeditor.com/ticket/11198): Widgets: Drag handler is not fully visible when an inline widget is in a heading.
+* [#11132](http://dev.ckeditor.com/ticket/11132): [Firefox] Fixed: Caret is lost after drag and drop of an inline widget.
+* [#11182](http://dev.ckeditor.com/ticket/11182): [IE10-11] Fixed: Editor crashes (IE11) or works with minor issues (IE10) if a page is loaded in Quirks Mode. See [`env.quirks`](http://docs.ckeditor.com/#!/api/CKEDITOR.env-property-quirks) for more details.
+* [#11204](http://dev.ckeditor.com/ticket/11204): Added `figure` and `figcaption` styles to the `contents.css` file so [Enhanced Image](http://ckeditor.com/addon/image2) looks nicer.
+* [#11202](http://dev.ckeditor.com/ticket/11202): Fixed: No newline in [BBCode](http://ckeditor.com/addon/bbcode) mode.
+* [#10890](http://dev.ckeditor.com/ticket/10890): Fixed: Error thrown when pressing the *Delete* key in a list item.
+* [#10055](http://dev.ckeditor.com/ticket/10055): [IE8-10] Fixed: *Delete* pressed on a selected image causes the browser to go back.
+* [#11183](http://dev.ckeditor.com/ticket/11183): Fixed: Inserting a horizontal rule or a table in multiple row selection causes a browser crash. Additionally, the [`editor.insertElement()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertElement) method does not insert the element into every range of a selection any more.
+* [#11042](http://dev.ckeditor.com/ticket/11042): Fixed: Selection made on an element containing a non-editable element was not auto faked.
+* [#11125](http://dev.ckeditor.com/ticket/11125): Fixed: Keyboard navigation through menu and drop-down items will now cycle.
+* [#11011](http://dev.ckeditor.com/ticket/11011): Fixed: The [`editor.applyStyle()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-applyStyle) method removes attributes from nested elements.
+* [#11179](http://dev.ckeditor.com/ticket/11179): Fixed: [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy) does not cleanup content generated by the [Table Resize](http://ckeditor.com/addon/tableresize) plugin for inline editors.
+* [#11237](http://dev.ckeditor.com/ticket/11237): Fixed: Table border attribute value is deleted when pasting content from Microsoft Word.
+* [#11250](http://dev.ckeditor.com/ticket/11250): Fixed: HTML entities inside the `<textarea>` element are not encoded.
+* [#11260](http://dev.ckeditor.com/ticket/11260): Fixed: Initially disabled buttons are not read by JAWS as disabled.
+* [#11200](http://dev.ckeditor.com/ticket/11200):  Added [Clipboard](http://ckeditor.com/addon/clipboard) plugin as a dependency for [Widget](http://ckeditor.com/addon/widget) to fix drag and drop.
+
+## CKEditor 4.3
+
+New Features:
+
+* [#10612](http://dev.ckeditor.com/ticket/10612): Internet Explorer 11 support.
+* [#10869](http://dev.ckeditor.com/ticket/10869): Widgets: Added better integration with the [Elements Path](http://ckeditor.com/addon/elementspath) plugin.
+* [#10886](http://dev.ckeditor.com/ticket/10886): Widgets: Added tooltip to the drag handle.
+* [#10933](http://dev.ckeditor.com/ticket/10933): Widgets: Introduced drag and drop of block widgets with the [Line Utilities](http://ckeditor.com/addon/lineutils) plugin.
+* [#10936](http://dev.ckeditor.com/ticket/10936): Widget System changes for easier integration with other dialog systems.
+* [#10895](http://dev.ckeditor.com/ticket/10895): [Enhanced Image](http://ckeditor.com/addon/image2): Added file browser integration.
+* [#11002](http://dev.ckeditor.com/ticket/11002): Added the [`draggable`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget.definition-property-draggable) option to disable drag and drop support for widgets.
+* [#10937](http://dev.ckeditor.com/ticket/10937): [Mathematical Formulas](http://ckeditor.com/addon/mathjax) widget improvements:
+  * loading indicator ([#10948](http://dev.ckeditor.com/ticket/10948)),
+  * applying paragraph changes (like font color change) to iframe ([#10841](http://dev.ckeditor.com/ticket/10841)),
+  * Firefox and IE9 clipboard fixes ([#10857](http://dev.ckeditor.com/ticket/10857)),
+  * fixing same origin policy issue ([#10840](http://dev.ckeditor.com/ticket/10840)),
+  * fixing undo bugs ([#10842](http://dev.ckeditor.com/ticket/10842), [#10930](http://dev.ckeditor.com/ticket/10930)),
+  * fixing other minor bugs.
+* [#10862](http://dev.ckeditor.com/ticket/10862): [Placeholder](http://ckeditor.com/addon/placeholder) plugin was rewritten as a widget.
+* [#10822](http://dev.ckeditor.com/ticket/10822): Added styles system integration with non-editable elements (for example widgets) and their nested editables. Styles cannot change non-editable content and are applied in nested editable only if allowed by its type and content filter.
+* [#10856](http://dev.ckeditor.com/ticket/10856): Menu buttons will now toggle the visibility of their panels when clicked multiple times. [Language](http://ckeditor.com/addon/language) plugin fixes: Added active language highlighting, added an option to remove the language.
+* [#10028](http://dev.ckeditor.com/ticket/10028): New [`config.dialog_noConfirmCancel`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-dialog_noConfirmCancel) configuration option that eliminates the need to confirm closing of a dialog window when the user changed any of its fields.
+* [#10848](http://dev.ckeditor.com/ticket/10848): Integrate remaining plugins ([Styles](http://ckeditor.com/addon/stylescombo), [Format](http://ckeditor.com/addon/format), [Font](http://ckeditor.com/addon/font), [Color Button](http://ckeditor.com/addon/colorbutton), [Language](http://ckeditor.com/addon/language) and [Indent](http://ckeditor.com/addon/indent)) with [active filter](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter).
+* [#10855](http://dev.ckeditor.com/ticket/10855): Change the extension of emoticons in the [BBCode](http://ckeditor.com/addon/bbcode) sample from GIF to PNG.
+
+Fixed Issues:
+
+* [#10831](http://dev.ckeditor.com/ticket/10831): [Enhanced Image](http://ckeditor.com/addon/image2): Merged `image2inline` and `image2block` into one `image2` widget.
+* [#10835](http://dev.ckeditor.com/ticket/10835): [Enhanced Image](http://ckeditor.com/addon/image2): Improved visibility of the resize handle.
+* [#10836](http://dev.ckeditor.com/ticket/10836): [Enhanced Image](http://ckeditor.com/addon/image2): Preserve custom mouse cursor while resizing the image.
+* [#10939](http://dev.ckeditor.com/ticket/10939): [Firefox] [Enhanced Image](http://ckeditor.com/addon/image2): hovering the image causes it to change.
+* [#10866](http://dev.ckeditor.com/ticket/10866): Fixed: Broken *Tab* key navigation in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
+* [#10833](http://dev.ckeditor.com/ticket/10833): Fixed: *Lock ratio* option should be on by default in the [Enhanced Image](http://ckeditor.com/addon/image2) dialog window.
+* [#10881](http://dev.ckeditor.com/ticket/10881): Various improvements to *Enter* key behavior in nested editables.
+* [#10879](http://dev.ckeditor.com/ticket/10879): [Remove Format](http://ckeditor.com/addon/removeformat) should not leak from a nested editable.
+* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [WebSpellChecker](http://ckeditor.com/addon/wsc) fails to apply changes if a nested editable was focused.
+* [#10877](http://dev.ckeditor.com/ticket/10877): Fixed: [SCAYT](http://ckeditor.com/addon/wsc) blocks typing in nested editables.
+* [#11079](http://dev.ckeditor.com/ticket/11079): Add button icons to the [Placeholder](http://ckeditor.com/addon/placeholder) sample.
+* [#10870](http://dev.ckeditor.com/ticket/10870): The `paste` command is no longer being disabled when the clipboard is empty.
+* [#10854](http://dev.ckeditor.com/ticket/10854): Fixed: Firefox prepends `<br>` to `<body>`, so it is stripped by the HTML data processor.
+* [#10823](http://dev.ckeditor.com/ticket/10823): Fixed: [Link](http://ckeditor.com/addon/link) plugin does not work with non-editable content.
+* [#10828](http://dev.ckeditor.com/ticket/10828): [Magic Line](http://ckeditor.com/addon/magicline) integration with the Widget System.
+* [#10865](http://dev.ckeditor.com/ticket/10865): Improved hiding copybin, so copying widgets works smoothly.
+* [#11066](http://dev.ckeditor.com/ticket/11066): Widget's private parts use CSS reset.
+* [#11027](http://dev.ckeditor.com/ticket/11027): Fixed: Block commands break on widgets; added the [`contentDomInvalidated`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-contentDomInvalidated) event.
+* [#10430](http://dev.ckeditor.com/ticket/10430): Resolve dependence of the [Image](http://ckeditor.com/addon/image) plugin on the [Form Elements](http://ckeditor.com/addon/forms) plugin.
+* [#10911](http://dev.ckeditor.com/ticket/10911): Fixed: Browser *Alt* hotkeys will no longer be blocked while a widget is focused.
+* [#11082](http://dev.ckeditor.com/ticket/11082): Fixed: Selected widget is not copied or cut when using toolbar buttons or context menu.
+* [#11083](http://dev.ckeditor.com/ticket/11083): Fixed list and div element application to block widgets.
+* [#10887](http://dev.ckeditor.com/ticket/10887): Internet Explorer 8 compatibility issues related to the Widget System.
+* [#11074](http://dev.ckeditor.com/ticket/11074): Temporarily disabled inline widget drag and drop, because of seriously buggy native `range#moveToPoint` method.
+* [#11098](http://dev.ckeditor.com/ticket/11098): Fixed: Wrong selection position after undoing widget drag and drop.
+* [#11110](http://dev.ckeditor.com/ticket/11110): Fixed: IFrame and Flash objects are being incorrectly pasted in certain conditions.
+* [#11129](http://dev.ckeditor.com/ticket/11129): Page break is lost when loading data.
+* [#11123](http://dev.ckeditor.com/ticket/11123): [Firefox] Widget is destroyed after being dragged outside of `<body>`.
+* [#11124](http://dev.ckeditor.com/ticket/11124): Fixed the [Elements Path](http://ckeditor.com/addon/elementspath) in an editor using the [Div Editing Area](http://ckeditor.com/addon/divarea).
+
+## CKEditor 4.3 Beta
+
+New Features:
+
+* [#9764](http://dev.ckeditor.com/ticket/9764): Widget System.
+  * [Widget plugin](http://ckeditor.com/addon/widget) introducing the [Widget API](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.widget).
+  * New [`editor.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) and [`editor.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-shiftEnterMode) properties &ndash; normalized versions of [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) and [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
+  * Dynamic editor settings. Starting from CKEditor 4.3 Beta, *Enter* mode values and [content filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) instances may be changed dynamically (for example when the caret was placed in an element in which editor features should be adjusted). When you are implementing a new editor feature, you should base its behavior on [dynamic](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) or [static](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-enterMode) *Enter* mode values depending on whether this feature works in selection context or globally on editor content.
+      * Dynamic *Enter* mode values &ndash; [`editor.setActiveEnterMode()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveEnterMode) method, [`editor.activeEnterModeChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeEnterModeChange) event, and two properties: [`editor.activeEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeEnterMode) and [`editor.activeShiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeShiftEnterMode).
+      * Dynamic content filter instances &ndash; [`editor.setActiveFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setActiveFilter) method, [`editor.activeFilterChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-activeFilterChange) event, and [`editor.activeFilter`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-activeFilter) property.
+  * "Fake" selection was introduced. It makes it possible to virtually select any element when the real selection remains hidden. See the  [`selection.fake()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.selection-method-fake) method.
+  * Default [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter) rules are not applied to non-editable elements (elements with `contenteditable` attribute set to `false` and their descendants) anymore. To add a rule which will be applied to all elements you need to pass an additional argument to the [`filter.addRules()`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter-method-addRules) method.
+  * Dozens of new methods were introduced &ndash; most interesting ones:
+      * [`document.find()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-find),
+      * [`document.findOne()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.document-method-findOne),
+      * [`editable.insertElementIntoRange()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertElementIntoRange),
+      * [`range.moveToClosestEditablePosition()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-moveToClosestEditablePosition),
+      * New methods for [`htmlParser.node`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.node) and [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element).
+* [#10659](http://dev.ckeditor.com/ticket/10659): New [Enhanced Image](http://ckeditor.com/addon/image2) plugin that introduces a widget with integrated image captions, an option to center images, and dynamic "click and drag" resizing.
+* [#10664](http://dev.ckeditor.com/ticket/10664): New [Mathematical Formulas](http://ckeditor.com/addon/mathjax) plugin that introduces the MathJax widget.
+* [#7987](https://dev.ckeditor.com/ticket/7987): New [Language](http://ckeditor.com/addon/language) plugin that implements Language toolbar button to support [WCAG 3.1.2 Language of Parts](http://www.w3.org/TR/UNDERSTANDING-WCAG20/meaning-other-lang-id.html).
+* [#10708](http://dev.ckeditor.com/ticket/10708): New [smileys](http://ckeditor.com/addon/smiley).
+
+## CKEditor 4.2.3
+
+Fixed Issues:
+
+* [#10994](http://dev.ckeditor.com/ticket/10994): Fixed: Loading external jQuery library when opening the [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) sample directly from file.
+* [#10975](http://dev.ckeditor.com/ticket/10975): [IE] Fixed: Error thrown while opening the color palette.
+* [#9929](http://dev.ckeditor.com/ticket/9929): [Blink/WebKit] Fixed: A non-breaking space is created once a character is deleted and a regular space is typed.
+* [#10963](http://dev.ckeditor.com/ticket/10963): Fixed: JAWS issue with the keyboard shortcut for [Magic Line](http://ckeditor.com/addon/magicline).
+* [#11096](http://dev.ckeditor.com/ticket/11096): Fixed: TypeError: Object has no method 'is'.
+
+## CKEditor 4.2.2
+
+Fixed Issues:
+
+* [#9314](http://dev.ckeditor.com/ticket/9314): Fixed: Incorrect error message on closing a dialog window without saving changs.
+* [#10308](http://dev.ckeditor.com/ticket/10308): [IE10] Fixed: Unspecified error when deleting a row.
+* [#10945](http://dev.ckeditor.com/ticket/10945): [Chrome] Fixed: Clicking with a mouse inside the editor does not show the caret.
+* [#10912](http://dev.ckeditor.com/ticket/10912): Prevent default action when content of a non-editable link is clicked.
+* [#10913](http://dev.ckeditor.com/ticket/10913): Fixed [`CKEDITOR.plugins.addExternal()`](http://docs.ckeditor.com/#!/api/CKEDITOR.resourceManager-method-addExternal) not handling paths including file name specified.
+* [#10666](http://dev.ckeditor.com/ticket/10666): Fixed [`CKEDITOR.tools.isArray()`](http://docs.ckeditor.com/#!/api/CKEDITOR.tools-method-isArray) not working cross frame.
+* [#10910](http://dev.ckeditor.com/ticket/10910): [IE9] Fixed JavaScript error thrown in Compatibility Mode when clicking and/or typing in the editing area.
+* [#10868](http://dev.ckeditor.com/ticket/10868): [IE8] Prevent the browser from crashing when applying the Inline Quotation style.
+* [#10915](http://dev.ckeditor.com/ticket/10915): Fixed: Invalid CSS filter in the Kama skin.
+* [#10914](http://dev.ckeditor.com/ticket/10914): Plugins [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock) are now included in the build configuration.
+* [#10812](http://dev.ckeditor.com/ticket/10812): Fixed [`range.createBookmark2()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dom.range-method-createBookmark2) incorrectly normalizing offsets. This bug was causing many issues: [#10850](http://dev.ckeditor.com/ticket/10850), [#10842](http://dev.ckeditor.com/ticket/10842).
+* [#10951](http://dev.ckeditor.com/ticket/10951): Reviewed and optimized focus handling on panels (combo, menu buttons, color buttons, and context menu) to enhance accessibility. Fixed [#10705](http://dev.ckeditor.com/ticket/10705), [#10706](http://dev.ckeditor.com/ticket/10706) and [#10707](http://dev.ckeditor.com/ticket/10707).
+* [#10704](http://dev.ckeditor.com/ticket/10704): Fixed a JAWS issue with the Select Color dialog window title not being announced.
+* [#10753](http://dev.ckeditor.com/ticket/10753): The floating toolbar in inline instances now has a dedicated accessibility label.
+
+## CKEditor 4.2.1
+
+Fixed Issues:
+
+* [#10301](http://dev.ckeditor.com/ticket/10301): [IE9-10] Undo fails after 3+ consecutive paste actions with a JavaScript error.
+* [#10689](http://dev.ckeditor.com/ticket/10689): Save toolbar button saves only the first editor instance.
+* [#10368](http://dev.ckeditor.com/ticket/10368): Move language reading direction definition (`dir`) from main language file to core.
+* [#9330](http://dev.ckeditor.com/ticket/9330): Fixed pasting anchors from MS Word.
+* [#8103](http://dev.ckeditor.com/ticket/8103): Fixed pasting nested lists from MS Word.
+* [#9958](http://dev.ckeditor.com/ticket/9958): [IE9] Pressing the "OK" button will trigger the `onbeforeunload` event in the popup dialog.
+* [#10662](http://dev.ckeditor.com/ticket/10662): Fixed styles from the Styles drop-down list not registering to the ACF in case when the [Shared Spaces plugin](http://ckeditor.com/addon/sharedspace) is used.
+* [#9654](http://dev.ckeditor.com/ticket/9654): Problems with Internet Explorer 10 Quirks Mode.
+* [#9816](http://dev.ckeditor.com/ticket/9816): Floating toolbar does not reposition vertically in several cases.
+* [#10646](http://dev.ckeditor.com/ticket/10646): Removing a selected sublist or nested table with *Backspace/Delete* removes the parent element.
+* [#10623](http://dev.ckeditor.com/ticket/10623): [WebKit] Page is scrolled when opening a drop-down list.
+* [#10004](http://dev.ckeditor.com/ticket/10004): [ChromeVox] Button names are not announced.
+* [#10731](http://dev.ckeditor.com/ticket/10731): [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin breaks cloning of editor configuration.
+* It is now possible to set per instance [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin configuration instead of setting the configuration globally.
+
+## CKEditor 4.2
+
+**Important Notes:**
+
+* Dropped compatibility support for Internet Explorer 7 and Firefox 3.6.
+
+* Both the Basic and the Standard distribution packages will not contain the new [Indent Block](http://ckeditor.com/addon/indentblock) plugin. Because of this the [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) might remove block indentations from existing contents. If you want to prevent this, either [add an appropriate ACF rule to your filter](http://docs.ckeditor.com/#!/guide/dev_allowed_content_rules) or create a custom build based on the Basic/Standard package and add the Indent Block plugin in [CKBuilder](http://ckeditor.com/builder).
+
+New Features:
+
+* [#10027](http://dev.ckeditor.com/ticket/10027): Separated list and block indentation into two plugins: [Indent List](http://ckeditor.com/addon/indentlist) and [Indent Block](http://ckeditor.com/addon/indentblock).
+* [#8244](http://dev.ckeditor.com/ticket/8244): Use *(Shift+)Tab* to indent and outdent lists.
+* [#10281](http://dev.ckeditor.com/ticket/10281): The [jQuery Adapter](http://docs.ckeditor.com/#!/guide/dev_jquery) is now available. Several jQuery-related issues fixed: [#8261](http://dev.ckeditor.com/ticket/8261), [#9077](http://dev.ckeditor.com/ticket/9077), [#8710](http://dev.ckeditor.com/ticket/8710), [#8530](http://dev.ckeditor.com/ticket/8530), [#9019](http://dev.ckeditor.com/ticket/9019), [#6181](http://dev.ckeditor.com/ticket/6181), [#7876](http://dev.ckeditor.com/ticket/7876), [#6906](http://dev.ckeditor.com/ticket/6906).
+* [#10042](http://dev.ckeditor.com/ticket/10042): Introduced [`config.title`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-title) setting to change the human-readable title of the editor.
+* [#9794](http://dev.ckeditor.com/ticket/9794): Added [`editor.change`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-change) event.
+* [#9923](http://dev.ckeditor.com/ticket/9923): HiDPI support in the editor UI. HiDPI icons for [Moono skin](http://ckeditor.com/addon/moono) added.
+* [#8031](http://dev.ckeditor.com/ticket/8031): Handle `required` attributes on `<textarea>` elements &mdash; introduced [`editor.required`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-required) event.
+* [#10280](http://dev.ckeditor.com/ticket/10280): Ability to replace `<textarea>` elements with the inline editor.
+
+Fixed Issues:
+
+* [#10599](http://dev.ckeditor.com/ticket/10599): [Indent](http://ckeditor.com/addon/indent) plugin is no longer required by the [List](http://ckeditor.com/addon/list) plugin.
+* [#10370](http://dev.ckeditor.com/ticket/10370): Inconsistency in data events between framed and inline editors.
+* [#10438](http://dev.ckeditor.com/ticket/10438): [FF, IE] No selection is done on an editable element on executing [`editor.setData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData).
+
+## CKEditor 4.1.3
+
+New Features:
+
+* Added new translation: Indonesian.
+
+Fixed Issues:
+
+* [#10644](http://dev.ckeditor.com/ticket/10644): Fixed a critical bug when pasting plain text in Blink-based browsers.
+* [#5189](http://dev.ckeditor.com/ticket/5189): [Find/Replace](http://ckeditor.com/addon/find) dialog window: rename "Cancel" button to "Close".
+* [#10562](http://dev.ckeditor.com/ticket/10562): [Housekeeping] Unified CSS gradient filter formats in the [Moono](http://ckeditor.com/addon/moono) skin.
+* [#10537](http://dev.ckeditor.com/ticket/10537): Advanced Content Filter should register a default rule for [`config.shiftEnterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode).
+* [#10610](http://dev.ckeditor.com/ticket/10610): [`CKEDITOR.dialog.addIframe()`](http://docs.ckeditor.com/#!/api/CKEDITOR.dialog-static-method-addIframe) incorrectly sets the iframe size in dialog windows.
+
+## CKEditor 4.1.2
+
+New Features:
+
+* Added new translation: Sinhala.
+
+Fixed Issues:
+
+* [#10339](http://dev.ckeditor.com/ticket/10339): Fixed: Error thrown when inserted data was totally stripped out after filtering and processing.
+* [#10298](http://dev.ckeditor.com/ticket/10298): Fixed: Data processor breaks attributes containing protected parts.
+* [#10367](http://dev.ckeditor.com/ticket/10367): Fixed: [`editable.insertText()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editable-method-insertText) loses characters when `RegExp` replace controls are being inserted.
+* [#10165](http://dev.ckeditor.com/ticket/10165): [IE] Access denied error when `document.domain` has been altered.
+* [#9761](http://dev.ckeditor.com/ticket/9761): Update the *Backspace* key state in [`keystrokeHandler.blockedKeystrokes`](http://docs.ckeditor.com/#!/api/CKEDITOR.keystrokeHandler-property-blockedKeystrokes) when calling [`editor.setReadOnly()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly).
+* [#6504](http://dev.ckeditor.com/ticket/6504): Fixed: Race condition while loading several [`config.customConfig`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-customConfig) files.
+* [#10146](http://dev.ckeditor.com/ticket/10146): [Firefox] Empty lines are being removed while [`config.enterMode`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode) is [`CKEDITOR.ENTER_BR`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-ENTER_BR).
+* [#10360](http://dev.ckeditor.com/ticket/10360): Fixed: ARIA `role="application"` should not be used for dialog windows.
+* [#10361](http://dev.ckeditor.com/ticket/10361): Fixed: ARIA `role="application"` should not be used for floating panels.
+* [#10510](http://dev.ckeditor.com/ticket/10510): Introduced unique voice labels to differentiate between different editor instances.
+* [#9945](http://dev.ckeditor.com/ticket/9945): [iOS] Scrolling not possible on iPad.
+* [#10389](http://dev.ckeditor.com/ticket/10389): Fixed: Invalid HTML in the "Text and Table" template.
+* [WebSpellChecker](http://ckeditor.com/addon/wsc) plugin user interface was changed to match CKEditor 4 style.
+
+## CKEditor 4.1.1
+
+New Features:
+
+* Added new translation: Albanian.
+
+Fixed Issues:
+
+* [#10172](http://dev.ckeditor.com/ticket/10172): Pressing *Delete* or *Backspace* in an empty table cell moves the cursor to the next/previous cell.
+* [#10219](http://dev.ckeditor.com/ticket/10219): Error thrown when destroying an editor instance in parallel with a `mouseup` event.
+* [#10265](http://dev.ckeditor.com/ticket/10265): Wrong loop type in the [File Browser](http://ckeditor.com/addon/filebrowser) plugin.
+* [#10249](http://dev.ckeditor.com/ticket/10249): Wrong undo/redo states at start.
+* [#10268](http://dev.ckeditor.com/ticket/10268): [Show Blocks](http://ckeditor.com/addon/showblocks) does not recover after switching to Source view.
+* [#9995](http://dev.ckeditor.com/ticket/9995): HTML code in the `<textarea>` should not be modified by the [`htmlDataProcessor`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlDataProcessor).
+* [#10320](http://dev.ckeditor.com/ticket/10320): [Justify](http://ckeditor.com/addon/justify) plugin should add elements to Advanced Content Filter based on current [Enter mode](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode).
+* [#10260](http://dev.ckeditor.com/ticket/10260): Fixed: Advanced Content Filter blocks [`tabSpaces`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-tabSpaces). Unified `data-cke-*` attributes filtering.
+* [#10315](http://dev.ckeditor.com/ticket/10315): [WebKit] [Undo manager](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager) should not record snapshots after a filling character was added/removed.
+* [#10291](http://dev.ckeditor.com/ticket/10291): [WebKit] Space after a filling character should be secured.
+* [#10330](http://dev.ckeditor.com/ticket/10330): [WebKit] The filling character is not removed on `keydown` in specific cases.
+* [#10285](http://dev.ckeditor.com/ticket/10285): Fixed: Styled text pasted from MS Word causes an infinite loop.
+* [#10131](http://dev.ckeditor.com/ticket/10131): Fixed: [`undoManager.update()`](http://docs.ckeditor.com/#!/api/CKEDITOR.plugins.undo.UndoManager-method-update) does not refresh the command state.
+* [#10337](http://dev.ckeditor.com/ticket/10337): Fixed: Unable to remove `<s>` using [Remove Format](http://ckeditor.com/addon/removeformat).
+
+## CKEditor 4.1
+
+Fixed Issues:
+
+* [#10192](http://dev.ckeditor.com/ticket/10192): Closing lists with the *Enter* key does not work with [Advanced Content Filter](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) in several cases.
+* [#10191](http://dev.ckeditor.com/ticket/10191): Fixed allowed content rules unification, so the [`filter.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.filter-property-allowedContent) property always contains rules in the same format.
+* [#10224](http://dev.ckeditor.com/ticket/10224): Advanced Content Filter does not remove non-empty `<a>` elements anymore.
+* Minor issues in plugin integration with Advanced Content Filter:
+  * [#10166](http://dev.ckeditor.com/ticket/10166): Added transformation from the `align` attribute to `float` style to preserve backward compatibility after the introduction of Advanced Content Filter.
+  * [#10195](http://dev.ckeditor.com/ticket/10195): [Image](http://ckeditor.com/addon/image) plugin no longer registers rules for links to Advanced Content Filter.
+  * [#10213](http://dev.ckeditor.com/ticket/10213): [Justify](http://ckeditor.com/addon/justify) plugin is now correctly registering rules to Advanced Content Filter when [`config.justifyClasses`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-justifyClasses) is defined.
+
+## CKEditor 4.1 RC
+
+New Features:
+
+* [#9829](http://dev.ckeditor.com/ticket/9829): Advanced Content Filter - data and features activation based on editor configuration.
+
+  Brand new data filtering system that works in 2 modes:
+
+  * Based on loaded features (toolbar items, plugins) - the data will be filtered according to what the editor in its
+  current configuration can handle.
+  * Based on [`config.allowedContent`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent) rules - the data
+  will be filtered and the editor features (toolbar items, commands, keystrokes) will be enabled if they are allowed.
+
+  See the `datafiltering.html` sample, [guides](http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter) and [`CKEDITOR.filter` API documentation](http://docs.ckeditor.com/#!/api/CKEDITOR.filter).
+* [#9387](http://dev.ckeditor.com/ticket/9387): Reintroduced [Shared Spaces](http://ckeditor.com/addon/sharedspace) - the ability to display toolbar and bottom editor space in selected locations and to share them by different editor instances.
+* [#9907](http://dev.ckeditor.com/ticket/9907): Added the [`contentPreview`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-contentPreview) event for preview data manipulation.
+* [#9713](http://dev.ckeditor.com/ticket/9713): Introduced the [Source Dialog](http://ckeditor.com/addon/sourcedialog) plugin that brings raw HTML editing for inline editor instances.
+* Included in [#9829](http://dev.ckeditor.com/ticket/9829): Introduced new events, [`toHtml`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toHtml) and [`toDataFormat`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-toDataFormat), allowing for better integration with data processing.
+* [#9981](http://dev.ckeditor.com/ticket/9981): Added ability to filter [`htmlParser.fragment`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.fragment), [`htmlParser.element`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element) etc. by many [`htmlParser.filter`](http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.filter)s before writing structure to an HTML string.
+* Included in [#10103](http://dev.ckeditor.com/ticket/10103):
+  * Introduced the [`editor.status`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-status) property to make it easier to check the current status of the editor.
+  * Default [`command`](http://docs.ckeditor.com/#!/api/CKEDITOR.command) state is now [`CKEDITOR.TRISTATE_DISABLE`](http://docs.ckeditor.com/#!/api/CKEDITOR-property-TRISTATE_DISABLED). It will be activated on [`editor.instanceReady`](http://docs.ckeditor.com/#!/api/CKEDITOR-event-instanceReady) or immediately after being added if the editor is already initialized.
+* [#9796](http://dev.ckeditor.com/ticket/9796): Introduced `<s>` as a default tag for strikethrough, which replaces obsolete `<strike>` in HTML5.
+
+## CKEditor 4.0.3
+
+Fixed Issues:
+
+* [#10196](http://dev.ckeditor.com/ticket/10196): Fixed context menus not opening with keyboard shortcuts when [Autogrow](http://ckeditor.com/addon/autogrow) is enabled.
+* [#10212](http://dev.ckeditor.com/ticket/10212): [IE7-10] Undo command throws errors after multiple switches between Source and WYSIWYG view.
+* [#10219](http://dev.ckeditor.com/ticket/10219): [Inline editor] Error thrown after calling [`editor.destroy()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-destroy).
+
+## CKEditor 4.0.2
+
+Fixed Issues:
+
+* [#9779](http://dev.ckeditor.com/ticket/9779): Fixed overriding [`CKEDITOR.getUrl()`](http://docs.ckeditor.com/#!/api/CKEDITOR-method-getUrl) with `CKEDITOR_GETURL`.
+* [#9772](http://dev.ckeditor.com/ticket/9772): Custom buttons in the dialog window footer have different look and size ([Moono](http://ckeditor.com/addon/moono), [Kama](http://ckeditor.com/addon/kama) skins).
+* [#9029](http://dev.ckeditor.com/ticket/9029): Custom styles added with the [`stylesSet.add()`](http://docs.ckeditor.com/#!/api/CKEDITOR.stylesSet-method-add) are displayed in the wrong order.
+* [#9887](http://dev.ckeditor.com/ticket/9887): Disable [Magic Line](http://ckeditor.com/addon/magicline) when [`editor.readOnly`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-property-readOnly) is set.
+* [#9882](http://dev.ckeditor.com/ticket/9882): Fixed empty document title on [`editor.getData()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData) if set via the Document Properties dialog window.
+* [#9773](http://dev.ckeditor.com/ticket/9773): Fixed rendering problems with selection fields in the Kama skin.
+* [#9851](http://dev.ckeditor.com/ticket/9851): The [`selectionChange`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-event-selectionChange) event is not fired when mouse selection ended outside editable.
+* [#9903](http://dev.ckeditor.com/ticket/9903): [Inline editor] Bad positioning of floating space with page horizontal scroll.
+* [#9872](http://dev.ckeditor.com/ticket/9872): [`editor.checkDirty()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty) returns `true` when called onload. Removed the obsolete `editor.mayBeDirty` flag.
+* [#9893](http://dev.ckeditor.com/ticket/9893): [IE] Fixed broken toolbar when editing mixed direction content in Quirks mode.
+* [#9845](http://dev.ckeditor.com/ticket/9845): Fixed TAB navigation in the [Link](http://ckeditor.com/addon/link) dialog window when the Anchor option is used and no anchors are available.
+* [#9883](http://dev.ckeditor.com/ticket/9883): Maximizing was making the entire page editable with [divarea](http://ckeditor.com/addon/divarea)-based editors.
+* [#9940](http://dev.ckeditor.com/ticket/9940): [Firefox] Navigating back to a page with the editor was making the entire page editable.
+* [#9966](http://dev.ckeditor.com/ticket/9966): Fixed: Unable to type square brackets with French keyboard layout. Changed [Magic Line](http://ckeditor.com/addon/magicline) keystrokes.
+* [#9507](http://dev.ckeditor.com/ticket/9507): [Firefox] Selection is moved before editable position when the editor is focused for the first time.
+* [#9947](http://dev.ckeditor.com/ticket/9947): [WebKit] Editor overflows parent container in some edge cases.
+* [#10105](http://dev.ckeditor.com/ticket/10105): Fixed: Broken [sourcearea](http://ckeditor.com/addon/sourcearea) view when an RTL language is set.
+* [#10123](http://dev.ckeditor.com/ticket/10123): [WebKit] Fixed: Several dialog windows have broken layout since the latest WebKit release.
+* [#10152](http://dev.ckeditor.com/ticket/10152): Fixed: Invalid ARIA property used on menu items.
+
+## CKEditor 4.0.1.1
+
+Fixed Issues:
+
+* Security update: Added protection against XSS attack and possible path disclosure in the PHP sample.
+
+## CKEditor 4.0.1
+
+Fixed Issues:
+
+* [#9655](http://dev.ckeditor.com/ticket/9655): Support for IE Quirks Mode in the new [Moono skin](http://ckeditor.com/addon/moono).
+* Accessibility issues (mainly in inline editor): [#9364](http://dev.ckeditor.com/ticket/9364), [#9368](http://dev.ckeditor.com/ticket/9368), [#9369](http://dev.ckeditor.com/ticket/9369), [#9370](http://dev.ckeditor.com/ticket/9370), [#9541](http://dev.ckeditor.com/ticket/9541), [#9543](http://dev.ckeditor.com/ticket/9543), [#9841](http://dev.ckeditor.com/ticket/9841), [#9844](http://dev.ckeditor.com/ticket/9844).
+* [Magic Line](http://ckeditor.com/addon/magicline) plugin:
+    * [#9481](http://dev.ckeditor.com/ticket/9481): Added accessibility support for Magic Line.
+    * [#9509](http://dev.ckeditor.com/ticket/9509): Added Magic Line support for forms.
+    * [#9573](http://dev.ckeditor.com/ticket/9573): Magic Line does not disappear on `mouseout` in a specific case.
+* [#9754](http://dev.ckeditor.com/ticket/9754): [WebKit] Cutting & pasting simple unformatted text generates an inline wrapper in WebKit browsers.
+* [#9456](http://dev.ckeditor.com/ticket/9456): [Chrome] Properly paste bullet list style from MS Word.
+* [#9699](http://dev.ckeditor.com/ticket/9699), [#9758](http://dev.ckeditor.com/ticket/9758): Improved selection locking when selecting by dragging.
+* Context menu:
+    * [#9712](http://dev.ckeditor.com/ticket/9712): Opening the context menu destroys editor focus.
+    * [#9366](http://dev.ckeditor.com/ticket/9366): Context menu should be displayed over the floating toolbar.
+    * [#9706](http://dev.ckeditor.com/ticket/9706): Context menu generates a JavaScript error in inline mode when the editor is attached to a header element.
+* [#9800](http://dev.ckeditor.com/ticket/9800): Hide float panel when resizing the window.
+* [#9721](http://dev.ckeditor.com/ticket/9721): Padding in content of div-based editor puts the editing area under the bottom UI space.
+* [#9528](http://dev.ckeditor.com/ticket/9528): Host page `box-sizing` style should not influence the editor UI elements.
+* [#9503](http://dev.ckeditor.com/ticket/9503): [Form Elements](http://ckeditor.com/addon/forms) plugin adds context menu listeners only on supported input types. Added support for `tel`, `email`, `search` and `url` input types.
+* [#9769](http://dev.ckeditor.com/ticket/9769): Improved floating toolbar positioning in a narrow window.
+* [#9875](http://dev.ckeditor.com/ticket/9875): Table dialog window does not populate width correctly.
+* [#8675](http://dev.ckeditor.com/ticket/8675): Deleting cells in a nested table removes the outer table cell.
+* [#9815](http://dev.ckeditor.com/ticket/9815): Cannot edit dialog window fields in an editor initialized in the jQuery UI modal dialog.
+* [#8888](http://dev.ckeditor.com/ticket/8888): CKEditor dialog windows do not show completely in a small window.
+* [#9360](http://dev.ckeditor.com/ticket/9360): [Inline editor] Blocks shown for a `<div>` element stay permanently even after the user exits editing the `<div>`.
+* [#9531](http://dev.ckeditor.com/ticket/9531): [Firefox & Inline editor] Toolbar is lost when closing the Format drop-down list by clicking its button.
+* [#9553](http://dev.ckeditor.com/ticket/9553): Table width incorrectly set when the `border-width` style is specified.
+* [#9594](http://dev.ckeditor.com/ticket/9594): Cannot tab past CKEditor when it is in read-only mode.
+* [#9658](http://dev.ckeditor.com/ticket/9658): [IE9] Justify not working on selected images.
+* [#9686](http://dev.ckeditor.com/ticket/9686): Added missing contents styles for `<pre>` elements.
+* [#9709](http://dev.ckeditor.com/ticket/9709): [Paste from Word](http://ckeditor.com/addon/pastefromword) should not depend on configuration from other styles.
+* [#9726](http://dev.ckeditor.com/ticket/9726): Removed [Color Dialog](http://ckeditor.com/addon/colordialog) plugin dependency from [Table Tools](http://ckeditor.com/addon/tabletools).
+* [#9765](http://dev.ckeditor.com/ticket/9765): Toolbar Collapse command documented incorrectly in the [Accessibility Instructions](http://ckeditor.com/addon/a11yhelp) dialog window.
+* [#9771](http://dev.ckeditor.com/ticket/9771): [WebKit & Opera] Fixed scrolling issues when pasting.
+* [#9787](http://dev.ckeditor.com/ticket/9787): [IE9] `onChange` is not fired for checkboxes in dialogs.
+* [#9842](http://dev.ckeditor.com/ticket/9842): [Firefox 17] When opening a toolbar menu for the first time and pressing the *Down Arrow* key, focus goes to the next toolbar button instead of the menu options.
+* [#9847](http://dev.ckeditor.com/ticket/9847): [Elements Path](http://ckeditor.com/addon/elementspath) should not be initialized in the inline editor.
+* [#9853](http://dev.ckeditor.com/ticket/9853): [`editor.addRemoveFormatFilter()`](http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-addRemoveFormatFilter) is exposed before it really works.
+* [#8893](http://dev.ckeditor.com/ticket/8893): Value of the [`pasteFromWordCleanupFile`](http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-pasteFromWordCleanupFile) configuration option is now taken from the instance configuration.
+* [#9693](http://dev.ckeditor.com/ticket/9693): Removed "Live Preview" checkbox from UI color picker.
+
+
+## CKEditor 4.0
+
+The first stable release of the new CKEditor 4 code line.
+
+The CKEditor JavaScript API has been kept compatible with CKEditor 4, whenever
+possible. The list of relevant changes can be found in the [API Changes page of
+the CKEditor 4 documentation][1].
+
+[1]: http://docs.ckeditor.com/#!/guide/dev_api_changes "API Changes"
diff --git a/sources/LICENSE.md b/sources/LICENSE.md
new file mode 100644 (file)
index 0000000..0f50a9e
--- /dev/null
@@ -0,0 +1,1641 @@
+Software License Agreement
+==========================
+
+CKEditor - The text editor for Internet - http://ckeditor.com
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+
+Licensed under the terms of any of the following licenses at your
+choice:
+
+ - GNU General Public License Version 2 or later (the "GPL")
+   http://www.gnu.org/licenses/gpl.html
+   (See Appendix A)
+
+ - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+   http://www.gnu.org/licenses/lgpl.html
+   (See Appendix B)
+
+ - Mozilla Public License Version 1.1 or later (the "MPL")
+   http://www.mozilla.org/MPL/MPL-1.1.html
+   (See Appendix C)
+
+You are not required to, but if you want to explicitly declare the
+license you have chosen to be bound to when using, reproducing,
+modifying and distributing this software, just include a text file
+titled "legal.txt" in your version of this software, indicating your
+license choice. In any case, your choice will not restrict any
+recipient of your version of this software to use, reproduce, modify
+and distribute this software under any of the above licenses.
+
+Sources of Intellectual Property Included in CKEditor
+-----------------------------------------------------
+
+Where not otherwise indicated, all CKEditor content is authored by
+CKSource engineers and consists of CKSource-owned intellectual
+property. In some specific instances, CKEditor will incorporate work
+done by developers outside of CKSource with their express permission.
+
+The following libraries are included in CKEditor under the MIT license (see Appendix D):
+
+* CKSource Samples Framework (included in the samples) - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* PicoModal (included in `samples/js/sf.js`) - Copyright (c) 2012 James Frasca.
+* CodeMirror (included in the samples) - Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others.
+
+Parts of code taken from the following libraries are included in CKEditor under the MIT license (see Appendix D):
+
+* jQuery (inspired the domReady function, ckeditor_base.js) - Copyright (c) 2011 John Resig, http://jquery.com/
+
+The following libraries are included in CKEditor under the SIL Open Font License, Version 1.1 (see Appendix E):
+
+* Font Awesome (included in the toolbar configurator) - Copyright (C) 2012 by Dave Gandy.
+
+The following libraries are included in CKEditor under the BSD-3 License (see Appendix F):
+
+* highlight.js (included in the `codesnippet` plugin) - Copyright (c) 2006, Ivan Sagalaev.
+* YUI Library (included in the `uicolor` plugin) - Copyright (c) 2009, Yahoo! Inc.
+
+(Ignore this line: %REMOVE_START%)
+
+The following libraries are included only in the development version of CKEditor under the MIT license (see Appendix D):
+
+* CKBuilder - Copyright (c) 2012-2017, CKSource - Frederico Knabben.
+* CKLangTool - Copyright (c) 2012-2017, CKSource - Frederico Knabben.
+* Optimist - Copyright 2010 James Halliday (mail@substack.net).
+* Q - Copyright 2009–2014 Kristopher Michael Kowal.
+* Tmp - Copyright (c) 2014 KARASZI István.
+* Mkdirp - Copyright 2010 James Halliday (mail@substack.net).
+* Bender.js - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* benderjs-coverage - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* benderjs-jquery - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* benderjs-sinon - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* benderjs-yui - Copyright (c) 2014-2017, CKSource - Frederico Knabben.
+* Grunt - Copyright (c) 2015 "Cowboy" Ben Alman.
+* grunt-contrib-imagemin - Copyright (c) 2014 Sindre Sorhus, contributors.
+* grunt-jscs - Copyright (c) 2014 Gustavo Henke, contributors.
+* grunt-contrib-jshint - Copyright (c) 2014 "Cowboy" Ben Alman, contributors.
+* grunt-contrib-less - Copyright (c) 2014 Tyler Kellen, contributors.
+* grunt-contrib-watch - Copyright (c) 2014 "Cowboy" Ben Alman, contributors.
+* grunt-contrib-concat - Copyright (c) 2014 "Cowboy" Ben Alman, contributors.
+* grunt-jsduck - Copyright (c) 2012 Dmitry Pashkevich, contributors.
+* grunt-githooks - Copyright (c) 2013 Romaric Pascal.
+* jQuery Form Plugin (used in jquery adapter test) - Copyright (c) 2012 M. Alsup
+
+The following libraries are included only in the development version of CKEditor under the BSD-3 License (see Appendix F):
+
+* ShellJS - Copyright (c) 2012, Artur Adib <aadib@mozilla.com>.
+
+The following libraries are included only in the development version of CKEditor under the Apache License (see Appendix G):
+
+* Less.js - Copyright (c) 2009-2014 Alexis Sellier & The Core Less Team.
+
+(Ignore this line: %REMOVE_END%)
+
+Trademarks
+----------
+
+CKEditor is a trademark of CKSource - Frederico Knabben. All other brand
+and product names are trademarks, registered trademarks or service
+marks of their respective holders.
+
+---
+
+Appendix A: The GPL License
+---------------------------
+
+```
+GNU GENERAL PUBLIC LICENSE
+Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software-to make sure the software is free for all its users.  This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it.  (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.)  You can apply it to
+your programs, too.
+
+  When we speak of free software, we are referring to freedom, not
+price.  Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+  To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+  For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have.  You must make sure that they, too, receive or can get the
+source code.  And you must show them these terms so they know their
+rights.
+
+  We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+  Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software.  If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+  Finally, any free program is threatened constantly by software
+patents.  We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary.  To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.
+
+GNU GENERAL PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License.  The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language.  (Hereinafter, translation is included without limitation in
+the term "modification".)  Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+  1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+  2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) You must cause the modified files to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    b) You must cause any work that you distribute or publish, that in
+    whole or in part contains or is derived from the Program or any
+    part thereof, to be licensed as a whole at no charge to all third
+    parties under the terms of this License.
+
+    c) If the modified program normally reads commands interactively
+    when run, you must cause it, when started running for such
+    interactive use in the most ordinary way, to print or display an
+    announcement including an appropriate copyright notice and a
+    notice that there is no warranty (or else, saying that you provide
+    a warranty) and that users may redistribute the program under
+    these conditions, and telling the user how to view a copy of this
+    License.  (Exception: if the Program itself is interactive but
+    does not normally print such an announcement, your work based on
+    the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+    a) Accompany it with the complete corresponding machine-readable
+    source code, which must be distributed under the terms of Sections
+    1 and 2 above on a medium customarily used for software interchange; or,
+
+    b) Accompany it with a written offer, valid for at least three
+    years, to give any third party, for a charge no more than your
+    cost of physically performing source distribution, a complete
+    machine-readable copy of the corresponding source code, to be
+    distributed under the terms of Sections 1 and 2 above on a medium
+    customarily used for software interchange; or,
+
+    c) Accompany it with the information you received as to the offer
+    to distribute corresponding source code.  (This alternative is
+    allowed only for noncommercial distribution and only if you
+    received the program in object code or executable form with such
+    an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it.  For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable.  However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License.  Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+  5. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Program or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+  6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+  7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded.  In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+  9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time.  Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation.  If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+  10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission.  For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this.  Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+NO WARRANTY
+
+  11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW.  EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.  THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU.  SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+  12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+END OF TERMS AND CONDITIONS
+```
+
+Appendix B: The LGPL License
+----------------------------
+
+```
+GNU LESSER GENERAL PUBLIC LICENSE
+Version 2.1, February 1999
+
+ Copyright (C) 1991, 1999 Free Software Foundation, Inc.
+     59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+[This is the first released version of the Lesser GPL.  It also counts
+ as the successor of the GNU Library Public License, version 2, hence
+ the version number 2.1.]
+
+Preamble
+
+  The licenses for most software are designed to take away your
+freedom to share and change it.  By contrast, the GNU General Public
+Licenses are intended to guarantee your freedom to share and change
+free software-to make sure the software is free for all its users.
+
+  This license, the Lesser General Public License, applies to some
+specially designated software packages-typically libraries-of the
+Free Software Foundation and other authors who decide to use it.  You
+can use it too, but we suggest you first think carefully about whether
+this license or the ordinary General Public License is the better
+strategy to use in any particular case, based on the explanations below.
+
+  When we speak of free software, we are referring to freedom of use,
+not price.  Our General Public Licenses are designed to make sure that
+you have the freedom to distribute copies of free software (and charge
+for this service if you wish); that you receive source code or can get
+it if you want it; that you can change the software and use pieces of
+it in new free programs; and that you are informed that you can do
+these things.
+
+  To protect your rights, we need to make restrictions that forbid
+distributors to deny you these rights or to ask you to surrender these
+rights.  These restrictions translate to certain responsibilities for
+you if you distribute copies of the library or if you modify it.
+
+  For example, if you distribute copies of the library, whether gratis
+or for a fee, you must give the recipients all the rights that we gave
+you.  You must make sure that they, too, receive or can get the source
+code.  If you link other code with the library, you must provide
+complete object files to the recipients, so that they can relink them
+with the library after making changes to the library and recompiling
+it.  And you must show them these terms so they know their rights.
+
+  We protect your rights with a two-step method: (1) we copyright the
+library, and (2) we offer you this license, which gives you legal
+permission to copy, distribute and/or modify the library.
+
+  To protect each distributor, we want to make it very clear that
+there is no warranty for the free library.  Also, if the library is
+modified by someone else and passed on, the recipients should know
+that what they have is not the original version, so that the original
+author's reputation will not be affected by problems that might be
+introduced by others.
+
+  Finally, software patents pose a constant threat to the existence of
+any free program.  We wish to make sure that a company cannot
+effectively restrict the users of a free program by obtaining a
+restrictive license from a patent holder.  Therefore, we insist that
+any patent license obtained for a version of the library must be
+consistent with the full freedom of use specified in this license.
+
+  Most GNU software, including some libraries, is covered by the
+ordinary GNU General Public License.  This license, the GNU Lesser
+General Public License, applies to certain designated libraries, and
+is quite different from the ordinary General Public License.  We use
+this license for certain libraries in order to permit linking those
+libraries into non-free programs.
+
+  When a program is linked with a library, whether statically or using
+a shared library, the combination of the two is legally speaking a
+combined work, a derivative of the original library.  The ordinary
+General Public License therefore permits such linking only if the
+entire combination fits its criteria of freedom.  The Lesser General
+Public License permits more lax criteria for linking other code with
+the library.
+
+  We call this license the "Lesser" General Public License because it
+does Less to protect the user's freedom than the ordinary General
+Public License.  It also provides other free software developers Less
+of an advantage over competing non-free programs.  These disadvantages
+are the reason we use the ordinary General Public License for many
+libraries.  However, the Lesser license provides advantages in certain
+special circumstances.
+
+  For example, on rare occasions, there may be a special need to
+encourage the widest possible use of a certain library, so that it becomes
+a de-facto standard.  To achieve this, non-free programs must be
+allowed to use the library.  A more frequent case is that a free
+library does the same job as widely used non-free libraries.  In this
+case, there is little to gain by limiting the free library to free
+software only, so we use the Lesser General Public License.
+
+  In other cases, permission to use a particular library in non-free
+programs enables a greater number of people to use a large body of
+free software.  For example, permission to use the GNU C Library in
+non-free programs enables many more people to use the whole GNU
+operating system, as well as its variant, the GNU/Linux operating
+system.
+
+  Although the Lesser General Public License is Less protective of the
+users' freedom, it does ensure that the user of a program that is
+linked with the Library has the freedom and the wherewithal to run
+that program using a modified version of the Library.
+
+  The precise terms and conditions for copying, distribution and
+modification follow.  Pay close attention to the difference between a
+"work based on the library" and a "work that uses the library".  The
+former contains code derived from the library, whereas the latter must
+be combined with the library in order to run.
+
+GNU LESSER GENERAL PUBLIC LICENSE
+TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+  0. This License Agreement applies to any software library or other
+program which contains a notice placed by the copyright holder or
+other authorized party saying it may be distributed under the terms of
+this Lesser General Public License (also called "this License").
+Each licensee is addressed as "you".
+
+  A "library" means a collection of software functions and/or data
+prepared so as to be conveniently linked with application programs
+(which use some of those functions and data) to form executables.
+
+  The "Library", below, refers to any such software library or work
+which has been distributed under these terms.  A "work based on the
+Library" means either the Library or any derivative work under
+copyright law: that is to say, a work containing the Library or a
+portion of it, either verbatim or with modifications and/or translated
+straightforwardly into another language.  (Hereinafter, translation is
+included without limitation in the term "modification".)
+
+  "Source code" for a work means the preferred form of the work for
+making modifications to it.  For a library, complete source code means
+all the source code for all modules it contains, plus any associated
+interface definition files, plus the scripts used to control compilation
+and installation of the library.
+
+  Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope.  The act of
+running a program using the Library is not restricted, and output from
+such a program is covered only if its contents constitute a work based
+on the Library (independent of the use of the Library in a tool for
+writing it).  Whether that is true depends on what the Library does
+and what the program that uses the Library does.
+
+  1. You may copy and distribute verbatim copies of the Library's
+complete source code as you receive it, in any medium, provided that
+you conspicuously and appropriately publish on each copy an
+appropriate copyright notice and disclaimer of warranty; keep intact
+all the notices that refer to this License and to the absence of any
+warranty; and distribute a copy of this License along with the
+Library.
+
+  You may charge a fee for the physical act of transferring a copy,
+and you may at your option offer warranty protection in exchange for a
+fee.
+
+  2. You may modify your copy or copies of the Library or any portion
+of it, thus forming a work based on the Library, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+    a) The modified work must itself be a software library.
+
+    b) You must cause the files modified to carry prominent notices
+    stating that you changed the files and the date of any change.
+
+    c) You must cause the whole of the work to be licensed at no
+    charge to all third parties under the terms of this License.
+
+    d) If a facility in the modified Library refers to a function or a
+    table of data to be supplied by an application program that uses
+    the facility, other than as an argument passed when the facility
+    is invoked, then you must make a good faith effort to ensure that,
+    in the event an application does not supply such function or
+    table, the facility still operates, and performs whatever part of
+    its purpose remains meaningful.
+
+    (For example, a function in a library to compute square roots has
+    a purpose that is entirely well-defined independent of the
+    application.  Therefore, Subsection 2d requires that any
+    application-supplied function or table used by this function must
+    be optional: if the application does not supply it, the square
+    root function must still compute square roots.)
+
+These requirements apply to the modified work as a whole.  If
+identifiable sections of that work are not derived from the Library,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works.  But when you
+distribute the same sections as part of a whole which is a work based
+on the Library, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote
+it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Library.
+
+In addition, mere aggregation of another work not based on the Library
+with the Library (or with a work based on the Library) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+  3. You may opt to apply the terms of the ordinary GNU General Public
+License instead of this License to a given copy of the Library.  To do
+this, you must alter all the notices that refer to this License, so
+that they refer to the ordinary GNU General Public License, version 2,
+instead of to this License.  (If a newer version than version 2 of the
+ordinary GNU General Public License has appeared, then you can specify
+that version instead if you wish.)  Do not make any other change in
+these notices.
+
+  Once this change is made in a given copy, it is irreversible for
+that copy, so the ordinary GNU General Public License applies to all
+subsequent copies and derivative works made from that copy.
+
+  This option is useful when you wish to copy part of the code of
+the Library into a program that is not a library.
+
+  4. You may copy and distribute the Library (or a portion or
+derivative of it, under Section 2) in object code or executable form
+under the terms of Sections 1 and 2 above provided that you accompany
+it with the complete corresponding machine-readable source code, which
+must be distributed under the terms of Sections 1 and 2 above on a
+medium customarily used for software interchange.
+
+  If distribution of object code is made by offering access to copy
+from a designated place, then offering equivalent access to copy the
+source code from the same place satisfies the requirement to
+distribute the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+  5. A program that contains no derivative of any portion of the
+Library, but is designed to work with the Library by being compiled or
+linked with it, is called a "work that uses the Library".  Such a
+work, in isolation, is not a derivative work of the Library, and
+therefore falls outside the scope of this License.
+
+  However, linking a "work that uses the Library" with the Library
+creates an executable that is a derivative of the Library (because it
+contains portions of the Library), rather than a "work that uses the
+library".  The executable is therefore covered by this License.
+Section 6 states terms for distribution of such executables.
+
+  When a "work that uses the Library" uses material from a header file
+that is part of the Library, the object code for the work may be a
+derivative work of the Library even though the source code is not.
+Whether this is true is especially significant if the work can be
+linked without the Library, or if the work is itself a library.  The
+threshold for this to be true is not precisely defined by law.
+
+  If such an object file uses only numerical parameters, data
+structure layouts and accessors, and small macros and small inline
+functions (ten lines or less in length), then the use of the object
+file is unrestricted, regardless of whether it is legally a derivative
+work.  (Executables containing this object code plus portions of the
+Library will still fall under Section 6.)
+
+  Otherwise, if the work is a derivative of the Library, you may
+distribute the object code for the work under the terms of Section 6.
+Any executables containing that work also fall under Section 6,
+whether or not they are linked directly with the Library itself.
+
+  6. As an exception to the Sections above, you may also combine or
+link a "work that uses the Library" with the Library to produce a
+work containing portions of the Library, and distribute that work
+under terms of your choice, provided that the terms permit
+modification of the work for the customer's own use and reverse
+engineering for debugging such modifications.
+
+  You must give prominent notice with each copy of the work that the
+Library is used in it and that the Library and its use are covered by
+this License.  You must supply a copy of this License.  If the work
+during execution displays copyright notices, you must include the
+copyright notice for the Library among them, as well as a reference
+directing the user to the copy of this License.  Also, you must do one
+of these things:
+
+    a) Accompany the work with the complete corresponding
+    machine-readable source code for the Library including whatever
+    changes were used in the work (which must be distributed under
+    Sections 1 and 2 above); and, if the work is an executable linked
+    with the Library, with the complete machine-readable "work that
+    uses the Library", as object code and/or source code, so that the
+    user can modify the Library and then relink to produce a modified
+    executable containing the modified Library.  (It is understood
+    that the user who changes the contents of definitions files in the
+    Library will not necessarily be able to recompile the application
+    to use the modified definitions.)
+
+    b) Use a suitable shared library mechanism for linking with the
+    Library.  A suitable mechanism is one that (1) uses at run time a
+    copy of the library already present on the user's computer system,
+    rather than copying library functions into the executable, and (2)
+    will operate properly with a modified version of the library, if
+    the user installs one, as long as the modified version is
+    interface-compatible with the version that the work was made with.
+
+    c) Accompany the work with a written offer, valid for at
+    least three years, to give the same user the materials
+    specified in Subsection 6a, above, for a charge no more
+    than the cost of performing this distribution.
+
+    d) If distribution of the work is made by offering access to copy
+    from a designated place, offer equivalent access to copy the above
+    specified materials from the same place.
+
+    e) Verify that the user has already received a copy of these
+    materials or that you have already sent this user a copy.
+
+  For an executable, the required form of the "work that uses the
+Library" must include any data and utility programs needed for
+reproducing the executable from it.  However, as a special exception,
+the materials to be distributed need not include anything that is
+normally distributed (in either source or binary form) with the major
+components (compiler, kernel, and so on) of the operating system on
+which the executable runs, unless that component itself accompanies
+the executable.
+
+  It may happen that this requirement contradicts the license
+restrictions of other proprietary libraries that do not normally
+accompany the operating system.  Such a contradiction means you cannot
+use both them and the Library together in an executable that you
+distribute.
+
+  7. You may place library facilities that are a work based on the
+Library side-by-side in a single library together with other library
+facilities not covered by this License, and distribute such a combined
+library, provided that the separate distribution of the work based on
+the Library and of the other library facilities is otherwise
+permitted, and provided that you do these two things:
+
+    a) Accompany the combined library with a copy of the same work
+    based on the Library, uncombined with any other library
+    facilities.  This must be distributed under the terms of the
+    Sections above.
+
+    b) Give prominent notice with the combined library of the fact
+    that part of it is a work based on the Library, and explaining
+    where to find the accompanying uncombined form of the same work.
+
+  8. You may not copy, modify, sublicense, link with, or distribute
+the Library except as expressly provided under this License.  Any
+attempt otherwise to copy, modify, sublicense, link with, or
+distribute the Library is void, and will automatically terminate your
+rights under this License.  However, parties who have received copies,
+or rights, from you under this License will not have their licenses
+terminated so long as such parties remain in full compliance.
+
+  9. You are not required to accept this License, since you have not
+signed it.  However, nothing else grants you permission to modify or
+distribute the Library or its derivative works.  These actions are
+prohibited by law if you do not accept this License.  Therefore, by
+modifying or distributing the Library (or any work based on the
+Library), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Library or works based on it.
+
+  10. Each time you redistribute the Library (or any work based on the
+Library), the recipient automatically receives a license from the
+original licensor to copy, distribute, link with or modify the Library
+subject to these terms and conditions.  You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties with
+this License.
+
+  11. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License.  If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Library at all.  For example, if a patent
+license would not permit royalty-free redistribution of the Library by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Library.
+
+If any portion of this section is held invalid or unenforceable under any
+particular circumstance, the balance of the section is intended to apply,
+and the section as a whole is intended to apply in other circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system which is
+implemented by public license practices.  Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+  12. If the distribution and/or use of the Library is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Library under this License may add
+an explicit geographical distribution limitation excluding those countries,
+so that distribution is permitted only in or among countries not thus
+excluded.  In such case, this License incorporates the limitation as if
+written in the body of this License.
+
+  13. The Free Software Foundation may publish revised and/or new
+versions of the Lesser General Public License from time to time.
+Such new versions will be similar in spirit to the present version,
+but may differ in detail to address new problems or concerns.
+
+Each version is given a distinguishing version number.  If the Library
+specifies a version number of this License which applies to it and
+"any later version", you have the option of following the terms and
+conditions either of that version or of any later version published by
+the Free Software Foundation.  If the Library does not specify a
+license version number, you may choose any version ever published by
+the Free Software Foundation.
+
+  14. If you wish to incorporate parts of the Library into other free
+programs whose distribution conditions are incompatible with these,
+write to the author to ask for permission.  For software which is
+copyrighted by the Free Software Foundation, write to the Free
+Software Foundation; we sometimes make exceptions for this.  Our
+decision will be guided by the two goals of preserving the free status
+of all derivatives of our free software and of promoting the sharing
+and reuse of software generally.
+
+NO WARRANTY
+
+  15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO
+WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW.
+EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR
+OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY
+KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+PURPOSE.  THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
+LIBRARY IS WITH YOU.  SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME
+THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
+
+  16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN
+WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY
+AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU
+FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR
+CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE
+LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING
+RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A
+FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF
+SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGES.
+
+END OF TERMS AND CONDITIONS
+```
+
+Appendix C: The MPL License
+---------------------------
+
+```
+MOZILLA PUBLIC LICENSE
+Version 1.1
+
+1. Definitions.
+
+     1.0.1. "Commercial Use" means distribution or otherwise making the
+     Covered Code available to a third party.
+
+     1.1. "Contributor" means each entity that creates or contributes to
+     the creation of Modifications.
+
+     1.2. "Contributor Version" means the combination of the Original
+     Code, prior Modifications used by a Contributor, and the Modifications
+     made by that particular Contributor.
+
+     1.3. "Covered Code" means the Original Code or Modifications or the
+     combination of the Original Code and Modifications, in each case
+     including portions thereof.
+
+     1.4. "Electronic Distribution Mechanism" means a mechanism generally
+     accepted in the software development community for the electronic
+     transfer of data.
+
+     1.5. "Executable" means Covered Code in any form other than Source
+     Code.
+
+     1.6. "Initial Developer" means the individual or entity identified
+     as the Initial Developer in the Source Code notice required by Exhibit
+     A.
+
+     1.7. "Larger Work" means a work which combines Covered Code or
+     portions thereof with code not governed by the terms of this License.
+
+     1.8. "License" means this document.
+
+     1.8.1. "Licensable" means having the right to grant, to the maximum
+     extent possible, whether at the time of the initial grant or
+     subsequently acquired, any and all of the rights conveyed herein.
+
+     1.9. "Modifications" means any addition to or deletion from the
+     substance or structure of either the Original Code or any previous
+     Modifications. When Covered Code is released as a series of files, a
+     Modification is:
+          A. Any addition to or deletion from the contents of a file
+          containing Original Code or previous Modifications.
+
+          B. Any new file that contains any part of the Original Code or
+          previous Modifications.
+
+     1.10. "Original Code" means Source Code of computer software code
+     which is described in the Source Code notice required by Exhibit A as
+     Original Code, and which, at the time of its release under this
+     License is not already Covered Code governed by this License.
+
+     1.10.1. "Patent Claims" means any patent claim(s), now owned or
+     hereafter acquired, including without limitation,  method, process,
+     and apparatus claims, in any patent Licensable by grantor.
+
+     1.11. "Source Code" means the preferred form of the Covered Code for
+     making modifications to it, including all modules it contains, plus
+     any associated interface definition files, scripts used to control
+     compilation and installation of an Executable, or source code
+     differential comparisons against either the Original Code or another
+     well known, available Covered Code of the Contributor's choice. The
+     Source Code can be in a compressed or archival form, provided the
+     appropriate decompression or de-archiving software is widely available
+     for no charge.
+
+     1.12. "You" (or "Your")  means an individual or a legal entity
+     exercising rights under, and complying with all of the terms of, this
+     License or a future version of this License issued under Section 6.1.
+     For legal entities, "You" includes any entity which controls, is
+     controlled by, or is under common control with You. For purposes of
+     this definition, "control" means (a) the power, direct or indirect,
+     to cause the direction or management of such entity, whether by
+     contract or otherwise, or (b) ownership of more than fifty percent
+     (50%) of the outstanding shares or beneficial ownership of such
+     entity.
+
+2. Source Code License.
+
+     2.1. The Initial Developer Grant.
+     The Initial Developer hereby grants You a world-wide, royalty-free,
+     non-exclusive license, subject to third party intellectual property
+     claims:
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Initial Developer to use, reproduce,
+          modify, display, perform, sublicense and distribute the Original
+          Code (or portions thereof) with or without Modifications, and/or
+          as part of a Larger Work; and
+
+          (b) under Patents Claims infringed by the making, using or
+          selling of Original Code, to make, have made, use, practice,
+          sell, and offer for sale, and/or otherwise dispose of the
+          Original Code (or portions thereof).
+
+          (c) the licenses granted in this Section 2.1(a) and (b) are
+          effective on the date Initial Developer first distributes
+          Original Code under the terms of this License.
+
+          (d) Notwithstanding Section 2.1(b) above, no patent license is
+          granted: 1) for code that You delete from the Original Code; 2)
+          separate from the Original Code;  or 3) for infringements caused
+          by: i) the modification of the Original Code or ii) the
+          combination of the Original Code with other software or devices.
+
+     2.2. Contributor Grant.
+     Subject to third party intellectual property claims, each Contributor
+     hereby grants You a world-wide, royalty-free, non-exclusive license
+
+          (a)  under intellectual property rights (other than patent or
+          trademark) Licensable by Contributor, to use, reproduce, modify,
+          display, perform, sublicense and distribute the Modifications
+          created by such Contributor (or portions thereof) either on an
+          unmodified basis, with other Modifications, as Covered Code
+          and/or as part of a Larger Work; and
+
+          (b) under Patent Claims infringed by the making, using, or
+          selling of  Modifications made by that Contributor either alone
+          and/or in combination with its Contributor Version (or portions
+          of such combination), to make, use, sell, offer for sale, have
+          made, and/or otherwise dispose of: 1) Modifications made by that
+          Contributor (or portions thereof); and 2) the combination of
+          Modifications made by that Contributor with its Contributor
+          Version (or portions of such combination).
+
+          (c) the licenses granted in Sections 2.2(a) and 2.2(b) are
+          effective on the date Contributor first makes Commercial Use of
+          the Covered Code.
+
+          (d)    Notwithstanding Section 2.2(b) above, no patent license is
+          granted: 1) for any code that Contributor has deleted from the
+          Contributor Version; 2)  separate from the Contributor Version;
+          3)  for infringements caused by: i) third party modifications of
+          Contributor Version or ii)  the combination of Modifications made
+          by that Contributor with other software  (except as part of the
+          Contributor Version) or other devices; or 4) under Patent Claims
+          infringed by Covered Code in the absence of Modifications made by
+          that Contributor.
+
+3. Distribution Obligations.
+
+     3.1. Application of License.
+     The Modifications which You create or to which You contribute are
+     governed by the terms of this License, including without limitation
+     Section 2.2. The Source Code version of Covered Code may be
+     distributed only under the terms of this License or a future version
+     of this License released under Section 6.1, and You must include a
+     copy of this License with every copy of the Source Code You
+     distribute. You may not offer or impose any terms on any Source Code
+     version that alters or restricts the applicable version of this
+     License or the recipients' rights hereunder. However, You may include
+     an additional document offering the additional rights described in
+     Section 3.5.
+
+     3.2. Availability of Source Code.
+     Any Modification which You create or to which You contribute must be
+     made available in Source Code form under the terms of this License
+     either on the same media as an Executable version or via an accepted
+     Electronic Distribution Mechanism to anyone to whom you made an
+     Executable version available; and if made available via Electronic
+     Distribution Mechanism, must remain available for at least twelve (12)
+     months after the date it initially became available, or at least six
+     (6) months after a subsequent version of that particular Modification
+     has been made available to such recipients. You are responsible for
+     ensuring that the Source Code version remains available even if the
+     Electronic Distribution Mechanism is maintained by a third party.
+
+     3.3. Description of Modifications.
+     You must cause all Covered Code to which You contribute to contain a
+     file documenting the changes You made to create that Covered Code and
+     the date of any change. You must include a prominent statement that
+     the Modification is derived, directly or indirectly, from Original
+     Code provided by the Initial Developer and including the name of the
+     Initial Developer in (a) the Source Code, and (b) in any notice in an
+     Executable version or related documentation in which You describe the
+     origin or ownership of the Covered Code.
+
+     3.4. Intellectual Property Matters
+          (a) Third Party Claims.
+          If Contributor has knowledge that a license under a third party's
+          intellectual property rights is required to exercise the rights
+          granted by such Contributor under Sections 2.1 or 2.2,
+          Contributor must include a text file with the Source Code
+          distribution titled "LEGAL" which describes the claim and the
+          party making the claim in sufficient detail that a recipient will
+          know whom to contact. If Contributor obtains such knowledge after
+          the Modification is made available as described in Section 3.2,
+          Contributor shall promptly modify the LEGAL file in all copies
+          Contributor makes available thereafter and shall take other steps
+          (such as notifying appropriate mailing lists or newsgroups)
+          reasonably calculated to inform those who received the Covered
+          Code that new knowledge has been obtained.
+
+          (b) Contributor APIs.
+          If Contributor's Modifications include an application programming
+          interface and Contributor has knowledge of patent licenses which
+          are reasonably necessary to implement that API, Contributor must
+          also include this information in the LEGAL file.
+
+               (c)    Representations.
+          Contributor represents that, except as disclosed pursuant to
+          Section 3.4(a) above, Contributor believes that Contributor's
+          Modifications are Contributor's original creation(s) and/or
+          Contributor has sufficient rights to grant the rights conveyed by
+          this License.
+
+     3.5. Required Notices.
+     You must duplicate the notice in Exhibit A in each file of the Source
+     Code.  If it is not possible to put such notice in a particular Source
+     Code file due to its structure, then You must include such notice in a
+     location (such as a relevant directory) where a user would be likely
+     to look for such a notice.  If You created one or more Modification(s)
+     You may add your name as a Contributor to the notice described in
+     Exhibit A.  You must also duplicate this License in any documentation
+     for the Source Code where You describe recipients' rights or ownership
+     rights relating to Covered Code.  You may choose to offer, and to
+     charge a fee for, warranty, support, indemnity or liability
+     obligations to one or more recipients of Covered Code. However, You
+     may do so only on Your own behalf, and not on behalf of the Initial
+     Developer or any Contributor. You must make it absolutely clear than
+     any such warranty, support, indemnity or liability obligation is
+     offered by You alone, and You hereby agree to indemnify the Initial
+     Developer and every Contributor for any liability incurred by the
+     Initial Developer or such Contributor as a result of warranty,
+     support, indemnity or liability terms You offer.
+
+     3.6. Distribution of Executable Versions.
+     You may distribute Covered Code in Executable form only if the
+     requirements of Section 3.1-3.5 have been met for that Covered Code,
+     and if You include a notice stating that the Source Code version of
+     the Covered Code is available under the terms of this License,
+     including a description of how and where You have fulfilled the
+     obligations of Section 3.2. The notice must be conspicuously included
+     in any notice in an Executable version, related documentation or
+     collateral in which You describe recipients' rights relating to the
+     Covered Code. You may distribute the Executable version of Covered
+     Code or ownership rights under a license of Your choice, which may
+     contain terms different from this License, provided that You are in
+     compliance with the terms of this License and that the license for the
+     Executable version does not attempt to limit or alter the recipient's
+     rights in the Source Code version from the rights set forth in this
+     License. If You distribute the Executable version under a different
+     license You must make it absolutely clear that any terms which differ
+     from this License are offered by You alone, not by the Initial
+     Developer or any Contributor. You hereby agree to indemnify the
+     Initial Developer and every Contributor for any liability incurred by
+     the Initial Developer or such Contributor as a result of any such
+     terms You offer.
+
+     3.7. Larger Works.
+     You may create a Larger Work by combining Covered Code with other code
+     not governed by the terms of this License and distribute the Larger
+     Work as a single product. In such a case, You must make sure the
+     requirements of this License are fulfilled for the Covered Code.
+
+4. Inability to Comply Due to Statute or Regulation.
+
+     If it is impossible for You to comply with any of the terms of this
+     License with respect to some or all of the Covered Code due to
+     statute, judicial order, or regulation then You must: (a) comply with
+     the terms of this License to the maximum extent possible; and (b)
+     describe the limitations and the code they affect. Such description
+     must be included in the LEGAL file described in Section 3.4 and must
+     be included with all distributions of the Source Code. Except to the
+     extent prohibited by statute or regulation, such description must be
+     sufficiently detailed for a recipient of ordinary skill to be able to
+     understand it.
+
+5. Application of this License.
+
+     This License applies to code to which the Initial Developer has
+     attached the notice in Exhibit A and to related Covered Code.
+
+6. Versions of the License.
+
+     6.1. New Versions.
+     Netscape Communications Corporation ("Netscape") may publish revised
+     and/or new versions of the License from time to time. Each version
+     will be given a distinguishing version number.
+
+     6.2. Effect of New Versions.
+     Once Covered Code has been published under a particular version of the
+     License, You may always continue to use it under the terms of that
+     version. You may also choose to use such Covered Code under the terms
+     of any subsequent version of the License published by Netscape. No one
+     other than Netscape has the right to modify the terms applicable to
+     Covered Code created under this License.
+
+     6.3. Derivative Works.
+     If You create or use a modified version of this License (which you may
+     only do in order to apply it to code which is not already Covered Code
+     governed by this License), You must (a) rename Your license so that
+     the phrases "Mozilla", "MOZILLAPL", "MOZPL", "Netscape",
+     "MPL", "NPL" or any confusingly similar phrase do not appear in your
+     license (except to note that your license differs from this License)
+     and (b) otherwise make it clear that Your version of the license
+     contains terms which differ from the Mozilla Public License and
+     Netscape Public License. (Filling in the name of the Initial
+     Developer, Original Code or Contributor in the notice described in
+     Exhibit A shall not of themselves be deemed to be modifications of
+     this License.)
+
+7. DISCLAIMER OF WARRANTY.
+
+     COVERED CODE IS PROVIDED UNDER THIS LICENSE ON AN "AS IS" BASIS,
+     WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+     WITHOUT LIMITATION, WARRANTIES THAT THE COVERED CODE IS FREE OF
+     DEFECTS, MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE OR NON-INFRINGING.
+     THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE COVERED CODE
+     IS WITH YOU. SHOULD ANY COVERED CODE PROVE DEFECTIVE IN ANY RESPECT,
+     YOU (NOT THE INITIAL DEVELOPER OR ANY OTHER CONTRIBUTOR) ASSUME THE
+     COST OF ANY NECESSARY SERVICING, REPAIR OR CORRECTION. THIS DISCLAIMER
+     OF WARRANTY CONSTITUTES AN ESSENTIAL PART OF THIS LICENSE. NO USE OF
+     ANY COVERED CODE IS AUTHORIZED HEREUNDER EXCEPT UNDER THIS DISCLAIMER.
+
+8. TERMINATION.
+
+     8.1.  This License and the rights granted hereunder will terminate
+     automatically if You fail to comply with terms herein and fail to cure
+     such breach within 30 days of becoming aware of the breach. All
+     sublicenses to the Covered Code which are properly granted shall
+     survive any termination of this License. Provisions which, by their
+     nature, must remain in effect beyond the termination of this License
+     shall survive.
+
+     8.2.  If You initiate litigation by asserting a patent infringement
+     claim (excluding declatory judgment actions) against Initial Developer
+     or a Contributor (the Initial Developer or Contributor against whom
+     You file such action is referred to as "Participant")  alleging that:
+
+     (a)  such Participant's Contributor Version directly or indirectly
+     infringes any patent, then any and all rights granted by such
+     Participant to You under Sections 2.1 and/or 2.2 of this License
+     shall, upon 60 days notice from Participant terminate prospectively,
+     unless if within 60 days after receipt of notice You either: (i)
+     agree in writing to pay Participant a mutually agreeable reasonable
+     royalty for Your past and future use of Modifications made by such
+     Participant, or (ii) withdraw Your litigation claim with respect to
+     the Contributor Version against such Participant.  If within 60 days
+     of notice, a reasonable royalty and payment arrangement are not
+     mutually agreed upon in writing by the parties or the litigation claim
+     is not withdrawn, the rights granted by Participant to You under
+     Sections 2.1 and/or 2.2 automatically terminate at the expiration of
+     the 60 day notice period specified above.
+
+     (b)  any software, hardware, or device, other than such Participant's
+     Contributor Version, directly or indirectly infringes any patent, then
+     any rights granted to You by such Participant under Sections 2.1(b)
+     and 2.2(b) are revoked effective as of the date You first made, used,
+     sold, distributed, or had made, Modifications made by that
+     Participant.
+
+     8.3.  If You assert a patent infringement claim against Participant
+     alleging that such Participant's Contributor Version directly or
+     indirectly infringes any patent where such claim is resolved (such as
+     by license or settlement) prior to the initiation of patent
+     infringement litigation, then the reasonable value of the licenses
+     granted by such Participant under Sections 2.1 or 2.2 shall be taken
+     into account in determining the amount or value of any payment or
+     license.
+
+     8.4.  In the event of termination under Sections 8.1 or 8.2 above,
+     all end user license agreements (excluding distributors and resellers)
+     which have been validly granted by You or any distributor hereunder
+     prior to termination shall survive termination.
+
+9. LIMITATION OF LIABILITY.
+
+     UNDER NO CIRCUMSTANCES AND UNDER NO LEGAL THEORY, WHETHER TORT
+     (INCLUDING NEGLIGENCE), CONTRACT, OR OTHERWISE, SHALL YOU, THE INITIAL
+     DEVELOPER, ANY OTHER CONTRIBUTOR, OR ANY DISTRIBUTOR OF COVERED CODE,
+     OR ANY SUPPLIER OF ANY OF SUCH PARTIES, BE LIABLE TO ANY PERSON FOR
+     ANY INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES OF ANY
+     CHARACTER INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF GOODWILL,
+     WORK STOPPAGE, COMPUTER FAILURE OR MALFUNCTION, OR ANY AND ALL OTHER
+     COMMERCIAL DAMAGES OR LOSSES, EVEN IF SUCH PARTY SHALL HAVE BEEN
+     INFORMED OF THE POSSIBILITY OF SUCH DAMAGES. THIS LIMITATION OF
+     LIABILITY SHALL NOT APPLY TO LIABILITY FOR DEATH OR PERSONAL INJURY
+     RESULTING FROM SUCH PARTY'S NEGLIGENCE TO THE EXTENT APPLICABLE LAW
+     PROHIBITS SUCH LIMITATION. SOME JURISDICTIONS DO NOT ALLOW THE
+     EXCLUSION OR LIMITATION OF INCIDENTAL OR CONSEQUENTIAL DAMAGES, SO
+     THIS EXCLUSION AND LIMITATION MAY NOT APPLY TO YOU.
+
+10. U.S. GOVERNMENT END USERS.
+
+     The Covered Code is a "commercial item," as that term is defined in
+     48 C.F.R. 2.101 (Oct. 1995), consisting of "commercial computer
+     software" and "commercial computer software documentation," as such
+     terms are used in 48 C.F.R. 12.212 (Sept. 1995). Consistent with 48
+     C.F.R. 12.212 and 48 C.F.R. 227.7202-1 through 227.7202-4 (June 1995),
+     all U.S. Government End Users acquire Covered Code with only those
+     rights set forth herein.
+
+11. MISCELLANEOUS.
+
+     This License represents the complete agreement concerning subject
+     matter hereof. If any provision of this License is held to be
+     unenforceable, such provision shall be reformed only to the extent
+     necessary to make it enforceable. This License shall be governed by
+     California law provisions (except to the extent applicable law, if
+     any, provides otherwise), excluding its conflict-of-law provisions.
+     With respect to disputes in which at least one party is a citizen of,
+     or an entity chartered or registered to do business in the United
+     States of America, any litigation relating to this License shall be
+     subject to the jurisdiction of the Federal Courts of the Northern
+     District of California, with venue lying in Santa Clara County,
+     California, with the losing party responsible for costs, including
+     without limitation, court costs and reasonable attorneys' fees and
+     expenses. The application of the United Nations Convention on
+     Contracts for the International Sale of Goods is expressly excluded.
+     Any law or regulation which provides that the language of a contract
+     shall be construed against the drafter shall not apply to this
+     License.
+
+12. RESPONSIBILITY FOR CLAIMS.
+
+     As between Initial Developer and the Contributors, each party is
+     responsible for claims and damages arising, directly or indirectly,
+     out of its utilization of rights under this License and You agree to
+     work with Initial Developer and Contributors to distribute such
+     responsibility on an equitable basis. Nothing herein is intended or
+     shall be deemed to constitute any admission of liability.
+
+13. MULTIPLE-LICENSED CODE.
+
+     Initial Developer may designate portions of the Covered Code as
+     "Multiple-Licensed".  "Multiple-Licensed" means that the Initial
+     Developer permits you to utilize portions of the Covered Code under
+     Your choice of the NPL or the alternative licenses, if any, specified
+     by the Initial Developer in the file described in Exhibit A.
+
+EXHIBIT A -Mozilla Public License.
+
+     ``The contents of this file are subject to the Mozilla Public License
+     Version 1.1 (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.mozilla.org/MPL/
+
+     Software distributed under the License is distributed on an "AS IS"
+     basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
+     License for the specific language governing rights and limitations
+     under the License.
+
+     The Original Code is ______________________________________.
+
+     The Initial Developer of the Original Code is ________________________.
+     Portions created by ______________________ are Copyright (C) ______
+     _______________________. All Rights Reserved.
+
+     Contributor(s): ______________________________________.
+
+     Alternatively, the contents of this file may be used under the terms
+     of the _____ license (the  "[___] License"), in which case the
+     provisions of [______] License are applicable instead of those
+     above.  If you wish to allow use of your version of this file only
+     under the terms of the [____] License and not to allow others to use
+     your version of this file under the MPL, indicate your decision by
+     deleting  the provisions above and replace  them with the notice and
+     other provisions required by the [___] License.  If you do not delete
+     the provisions above, a recipient may use your version of this file
+     under either the MPL or the [___] License."
+
+     [NOTE: The text of this Exhibit A may differ slightly from the text of
+     the notices in the Source Code files of the Original Code. You should
+     use the text of this Exhibit A rather than the text found in the
+     Original Code Source Code for Your Modifications.]
+```
+
+Appendix D: The MIT License
+---------------------------
+
+```
+The MIT License (MIT)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+```
+
+Appendix E: The SIL Open Font License Version 1.1
+---------------------------------------------
+
+```
+SIL OPEN FONT LICENSE Version 1.1 - 26 February 2007
+-----------------------------------------------------------
+
+PREAMBLE
+The goals of the Open Font License (OFL) are to stimulate worldwide
+development of collaborative font projects, to support the font creation
+efforts of academic and linguistic communities, and to provide a free and
+open framework in which fonts may be shared and improved in partnership
+with others.
+
+The OFL allows the licensed fonts to be used, studied, modified and
+redistributed freely as long as they are not sold by themselves. The
+fonts, including any derivative works, can be bundled, embedded,
+redistributed and/or sold with any software provided that any reserved
+names are not used by derivative works. The fonts and derivatives,
+however, cannot be released under any other type of license. The
+requirement for fonts to remain under this license does not apply
+to any document created using the fonts or their derivatives.
+
+DEFINITIONS
+"Font Software" refers to the set of files released by the Copyright
+Holder(s) under this license and clearly marked as such. This may
+include source files, build scripts and documentation.
+
+"Reserved Font Name" refers to any names specified as such after the
+copyright statement(s).
+
+"Original Version" refers to the collection of Font Software components as
+distributed by the Copyright Holder(s).
+
+"Modified Version" refers to any derivative made by adding to, deleting,
+or substituting -- in part or in whole -- any of the components of the
+Original Version, by changing formats or by porting the Font Software to a
+new environment.
+
+"Author" refers to any designer, engineer, programmer, technical
+writer or other person who contributed to the Font Software.
+
+PERMISSION & CONDITIONS
+Permission is hereby granted, free of charge, to any person obtaining
+a copy of the Font Software, to use, study, copy, merge, embed, modify,
+redistribute, and sell modified and unmodified copies of the Font
+Software, subject to the following conditions:
+
+1) Neither the Font Software nor any of its individual components,
+in Original or Modified Versions, may be sold by itself.
+
+2) Original or Modified Versions of the Font Software may be bundled,
+redistributed and/or sold with any software, provided that each copy
+contains the above copyright notice and this license. These can be
+included either as stand-alone text files, human-readable headers or
+in the appropriate machine-readable metadata fields within text or
+binary files as long as those fields can be easily viewed by the user.
+
+3) No Modified Version of the Font Software may use the Reserved Font
+Name(s) unless explicit written permission is granted by the corresponding
+Copyright Holder. This restriction only applies to the primary font name as
+presented to the users.
+
+4) The name(s) of the Copyright Holder(s) or the Author(s) of the Font
+Software shall not be used to promote, endorse or advertise any
+Modified Version, except to acknowledge the contribution(s) of the
+Copyright Holder(s) and the Author(s) or with their explicit written
+permission.
+
+5) The Font Software, modified or unmodified, in part or in whole,
+must be distributed entirely under this license, and must not be
+distributed under any other license. The requirement for fonts to
+remain under this license does not apply to any document created
+using the Font Software.
+
+TERMINATION
+This license becomes null and void if any of the above conditions are
+not met.
+
+DISCLAIMER
+THE FONT SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTIES OF
+MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT
+OF COPYRIGHT, PATENT, TRADEMARK, OR OTHER RIGHT. IN NO EVENT SHALL THE
+COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+INCLUDING ANY GENERAL, SPECIAL, INDIRECT, INCIDENTAL, OR CONSEQUENTIAL
+DAMAGES, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF THE USE OR INABILITY TO USE THE FONT SOFTWARE OR FROM
+OTHER DEALINGS IN THE FONT SOFTWARE.
+```
+
+Appendix F: The BSD-3 License
+-----------------------------
+
+```
+Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
+
+1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
+
+2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
+
+3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+```
+
+(Ignore this line: %REMOVE_START%)
+
+Appendix G: The Apache License
+------------------------------
+
+```
+
+                              Apache License
+                        Version 2.0, January 2004
+                     http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+   "License" shall mean the terms and conditions for use, reproduction,
+   and distribution as defined by Sections 1 through 9 of this document.
+
+   "Licensor" shall mean the copyright owner or entity authorized by
+   the copyright owner that is granting the License.
+
+   "Legal Entity" shall mean the union of the acting entity and all
+   other entities that control, are controlled by, or are under common
+   control with that entity. For the purposes of this definition,
+   "control" means (i) the power, direct or indirect, to cause the
+   direction or management of such entity, whether by contract or
+   otherwise, or (ii) ownership of fifty percent (50%) or more of the
+   outstanding shares, or (iii) beneficial ownership of such entity.
+
+   "You" (or "Your") shall mean an individual or Legal Entity
+   exercising permissions granted by this License.
+
+   "Source" form shall mean the preferred form for making modifications,
+   including but not limited to software source code, documentation
+   source, and configuration files.
+
+   "Object" form shall mean any form resulting from mechanical
+   transformation or translation of a Source form, including but
+   not limited to compiled object code, generated documentation,
+   and conversions to other media types.
+
+   "Work" shall mean the work of authorship, whether in Source or
+   Object form, made available under the License, as indicated by a
+   copyright notice that is included in or attached to the work
+   (an example is provided in the Appendix below).
+
+   "Derivative Works" shall mean any work, whether in Source or Object
+   form, that is based on (or derived from) the Work and for which the
+   editorial revisions, annotations, elaborations, or other modifications
+   represent, as a whole, an original work of authorship. For the purposes
+   of this License, Derivative Works shall not include works that remain
+   separable from, or merely link (or bind by name) to the interfaces of,
+   the Work and Derivative Works thereof.
+
+   "Contribution" shall mean any work of authorship, including
+   the original version of the Work and any modifications or additions
+   to that Work or Derivative Works thereof, that is intentionally
+   submitted to Licensor for inclusion in the Work by the copyright owner
+   or by an individual or Legal Entity authorized to submit on behalf of
+   the copyright owner. For the purposes of this definition, "submitted"
+   means any form of electronic, verbal, or written communication sent
+   to the Licensor or its representatives, including but not limited to
+   communication on electronic mailing lists, source code control systems,
+   and issue tracking systems that are managed by, or on behalf of, the
+   Licensor for the purpose of discussing and improving the Work, but
+   excluding communication that is conspicuously marked or otherwise
+   designated in writing by the copyright owner as "Not a Contribution."
+
+   "Contributor" shall mean Licensor and any individual or Legal Entity
+   on behalf of whom a Contribution has been received by Licensor and
+   subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   copyright license to reproduce, prepare Derivative Works of,
+   publicly display, publicly perform, sublicense, and distribute the
+   Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+   this License, each Contributor hereby grants to You a perpetual,
+   worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+   (except as stated in this section) patent license to make, have made,
+   use, offer to sell, sell, import, and otherwise transfer the Work,
+   where such license applies only to those patent claims licensable
+   by such Contributor that are necessarily infringed by their
+   Contribution(s) alone or by combination of their Contribution(s)
+   with the Work to which such Contribution(s) was submitted. If You
+   institute patent litigation against any entity (including a
+   cross-claim or counterclaim in a lawsuit) alleging that the Work
+   or a Contribution incorporated within the Work constitutes direct
+   or contributory patent infringement, then any patent licenses
+   granted to You under this License for that Work shall terminate
+   as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+   Work or Derivative Works thereof in any medium, with or without
+   modifications, and in Source or Object form, provided that You
+   meet the following conditions:
+
+   (a) You must give any other recipients of the Work or
+       Derivative Works a copy of this License; and
+
+   (b) You must cause any modified files to carry prominent notices
+       stating that You changed the files; and
+
+   (c) You must retain, in the Source form of any Derivative Works
+       that You distribute, all copyright, patent, trademark, and
+       attribution notices from the Source form of the Work,
+       excluding those notices that do not pertain to any part of
+       the Derivative Works; and
+
+   (d) If the Work includes a "NOTICE" text file as part of its
+       distribution, then any Derivative Works that You distribute must
+       include a readable copy of the attribution notices contained
+       within such NOTICE file, excluding those notices that do not
+       pertain to any part of the Derivative Works, in at least one
+       of the following places: within a NOTICE text file distributed
+       as part of the Derivative Works; within the Source form or
+       documentation, if provided along with the Derivative Works; or,
+       within a display generated by the Derivative Works, if and
+       wherever such third-party notices normally appear. The contents
+       of the NOTICE file are for informational purposes only and
+       do not modify the License. You may add Your own attribution
+       notices within Derivative Works that You distribute, alongside
+       or as an addendum to the NOTICE text from the Work, provided
+       that such additional attribution notices cannot be construed
+       as modifying the License.
+
+   You may add Your own copyright statement to Your modifications and
+   may provide additional or different license terms and conditions
+   for use, reproduction, or distribution of Your modifications, or
+   for any such Derivative Works as a whole, provided Your use,
+   reproduction, and distribution of the Work otherwise complies with
+   the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+   any Contribution intentionally submitted for inclusion in the Work
+   by You to the Licensor shall be under the terms and conditions of
+   this License, without any additional terms or conditions.
+   Notwithstanding the above, nothing herein shall supersede or modify
+   the terms of any separate license agreement you may have executed
+   with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+   names, trademarks, service marks, or product names of the Licensor,
+   except as required for reasonable and customary use in describing the
+   origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+   agreed to in writing, Licensor provides the Work (and each
+   Contributor provides its Contributions) on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+   implied, including, without limitation, any warranties or conditions
+   of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+   PARTICULAR PURPOSE. You are solely responsible for determining the
+   appropriateness of using or redistributing the Work and assume any
+   risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+   whether in tort (including negligence), contract, or otherwise,
+   unless required by applicable law (such as deliberate and grossly
+   negligent acts) or agreed to in writing, shall any Contributor be
+   liable to You for damages, including any direct, indirect, special,
+   incidental, or consequential damages of any character arising as a
+   result of this License or out of the use or inability to use the
+   Work (including but not limited to damages for loss of goodwill,
+   work stoppage, computer failure or malfunction, or any and all
+   other commercial damages or losses), even if such Contributor
+   has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+   the Work or Derivative Works thereof, You may choose to offer,
+   and charge a fee for, acceptance of support, warranty, indemnity,
+   or other liability obligations and/or rights consistent with this
+   License. However, in accepting such obligations, You may act only
+   on Your own behalf and on Your sole responsibility, not on behalf
+   of any other Contributor, and only if You agree to indemnify,
+   defend, and hold each Contributor harmless for any liability
+   incurred by, or claims asserted against, such Contributor by reason
+   of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+```
+
+(Ignore this line: %REMOVE_END%)
diff --git a/sources/README.md b/sources/README.md
new file mode 100644 (file)
index 0000000..d18d4a1
--- /dev/null
@@ -0,0 +1,39 @@
+CKEditor 4
+==========
+
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+http://ckeditor.com - See LICENSE.md for license information.
+
+CKEditor is a text editor to be used inside web pages. It's not a replacement
+for desktop text editors like Word or OpenOffice, but a component to be used as
+part of web applications and websites.
+
+## Documentation
+
+The full editor documentation is available online at the following address:
+http://docs.ckeditor.com
+
+## Installation
+
+Installing CKEditor is an easy task. Just follow these simple steps:
+
+ 1. **Download** the latest version from the CKEditor website:
+    http://ckeditor.com. You should have already completed this step, but be
+    sure you have the very latest version.
+ 2. **Extract** (decompress) the downloaded file into the root of your website.
+
+**Note:** CKEditor is by default installed in the `ckeditor` folder. You can
+place the files in whichever you want though.
+
+## Checking Your Installation
+
+The editor comes with a few sample pages that can be used to verify that
+installation proceeded properly. Take a look at the `samples` directory.
+
+To test your installation, just call the following page at your website:
+
+       http://<your site>/<CKEditor installation path>/samples/index.html
+
+For example:
+
+       http://www.example.com/ckeditor/samples/index.html
diff --git a/sources/adapters/jquery.js b/sources/adapters/jquery.js
new file mode 100644 (file)
index 0000000..4a7796b
--- /dev/null
@@ -0,0 +1,379 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR_Adapters.jQuery jQuery Adapter}.
+ */
+
+/**
+ * @class CKEDITOR_Adapters.jQuery
+ * @singleton
+ *
+ * The jQuery Adapter allows for easy use of basic CKEditor functions and access to the internal API.
+ * To find more information about the jQuery Adapter, go to the [jQuery Adapter section](#!/guide/dev_jquery)
+ * of the Developer's Guide or see the "Create Editors with jQuery" sample.
+ *
+ * @aside guide dev_jquery
+ */
+
+( function( $ ) {
+       if ( typeof $ == 'undefined' ) {
+               throw new Error( 'jQuery should be loaded before CKEditor jQuery adapter.' );
+       }
+
+       if ( typeof CKEDITOR == 'undefined' ) {
+               throw new Error( 'CKEditor should be loaded before CKEditor jQuery adapter.' );
+       }
+
+       /**
+        * Allows CKEditor to override `jQuery.fn.val()`. When set to `true`, the `val()` function
+        * used on textarea elements replaced with CKEditor uses the CKEditor API.
+        *
+        * This configuration option is global and is executed during the loading of the jQuery Adapter.
+        * It cannot be customized across editor instances.
+        *
+        * Read more in the [documentation](#!/guide/dev_jquery).
+        *
+        *              <script>
+        *                      CKEDITOR.config.jqueryOverrideVal = true;
+        *              </script>
+        *
+        *              <!-- Important: The jQuery Adapter is loaded *after* setting jqueryOverrideVal. -->
+        *              <script src="/ckeditor/adapters/jquery.js"></script>
+        *
+        *              <script>
+        *                      $( 'textarea' ).ckeditor();
+        *                      // ...
+        *                      $( 'textarea' ).val( 'New content' );
+        *              </script>
+        *
+        * @cfg {Boolean} [jqueryOverrideVal=true]
+        * @member CKEDITOR.config
+        */
+       CKEDITOR.config.jqueryOverrideVal =
+               typeof CKEDITOR.config.jqueryOverrideVal == 'undefined' ? true : CKEDITOR.config.jqueryOverrideVal;
+
+       // jQuery object methods.
+       $.extend( $.fn, {
+               /**
+                * Returns an existing CKEditor instance for the first matched element.
+                * Allows to easily use the internal API. Does not return a jQuery object.
+                *
+                * Raises an exception if the editor does not exist or is not ready yet.
+                *
+                * @returns CKEDITOR.editor
+                * @deprecated Use {@link #editor editor property} instead.
+                */
+               ckeditorGet: function() {
+                       var instance = this.eq( 0 ).data( 'ckeditorInstance' );
+
+                       if ( !instance )
+                               throw 'CKEditor is not initialized yet, use ckeditor() with a callback.';
+
+                       return instance;
+               },
+
+               /**
+                * A jQuery function which triggers the creation of CKEditor with `<textarea>` and
+                * {@link CKEDITOR.dtd#$editable editable} elements.
+                * Every `<textarea>` element will be converted to a classic (`iframe`-based) editor,
+                * while any other supported element will be converted to an inline editor.
+                * This method binds the callback to the `instanceReady` event of all instances.
+                * If the editor has already been created, the callback is fired straightaway.
+                * You can also create multiple editors at once by using `$( '.className' ).ckeditor();`.
+                *
+                * **Note**: jQuery chaining and mixed parameter order is allowed.
+                *
+                * @param {Function} callback
+                * Function to be run on the editor instance. Callback takes the source element as a parameter.
+                *
+                *              $( 'textarea' ).ckeditor( function( textarea ) {
+                *                      // Callback function code.
+                *              } );
+                *
+                * @param {Object} config
+                * Configuration options for new instance(s) if not already created.
+                *
+                *              $( 'textarea' ).ckeditor( {
+                *                      uiColor: '#9AB8F3'
+                *              } );
+                *
+                * @returns jQuery.fn
+                */
+               ckeditor: function( callback, config ) {
+                       if ( !CKEDITOR.env.isCompatible )
+                               throw new Error( 'The environment is incompatible.' );
+
+                       // Reverse the order of arguments if the first one isn't a function.
+                       if ( !$.isFunction( callback ) ) {
+                               var tmp = config;
+                               config = callback;
+                               callback = tmp;
+                       }
+
+                       // An array of instanceReady callback promises.
+                       var promises = [];
+
+                       config = config || {};
+
+                       // Iterate over the collection.
+                       this.each( function() {
+                               var $element = $( this ),
+                                       editor = $element.data( 'ckeditorInstance' ),
+                                       instanceLock = $element.data( '_ckeditorInstanceLock' ),
+                                       element = this,
+                                       dfd = new $.Deferred();
+
+                               promises.push( dfd.promise() );
+
+                               if ( editor && !instanceLock ) {
+                                       if ( callback )
+                                               callback.apply( editor, [ this ] );
+
+                                       dfd.resolve();
+                               } else if ( !instanceLock ) {
+                                       // CREATE NEW INSTANCE
+
+                                       // Handle config.autoUpdateElement inside this plugin if desired.
+                                       if ( config.autoUpdateElement || ( typeof config.autoUpdateElement == 'undefined' && CKEDITOR.config.autoUpdateElement ) ) {
+                                               config.autoUpdateElementJquery = true;
+                                       }
+
+                                       // Always disable config.autoUpdateElement.
+                                       config.autoUpdateElement = false;
+                                       $element.data( '_ckeditorInstanceLock', true );
+
+                                       // Set instance reference in element's data.
+                                       if ( $( this ).is( 'textarea' ) )
+                                               editor = CKEDITOR.replace( element, config );
+                                       else
+                                               editor = CKEDITOR.inline( element, config );
+
+                                       $element.data( 'ckeditorInstance', editor );
+
+                                       // Register callback.
+                                       editor.on( 'instanceReady', function( evt ) {
+                                               var editor = evt.editor;
+
+                                               setTimeout( function() {
+                                                       // Delay bit more if editor is still not ready.
+                                                       if ( !editor.element ) {
+                                                               setTimeout( arguments.callee, 100 );
+                                                               return;
+                                                       }
+
+                                                       // Remove this listener. Triggered when new instance is ready.
+                                                       evt.removeListener();
+
+                                                       /**
+                                                        * Forwards the CKEditor {@link CKEDITOR.editor#event-dataReady dataReady event} as a jQuery event.
+                                                        *
+                                                        * @event dataReady
+                                                        * @param {CKEDITOR.editor} editor Editor instance.
+                                                        */
+                                                       editor.on( 'dataReady', function() {
+                                                               $element.trigger( 'dataReady.ckeditor', [ editor ] );
+                                                       } );
+
+                                                       /**
+                                                        * Forwards the CKEditor {@link CKEDITOR.editor#event-setData setData event} as a jQuery event.
+                                                        *
+                                                        * @event setData
+                                                        * @param {CKEDITOR.editor} editor Editor instance.
+                                                        * @param data
+                                                        * @param {String} data.dataValue The data that will be used.
+                                                        */
+                                                       editor.on( 'setData', function( evt ) {
+                                                               $element.trigger( 'setData.ckeditor', [ editor, evt.data ] );
+                                                       } );
+
+                                                       /**
+                                                        * Forwards the CKEditor {@link CKEDITOR.editor#event-getData getData event} as a jQuery event.
+                                                        *
+                                                        * @event getData
+                                                        * @param {CKEDITOR.editor} editor Editor instance.
+                                                        * @param data
+                                                        * @param {String} data.dataValue The data that will be returned.
+                                                        */
+                                                       editor.on( 'getData', function( evt ) {
+                                                               $element.trigger( 'getData.ckeditor', [ editor, evt.data ] );
+                                                       }, 999 );
+
+                                                       /**
+                                                        * Forwards the CKEditor {@link CKEDITOR.editor#event-destroy destroy event} as a jQuery event.
+                                                        *
+                                                        * @event destroy
+                                                        * @param {CKEDITOR.editor} editor Editor instance.
+                                                        */
+                                                       editor.on( 'destroy', function() {
+                                                               $element.trigger( 'destroy.ckeditor', [ editor ] );
+                                                       } );
+
+                                                       // Overwrite save button to call jQuery submit instead of javascript submit.
+                                                       // Otherwise jQuery.forms does not work properly
+                                                       editor.on( 'save', function() {
+                                                               $( element.form ).submit();
+                                                               return false;
+                                                       }, null, null, 20 );
+
+                                                       // Integrate with form submit.
+                                                       if ( editor.config.autoUpdateElementJquery && $element.is( 'textarea' ) && $( element.form ).length ) {
+                                                               var onSubmit = function() {
+                                                                       $element.ckeditor( function() {
+                                                                               editor.updateElement();
+                                                                       } );
+                                                               };
+
+                                                               // Bind to submit event.
+                                                               $( element.form ).submit( onSubmit );
+
+                                                               // Bind to form-pre-serialize from jQuery Forms plugin.
+                                                               $( element.form ).bind( 'form-pre-serialize', onSubmit );
+
+                                                               // Unbind when editor destroyed.
+                                                               $element.bind( 'destroy.ckeditor', function() {
+                                                                       $( element.form ).unbind( 'submit', onSubmit );
+                                                                       $( element.form ).unbind( 'form-pre-serialize', onSubmit );
+                                                               } );
+                                                       }
+
+                                                       // Garbage collect on destroy.
+                                                       editor.on( 'destroy', function() {
+                                                               $element.removeData( 'ckeditorInstance' );
+                                                       } );
+
+                                                       // Remove lock.
+                                                       $element.removeData( '_ckeditorInstanceLock' );
+
+                                                       /**
+                                                        * Forwards the CKEditor {@link CKEDITOR.editor#event-instanceReady instanceReady event} as a jQuery event.
+                                                        *
+                                                        * @event instanceReady
+                                                        * @param {CKEDITOR.editor} editor Editor instance.
+                                                        */
+                                                       $element.trigger( 'instanceReady.ckeditor', [ editor ] );
+
+                                                       // Run given (first) code.
+                                                       if ( callback )
+                                                               callback.apply( editor, [ element ] );
+
+                                                       dfd.resolve();
+                                               }, 0 );
+                                       }, null, null, 9999 );
+                               } else {
+                                       // Editor is already during creation process, bind our code to the event.
+                                       editor.once( 'instanceReady', function() {
+                                               setTimeout( function() {
+                                                       // Delay bit more if editor is still not ready.
+                                                       if ( !editor.element ) {
+                                                               setTimeout( arguments.callee, 100 );
+                                                               return;
+                                                       }
+
+                                                       // Run given code.
+                                                       if ( editor.element.$ == element && callback )
+                                                               callback.apply( editor, [ element ] );
+
+                                                       dfd.resolve();
+                                               }, 0 );
+                                       }, null, null, 9999 );
+                               }
+                       } );
+
+                       /**
+                        * The [jQuery Promise object]((http://api.jquery.com/promise/)) that handles the asynchronous constructor.
+                        * This promise will be resolved after **all** of the constructors.
+                        *
+                        * @property {Function} promise
+                        */
+                       var dfd = new $.Deferred();
+
+                       this.promise = dfd.promise();
+
+                       $.when.apply( this, promises ).then( function() {
+                               dfd.resolve();
+                       } );
+
+                       /**
+                        * Existing CKEditor instance. Allows to easily use the internal API.
+                        *
+                        * **Note**: This is not a jQuery object.
+                        *
+                        *              var editor = $( 'textarea' ).ckeditor().editor;
+                        *
+                        * @property {CKEDITOR.editor} editor
+                        */
+                       this.editor = this.eq( 0 ).data( 'ckeditorInstance' );
+
+                       return this;
+               }
+       } );
+
+       /**
+        * Overwritten jQuery `val()` method for `<textarea>` elements that have bound CKEditor instances.
+        * This method gets or sets editor content by using the {@link CKEDITOR.editor#method-getData editor.getData()}
+        * or {@link CKEDITOR.editor#method-setData editor.setData()} methods. To handle
+        * the {@link CKEDITOR.editor#method-setData editor.setData()} callback (as `setData` is asynchronous),
+        * `val( 'some data' )` will return a [jQuery Promise object](http://api.jquery.com/promise/).
+        *
+        * @method val
+        * @returns String|Number|Array|jQuery.fn|function(jQuery Promise)
+        */
+       if ( CKEDITOR.config.jqueryOverrideVal ) {
+               $.fn.val = CKEDITOR.tools.override( $.fn.val, function( oldValMethod ) {
+                       return function( value ) {
+                               // Setter, i.e. .val( "some data" );
+                               if ( arguments.length ) {
+                                       var _this = this,
+                                               promises = [], //use promise to handle setData callback
+
+                                               result = this.each( function() {
+                                                       var $elem = $( this ),
+                                                               editor = $elem.data( 'ckeditorInstance' );
+
+                                                       // Handle .val for CKEditor.
+                                                       if ( $elem.is( 'textarea' ) && editor ) {
+                                                               var dfd = new $.Deferred();
+
+                                                               editor.setData( value, function() {
+                                                                       dfd.resolve();
+                                                               } );
+
+                                                               promises.push( dfd.promise() );
+                                                               return true;
+                                                               // Call default .val function for rest of elements
+                                                       } else {
+                                                               return oldValMethod.call( $elem, value );
+                                                       }
+                                               } );
+
+                                       // If there is no promise return default result (jQuery object of chaining).
+                                       if ( !promises.length )
+                                               return result;
+                                       // Create one promise which will be resolved when all of promises will be done.
+                                       else {
+                                               var dfd = new $.Deferred();
+
+                                               $.when.apply( this, promises ).done( function() {
+                                                       dfd.resolveWith( _this );
+                                               } );
+
+                                               return dfd.promise();
+                                       }
+                               }
+                               // Getter .val();
+                               else {
+                                       var $elem = $( this ).eq( 0 ),
+                                               editor = $elem.data( 'ckeditorInstance' );
+
+                                       if ( $elem.is( 'textarea' ) && editor )
+                                               return editor.getData();
+                                       else
+                                               return oldValMethod.call( $elem );
+                               }
+                       };
+               } );
+       }
+} )( window.jQuery );
diff --git a/sources/ckeditor.js b/sources/ckeditor.js
new file mode 100644 (file)
index 0000000..8dc999b
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+// Compressed version of core/ckeditor_base.js. See original for instructions.
+/* jshint ignore:start */
+/* jscs:disable */
+window.CKEDITOR||(window.CKEDITOR=function(){var e=/(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i,b={timestamp:"",version:"%VERSION%",revision:"%REV%",rnd:Math.floor(900*Math.random())+100,_:{pending:[],basePathSrcPattern:e},status:"unloaded",basePath:function(){var a=window.CKEDITOR_BASEPATH||"";if(!a)for(var b=document.getElementsByTagName("script"),c=0;c<b.length;c++){var f=b[c].src.match(e);if(f){a=f[1];break}}-1==a.indexOf(":/")&&"//"!=a.slice(0,2)&&(a=0===a.indexOf("/")?location.href.match(/^.*?:\/\/[^\/]*/)[0]+
+a:location.href.match(/^[^\?]*\/(?:)/)[0]+a);if(!a)throw'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';return a}(),getUrl:function(a){-1==a.indexOf(":/")&&0!==a.indexOf("/")&&(a=this.basePath+a);this.timestamp&&"/"!=a.charAt(a.length-1)&&!/[&?]t=/.test(a)&&(a+=(0<=a.indexOf("?")?"&":"?")+"t="+this.timestamp);return a},domReady:function(){function a(){try{document.addEventListener?(document.removeEventListener("DOMContentLoaded",
+a,!1),b()):document.attachEvent&&"complete"===document.readyState&&(document.detachEvent("onreadystatechange",a),b())}catch(f){}}function b(){for(var a;a=c.shift();)a()}var c=[];return function(b){c.push(b);"complete"===document.readyState&&setTimeout(a,1);if(1==c.length)if(document.addEventListener)document.addEventListener("DOMContentLoaded",a,!1),window.addEventListener("load",a,!1);else if(document.attachEvent){document.attachEvent("onreadystatechange",a);window.attachEvent("onload",a);b=!1;try{b=
+!window.frameElement}catch(e){}if(document.documentElement.doScroll&&b){var d=function(){try{document.documentElement.doScroll("left")}catch(b){setTimeout(d,1);return}a()};d()}}}}()},d=window.CKEDITOR_GETURL;if(d){var g=b.getUrl;b.getUrl=function(a){return d.call(b,a)||g.call(b,a)}}return b}());
+/* jscs:enable */
+/* jshint ignore:end */
+
+if ( CKEDITOR.loader )
+       CKEDITOR.loader.load( 'ckeditor' );
+else {
+       // Set the script name to be loaded by the loader.
+       CKEDITOR._autoLoad = 'ckeditor';
+
+       // Include the loader script.
+       if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
+               var script = document.createElement( 'script' );
+               script.type = 'text/javascript';
+               script.src = CKEDITOR.getUrl( 'core/loader.js' );
+               document.body.appendChild( script );
+       } else {
+               document.write( '<script type="text/javascript" src="' + CKEDITOR.getUrl( 'core/loader.js' ) + '"></script>' );
+       }
+
+}
+
+/**
+ * The skin to load for all created instances, it may be the name of the skin
+ * folder inside the editor installation path, or the name and the path separated
+ * by a comma.
+ *
+ * **Note:** This is a global configuration that applies to all instances.
+ *
+ *             CKEDITOR.skinName = 'moono';
+ *
+ *             CKEDITOR.skinName = 'myskin,/customstuff/myskin/';
+ *
+ * @cfg {String} [skinName='moono-lisa']
+ * @member CKEDITOR
+ */
+CKEDITOR.skinName = 'moono-lisa';
diff --git a/sources/config.js b/sources/config.js
new file mode 100644 (file)
index 0000000..c3716d1
--- /dev/null
@@ -0,0 +1,17 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+CKEDITOR.editorConfig = function( config ) {
+       \r
+       // %REMOVE_START%\r
+       // The configuration options below are needed when running CKEditor from source files.\r
+       config.plugins = 'dialogui,dialog,a11yhelp,dialogadvtab,basicstyles,panel,floatpanel,menu,contextmenu,resize,button,toolbar,elementspath,enterkey,entities,popup,filebrowser,floatingspace,listblock,richcombo,format,horizontalrule,htmlwriter,fakeobjects,iframe,wysiwygarea,image,indent,indentblock,indentlist,justify,link,list,liststyle,magicline,maximize,removeformat,showborders,sourcearea,tab,lineutils,clipboard,widgetselection,widget,oembed';\r
+       config.skin = 'moono';\r
+       // %REMOVE_END%\r
+\r
+       // Define changes to default configuration here. For example:
+       // config.language = 'fr';
+       // config.uiColor = '#AADC6E';
+};
diff --git a/sources/contents.css b/sources/contents.css
new file mode 100644 (file)
index 0000000..8571059
--- /dev/null
@@ -0,0 +1,208 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+
+body
+{
+       /* Font */
+       font-family: sans-serif, Arial, Verdana, "Trebuchet MS";
+       font-size: 12px;
+
+       /* Text color */
+       color: #333;
+
+       /* Remove the background color to make it transparent */
+       background-color: #fff;
+
+       margin: 20px;
+}
+
+.cke_editable
+{
+       font-size: 13px;
+       line-height: 1.6;
+
+       /* Fix for missing scrollbars with RTL texts. (#10488) */
+       word-wrap: break-word;
+}
+
+blockquote
+{
+       font-style: italic;
+       font-family: Georgia, Times, "Times New Roman", serif;
+       padding: 2px 0;
+       border-style: solid;
+       border-color: #ccc;
+       border-width: 0;
+}
+
+.cke_contents_ltr blockquote
+{
+       padding-left: 20px;
+       padding-right: 8px;
+       border-left-width: 5px;
+}
+
+.cke_contents_rtl blockquote
+{
+       padding-left: 8px;
+       padding-right: 20px;
+       border-right-width: 5px;
+}
+
+a
+{
+       color: #0782C1;
+}
+
+ol,ul,dl
+{
+       /* IE7: reset rtl list margin. (#7334) */
+       *margin-right: 0px;
+       /* preserved spaces for list items with text direction other than the list. (#6249,#8049)*/
+       padding: 0 40px;
+}
+
+h1,h2,h3,h4,h5,h6
+{
+       font-weight: normal;
+       line-height: 1.2;
+}
+
+hr
+{
+       border: 0px;
+       border-top: 1px solid #ccc;
+}
+
+img.right
+{
+       border: 1px solid #ccc;
+       float: right;
+       margin-left: 15px;
+       padding: 5px;
+}
+
+img.left
+{
+       border: 1px solid #ccc;
+       float: left;
+       margin-right: 15px;
+       padding: 5px;
+}
+
+pre
+{
+       white-space: pre-wrap; /* CSS 2.1 */
+       word-wrap: break-word; /* IE7 */
+       -moz-tab-size: 4;
+       tab-size: 4;
+}
+
+.marker
+{
+       background-color: Yellow;
+}
+
+span[lang]
+{
+       font-style: italic;
+}
+
+figure
+{
+       text-align: center;
+       border: solid 1px #ccc;
+       border-radius: 2px;
+       background: rgba(0,0,0,0.05);
+       padding: 10px;
+       margin: 10px 20px;
+       display: inline-block;
+}
+
+figure > figcaption
+{
+       text-align: center;
+       display: block; /* For IE8 */
+}
+
+a > img {
+       padding: 1px;
+       margin: 1px;
+       border: none;
+       outline: 1px solid #0782C1;
+}
+
+/* Widget Styles */
+.code-featured
+{
+       border: 5px solid red;
+}
+
+.math-featured
+{
+       padding: 20px;
+       box-shadow: 0 0 2px rgba(200, 0, 0, 1);
+       background-color: rgba(255, 0, 0, 0.05);
+       margin: 10px;
+}
+
+.image-clean
+{
+       border: 0;
+       background: none;
+       padding: 0;
+}
+
+.image-clean > figcaption
+{
+       font-size: .9em;
+       text-align: right;
+}
+
+.image-grayscale
+{
+       background-color: white;
+       color: #666;
+}
+
+.image-grayscale img, img.image-grayscale
+{
+       filter: grayscale(100%);
+}
+
+.embed-240p
+{
+       max-width: 426px;
+       max-height: 240px;
+       margin:0 auto;
+}
+
+.embed-360p
+{
+       max-width: 640px;
+       max-height: 360px;
+       margin:0 auto;
+}
+
+.embed-480p
+{
+       max-width: 854px;
+       max-height: 480px;
+       margin:0 auto;
+}
+
+.embed-720p
+{
+       max-width: 1280px;
+       max-height: 720px;
+       margin:0 auto;
+}
+
+.embed-1080p
+{
+       max-width: 1920px;
+       max-height: 1080px;
+       margin:0 auto;
+}
diff --git a/sources/core/_bootstrap.js b/sources/core/_bootstrap.js
new file mode 100644 (file)
index 0000000..0163912
--- /dev/null
@@ -0,0 +1,74 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview API initialization code.
+ */
+
+( function() {
+       // Disable HC detection in WebKit. (#5429)
+       if ( CKEDITOR.env.webkit )
+               CKEDITOR.env.hc = false;
+       else {
+               // Check whether high contrast is active by creating a colored border.
+               var hcDetect = CKEDITOR.dom.element.createFromHtml( '<div style="width:0;height:0;position:absolute;left:-10000px;' +
+                       'border:1px solid;border-color:red blue"></div>', CKEDITOR.document );
+
+               hcDetect.appendTo( CKEDITOR.document.getHead() );
+
+               // Update CKEDITOR.env.
+               // Catch exception needed sometimes for FF. (#4230)
+               try {
+                       var top = hcDetect.getComputedStyle( 'border-top-color' ),
+                               right = hcDetect.getComputedStyle( 'border-right-color' );
+
+                       // We need to check if getComputedStyle returned any value, because on FF
+                       // it returnes empty string if CKEditor is loaded in hidden iframe. (#11121)
+                       CKEDITOR.env.hc = !!( top && top == right );
+               } catch ( e ) {
+                       CKEDITOR.env.hc = false;
+               }
+
+               hcDetect.remove();
+       }
+
+       if ( CKEDITOR.env.hc )
+               CKEDITOR.env.cssClass += ' cke_hc';
+
+       // Initially hide UI spaces when relevant skins are loading, later restored by skin css.
+       CKEDITOR.document.appendStyleText( '.cke{visibility:hidden;}' );
+
+       // Mark the editor as fully loaded.
+       CKEDITOR.status = 'loaded';
+       CKEDITOR.fireOnce( 'loaded' );
+
+       // Process all instances created by the "basic" implementation.
+       var pending = CKEDITOR._.pending;
+       if ( pending ) {
+               delete CKEDITOR._.pending;
+
+               for ( var i = 0; i < pending.length; i++ ) {
+                       CKEDITOR.editor.prototype.constructor.apply( pending[ i ][ 0 ], pending[ i ][ 1 ] );
+                       CKEDITOR.add( pending[ i ][ 0 ] );
+               }
+       }
+} )();
+
+/**
+ * Indicates that CKEditor is running on a High Contrast environment.
+ *
+ *             if ( CKEDITOR.env.hc )
+ *                     alert( 'You\'re running on High Contrast mode. The editor interface will get adapted to provide you a better experience.' );
+ *
+ * @property {Boolean} hc
+ * @member CKEDITOR.env
+ */
+
+/**
+ * Fired when a CKEDITOR core object is fully loaded and ready for interaction.
+ *
+ * @event loaded
+ * @member CKEDITOR
+ */
diff --git a/sources/core/ckeditor.js b/sources/core/ckeditor.js
new file mode 100644 (file)
index 0000000..2756204
--- /dev/null
@@ -0,0 +1,204 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Contains the third and last part of the {@link CKEDITOR} object
+ *             definition.
+ */
+
+/** @class CKEDITOR */
+
+// Remove the CKEDITOR.loadFullCore reference defined on ckeditor_basic.
+delete CKEDITOR.loadFullCore;
+
+/**
+ * Stores references to all editor instances created. The name of the properties
+ * in this object correspond to instance names, and their values contain the
+ * {@link CKEDITOR.editor} object representing them.
+ *
+ *             alert( CKEDITOR.instances.editor1.name ); // 'editor1'
+ *
+ * @property {Object}
+ */
+CKEDITOR.instances = {};
+
+/**
+ * The document of the window storing the CKEDITOR object.
+ *
+ *             alert( CKEDITOR.document.getBody().getName() ); // 'body'
+ *
+ * @property {CKEDITOR.dom.document}
+ */
+CKEDITOR.document = new CKEDITOR.dom.document( document );
+
+/**
+ * Adds an editor instance to the global {@link CKEDITOR} object. This function
+ * is available for internal use mainly.
+ *
+ * @param {CKEDITOR.editor} editor The editor instance to be added.
+ */
+CKEDITOR.add = function( editor ) {
+       CKEDITOR.instances[ editor.name ] = editor;
+
+       editor.on( 'focus', function() {
+               if ( CKEDITOR.currentInstance != editor ) {
+                       CKEDITOR.currentInstance = editor;
+                       CKEDITOR.fire( 'currentInstance' );
+               }
+       } );
+
+       editor.on( 'blur', function() {
+               if ( CKEDITOR.currentInstance == editor ) {
+                       CKEDITOR.currentInstance = null;
+                       CKEDITOR.fire( 'currentInstance' );
+               }
+       } );
+
+       CKEDITOR.fire( 'instance', null, editor );
+};
+
+/**
+ * Removes an editor instance from the global {@link CKEDITOR} object. This function
+ * is available for internal use only. External code must use {@link CKEDITOR.editor#method-destroy}.
+ *
+ * @private
+ * @param {CKEDITOR.editor} editor The editor instance to be removed.
+ */
+CKEDITOR.remove = function( editor ) {
+       delete CKEDITOR.instances[ editor.name ];
+};
+
+( function() {
+       var tpls = {};
+
+       /**
+        * Adds a named {@link CKEDITOR.template} instance to be reused among all editors.
+        * This will return the existing one if a template with same name is already
+        * defined. Additionally, it fires the "template" event to allow template source customization.
+        *
+        * @param {String} name The name which identifies a UI template.
+        * @param {String} source The source string for constructing this template.
+        * @returns {CKEDITOR.template} The created template instance.
+        */
+       CKEDITOR.addTemplate = function( name, source ) {
+               var tpl = tpls[ name ];
+               if ( tpl )
+                       return tpl;
+
+               // Make it possible to customize the template through event.
+               var params = { name: name, source: source };
+               CKEDITOR.fire( 'template', params );
+
+               return ( tpls[ name ] = new CKEDITOR.template( params.source ) );
+       };
+
+       /**
+        * Retrieves a defined template created with {@link CKEDITOR#addTemplate}.
+        *
+        * @param {String} name The template name.
+        */
+       CKEDITOR.getTemplate = function( name ) {
+               return tpls[ name ];
+       };
+} )();
+
+( function() {
+       var styles = [];
+
+       /**
+        * Adds CSS rules to be appended to the editor document.
+        * This method is mostly used by plugins to add custom styles to the editor
+        * document. For basic content styling the `contents.css` file should be
+        * used instead.
+        *
+        * **Note:** This function should be called before the creation of editor instances.
+        *
+        *              // Add styles for all headings inside editable contents.
+        *              CKEDITOR.addCss( '.cke_editable h1,.cke_editable h2,.cke_editable h3 { border-bottom: 1px dotted red }' );
+        *
+        * @param {String} css The style rules to be appended.
+        * @see CKEDITOR.config#contentsCss
+        */
+       CKEDITOR.addCss = function( css ) {
+               styles.push( css );
+       };
+
+       /**
+        * Returns a string will all CSS rules passed to the {@link CKEDITOR#addCss} method.
+        *
+        * @returns {String} A string containing CSS rules.
+        */
+       CKEDITOR.getCss = function() {
+               return styles.join( '\n' );
+       };
+} )();
+
+// Perform global clean up to free as much memory as possible
+// when there are no instances left
+CKEDITOR.on( 'instanceDestroyed', function() {
+       if ( CKEDITOR.tools.isEmpty( this.instances ) )
+               CKEDITOR.fire( 'reset' );
+} );
+
+// Load the bootstrap script.
+CKEDITOR.loader.load( '_bootstrap' ); // %REMOVE_LINE%
+
+// Tri-state constants.
+/**
+ * Used to indicate the ON or ACTIVE state.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ */
+CKEDITOR.TRISTATE_ON = 1;
+
+/**
+ * Used to indicate the OFF or INACTIVE state.
+ *
+ * @readonly
+ * @property {Number} [=2]
+ */
+CKEDITOR.TRISTATE_OFF = 2;
+
+/**
+ * Used to indicate the DISABLED state.
+ *
+ * @readonly
+ * @property {Number} [=0]
+ */
+CKEDITOR.TRISTATE_DISABLED = 0;
+
+/**
+ * The editor which is currently active (has user focus).
+ *
+ *             function showCurrentEditorName() {
+ *                     if ( CKEDITOR.currentInstance )
+ *                             alert( CKEDITOR.currentInstance.name );
+ *                     else
+ *                             alert( 'Please focus an editor first.' );
+ *             }
+ *
+ * @property {CKEDITOR.editor} currentInstance
+ * @see CKEDITOR#event-currentInstance
+ */
+
+/**
+ * Fired when the CKEDITOR.currentInstance object reference changes. This may
+ * happen when setting the focus on different editor instances in the page.
+ *
+ *             var editor; // A variable to store a reference to the current editor.
+ *             CKEDITOR.on( 'currentInstance', function() {
+ *                     editor = CKEDITOR.currentInstance;
+ *             } );
+ *
+ * @event currentInstance
+ */
+
+/**
+ * Fired when the last instance has been destroyed. This event is used to perform
+ * global memory cleanup.
+ *
+ * @event reset
+ */
diff --git a/sources/core/ckeditor_base.js b/sources/core/ckeditor_base.js
new file mode 100644 (file)
index 0000000..8c36b11
--- /dev/null
@@ -0,0 +1,318 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Contains the first and essential part of the {@link CKEDITOR}
+ *             object definition.
+ */
+
+// #### Compressed Code
+// Compressed code in ckeditor.js must be be updated on changes in the script.
+// The Closure Compiler online service should be used when updating this manually:
+// http://closure-compiler.appspot.com/
+
+// #### Raw code
+// ATTENTION: read the above "Compressed Code" notes when changing this code.
+
+if ( !window.CKEDITOR ) {
+       /**
+        * This is the API entry point. The entire CKEditor code runs under this object.
+        * @class CKEDITOR
+        * @singleton
+        */
+       window.CKEDITOR = ( function() {
+               var basePathSrcPattern = /(^|.*[\\\/])ckeditor\.js(?:\?.*|;.*)?$/i;
+
+               var CKEDITOR = {
+
+                       /**
+                        * A constant string unique for each release of CKEditor. Its value
+                        * is used, by default, to build the URL for all resources loaded
+                        * by the editor code, guaranteeing clean cache results when
+                        * upgrading.
+                        *
+                        * **Note:** There is [a known issue where "icons.png" does not include
+                        * timestamp](http://dev.ckeditor.com/ticket/10685) and might get cached.
+                        * We are working on having it fixed.
+                        *
+                        *              alert( CKEDITOR.timestamp ); // e.g. '87dm'
+                        */
+                       timestamp: '',                          // %REMOVE_LINE%
+                       /*                                                      // %REMOVE_LINE%
+                       // The production implementation contains a fixed timestamp, unique
+                       // for each release and generated by the releaser.
+                       // (Base 36 value of each component of YYMMDDHH - 4 chars total - e.g. 87bm == 08071122)
+                       timestamp: '%TIMESTAMP%',
+                       // %REMOVE_LINE% */
+
+                       /**
+                        * Contains the CKEditor version number.
+                        *
+                        *              alert( CKEDITOR.version ); // e.g. 'CKEditor 3.4.1'
+                        */
+                       version: '%VERSION%',
+
+                       /**
+                        * Contains the CKEditor revision number.
+                        * The revision number is incremented automatically, following each
+                        * modification to the CKEditor source code.
+                        *
+                        *              alert( CKEDITOR.revision ); // e.g. '3975'
+                        */
+                       revision: '%REV%',
+
+                       /**
+                        * A 3-digit random integer, valid for the entire life of the CKEDITOR object.
+                        *
+                        *              alert( CKEDITOR.rnd ); // e.g. 319
+                        *
+                        * @property {Number}
+                        */
+                       rnd: Math.floor( Math.random() * ( 999 /*Max*/ - 100 /*Min*/ + 1 ) ) + 100 /*Min*/,
+
+                       /**
+                        * Private object used to hold core stuff. It should not be used outside of
+                        * the API code as properties defined here may change at any time
+                        * without notice.
+                        *
+                        * @private
+                        */
+                       _: {
+                               pending: [],
+                               basePathSrcPattern: basePathSrcPattern
+                       },
+
+                       /**
+                        * Indicates the API loading status. The following statuses are available:
+                        *
+                        * * **unloaded**: the API is not yet loaded.
+                        * * **basic_loaded**: the basic API features are available.
+                        * * **basic_ready**: the basic API is ready to load the full core code.
+                        * * **loaded**: the API can be fully used.
+                        *
+                        * Example:
+                        *
+                        *              if ( CKEDITOR.status == 'loaded' ) {
+                        *                      // The API can now be fully used.
+                        *                      doSomething();
+                        *              } else {
+                        *                      // Wait for the full core to be loaded and fire its loading.
+                        *                      CKEDITOR.on( 'load', doSomething );
+                        *                      CKEDITOR.loadFullCore && CKEDITOR.loadFullCore();
+                        *              }
+                        */
+                       status: 'unloaded',
+
+                       /**
+                        * The full URL for the CKEditor installation directory.
+                        * It is possible to manually provide the base path by setting a
+                        * global variable named `CKEDITOR_BASEPATH`. This global variable
+                        * must be set **before** the editor script loading.
+                        *
+                        *              alert( CKEDITOR.basePath ); // e.g. 'http://www.example.com/ckeditor/'
+                        *
+                        * @property {String}
+                        */
+                       basePath: ( function() {
+                               // Find out the editor directory path, based on its <script> tag.
+                               var path = window.CKEDITOR_BASEPATH || '';
+
+                               if ( !path ) {
+                                       var scripts = document.getElementsByTagName( 'script' );
+
+                                       for ( var i = 0; i < scripts.length; i++ ) {
+                                               var match = scripts[ i ].src.match( basePathSrcPattern );
+
+                                               if ( match ) {
+                                                       path = match[ 1 ];
+                                                       break;
+                                               }
+                                       }
+                               }
+
+                               // In IE (only) the script.src string is the raw value entered in the
+                               // HTML source. Other browsers return the full resolved URL instead.
+                               if ( path.indexOf( ':/' ) == -1 && path.slice( 0, 2 ) != '//' ) {
+                                       // Absolute path.
+                                       if ( path.indexOf( '/' ) === 0 )
+                                               path = location.href.match( /^.*?:\/\/[^\/]*/ )[ 0 ] + path;
+                                       // Relative path.
+                                       else
+                                               path = location.href.match( /^[^\?]*\/(?:)/ )[ 0 ] + path;
+                               }
+
+                               if ( !path )
+                                       throw 'The CKEditor installation path could not be automatically detected. Please set the global variable "CKEDITOR_BASEPATH" before creating editor instances.';
+
+                               return path;
+                       } )(),
+
+                       /**
+                        * Gets the full URL for CKEditor resources. By default, URLs
+                        * returned by this function contain a querystring parameter ("t")
+                        * set to the {@link CKEDITOR#timestamp} value.
+                        *
+                        * It is possible to provide a custom implementation of this
+                        * function by setting a global variable named `CKEDITOR_GETURL`.
+                        * This global variable must be set **before** the editor script
+                        * loading. If the custom implementation returns nothing (`==null`), the
+                        * default implementation is used.
+                        *
+                        *              // e.g. 'http://www.example.com/ckeditor/skins/default/editor.css?t=87dm'
+                        *              alert( CKEDITOR.getUrl( 'skins/default/editor.css' ) );
+                        *
+                        *              // e.g. 'http://www.example.com/skins/default/editor.css?t=87dm'
+                        *              alert( CKEDITOR.getUrl( '/skins/default/editor.css' ) );
+                        *
+                        *              // e.g. 'http://www.somesite.com/skins/default/editor.css?t=87dm'
+                        *              alert( CKEDITOR.getUrl( 'http://www.somesite.com/skins/default/editor.css' ) );
+                        *
+                        * @param {String} resource The resource whose full URL we want to get.
+                        * It may be a full, absolute, or relative URL.
+                        * @returns {String} The full URL.
+                        */
+                       getUrl: function( resource ) {
+                               // If this is not a full or absolute path.
+                               if ( resource.indexOf( ':/' ) == -1 && resource.indexOf( '/' ) !== 0 )
+                                       resource = this.basePath + resource;
+
+                               // Add the timestamp, except for directories.
+                               if ( this.timestamp && resource.charAt( resource.length - 1 ) != '/' && !( /[&?]t=/ ).test( resource ) )
+                                       resource += ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + this.timestamp;
+
+                               return resource;
+                       },
+
+                       /**
+                        * Specify a function to execute when the DOM is fully loaded.
+                        *
+                        * If called after the DOM has been initialized, the function passed in will
+                        * be executed immediately.
+                        *
+                        * @method
+                        * @todo
+                        */
+                       domReady: ( function() {
+                               // Based on the original jQuery code (available under the MIT license, see LICENSE.md).
+
+                               var callbacks = [];
+
+                               function onReady() {
+                                       try {
+                                               // Cleanup functions for the document ready method
+                                               if ( document.addEventListener ) {
+                                                       document.removeEventListener( 'DOMContentLoaded', onReady, false );
+                                                       executeCallbacks();
+                                               }
+                                               // Make sure body exists, at least, in case IE gets a little overzealous.
+                                               else if ( document.attachEvent && document.readyState === 'complete' ) {
+                                                       document.detachEvent( 'onreadystatechange', onReady );
+                                                       executeCallbacks();
+                                               }
+                                       } catch ( er ) {}
+                               }
+
+                               function executeCallbacks() {
+                                       var i;
+                                       while ( ( i = callbacks.shift() ) )
+                                               i();
+                               }
+
+                               return function( fn ) {
+                                       callbacks.push( fn );
+
+                                       // Catch cases where this is called after the
+                                       // browser event has already occurred.
+                                       if ( document.readyState === 'complete' )
+                                               // Handle it asynchronously to allow scripts the opportunity to delay ready
+                                               setTimeout( onReady, 1 );
+
+                                       // Run below once on demand only.
+                                       if ( callbacks.length != 1 )
+                                               return;
+
+                                       // For IE>8, Firefox, Opera and Webkit.
+                                       if ( document.addEventListener ) {
+                                               // Use the handy event callback
+                                               document.addEventListener( 'DOMContentLoaded', onReady, false );
+
+                                               // A fallback to window.onload, that will always work
+                                               window.addEventListener( 'load', onReady, false );
+
+                                       }
+                                       // If old IE event model is used
+                                       else if ( document.attachEvent ) {
+                                               // ensure firing before onload,
+                                               // maybe late but safe also for iframes
+                                               document.attachEvent( 'onreadystatechange', onReady );
+
+                                               // A fallback to window.onload, that will always work
+                                               window.attachEvent( 'onload', onReady );
+
+                                               // If IE and not a frame
+                                               // continually check to see if the document is ready
+                                               // use the trick by Diego Perini
+                                               // http://javascript.nwbox.com/IEContentLoaded/
+                                               var toplevel = false;
+
+                                               try {
+                                                       toplevel = !window.frameElement;
+                                               } catch ( e ) {}
+
+                                               if ( document.documentElement.doScroll && toplevel ) {
+                                                       scrollCheck();
+                                               }
+                                       }
+
+                                       function scrollCheck() {
+                                               try {
+                                                       document.documentElement.doScroll( 'left' );
+                                               } catch ( e ) {
+                                                       setTimeout( scrollCheck, 1 );
+                                                       return;
+                                               }
+                                               onReady();
+                                       }
+                               };
+
+                       } )()
+               };
+
+               // Make it possible to override the "url" function with a custom
+               // implementation pointing to a global named CKEDITOR_GETURL.
+               var newGetUrl = window.CKEDITOR_GETURL;
+               if ( newGetUrl ) {
+                       var originalGetUrl = CKEDITOR.getUrl;
+                       CKEDITOR.getUrl = function( resource ) {
+                               return newGetUrl.call( CKEDITOR, resource ) || originalGetUrl.call( CKEDITOR, resource );
+                       };
+               }
+
+               return CKEDITOR;
+       } )();
+}
+
+/**
+ * Function called upon loading a custom configuration file that can
+ * modify the editor instance configuration ({@link CKEDITOR.editor#config}).
+ * It is usually defined inside the custom configuration files that can
+ * include developer defined settings.
+ *
+ *             // This is supposed to be placed in the config.js file.
+ *             CKEDITOR.editorConfig = function( config ) {
+ *                     // Define changes to default configuration here. For example:
+ *                     config.language = 'fr';
+ *                     config.uiColor = '#AADC6E';
+ *             };
+ *
+ * @method editorConfig
+ * @param {CKEDITOR.config} config A configuration object containing the
+ * settings defined for a {@link CKEDITOR.editor} instance up to this
+ * function call. Note that not all settings may still be available. See
+ * [Configuration Loading Order](http://docs.cksource.com/CKEditor_3.x/Developers_Guide/Setting_Configurations#Configuration_Loading_Order)
+ * for details.
+ */
+
+// PACKAGER_RENAME( CKEDITOR )
diff --git a/sources/core/ckeditor_basic.js b/sources/core/ckeditor_basic.js
new file mode 100644 (file)
index 0000000..c07e4d9
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Contains the second part of the {@link CKEDITOR} object
+ *             definition, which defines the basic editor features to be available in
+ *             the root ckeditor_basic.js file.
+ */
+
+if ( CKEDITOR.status == 'unloaded' ) {
+       ( function() {
+               CKEDITOR.event.implementOn( CKEDITOR );
+
+               /**
+                * Forces the full CKEditor core code, in the case only the basic code has been
+                * loaded (`ckeditor_basic.js`). This method self-destroys (becomes undefined) in
+                * the first call or as soon as the full code is available.
+                *
+                *              // Check if the full core code has been loaded and load it.
+                *              if ( CKEDITOR.loadFullCore )
+                *                      CKEDITOR.loadFullCore();
+                *
+                * @member CKEDITOR
+                */
+               CKEDITOR.loadFullCore = function() {
+                       // If the basic code is not ready, just mark it to be loaded.
+                       if ( CKEDITOR.status != 'basic_ready' ) {
+                               CKEDITOR.loadFullCore._load = 1;
+                               return;
+                       }
+
+                       // Destroy this function.
+                       delete CKEDITOR.loadFullCore;
+
+                       // Append the script to the head.
+                       var script = document.createElement( 'script' );
+                       script.type = 'text/javascript';
+                       script.src = CKEDITOR.basePath + 'ckeditor.js';
+                       script.src = CKEDITOR.basePath + 'ckeditor_source.js'; // %REMOVE_LINE%
+
+                       document.getElementsByTagName( 'head' )[ 0 ].appendChild( script );
+               };
+
+               /**
+                * The time to wait (in seconds) to load the full editor code after the
+                * page load, if the "ckeditor_basic" file is used. If set to zero, the
+                * editor is loaded on demand, as soon as an instance is created.
+                *
+                * This value must be set on the page before the page load completion.
+                *
+                *              // Loads the full source after five seconds.
+                *              CKEDITOR.loadFullCoreTimeout = 5;
+                *
+                * @property
+                * @member CKEDITOR
+                */
+               CKEDITOR.loadFullCoreTimeout = 0;
+
+               // Documented at ckeditor.js.
+               CKEDITOR.add = function( editor ) {
+                       // For now, just put the editor in the pending list. It will be
+                       // processed as soon as the full code gets loaded.
+                       var pending = this._.pending || ( this._.pending = [] );
+                       pending.push( editor );
+               };
+
+               ( function() {
+                       var onload = function() {
+                                       var loadFullCore = CKEDITOR.loadFullCore,
+                                               loadFullCoreTimeout = CKEDITOR.loadFullCoreTimeout;
+
+                                       if ( !loadFullCore )
+                                               return;
+
+                                       CKEDITOR.status = 'basic_ready';
+
+                                       if ( loadFullCore && loadFullCore._load )
+                                               loadFullCore();
+                                       else if ( loadFullCoreTimeout ) {
+                                               setTimeout( function() {
+                                                       if ( CKEDITOR.loadFullCore )
+                                                               CKEDITOR.loadFullCore();
+                                               }, loadFullCoreTimeout * 1000 );
+                                       }
+                               };
+
+                       CKEDITOR.domReady( onload );
+               } )();
+
+               CKEDITOR.status = 'basic_loaded';
+       } )();
+}
diff --git a/sources/core/command.js b/sources/core/command.js
new file mode 100644 (file)
index 0000000..0446d24
--- /dev/null
@@ -0,0 +1,275 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Represents a command that can be executed on an editor instance.
+ *
+ *             var command = new CKEDITOR.command( editor, {
+ *                     exec: function( editor ) {
+ *                             alert( editor.document.getBody().getHtml() );
+ *                     }
+ *             } );
+ *
+ * @class
+ * @extends CKEDITOR.commandDefinition
+ * @mixins CKEDITOR.event
+ * @constructor Creates a command class instance.
+ * @param {CKEDITOR.editor} editor The editor instance this command will be
+ * related to.
+ * @param {CKEDITOR.commandDefinition} commandDefinition The command
+ * definition.
+ */
+CKEDITOR.command = function( editor, commandDefinition ) {
+       /**
+        * Lists UI items that are associated to this command. This list can be
+        * used to interact with the UI on command execution (by the execution code
+        * itself, for example).
+        *
+        *              alert( 'Number of UI items associated to this command: ' + command.uiItems.length );
+        */
+       this.uiItems = [];
+
+       /**
+        * Executes the command.
+        *
+        *              command.exec(); // The command gets executed.
+        *
+        * **Note:** You should use the {@link CKEDITOR.editor#execCommand} method instead of calling
+        * `command.exec()` directly.
+        *
+        * @param {Object} [data] Any data to pass to the command. Depends on the
+        * command implementation and requirements.
+        * @returns {Boolean} A boolean indicating that the command has been successfully executed.
+        */
+       this.exec = function( data ) {
+               if ( this.state == CKEDITOR.TRISTATE_DISABLED || !this.checkAllowed() )
+                       return false;
+
+               if ( this.editorFocus ) // Give editor focus if necessary (#4355).
+                       editor.focus();
+
+               if ( this.fire( 'exec' ) === false )
+                       return true;
+
+               return ( commandDefinition.exec.call( this, editor, data ) !== false );
+       };
+
+       /**
+        * Explicitly update the status of the command, by firing the {@link CKEDITOR.command#event-refresh} event,
+        * as well as invoke the {@link CKEDITOR.commandDefinition#refresh} method if defined, this method
+        * is to allow different parts of the editor code to contribute in command status resolution.
+        *
+        * @param {CKEDITOR.editor} editor The editor instance.
+        * @param {CKEDITOR.dom.elementPath} path
+        */
+       this.refresh = function( editor, path ) {
+               // Do nothing is we're on read-only and this command doesn't support it.
+               // We don't need to disabled the command explicitely here, because this
+               // is already done by the "readOnly" event listener.
+               if ( !this.readOnly && editor.readOnly )
+                       return true;
+
+               // Disable commands that are not allowed in the current selection path context.
+               if ( this.context && !path.isContextFor( this.context ) ) {
+                       this.disable();
+                       return true;
+               }
+
+               // Disable commands that are not allowed by the active filter.
+               if ( !this.checkAllowed( true ) ) {
+                       this.disable();
+                       return true;
+               }
+
+               // Make the "enabled" state a default for commands enabled from start.
+               if ( !this.startDisabled )
+                       this.enable();
+
+               // Disable commands which shouldn't be enabled in this mode.
+               if ( this.modes && !this.modes[ editor.mode ] )
+                       this.disable();
+
+               if ( this.fire( 'refresh', { editor: editor, path: path } ) === false )
+                       return true;
+
+               return ( commandDefinition.refresh && commandDefinition.refresh.apply( this, arguments ) !== false );
+       };
+
+       var allowed;
+
+       /**
+        * Checks whether this command is allowed by the active allowed
+        * content filter ({@link CKEDITOR.editor#activeFilter}). This means
+        * that if command implements {@link CKEDITOR.feature} interface it will be tested
+        * by the {@link CKEDITOR.filter#checkFeature} method.
+        *
+        * @since 4.1
+        * @param {Boolean} [noCache] Skip cache for example due to active filter change. Since CKEditor 4.2.
+        * @returns {Boolean} Whether this command is allowed.
+        */
+       this.checkAllowed = function( noCache ) {
+               if ( !noCache && typeof allowed == 'boolean' )
+                       return allowed;
+
+               return allowed = editor.activeFilter.checkFeature( this );
+       };
+
+       CKEDITOR.tools.extend( this, commandDefinition, {
+               /**
+                * The editor modes within which the command can be executed. The
+                * execution will have no action if the current mode is not listed
+                * in this property.
+                *
+                *              // Enable the command in both WYSIWYG and Source modes.
+                *              command.modes = { wysiwyg:1,source:1 };
+                *
+                *              // Enable the command in Source mode only.
+                *              command.modes = { source:1 };
+                *
+                * @see CKEDITOR.editor#mode
+                */
+               modes: { wysiwyg: 1 },
+
+               /**
+                * Indicates that the editor will get the focus before executing
+                * the command.
+                *
+                *              // Do not force the editor to have focus when executing the command.
+                *              command.editorFocus = false;
+                *
+                * @property {Boolean} [=true]
+                */
+               editorFocus: 1,
+
+               /**
+                * Indicates that this command is sensible to the selection context.
+                * If `true`, the {@link CKEDITOR.command#method-refresh} method will be
+                * called for this command on the {@link CKEDITOR.editor#event-selectionChange} event.
+                *
+                * @property {Boolean} [=false]
+                */
+               contextSensitive: !!commandDefinition.context,
+
+               /**
+                * Indicates the editor state. Possible values are:
+                *
+                * * {@link CKEDITOR#TRISTATE_DISABLED}: the command is
+                *     disabled. It's execution will have no effect. Same as {@link #disable}.
+                * * {@link CKEDITOR#TRISTATE_ON}: the command is enabled
+                *     and currently active in the editor (for context sensitive commands,      for example).
+                * * {@link CKEDITOR#TRISTATE_OFF}: the command is enabled
+                *     and currently inactive in the editor (for context sensitive      commands, for example).
+                *
+                * Do not set this property directly, using the {@link #setState} method instead.
+                *
+                *              if ( command.state == CKEDITOR.TRISTATE_DISABLED )
+                *                      alert( 'This command is disabled' );
+                *
+                * @property {Number} [=CKEDITOR.TRISTATE_DISABLED]
+                */
+               state: CKEDITOR.TRISTATE_DISABLED
+       } );
+
+       // Call the CKEDITOR.event constructor to initialize this instance.
+       CKEDITOR.event.call( this );
+};
+
+CKEDITOR.command.prototype = {
+       /**
+        * Enables the command for execution. The command state (see
+        * {@link CKEDITOR.command#property-state}) available before disabling it is restored.
+        *
+        *              command.enable();
+        *              command.exec(); // Execute the command.
+        */
+       enable: function() {
+               if ( this.state == CKEDITOR.TRISTATE_DISABLED && this.checkAllowed() )
+                       this.setState( ( !this.preserveState || ( typeof this.previousState == 'undefined' ) ) ? CKEDITOR.TRISTATE_OFF : this.previousState );
+       },
+
+       /**
+        * Disables the command for execution. The command state (see
+        * {@link CKEDITOR.command#property-state}) will be set to {@link CKEDITOR#TRISTATE_DISABLED}.
+        *
+        *              command.disable();
+        *              command.exec(); // "false" - Nothing happens.
+        */
+       disable: function() {
+               this.setState( CKEDITOR.TRISTATE_DISABLED );
+       },
+
+       /**
+        * Sets the command state.
+        *
+        *              command.setState( CKEDITOR.TRISTATE_ON );
+        *              command.exec(); // Execute the command.
+        *              command.setState( CKEDITOR.TRISTATE_DISABLED );
+        *              command.exec(); // 'false' - Nothing happens.
+        *              command.setState( CKEDITOR.TRISTATE_OFF );
+        *              command.exec(); // Execute the command.
+        *
+        * @param {Number} newState The new state. See {@link #property-state}.
+        * @returns {Boolean} Returns `true` if the command state changed.
+        */
+       setState: function( newState ) {
+               // Do nothing if there is no state change.
+               if ( this.state == newState )
+                       return false;
+
+               if ( newState != CKEDITOR.TRISTATE_DISABLED && !this.checkAllowed() )
+                       return false;
+
+               this.previousState = this.state;
+
+               // Set the new state.
+               this.state = newState;
+
+               // Fire the "state" event, so other parts of the code can react to the
+               // change.
+               this.fire( 'state' );
+
+               return true;
+       },
+
+       /**
+        * Toggles the on/off (active/inactive) state of the command. This is
+        * mainly used internally by context sensitive commands.
+        *
+        *              command.toggleState();
+        */
+       toggleState: function() {
+               if ( this.state == CKEDITOR.TRISTATE_OFF )
+                       this.setState( CKEDITOR.TRISTATE_ON );
+               else if ( this.state == CKEDITOR.TRISTATE_ON )
+                       this.setState( CKEDITOR.TRISTATE_OFF );
+       }
+};
+
+CKEDITOR.event.implementOn( CKEDITOR.command.prototype );
+
+/**
+ * Indicates the previous command state.
+ *
+ *             alert( command.previousState );
+ *
+ * @property {Number} previousState
+ * @see #state
+ */
+
+/**
+ * Fired when the command state changes.
+ *
+ *             command.on( 'state', function() {
+ *                     // Alerts the new state.
+ *                     alert( this.state );
+ *             } );
+ *
+ * @event state
+ */
+
+ /**
+ * @event refresh
+ * @todo
+ */
diff --git a/sources/core/commanddefinition.js b/sources/core/commanddefinition.js
new file mode 100644 (file)
index 0000000..10a040f
--- /dev/null
@@ -0,0 +1,162 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the "virtual" {@link CKEDITOR.commandDefinition} class
+ *             which contains the defintion of a command. This file is for
+ *             documentation purposes only.
+ */
+
+/**
+ * Virtual class that illustrates the features of command objects to be
+ * passed to the {@link CKEDITOR.editor#addCommand} function.
+ *
+ * @class CKEDITOR.commandDefinition
+ * @abstract
+ */
+
+/**
+ * The function to be fired when the commend is executed.
+ *
+ *             editorInstance.addCommand( 'sample', {
+ *                     exec: function( editor ) {
+ *                             alert( 'Executing a command for the editor name "' + editor.name + '"!' );
+ *                     }
+ *             } );
+ *
+ * @method exec
+ * @param {CKEDITOR.editor} editor The editor within which to run the command.
+ * @param {Object} [data] Additional data to be used to execute the command.
+ * @returns {Boolean} Whether the command has been successfully executed.
+ * Defaults to `true` if nothing is returned.
+ */
+
+/**
+ * Whether the command needs to be hooked into the redo/undo system.
+ *
+ *             editorInstance.addCommand( 'alertName', {
+ *                     exec: function( editor ) {
+ *                             alert( editor.name );
+ *                     },
+ *                     canUndo: false // No support for undo/redo.
+ *             } );
+ *
+ * @property {Boolean} [canUndo=true]
+ */
+
+/**
+ * Whether the command is asynchronous, which means that the
+ * {@link CKEDITOR.editor#event-afterCommandExec} event will be fired by the
+ * command itself manually, and that the return value of this command is not to
+ * be returned by the {@link #exec} function.
+ *
+ *             editorInstance.addCommand( 'loadoptions', {
+ *                     exec: function( editor ) {
+ *                             var cmd = this;
+ *                             // Asynchronous operation below.
+ *                             CKEDITOR.ajax.loadXml( 'data.xml', function() {
+ *                                     editor.fire( 'afterCommandExec', {
+ *                                             name: 'loadoptions',
+ *                                             command: cmd
+ *                                     } );
+ *                             } );
+ *                     },
+ *                     async: true // The command needs some time to complete after the exec function returns.
+ *             } );
+ *
+ * @property {Boolean} [async=false]
+ */
+
+/**
+ * Whether the command should give focus to the editor before execution.
+ *
+ *             editorInstance.addCommand( 'maximize', {
+ *                             exec: function( editor ) {
+ *                             // ...
+ *                     },
+ *                     editorFocus: false // The command does not require focusing the editing document.
+ *             } );
+ *
+ * See also {@link CKEDITOR.command#editorFocus}.
+ *
+ * @property {Boolean} [editorFocus=true]
+ */
+
+
+/**
+ * Whether the command state should be set to {@link CKEDITOR#TRISTATE_DISABLED} on startup.
+ *
+ *             editorInstance.addCommand( 'unlink', {
+ *                     exec: function( editor ) {
+ *                             // ...
+ *                     },
+ *                     startDisabled: true // The command is unavailable until the selection is inside a link.
+ *             } );
+ *
+ * @property {Boolean} [startDisabled=false]
+ */
+
+/**
+ * Indicates that this command is sensitive to the selection context.
+ * If `true`, the {@link CKEDITOR.command#method-refresh} method will be
+ * called for this command on selection changes, with a single parameter
+ * representing the current elements path.
+ *
+ * @property {Boolean} [contextSensitive=true]
+ */
+
+/**
+ * Defined by the command definition, a function to determine the command state. It will be invoked
+ * when the editor has its `states` or `selection` changed.
+ *
+ * **Note:** The function provided must be calling {@link CKEDITOR.command#setState} in all circumstances
+ * if it is intended to update the command state.
+ *
+ * @method refresh
+ * @param {CKEDITOR.editor} editor
+ * @param {CKEDITOR.dom.elementPath} path
+ */
+
+/**
+ * Sets the element name used to reflect the command state on selection changes.
+ * If the selection is in a place where the element is not allowed, the command
+ * will be disabled.
+ * Setting this property overrides {@link #contextSensitive} to `true`.
+ *
+ * @property {Boolean} [context=true]
+ */
+
+/**
+ * The editor modes within which the command can be executed. The execution
+ * will have no action if the current mode is not listed in this property.
+ *
+ *             editorInstance.addCommand( 'link', {
+ *                     exec: function( editor ) {
+ *                             // ...
+ *                     },
+ *                     modes: { wysiwyg:1 } // The command is available in wysiwyg mode only.
+ *             } );
+ *
+ * See also {@link CKEDITOR.command#modes}.
+ *
+ * @property {Object} [modes={ wysiwyg:1 }]
+ */
+
+/**
+ * Whether the command should be enabled in the {@link CKEDITOR.editor#setReadOnly read-only mode}.
+ *
+ * @since 4.0
+ * @property {Boolean} [readOnly=false]
+ */
+
+/**
+ * A property that should be set when a command has no keystroke assigned by {@link CKEDITOR.editor#setKeystroke}, but
+ * the keystroke is still supported. For example: `cut`, `copy` and `paste` commands are handled that way.
+ * This property is used when displaying keystroke information in tooltips and context menus. It is used by
+ * {@link CKEDITOR.editor#getCommandKeystroke}.
+ *
+ * @since 4.6.0
+ * @property {Number} fakeKeystroke
+ */
diff --git a/sources/core/config.js b/sources/core/config.js
new file mode 100644 (file)
index 0000000..f0f4aec
--- /dev/null
@@ -0,0 +1,451 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.config} object that stores the
+ * default configuration settings.
+ */
+
+/**
+ * Used in conjunction with the {@link CKEDITOR.config#enterMode}
+ * and {@link CKEDITOR.config#shiftEnterMode} configuration
+ * settings to make the editor produce `<p>` tags when
+ * using the <kbd>Enter</kbd> key.
+ *
+ * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+ * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.ENTER_P = 1;
+
+/**
+ * Used in conjunction with the {@link CKEDITOR.config#enterMode}
+ * and {@link CKEDITOR.config#shiftEnterMode} configuration
+ * settings to make the editor produce `<br>` tags when
+ * using the <kbd>Enter</kbd> key.
+ *
+ * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+ * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+ *
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.ENTER_BR = 2;
+
+/**
+ * Used in conjunction with the {@link CKEDITOR.config#enterMode}
+ * and {@link CKEDITOR.config#shiftEnterMode} configuration
+ * settings to make the editor produce `<div>` tags when
+ * using the <kbd>Enter</kbd> key.
+ *
+ * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+ * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+ *
+ * @readonly
+ * @property {Number} [=3]
+ * @member CKEDITOR
+ */
+CKEDITOR.ENTER_DIV = 3;
+
+/**
+ * Stores default configuration settings. Changes to this object are
+ * reflected in all editor instances, if not specified otherwise for a particular
+ * instance.
+ *
+ * Read more about setting CKEditor configuration in the
+ * [documentation](#!/guide/dev_configuration).
+ *
+ * @class
+ * @singleton
+ */
+CKEDITOR.config = {
+       /**
+        * The URL path to the custom configuration file to be loaded. If not
+        * overwritten with inline configuration, it defaults to the `config.js`
+        * file present in the root of the CKEditor installation directory.
+        *
+        * CKEditor will recursively load custom configuration files defined inside
+        * other custom configuration files.
+        *
+        * Read more about setting CKEditor configuration in the
+        * [documentation](#!/guide/dev_configuration).
+        *
+        *              // Load a specific configuration file.
+        *              CKEDITOR.replace( 'myfield', { customConfig: '/myconfig.js' } );
+        *
+        *              // Do not load any custom configuration file.
+        *              CKEDITOR.replace( 'myfield', { customConfig: '' } );
+        *
+        * @cfg {String} [="<CKEditor folder>/config.js"]
+        */
+       customConfig: 'config.js',
+
+       /**
+        * Whether the element replaced by the editor (usually a `<textarea>`)
+        * is to be updated automatically when posting the form containing the editor.
+        *
+        * @cfg
+        */
+       autoUpdateElement: true,
+
+       /**
+        * The user interface language localization to use. If left empty, the editor
+        * will automatically be localized to the user language. If the user language is not supported,
+        * the language specified in the {@link CKEDITOR.config#defaultLanguage}
+        * configuration setting is used.
+        *
+        * Read more in the [documentation](#!/guide/dev_uilanguage) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/uilanguages.html).
+        *
+        *              // Load the German interface.
+        *              config.language = 'de';
+        *
+        * @cfg
+        */
+       language: '',
+
+       /**
+        * The language to be used if the {@link CKEDITOR.config#language}
+        * setting is left empty and it is not possible to localize the editor to the user language.
+        *
+        * Read more in the [documentation](#!/guide/dev_uilanguage) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/uilanguages.html).
+        *
+        *              config.defaultLanguage = 'it';
+        *
+        * @cfg
+        */
+       defaultLanguage: 'en',
+
+       /**
+        * The writing direction of the language which is used to create editor content.
+        * Allowed values are:
+        *
+        * * `''` (an empty string) &ndash; Indicates that content direction will be the same as either
+        *      the editor UI direction or the page element direction depending on the editor type:
+        *     * [Classic editor](#!/guide/dev_framed) &ndash; The same as the user interface language direction.
+        *     * [Inline editor](#!/guide/dev_inline)&ndash; The same as the editable element text direction.
+        * * `'ltr'` &ndash; Indicates a Left-To-Right text direction (like in English).
+        * * `'rtl'` &ndash; Indicates a Right-To-Left text direction (like in Arabic).
+        *
+        * See the [SDK sample](http://sdk.ckeditor.com/samples/language.html).
+        *
+        * Example:
+        *
+        *              config.contentsLangDirection = 'rtl';
+        *
+        * @cfg
+        */
+       contentsLangDirection: '',
+
+       /**
+        * Sets the behavior of the <kbd>Enter</kbd> key. It also determines other behavior
+        * rules of the editor, like whether the `<br>` element is to be used
+        * as a paragraph separator when indenting text.
+        * The allowed values are the following constants that cause the behavior outlined below:
+        *
+        * * {@link CKEDITOR#ENTER_P} (1) &ndash; New `<p>` paragraphs are created.
+        * * {@link CKEDITOR#ENTER_BR} (2) &ndash; Lines are broken with `<br>` elements.
+        * * {@link CKEDITOR#ENTER_DIV} (3) &ndash; New `<div>` blocks are created.
+        *
+        * **Note**: It is recommended to use the {@link CKEDITOR#ENTER_P} setting because of
+        * its semantic value and correctness. The editor is optimized for this setting.
+        *
+        * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+        *
+        *              // Not recommended.
+        *              config.enterMode = CKEDITOR.ENTER_BR;
+        *
+        * @cfg {Number} [=CKEDITOR.ENTER_P]
+        */
+       enterMode: CKEDITOR.ENTER_P,
+
+       /**
+        * Forces the use of {@link CKEDITOR.config#enterMode} as line break regardless
+        * of the context. If, for example, {@link CKEDITOR.config#enterMode} is set
+        * to {@link CKEDITOR#ENTER_P}, pressing the <kbd>Enter</kbd> key inside a
+        * `<div>` element will create a new paragraph with a `<p>`
+        * instead of a `<div>`.
+        *
+        * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+        *
+        *              // Not recommended.
+        *              config.forceEnterMode = true;
+        *
+        * @since 3.2.1
+        * @cfg
+        */
+       forceEnterMode: false,
+
+       /**
+        * Similarly to the {@link CKEDITOR.config#enterMode} setting, it defines the behavior
+        * of the <kbd>Shift+Enter</kbd> key combination.
+        *
+        * The allowed values are the following constants that cause the behavior outlined below:
+        *
+        * * {@link CKEDITOR#ENTER_P} (1) &ndash; New `<p>` paragraphs are created.
+        * * {@link CKEDITOR#ENTER_BR} (2) &ndash; Lines are broken with `<br>` elements.
+        * * {@link CKEDITOR#ENTER_DIV} (3) &ndash; New `<div>` blocks are created.
+        *
+        * Read more in the [documentation](#!/guide/dev_enterkey) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/enterkey.html).
+        *
+        * Example:
+        *
+        *              config.shiftEnterMode = CKEDITOR.ENTER_P;
+        *
+        * @cfg {Number} [=CKEDITOR.ENTER_BR]
+        */
+       shiftEnterMode: CKEDITOR.ENTER_BR,
+
+       /**
+        * Sets the `DOCTYPE` to be used when loading the editor content as HTML.
+        *
+        *              // Set the DOCTYPE to the HTML 4 (Quirks) mode.
+        *              config.docType = '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">';
+        *
+        * @cfg
+        */
+       docType: '<!DOCTYPE html>',
+
+       /**
+        * Sets the `id` attribute to be used on the `body` element
+        * of the editing area. This can be useful when you intend to reuse the original CSS
+        * file you are using on your live website and want to assign the editor the same ID
+        * as the section that will include the contents. In this way ID-specific CSS rules will
+        * be enabled.
+        *
+        *              config.bodyId = 'contents_id';
+        *
+        * @since 3.1
+        * @cfg
+        */
+       bodyId: '',
+
+       /**
+        * Sets the `class` attribute to be used on the `body` element
+        * of the editing area. This can be useful when you intend to reuse the original CSS
+        * file you are using on your live website and want to assign the editor the same class
+        * as the section that will include the contents. In this way class-specific CSS rules will
+        * be enabled.
+        *
+        *              config.bodyClass = 'contents';
+        *
+        * **Note:** The editor needs to load stylesheets containing contents styles. You can either
+        * copy them to the `contents.css` file that the editor loads by default or set the {@link #contentsCss}
+        * option.
+        *
+        * **Note:** This setting only applies to [classic editor](#!/guide/dev_framed) (the one that uses `iframe`).
+        *
+        * @since 3.1
+        * @cfg
+        */
+       bodyClass: '',
+
+       /**
+        * Indicates whether the content to be edited is being input as a full HTML page.
+        * A full page includes the `<html>`, `<head>`, and `<body>` elements.
+        * The final output will also reflect this setting, including the
+        * `<body>` content only if this setting is disabled.
+        *
+        * Read more in the [documentation](#!/guide/dev_fullpage) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/fullpage.html).
+        *
+        *              config.fullPage = true;
+        *
+        * @since 3.1
+        * @cfg
+        */
+       fullPage: false,
+
+       /**
+        * The height of the editing area that includes the editor content. This configuration
+        * option accepts an integer (to denote a value in pixels) or any CSS-defined length unit
+        * except percent (`%`) values which are not supported.
+        *
+        * **Note:** This configuration option is ignored by [inline editor](#!/guide/dev_inline).
+        *
+        * Read more in the [documentation](#!/guide/dev_size) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/size.html).
+        *
+        *              config.height = 500;            // 500 pixels.
+        *              config.height = '25em';         // CSS length.
+        *              config.height = '300px';        // CSS length.
+        *
+        * @cfg {Number/String}
+        */
+       height: 200,
+
+       /**
+        * The CSS file(s) to be used to apply style to editor content. It should
+        * reflect the CSS used in the target pages where the content is to be
+        * displayed.
+        *
+        * **Note:** This configuration value is ignored by [inline editor](#!/guide/dev_inline)
+        * as it uses the styles that come directly from the page that CKEditor is
+        * rendered on. It is also ignored in the {@link #fullPage full page mode} in
+        * which the developer has full control over the page HTML code.
+        *
+        * Read more in the [documentation](#!/guide/dev_styles) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/styles.html).
+        *
+        *              config.contentsCss = '/css/mysitestyles.css';
+        *              config.contentsCss = [ '/css/mysitestyles.css', '/css/anotherfile.css' ];
+        *
+        * @cfg {String/Array} [contentsCss=CKEDITOR.getUrl( 'contents.css' )]
+        */
+       contentsCss: CKEDITOR.getUrl( 'contents.css' ),
+
+       /**
+        * Comma-separated list of plugins to be used in an editor instance. Note that
+        * the actual plugins that are to be loaded could still be affected by two other settings:
+        * {@link CKEDITOR.config#extraPlugins} and {@link CKEDITOR.config#removePlugins}.
+        *
+        * @cfg {String} [="<default list of plugins>"]
+        */
+       plugins: '', // %REMOVE_LINE%
+
+       /**
+        * A list of additional plugins to be loaded. This setting makes it easier
+        * to add new plugins without having to touch the {@link CKEDITOR.config#plugins} setting.
+        *
+        * **Note:** The most recommended way to
+        * [add CKEditor plugins](http://docs.ckeditor.com/#!/guide/dev_plugins) is through
+        * [CKEditor Builder](http://ckeditor.com/builder). Read more in the
+        * [documentation](#!/guide/dev_plugins).
+        *
+        *              config.extraPlugins = 'myplugin,anotherplugin';
+        *
+        * @cfg
+        */
+       extraPlugins: '',
+
+       /**
+        * A list of plugins that must not be loaded. This setting makes it possible
+        * to avoid loading some plugins defined in the {@link CKEDITOR.config#plugins}
+        * setting without having to touch it.
+        *
+        * **Note:** A plugin required by another plugin cannot be removed and will cause
+        * an error to be thrown. So for example if `contextmenu` is required by `tabletools`,
+        * it can only be removed if `tabletools` is not loaded.
+        *
+        *              config.removePlugins = 'elementspath,save,font';
+        *
+        * @cfg
+        */
+       removePlugins: '',
+
+       /**
+        * A list of regular expressions to be executed on input HTML,
+        * indicating HTML source code that when matched, must **not** be available in the WYSIWYG
+        * mode for editing.
+        *
+        *              config.protectedSource.push( /<\?[\s\S]*?\?>/g );                                                                                       // PHP code
+        *              config.protectedSource.push( /<%[\s\S]*?%>/g );                                                                                         // ASP code
+        *              config.protectedSource.push( /(<asp:[^\>]+>[\s|\S]*?<\/asp:[^\>]+>)|(<asp:[^\>]+\/>)/gi );      // ASP.NET code
+        *
+        * @cfg
+        */
+       protectedSource: [],
+
+       /**
+        * The editor `tabindex` value.
+        *
+        * Read more in the [documentation](#!/guide/dev_tabindex) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/tabindex.html).
+        *
+        *              config.tabIndex = 1;
+        *
+        * @cfg
+        */
+       tabIndex: 0,
+
+       /**
+        * The editor UI outer width. This configuration option accepts an integer
+        * (to denote a value in pixels) or any CSS-defined length unit.
+        *
+        * Unlike the {@link CKEDITOR.config#height} setting, this
+        * one will set the outer width of the entire editor UI, not for the
+        * editing area only.
+        *
+        * **Note:** This configuration option is ignored by [inline editor](#!/guide/dev_inline).
+        *
+        * Read more in the [documentation](#!/guide/dev_size) and see the
+        * [SDK sample](http://sdk.ckeditor.com/samples/size.html).
+        *
+        *              config.width = 850;             // 850 pixels wide.
+        *              config.width = '75%';   // CSS unit.
+        *
+        * @cfg {String/Number}
+        */
+       width: '',
+
+       /**
+        * The base Z-index for floating dialog windows and popups.
+        *
+        *              config.baseFloatZIndex = 2000;
+        *
+        * @cfg
+        */
+       baseFloatZIndex: 10000,
+
+       /**
+        * The keystrokes that are blocked by default as the browser implementation
+        * is buggy. These default keystrokes are handled by the editor.
+        *
+        *              // Default setting.
+        *              config.blockedKeystrokes = [
+        *                      CKEDITOR.CTRL + 66, // Ctrl+B
+        *                      CKEDITOR.CTRL + 73, // Ctrl+I
+        *                      CKEDITOR.CTRL + 85 // Ctrl+U
+        *              ];
+        *
+        * @cfg {Array} [blockedKeystrokes=see example]
+        */
+       blockedKeystrokes: [
+               CKEDITOR.CTRL + 66, // Ctrl+B
+               CKEDITOR.CTRL + 73, // Ctrl+I
+               CKEDITOR.CTRL + 85 // Ctrl+U
+       ]
+};
+
+/**
+ * Indicates that some of the editor features, like alignment and text
+ * direction, should use the "computed value" of the feature to indicate its
+ * on/off state instead of using the "real value".
+ *
+ * If enabled in a Left-To-Right written document, the "Left Justify"
+ * alignment button will be shown as active, even if the alignment style is not
+ * explicitly applied to the current paragraph in the editor.
+ *
+ *             config.useComputedState = false;
+ *
+ * @since 3.4
+ * @cfg {Boolean} [useComputedState=true]
+ */
+
+/**
+ * The base user interface color to be used by the editor. Not all skins are
+ * [compatible with this setting](#!/guide/skin_sdk_chameleon).
+ *
+ * Read more in the [documentation](#!/guide/dev_uicolor) and see the
+ * [SDK sample](http://sdk.ckeditor.com/samples/uicolor.html).
+ *
+ *             // Using a color code.
+ *             config.uiColor = '#AADC6E';
+ *
+ *             // Using an HTML color name.
+ *             config.uiColor = 'Gold';
+ *
+ * @cfg {String} uiColor
+ */
+
+// PACKAGER_RENAME( CKEDITOR.config )
diff --git a/sources/core/creators/inline.js b/sources/core/creators/inline.js
new file mode 100644 (file)
index 0000000..adb402f
--- /dev/null
@@ -0,0 +1,157 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       /** @class CKEDITOR */
+
+       /**
+        * Turns a DOM element with the `contenteditable` attribute set to `true` into a
+        * CKEditor instance. Check {@link CKEDITOR.dtd#$editable} for a list of
+        * allowed element names.
+        *
+        * **Note:** If the DOM element for which inline editing is being enabled does not have
+        * the `contenteditable` attribute set to `true`, the editor will start in read-only mode.
+        *
+        *              <div contenteditable="true" id="content">...</div>
+        *              ...
+        *              CKEDITOR.inline( 'content' );
+        *
+        * It is also possible to create an inline editor from the `<textarea>` element.
+        * If you do so, an additional `<div>` element with editable content will be created
+        * directly after the `<textarea>` element and the `<textarea>` element will be hidden.
+        *
+        * @param {Object/String} element The DOM element or its ID.
+        * @param {Object} [instanceConfig] The specific configurations to apply to this editor instance.
+        * See {@link CKEDITOR.config}.
+        * @returns {CKEDITOR.editor} The editor instance created.
+        */
+       CKEDITOR.inline = function( element, instanceConfig ) {
+               if ( !CKEDITOR.env.isCompatible )
+                       return null;
+
+               element = CKEDITOR.dom.element.get( element );
+
+               // Avoid multiple inline editor instances on the same element.
+               if ( element.getEditor() )
+                       throw 'The editor instance "' + element.getEditor().name + '" is already attached to the provided element.';
+
+               var editor = new CKEDITOR.editor( instanceConfig, element, CKEDITOR.ELEMENT_MODE_INLINE ),
+                       textarea = element.is( 'textarea' ) ? element : null;
+
+               if ( textarea ) {
+                       editor.setData( textarea.getValue(), null, true );
+
+                       //Change element from textarea to div
+                       element = CKEDITOR.dom.element.createFromHtml(
+                               '<div contenteditable="' + !!editor.readOnly + '" class="cke_textarea_inline">' +
+                                       textarea.getValue() +
+                               '</div>',
+                               CKEDITOR.document );
+
+                       element.insertAfter( textarea );
+                       textarea.hide();
+
+                       // Attaching the concrete form.
+                       if ( textarea.$.form )
+                               editor._attachToForm();
+               } else {
+                       // Initial editor data is simply loaded from the page element content to make
+                       // data retrieval possible immediately after the editor creation.
+                       editor.setData( element.getHtml(), null, true );
+               }
+
+               // Once the editor is loaded, start the UI.
+               editor.on( 'loaded', function() {
+                       editor.fire( 'uiReady' );
+
+                       // Enable editing on the element.
+                       editor.editable( element );
+
+                       // Editable itself is the outermost element.
+                       editor.container = element;
+                       editor.ui.contentsElement = element;
+
+                       // Load and process editor data.
+                       editor.setData( editor.getData( 1 ) );
+
+                       // Clean on startup.
+                       editor.resetDirty();
+
+                       editor.fire( 'contentDom' );
+
+                       // Inline editing defaults to "wysiwyg" mode, so plugins don't
+                       // need to make special handling for this "mode-less" environment.
+                       editor.mode = 'wysiwyg';
+                       editor.fire( 'mode' );
+
+                       // The editor is completely loaded for interaction.
+                       editor.status = 'ready';
+                       editor.fireOnce( 'instanceReady' );
+                       CKEDITOR.fire( 'instanceReady', null, editor );
+
+                       // give priority to plugins that relay on editor#loaded for bootstrapping.
+               }, null, null, 10000 );
+
+               // Handle editor destroying.
+               editor.on( 'destroy', function() {
+                       // Remove container from DOM if inline-textarea editor.
+                       // Show <textarea> back again.
+                       if ( textarea ) {
+                               editor.container.clearCustomData();
+                               editor.container.remove();
+                               textarea.show();
+                       }
+
+                       editor.element.clearCustomData();
+
+                       delete editor.element;
+               } );
+
+               return editor;
+       };
+
+       /**
+        * Calls {@link CKEDITOR#inline} for all page elements with
+        * the `contenteditable` attribute set to `true`.
+        *
+        */
+       CKEDITOR.inlineAll = function() {
+               var el, data;
+
+               for ( var name in CKEDITOR.dtd.$editable ) {
+                       var elements = CKEDITOR.document.getElementsByTag( name );
+
+                       for ( var i = 0, len = elements.count(); i < len; i++ ) {
+                               el = elements.getItem( i );
+
+                               if ( el.getAttribute( 'contenteditable' ) == 'true' ) {
+                                       // Fire the "inline" event, making it possible to customize
+                                       // the instance settings and eventually cancel the creation.
+
+                                       data = {
+                                               element: el,
+                                               config: {}
+                                       };
+
+                                       if ( CKEDITOR.fire( 'inline', data ) !== false )
+                                               CKEDITOR.inline( el, data.config );
+                               }
+                       }
+               }
+       };
+
+       CKEDITOR.domReady( function() {
+               !CKEDITOR.disableAutoInline && CKEDITOR.inlineAll();
+       } );
+} )();
+
+/**
+ * Disables creating the inline editor automatically for elements with
+ * the `contenteditable` attribute set to `true`.
+ *
+ *             CKEDITOR.disableAutoInline = true;
+ *
+ * @cfg {Boolean} [disableAutoInline=false]
+ */
diff --git a/sources/core/creators/themedui.js b/sources/core/creators/themedui.js
new file mode 100644 (file)
index 0000000..04927d0
--- /dev/null
@@ -0,0 +1,541 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+ /** @class CKEDITOR */
+
+/**
+ * The class name used to identify `<textarea>` elements to be replaced
+ * by CKEditor instances. Set it to empty/`null` to disable this feature.
+ *
+ *             CKEDITOR.replaceClass = 'rich_editor';
+ *
+ * @cfg {String} [replaceClass='ckeditor']
+ */
+CKEDITOR.replaceClass = 'ckeditor';
+
+( function() {
+       /**
+        * Replaces a `<textarea>` or a DOM element (`<div>`) with a CKEditor
+        * instance. For textareas, the initial value in the editor will be the
+        * textarea value. For DOM elements, their `innerHTML` will be used
+        * instead. It is recommended to use `<textarea>` and `<div>` elements only.
+        *
+        *              <textarea id="myfield" name="myfield"></textarea>
+        *              ...
+        *              CKEDITOR.replace( 'myfield' );
+        *
+        *              var textarea = document.body.appendChild( document.createElement( 'textarea' ) );
+        *              CKEDITOR.replace( textarea );
+        *
+        * @param {Object/String} element The DOM element (textarea), its ID, or name.
+        * @param {Object} [config] The specific configuration to apply to this
+        * editor instance. Configuration set here will override the global CKEditor settings
+        * (see {@link CKEDITOR.config}).
+        * @returns {CKEDITOR.editor} The editor instance created.
+        */
+       CKEDITOR.replace = function( element, config ) {
+               return createInstance( element, config, null, CKEDITOR.ELEMENT_MODE_REPLACE );
+       };
+
+       /**
+        * Creates a new editor instance at the end of a specific DOM element.
+        *
+        *              <!DOCTYPE html>
+        *              <html>
+        *                      <head>
+        *                              <meta charset="utf-8">
+        *                              <title>CKEditor</title>
+        *                              <!-- Make sure the path to CKEditor is correct. -->
+        *                              <script src="/ckeditor/ckeditor.js"></script>
+        *                      </head>
+        *                      <body>
+        *                              <div id="editorSpace"></div>
+        *                              <script>
+        *                                      CKEDITOR.appendTo( 'editorSpace' );
+        *                              </script>
+        *                      </body>
+        *              </html>
+        *
+        * @param {Object/String} element The DOM element, its ID, or name.
+        * @param {Object} [config] The specific configuration to apply to this
+        * editor instance. Configuration set here will override the global CKEditor settings
+        * (see {@link CKEDITOR.config}).
+        * @param {String} [data] Since 3.3. Initial value for the instance.
+        * @returns {CKEDITOR.editor} The editor instance created.
+        */
+       CKEDITOR.appendTo = function( element, config, data ) {
+               return createInstance( element, config, data, CKEDITOR.ELEMENT_MODE_APPENDTO );
+       };
+
+       /**
+        * Replaces all `<textarea>` elements available in the document with
+        * editor instances.
+        *
+        *              // Replace all <textarea> elements in the page.
+        *              CKEDITOR.replaceAll();
+        *
+        *              // Replace all <textarea class="myClassName"> elements in the page.
+        *              CKEDITOR.replaceAll( 'myClassName' );
+        *
+        *              // Selectively replace <textarea> elements, based on a custom evaluation function.
+        *              CKEDITOR.replaceAll( function( textarea, config ) {
+        *                      // A function that needs to be evaluated for the <textarea>
+        *                      // to be replaced. It must explicitly return "false" to ignore a
+        *                      // specific <textarea>.
+        *                      // You can also customize the editor instance by having the function
+        *                      // modify the "config" parameter.
+        *              } );
+        *
+        *              // Full page example where three <textarea> elements are replaced.
+        *              <!DOCTYPE html>
+        *              <html>
+        *                      <head>
+        *                              <meta charset="utf-8">
+        *                              <title>CKEditor</title>
+        *                              <!-- Make sure the path to CKEditor is correct. -->
+        *                              <script src="/ckeditor/ckeditor.js"></script>
+        *                      </head>
+        *                      <body>
+        *                              <textarea name="editor1"></textarea>
+        *                              <textarea name="editor2"></textarea>
+        *                              <textarea name="editor3"></textarea>
+        *                              <script>
+        *                                      // Replace all three <textarea> elements above with CKEditor instances.
+        *                                      CKEDITOR.replaceAll();
+        *                              </script>
+        *                      </body>
+        *              </html>
+        *
+        * @param {String} [className] The `<textarea>` class name.
+        * @param {Function} [evaluator] An evaluation function that must return `true` for a `<textarea>`
+        * to be replaced with the editor. If the function returns `false`, the `<textarea>` element
+        * will not be replaced.
+        */
+       CKEDITOR.replaceAll = function() {
+               var textareas = document.getElementsByTagName( 'textarea' );
+
+               for ( var i = 0; i < textareas.length; i++ ) {
+                       var config = null,
+                               textarea = textareas[ i ];
+
+                       // The "name" and/or "id" attribute must exist.
+                       if ( !textarea.name && !textarea.id )
+                               continue;
+
+                       if ( typeof arguments[ 0 ] == 'string' ) {
+                               // The textarea class name could be passed as the function
+                               // parameter.
+
+                               var classRegex = new RegExp( '(?:^|\\s)' + arguments[ 0 ] + '(?:$|\\s)' );
+
+                               if ( !classRegex.test( textarea.className ) )
+                                       continue;
+                       } else if ( typeof arguments[ 0 ] == 'function' ) {
+                               // An evaluation function could be passed as the function parameter.
+                               // It must explicitly return "false" to ignore a specific <textarea>.
+                               config = {};
+                               if ( arguments[ 0 ]( textarea, config ) === false )
+                                       continue;
+                       }
+
+                       this.replace( textarea, config );
+               }
+       };
+
+       /** @class CKEDITOR.editor */
+
+       /**
+        * Registers an editing mode. This function is to be used mainly by plugins.
+        *
+        * @param {String} mode The mode name.
+        * @param {Function} exec The function that performs the actual mode change.
+        */
+       CKEDITOR.editor.prototype.addMode = function( mode, exec ) {
+               ( this._.modes || ( this._.modes = {} ) )[ mode ] = exec;
+       };
+
+       /**
+        * Changes the editing mode of this editor instance.
+        *
+        * **Note:** The mode switch could be asynchronous depending on the mode provider.
+        * Use the `callback` to hook subsequent code.
+        *
+        *              // Switch to "source" view.
+        *              CKEDITOR.instances.editor1.setMode( 'source' );
+        *              // Switch to "wysiwyg" view and be notified on completion.
+        *              CKEDITOR.instances.editor1.setMode( 'wysiwyg', function() { alert( 'wysiwyg mode loaded!' ); } );
+        *
+        * @param {String} [newMode] If not specified, the {@link CKEDITOR.config#startupMode} will be used.
+        * @param {Function} [callback] Optional callback function which is invoked once the mode switch has succeeded.
+        */
+       CKEDITOR.editor.prototype.setMode = function( newMode, callback ) {
+               var editor = this;
+
+               var modes = this._.modes;
+
+               // Mode loading quickly fails.
+               if ( newMode == editor.mode || !modes || !modes[ newMode ] )
+                       return;
+
+               editor.fire( 'beforeSetMode', newMode );
+
+               if ( editor.mode ) {
+                       var isDirty = editor.checkDirty(),
+                               previousModeData = editor._.previousModeData,
+                               currentData,
+                               unlockSnapshot = 0;
+
+                       editor.fire( 'beforeModeUnload' );
+
+                       // Detach the current editable. While detaching editable will set
+                       // cached editor's data (with internal setData call). We use this
+                       // data below to avoid two getData() calls in a row.
+                       editor.editable( 0 );
+
+                       editor._.previousMode = editor.mode;
+                       // Get cached data, which was set while detaching editable.
+                       editor._.previousModeData = currentData = editor.getData( 1 );
+
+                       // If data has not been modified in the mode which we are currently leaving,
+                       // avoid making snapshot right after initializing new mode.
+                       // http://dev.ckeditor.com/ticket/5217#comment:20
+                       // Tested by:
+                       // 'test switch mode with unrecoreded, inner HTML specific content (boguses)'
+                       // 'test switch mode with unrecoreded, inner HTML specific content (boguses) plus changes in source mode'
+                       if ( editor.mode == 'source' && previousModeData == currentData ) {
+                               // We need to make sure that unlockSnapshot will update the last snapshot
+                               // (will not create new one) if lockSnapshot is not called on outdated snapshots stack.
+                               // Additionally, forceUpdate prevents from making content image now, which is useless
+                               // (because it equals editor data not inner HTML).
+                               editor.fire( 'lockSnapshot', { forceUpdate: true } );
+                               unlockSnapshot = 1;
+                       }
+
+                       // Clear up the mode space.
+                       editor.ui.space( 'contents' ).setHtml( '' );
+
+                       editor.mode = '';
+               } else {
+                       editor._.previousModeData = editor.getData( 1 );
+               }
+
+               // Fire the mode handler.
+               this._.modes[ newMode ]( function() {
+                       // Set the current mode.
+                       editor.mode = newMode;
+
+                       if ( isDirty !== undefined )
+                               !isDirty && editor.resetDirty();
+
+                       if ( unlockSnapshot )
+                               editor.fire( 'unlockSnapshot' );
+                       // Since snapshot made on dataReady (which normally catches changes done by setData)
+                       // won't work because editor.mode was not set yet (it's set in this function), we need
+                       // to make special snapshot for changes done in source mode here.
+                       else if ( newMode == 'wysiwyg' )
+                               editor.fire( 'saveSnapshot' );
+
+                       // Delay to avoid race conditions (setMode inside setMode).
+                       setTimeout( function() {
+                               editor.fire( 'mode' );
+                               callback && callback.call( editor );
+                       }, 0 );
+               } );
+       };
+
+       /**
+        * Resizes the editor interface.
+        *
+        *              editor.resize( 900, 300 );
+        *
+        *              editor.resize( '100%', 450, true );
+        *
+        * @param {Number/String} width The new width. It can be an integer denoting a value
+        * in pixels or a CSS size value with unit.
+        * @param {Number/String} height The new height. It can be an integer denoting a value
+        * in pixels or a CSS size value with unit.
+        * @param {Boolean} [isContentHeight] Indicates that the provided height is to
+        * be applied to the editor content area, and not to the entire editor
+        * interface. Defaults to `false`.
+        * @param {Boolean} [resizeInner] Indicates that it is the inner interface
+        * element that must be resized, not the outer element. The default theme
+        * defines the editor interface inside a pair of `<span>` elements
+        * (`<span><span>...</span></span>`). By default the first,
+        * outer `<span>` element receives the sizes. If this parameter is set to
+        * `true`, the second, inner `<span>` is resized instead.
+        */
+       CKEDITOR.editor.prototype.resize = function( width, height, isContentHeight, resizeInner ) {
+               var container = this.container,
+                       contents = this.ui.space( 'contents' ),
+                       contentsFrame = CKEDITOR.env.webkit && this.document && this.document.getWindow().$.frameElement,
+                       outer;
+
+               if ( resizeInner ) {
+                       outer = this.container.getFirst( function( node ) {
+                               return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_inner' );
+                       } );
+               } else {
+                       outer = container;
+               }
+
+               // Set as border box width. (#5353)
+               outer.setSize( 'width', width, true );
+
+               // WebKit needs to refresh the iframe size to avoid rendering issues. (1/2) (#8348)
+               contentsFrame && ( contentsFrame.style.width = '1%' );
+
+               // Get the height delta between the outer table and the content area.
+               var contentsOuterDelta = ( outer.$.offsetHeight || 0 ) - ( contents.$.clientHeight || 0 ),
+
+               // If we're setting the content area's height, then we don't need the delta.
+                       resultContentsHeight = Math.max( height - ( isContentHeight ? 0 : contentsOuterDelta ), 0 ),
+                       resultOuterHeight = ( isContentHeight ? height + contentsOuterDelta : height );
+
+               contents.setStyle( 'height', resultContentsHeight + 'px' );
+
+               // WebKit needs to refresh the iframe size to avoid rendering issues. (2/2) (#8348)
+               contentsFrame && ( contentsFrame.style.width = '100%' );
+
+               // Emit a resize event.
+               this.fire( 'resize', {
+                       outerHeight: resultOuterHeight,
+                       contentsHeight: resultContentsHeight,
+                       // Sometimes width is not provided.
+                       outerWidth: width || outer.getSize( 'width' )
+               } );
+       };
+
+       /**
+        * Gets the element that can be used to check the editor size. This method
+        * is mainly used by the [Editor Resize](http://ckeditor.com/addon/resize) plugin, which adds
+        * a UI handle that can be used to resize the editor.
+        *
+        * @param {Boolean} forContents Whether to return the "contents" part of the theme instead of the container.
+        * @returns {CKEDITOR.dom.element} The resizable element.
+        */
+       CKEDITOR.editor.prototype.getResizable = function( forContents ) {
+               return forContents ? this.ui.space( 'contents' ) : this.container;
+       };
+
+       function createInstance( element, config, data, mode ) {
+               if ( !CKEDITOR.env.isCompatible )
+                       return null;
+
+               element = CKEDITOR.dom.element.get( element );
+
+               // Avoid multiple inline editor instances on the same element.
+               if ( element.getEditor() )
+                       throw 'The editor instance "' + element.getEditor().name + '" is already attached to the provided element.';
+
+               // Create the editor instance.
+               var editor = new CKEDITOR.editor( config, element, mode );
+
+               if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
+                       // Do not replace the textarea right now, just hide it. The effective
+                       // replacement will be done later in the editor creation lifecycle.
+                       element.setStyle( 'visibility', 'hidden' );
+
+                       // #8031 Remember if textarea was required and remove the attribute.
+                       editor._.required = element.hasAttribute( 'required' );
+                       element.removeAttribute( 'required' );
+               }
+
+               data && editor.setData( data, null, true );
+
+               // Once the editor is loaded, start the UI.
+               editor.on( 'loaded', function() {
+                       loadTheme( editor );
+
+                       if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE && editor.config.autoUpdateElement && element.$.form )
+                               editor._attachToForm();
+
+                       editor.setMode( editor.config.startupMode, function() {
+                               // Clean on startup.
+                               editor.resetDirty();
+
+                               // Editor is completely loaded for interaction.
+                               editor.status = 'ready';
+                               editor.fireOnce( 'instanceReady' );
+                               CKEDITOR.fire( 'instanceReady', null, editor );
+                       } );
+               } );
+
+               editor.on( 'destroy', destroy );
+               return editor;
+       }
+
+       function destroy() {
+               var editor = this,
+                       container = editor.container,
+                       element = editor.element;
+
+               if ( container ) {
+                       container.clearCustomData();
+                       container.remove();
+               }
+
+               if ( element ) {
+                       element.clearCustomData();
+                       if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
+                               element.show();
+                               if ( editor._.required )
+                                       element.setAttribute( 'required', 'required' );
+                       }
+                       delete editor.element;
+               }
+       }
+
+       function loadTheme( editor ) {
+               var name = editor.name,
+                       element = editor.element,
+                       elementMode = editor.elementMode;
+
+               // Get the HTML for the predefined spaces.
+               var topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html;
+               var bottomHtml = editor.fire( 'uiSpace', { space: 'bottom', html: '' } ).html;
+
+               var themedTpl = new CKEDITOR.template(
+                       '<{outerEl}' +
+                               ' id="cke_{name}"' +
+                               ' class="{id} cke cke_reset cke_chrome cke_editor_{name} cke_{langDir} ' + CKEDITOR.env.cssClass + '" ' +
+                               ' dir="{langDir}"' +
+                               ' lang="{langCode}"' +
+                               ' role="application"' +
+                               ( editor.title ? ' aria-labelledby="cke_{name}_arialbl"' : '' ) +
+                               '>' +
+                               ( editor.title ? '<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' : '' ) +
+                               '<{outerEl} class="cke_inner cke_reset" role="presentation">' +
+                                       '{topHtml}' +
+                                       '<{outerEl} id="{contentId}" class="cke_contents cke_reset" role="presentation"></{outerEl}>' +
+                                       '{bottomHtml}' +
+                               '</{outerEl}>' +
+                       '</{outerEl}>' );
+
+               var container = CKEDITOR.dom.element.createFromHtml( themedTpl.output( {
+                       id: editor.id,
+                       name: name,
+                       langDir: editor.lang.dir,
+                       langCode: editor.langCode,
+                       voiceLabel: editor.title,
+                       topHtml: topHtml ? '<span id="' + editor.ui.spaceId( 'top' ) + '" class="cke_top cke_reset_all" role="presentation" style="height:auto">' + topHtml + '</span>' : '',
+                       contentId: editor.ui.spaceId( 'contents' ),
+                       bottomHtml: bottomHtml ? '<span id="' + editor.ui.spaceId( 'bottom' ) + '" class="cke_bottom cke_reset_all" role="presentation">' + bottomHtml + '</span>' : '',
+                       outerEl: CKEDITOR.env.ie ? 'span' : 'div'       // #9571
+               } ) );
+
+               if ( elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
+                       element.hide();
+                       container.insertAfter( element );
+               } else {
+                       element.append( container );
+               }
+
+               editor.container = container;
+               editor.ui.contentsElement = editor.ui.space( 'contents' );
+
+               // Make top and bottom spaces unelectable, but not content space,
+               // otherwise the editable area would be affected.
+               topHtml && editor.ui.space( 'top' ).unselectable();
+               bottomHtml && editor.ui.space( 'bottom' ).unselectable();
+
+               var width = editor.config.width, height = editor.config.height;
+               if ( width )
+                       container.setStyle( 'width', CKEDITOR.tools.cssLength( width ) );
+
+               // The editor height is applied to the contents space.
+               if ( height )
+                       editor.ui.space( 'contents' ).setStyle( 'height', CKEDITOR.tools.cssLength( height ) );
+
+               // Disable browser context menu for editor's chrome.
+               container.disableContextMenu();
+
+               // Redirect the focus into editor for webkit. (#5713)
+               CKEDITOR.env.webkit && container.on( 'focus', function() {
+                       editor.focus();
+               } );
+
+               editor.fireOnce( 'uiReady' );
+       }
+
+       // Replace all textareas with the default class name.
+       CKEDITOR.domReady( function() {
+               CKEDITOR.replaceClass && CKEDITOR.replaceAll( CKEDITOR.replaceClass );
+       } );
+} )();
+
+/**
+ * The current editing mode. An editing mode basically provides
+ * different ways of editing or viewing the editor content.
+ *
+ *             alert( CKEDITOR.instances.editor1.mode ); // (e.g.) 'wysiwyg'
+ *
+ * @readonly
+ * @property {String} mode
+ */
+
+/**
+ * The mode to load at the editor startup. It depends on the plugins
+ * loaded. By default, the `wysiwyg` and `source` modes are available.
+ *
+ *             config.startupMode = 'source';
+ *
+ * @cfg {String} [startupMode='wysiwyg']
+ * @member CKEDITOR.config
+ */
+CKEDITOR.config.startupMode = 'wysiwyg';
+
+/**
+ * Fired after the editor instance is resized through
+ * the {@link CKEDITOR.editor#method-resize CKEDITOR.resize} method.
+ *
+ * @event resize
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {Object} data Available since CKEditor 4.5.
+ * @param {Number} data.outerHeight The height of the entire area that the editor covers.
+ * @param {Number} data.contentsHeight Editable area height in pixels.
+ * @param {Number} data.outerWidth The width of the entire area that the editor covers.
+ */
+
+/**
+ * Fired before changing the editing mode. See also
+ * {@link #beforeSetMode} and {@link #event-mode}.
+ *
+ * @event beforeModeUnload
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Fired before the editor mode is set. See also
+ * {@link #event-mode} and {@link #beforeModeUnload}.
+ *
+ * @since 3.5.3
+ * @event beforeSetMode
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {String} data The name of the mode which is about to be set.
+ */
+
+/**
+ * Fired after setting the editing mode. See also {@link #beforeSetMode} and {@link #beforeModeUnload}
+ *
+ * @event mode
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Fired when the editor (replacing a `<textarea>` which has a `required` attribute) is empty during form submission.
+ *
+ * This event replaces native required fields validation that the browsers cannot
+ * perform when CKEditor replaces `<textarea>` elements.
+ *
+ * You can cancel this event to prevent the page from submitting data.
+ *
+ *             editor.on( 'required', function( evt ) {
+ *                     alert( 'Article content is required.' );
+ *                     evt.cancel();
+ *             } );
+ *
+ * @event required
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
diff --git a/sources/core/dataprocessor.js b/sources/core/dataprocessor.js
new file mode 100644 (file)
index 0000000..c42eab4
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the "virtual" {@link CKEDITOR.dataProcessor} class, which
+ *             defines the basic structure of data processor objects to be
+ *             set to {@link CKEDITOR.editor.dataProcessor}.
+ */
+
+/**
+ * If defined, points to the data processor which is responsible for translating
+ * and transforming the editor data on input and output.
+ * Generally it will point to an instance of {@link CKEDITOR.htmlDataProcessor},
+ * which handles HTML data. The editor may also handle other data formats by
+ * using different data processors provided by specific plugins.
+ *
+ * @property {CKEDITOR.dataProcessor} dataProcessor
+ * @member CKEDITOR.editor
+ */
+
+/**
+ * Represents a data processor which is responsible for translating and
+ * transforming the editor data on input and output.
+ *
+ * This class is here for documentation purposes only and is not really part of
+ * the API. It serves as the base ("interface") for data processor implementations.
+ *
+ * @class CKEDITOR.dataProcessor
+ * @abstract
+ */
+
+/**
+ * Transforms input data into HTML to be loaded into the editor.
+ * While the editor is able to handle non-HTML data (like BBCode), it can only
+ * handle HTML data at runtime. The role of the data processor is to transform
+ * the input data into HTML through this function.
+ *
+ *             // Tranforming BBCode data, with a custom BBCode data processor available.
+ *             var data = 'This is [b]an example[/b].';
+ *             var html = editor.dataProcessor.toHtml( data ); // '<p>This is <b>an example</b>.</p>'
+ *
+ * @method toHtml
+ * @param {String} data The input data to be transformed.
+ * @param {String} [fixForBody] The tag name to be used if the data must be
+ * fixed because it is supposed to be loaded direcly into the `<body>`
+ * tag. This is generally not used by non-HTML data processors.
+ * @todo fixForBody type - compare to htmlDataProcessor.
+ */
+
+/**
+ * Transforms HTML into data to be output by the editor, in the format
+ * expected by the data processor.
+ *
+ * While the editor is able to handle non-HTML data (like BBCode), it can only
+ * handle HTML data at runtime. The role of the data processor is to transform
+ * the HTML data containined by the editor into a specific data format through
+ * this function.
+ *
+ *             // Tranforming into BBCode data, with a custom BBCode data processor available.
+ *             var html = '<p>This is <b>an example</b>.</p>';
+ *             var data = editor.dataProcessor.toDataFormat( html ); // 'This is [b]an example[/b].'
+ *
+ * @method toDataFormat
+ * @param {String} html The HTML to be transformed.
+ * @param {String} fixForBody The tag name to be used if the output data is
+ * coming from the `<body>` element and may be eventually fixed for it. This is
+ * generally not used by non-HTML data processors.
+ */
diff --git a/sources/core/dom.js b/sources/core/dom.js
new file mode 100644 (file)
index 0000000..84aa21d
--- /dev/null
@@ -0,0 +1,13 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom} object, which contains DOM
+ *             manipulation objects and function.
+ */
+
+CKEDITOR.dom = {};
+
+// PACKAGER_RENAME( CKEDITOR.dom )
diff --git a/sources/core/dom/comment.js b/sources/core/dom/comment.js
new file mode 100644 (file)
index 0000000..4abb453
--- /dev/null
@@ -0,0 +1,53 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.comment} class, which represents
+ *             a DOM comment node.
+ */
+
+/**
+ * Represents a DOM comment node.
+ *
+ *             var nativeNode = document.createComment( 'Example' );
+ *             var comment = new CKEDITOR.dom.comment( nativeNode );
+ *
+ *             var comment = new CKEDITOR.dom.comment( 'Example' );
+ *
+ * @class
+ * @extends CKEDITOR.dom.node
+ * @constructor Creates a comment class instance.
+ * @param {Object/String} comment A native DOM comment node or a string containing
+ * the text to use to create a new comment node.
+ * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
+ * the node in case of new node creation. Defaults to the current document.
+ */
+CKEDITOR.dom.comment = function( comment, ownerDocument ) {
+       if ( typeof comment == 'string' )
+               comment = ( ownerDocument ? ownerDocument.$ : document ).createComment( comment );
+
+       CKEDITOR.dom.domObject.call( this, comment );
+};
+
+CKEDITOR.dom.comment.prototype = new CKEDITOR.dom.node();
+
+CKEDITOR.tools.extend( CKEDITOR.dom.comment.prototype, {
+       /**
+        * The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
+        *
+        * @readonly
+        * @property {Number} [=CKEDITOR.NODE_COMMENT]
+        */
+       type: CKEDITOR.NODE_COMMENT,
+
+       /**
+        * Gets the outer HTML of this comment.
+        *
+        * @returns {String} The HTML `<!-- comment value -->`.
+        */
+       getOuterHtml: function() {
+               return '<!--' + this.$.nodeValue + '-->';
+       }
+} );
diff --git a/sources/core/dom/document.js b/sources/core/dom/document.js
new file mode 100644 (file)
index 0000000..51c5b19
--- /dev/null
@@ -0,0 +1,326 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.document} class which
+ *             represents a DOM document.
+ */
+
+/**
+ * Represents a DOM document.
+ *
+ *             var document = new CKEDITOR.dom.document( document );
+ *
+ * @class
+ * @extends CKEDITOR.dom.domObject
+ * @constructor Creates a document class instance.
+ * @param {Object} domDocument A native DOM document.
+ */
+CKEDITOR.dom.document = function( domDocument ) {
+       CKEDITOR.dom.domObject.call( this, domDocument );
+};
+
+// PACKAGER_RENAME( CKEDITOR.dom.document )
+
+CKEDITOR.dom.document.prototype = new CKEDITOR.dom.domObject();
+
+CKEDITOR.tools.extend( CKEDITOR.dom.document.prototype, {
+       /**
+        * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT}.
+        *
+        * @readonly
+        * @property {Number} [=CKEDITOR.NODE_DOCUMENT]
+        */
+       type: CKEDITOR.NODE_DOCUMENT,
+
+       /**
+        * Appends a CSS file to the document.
+        *
+        *              CKEDITOR.document.appendStyleSheet( '/mystyles.css' );
+        *
+        * @param {String} cssFileUrl The CSS file URL.
+        */
+       appendStyleSheet: function( cssFileUrl ) {
+               if ( this.$.createStyleSheet )
+                       this.$.createStyleSheet( cssFileUrl );
+               else {
+                       var link = new CKEDITOR.dom.element( 'link' );
+                       link.setAttributes( {
+                               rel: 'stylesheet',
+                               type: 'text/css',
+                               href: cssFileUrl
+                       } );
+
+                       this.getHead().append( link );
+               }
+       },
+
+       /**
+        * Creates a CSS stylesheet and inserts it into the document.
+        *
+        * @param cssStyleText {String} CSS style text.
+        * @returns {Object} The created DOM native stylesheet object.
+        */
+       appendStyleText: function( cssStyleText ) {
+               if ( this.$.createStyleSheet ) {
+                       var styleSheet = this.$.createStyleSheet( '' );
+                       styleSheet.cssText = cssStyleText;
+               } else {
+                       var style = new CKEDITOR.dom.element( 'style', this );
+                       style.append( new CKEDITOR.dom.text( cssStyleText, this ) );
+                       this.getHead().append( style );
+               }
+
+               return styleSheet || style.$.sheet;
+       },
+
+       /**
+        * Creates a {@link CKEDITOR.dom.element} instance in this document.
+        *
+        * @param {String} name The name of the element.
+        * @param {Object} [attributesAndStyles]
+        * @param {Object} [attributesAndStyles.attributes] Attributes that will be set.
+        * @param {Object} [attributesAndStyles.styles] Styles that will be set.
+        * @returns {CKEDITOR.dom.element}
+        */
+       createElement: function( name, attribsAndStyles ) {
+               var element = new CKEDITOR.dom.element( name, this );
+
+               if ( attribsAndStyles ) {
+                       if ( attribsAndStyles.attributes )
+                               element.setAttributes( attribsAndStyles.attributes );
+
+                       if ( attribsAndStyles.styles )
+                               element.setStyles( attribsAndStyles.styles );
+               }
+
+               return element;
+       },
+
+       /**
+        * Creates a {@link CKEDITOR.dom.text} instance in this document.
+        *
+        * @param {String} text Value of the text node.
+        * @returns {CKEDITOR.dom.element}
+        */
+       createText: function( text ) {
+               return new CKEDITOR.dom.text( text, this );
+       },
+
+       /**
+        * Moves the selection focus to this document's window.
+        */
+       focus: function() {
+               this.getWindow().focus();
+       },
+
+       /**
+        * Returns the element that is currently designated as the active element in the document.
+        *
+        * **Note:** Only one element can be active at a time in a document.
+        * An active element does not necessarily have focus,
+        * but an element with focus is always the active element in a document.
+        *
+        * @returns {CKEDITOR.dom.element} Active element or `null` if an IE8-9 bug is encountered.
+        * See [#10030](http://dev.ckeditor.com/ticket/10030).
+        */
+       getActive: function() {
+               var $active;
+               try {
+                       $active = this.$.activeElement;
+               } catch ( e ) {
+                       return null;
+               }
+               return new CKEDITOR.dom.element( $active );
+       },
+
+       /**
+        * Gets an element based on its ID.
+        *
+        *              var element = CKEDITOR.document.getById( 'myElement' );
+        *              alert( element.getId() ); // 'myElement'
+        *
+        * @param {String} elementId The element ID.
+        * @returns {CKEDITOR.dom.element} The element instance, or `null` if not found.
+        */
+       getById: function( elementId ) {
+               var $ = this.$.getElementById( elementId );
+               return $ ? new CKEDITOR.dom.element( $ ) : null;
+       },
+
+       /**
+        * Gets a node based on its address. See {@link CKEDITOR.dom.node#getAddress}.
+        *
+        * @param {Array} address
+        * @param {Boolean} [normalized=false]
+        */
+       getByAddress: function( address, normalized ) {
+               var $ = this.$.documentElement;
+
+               for ( var i = 0; $ && i < address.length; i++ ) {
+                       var target = address[ i ];
+
+                       if ( !normalized ) {
+                               $ = $.childNodes[ target ];
+                               continue;
+                       }
+
+                       var currentIndex = -1;
+
+                       for ( var j = 0; j < $.childNodes.length; j++ ) {
+                               var candidate = $.childNodes[ j ];
+
+                               if ( normalized === true && candidate.nodeType == 3 && candidate.previousSibling && candidate.previousSibling.nodeType == 3 )
+                                       continue;
+
+                               currentIndex++;
+
+                               if ( currentIndex == target ) {
+                                       $ = candidate;
+                                       break;
+                               }
+                       }
+               }
+
+               return $ ? new CKEDITOR.dom.node( $ ) : null;
+       },
+
+       /**
+        * Gets elements list based on a given tag name.
+        *
+        * @param {String} tagName The element tag name.
+        * @returns {CKEDITOR.dom.nodeList} The nodes list.
+        */
+       getElementsByTag: function( tagName, namespace ) {
+               if ( !( CKEDITOR.env.ie && ( document.documentMode <= 8 ) ) && namespace )
+                       tagName = namespace + ':' + tagName;
+               return new CKEDITOR.dom.nodeList( this.$.getElementsByTagName( tagName ) );
+       },
+
+       /**
+        * Gets the `<head>` element for this document.
+        *
+        *              var element = CKEDITOR.document.getHead();
+        *              alert( element.getName() ); // 'head'
+        *
+        * @returns {CKEDITOR.dom.element} The `<head>` element.
+        */
+       getHead: function() {
+               var head = this.$.getElementsByTagName( 'head' )[ 0 ];
+               if ( !head )
+                       head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
+               else
+                       head = new CKEDITOR.dom.element( head );
+
+               return head;
+       },
+
+       /**
+        * Gets the `<body>` element for this document.
+        *
+        *              var element = CKEDITOR.document.getBody();
+        *              alert( element.getName() ); // 'body'
+        *
+        * @returns {CKEDITOR.dom.element} The `<body>` element.
+        */
+       getBody: function() {
+               return new CKEDITOR.dom.element( this.$.body );
+       },
+
+       /**
+        * Gets the DOM document element for this document.
+        *
+        * @returns {CKEDITOR.dom.element} The DOM document element.
+        */
+       getDocumentElement: function() {
+               return new CKEDITOR.dom.element( this.$.documentElement );
+       },
+
+       /**
+        * Gets the window object that stores this document.
+        *
+        * @returns {CKEDITOR.dom.window} The window object.
+        */
+       getWindow: function() {
+               return new CKEDITOR.dom.window( this.$.parentWindow || this.$.defaultView );
+       },
+
+       /**
+        * Defines the document content through `document.write`. Note that the
+        * previous document content will be lost (cleaned).
+        *
+        *              document.write(
+        *                      '<html>' +
+        *                              '<head><title>Sample Document</title></head>' +
+        *                              '<body>Document content created by code.</body>' +
+        *                      '</html>'
+        *              );
+        *
+        * @since 3.5
+        * @param {String} html The HTML defining the document content.
+        */
+       write: function( html ) {
+               // Don't leave any history log in IE. (#5657)
+               this.$.open( 'text/html', 'replace' );
+
+               // Support for custom document.domain in IE.
+               //
+               // The script must be appended because if placed before the
+               // doctype, IE will go into quirks mode and mess with
+               // the editable, e.g. by changing its default height.
+               if ( CKEDITOR.env.ie )
+                       html = html.replace( /(?:^\s*<!DOCTYPE[^>]*?>)|^/i, '$&\n<script data-cke-temp="1">(' + CKEDITOR.tools.fixDomain + ')();</script>' );
+
+               this.$.write( html );
+               this.$.close();
+       },
+
+       /**
+        * Wrapper for `querySelectorAll`. Returns a list of elements within this document that match
+        * the specified `selector`.
+        *
+        * **Note:** The returned list is not a live collection (like the result of native `querySelectorAll`).
+        *
+        * @since 4.3
+        * @param {String} selector
+        * @returns {CKEDITOR.dom.nodeList}
+        */
+       find: function( selector ) {
+               return new CKEDITOR.dom.nodeList( this.$.querySelectorAll( selector ) );
+       },
+
+       /**
+        * Wrapper for `querySelector`. Returns the first element within this document that matches
+        * the specified `selector`.
+        *
+        * @since 4.3
+        * @param {String} selector
+        * @returns {CKEDITOR.dom.element}
+        */
+       findOne: function( selector ) {
+               var el = this.$.querySelector( selector );
+
+               return el ? new CKEDITOR.dom.element( el ) : null;
+       },
+
+       /**
+        * Internet Explorer 8 only method. It returns a document fragment which has all HTML5 elements enabled.
+        *
+        * @since 4.3
+        * @private
+        * @returns DocumentFragment
+        */
+       _getHtml5ShivFrag: function() {
+               var $frag = this.getCustomData( 'html5ShivFrag' );
+
+               if ( !$frag ) {
+                       $frag = this.$.createDocumentFragment();
+                       CKEDITOR.tools.enableHtml5Elements( $frag, true );
+                       this.setCustomData( 'html5ShivFrag', $frag );
+               }
+
+               return $frag;
+       }
+} );
diff --git a/sources/core/dom/documentfragment.js b/sources/core/dom/documentfragment.js
new file mode 100644 (file)
index 0000000..1058144
--- /dev/null
@@ -0,0 +1,62 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * DocumentFragment is a "lightweight" or "minimal" Document object. It is
+ * commonly used to extract a portion of a document's tree or to create a new
+ * fragment of a document. Various operations may take document fragment objects
+ * as arguments and result in all the child nodes of the document fragment being
+ * moved to the child list of this node.
+ *
+ * @class
+ * @constructor Creates a document fragment class instance.
+ * @param {CKEDITOR.dom.document/DocumentFragment} [nodeOrDoc=CKEDITOR.document]
+ */
+CKEDITOR.dom.documentFragment = function( nodeOrDoc ) {
+       nodeOrDoc = nodeOrDoc || CKEDITOR.document;
+
+       if ( nodeOrDoc.type == CKEDITOR.NODE_DOCUMENT )
+               this.$ = nodeOrDoc.$.createDocumentFragment();
+       else
+               this.$ = nodeOrDoc;
+};
+
+CKEDITOR.tools.extend( CKEDITOR.dom.documentFragment.prototype, CKEDITOR.dom.element.prototype, {
+       /**
+        * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
+        *
+        * @readonly
+        * @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
+        */
+       type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
+
+       /**
+        * Inserts the document fragment content after the specified node.
+        *
+        * @param {CKEDITOR.dom.node} node
+        */
+       insertAfterNode: function( node ) {
+               node = node.$;
+               node.parentNode.insertBefore( this.$, node.nextSibling );
+       },
+
+       /**
+        * Gets HTML of this document fragment's children.
+        *
+        * @since 4.5
+        * @returns {String} The HTML of this document fragment's children.
+        */
+       getHtml: function() {
+               var container = new CKEDITOR.dom.element( 'div' );
+
+               this.clone( 1, 1 ).appendTo( container );
+
+               return container.getHtml().replace( /\s*data-cke-expando=".*?"/g, '' );
+       }
+}, true, {
+       'append': 1, 'appendBogus': 1, 'clone': 1, 'getFirst': 1, 'getHtml': 1, 'getLast': 1, 'getParent': 1, 'getNext': 1, 'getPrevious': 1,
+       'appendTo': 1, 'moveChildren': 1, 'insertBefore': 1, 'insertAfterNode': 1, 'replace': 1, 'trim': 1, 'type': 1,
+       'ltrim': 1, 'rtrim': 1, 'getDocument': 1, 'getChildCount': 1, 'getChild': 1, 'getChildren': 1
+} );
diff --git a/sources/core/dom/domobject.js b/sources/core/dom/domobject.js
new file mode 100644 (file)
index 0000000..4c593ff
--- /dev/null
@@ -0,0 +1,266 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.editor} class, which is the base
+ *             for other classes representing DOM objects.
+ */
+
+/**
+ * Represents a DOM object. This class is not intended to be used directly. It
+ * serves as the base class for other classes representing specific DOM
+ * objects.
+ *
+ * @class
+ * @mixins CKEDITOR.event
+ * @constructor Creates a domObject class instance.
+ * @param {Object} nativeDomObject A native DOM object.
+ */
+CKEDITOR.dom.domObject = function( nativeDomObject ) {
+       if ( nativeDomObject ) {
+               /**
+                * The native DOM object represented by this class instance.
+                *
+                *              var element = new CKEDITOR.dom.element( 'span' );
+                *              alert( element.$.nodeType ); // '1'
+                *
+                * @readonly
+                * @property {Object}
+                */
+               this.$ = nativeDomObject;
+       }
+};
+
+CKEDITOR.dom.domObject.prototype = ( function() {
+       // Do not define other local variables here. We want to keep the native
+       // listener closures as clean as possible.
+
+       var getNativeListener = function( domObject, eventName ) {
+                       return function( domEvent ) {
+                               // In FF, when reloading the page with the editor focused, it may
+                               // throw an error because the CKEDITOR global is not anymore
+                               // available. So, we check it here first. (#2923)
+                               if ( typeof CKEDITOR != 'undefined' )
+                                       domObject.fire( eventName, new CKEDITOR.dom.event( domEvent ) );
+                       };
+               };
+
+       return {
+
+               /**
+                * Gets the private `_` object which is bound to the native
+                * DOM object using {@link #getCustomData}.
+                *
+                *              var elementA = new CKEDITOR.dom.element( nativeElement );
+                *              elementA.getPrivate().value = 1;
+                *              ...
+                *              var elementB = new CKEDITOR.dom.element( nativeElement );
+                *              elementB.getPrivate().value; // 1
+                *
+                * @returns {Object} The private object.
+                */
+               getPrivate: function() {
+                       var priv;
+
+                       // Get the main private object from the custom data. Create it if not defined.
+                       if ( !( priv = this.getCustomData( '_' ) ) )
+                               this.setCustomData( '_', ( priv = {} ) );
+
+                       return priv;
+               },
+
+               // Docs inherited from event.
+               on: function( eventName ) {
+                       // We customize the "on" function here. The basic idea is that we'll have
+                       // only one listener for a native event, which will then call all listeners
+                       // set to the event.
+
+                       // Get the listeners holder object.
+                       var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
+
+                       if ( !nativeListeners ) {
+                               nativeListeners = {};
+                               this.setCustomData( '_cke_nativeListeners', nativeListeners );
+                       }
+
+                       // Check if we have a listener for that event.
+                       if ( !nativeListeners[ eventName ] ) {
+                               var listener = nativeListeners[ eventName ] = getNativeListener( this, eventName );
+
+                               if ( this.$.addEventListener )
+                                       this.$.addEventListener( eventName, listener, !!CKEDITOR.event.useCapture );
+                               else if ( this.$.attachEvent )
+                                       this.$.attachEvent( 'on' + eventName, listener );
+                       }
+
+                       // Call the original implementation.
+                       return CKEDITOR.event.prototype.on.apply( this, arguments );
+               },
+
+               // Docs inherited from event.
+               removeListener: function( eventName ) {
+                       // Call the original implementation.
+                       CKEDITOR.event.prototype.removeListener.apply( this, arguments );
+
+                       // If we don't have listeners for this event, clean the DOM up.
+                       if ( !this.hasListeners( eventName ) ) {
+                               var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
+                               var listener = nativeListeners && nativeListeners[ eventName ];
+                               if ( listener ) {
+                                       if ( this.$.removeEventListener )
+                                               this.$.removeEventListener( eventName, listener, false );
+                                       else if ( this.$.detachEvent )
+                                               this.$.detachEvent( 'on' + eventName, listener );
+
+                                       delete nativeListeners[ eventName ];
+                               }
+                       }
+               },
+
+               /**
+                * Removes any listener set on this object.
+                *
+                * To avoid memory leaks we must assure that there are no
+                * references left after the object is no longer needed.
+                */
+               removeAllListeners: function() {
+                       var nativeListeners = this.getCustomData( '_cke_nativeListeners' );
+                       for ( var eventName in nativeListeners ) {
+                               var listener = nativeListeners[ eventName ];
+                               if ( this.$.detachEvent )
+                                       this.$.detachEvent( 'on' + eventName, listener );
+                               else if ( this.$.removeEventListener )
+                                       this.$.removeEventListener( eventName, listener, false );
+
+                               delete nativeListeners[ eventName ];
+                       }
+
+                       // Remove events from events object so fire() method will not call
+                       // listeners (#11400).
+                       CKEDITOR.event.prototype.removeAllListeners.call( this );
+               }
+       };
+} )();
+
+( function( domObjectProto ) {
+       var customData = {};
+
+       CKEDITOR.on( 'reset', function() {
+               customData = {};
+       } );
+
+       /**
+        * Determines whether the specified object is equal to the current object.
+        *
+        *              var doc = new CKEDITOR.dom.document( document );
+        *              alert( doc.equals( CKEDITOR.document ) );       // true
+        *              alert( doc == CKEDITOR.document );                      // false
+        *
+        * @param {Object} object The object to compare with the current object.
+        * @returns {Boolean} `true` if the object is equal.
+        */
+       domObjectProto.equals = function( object ) {
+               // Try/Catch to avoid IE permission error when object is from different document.
+               try {
+                       return ( object && object.$ === this.$ );
+               } catch ( er ) {
+                       return false;
+               }
+       };
+
+       /**
+        * Sets a data slot value for this object. These values are shared by all
+        * instances pointing to that same DOM object.
+        *
+        * **Note:** The created data slot is only guaranteed to be available on this unique DOM node,
+        * thus any wish to continue access to it from other element clones (either created by
+        * clone node or from `innerHtml`) will fail. For such usage please use
+        * {@link CKEDITOR.dom.element#setAttribute} instead.
+        *
+        * **Note**: This method does not work on text nodes prior to Internet Explorer 9.
+        *
+        *              var element = new CKEDITOR.dom.element( 'span' );
+        *              element.setCustomData( 'hasCustomData', true );
+        *
+        * @param {String} key A key used to identify the data slot.
+        * @param {Object} value The value to set to the data slot.
+        * @returns {CKEDITOR.dom.domObject} This DOM object instance.
+        * @chainable
+        */
+       domObjectProto.setCustomData = function( key, value ) {
+               var expandoNumber = this.getUniqueId(),
+                       dataSlot = customData[ expandoNumber ] || ( customData[ expandoNumber ] = {} );
+
+               dataSlot[ key ] = value;
+
+               return this;
+       };
+
+       /**
+        * Gets the value set to a data slot in this object.
+        *
+        *              var element = new CKEDITOR.dom.element( 'span' );
+        *              alert( element.getCustomData( 'hasCustomData' ) );              // e.g. 'true'
+        *              alert( element.getCustomData( 'nonExistingKey' ) );             // null
+        *
+        * @param {String} key The key used to identify the data slot.
+        * @returns {Object} This value set to the data slot.
+        */
+       domObjectProto.getCustomData = function( key ) {
+               var expandoNumber = this.$[ 'data-cke-expando' ],
+                       dataSlot = expandoNumber && customData[ expandoNumber ];
+
+               return ( dataSlot && key in dataSlot ) ? dataSlot[ key ] : null;
+       };
+
+       /**
+        * Removes the value in the data slot under the given `key`.
+        *
+        * @param {String} key
+        * @returns {Object} Removed value or `null` if not found.
+        */
+       domObjectProto.removeCustomData = function( key ) {
+               var expandoNumber = this.$[ 'data-cke-expando' ],
+                       dataSlot = expandoNumber && customData[ expandoNumber ],
+                       retval, hadKey;
+
+               if ( dataSlot ) {
+                       retval = dataSlot[ key ];
+                       hadKey = key in dataSlot;
+                       delete dataSlot[ key ];
+               }
+
+               return hadKey ? retval : null;
+       };
+
+       /**
+        * Removes any data stored in this object.
+        * To avoid memory leaks we must assure that there are no
+        * references left after the object is no longer needed.
+        */
+       domObjectProto.clearCustomData = function() {
+               // Clear all event listeners
+               this.removeAllListeners();
+
+               var expandoNumber = this.$[ 'data-cke-expando' ];
+               expandoNumber && delete customData[ expandoNumber ];
+       };
+
+       /**
+        * Gets an ID that can be used to identify this DOM object in
+        * the running session.
+        *
+        * **Note**: This method does not work on text nodes prior to Internet Explorer 9.
+        *
+        * @returns {Number} A unique ID.
+        */
+       domObjectProto.getUniqueId = function() {
+               return this.$[ 'data-cke-expando' ] || ( this.$[ 'data-cke-expando' ] = CKEDITOR.tools.getNextNumber() );
+       };
+
+       // Implement CKEDITOR.event.
+       CKEDITOR.event.implementOn( domObjectProto );
+
+} )( CKEDITOR.dom.domObject.prototype );
diff --git a/sources/core/dom/element.js b/sources/core/dom/element.js
new file mode 100644 (file)
index 0000000..e02ff17
--- /dev/null
@@ -0,0 +1,2183 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.element} class, which
+ *             represents a DOM element.
+ */
+
+/**
+ * Represents a DOM element.
+ *
+ *             // Create a new <span> element.
+ *             var element = new CKEDITOR.dom.element( 'span' );
+ *
+ *             // Create an element based on a native DOM element.
+ *             var element = new CKEDITOR.dom.element( document.getElementById( 'myId' ) );
+ *
+ * @class
+ * @extends CKEDITOR.dom.node
+ * @constructor Creates an element class instance.
+ * @param {Object/String} element A native DOM element or the element name for
+ * new elements.
+ * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
+ * the element in case of element creation.
+ */
+CKEDITOR.dom.element = function( element, ownerDocument ) {
+       if ( typeof element == 'string' )
+               element = ( ownerDocument ? ownerDocument.$ : document ).createElement( element );
+
+       // Call the base constructor (we must not call CKEDITOR.dom.node).
+       CKEDITOR.dom.domObject.call( this, element );
+};
+
+// PACKAGER_RENAME( CKEDITOR.dom.element )
+/**
+ * The the {@link CKEDITOR.dom.element} representing and element. If the
+ * element is a native DOM element, it will be transformed into a valid
+ * CKEDITOR.dom.element object.
+ *
+ *             var element = new CKEDITOR.dom.element( 'span' );
+ *             alert( element == CKEDITOR.dom.element.get( element ) ); // true
+ *
+ *             var element = document.getElementById( 'myElement' );
+ *             alert( CKEDITOR.dom.element.get( element ).getName() ); // (e.g.) 'p'
+ *
+ * @static
+ * @param {String/Object} element Element's id or name or native DOM element.
+ * @returns {CKEDITOR.dom.element} The transformed element.
+ */
+CKEDITOR.dom.element.get = function( element ) {
+       var el = typeof element == 'string' ? document.getElementById( element ) || document.getElementsByName( element )[ 0 ] : element;
+
+       return el && ( el.$ ? el : new CKEDITOR.dom.element( el ) );
+};
+
+CKEDITOR.dom.element.prototype = new CKEDITOR.dom.node();
+
+/**
+ * Creates an instance of the {@link CKEDITOR.dom.element} class based on the
+ * HTML representation of an element.
+ *
+ *             var element = CKEDITOR.dom.element.createFromHtml( '<strong class="anyclass">My element</strong>' );
+ *             alert( element.getName() ); // 'strong'
+ *
+ * @static
+ * @param {String} html The element HTML. It should define only one element in
+ * the "root" level. The "root" element can have child nodes, but not siblings.
+ * @returns {CKEDITOR.dom.element} The element instance.
+ */
+CKEDITOR.dom.element.createFromHtml = function( html, ownerDocument ) {
+       var temp = new CKEDITOR.dom.element( 'div', ownerDocument );
+       temp.setHtml( html );
+
+       // When returning the node, remove it from its parent to detach it.
+       return temp.getFirst().remove();
+};
+
+/**
+ * Sets {@link CKEDITOR.dom.element#setCustomData custom data} on an element in a way that it is later
+ * possible to {@link #clearAllMarkers clear all data} set on all elements sharing the same database.
+ *
+ * This mechanism is very useful when processing some portion of DOM. All markers can later be removed
+ * by calling the {@link #clearAllMarkers} method, hence markers will not leak to second pass of this algorithm.
+ *
+ *             var database = {};
+ *             CKEDITOR.dom.element.setMarker( database, element1, 'foo', 'bar' );
+ *             CKEDITOR.dom.element.setMarker( database, element2, 'oof', [ 1, 2, 3 ] );
+ *
+ *             element1.getCustomData( 'foo' ); // 'bar'
+ *             element2.getCustomData( 'oof' ); // [ 1, 2, 3 ]
+ *
+ *             CKEDITOR.dom.element.clearAllMarkers( database );
+ *
+ *             element1.getCustomData( 'foo' ); // null
+ *
+ * @static
+ * @param {Object} database
+ * @param {CKEDITOR.dom.element} element
+ * @param {String} name
+ * @param {Object} value
+ * @returns {CKEDITOR.dom.element} The element.
+ */
+CKEDITOR.dom.element.setMarker = function( database, element, name, value ) {
+       var id = element.getCustomData( 'list_marker_id' ) || ( element.setCustomData( 'list_marker_id', CKEDITOR.tools.getNextNumber() ).getCustomData( 'list_marker_id' ) ),
+               markerNames = element.getCustomData( 'list_marker_names' ) || ( element.setCustomData( 'list_marker_names', {} ).getCustomData( 'list_marker_names' ) );
+       database[ id ] = element;
+       markerNames[ name ] = 1;
+
+       return element.setCustomData( name, value );
+};
+
+/**
+ * Removes all markers added using this database. See the {@link #setMarker} method for more information.
+ *
+ * @param {Object} database
+ * @static
+ */
+CKEDITOR.dom.element.clearAllMarkers = function( database ) {
+       for ( var i in database )
+               CKEDITOR.dom.element.clearMarkers( database, database[ i ], 1 );
+};
+
+/**
+ * Removes all markers added to this element and removes it from the database if
+ * `removeFromDatabase` was passed. See the {@link #setMarker} method for more information.
+ *
+ *             var database = {};
+ *             CKEDITOR.dom.element.setMarker( database, element1, 'foo', 'bar' );
+ *             CKEDITOR.dom.element.setMarker( database, element2, 'oof', [ 1, 2, 3 ] );
+ *
+ *             element1.getCustomData( 'foo' ); // 'bar'
+ *             element2.getCustomData( 'oof' ); // [ 1, 2, 3 ]
+ *
+ *             CKEDITOR.dom.element.clearMarkers( database, element1, true );
+ *
+ *             element1.getCustomData( 'foo' ); // null
+ *             element2.getCustomData( 'oof' ); // [ 1, 2, 3 ]
+ *
+ * @param {Object} database
+ * @static
+ */
+CKEDITOR.dom.element.clearMarkers = function( database, element, removeFromDatabase ) {
+       var names = element.getCustomData( 'list_marker_names' ),
+               id = element.getCustomData( 'list_marker_id' );
+       for ( var i in names )
+               element.removeCustomData( i );
+       element.removeCustomData( 'list_marker_names' );
+       if ( removeFromDatabase ) {
+               element.removeCustomData( 'list_marker_id' );
+               delete database[ id ];
+       }
+};
+
+( function() {
+       var elementsClassList = document.createElement( '_' ).classList,
+               supportsClassLists = typeof elementsClassList !== 'undefined' && String( elementsClassList.add ).match( /\[Native code\]/gi ) !== null,
+               rclass = /[\n\t\r]/g;
+
+       function hasClass( classNames, className ) {
+               // Source: jQuery.
+               return ( ' ' + classNames + ' ' ).replace( rclass, ' ' ).indexOf( ' ' + className + ' ' ) > -1;
+       }
+
+       CKEDITOR.tools.extend( CKEDITOR.dom.element.prototype, {
+               /**
+                * The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
+                *
+                * @readonly
+                * @property {Number} [=CKEDITOR.NODE_ELEMENT]
+                */
+               type: CKEDITOR.NODE_ELEMENT,
+
+               /**
+                * Adds a CSS class to the element. It appends the class to the
+                * already existing names.
+                *
+                *              var element = new CKEDITOR.dom.element( 'div' );
+                *              element.addClass( 'classA' ); // <div class="classA">
+                *              element.addClass( 'classB' ); // <div class="classA classB">
+                *              element.addClass( 'classA' ); // <div class="classA classB">
+                *
+                * **Note:** Since CKEditor 4.5 this method cannot be used with multiple classes (`'classA classB'`).
+                *
+                * @chainable
+                * @method addClass
+                * @param {String} className The name of the class to be added.
+                */
+               addClass: supportsClassLists ?
+                       function( className ) {
+                               this.$.classList.add( className );
+
+                               return this;
+                       } : function( className ) {
+                               var c = this.$.className;
+                               if ( c ) {
+                                       if ( !hasClass( c, className ) )
+                                               c += ' ' + className;
+                               }
+                               this.$.className = c || className;
+
+                               return this;
+                       },
+
+               /**
+                * Removes a CSS class name from the elements classes. Other classes
+                * remain untouched.
+                *
+                *              var element = new CKEDITOR.dom.element( 'div' );
+                *              element.addClass( 'classA' );           // <div class="classA">
+                *              element.addClass( 'classB' );           // <div class="classA classB">
+                *              element.removeClass( 'classA' );        // <div class="classB">
+                *              element.removeClass( 'classB' );        // <div>
+                *
+                * @chainable
+                * @method removeClass
+                * @param {String} className The name of the class to remove.
+                */
+               removeClass: supportsClassLists ?
+                       function( className ) {
+                               var $ = this.$;
+                               $.classList.remove( className );
+
+                               if ( !$.className )
+                                       $.removeAttribute( 'class' );
+
+                               return this;
+                       } : function( className ) {
+                               var c = this.getAttribute( 'class' );
+                               if ( c && hasClass( c, className ) ) {
+                                       c = c
+                                               .replace( new RegExp( '(?:^|\\s+)' + className + '(?=\\s|$)' ), '' )
+                                               .replace( /^\s+/, '' );
+
+                                       if ( c )
+                                               this.setAttribute( 'class', c );
+                                       else
+                                               this.removeAttribute( 'class' );
+                               }
+
+                               return this;
+                       },
+
+               /**
+                * Checks if element has class name.
+                *
+                * @param {String} className
+                * @returns {Boolean}
+                */
+               hasClass: function( className ) {
+                       return hasClass( this.$.className, className );
+               },
+
+               /**
+                * Append a node as a child of this element.
+                *
+                *              var p = new CKEDITOR.dom.element( 'p' );
+                *
+                *              var strong = new CKEDITOR.dom.element( 'strong' );
+                *              p.append( strong );
+                *
+                *              var em = p.append( 'em' );
+                *
+                *              // Result: '<p><strong></strong><em></em></p>'
+                *
+                * @param {CKEDITOR.dom.node/String} node The node or element name to be appended.
+                * @param {Boolean} [toStart=false] Indicates that the element is to be appended at the start.
+                * @returns {CKEDITOR.dom.node} The appended node.
+                */
+               append: function( node, toStart ) {
+                       if ( typeof node == 'string' )
+                               node = this.getDocument().createElement( node );
+
+                       if ( toStart )
+                               this.$.insertBefore( node.$, this.$.firstChild );
+                       else
+                               this.$.appendChild( node.$ );
+
+                       return node;
+               },
+
+               /**
+                * Append HTML as a child(ren) of this element.
+                *
+                * @param {String} html
+                */
+               appendHtml: function( html ) {
+                       if ( !this.$.childNodes.length )
+                               this.setHtml( html );
+                       else {
+                               var temp = new CKEDITOR.dom.element( 'div', this.getDocument() );
+                               temp.setHtml( html );
+                               temp.moveChildren( this );
+                       }
+               },
+
+               /**
+                * Append text to this element.
+                *
+                *              var p = new CKEDITOR.dom.element( 'p' );
+                *              p.appendText( 'This is' );
+                *              p.appendText( ' some text' );
+                *
+                *              // Result: '<p>This is some text</p>'
+                *
+                * @param {String} text The text to be appended.
+                */
+               appendText: function( text ) {
+                       // On IE8 it is impossible to append node to script tag, so we use its text.
+                       // On the contrary, on Safari the text property is unpredictable in links. (#13232)
+                       if ( this.$.text != null && CKEDITOR.env.ie && CKEDITOR.env.version < 9 )
+                               this.$.text += text;
+                       else
+                               this.append( new CKEDITOR.dom.text( text ) );
+               },
+
+               /**
+                * Appends a `<br>` filler element to this element if the filler is not present already.
+                * By default filler is appended only if {@link CKEDITOR.env#needsBrFiller} is `true`,
+                * however when `force` is set to `true` filler will be appended regardless of the environment.
+                *
+                * @param {Boolean} [force] Append filler regardless of the environment.
+                */
+               appendBogus: function( force ) {
+                       if ( !force && !CKEDITOR.env.needsBrFiller )
+                               return;
+
+                       var lastChild = this.getLast();
+
+                       // Ignore empty/spaces text.
+                       while ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.rtrim( lastChild.getText() ) )
+                               lastChild = lastChild.getPrevious();
+                       if ( !lastChild || !lastChild.is || !lastChild.is( 'br' ) ) {
+                               var bogus = this.getDocument().createElement( 'br' );
+
+                               CKEDITOR.env.gecko && bogus.setAttribute( 'type', '_moz' );
+
+                               this.append( bogus );
+                       }
+               },
+
+               /**
+                * Breaks one of the ancestor element in the element position, moving
+                * this element between the broken parts.
+                *
+                *              // Before breaking:
+                *              //              <b>This <i>is some<span /> sample</i> test text</b>
+                *              // If "element" is <span /> and "parent" is <i>:
+                *              //              <b>This <i>is some</i><span /><i> sample</i> test text</b>
+                *              element.breakParent( parent );
+                *
+                *              // Before breaking:
+                *              //              <b>This <i>is some<span /> sample</i> test text</b>
+                *              // If "element" is <span /> and "parent" is <b>:
+                *              //              <b>This <i>is some</i></b><span /><b><i> sample</i> test text</b>
+                *              element.breakParent( parent );
+                *
+                * @param {CKEDITOR.dom.element} parent The anscestor element to get broken.
+                * @param {Boolean} [cloneId=false] Whether to preserve ancestor ID attributes while breaking.
+                */
+               breakParent: function( parent, cloneId ) {
+                       var range = new CKEDITOR.dom.range( this.getDocument() );
+
+                       // We'll be extracting part of this element, so let's use our
+                       // range to get the correct piece.
+                       range.setStartAfter( this );
+                       range.setEndAfter( parent );
+
+                       // Extract it.
+                       var docFrag = range.extractContents( false, cloneId || false ),
+                               tmpElement,
+                               current;
+
+                       // Move the element outside the broken element.
+                       range.insertNode( this.remove() );
+
+                       // In case of Internet Explorer, we must check if there is no background-color
+                       // added to the element. In such case, we have to overwrite it to prevent "switching it off"
+                       // by a browser (#14667).
+                       if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {
+                               tmpElement = new CKEDITOR.dom.element( 'div' );
+
+                               while ( current = docFrag.getFirst() ) {
+                                       if ( current.$.style.backgroundColor ) {
+                                               // This is a necessary hack to make sure that IE will track backgroundColor CSS property, see
+                                               // http://dev.ckeditor.com/ticket/14667#comment:8 for more details.
+                                               current.$.style.backgroundColor = current.$.style.backgroundColor;
+                                       }
+
+                                       tmpElement.append( current );
+                               }
+
+                               // Re-insert the extracted piece after the element.
+                               tmpElement.insertAfter( this );
+                               tmpElement.remove( true );
+                       } else {
+                               // Re-insert the extracted piece after the element.
+                               docFrag.insertAfterNode( this );
+                       }
+               },
+
+               /**
+                * Checks if this element contains given node.
+                *
+                * @method
+                * @param {CKEDITOR.dom.node} node
+                * @returns {Boolean}
+                */
+               contains: !document.compareDocumentPosition ?
+                       function( node ) {
+                               var $ = this.$;
+
+                               return node.type != CKEDITOR.NODE_ELEMENT ? $.contains( node.getParent().$ ) : $ != node.$ && $.contains( node.$ );
+                       } : function( node ) {
+                               return !!( this.$.compareDocumentPosition( node.$ ) & 16 );
+                       },
+
+               /**
+                * Moves the selection focus to this element.
+                *
+                *              var element = CKEDITOR.document.getById( 'myTextarea' );
+                *              element.focus();
+                *
+                * @method
+                * @param  {Boolean} defer Whether to asynchronously defer the
+                * execution by 100 ms.
+                */
+               focus: ( function() {
+                       function exec() {
+                               // IE throws error if the element is not visible.
+                               try {
+                                       this.$.focus();
+                               } catch ( e ) {}
+                       }
+
+                       return function( defer ) {
+                               if ( defer )
+                                       CKEDITOR.tools.setTimeout( exec, 100, this );
+                               else
+                                       exec.call( this );
+                       };
+               } )(),
+
+               /**
+                * Gets the inner HTML of this element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' );
+                *              alert( element.getHtml() ); // '<b>Example</b>'
+                *
+                * @returns {String} The inner HTML of this element.
+                */
+               getHtml: function() {
+                       var retval = this.$.innerHTML;
+                       // Strip <?xml:namespace> tags in IE. (#3341).
+                       return CKEDITOR.env.ie ? retval.replace( /<\?[^>]*>/g, '' ) : retval;
+               },
+
+               /**
+                * Gets the outer (inner plus tags) HTML of this element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div class="bold"><b>Example</b></div>' );
+                *              alert( element.getOuterHtml() ); // '<div class="bold"><b>Example</b></div>'
+                *
+                * @returns {String} The outer HTML of this element.
+                */
+               getOuterHtml: function() {
+                       if ( this.$.outerHTML ) {
+                               // IE includes the <?xml:namespace> tag in the outerHTML of
+                               // namespaced element. So, we must strip it here. (#3341)
+                               return this.$.outerHTML.replace( /<\?[^>]*>/, '' );
+                       }
+
+                       var tmpDiv = this.$.ownerDocument.createElement( 'div' );
+                       tmpDiv.appendChild( this.$.cloneNode( true ) );
+                       return tmpDiv.innerHTML;
+               },
+
+               /**
+                * Retrieve the bounding rectangle of the current element, in pixels,
+                * relative to the upper-left corner of the browser's client area.
+                *
+                * @returns {Object} The dimensions of the DOM element including
+                * `left`, `top`, `right`, `bottom`, `width` and `height`.
+                */
+               getClientRect: function() {
+                       // http://help.dottoro.com/ljvmcrrn.php
+                       var rect = CKEDITOR.tools.extend( {}, this.$.getBoundingClientRect() );
+
+                       !rect.width && ( rect.width = rect.right - rect.left );
+                       !rect.height && ( rect.height = rect.bottom - rect.top );
+
+                       return rect;
+               },
+
+               /**
+                * Sets the inner HTML of this element.
+                *
+                *              var p = new CKEDITOR.dom.element( 'p' );
+                *              p.setHtml( '<b>Inner</b> HTML' );
+                *
+                *              // Result: '<p><b>Inner</b> HTML</p>'
+                *
+                * @method
+                * @param {String} html The HTML to be set for this element.
+                * @returns {String} The inserted HTML.
+                */
+               setHtml: ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) ?
+                       // old IEs throws error on HTML manipulation (through the "innerHTML" property)
+                       // on the element which resides in an DTD invalid position,  e.g. <span><div></div></span>
+                       // fortunately it can be worked around with DOM manipulation.
+                       function( html ) {
+                               try {
+                                       var $ = this.$;
+
+                                       // Fix the case when setHtml is called on detached element.
+                                       // HTML5 shiv used for document in which this element was created
+                                       // won't affect that detached element. So get document fragment with
+                                       // all HTML5 elements enabled and set innerHTML while this element is appended to it.
+                                       if ( this.getParent() )
+                                               return ( $.innerHTML = html );
+                                       else {
+                                               var $frag = this.getDocument()._getHtml5ShivFrag();
+                                               $frag.appendChild( $ );
+                                               $.innerHTML = html;
+                                               $frag.removeChild( $ );
+
+                                               return html;
+                                       }
+                               }
+                               catch ( e ) {
+                                       this.$.innerHTML = '';
+
+                                       var temp = new CKEDITOR.dom.element( 'body', this.getDocument() );
+                                       temp.$.innerHTML = html;
+
+                                       var children = temp.getChildren();
+                                       while ( children.count() )
+                                               this.append( children.getItem( 0 ) );
+
+                                       return html;
+                               }
+                       } : function( html ) {
+                               return ( this.$.innerHTML = html );
+                       },
+
+               /**
+                * Sets the element contents as plain text.
+                *
+                *              var element = new CKEDITOR.dom.element( 'div' );
+                *              element.setText( 'A > B & C < D' );
+                *              alert( element.innerHTML ); // 'A &gt; B &amp; C &lt; D'
+                *
+                * @param {String} text The text to be set.
+                * @returns {String} The inserted text.
+                */
+               setText: ( function() {
+                       var supportsTextContent = document.createElement( 'p' );
+                       supportsTextContent.innerHTML = 'x';
+                       supportsTextContent = supportsTextContent.textContent;
+
+                       return function( text ) {
+                               this.$[ supportsTextContent ? 'textContent' : 'innerText' ] = text;
+                       };
+               } )(),
+
+               /**
+                * Gets the value of an element attribute.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<input type="text" />' );
+                *              alert( element.getAttribute( 'type' ) ); // 'text'
+                *
+                * @method
+                * @param {String} name The attribute name.
+                * @returns {String} The attribute value or null if not defined.
+                */
+               getAttribute: ( function() {
+                       var standard = function( name ) {
+                                       return this.$.getAttribute( name, 2 );
+                               };
+
+                       if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ) {
+                               return function( name ) {
+                                       switch ( name ) {
+                                               case 'class':
+                                                       name = 'className';
+                                                       break;
+
+                                               case 'http-equiv':
+                                                       name = 'httpEquiv';
+                                                       break;
+
+                                               case 'name':
+                                                       return this.$.name;
+
+                                               case 'tabindex':
+                                                       var tabIndex = standard.call( this, name );
+
+                                                       // IE returns tabIndex=0 by default for all
+                                                       // elements. For those elements,
+                                                       // getAtrribute( 'tabindex', 2 ) returns 32768
+                                                       // instead. So, we must make this check to give a
+                                                       // uniform result among all browsers.
+                                                       if ( tabIndex !== 0 && this.$.tabIndex === 0 )
+                                                               tabIndex = null;
+
+                                                       return tabIndex;
+
+                                               case 'checked':
+                                                       var attr = this.$.attributes.getNamedItem( name ),
+                                                               attrValue = attr.specified ? attr.nodeValue // For value given by parser.
+                                                               : this.$.checked; // For value created via DOM interface.
+
+                                                       return attrValue ? 'checked' : null;
+
+                                               case 'hspace':
+                                               case 'value':
+                                                       return this.$[ name ];
+
+                                               case 'style':
+                                                       // IE does not return inline styles via getAttribute(). See #2947.
+                                                       return this.$.style.cssText;
+
+                                               case 'contenteditable':
+                                               case 'contentEditable':
+                                                       return this.$.attributes.getNamedItem( 'contentEditable' ).specified ? this.$.getAttribute( 'contentEditable' ) : null;
+                                       }
+
+                                       return standard.call( this, name );
+                               };
+                       } else {
+                               return standard;
+                       }
+               } )(),
+
+               /**
+                * Gets the values of all element attributes.
+                *
+                * @param {Array} exclude The names of attributes to be excluded from the returned object.
+                * @return {Object} An object containing all element attributes with their values.
+                */
+               getAttributes: function( exclude ) {
+                       var attributes = {},
+                               attrDefs = this.$.attributes,
+                               i;
+
+                       exclude = CKEDITOR.tools.isArray( exclude ) ? exclude : [];
+
+                       for ( i = 0; i < attrDefs.length; i++ ) {
+                               if ( CKEDITOR.tools.indexOf( exclude, attrDefs[ i ].name ) === -1 ) {
+                                       attributes[ attrDefs[ i ].name ] = attrDefs[ i ].value;
+                               }
+                       }
+
+                       return attributes;
+               },
+
+               /**
+                * Gets the nodes list containing all children of this element.
+                *
+                * @returns {CKEDITOR.dom.nodeList}
+                */
+               getChildren: function() {
+                       return new CKEDITOR.dom.nodeList( this.$.childNodes );
+               },
+
+               /**
+                * Gets the current computed value of one of the element CSS style
+                * properties.
+                *
+                *              var element = new CKEDITOR.dom.element( 'span' );
+                *              alert( element.getComputedStyle( 'display' ) ); // 'inline'
+                *
+                * @method
+                * @param {String} propertyName The style property name.
+                * @returns {String} The property value.
+                */
+               getComputedStyle: ( document.defaultView && document.defaultView.getComputedStyle ) ?
+                               function( propertyName ) {
+                                       var style = this.getWindow().$.getComputedStyle( this.$, null );
+
+                                       // Firefox may return null if we call the above on a hidden iframe. (#9117)
+                                       return style ? style.getPropertyValue( propertyName ) : '';
+                               } : function( propertyName ) {
+                                       return this.$.currentStyle[ CKEDITOR.tools.cssStyleToDomStyle( propertyName ) ];
+                               },
+
+               /**
+                * Gets the DTD entries for this element.
+                *
+                * @returns {Object} An object containing the list of elements accepted
+                * by this element.
+                */
+               getDtd: function() {
+                       var dtd = CKEDITOR.dtd[ this.getName() ];
+
+                       this.getDtd = function() {
+                               return dtd;
+                       };
+
+                       return dtd;
+               },
+
+               /**
+                * Gets all this element's descendants having given tag name.
+                *
+                * @method
+                * @param {String} tagName
+                */
+               getElementsByTag: CKEDITOR.dom.document.prototype.getElementsByTag,
+
+               /**
+                * Gets the computed tabindex for this element.
+                *
+                *              var element = CKEDITOR.document.getById( 'myDiv' );
+                *              alert( element.getTabIndex() ); // (e.g.) '-1'
+                *
+                * @method
+                * @returns {Number} The tabindex value.
+                */
+               getTabIndex: function() {
+                       var tabIndex = this.$.tabIndex;
+
+                       // IE returns tabIndex=0 by default for all elements. In
+                       // those cases we must check that the element really has
+                       // the tabindex attribute set to zero, or it is one of
+                       // those element that should have zero by default.
+                       if ( tabIndex === 0 && !CKEDITOR.dtd.$tabIndex[ this.getName() ] && parseInt( this.getAttribute( 'tabindex' ), 10 ) !== 0 )
+                               return -1;
+
+                       return tabIndex;
+               },
+
+               /**
+                * Gets the text value of this element.
+                *
+                * Only in IE (which uses innerText), `<br>` will cause linebreaks,
+                * and sucessive whitespaces (including line breaks) will be reduced to
+                * a single space. This behavior is ok for us, for now. It may change
+                * in the future.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div>Sample <i>text</i>.</div>' );
+                *              alert( <b>element.getText()</b> ); // 'Sample text.'
+                *
+                * @returns {String} The text value.
+                */
+               getText: function() {
+                       return this.$.textContent || this.$.innerText || '';
+               },
+
+               /**
+                * Gets the window object that contains this element.
+                *
+                * @returns {CKEDITOR.dom.window} The window object.
+                */
+               getWindow: function() {
+                       return this.getDocument().getWindow();
+               },
+
+               /**
+                * Gets the value of the `id` attribute of this element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<p id="myId"></p>' );
+                *              alert( element.getId() ); // 'myId'
+                *
+                * @returns {String} The element id, or null if not available.
+                */
+               getId: function() {
+                       return this.$.id || null;
+               },
+
+               /**
+                * Gets the value of the `name` attribute of this element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<input name="myName"></input>' );
+                *              alert( <b>element.getNameAtt()</b> ); // 'myName'
+                *
+                * @returns {String} The element name, or null if not available.
+                */
+               getNameAtt: function() {
+                       return this.$.name || null;
+               },
+
+               /**
+                * Gets the element name (tag name). The returned name is guaranteed to
+                * be always full lowercased.
+                *
+                *              var element = new CKEDITOR.dom.element( 'span' );
+                *              alert( element.getName() ); // 'span'
+                *
+                * @returns {String} The element name.
+                */
+               getName: function() {
+                       // Cache the lowercased name inside a closure.
+                       var nodeName = this.$.nodeName.toLowerCase();
+
+                       if ( CKEDITOR.env.ie && ( document.documentMode <= 8 ) ) {
+                               var scopeName = this.$.scopeName;
+                               if ( scopeName != 'HTML' )
+                                       nodeName = scopeName.toLowerCase() + ':' + nodeName;
+                       }
+
+                       this.getName = function() {
+                               return nodeName;
+                       };
+
+                       return this.getName();
+               },
+
+               /**
+                * Gets the value set to this element. This value is usually available
+                * for form field elements.
+                *
+                * @returns {String} The element value.
+                */
+               getValue: function() {
+                       return this.$.value;
+               },
+
+               /**
+                * Gets the first child node of this element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b></div>' );
+                *              var first = element.getFirst();
+                *              alert( first.getName() ); // 'b'
+                *
+                * @param {Function} evaluator Filtering the result node.
+                * @returns {CKEDITOR.dom.node} The first child node or null if not available.
+                */
+               getFirst: function( evaluator ) {
+                       var first = this.$.firstChild,
+                               retval = first && new CKEDITOR.dom.node( first );
+                       if ( retval && evaluator && !evaluator( retval ) )
+                               retval = retval.getNext( evaluator );
+
+                       return retval;
+               },
+
+               /**
+                * See {@link #getFirst}.
+                *
+                * @param {Function} evaluator Filtering the result node.
+                * @returns {CKEDITOR.dom.node}
+                */
+               getLast: function( evaluator ) {
+                       var last = this.$.lastChild,
+                               retval = last && new CKEDITOR.dom.node( last );
+                       if ( retval && evaluator && !evaluator( retval ) )
+                               retval = retval.getPrevious( evaluator );
+
+                       return retval;
+               },
+
+               /**
+                * Gets CSS style value.
+                *
+                * @param {String} name The CSS property name.
+                * @returns {String} Style value.
+                */
+               getStyle: function( name ) {
+                       return this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ];
+               },
+
+               /**
+                * Checks if the element name matches the specified criteria.
+                *
+                *              var element = new CKEDITOR.element( 'span' );
+                *              alert( element.is( 'span' ) );                  // true
+                *              alert( element.is( 'p', 'span' ) );             // true
+                *              alert( element.is( 'p' ) );                             // false
+                *              alert( element.is( 'p', 'div' ) );              // false
+                *              alert( element.is( { p:1,span:1 } ) );  // true
+                *
+                * @param {String.../Object} name One or more names to be checked, or a {@link CKEDITOR.dtd} object.
+                * @returns {Boolean} `true` if the element name matches any of the names.
+                */
+               is: function() {
+                       var name = this.getName();
+
+                       // Check against the specified DTD liternal.
+                       if ( typeof arguments[ 0 ] == 'object' )
+                               return !!arguments[ 0 ][ name ];
+
+                       // Check for tag names
+                       for ( var i = 0; i < arguments.length; i++ ) {
+                               if ( arguments[ i ] == name )
+                                       return true;
+                       }
+                       return false;
+               },
+
+               /**
+                * Decide whether one element is able to receive cursor.
+                *
+                * @param {Boolean} [textCursor=true] Only consider element that could receive text child.
+                */
+               isEditable: function( textCursor ) {
+                       var name = this.getName();
+
+                       if ( this.isReadOnly() || this.getComputedStyle( 'display' ) == 'none' ||
+                               this.getComputedStyle( 'visibility' ) == 'hidden' ||
+                               CKEDITOR.dtd.$nonEditable[ name ] ||
+                               CKEDITOR.dtd.$empty[ name ] ||
+                               ( this.is( 'a' ) &&
+                                       ( this.data( 'cke-saved-name' ) || this.hasAttribute( 'name' ) ) &&
+                                       !this.getChildCount()
+                               ) ) {
+                               return false;
+                       }
+
+                       if ( textCursor !== false ) {
+                               // Get the element DTD (defaults to span for unknown elements).
+                               var dtd = CKEDITOR.dtd[ name ] || CKEDITOR.dtd.span;
+                               // In the DTD # == text node.
+                               return !!( dtd && dtd[ '#' ] );
+                       }
+
+                       return true;
+               },
+
+               /**
+                * Compare this element's inner html, tag name, attributes, etc. with other one.
+                *
+                * See [W3C's DOM Level 3 spec - node#isEqualNode](http://www.w3.org/TR/DOM-Level-3-Core/core.html#Node3-isEqualNode)
+                * for more details.
+                *
+                * @param {CKEDITOR.dom.element} otherElement Element to compare.
+                * @returns {Boolean}
+                */
+               isIdentical: function( otherElement ) {
+                       // do shallow clones, but with IDs
+                       var thisEl = this.clone( 0, 1 ),
+                               otherEl = otherElement.clone( 0, 1 );
+
+                       // Remove distractions.
+                       thisEl.removeAttributes( [ '_moz_dirty', 'data-cke-expando', 'data-cke-saved-href', 'data-cke-saved-name' ] );
+                       otherEl.removeAttributes( [ '_moz_dirty', 'data-cke-expando', 'data-cke-saved-href', 'data-cke-saved-name' ] );
+
+                       // Native comparison available.
+                       if ( thisEl.$.isEqualNode ) {
+                               // Styles order matters.
+                               thisEl.$.style.cssText = CKEDITOR.tools.normalizeCssText( thisEl.$.style.cssText );
+                               otherEl.$.style.cssText = CKEDITOR.tools.normalizeCssText( otherEl.$.style.cssText );
+                               return thisEl.$.isEqualNode( otherEl.$ );
+                       } else {
+                               thisEl = thisEl.getOuterHtml();
+                               otherEl = otherEl.getOuterHtml();
+
+                               // Fix tiny difference between link href in older IEs.
+                               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && this.is( 'a' ) ) {
+                                       var parent = this.getParent();
+                                       if ( parent.type == CKEDITOR.NODE_ELEMENT ) {
+                                               var el = parent.clone();
+                                               el.setHtml( thisEl ), thisEl = el.getHtml();
+                                               el.setHtml( otherEl ), otherEl = el.getHtml();
+                                       }
+                               }
+
+                               return thisEl == otherEl;
+                       }
+               },
+
+               /**
+                * Checks if this element is visible. May not work if the element is
+                * child of an element with visibility set to `hidden`, but works well
+                * on the great majority of cases.
+                *
+                * @returns {Boolean} True if the element is visible.
+                */
+               isVisible: function() {
+                       var isVisible = ( this.$.offsetHeight || this.$.offsetWidth ) && this.getComputedStyle( 'visibility' ) != 'hidden',
+                               elementWindow, elementWindowFrame;
+
+                       // Webkit and Opera report non-zero offsetHeight despite that
+                       // element is inside an invisible iframe. (#4542)
+                       if ( isVisible && CKEDITOR.env.webkit ) {
+                               elementWindow = this.getWindow();
+
+                               if ( !elementWindow.equals( CKEDITOR.document.getWindow() ) && ( elementWindowFrame = elementWindow.$.frameElement ) )
+                                       isVisible = new CKEDITOR.dom.element( elementWindowFrame ).isVisible();
+
+                       }
+
+                       return !!isVisible;
+               },
+
+               /**
+                * Whether it's an empty inline elements which has no visual impact when removed.
+                *
+                * @returns {Boolean}
+                */
+               isEmptyInlineRemoveable: function() {
+                       if ( !CKEDITOR.dtd.$removeEmpty[ this.getName() ] )
+                               return false;
+
+                       var children = this.getChildren();
+                       for ( var i = 0, count = children.count(); i < count; i++ ) {
+                               var child = children.getItem( i );
+
+                               if ( child.type == CKEDITOR.NODE_ELEMENT && child.data( 'cke-bookmark' ) )
+                                       continue;
+
+                               if ( child.type == CKEDITOR.NODE_ELEMENT && !child.isEmptyInlineRemoveable() || child.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( child.getText() ) )
+                                       return false;
+
+                       }
+                       return true;
+               },
+
+               /**
+                * Checks if the element has any defined attributes.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div title="Test">Example</div>' );
+                *              alert( element.hasAttributes() ); // true
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div>Example</div>' );
+                *              alert( element.hasAttributes() ); // false
+                *
+                * @method
+                * @returns {Boolean} True if the element has attributes.
+                */
+               hasAttributes: CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ?
+                       function() {
+                               var attributes = this.$.attributes;
+
+                               for ( var i = 0; i < attributes.length; i++ ) {
+                                       var attribute = attributes[ i ];
+
+                                       switch ( attribute.nodeName ) {
+                                               case 'class':
+                                                       // IE has a strange bug. If calling removeAttribute('className'),
+                                                       // the attributes collection will still contain the "class"
+                                                       // attribute, which will be marked as "specified", even if the
+                                                       // outerHTML of the element is not displaying the class attribute.
+                                                       // Note : I was not able to reproduce it outside the editor,
+                                                       // but I've faced it while working on the TC of #1391.
+                                                       if ( this.getAttribute( 'class' ) ) {
+                                                               return true;
+                                                       }
+
+                                               // Attributes to be ignored.
+                                               /* falls through */
+                                               case 'data-cke-expando':
+                                                       continue;
+
+
+                                               /* falls through */
+                                               default:
+                                                       if ( attribute.specified ) {
+                                                               return true;
+                                                       }
+                                       }
+                               }
+
+                               return false;
+                       } : function() {
+                               var attrs = this.$.attributes,
+                                       attrsNum = attrs.length;
+
+                               // The _moz_dirty attribute might get into the element after pasting (#5455)
+                               var execludeAttrs = { 'data-cke-expando': 1, _moz_dirty: 1 };
+
+                               return attrsNum > 0 && ( attrsNum > 2 || !execludeAttrs[ attrs[ 0 ].nodeName ] || ( attrsNum == 2 && !execludeAttrs[ attrs[ 1 ].nodeName ] ) );
+                       },
+
+               /**
+                * Checks if the specified attribute is defined for this element.
+                *
+                * @method
+                * @param {String} name The attribute name.
+                * @returns {Boolean} `true` if the specified attribute is defined.
+                */
+               hasAttribute: ( function() {
+                       function ieHasAttribute( name ) {
+                               var $attr = this.$.attributes.getNamedItem( name );
+
+                               if ( this.getName() == 'input' ) {
+                                       switch ( name ) {
+                                               case 'class':
+                                                       return this.$.className.length > 0;
+                                               case 'checked':
+                                                       return !!this.$.checked;
+                                               case 'value':
+                                                       var type = this.getAttribute( 'type' );
+                                                       return type == 'checkbox' || type == 'radio' ? this.$.value != 'on' : !!this.$.value;
+                                       }
+                               }
+
+                               if ( !$attr )
+                                       return false;
+
+                               return $attr.specified;
+                       }
+
+                       if ( CKEDITOR.env.ie ) {
+                               if ( CKEDITOR.env.version < 8 ) {
+                                       return function( name ) {
+                                               // On IE < 8 the name attribute cannot be retrieved
+                                               // right after the element creation and setting the
+                                               // name with setAttribute.
+                                               if ( name == 'name' )
+                                                       return !!this.$.name;
+
+                                               return ieHasAttribute.call( this, name );
+                                       };
+                               } else {
+                                       return ieHasAttribute;
+                               }
+                       } else {
+                               return function( name ) {
+                                       // On other browsers specified property is deprecated and return always true,
+                                       // but fortunately $.attributes contains only specified attributes.
+                                       return !!this.$.attributes.getNamedItem( name );
+                               };
+                       }
+               } )(),
+
+               /**
+                * Hides this element (sets `display: none`).
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.hide();
+                */
+               hide: function() {
+                       this.setStyle( 'display', 'none' );
+               },
+
+               /**
+                * Moves this element's children to the target element.
+                *
+                * @param {CKEDITOR.dom.element} target
+                * @param {Boolean} [toStart=false] Insert moved children at the
+                * beginning of the target element.
+                */
+               moveChildren: function( target, toStart ) {
+                       var $ = this.$;
+                       target = target.$;
+
+                       if ( $ == target )
+                               return;
+
+                       var child;
+
+                       if ( toStart ) {
+                               while ( ( child = $.lastChild ) )
+                                       target.insertBefore( $.removeChild( child ), target.firstChild );
+                       } else {
+                               while ( ( child = $.firstChild ) )
+                                       target.appendChild( $.removeChild( child ) );
+                       }
+               },
+
+               /**
+                * Merges sibling elements that are identical to this one.
+                *
+                * Identical child elements are also merged. For example:
+                *
+                *              <b><i></i></b><b><i></i></b> => <b><i></i></b>
+                *
+                * @method
+                * @param {Boolean} [inlineOnly=true] Allow only inline elements to be merged.
+                */
+               mergeSiblings: ( function() {
+                       function mergeElements( element, sibling, isNext ) {
+                               if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT ) {
+                                       // Jumping over bookmark nodes and empty inline elements, e.g. <b><i></i></b>,
+                                       // queuing them to be moved later. (#5567)
+                                       var pendingNodes = [];
+
+                                       while ( sibling.data( 'cke-bookmark' ) || sibling.isEmptyInlineRemoveable() ) {
+                                               pendingNodes.push( sibling );
+                                               sibling = isNext ? sibling.getNext() : sibling.getPrevious();
+                                               if ( !sibling || sibling.type != CKEDITOR.NODE_ELEMENT )
+                                                       return;
+                                       }
+
+                                       if ( element.isIdentical( sibling ) ) {
+                                               // Save the last child to be checked too, to merge things like
+                                               // <b><i></i></b><b><i></i></b> => <b><i></i></b>
+                                               var innerSibling = isNext ? element.getLast() : element.getFirst();
+
+                                               // Move pending nodes first into the target element.
+                                               while ( pendingNodes.length )
+                                                       pendingNodes.shift().move( element, !isNext );
+
+                                               sibling.moveChildren( element, !isNext );
+                                               sibling.remove();
+
+                                               // Now check the last inner child (see two comments above).
+                                               if ( innerSibling && innerSibling.type == CKEDITOR.NODE_ELEMENT )
+                                                       innerSibling.mergeSiblings();
+                                       }
+                               }
+                       }
+
+                       return function( inlineOnly ) {
+                               // Merge empty links and anchors also. (#5567)
+                               if ( !( inlineOnly === false || CKEDITOR.dtd.$removeEmpty[ this.getName() ] || this.is( 'a' ) ) ) {
+                                       return;
+                               }
+
+                               mergeElements( this, this.getNext(), true );
+                               mergeElements( this, this.getPrevious() );
+                       };
+               } )(),
+
+               /**
+                * Shows this element (displays it).
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.show();
+                */
+               show: function() {
+                       this.setStyles( {
+                               display: '',
+                               visibility: ''
+                       } );
+               },
+
+               /**
+                * Sets the value of an element attribute.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.setAttribute( 'class', 'myClass' );
+                *              element.setAttribute( 'title', 'This is an example' );
+                *
+                * @method
+                * @param {String} name The name of the attribute.
+                * @param {String} value The value to be set to the attribute.
+                * @returns {CKEDITOR.dom.element} This element instance.
+                */
+               setAttribute: ( function() {
+                       var standard = function( name, value ) {
+                                       this.$.setAttribute( name, value );
+                                       return this;
+                               };
+
+                       if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ) {
+                               return function( name, value ) {
+                                       if ( name == 'class' )
+                                               this.$.className = value;
+                                       else if ( name == 'style' )
+                                               this.$.style.cssText = value;
+                                       else if ( name == 'tabindex' ) // Case sensitive.
+                                       this.$.tabIndex = value;
+                                       else if ( name == 'checked' )
+                                               this.$.checked = value;
+                                       else if ( name == 'contenteditable' )
+                                               standard.call( this, 'contentEditable', value );
+                                       else
+                                               standard.apply( this, arguments );
+                                       return this;
+                               };
+                       } else if ( CKEDITOR.env.ie8Compat && CKEDITOR.env.secure ) {
+                               return function( name, value ) {
+                                       // IE8 throws error when setting src attribute to non-ssl value. (#7847)
+                                       if ( name == 'src' && value.match( /^http:\/\// ) ) {
+                                               try {
+                                                       standard.apply( this, arguments );
+                                               } catch ( e ) {}
+                                       } else {
+                                               standard.apply( this, arguments );
+                                       }
+                                       return this;
+                               };
+                       } else {
+                               return standard;
+                       }
+               } )(),
+
+               /**
+                * Sets the value of several element attributes.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.setAttributes( {
+                *                      'class':        'myClass',
+                *                      title:          'This is an example'
+                *              } );
+                *
+                * @chainable
+                * @param {Object} attributesPairs An object containing the names and
+                * values of the attributes.
+                * @returns {CKEDITOR.dom.element} This element instance.
+                */
+               setAttributes: function( attributesPairs ) {
+                       for ( var name in attributesPairs )
+                               this.setAttribute( name, attributesPairs[ name ] );
+                       return this;
+               },
+
+               /**
+                * Sets the element value. This function is usually used with form
+                * field element.
+                *
+                * @chainable
+                * @param {String} value The element value.
+                * @returns {CKEDITOR.dom.element} This element instance.
+                */
+               setValue: function( value ) {
+                       this.$.value = value;
+                       return this;
+               },
+
+               /**
+                * Removes an attribute from the element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' );
+                *              element.removeAttribute( 'class' );
+                *
+                * @method
+                * @param {String} name The attribute name.
+                */
+               removeAttribute: ( function() {
+                       var standard = function( name ) {
+                                       this.$.removeAttribute( name );
+                               };
+
+                       if ( CKEDITOR.env.ie && ( CKEDITOR.env.ie7Compat || CKEDITOR.env.quirks ) ) {
+                               return function( name ) {
+                                       if ( name == 'class' )
+                                               name = 'className';
+                                       else if ( name == 'tabindex' )
+                                               name = 'tabIndex';
+                                       else if ( name == 'contenteditable' )
+                                               name = 'contentEditable';
+                                       standard.call( this, name );
+                               };
+                       } else {
+                               return standard;
+                       }
+               } )(),
+
+               /**
+                * Removes all element's attributes or just given ones.
+                *
+                * @param {Array} [attributes] The array with attributes names.
+                */
+               removeAttributes: function( attributes ) {
+                       if ( CKEDITOR.tools.isArray( attributes ) ) {
+                               for ( var i = 0; i < attributes.length; i++ ) {
+                                       this.removeAttribute( attributes[ i ] );
+                               }
+                       } else {
+                               attributes = attributes || this.getAttributes();
+
+                               for ( var attr in attributes ) {
+                                       attributes.hasOwnProperty( attr ) && this.removeAttribute( attr );
+                               }
+                       }
+               },
+
+               /**
+                * Removes a style from the element.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div style="display:none"></div>' );
+                *              element.removeStyle( 'display' );
+                *
+                * @method
+                * @param {String} name The style name.
+                */
+               removeStyle: function( name ) {
+                       // Removes the specified property from the current style object.
+                       var $ = this.$.style;
+
+                       // "removeProperty" need to be specific on the following styles.
+                       if ( !$.removeProperty && ( name == 'border' || name == 'margin' || name == 'padding' ) ) {
+                               var names = expandedRules( name );
+                               for ( var i = 0 ; i < names.length ; i++ )
+                                       this.removeStyle( names[ i ] );
+                               return;
+                       }
+
+                       $.removeProperty ? $.removeProperty( name ) : $.removeAttribute( CKEDITOR.tools.cssStyleToDomStyle( name ) );
+
+                       // Eventually remove empty style attribute.
+                       if ( !this.$.style.cssText )
+                               this.removeAttribute( 'style' );
+               },
+
+               /**
+                * Sets the value of an element style.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.setStyle( 'background-color', '#ff0000' );
+                *              element.setStyle( 'margin-top', '10px' );
+                *              element.setStyle( 'float', 'right' );
+                *
+                * @param {String} name The name of the style. The CSS naming notation
+                * must be used (e.g. `background-color`).
+                * @param {String} value The value to be set to the style.
+                * @returns {CKEDITOR.dom.element} This element instance.
+                */
+               setStyle: function( name, value ) {
+                       this.$.style[ CKEDITOR.tools.cssStyleToDomStyle( name ) ] = value;
+                       return this;
+               },
+
+               /**
+                * Sets the value of several element styles.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.setStyles( {
+                *                      position:       'absolute',
+                *                      float:          'right'
+                *              } );
+                *
+                * @param {Object} stylesPairs An object containing the names and
+                * values of the styles.
+                * @returns {CKEDITOR.dom.element} This element instance.
+                */
+               setStyles: function( stylesPairs ) {
+                       for ( var name in stylesPairs )
+                               this.setStyle( name, stylesPairs[ name ] );
+                       return this;
+               },
+
+               /**
+                * Sets the opacity of an element.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.setOpacity( 0.75 );
+                *
+                * @param {Number} opacity A number within the range `[0.0, 1.0]`.
+                */
+               setOpacity: function( opacity ) {
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {
+                               opacity = Math.round( opacity * 100 );
+                               this.setStyle( 'filter', opacity >= 100 ? '' : 'progid:DXImageTransform.Microsoft.Alpha(opacity=' + opacity + ')' );
+                       } else {
+                               this.setStyle( 'opacity', opacity );
+                       }
+               },
+
+               /**
+                * Makes the element and its children unselectable.
+                *
+                *              var element = CKEDITOR.document.getById( 'myElement' );
+                *              element.unselectable();
+                *
+                * @method
+                */
+               unselectable: function() {
+                       // CSS unselectable.
+                       this.setStyles( CKEDITOR.tools.cssVendorPrefix( 'user-select', 'none' ) );
+
+                       // For IE/Opera which doesn't support for the above CSS style,
+                       // the unselectable="on" attribute only specifies the selection
+                       // process cannot start in the element itself, and it doesn't inherit.
+                       if ( CKEDITOR.env.ie ) {
+                               this.setAttribute( 'unselectable', 'on' );
+
+                               var element,
+                                       elements = this.getElementsByTag( '*' );
+
+                               for ( var i = 0, count = elements.count() ; i < count ; i++ ) {
+                                       element = elements.getItem( i );
+                                       element.setAttribute( 'unselectable', 'on' );
+                               }
+                       }
+               },
+
+               /**
+                * Gets closest positioned (`position != static`) ancestor.
+                *
+                * @returns {CKEDITOR.dom.element} Positioned ancestor or `null`.
+                */
+               getPositionedAncestor: function() {
+                       var current = this;
+                       while ( current.getName() != 'html' ) {
+                               if ( current.getComputedStyle( 'position' ) != 'static' )
+                                       return current;
+
+                               current = current.getParent();
+                       }
+                       return null;
+               },
+
+               /**
+                * Gets this element's position in document.
+                *
+                * @param {CKEDITOR.dom.document} [refDocument]
+                * @returns {Object} Element's position.
+                * @returns {Number} return.x
+                * @returns {Number} return.y
+                * @todo refDocument
+                */
+               getDocumentPosition: function( refDocument ) {
+                       var x = 0,
+                               y = 0,
+                               doc = this.getDocument(),
+                               body = doc.getBody(),
+                               quirks = doc.$.compatMode == 'BackCompat';
+
+                       if ( document.documentElement.getBoundingClientRect &&
+                               ( CKEDITOR.env.ie ? CKEDITOR.env.version !== 8 : true ) ) {
+                               var box = this.$.getBoundingClientRect(),
+                                       $doc = doc.$,
+                                       $docElem = $doc.documentElement;
+
+                               var clientTop = $docElem.clientTop || body.$.clientTop || 0,
+                                       clientLeft = $docElem.clientLeft || body.$.clientLeft || 0,
+                                       needAdjustScrollAndBorders = true;
+
+                               // #3804: getBoundingClientRect() works differently on IE and non-IE
+                               // browsers, regarding scroll positions.
+                               //
+                               // On IE, the top position of the <html> element is always 0, no matter
+                               // how much you scrolled down.
+                               //
+                               // On other browsers, the top position of the <html> element is negative
+                               // scrollTop.
+                               if ( CKEDITOR.env.ie ) {
+                                       var inDocElem = doc.getDocumentElement().contains( this ),
+                                               inBody = doc.getBody().contains( this );
+
+                                       needAdjustScrollAndBorders = ( quirks && inBody ) || ( !quirks && inDocElem );
+                               }
+
+                               // #12747.
+                               if ( needAdjustScrollAndBorders ) {
+                                       var scrollRelativeLeft,
+                                               scrollRelativeTop;
+
+                                       // See #12758 to know more about document.(documentElement|body).scroll(Left|Top) in Webkit.
+                                       if ( CKEDITOR.env.webkit || ( CKEDITOR.env.ie && CKEDITOR.env.version >= 12 ) ) {
+                                               scrollRelativeLeft = body.$.scrollLeft || $docElem.scrollLeft;
+                                               scrollRelativeTop = body.$.scrollTop || $docElem.scrollTop;
+                                       } else {
+                                               var scrollRelativeElement = quirks ? body.$ : $docElem;
+
+                                               scrollRelativeLeft = scrollRelativeElement.scrollLeft;
+                                               scrollRelativeTop = scrollRelativeElement.scrollTop;
+                                       }
+
+                                       x = box.left + scrollRelativeLeft - clientLeft;
+                                       y = box.top + scrollRelativeTop - clientTop;
+                               }
+                       } else {
+                               var current = this,
+                                       previous = null,
+                                       offsetParent;
+                               while ( current && !( current.getName() == 'body' || current.getName() == 'html' ) ) {
+                                       x += current.$.offsetLeft - current.$.scrollLeft;
+                                       y += current.$.offsetTop - current.$.scrollTop;
+
+                                       // Opera includes clientTop|Left into offsetTop|Left.
+                                       if ( !current.equals( this ) ) {
+                                               x += ( current.$.clientLeft || 0 );
+                                               y += ( current.$.clientTop || 0 );
+                                       }
+
+                                       var scrollElement = previous;
+                                       while ( scrollElement && !scrollElement.equals( current ) ) {
+                                               x -= scrollElement.$.scrollLeft;
+                                               y -= scrollElement.$.scrollTop;
+                                               scrollElement = scrollElement.getParent();
+                                       }
+
+                                       previous = current;
+                                       current = ( offsetParent = current.$.offsetParent ) ? new CKEDITOR.dom.element( offsetParent ) : null;
+                               }
+                       }
+
+                       if ( refDocument ) {
+                               var currentWindow = this.getWindow(),
+                                       refWindow = refDocument.getWindow();
+
+                               if ( !currentWindow.equals( refWindow ) && currentWindow.$.frameElement ) {
+                                       var iframePosition = ( new CKEDITOR.dom.element( currentWindow.$.frameElement ) ).getDocumentPosition( refDocument );
+
+                                       x += iframePosition.x;
+                                       y += iframePosition.y;
+                               }
+                       }
+
+                       if ( !document.documentElement.getBoundingClientRect ) {
+                               // In Firefox, we'll endup one pixel before the element positions,
+                               // so we must add it here.
+                               if ( CKEDITOR.env.gecko && !quirks ) {
+                                       x += this.$.clientLeft ? 1 : 0;
+                                       y += this.$.clientTop ? 1 : 0;
+                               }
+                       }
+
+                       return { x: x, y: y };
+               },
+
+               /**
+                * Make any page element visible inside the browser viewport.
+                *
+                * @param {Boolean} [alignToTop=false]
+                */
+               scrollIntoView: function( alignToTop ) {
+                       var parent = this.getParent();
+                       if ( !parent )
+                               return;
+
+                       // Scroll the element into parent container from the inner out.
+                       do {
+                               // Check ancestors that overflows.
+                               var overflowed =
+                                       parent.$.clientWidth && parent.$.clientWidth < parent.$.scrollWidth ||
+                                       parent.$.clientHeight && parent.$.clientHeight < parent.$.scrollHeight;
+
+                               // Skip body element, which will report wrong clientHeight when containing
+                               // floated content. (#9523)
+                               if ( overflowed && !parent.is( 'body' ) )
+                                       this.scrollIntoParent( parent, alignToTop, 1 );
+
+                               // Walk across the frame.
+                               if ( parent.is( 'html' ) ) {
+                                       var win = parent.getWindow();
+
+                                       // Avoid security error.
+                                       try {
+                                               var iframe = win.$.frameElement;
+                                               iframe && ( parent = new CKEDITOR.dom.element( iframe ) );
+                                       } catch ( er ) {}
+                               }
+                       }
+                       while ( ( parent = parent.getParent() ) );
+               },
+
+               /**
+                * Make any page element visible inside one of the ancestors by scrolling the parent.
+                *
+                * @param {CKEDITOR.dom.element/CKEDITOR.dom.window} parent The container to scroll into.
+                * @param {Boolean} [alignToTop] Align the element's top side with the container's
+                * when `true` is specified; align the bottom with viewport bottom when
+                * `false` is specified. Otherwise scroll on either side with the minimum
+                * amount to show the element.
+                * @param {Boolean} [hscroll] Whether horizontal overflow should be considered.
+                */
+               scrollIntoParent: function( parent, alignToTop, hscroll ) {
+                       !parent && ( parent = this.getWindow() );
+
+                       var doc = parent.getDocument();
+                       var isQuirks = doc.$.compatMode == 'BackCompat';
+
+                       // On window <html> is scrolled while quirks scrolls <body>.
+                       if ( parent instanceof CKEDITOR.dom.window )
+                               parent = isQuirks ? doc.getBody() : doc.getDocumentElement();
+
+                       // Scroll the parent by the specified amount.
+                       function scrollBy( x, y ) {
+                               // Webkit doesn't support "scrollTop/scrollLeft"
+                               // on documentElement/body element.
+                               if ( /body|html/.test( parent.getName() ) )
+                                       parent.getWindow().$.scrollBy( x, y );
+                               else {
+                                       parent.$.scrollLeft += x;
+                                       parent.$.scrollTop += y;
+                               }
+                       }
+
+                       // Figure out the element position relative to the specified window.
+                       function screenPos( element, refWin ) {
+                               var pos = { x: 0, y: 0 };
+
+                               if ( !( element.is( isQuirks ? 'body' : 'html' ) ) ) {
+                                       var box = element.$.getBoundingClientRect();
+                                       pos.x = box.left, pos.y = box.top;
+                               }
+
+                               var win = element.getWindow();
+                               if ( !win.equals( refWin ) ) {
+                                       var outerPos = screenPos( CKEDITOR.dom.element.get( win.$.frameElement ), refWin );
+                                       pos.x += outerPos.x, pos.y += outerPos.y;
+                               }
+
+                               return pos;
+                       }
+
+                       // calculated margin size.
+                       function margin( element, side ) {
+                               return parseInt( element.getComputedStyle( 'margin-' + side ) || 0, 10 ) || 0;
+                       }
+
+                       // [WebKit] Reset stored scrollTop value to not break scrollIntoView() method flow.
+                       // Scrolling breaks when range.select() is used right after element.scrollIntoView(). (#14659)
+                       if ( CKEDITOR.env.webkit ) {
+                               var editor = this.getEditor( false );
+
+                               if ( editor ) {
+                                       editor._.previousScrollTop = null;
+                               }
+                       }
+
+                       var win = parent.getWindow();
+
+                       var thisPos = screenPos( this, win ),
+                               parentPos = screenPos( parent, win ),
+                               eh = this.$.offsetHeight,
+                               ew = this.$.offsetWidth,
+                               ch = parent.$.clientHeight,
+                               cw = parent.$.clientWidth,
+                               lt, br;
+
+                       // Left-top margins.
+                       lt = {
+                               x: thisPos.x - margin( this, 'left' ) - parentPos.x || 0,
+                               y: thisPos.y - margin( this, 'top' ) - parentPos.y || 0
+                       };
+
+                       // Bottom-right margins.
+                       br = {
+                               x: thisPos.x + ew + margin( this, 'right' ) - ( ( parentPos.x ) + cw ) || 0,
+                               y: thisPos.y + eh + margin( this, 'bottom' ) - ( ( parentPos.y ) + ch ) || 0
+                       };
+
+                       // 1. Do the specified alignment as much as possible;
+                       // 2. Otherwise be smart to scroll only the minimum amount;
+                       // 3. Never cut at the top;
+                       // 4. DO NOT scroll when already visible.
+                       if ( lt.y < 0 || br.y > 0 )
+                               scrollBy( 0, alignToTop === true ? lt.y : alignToTop === false ? br.y : lt.y < 0 ? lt.y : br.y );
+
+                       if ( hscroll && ( lt.x < 0 || br.x > 0 ) )
+                               scrollBy( lt.x < 0 ? lt.x : br.x, 0 );
+               },
+
+               /**
+                * Switch the `class` attribute to reflect one of the triple states of an
+                * element in one of {@link CKEDITOR#TRISTATE_ON}, {@link CKEDITOR#TRISTATE_OFF}
+                * or {@link CKEDITOR#TRISTATE_DISABLED}.
+                *
+                *              link.setState( CKEDITOR.TRISTATE_ON );
+                *              // <a class="cke_on" aria-pressed="true">...</a>
+                *              link.setState( CKEDITOR.TRISTATE_OFF );
+                *              // <a class="cke_off">...</a>
+                *              link.setState( CKEDITOR.TRISTATE_DISABLED );
+                *              // <a class="cke_disabled" aria-disabled="true">...</a>
+                *
+                *              span.setState( CKEDITOR.TRISTATE_ON, 'cke_button' );
+                *              // <span class="cke_button_on">...</span>
+                *
+                * @param {Number} state Indicate the element state. One of {@link CKEDITOR#TRISTATE_ON},
+                * {@link CKEDITOR#TRISTATE_OFF}, {@link CKEDITOR#TRISTATE_DISABLED}.
+                * @param [base='cke'] The prefix apply to each of the state class name.
+                * @param [useAria=true] Whether toggle the ARIA state attributes besides of class name change.
+                */
+               setState: function( state, base, useAria ) {
+                       base = base || 'cke';
+
+                       switch ( state ) {
+                               case CKEDITOR.TRISTATE_ON:
+                                       this.addClass( base + '_on' );
+                                       this.removeClass( base + '_off' );
+                                       this.removeClass( base + '_disabled' );
+                                       useAria && this.setAttribute( 'aria-pressed', true );
+                                       useAria && this.removeAttribute( 'aria-disabled' );
+                                       break;
+
+                               case CKEDITOR.TRISTATE_DISABLED:
+                                       this.addClass( base + '_disabled' );
+                                       this.removeClass( base + '_off' );
+                                       this.removeClass( base + '_on' );
+                                       useAria && this.setAttribute( 'aria-disabled', true );
+                                       useAria && this.removeAttribute( 'aria-pressed' );
+                                       break;
+
+                               default:
+                                       this.addClass( base + '_off' );
+                                       this.removeClass( base + '_on' );
+                                       this.removeClass( base + '_disabled' );
+                                       useAria && this.removeAttribute( 'aria-pressed' );
+                                       useAria && this.removeAttribute( 'aria-disabled' );
+                                       break;
+                       }
+               },
+
+               /**
+                * Returns the inner document of this `<iframe>` element.
+                *
+                * @returns {CKEDITOR.dom.document} The inner document.
+                */
+               getFrameDocument: function() {
+                       var $ = this.$;
+
+                       try {
+                               // In IE, with custom document.domain, it may happen that
+                               // the iframe is not yet available, resulting in "Access
+                               // Denied" for the following property access.
+                               $.contentWindow.document;
+                       } catch ( e ) {
+                               // Trick to solve this issue, forcing the iframe to get ready
+                               // by simply setting its "src" property.
+                               $.src = $.src;
+                       }
+
+                       return $ && new CKEDITOR.dom.document( $.contentWindow.document );
+               },
+
+               /**
+                * Copy all the attributes from one node to the other, kinda like a clone
+                * skipAttributes is an object with the attributes that must **not** be copied.
+                *
+                * @param {CKEDITOR.dom.element} dest The destination element.
+                * @param {Object} skipAttributes A dictionary of attributes to skip.
+                */
+               copyAttributes: function( dest, skipAttributes ) {
+                       var attributes = this.$.attributes;
+                       skipAttributes = skipAttributes || {};
+
+                       for ( var n = 0; n < attributes.length; n++ ) {
+                               var attribute = attributes[ n ];
+
+                               // Lowercase attribute name hard rule is broken for
+                               // some attribute on IE, e.g. CHECKED.
+                               var attrName = attribute.nodeName.toLowerCase(),
+                                       attrValue;
+
+                               // We can set the type only once, so do it with the proper value, not copying it.
+                               if ( attrName in skipAttributes )
+                                       continue;
+
+                               if ( attrName == 'checked' && ( attrValue = this.getAttribute( attrName ) ) )
+                                       dest.setAttribute( attrName, attrValue );
+                               // IE contains not specified attributes in $.attributes so we need to check
+                               // if elements attribute is specified using hasAttribute.
+                               else if ( !CKEDITOR.env.ie || this.hasAttribute( attrName ) ) {
+                                       attrValue = this.getAttribute( attrName );
+                                       if ( attrValue === null )
+                                               attrValue = attribute.nodeValue;
+
+                                       dest.setAttribute( attrName, attrValue );
+                               }
+                       }
+
+                       // The style:
+                       if ( this.$.style.cssText !== '' )
+                               dest.$.style.cssText = this.$.style.cssText;
+               },
+
+               /**
+                * Changes the tag name of the current element.
+                *
+                * @param {String} newTag The new tag for the element.
+                */
+               renameNode: function( newTag ) {
+                       // If it's already correct exit here.
+                       if ( this.getName() == newTag )
+                               return;
+
+                       var doc = this.getDocument();
+
+                       // Create the new node.
+                       var newNode = new CKEDITOR.dom.element( newTag, doc );
+
+                       // Copy all attributes.
+                       this.copyAttributes( newNode );
+
+                       // Move children to the new node.
+                       this.moveChildren( newNode );
+
+                       // Replace the node.
+                       this.getParent( true ) && this.$.parentNode.replaceChild( newNode.$, this.$ );
+                       newNode.$[ 'data-cke-expando' ] = this.$[ 'data-cke-expando' ];
+                       this.$ = newNode.$;
+                       // Bust getName's cache. (#8663)
+                       delete this.getName;
+               },
+
+               /**
+                * Gets a DOM tree descendant under the current node.
+                *
+                *              var strong = p.getChild( 0 );
+                *
+                * @method
+                * @param {Array/Number} indices The child index or array of child indices under the node.
+                * @returns {CKEDITOR.dom.node} The specified DOM child under the current node. Null if child does not exist.
+                */
+               getChild: ( function() {
+                       function getChild( rawNode, index ) {
+                               var childNodes = rawNode.childNodes;
+
+                               if ( index >= 0 && index < childNodes.length )
+                                       return childNodes[ index ];
+                       }
+
+                       return function( indices ) {
+                               var rawNode = this.$;
+
+                               if ( !indices.slice )
+                                       rawNode = getChild( rawNode, indices );
+                               else {
+                                       indices = indices.slice();
+                                       while ( indices.length > 0 && rawNode )
+                                               rawNode = getChild( rawNode, indices.shift() );
+                               }
+
+                               return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
+                       };
+               } )(),
+
+               /**
+                * Gets number of element's children.
+                *
+                * @returns {Number}
+                */
+               getChildCount: function() {
+                       return this.$.childNodes.length;
+               },
+
+               /**
+                * Disables browser's context menu in this element.
+                */
+               disableContextMenu: function() {
+                       this.on( 'contextmenu', function( evt ) {
+                               // Cancel the browser context menu.
+                               if ( !evt.data.getTarget().getAscendant( enablesContextMenu, true ) )
+                                       evt.data.preventDefault();
+                       } );
+
+                       function enablesContextMenu( node ) {
+                               return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_enable_context_menu' );
+                       }
+               },
+
+               /**
+                * Gets element's direction. Supports both CSS `direction` prop and `dir` attr.
+                */
+               getDirection: function( useComputed ) {
+                       if ( useComputed ) {
+                               return this.getComputedStyle( 'direction' ) ||
+                                               this.getDirection() ||
+                                               this.getParent() && this.getParent().getDirection( 1 ) ||
+                                               this.getDocument().$.dir ||
+                                               'ltr';
+                       }
+                       else {
+                               return this.getStyle( 'direction' ) || this.getAttribute( 'dir' );
+                       }
+               },
+
+               /**
+                * Gets, sets and removes custom data to be stored as HTML5 data-* attributes.
+                *
+                *              element.data( 'extra-info', 'test' );   // Appended the attribute data-extra-info="test" to the element.
+                *              alert( element.data( 'extra-info' ) );  // 'test'
+                *              element.data( 'extra-info', false );    // Remove the data-extra-info attribute from the element.
+                *
+                * @param {String} name The name of the attribute, excluding the `data-` part.
+                * @param {String} [value] The value to set. If set to false, the attribute will be removed.
+                */
+               data: function( name, value ) {
+                       name = 'data-' + name;
+                       if ( value === undefined )
+                               return this.getAttribute( name );
+                       else if ( value === false )
+                               this.removeAttribute( name );
+                       else
+                               this.setAttribute( name, value );
+
+                       return null;
+               },
+
+               /**
+                * Retrieves an editor instance which is based on this element (if any).
+                * It basically loops over {@link CKEDITOR#instances} in search for an instance
+                * that uses the element.
+                *
+                *              var element = new CKEDITOR.dom.element( 'div' );
+                *              element.appendTo( CKEDITOR.document.getBody() );
+                *              CKEDITOR.replace( element );
+                *              alert( element.getEditor().name ); // 'editor1'
+                *
+                * By default this method considers only original DOM elements upon which the editor
+                * was created. Setting `optimized` parameter to `false` will consider editor editable
+                * and its children.
+                *
+                * @param {Boolean} [optimized=true] If set to `false` it will scan every editor editable.
+                * @returns {CKEDITOR.editor} An editor instance or null if nothing has been found.
+                */
+               getEditor: function( optimized ) {
+                       var instances = CKEDITOR.instances,
+                               name, instance, editable;
+
+                       optimized = optimized || optimized === undefined;
+
+                       for ( name in instances ) {
+                               instance = instances[ name ];
+
+                               if ( instance.element.equals( this ) && instance.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO )
+                                       return instance;
+
+                               if ( !optimized ) {
+                                       editable = instance.editable();
+
+                                       if ( editable && ( editable.equals( this ) || editable.contains( this ) ) ) {
+                                               return instance;
+                                       }
+                               }
+                       }
+
+                       return null;
+               },
+
+               /**
+                * Returns list of elements within this element that match specified `selector`.
+                *
+                * **Notes:**
+                *
+                *      * Not available in IE7.
+                *      * Returned list is not a live collection (like a result of native `querySelectorAll`).
+                *      * Unlike native `querySelectorAll` this method ensures selector contextualization. This is:
+                *
+                *                      HTML:           '<body><div><i>foo</i></div></body>'
+                *                      Native:         div.querySelectorAll( 'body i' ) // ->          [ <i>foo</i> ]
+                *                      Method:         div.find( 'body i' ) // ->                                      []
+                *                                              div.find( 'i' ) // ->                                           [ <i>foo</i> ]
+                *
+                * @since 4.3
+                * @param {String} selector
+                * @returns {CKEDITOR.dom.nodeList}
+                */
+               find: function( selector ) {
+                       var removeTmpId = createTmpId( this ),
+                               list = new CKEDITOR.dom.nodeList(
+                                       this.$.querySelectorAll( getContextualizedSelector( this, selector ) )
+                               );
+
+                       removeTmpId();
+
+                       return list;
+               },
+
+               /**
+                * Returns first element within this element that matches specified `selector`.
+                *
+                * **Notes:**
+                *
+                *      * Not available in IE7.
+                *      * Unlike native `querySelectorAll` this method ensures selector contextualization. This is:
+                *
+                *                      HTML:           '<body><div><i>foo</i></div></body>'
+                *                      Native:         div.querySelector( 'body i' ) // ->                     <i>foo</i>
+                *                      Method:         div.findOne( 'body i' ) // ->                           null
+                *                                              div.findOne( 'i' ) // ->                                        <i>foo</i>
+                *
+                * @since 4.3
+                * @param {String} selector
+                * @returns {CKEDITOR.dom.element}
+                */
+               findOne: function( selector ) {
+                       var removeTmpId = createTmpId( this ),
+                               found = this.$.querySelector( getContextualizedSelector( this, selector ) );
+
+                       removeTmpId();
+
+                       return found ? new CKEDITOR.dom.element( found ) : null;
+               },
+
+               /**
+                * Traverse the DOM of this element (inclusive), executing a callback for
+                * each node.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<div><p>foo<b>bar</b>bom</p></div>' );
+                *              element.forEach( function( node ) {
+                *                      console.log( node );
+                *              } );
+                *              // Will log:
+                *              // 1. <div> element,
+                *              // 2. <p> element,
+                *              // 3. "foo" text node,
+                *              // 4. <b> element,
+                *              // 5. "bar" text node,
+                *              // 6. "bom" text node.
+                *
+                * @since 4.3
+                * @param {Function} callback Function to be executed on every node.
+                * If `callback` returns `false` descendants of the node will be ignored.
+                * @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
+                * @param {Number} [type] If specified `callback` will be executed only on
+                * nodes of this type.
+                * @param {Boolean} [skipRoot] Don't execute `callback` on this element.
+                */
+               forEach: function( callback, type, skipRoot ) {
+                       if ( !skipRoot && ( !type || this.type == type ) )
+                                       var ret = callback( this );
+
+                       // Do not filter children if callback returned false.
+                       if ( ret === false )
+                               return;
+
+                       var children = this.getChildren(),
+                               node,
+                               i = 0;
+
+                       // We do not cache the size, because the live list of nodes may be changed by the callback.
+                       for ( ; i < children.count(); i++ ) {
+                               node = children.getItem( i );
+                               if ( node.type == CKEDITOR.NODE_ELEMENT )
+                                       node.forEach( callback, type );
+                               else if ( !type || node.type == type )
+                                       callback( node );
+                       }
+               }
+       } );
+
+       function createTmpId( element ) {
+               var hadId = true;
+
+               if ( !element.$.id ) {
+                       element.$.id = 'cke_tmp_' + CKEDITOR.tools.getNextNumber();
+                       hadId = false;
+               }
+
+               return function() {
+                       if ( !hadId )
+                               element.removeAttribute( 'id' );
+               };
+       }
+
+       function getContextualizedSelector( element, selector ) {
+               var id = CKEDITOR.tools.escapeCss( element.$.id );
+               return '#' + id + ' ' + selector.split( /,\s*/ ).join( ', #' + id + ' ' );
+       }
+
+       var sides = {
+               width: [ 'border-left-width', 'border-right-width', 'padding-left', 'padding-right' ],
+               height: [ 'border-top-width', 'border-bottom-width', 'padding-top', 'padding-bottom' ]
+       };
+
+       // Generate list of specific style rules, applicable to margin/padding/border.
+       function expandedRules( style ) {
+               var sides = [ 'top', 'left', 'right', 'bottom' ], components;
+
+               if ( style == 'border' )
+                               components = [ 'color', 'style', 'width' ];
+
+               var styles = [];
+               for ( var i = 0 ; i < sides.length ; i++ ) {
+
+                       if ( components ) {
+                               for ( var j = 0 ; j < components.length ; j++ )
+                                       styles.push( [ style, sides[ i ], components[ j ] ].join( '-' ) );
+                       } else {
+                               styles.push( [ style, sides[ i ] ].join( '-' ) );
+                       }
+               }
+
+               return styles;
+       }
+
+       function marginAndPaddingSize( type ) {
+               var adjustment = 0;
+               for ( var i = 0, len = sides[ type ].length; i < len; i++ )
+                       adjustment += parseFloat( this.getComputedStyle( sides[ type ][ i ] ) || 0, 10 ) || 0;
+               return adjustment;
+       }
+
+       /**
+        * Sets the element size considering the box model.
+        *
+        * @param {'width'/'height'} type The dimension to set.
+        * @param {Number} size The length unit in px.
+        * @param {Boolean} isBorderBox Apply the size based on the border box model.
+        */
+       CKEDITOR.dom.element.prototype.setSize = function( type, size, isBorderBox ) {
+               if ( typeof size == 'number' ) {
+                       if ( isBorderBox && !( CKEDITOR.env.ie && CKEDITOR.env.quirks ) )
+                               size -= marginAndPaddingSize.call( this, type );
+
+                       this.setStyle( type, size + 'px' );
+               }
+       };
+
+       /**
+        * Gets the element size, possibly considering the box model.
+        *
+        * @param {'width'/'height'} type The dimension to get.
+        * @param {Boolean} isBorderBox Get the size based on the border box model.
+        */
+       CKEDITOR.dom.element.prototype.getSize = function( type, isBorderBox ) {
+               var size = Math.max( this.$[ 'offset' + CKEDITOR.tools.capitalize( type ) ], this.$[ 'client' + CKEDITOR.tools.capitalize( type ) ] ) || 0;
+
+               if ( isBorderBox )
+                       size -= marginAndPaddingSize.call( this, type );
+
+               return size;
+       };
+} )();
diff --git a/sources/core/dom/elementpath.js b/sources/core/dom/elementpath.js
new file mode 100644 (file)
index 0000000..1a3aed0
--- /dev/null
@@ -0,0 +1,251 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+( function() {
+
+       var pathBlockLimitElements = {},
+               pathBlockElements = {},
+               tag;
+
+       // Elements that are considered the "Block limit" in an element path.
+       for ( tag in CKEDITOR.dtd.$blockLimit ) {
+               // Exclude from list roots.
+               if ( !( tag in CKEDITOR.dtd.$list ) )
+                       pathBlockLimitElements[ tag ] = 1;
+       }
+
+       // Elements that are considered the "End level Block" in an element path.
+       for ( tag in CKEDITOR.dtd.$block ) {
+               // Exclude block limits, and empty block element, e.g. hr.
+               if ( !( tag in CKEDITOR.dtd.$blockLimit || tag in CKEDITOR.dtd.$empty ) )
+                       pathBlockElements[ tag ] = 1;
+       }
+
+       // Check if an element contains any block element.
+       function checkHasBlock( element ) {
+               var childNodes = element.getChildren();
+
+               for ( var i = 0, count = childNodes.count(); i < count; i++ ) {
+                       var child = childNodes.getItem( i );
+
+                       if ( child.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$block[ child.getName() ] )
+                               return true;
+               }
+
+               return false;
+       }
+
+       /**
+        * Retrieve the list of nodes walked from the start node up to the editable element of the editor.
+        *
+        * @class
+        * @constructor Creates an element path class instance.
+        * @param {CKEDITOR.dom.element} startNode From which the path should start.
+        * @param {CKEDITOR.dom.element} root To which element the path should stop, defaults to the `body` element.
+        */
+       CKEDITOR.dom.elementPath = function( startNode, root ) {
+               var block = null,
+                       blockLimit = null,
+                       elements = [],
+                       e = startNode,
+                       elementName;
+
+               // Backward compact.
+               root = root || startNode.getDocument().getBody();
+
+               do {
+                       if ( e.type == CKEDITOR.NODE_ELEMENT ) {
+                               elements.push( e );
+
+                               if ( !this.lastElement ) {
+                                       this.lastElement = e;
+
+                                       // If an object or non-editable element is fully selected at the end of the element path,
+                                       // it must not become the block limit.
+                                       if ( e.is( CKEDITOR.dtd.$object ) || e.getAttribute( 'contenteditable' ) == 'false' )
+                                               continue;
+                               }
+
+                               if ( e.equals( root ) )
+                                       break;
+
+                               if ( !blockLimit ) {
+                                       elementName = e.getName();
+
+                                       // First editable element becomes a block limit, because it cannot be split.
+                                       if ( e.getAttribute( 'contenteditable' ) == 'true' )
+                                               blockLimit = e;
+                                       // "Else" because element cannot be both - block and block levelimit.
+                                       else if ( !block && pathBlockElements[ elementName ] )
+                                               block = e;
+
+                                       if ( pathBlockLimitElements[ elementName ] ) {
+                                               // End level DIV is considered as the block, if no block is available. (#525)
+                                               // But it must NOT be the root element (checked above).
+                                               if ( !block && elementName == 'div' && !checkHasBlock( e ) )
+                                                       block = e;
+                                               else
+                                                       blockLimit = e;
+                                       }
+                               }
+                       }
+               }
+               while ( ( e = e.getParent() ) );
+
+               // Block limit defaults to root.
+               if ( !blockLimit )
+                       blockLimit = root;
+
+               /**
+                * First non-empty block element which:
+                *
+                * * is not a {@link CKEDITOR.dtd#$blockLimit},
+                * * or is a `div` which does not contain block elements and is not a `root`.
+                *
+                * This means a first, splittable block in elements path.
+                *
+                * @readonly
+                * @property {CKEDITOR.dom.element}
+                */
+               this.block = block;
+
+               /**
+                * See the {@link CKEDITOR.dtd#$blockLimit} description.
+                *
+                * @readonly
+                * @property {CKEDITOR.dom.element}
+                */
+               this.blockLimit = blockLimit;
+
+               /**
+                * The root of the elements path - `root` argument passed to class constructor or a `body` element.
+                *
+                * @readonly
+                * @property {CKEDITOR.dom.element}
+                */
+               this.root = root;
+
+               /**
+                * An array of elements (from `startNode` to `root`) in the path.
+                *
+                * @readonly
+                * @property {CKEDITOR.dom.element[]}
+                */
+               this.elements = elements;
+
+               /**
+                * The last element of the elements path - `startNode` or its parent.
+                *
+                * @readonly
+                * @property {CKEDITOR.dom.element} lastElement
+                */
+       };
+
+} )();
+
+CKEDITOR.dom.elementPath.prototype = {
+       /**
+        * Compares this element path with another one.
+        *
+        * @param {CKEDITOR.dom.elementPath} otherPath The elementPath object to be
+        * compared with this one.
+        * @returns {Boolean} `true` if the paths are equal, containing the same
+        * number of elements and the same elements in the same order.
+        */
+       compare: function( otherPath ) {
+               var thisElements = this.elements;
+               var otherElements = otherPath && otherPath.elements;
+
+               if ( !otherElements || thisElements.length != otherElements.length )
+                       return false;
+
+               for ( var i = 0; i < thisElements.length; i++ ) {
+                       if ( !thisElements[ i ].equals( otherElements[ i ] ) )
+                               return false;
+               }
+
+               return true;
+       },
+
+       /**
+        * Search the path elements that meets the specified criteria.
+        *
+        * @param {String/Array/Function/Object/CKEDITOR.dom.element} query The criteria that can be
+        * either a tag name, list (array and object) of tag names, element or an node evaluator function.
+        * @param {Boolean} [excludeRoot] Not taking path root element into consideration.
+        * @param {Boolean} [fromTop] Search start from the topmost element instead of bottom.
+        * @returns {CKEDITOR.dom.element} The first matched dom element or `null`.
+        */
+       contains: function( query, excludeRoot, fromTop ) {
+               var evaluator;
+               if ( typeof query == 'string' )
+                       evaluator = function( node ) {
+                               return node.getName() == query;
+                       };
+               if ( query instanceof CKEDITOR.dom.element )
+                       evaluator = function( node ) {
+                               return node.equals( query );
+                       };
+               else if ( CKEDITOR.tools.isArray( query ) )
+                       evaluator = function( node ) {
+                               return CKEDITOR.tools.indexOf( query, node.getName() ) > -1;
+                       };
+               else if ( typeof query == 'function' )
+                       evaluator = query;
+               else if ( typeof query == 'object' )
+                       evaluator = function( node ) {
+                               return node.getName() in query;
+                       };
+
+               var elements = this.elements,
+                       length = elements.length;
+               excludeRoot && length--;
+
+               if ( fromTop ) {
+                       elements = Array.prototype.slice.call( elements, 0 );
+                       elements.reverse();
+               }
+
+               for ( var i = 0; i < length; i++ ) {
+                       if ( evaluator( elements[ i ] ) )
+                               return elements[ i ];
+               }
+
+               return null;
+       },
+
+       /**
+        * Check whether the elements path is the proper context for the specified
+        * tag name in the DTD.
+        *
+        * @param {String} tag The tag name.
+        * @returns {Boolean}
+        */
+       isContextFor: function( tag ) {
+               var holder;
+
+               // Check for block context.
+               if ( tag in CKEDITOR.dtd.$block ) {
+                       // Indeterminate elements which are not subjected to be splitted or surrounded must be checked first.
+                       var inter = this.contains( CKEDITOR.dtd.$intermediate );
+                       holder = inter || ( this.root.equals( this.block ) && this.block ) || this.blockLimit;
+                       return !!holder.getDtd()[ tag ];
+               }
+
+               return true;
+       },
+
+       /**
+        * Retrieve the text direction for this elements path.
+        *
+        * @returns {'ltr'/'rtl'}
+        */
+       direction: function() {
+               var directionNode = this.block || this.blockLimit || this.root;
+               return directionNode.getDirection( 1 );
+       }
+};
diff --git a/sources/core/dom/event.js b/sources/core/dom/event.js
new file mode 100644 (file)
index 0000000..8b1193a
--- /dev/null
@@ -0,0 +1,208 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.event} class, which
+ *             represents the a native DOM event object.
+ */
+
+/**
+ * Represents a native DOM event object.
+ *
+ * @class
+ * @constructor Creates an event class instance.
+ * @param {Object} domEvent A native DOM event object.
+ */
+CKEDITOR.dom.event = function( domEvent ) {
+       /**
+        * The native DOM event object represented by this class instance.
+        *
+        * @readonly
+        */
+       this.$ = domEvent;
+};
+
+CKEDITOR.dom.event.prototype = {
+       /**
+        * Gets the key code associated to the event.
+        *
+        *              alert( event.getKey() ); // '65' is 'a' has been pressed
+        *
+        * @returns {Number} The key code.
+        */
+       getKey: function() {
+               return this.$.keyCode || this.$.which;
+       },
+
+       /**
+        * Gets a number represeting the combination of the keys pressed during the
+        * event. It is the sum with the current key code and the {@link CKEDITOR#CTRL},
+        * {@link CKEDITOR#SHIFT} and {@link CKEDITOR#ALT} constants.
+        *
+        *              alert( event.getKeystroke() == 65 );                                                                    // 'a' key
+        *              alert( event.getKeystroke() == CKEDITOR.CTRL + 65 );                                    // CTRL + 'a' key
+        *              alert( event.getKeystroke() == CKEDITOR.CTRL + CKEDITOR.SHIFT + 65 );   // CTRL + SHIFT + 'a' key
+        *
+        * @returns {Number} The number representing the keys combination.
+        */
+       getKeystroke: function() {
+               var keystroke = this.getKey();
+
+               if ( this.$.ctrlKey || this.$.metaKey )
+                       keystroke += CKEDITOR.CTRL;
+
+               if ( this.$.shiftKey )
+                       keystroke += CKEDITOR.SHIFT;
+
+               if ( this.$.altKey )
+                       keystroke += CKEDITOR.ALT;
+
+               return keystroke;
+       },
+
+       /**
+        * Prevents the original behavior of the event to happen. It can optionally
+        * stop propagating the event in the event chain.
+        *
+        *              var element = CKEDITOR.document.getById( 'myElement' );
+        *              element.on( 'click', function( ev ) {
+        *                      // The DOM event object is passed by the 'data' property.
+        *                      var domEvent = ev.data;
+        *                      // Prevent the click to chave any effect in the element.
+        *                      domEvent.preventDefault();
+        *              } );
+        *
+        * @param {Boolean} [stopPropagation=false] Stop propagating this event in the
+        * event chain.
+        */
+       preventDefault: function( stopPropagation ) {
+               var $ = this.$;
+               if ( $.preventDefault )
+                       $.preventDefault();
+               else
+                       $.returnValue = false;
+
+               if ( stopPropagation )
+                       this.stopPropagation();
+       },
+
+       /**
+        * Stops this event propagation in the event chain.
+        */
+       stopPropagation: function() {
+               var $ = this.$;
+               if ( $.stopPropagation )
+                       $.stopPropagation();
+               else
+                       $.cancelBubble = true;
+       },
+
+       /**
+        * Returns the DOM node where the event was targeted to.
+        *
+        *              var element = CKEDITOR.document.getById( 'myElement' );
+        *              element.on( 'click', function( ev ) {
+        *                      // The DOM event object is passed by the 'data' property.
+        *                      var domEvent = ev.data;
+        *                      // Add a CSS class to the event target.
+        *                      domEvent.getTarget().addClass( 'clicked' );
+        *              } );
+        *
+        * @returns {CKEDITOR.dom.node} The target DOM node.
+        */
+       getTarget: function() {
+               var rawNode = this.$.target || this.$.srcElement;
+               return rawNode ? new CKEDITOR.dom.node( rawNode ) : null;
+       },
+
+       /**
+        * Returns an integer value that indicates the current processing phase of an event.
+        * For browsers that doesn't support event phase, {@link CKEDITOR#EVENT_PHASE_AT_TARGET} is always returned.
+        *
+        * @returns {Number} One of {@link CKEDITOR#EVENT_PHASE_CAPTURING},
+        * {@link CKEDITOR#EVENT_PHASE_AT_TARGET}, or {@link CKEDITOR#EVENT_PHASE_BUBBLING}.
+        */
+       getPhase: function() {
+               return this.$.eventPhase || 2;
+       },
+
+       /**
+        * Retrieves the coordinates of the mouse pointer relative to the top-left
+        * corner of the document, in mouse related event.
+        *
+        *              element.on( 'mousemouse', function( ev ) {
+        *                      var pageOffset = ev.data.getPageOffset();
+        *                      alert( pageOffset.x );                  // page offset X
+        *                      alert( pageOffset.y );                  // page offset Y
+        *     } );
+        *
+        * @returns {Object} The object contains the position.
+        * @returns {Number} return.x
+        * @returns {Number} return.y
+        */
+       getPageOffset: function() {
+               var doc = this.getTarget().getDocument().$;
+               var pageX = this.$.pageX || this.$.clientX + ( doc.documentElement.scrollLeft || doc.body.scrollLeft );
+               var pageY = this.$.pageY || this.$.clientY + ( doc.documentElement.scrollTop || doc.body.scrollTop );
+               return { x: pageX, y: pageY };
+       }
+};
+
+// For the followind constants, we need to go over the Unicode boundaries
+// (0x10FFFF) to avoid collision.
+
+/**
+ * CTRL key (0x110000).
+ *
+ * @readonly
+ * @property {Number} [=0x110000]
+ * @member CKEDITOR
+ */
+CKEDITOR.CTRL = 0x110000;
+
+/**
+ * SHIFT key (0x220000).
+ *
+ * @readonly
+ * @property {Number} [=0x220000]
+ * @member CKEDITOR
+ */
+CKEDITOR.SHIFT = 0x220000;
+
+/**
+ * ALT key (0x440000).
+ *
+ * @readonly
+ * @property {Number} [=0x440000]
+ * @member CKEDITOR
+ */
+CKEDITOR.ALT = 0x440000;
+
+/**
+ * Capturing phase.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.EVENT_PHASE_CAPTURING = 1;
+
+/**
+ * Event at target.
+ *
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.EVENT_PHASE_AT_TARGET = 2;
+
+/**
+ * Bubbling phase.
+ *
+ * @readonly
+ * @property {Number} [=3]
+ * @member CKEDITOR
+ */
+CKEDITOR.EVENT_PHASE_BUBBLING = 3;
diff --git a/sources/core/dom/iterator.js b/sources/core/dom/iterator.js
new file mode 100644 (file)
index 0000000..50056ec
--- /dev/null
@@ -0,0 +1,565 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @ignore
+ * File overview: DOM iterator which iterates over list items, lines and paragraphs.
+ */
+
+'use strict';
+
+( function() {
+       /**
+        * Represents the iterator class. It can be used to iterate
+        * over all elements (or even text nodes in case of {@link #enlargeBr} set to `false`)
+        * which establish "paragraph-like" spaces within the passed range.
+        *
+        *              // <h1>[foo</h1><p>bar]</p>
+        *              var iterator = range.createIterator();
+        *              iterator.getNextParagraph(); // h1 element
+        *              iterator.getNextParagraph(); // p element
+        *
+        *              // <ul><li>[foo</li><li>bar]</li>
+        *              // With enforceRealBlocks set to false the iterator will return two list item elements.
+        *              // With enforceRealBlocks set to true the iterator will return two paragraphs and the DOM will be changed to:
+        *              // <ul><li><p>foo</p></li><li><p>bar</p></li>
+        *
+        * @class CKEDITOR.dom.iterator
+        * @constructor Creates an iterator class instance.
+        * @param {CKEDITOR.dom.range} range
+        */
+       function iterator( range ) {
+               if ( arguments.length < 1 )
+                       return;
+
+               /**
+                * @readonly
+                * @property {CKEDITOR.dom.range}
+                */
+               this.range = range;
+
+               /**
+                * @property {Boolean} [forceBrBreak=false]
+                */
+               this.forceBrBreak = 0;
+
+               // (#3730).
+               /**
+                * Whether to include `<br>` elements in the enlarged range. Should be
+                * set to `false` when using the iterator in the {@link CKEDITOR#ENTER_BR} mode.
+                *
+                * @property {Boolean} [enlargeBr=true]
+                */
+               this.enlargeBr = 1;
+
+               /**
+                * Whether the iterator should create a transformable block
+                * if the current one contains text and cannot be transformed.
+                * For example new blocks will be established in elements like
+                * `<li>` or `<td>`.
+                *
+                * @property {Boolean} [enforceRealBlocks=false]
+                */
+               this.enforceRealBlocks = 0;
+
+               this._ || ( this._ = {} );
+       }
+
+       /**
+        * Default iterator's filter. It is set only for nested iterators.
+        *
+        * @since 4.3
+        * @readonly
+        * @property {CKEDITOR.filter} filter
+        */
+
+       /**
+        * Iterator's active filter. It is set by the {@link #getNextParagraph} method
+        * when it enters a nested editable.
+        *
+        * @since 4.3
+        * @readonly
+        * @property {CKEDITOR.filter} activeFilter
+        */
+
+       var beginWhitespaceRegex = /^[\r\n\t ]+$/,
+               // Ignore bookmark nodes.(#3783)
+               bookmarkGuard = CKEDITOR.dom.walker.bookmark( false, true ),
+               whitespacesGuard = CKEDITOR.dom.walker.whitespaces( true ),
+               skipGuard = function( node ) {
+                       return bookmarkGuard( node ) && whitespacesGuard( node );
+               },
+               listItemNames = { dd: 1, dt: 1, li: 1 };
+
+       iterator.prototype = {
+               /**
+                * Returns the next paragraph-like element or `null` if the end of a range is reached.
+                *
+                * @param {String} [blockTag='p'] Name of a block element which will be established by
+                * the iterator in block-less elements (see {@link #enforceRealBlocks}).
+                */
+               getNextParagraph: function( blockTag ) {
+                       // The block element to be returned.
+                       var block;
+
+                       // The range object used to identify the paragraph contents.
+                       var range;
+
+                       // Indicats that the current element in the loop is the last one.
+                       var isLast;
+
+                       // Instructs to cleanup remaining BRs.
+                       var removePreviousBr, removeLastBr;
+
+                       blockTag = blockTag || 'p';
+
+                       // We're iterating over nested editable.
+                       if ( this._.nestedEditable ) {
+                               // Get next block from nested iterator and returns it if was found.
+                               block = this._.nestedEditable.iterator.getNextParagraph( blockTag );
+                               if ( block ) {
+                                       // Inherit activeFilter from the nested iterator.
+                                       this.activeFilter = this._.nestedEditable.iterator.activeFilter;
+                                       return block;
+                               }
+
+                               // No block in nested iterator means that we reached the end of the nested editable.
+                               // Reset the active filter to the default filter (or undefined if this iterator didn't have it).
+                               this.activeFilter = this.filter;
+
+                               // Try to find next nested editable or get back to parent (this) iterator.
+                               if ( startNestedEditableIterator( this, blockTag, this._.nestedEditable.container, this._.nestedEditable.remaining ) ) {
+                                       // Inherit activeFilter from the nested iterator.
+                                       this.activeFilter = this._.nestedEditable.iterator.activeFilter;
+                                       return this._.nestedEditable.iterator.getNextParagraph( blockTag );
+                               } else {
+                                       this._.nestedEditable = null;
+                               }
+                       }
+
+                       // Block-less range should be checked first.
+                       if ( !this.range.root.getDtd()[ blockTag ] )
+                               return null;
+
+                       // This is the first iteration. Let's initialize it.
+                       if ( !this._.started )
+                               range = startIterator.call( this );
+
+                       var currentNode = this._.nextNode,
+                               lastNode = this._.lastNode;
+
+                       this._.nextNode = null;
+                       while ( currentNode ) {
+                               // closeRange indicates that a paragraph boundary has been found,
+                               // so the range can be closed.
+                               var closeRange = 0,
+                                       parentPre = currentNode.hasAscendant( 'pre' );
+
+                               // includeNode indicates that the current node is good to be part
+                               // of the range. By default, any non-element node is ok for it.
+                               var includeNode = ( currentNode.type != CKEDITOR.NODE_ELEMENT ),
+                                       continueFromSibling = 0;
+
+                               // If it is an element node, let's check if it can be part of the range.
+                               if ( !includeNode ) {
+                                       var nodeName = currentNode.getName();
+
+                                       // Non-editable block was found - return it and move to processing
+                                       // its nested editables if they exist.
+                                       if ( CKEDITOR.dtd.$block[ nodeName ] && currentNode.getAttribute( 'contenteditable' ) == 'false' ) {
+                                               block = currentNode;
+
+                                               // Setup iterator for first of nested editables.
+                                               // If there's no editable, then algorithm will move to next element after current block.
+                                               startNestedEditableIterator( this, blockTag, block );
+
+                                               // Gets us straight to the end of getParagraph() because block variable is set.
+                                               break;
+                                       } else if ( currentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
+                                               // <br> boundaries must be part of the range. It will
+                                               // happen only if ForceBrBreak.
+                                               if ( nodeName == 'br' )
+                                                       includeNode = 1;
+                                               else if ( !range && !currentNode.getChildCount() && nodeName != 'hr' ) {
+                                                       // If we have found an empty block, and haven't started
+                                                       // the range yet, it means we must return this block.
+                                                       block = currentNode;
+                                                       isLast = currentNode.equals( lastNode );
+                                                       break;
+                                               }
+
+                                               // The range must finish right before the boundary,
+                                               // including possibly skipped empty spaces. (#1603)
+                                               if ( range ) {
+                                                       range.setEndAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
+
+                                                       // The found boundary must be set as the next one at this
+                                                       // point. (#1717)
+                                                       if ( nodeName != 'br' ) {
+                                                               this._.nextNode = currentNode;
+                                                       }
+                                               }
+
+                                               closeRange = 1;
+                                       } else {
+                                               // If we have child nodes, let's check them.
+                                               if ( currentNode.getFirst() ) {
+                                                       // If we don't have a range yet, let's start it.
+                                                       if ( !range ) {
+                                                               range = this.range.clone();
+                                                               range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
+                                                       }
+
+                                                       currentNode = currentNode.getFirst();
+                                                       continue;
+                                               }
+                                               includeNode = 1;
+                                       }
+                               } else if ( currentNode.type == CKEDITOR.NODE_TEXT ) {
+                                       // Ignore normal whitespaces (i.e. not including &nbsp; or
+                                       // other unicode whitespaces) before/after a block node.
+                                       if ( beginWhitespaceRegex.test( currentNode.getText() ) )
+                                               includeNode = 0;
+                               }
+
+                               // The current node is good to be part of the range and we are
+                               // starting a new range, initialize it first.
+                               if ( includeNode && !range ) {
+                                       range = this.range.clone();
+                                       range.setStartAt( currentNode, CKEDITOR.POSITION_BEFORE_START );
+                               }
+
+                               // The last node has been found.
+                               isLast = ( ( !closeRange || includeNode ) && currentNode.equals( lastNode ) );
+
+                               // If we are in an element boundary, let's check if it is time
+                               // to close the range, otherwise we include the parent within it.
+                               if ( range && !closeRange ) {
+                                       while ( !currentNode.getNext( skipGuard ) && !isLast ) {
+                                               var parentNode = currentNode.getParent();
+
+                                               if ( parentNode.isBlockBoundary( this.forceBrBreak && !parentPre && { br: 1 } ) ) {
+                                                       closeRange = 1;
+                                                       includeNode = 0;
+                                                       isLast = isLast || ( parentNode.equals( lastNode ) );
+                                                       // Make sure range includes bookmarks at the end of the block. (#7359)
+                                                       range.setEndAt( parentNode, CKEDITOR.POSITION_BEFORE_END );
+                                                       break;
+                                               }
+
+                                               currentNode = parentNode;
+                                               includeNode = 1;
+                                               isLast = ( currentNode.equals( lastNode ) );
+                                               continueFromSibling = 1;
+                                       }
+                               }
+
+                               // Now finally include the node.
+                               if ( includeNode )
+                                       range.setEndAt( currentNode, CKEDITOR.POSITION_AFTER_END );
+
+                               currentNode = this._getNextSourceNode( currentNode, continueFromSibling, lastNode );
+                               isLast = !currentNode;
+
+                               // We have found a block boundary. Let's close the range and move out of the
+                               // loop.
+                               if ( isLast || ( closeRange && range ) )
+                                       break;
+                       }
+
+                       // Now, based on the processed range, look for (or create) the block to be returned.
+                       if ( !block ) {
+                               // If no range has been found, this is the end.
+                               if ( !range ) {
+                                       this._.docEndMarker && this._.docEndMarker.remove();
+                                       this._.nextNode = null;
+                                       return null;
+                               }
+
+                               var startPath = new CKEDITOR.dom.elementPath( range.startContainer, range.root );
+                               var startBlockLimit = startPath.blockLimit,
+                                       checkLimits = { div: 1, th: 1, td: 1 };
+                               block = startPath.block;
+
+                               if ( !block && startBlockLimit && !this.enforceRealBlocks && checkLimits[ startBlockLimit.getName() ] &&
+                                       range.checkStartOfBlock() && range.checkEndOfBlock() && !startBlockLimit.equals( range.root ) ) {
+                                       block = startBlockLimit;
+                               } else if ( !block || ( this.enforceRealBlocks && block.is( listItemNames ) ) ) {
+                                       // Create the fixed block.
+                                       block = this.range.document.createElement( blockTag );
+
+                                       // Move the contents of the temporary range to the fixed block.
+                                       range.extractContents().appendTo( block );
+                                       block.trim();
+
+                                       // Insert the fixed block into the DOM.
+                                       range.insertNode( block );
+
+                                       removePreviousBr = removeLastBr = true;
+                               } else if ( block.getName() != 'li' ) {
+                                       // If the range doesn't includes the entire contents of the
+                                       // block, we must split it, isolating the range in a dedicated
+                                       // block.
+                                       if ( !range.checkStartOfBlock() || !range.checkEndOfBlock() ) {
+                                               // The resulting block will be a clone of the current one.
+                                               block = block.clone( false );
+
+                                               // Extract the range contents, moving it to the new block.
+                                               range.extractContents().appendTo( block );
+                                               block.trim();
+
+                                               // Split the block. At this point, the range will be in the
+                                               // right position for our intents.
+                                               var splitInfo = range.splitBlock();
+
+                                               removePreviousBr = !splitInfo.wasStartOfBlock;
+                                               removeLastBr = !splitInfo.wasEndOfBlock;
+
+                                               // Insert the new block into the DOM.
+                                               range.insertNode( block );
+                                       }
+                               } else if ( !isLast ) {
+                                       // LIs are returned as is, with all their children (due to the
+                                       // nested lists). But, the next node is the node right after
+                                       // the current range, which could be an <li> child (nested
+                                       // lists) or the next sibling <li>.
+
+                                       this._.nextNode = ( block.equals( lastNode ) ? null : this._getNextSourceNode( range.getBoundaryNodes().endNode, 1, lastNode  ) );
+                               }
+                       }
+
+                       if ( removePreviousBr ) {
+                               var previousSibling = block.getPrevious();
+                               if ( previousSibling && previousSibling.type == CKEDITOR.NODE_ELEMENT ) {
+                                       if ( previousSibling.getName() == 'br' )
+                                               previousSibling.remove();
+                                       else if ( previousSibling.getLast() && previousSibling.getLast().$.nodeName.toLowerCase() == 'br' )
+                                               previousSibling.getLast().remove();
+                               }
+                       }
+
+                       if ( removeLastBr ) {
+                               var lastChild = block.getLast();
+                               if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && lastChild.getName() == 'br' ) {
+                                       // Remove br filler on browser which do not need it.
+                                       if ( !CKEDITOR.env.needsBrFiller || lastChild.getPrevious( bookmarkGuard ) || lastChild.getNext( bookmarkGuard ) )
+                                               lastChild.remove();
+                               }
+                       }
+
+                       // Get a reference for the next element. This is important because the
+                       // above block can be removed or changed, so we can rely on it for the
+                       // next interation.
+                       if ( !this._.nextNode ) {
+                               this._.nextNode = ( isLast || block.equals( lastNode ) || !lastNode ) ? null : this._getNextSourceNode( block, 1, lastNode );
+                       }
+
+                       return block;
+               },
+
+               /**
+                * Gets the next element to check or `null` when the `lastNode` or the
+                * {@link #range}'s {@link CKEDITOR.dom.range#root root} is reached. Bookmarks are skipped.
+                *
+                * @since 4.4.6
+                * @private
+                * @param {CKEDITOR.dom.node} node
+                * @param {Boolean} startFromSibling
+                * @param {CKEDITOR.dom.node} lastNode
+                * @returns {CKEDITOR.dom.node}
+                */
+               _getNextSourceNode: function( node, startFromSibling, lastNode ) {
+                       var rootNode = this.range.root,
+                               next;
+
+                       // Here we are checking in guard function whether current element
+                       // reach lastNode(default behaviour) and root node to prevent against
+                       // getting out of editor instance root DOM object.
+                       // #12484
+                       function guardFunction( node ) {
+                               return !( node.equals( lastNode ) || node.equals( rootNode ) );
+                       }
+
+                       next = node.getNextSourceNode( startFromSibling, null, guardFunction );
+                       while ( !bookmarkGuard( next ) ) {
+                               next = next.getNextSourceNode( startFromSibling, null, guardFunction );
+                       }
+                       return next;
+               }
+       };
+
+       // @context CKEDITOR.dom.iterator
+       // @returns Collapsed range which will be reused when during furter processing.
+       function startIterator() {
+               var range = this.range.clone(),
+                       // Indicate at least one of the range boundaries is inside a preformat block.
+                       touchPre,
+
+                       // (#12178)
+                       // Remember if following situation takes place:
+                       // * startAtInnerBoundary: <p>foo[</p>...
+                       // * endAtInnerBoundary: ...<p>]bar</p>
+                       // Because information about line break will be lost when shrinking range.
+                       // Note that we test only if path block exist, because we must properly shrink
+                       // range containing table and/or table cells.
+                       // Note: When range is collapsed there's no way it can be shrinked.
+                       // By checking if range is collapsed we also prevent #12308.
+                       startPath = range.startPath(),
+                       endPath = range.endPath(),
+                       startAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, startPath.block ),
+                       endAtInnerBoundary = !range.collapsed && rangeAtInnerBlockBoundary( range, endPath.block, 1 );
+
+               // Shrink the range to exclude harmful "noises" (#4087, #4450, #5435).
+               range.shrink( CKEDITOR.SHRINK_ELEMENT, true );
+
+               if ( startAtInnerBoundary )
+                       range.setStartAt( startPath.block, CKEDITOR.POSITION_BEFORE_END );
+               if ( endAtInnerBoundary )
+                       range.setEndAt( endPath.block, CKEDITOR.POSITION_AFTER_START );
+
+               touchPre = range.endContainer.hasAscendant( 'pre', true ) || range.startContainer.hasAscendant( 'pre', true );
+
+               range.enlarge( this.forceBrBreak && !touchPre || !this.enlargeBr ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
+
+               if ( !range.collapsed ) {
+                       var walker = new CKEDITOR.dom.walker( range.clone() ),
+                               ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
+                       // Avoid anchor inside bookmark inner text.
+                       walker.evaluator = ignoreBookmarkTextEvaluator;
+                       this._.nextNode = walker.next();
+                       // TODO: It's better to have walker.reset() used here.
+                       walker = new CKEDITOR.dom.walker( range.clone() );
+                       walker.evaluator = ignoreBookmarkTextEvaluator;
+                       var lastNode = walker.previous();
+                       this._.lastNode = lastNode.getNextSourceNode( true, null, range.root );
+
+                       // We may have an empty text node at the end of block due to [3770].
+                       // If that node is the lastNode, it would cause our logic to leak to the
+                       // next block.(#3887)
+                       if ( this._.lastNode && this._.lastNode.type == CKEDITOR.NODE_TEXT && !CKEDITOR.tools.trim( this._.lastNode.getText() ) && this._.lastNode.getParent().isBlockBoundary() ) {
+                               var testRange = this.range.clone();
+                               testRange.moveToPosition( this._.lastNode, CKEDITOR.POSITION_AFTER_END );
+                               if ( testRange.checkEndOfBlock() ) {
+                                       var path = new CKEDITOR.dom.elementPath( testRange.endContainer, testRange.root ),
+                                               lastBlock = path.block || path.blockLimit;
+                                       this._.lastNode = lastBlock.getNextSourceNode( true );
+                               }
+                       }
+
+                       // The end of document or range.root was reached, so we need a marker node inside.
+                       if ( !this._.lastNode || !range.root.contains( this._.lastNode ) ) {
+                               this._.lastNode = this._.docEndMarker = range.document.createText( '' );
+                               this._.lastNode.insertAfter( lastNode );
+                       }
+
+                       // Let's reuse this variable.
+                       range = null;
+               }
+
+               this._.started = 1;
+
+               return range;
+       }
+
+       // Does a nested editables lookup inside editablesContainer.
+       // If remainingEditables is set will lookup inside this array.
+       // @param {CKEDITOR.dom.element} editablesContainer
+       // @param {CKEDITOR.dom.element[]} [remainingEditables]
+       function getNestedEditableIn( editablesContainer, remainingEditables ) {
+               if ( remainingEditables == null )
+                       remainingEditables = findNestedEditables( editablesContainer );
+
+               var editable;
+
+               while ( ( editable = remainingEditables.shift() ) ) {
+                       if ( isIterableEditable( editable ) )
+                               return { element: editable, remaining: remainingEditables };
+               }
+
+               return null;
+       }
+
+       // Checkes whether we can iterate over this editable.
+       function isIterableEditable( editable ) {
+               // Reject blockless editables.
+               return editable.getDtd().p;
+       }
+
+       // Finds nested editables within container. Does not return
+       // editables nested in another editable (twice).
+       function findNestedEditables( container ) {
+               var editables = [];
+
+               container.forEach( function( element ) {
+                       if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
+                               editables.push( element );
+                               return false; // Skip children.
+                       }
+               }, CKEDITOR.NODE_ELEMENT, true );
+
+               return editables;
+       }
+
+       // Looks for a first nested editable after previousEditable (if passed) and creates
+       // nested iterator for it.
+       function startNestedEditableIterator( parentIterator, blockTag, editablesContainer, remainingEditables ) {
+               var editable = getNestedEditableIn( editablesContainer, remainingEditables );
+
+               if ( !editable )
+                       return 0;
+
+               var filter = CKEDITOR.filter.instances[ editable.element.data( 'cke-filter' ) ];
+
+               // If current editable has a filter and this filter does not allow for block tag,
+               // search for next nested editable in remaining ones.
+               if ( filter && !filter.check( blockTag ) )
+                       return startNestedEditableIterator( parentIterator, blockTag, editablesContainer, editable.remaining );
+
+               var range = new CKEDITOR.dom.range( editable.element );
+               range.selectNodeContents( editable.element );
+
+               var iterator = range.createIterator();
+               // This setting actually does not change anything in this case,
+               // because entire range contents is selected, so there're no <br>s to be included.
+               // But it seems right to copy it too.
+               iterator.enlargeBr = parentIterator.enlargeBr;
+               // Inherit configuration from parent iterator.
+               iterator.enforceRealBlocks = parentIterator.enforceRealBlocks;
+               // Set the activeFilter (which can be overriden when this iteator will start nested iterator)
+               // and the default filter, which will make it possible to reset to
+               // current iterator's activeFilter after leaving nested editable.
+               iterator.activeFilter = iterator.filter = filter;
+
+               parentIterator._.nestedEditable = {
+                       element: editable.element,
+                       container: editablesContainer,
+                       remaining: editable.remaining,
+                       iterator: iterator
+               };
+
+               return 1;
+       }
+
+       // Checks whether range starts or ends at inner block boundary.
+       // See usage comments to learn more.
+       function rangeAtInnerBlockBoundary( range, block, checkEnd ) {
+               if ( !block )
+                       return false;
+
+               var testRange = range.clone();
+               testRange.collapse( !checkEnd );
+               return testRange.checkBoundaryOfElement( block, checkEnd ? CKEDITOR.START : CKEDITOR.END );
+       }
+
+       /**
+        * Creates a {@link CKEDITOR.dom.iterator} instance for this range.
+        *
+        * @member CKEDITOR.dom.range
+        * @returns {CKEDITOR.dom.iterator}
+        */
+       CKEDITOR.dom.range.prototype.createIterator = function() {
+               return new iterator( this );
+       };
+} )();
diff --git a/sources/core/dom/node.js b/sources/core/dom/node.js
new file mode 100644 (file)
index 0000000..51bba18
--- /dev/null
@@ -0,0 +1,902 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.node} class which is the base
+ *             class for classes that represent DOM nodes.
+ */
+
+/**
+ * Base class for classes representing DOM nodes. This constructor may return
+ * an instance of a class that inherits from this class, like
+ * {@link CKEDITOR.dom.element} or {@link CKEDITOR.dom.text}.
+ *
+ * @class
+ * @extends CKEDITOR.dom.domObject
+ * @constructor Creates a node class instance.
+ * @param {Object} domNode A native DOM node.
+ * @see CKEDITOR.dom.element
+ * @see CKEDITOR.dom.text
+ */
+CKEDITOR.dom.node = function( domNode ) {
+       if ( domNode ) {
+               var type =
+                       domNode.nodeType == CKEDITOR.NODE_DOCUMENT ? 'document' :
+                       domNode.nodeType == CKEDITOR.NODE_ELEMENT ? 'element' :
+                       domNode.nodeType == CKEDITOR.NODE_TEXT ? 'text' :
+                       domNode.nodeType == CKEDITOR.NODE_COMMENT ? 'comment' :
+                       domNode.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ? 'documentFragment' :
+                       'domObject'; // Call the base constructor otherwise.
+
+               return new CKEDITOR.dom[ type ]( domNode );
+       }
+
+       return this;
+};
+
+CKEDITOR.dom.node.prototype = new CKEDITOR.dom.domObject();
+
+/**
+ * Element node type.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.NODE_ELEMENT = 1;
+
+/**
+ * Document node type.
+ *
+ * @readonly
+ * @property {Number} [=9]
+ * @member CKEDITOR
+ */
+CKEDITOR.NODE_DOCUMENT = 9;
+
+/**
+ * Text node type.
+ *
+ * @readonly
+ * @property {Number} [=3]
+ * @member CKEDITOR
+ */
+CKEDITOR.NODE_TEXT = 3;
+
+/**
+ * Comment node type.
+ *
+ * @readonly
+ * @property {Number} [=8]
+ * @member CKEDITOR
+ */
+CKEDITOR.NODE_COMMENT = 8;
+
+/**
+ * Document fragment node type.
+ *
+ * @readonly
+ * @property {Number} [=11]
+ * @member CKEDITOR
+ */
+CKEDITOR.NODE_DOCUMENT_FRAGMENT = 11;
+
+/**
+ * Indicates that positions of both nodes are identical (this is the same node). See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=0]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_IDENTICAL = 0;
+
+/**
+ * Indicates that nodes are in different (detached) trees. See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_DISCONNECTED = 1;
+
+/**
+ * Indicates that the context node follows the other node. See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_FOLLOWING = 2;
+
+/**
+ * Indicates that the context node precedes the other node. See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=4]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_PRECEDING = 4;
+
+/**
+ * Indicates that the context node is a descendant of the other node. See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=8]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_IS_CONTAINED = 8;
+
+/**
+ * Indicates that the context node contains the other node. See {@link CKEDITOR.dom.node#getPosition}.
+ *
+ * @readonly
+ * @property {Number} [=16]
+ * @member CKEDITOR
+ */
+CKEDITOR.POSITION_CONTAINS = 16;
+
+CKEDITOR.tools.extend( CKEDITOR.dom.node.prototype, {
+       /**
+        * Makes this node a child of another element.
+        *
+        *              var p = new CKEDITOR.dom.element( 'p' );
+        *              var strong = new CKEDITOR.dom.element( 'strong' );
+        *              strong.appendTo( p );
+        *
+        *              // Result: '<p><strong></strong></p>'.
+        *
+        * @param {CKEDITOR.dom.element} element The target element to which this node will be appended.
+        * @returns {CKEDITOR.dom.element} The target element.
+        */
+       appendTo: function( element, toStart ) {
+               element.append( this, toStart );
+               return element;
+       },
+
+       /**
+        * Clones this node.
+        *
+        * **Note**: Values set by {#setCustomData} will not be available in the clone.
+        *
+        * @param {Boolean} [includeChildren=false] If `true` then all node's
+        * children will be cloned recursively.
+        * @param {Boolean} [cloneId=false] Whether ID attributes should be cloned, too.
+        * @returns {CKEDITOR.dom.node} Clone of this node.
+        */
+       clone: function( includeChildren, cloneId ) {
+               var $clone = this.$.cloneNode( includeChildren );
+
+               // The "id" attribute should never be cloned to avoid duplication.
+               removeIds( $clone );
+
+               var node = new CKEDITOR.dom.node( $clone );
+
+               // On IE8 we need to fixed HTML5 node name, see details below.
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 &&
+                       ( this.type == CKEDITOR.NODE_ELEMENT || this.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) {
+                       renameNodes( node );
+               }
+
+               return node;
+
+               function removeIds( node ) {
+                       // Reset data-cke-expando only when has been cloned (IE and only for some types of objects).
+                       if ( node[ 'data-cke-expando' ] )
+                               node[ 'data-cke-expando' ] = false;
+
+                       if ( node.nodeType != CKEDITOR.NODE_ELEMENT && node.nodeType != CKEDITOR.NODE_DOCUMENT_FRAGMENT  )
+                               return;
+
+                       if ( !cloneId && node.nodeType == CKEDITOR.NODE_ELEMENT )
+                               node.removeAttribute( 'id', false );
+
+                       if ( includeChildren ) {
+                               var childs = node.childNodes;
+                               for ( var i = 0; i < childs.length; i++ )
+                                       removeIds( childs[ i ] );
+                       }
+               }
+
+               // IE8 rename HTML5 nodes by adding `:` at the begging of the tag name when the node is cloned,
+               // so `<figure>` will be `<:figure>` after 'cloneNode'. We need to fix it (#13101).
+               function renameNodes( node ) {
+                       if ( node.type != CKEDITOR.NODE_ELEMENT && node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT )
+                               return;
+
+                       if ( node.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT ) {
+                               var name = node.getName();
+                               if ( name[ 0 ] == ':' ) {
+                                       node.renameNode( name.substring( 1 ) );
+                               }
+                       }
+
+                       if ( includeChildren ) {
+                               for ( var i = 0; i < node.getChildCount(); i++ )
+                                       renameNodes( node.getChild( i ) );
+                       }
+               }
+       },
+
+       /**
+        * Checks if the node is preceded by any sibling.
+        *
+        * @returns {Boolean}
+        */
+       hasPrevious: function() {
+               return !!this.$.previousSibling;
+       },
+
+       /**
+        * Checks if the node is succeeded by any sibling.
+        *
+        * @returns {Boolean}
+        */
+       hasNext: function() {
+               return !!this.$.nextSibling;
+       },
+
+       /**
+        * Inserts this element after a node.
+        *
+        *              var em = new CKEDITOR.dom.element( 'em' );
+        *              var strong = new CKEDITOR.dom.element( 'strong' );
+        *              strong.insertAfter( em );
+        *
+        *              // Result: '<em></em><strong></strong>'
+        *
+        * @param {CKEDITOR.dom.node} node The node that will precede this element.
+        * @returns {CKEDITOR.dom.node} The node preceding this one after insertion.
+        */
+       insertAfter: function( node ) {
+               node.$.parentNode.insertBefore( this.$, node.$.nextSibling );
+               return node;
+       },
+
+       /**
+        * Inserts this element before a node.
+        *
+        *              var em = new CKEDITOR.dom.element( 'em' );
+        *              var strong = new CKEDITOR.dom.element( 'strong' );
+        *              strong.insertBefore( em );
+        *
+        *              // result: '<strong></strong><em></em>'
+        *
+        * @param {CKEDITOR.dom.node} node The node that will succeed this element.
+        * @returns {CKEDITOR.dom.node} The node being inserted.
+        */
+       insertBefore: function( node ) {
+               node.$.parentNode.insertBefore( this.$, node.$ );
+               return node;
+       },
+
+       /**
+        * Inserts a node before this node.
+        *
+        *              var em = new CKEDITOR.dom.element( 'em' );
+        *              var strong = new CKEDITOR.dom.element( 'strong' );
+        *              strong.insertBeforeMe( em );
+        *
+        *              // result: '<em></em><strong></strong>'
+        *
+        * @param {CKEDITOR.dom.node} node The node that will preceed this element.
+        * @returns {CKEDITOR.dom.node} The node being inserted.
+        */
+       insertBeforeMe: function( node ) {
+               this.$.parentNode.insertBefore( node.$, this.$ );
+               return node;
+       },
+
+       /**
+        * Retrieves a uniquely identifiable tree address for this node.
+        * The tree address returned is an array of integers, with each integer
+        * indicating a child index of a DOM node, starting from
+        * `document.documentElement`.
+        *
+        * For example, assuming `<body>` is the second child
+        * of `<html>` (`<head>` being the first),
+        * and we would like to address the third child under the
+        * fourth child of `<body>`, the tree address returned would be:
+        * `[1, 3, 2]`.
+        *
+        * The tree address cannot be used for finding back the DOM tree node once
+        * the DOM tree structure has been modified.
+        *
+        * @param {Boolean} [normalized=false] See {@link #getIndex}.
+        * @returns {Array} The address.
+        */
+       getAddress: function( normalized ) {
+               var address = [];
+               var $documentElement = this.getDocument().$.documentElement;
+               var node = this.$;
+
+               while ( node && node != $documentElement ) {
+                       var parentNode = node.parentNode;
+
+                       if ( parentNode ) {
+                               // Get the node index. For performance, call getIndex
+                               // directly, instead of creating a new node object.
+                               address.unshift( this.getIndex.call( { $: node }, normalized ) );
+                       }
+
+                       node = parentNode;
+               }
+
+               return address;
+       },
+
+       /**
+        * Gets the document containing this element.
+        *
+        *              var element = CKEDITOR.document.getById( 'example' );
+        *              alert( element.getDocument().equals( CKEDITOR.document ) ); // true
+        *
+        * @returns {CKEDITOR.dom.document} The document.
+        */
+       getDocument: function() {
+               return new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
+       },
+
+       /**
+        * Gets the index of a node in an array of its `parent.childNodes`.
+        * Returns `-1` if a node does not have a parent or when the `normalized` argument is set to `true`
+        * and the text node is empty and will be removed during the normalization.
+        *
+        * Let us assume having the following `childNodes` array:
+        *
+        *              [ emptyText, element1, text, text, element2, emptyText2 ]
+        *
+        *              emptyText.getIndex()                    // 0
+        *              emptyText.getIndex( true )              // -1
+        *              element1.getIndex();                    // 1
+        *              element1.getIndex( true );              // 0
+        *              element2.getIndex();                    // 4
+        *              element2.getIndex( true );              // 2
+        *              emptyText2.getIndex();                  // 5
+        *              emptyText2.getIndex( true );    // -1
+        *
+        * @param {Boolean} normalized When `true`, adjacent text nodes are merged and empty text nodes are removed.
+        * @returns {Number} Index of a node or `-1` if a node does not have a parent or is removed during the normalization.
+        */
+       getIndex: function( normalized ) {
+               // Attention: getAddress depends on this.$
+               // getIndex is called on a plain object: { $ : node }
+
+               var current = this.$,
+                       index = -1,
+                       isNormalizing;
+
+               if ( !this.$.parentNode )
+                       return -1;
+
+               // The idea is - all empty text nodes will be virtually merged into their adjacent text nodes.
+               // If an empty text node does not have an adjacent non-empty text node we can return -1 straight away,
+               // because it and all its sibling text nodes will be merged into an empty text node and then totally ignored.
+               if ( normalized && current.nodeType == CKEDITOR.NODE_TEXT && isEmpty( current ) ) {
+                       var adjacent = getAdjacentNonEmptyTextNode( current ) || getAdjacentNonEmptyTextNode( current, true );
+
+                       if ( !adjacent )
+                               return -1;
+               }
+
+               do {
+                       // Bypass blank node and adjacent text nodes.
+                       if ( normalized && current != this.$ && current.nodeType == CKEDITOR.NODE_TEXT && ( isNormalizing || isEmpty( current ) ) )
+                               continue;
+
+                       index++;
+                       isNormalizing = current.nodeType == CKEDITOR.NODE_TEXT;
+               }
+               while ( ( current = current.previousSibling ) );
+
+               return index;
+
+               function getAdjacentNonEmptyTextNode( node, lookForward ) {
+                       var sibling = lookForward ? node.nextSibling : node.previousSibling;
+
+                       if ( !sibling || sibling.nodeType != CKEDITOR.NODE_TEXT ) {
+                               return null;
+                       }
+
+                       // If found a non-empty text node, then return it.
+                       // If not, then continue search.
+                       return isEmpty( sibling ) ? getAdjacentNonEmptyTextNode( sibling, lookForward ) : sibling;
+               }
+
+               // Checks whether a text node is empty or is FCSeq string (which will be totally removed when normalizing).
+               function isEmpty( textNode ) {
+                       return !textNode.nodeValue || textNode.nodeValue == CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
+               }
+       },
+
+       /**
+        * @todo
+        */
+       getNextSourceNode: function( startFromSibling, nodeType, guard ) {
+               // If "guard" is a node, transform it in a function.
+               if ( guard && !guard.call ) {
+                       var guardNode = guard;
+                       guard = function( node ) {
+                               return !node.equals( guardNode );
+                       };
+               }
+
+               var node = ( !startFromSibling && this.getFirst && this.getFirst() ),
+                       parent;
+
+               // Guarding when we're skipping the current element( no children or 'startFromSibling' ).
+               // send the 'moving out' signal even we don't actually dive into.
+               if ( !node ) {
+                       if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
+                               return null;
+                       node = this.getNext();
+               }
+
+               while ( !node && ( parent = ( parent || this ).getParent() ) ) {
+                       // The guard check sends the "true" paramenter to indicate that
+                       // we are moving "out" of the element.
+                       if ( guard && guard( parent, true ) === false )
+                               return null;
+
+                       node = parent.getNext();
+               }
+
+               if ( !node )
+                       return null;
+
+               if ( guard && guard( node ) === false )
+                       return null;
+
+               if ( nodeType && nodeType != node.type )
+                       return node.getNextSourceNode( false, nodeType, guard );
+
+               return node;
+       },
+
+       /**
+        * @todo
+        */
+       getPreviousSourceNode: function( startFromSibling, nodeType, guard ) {
+               if ( guard && !guard.call ) {
+                       var guardNode = guard;
+                       guard = function( node ) {
+                               return !node.equals( guardNode );
+                       };
+               }
+
+               var node = ( !startFromSibling && this.getLast && this.getLast() ),
+                       parent;
+
+               // Guarding when we're skipping the current element( no children or 'startFromSibling' ).
+               // send the 'moving out' signal even we don't actually dive into.
+               if ( !node ) {
+                       if ( this.type == CKEDITOR.NODE_ELEMENT && guard && guard( this, true ) === false )
+                               return null;
+                       node = this.getPrevious();
+               }
+
+               while ( !node && ( parent = ( parent || this ).getParent() ) ) {
+                       // The guard check sends the "true" paramenter to indicate that
+                       // we are moving "out" of the element.
+                       if ( guard && guard( parent, true ) === false )
+                               return null;
+
+                       node = parent.getPrevious();
+               }
+
+               if ( !node )
+                       return null;
+
+               if ( guard && guard( node ) === false )
+                       return null;
+
+               if ( nodeType && node.type != nodeType )
+                       return node.getPreviousSourceNode( false, nodeType, guard );
+
+               return node;
+       },
+
+       /**
+        * Gets the node that preceeds this element in its parent's child list.
+        *
+        *              var element = CKEDITOR.dom.element.createFromHtml( '<div><i>prev</i><b>Example</b></div>' );
+        *              var first = element.getLast().getPrev();
+        *              alert( first.getName() ); // 'i'
+        *
+        * @param {Function} [evaluator] Filtering the result node.
+        * @returns {CKEDITOR.dom.node} The previous node or null if not available.
+        */
+       getPrevious: function( evaluator ) {
+               var previous = this.$,
+                       retval;
+               do {
+                       previous = previous.previousSibling;
+
+                       // Avoid returning the doc type node.
+                       // http://www.w3.org/TR/REC-DOM-Level-1/level-one-core.html#ID-412266927
+                       retval = previous && previous.nodeType != 10 && new CKEDITOR.dom.node( previous );
+               }
+               while ( retval && evaluator && !evaluator( retval ) );
+               return retval;
+       },
+
+       /**
+        * Gets the node that follows this element in its parent's child list.
+        *
+        *              var element = CKEDITOR.dom.element.createFromHtml( '<div><b>Example</b><i>next</i></div>' );
+        *              var last = element.getFirst().getNext();
+        *              alert( last.getName() ); // 'i'
+        *
+        * @param {Function} [evaluator] Filtering the result node.
+        * @returns {CKEDITOR.dom.node} The next node or null if not available.
+        */
+       getNext: function( evaluator ) {
+               var next = this.$,
+                       retval;
+               do {
+                       next = next.nextSibling;
+                       retval = next && new CKEDITOR.dom.node( next );
+               }
+               while ( retval && evaluator && !evaluator( retval ) );
+               return retval;
+       },
+
+       /**
+        * Gets the parent element for this node.
+        *
+        *              var node = editor.document.getBody().getFirst();
+        *              var parent = node.getParent();
+        *              alert( parent.getName() ); // 'body'
+        *
+        * @param {Boolean} [allowFragmentParent=false] Consider also parent node that is of
+        * fragment type {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
+        * @returns {CKEDITOR.dom.element} The parent element.
+        */
+       getParent: function( allowFragmentParent ) {
+               var parent = this.$.parentNode;
+               return ( parent && ( parent.nodeType == CKEDITOR.NODE_ELEMENT || allowFragmentParent && parent.nodeType == CKEDITOR.NODE_DOCUMENT_FRAGMENT ) ) ? new CKEDITOR.dom.node( parent ) : null;
+       },
+
+       /**
+        * Returns an array containing node parents and the node itself. By default nodes are in _descending_ order.
+        *
+        *              // Assuming that body has paragraph as the first child.
+        *              var node = editor.document.getBody().getFirst();
+        *              var parents = node.getParents();
+        *              alert( parents[ 0 ].getName() + ',' + parents[ 2 ].getName() ); // 'html,p'
+        *
+        * @param {Boolean} [closerFirst=false] Determines the order of returned nodes.
+        * @returns {Array} Returns an array of {@link CKEDITOR.dom.node}.
+        */
+       getParents: function( closerFirst ) {
+               var node = this;
+               var parents = [];
+
+               do {
+                       parents[ closerFirst ? 'push' : 'unshift' ]( node );
+               }
+               while ( ( node = node.getParent() ) );
+
+               return parents;
+       },
+
+       /**
+        * @todo
+        */
+       getCommonAncestor: function( node ) {
+               if ( node.equals( this ) )
+                       return this;
+
+               if ( node.contains && node.contains( this ) )
+                       return node;
+
+               var start = this.contains ? this : this.getParent();
+
+               do {
+                       if ( start.contains( node ) ) return start;
+               }
+               while ( ( start = start.getParent() ) );
+
+               return null;
+       },
+
+       /**
+        * Determines the position relation between this node and the given {@link CKEDITOR.dom.node} in the document.
+        * This node can be preceding ({@link CKEDITOR#POSITION_PRECEDING}) or following ({@link CKEDITOR#POSITION_FOLLOWING})
+        * the given node. This node can also contain ({@link CKEDITOR#POSITION_CONTAINS}) or be contained by
+        * ({@link CKEDITOR#POSITION_IS_CONTAINED}) the given node. The function returns a bitmask of constants
+        * listed above or {@link CKEDITOR#POSITION_IDENTICAL} if the given node is the same as this node.
+        *
+        * @param {CKEDITOR.dom.node} otherNode A node to check relation with.
+        * @returns {Number} Position relation between this node and given node.
+        */
+       getPosition: function( otherNode ) {
+               var $ = this.$;
+               var $other = otherNode.$;
+
+               if ( $.compareDocumentPosition )
+                       return $.compareDocumentPosition( $other );
+
+               // IE and Safari have no support for compareDocumentPosition.
+
+               if ( $ == $other )
+                       return CKEDITOR.POSITION_IDENTICAL;
+
+               // Only element nodes support contains and sourceIndex.
+               if ( this.type == CKEDITOR.NODE_ELEMENT && otherNode.type == CKEDITOR.NODE_ELEMENT ) {
+                       if ( $.contains ) {
+                               if ( $.contains( $other ) )
+                                       return CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING;
+
+                               if ( $other.contains( $ ) )
+                                       return CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
+                       }
+
+                       if ( 'sourceIndex' in $ )
+                               return ( $.sourceIndex < 0 || $other.sourceIndex < 0 ) ? CKEDITOR.POSITION_DISCONNECTED : ( $.sourceIndex < $other.sourceIndex ) ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
+
+               }
+
+               // For nodes that don't support compareDocumentPosition, contains
+               // or sourceIndex, their "address" is compared.
+
+               var addressOfThis = this.getAddress(),
+                       addressOfOther = otherNode.getAddress(),
+                       minLevel = Math.min( addressOfThis.length, addressOfOther.length );
+
+               // Determinate preceding/following relationship.
+               for ( var i = 0; i < minLevel; i++ ) {
+                       if ( addressOfThis[ i ] != addressOfOther[ i ] ) {
+                               return addressOfThis[ i ] < addressOfOther[ i ] ? CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_FOLLOWING;
+                       }
+               }
+
+               // Determinate contains/contained relationship.
+               return ( addressOfThis.length < addressOfOther.length ) ? CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING : CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING;
+       },
+
+       /**
+        * Gets the closest ancestor node of this node, specified by its name or using an evaluator function.
+        *
+        *              // Suppose we have the following HTML structure:
+        *              // <div id="outer"><div id="inner"><p><b>Some text</b></p></div></div>
+        *              // If node == <b>
+        *              ascendant = node.getAscendant( 'div' );                         // ascendant == <div id="inner">
+        *              ascendant = node.getAscendant( 'b' );                           // ascendant == null
+        *              ascendant = node.getAscendant( 'b', true );                     // ascendant == <b>
+        *              ascendant = node.getAscendant( { div:1, p:1 } );        // Searches for the first 'div' or 'p': ascendant == <div id="inner">
+        *
+        *              // Using custom evaluator:
+        *              ascendant = node.getAscendant( function( el ) {
+        *                      return el.getId() == 'inner';
+        *              } );
+        *              // ascendant == <div id="inner">
+        *
+        * @since 3.6.1
+        * @param {String/Function/Object} query The name of the ancestor node to search or
+        * an object with the node names to search for or an evaluator function.
+        * @param {Boolean} [includeSelf] Whether to include the current
+        * node in the search.
+        * @returns {CKEDITOR.dom.node} The located ancestor node or `null` if not found.
+        */
+       getAscendant: function( query, includeSelf ) {
+               var $ = this.$,
+                       evaluator,
+                       isCustomEvaluator;
+
+               if ( !includeSelf ) {
+                       $ = $.parentNode;
+               }
+
+               // Custom checker provided in an argument.
+               if ( typeof query == 'function' ) {
+                       isCustomEvaluator = true;
+                       evaluator = query;
+               } else {
+                       // Predefined tag name checker.
+                       isCustomEvaluator = false;
+                       evaluator = function( $ ) {
+                               var name = ( typeof $.nodeName == 'string' ? $.nodeName.toLowerCase() : '' );
+
+                               return ( typeof query == 'string' ? name == query : name in query );
+                       };
+               }
+
+               while ( $ ) {
+                       // For user provided checker we use CKEDITOR.dom.node.
+                       if ( evaluator( isCustomEvaluator ? new CKEDITOR.dom.node( $ ) : $ ) ) {
+                               return new CKEDITOR.dom.node( $ );
+                       }
+
+                       try {
+                               $ = $.parentNode;
+                       } catch ( e ) {
+                               $ = null;
+                       }
+               }
+
+               return null;
+       },
+
+       /**
+        * @todo
+        */
+       hasAscendant: function( name, includeSelf ) {
+               var $ = this.$;
+
+               if ( !includeSelf )
+                       $ = $.parentNode;
+
+               while ( $ ) {
+                       if ( $.nodeName && $.nodeName.toLowerCase() == name )
+                               return true;
+
+                       $ = $.parentNode;
+               }
+               return false;
+       },
+
+       /**
+        * @todo
+        */
+       move: function( target, toStart ) {
+               target.append( this.remove(), toStart );
+       },
+
+       /**
+        * Removes this node from the document DOM.
+        *
+        *              var element = CKEDITOR.document.getById( 'MyElement' );
+        *              element.remove();
+        *
+        * @param {Boolean} [preserveChildren=false] Indicates that the children
+        * elements must remain in the document, removing only the outer tags.
+        */
+       remove: function( preserveChildren ) {
+               var $ = this.$;
+               var parent = $.parentNode;
+
+               if ( parent ) {
+                       if ( preserveChildren ) {
+                               // Move all children before the node.
+                               for ( var child;
+                               ( child = $.firstChild ); ) {
+                                       parent.insertBefore( $.removeChild( child ), $ );
+                               }
+                       }
+
+                       parent.removeChild( $ );
+               }
+
+               return this;
+       },
+
+       /**
+        * @todo
+        */
+       replace: function( nodeToReplace ) {
+               this.insertBefore( nodeToReplace );
+               nodeToReplace.remove();
+       },
+
+       /**
+        * @todo
+        */
+       trim: function() {
+               this.ltrim();
+               this.rtrim();
+       },
+
+       /**
+        * @todo
+        */
+       ltrim: function() {
+               var child;
+               while ( this.getFirst && ( child = this.getFirst() ) ) {
+                       if ( child.type == CKEDITOR.NODE_TEXT ) {
+                               var trimmed = CKEDITOR.tools.ltrim( child.getText() ),
+                                       originalLength = child.getLength();
+
+                               if ( !trimmed ) {
+                                       child.remove();
+                                       continue;
+                               } else if ( trimmed.length < originalLength ) {
+                                       child.split( originalLength - trimmed.length );
+
+                                       // IE BUG: child.remove() may raise JavaScript errors here. (#81)
+                                       this.$.removeChild( this.$.firstChild );
+                               }
+                       }
+                       break;
+               }
+       },
+
+       /**
+        * @todo
+        */
+       rtrim: function() {
+               var child;
+               while ( this.getLast && ( child = this.getLast() ) ) {
+                       if ( child.type == CKEDITOR.NODE_TEXT ) {
+                               var trimmed = CKEDITOR.tools.rtrim( child.getText() ),
+                                       originalLength = child.getLength();
+
+                               if ( !trimmed ) {
+                                       child.remove();
+                                       continue;
+                               } else if ( trimmed.length < originalLength ) {
+                                       child.split( trimmed.length );
+
+                                       // IE BUG: child.getNext().remove() may raise JavaScript errors here.
+                                       // (#81)
+                                       this.$.lastChild.parentNode.removeChild( this.$.lastChild );
+                               }
+                       }
+                       break;
+               }
+
+               if ( CKEDITOR.env.needsBrFiller ) {
+                       child = this.$.lastChild;
+
+                       if ( child && child.type == 1 && child.nodeName.toLowerCase() == 'br' ) {
+                               // Use "eChildNode.parentNode" instead of "node" to avoid IE bug (#324).
+                               child.parentNode.removeChild( child );
+                       }
+               }
+       },
+
+       /**
+        * Checks if this node is read-only (should not be changed).
+        *
+        *              // For the following HTML:
+        *              // <b>foo</b><div contenteditable="false"><i>bar</i></div>
+        *
+        *              elB.isReadOnly(); // -> false
+        *              foo.isReadOnly(); // -> false
+        *              elDiv.isReadOnly(); // -> true
+        *              elI.isReadOnly(); // -> true
+        *
+        * This method works in two modes depending on browser support for the `element.isContentEditable` property and
+        * the value of the `checkOnlyAttributes` parameter. The `element.isContentEditable` check is faster, but it is known
+        * to malfunction in hidden or detached nodes. Additionally, when processing some detached DOM tree you may want to imitate
+        * that this happens inside an editable container (like it would happen inside the {@link CKEDITOR.editable}). To do so,
+        * you can temporarily attach this tree to an element with the `data-cke-editable` attribute and use the
+        * `checkOnlyAttributes` mode.
+        *
+        * @since 3.5
+        * @param {Boolean} [checkOnlyAttributes=false] If `true`, only attributes will be checked, native methods will not
+        * be used. This parameter needs to be `true` to check hidden or detached elements. Introduced in 4.5.
+        * @returns {Boolean}
+        */
+       isReadOnly: function( checkOnlyAttributes ) {
+               var element = this;
+               if ( this.type != CKEDITOR.NODE_ELEMENT )
+                       element = this.getParent();
+
+               // Prevent Edge crash (#13609, #13919).
+               if ( CKEDITOR.env.edge && element && element.is( 'textarea', 'input' ) ) {
+                       checkOnlyAttributes = true;
+               }
+
+               if ( !checkOnlyAttributes && element && typeof element.$.isContentEditable != 'undefined' ) {
+                       return !( element.$.isContentEditable || element.data( 'cke-editable' ) );
+               }
+               else {
+                       // Degrade for old browsers which don't support "isContentEditable", e.g. FF3
+
+                       while ( element ) {
+                               if ( element.data( 'cke-editable' ) ) {
+                                       return false;
+                               } else if ( element.hasAttribute( 'contenteditable' ) ) {
+                                       return element.getAttribute( 'contenteditable' ) == 'false';
+                               }
+
+                               element = element.getParent();
+                       }
+
+                       // Reached the root of DOM tree, no editable found.
+                       return true;
+               }
+       }
+} );
diff --git a/sources/core/dom/nodelist.js b/sources/core/dom/nodelist.js
new file mode 100644 (file)
index 0000000..165a415
--- /dev/null
@@ -0,0 +1,43 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Represents a list of {@link CKEDITOR.dom.node} objects.
+ * It's a wrapper for native nodes list.
+ *
+ *             var nodeList = CKEDITOR.document.getBody().getChildren();
+ *             alert( nodeList.count() ); // number [0;N]
+ *
+ * @class
+ * @constructor Creates a document class instance.
+ * @param {Object} nativeList
+ */
+CKEDITOR.dom.nodeList = function( nativeList ) {
+       this.$ = nativeList;
+};
+
+CKEDITOR.dom.nodeList.prototype = {
+       /**
+        * Get count of nodes in this list.
+        *
+        * @returns {Number}
+        */
+       count: function() {
+               return this.$.length;
+       },
+
+       /**
+        * Get node from the list.
+        *
+        * @returns {CKEDITOR.dom.node}
+        */
+       getItem: function( index ) {
+               if ( index < 0 || index >= this.$.length )
+                       return null;
+
+               var $node = this.$[ index ];
+               return $node ? new CKEDITOR.dom.node( $node ) : null;
+       }
+};
diff --git a/sources/core/dom/range.js b/sources/core/dom/range.js
new file mode 100644 (file)
index 0000000..6407074
--- /dev/null
@@ -0,0 +1,2978 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Represents a delimited piece of content in a DOM Document.
+ * It is contiguous in the sense that it can be characterized as selecting all
+ * of the content between a pair of boundary-points.
+ *
+ * This class shares much of the W3C
+ * [Document Object Model Range](http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html)
+ * ideas and features, adding several range manipulation tools to it, but it's
+ * not intended to be compatible with it.
+ *
+ *             // Create a range for the entire contents of the editor document body.
+ *             var range = new CKEDITOR.dom.range( editor.document );
+ *             range.selectNodeContents( editor.document.getBody() );
+ *             // Delete the contents.
+ *             range.deleteContents();
+ *
+ * Usually you will want to work on a ranges rooted in the editor's {@link CKEDITOR.editable editable}
+ * element. Such ranges can be created with a shorthand method &ndash; {@link CKEDITOR.editor#createRange editor.createRange}.
+ *
+ *             var range = editor.createRange();
+ *             range.root.equals( editor.editable() ); // -> true
+ *
+ * Note that the {@link #root} of a range is an important property, which limits many
+ * algorithms implemented in range's methods. Therefore it is crucial, especially
+ * when using ranges inside inline editors, to specify correct root, so using
+ * the {@link CKEDITOR.editor#createRange} method is highly recommended.
+ *
+ * ### Selection
+ *
+ * Range is only a logical representation of a piece of content in a DOM. It should not
+ * be confused with a {@link CKEDITOR.dom.selection selection} which represents "physically
+ * marked" content. It is possible to create unlimited number of various ranges, when
+ * only one real selection may exist at a time in a document. Ranges are used to read position
+ * of selection in the DOM and to move selection to new positions.
+ *
+ * The editor selection may be retrieved using the {@link CKEDITOR.editor#getSelection} method:
+ *
+ *             var sel = editor.getSelection(),
+ *                     ranges = sel.getRanges(); // CKEDITOR.dom.rangeList instance.
+ *
+ *             var range = ranges[ 0 ];
+ *             range.root; // -> editor's editable element.
+ *
+ * A range can also be selected:
+ *
+ *             var range = editor.createRange();
+ *             range.selectNodeContents( editor.editable() );
+ *             sel.selectRanges( [ range ] );
+ *
+ * @class
+ * @constructor Creates a {@link CKEDITOR.dom.range} instance that can be used inside a specific DOM Document.
+ * @param {CKEDITOR.dom.document/CKEDITOR.dom.element} root The document or element
+ * within which the range will be scoped.
+ * @todo global "TODO" - precise algorithms descriptions needed for the most complex methods like #enlarge.
+ */
+CKEDITOR.dom.range = function( root ) {
+       /**
+        * Node within which the range begins.
+        *
+        *              var range = new CKEDITOR.dom.range( editor.document );
+        *              range.selectNodeContents( editor.document.getBody() );
+        *              alert( range.startContainer.getName() ); // 'body'
+        *
+        * @readonly
+        * @property {CKEDITOR.dom.element/CKEDITOR.dom.text}
+        */
+       this.startContainer = null;
+
+       /**
+        * Offset within the starting node of the range.
+        *
+        *              var range = new CKEDITOR.dom.range( editor.document );
+        *              range.selectNodeContents( editor.document.getBody() );
+        *              alert( range.startOffset ); // 0
+        *
+        * @readonly
+        * @property {Number}
+        */
+       this.startOffset = null;
+
+       /**
+        * Node within which the range ends.
+        *
+        *              var range = new CKEDITOR.dom.range( editor.document );
+        *              range.selectNodeContents( editor.document.getBody() );
+        *              alert( range.endContainer.getName() ); // 'body'
+        *
+        * @readonly
+        * @property {CKEDITOR.dom.element/CKEDITOR.dom.text}
+        */
+       this.endContainer = null;
+
+       /**
+        * Offset within the ending node of the range.
+        *
+        *              var range = new CKEDITOR.dom.range( editor.document );
+        *              range.selectNodeContents( editor.document.getBody() );
+        *              alert( range.endOffset ); // == editor.document.getBody().getChildCount()
+        *
+        * @readonly
+        * @property {Number}
+        */
+       this.endOffset = null;
+
+       /**
+        * Indicates that this is a collapsed range. A collapsed range has its
+        * start and end boundaries at the very same point so nothing is contained
+        * in it.
+        *
+        *              var range = new CKEDITOR.dom.range( editor.document );
+        *              range.selectNodeContents( editor.document.getBody() );
+        *              alert( range.collapsed ); // false
+        *              range.collapse();
+        *              alert( range.collapsed ); // true
+        *
+        * @readonly
+        */
+       this.collapsed = true;
+
+       var isDocRoot = root instanceof CKEDITOR.dom.document;
+       /**
+        * The document within which the range can be used.
+        *
+        *              // Selects the body contents of the range document.
+        *              range.selectNodeContents( range.document.getBody() );
+        *
+        * @readonly
+        * @property {CKEDITOR.dom.document}
+        */
+       this.document = isDocRoot ? root : root.getDocument();
+
+       /**
+        * The ancestor DOM element within which the range manipulation are limited.
+        *
+        * @readonly
+        * @property {CKEDITOR.dom.element}
+        */
+       this.root = isDocRoot ? root.getBody() : root;
+};
+
+( function() {
+       // Updates the "collapsed" property for the given range object.
+       function updateCollapsed( range ) {
+               range.collapsed = ( range.startContainer && range.endContainer && range.startContainer.equals( range.endContainer ) && range.startOffset == range.endOffset );
+       }
+
+       // This is a shared function used to delete, extract and clone the range content.
+       //
+       // The outline of the algorithm:
+       //
+       // 1. Normalization. We handle special cases, split text nodes if we can, find boundary nodes (startNode and endNode).
+       // 2. Gathering data.
+       //   * We start by creating two arrays of boundary nodes parents. You can imagine these arrays as lines limiting
+       //   the tree from the left and right and thus marking the part which is selected by the range. The both lines
+       //   start in the same node which is the range.root and end in startNode and endNode.
+       //   * Then we find min level and max levels. Level represents all nodes which are equally far from the range.root.
+       //   Min level is the level at which the left and right boundaries diverged (the first diverged level). And max levels
+       //   are how deep the start and end nodes are nested.
+       // 3. Cloning/extraction.
+       //   * We start iterating over start node parents (left branch) from min level and clone the parent (usually shallow clone,
+       //   because we know that it's not fully selected) and its right siblings (deep clone, because they are fully selected).
+       //   We iterate over siblings up to meeting end node parent or end of the siblings chain.
+       //   * We clone level after level down to the startNode.
+       //   * Then we do the same with end node parents (right branch), because it may contains notes we omit during the previous
+       //   step, for example if the right branch is deeper then left branch. Things are more complicated here because we have to
+       //   watch out for nodes that were already cloned.
+       //   * ***Note:** Setting `cloneId` option to `false` for **extraction** works for partially selected elements only.
+       //   See range.extractContents to know more.
+       // 4. Clean up.
+       //   * There are two things we need to do - updating the range position and perform the action of the "mergeThen"
+       //   param (see range.deleteContents or range.extractContents).
+       //   See comments in mergeAndUpdate because this is lots of fun too.
+       function execContentsAction( range, action, docFrag, mergeThen, cloneId ) {
+               'use strict';
+
+               range.optimizeBookmark();
+
+               var isDelete = action === 0;
+               var isExtract = action == 1;
+               var isClone = action == 2;
+               var doClone = isClone || isExtract;
+
+               var startNode = range.startContainer;
+               var endNode = range.endContainer;
+
+               var startOffset = range.startOffset;
+               var endOffset = range.endOffset;
+
+               var cloneStartNode;
+               var cloneEndNode;
+
+               var doNotRemoveStartNode;
+               var doNotRemoveEndNode;
+
+               var cloneStartText;
+               var cloneEndText;
+
+               // Handle here an edge case where we clone a range which is located in one text node.
+               // This allows us to not think about startNode == endNode case later on.
+               // We do that only when cloning, because in other cases we can safely split this text node
+               // and hence we can easily handle this case as many others.
+               if ( isClone && endNode.type == CKEDITOR.NODE_TEXT && startNode.equals( endNode ) ) {
+                       startNode = range.document.createText( startNode.substring( startOffset, endOffset ) );
+                       docFrag.append( startNode );
+                       return;
+               }
+
+               // For text containers, we must simply split the node and point to the
+               // second part. The removal will be handled by the rest of the code.
+               if ( endNode.type == CKEDITOR.NODE_TEXT ) {
+                       // If Extract or Delete we can split the text node,
+                       // but if Clone (2), then we cannot modify the DOM (#11586) so we mark the text node for cloning.
+                       if ( !isClone ) {
+                               endNode = endNode.split( endOffset );
+                       } else {
+                               cloneEndText = true;
+                       }
+               } else {
+                       // If there's no node after the range boundary we set endNode to the previous node
+                       // and mark it to be cloned.
+                       if ( endNode.getChildCount() > 0 ) {
+                               // If the offset points after the last node.
+                               if ( endOffset >= endNode.getChildCount() ) {
+                                       endNode = endNode.getChild( endOffset - 1 );
+                                       cloneEndNode = true;
+                               } else {
+                                       endNode = endNode.getChild( endOffset );
+                               }
+                       }
+                       // The end container is empty (<h1>]</h1>), but we want to clone it, although not remove.
+                       else {
+                               cloneEndNode = true;
+                               doNotRemoveEndNode = true;
+                       }
+               }
+
+               // For text containers, we must simply split the node. The removal will
+               // be handled by the rest of the code .
+               if ( startNode.type == CKEDITOR.NODE_TEXT ) {
+                       // If Extract or Delete we can split the text node,
+                       // but if Clone (2), then we cannot modify the DOM (#11586) so we mark
+                       // the text node for cloning.
+                       if ( !isClone ) {
+                               startNode.split( startOffset );
+                       } else {
+                               cloneStartText = true;
+                       }
+               } else {
+                       // If there's no node before the range boundary we set startNode to the next node
+                       // and mark it to be cloned.
+                       if ( startNode.getChildCount() > 0 ) {
+                               if ( startOffset === 0 ) {
+                                       startNode = startNode.getChild( startOffset );
+                                       cloneStartNode = true;
+                               } else {
+                                       startNode = startNode.getChild( startOffset - 1 );
+                               }
+                       }
+                       // The start container is empty (<h1>[</h1>), but we want to clone it, although not remove.
+                       else {
+                               cloneStartNode = true;
+                               doNotRemoveStartNode = true;
+                       }
+               }
+
+                       // Get the parent nodes tree for the start and end boundaries.
+               var startParents = startNode.getParents(),
+                       endParents = endNode.getParents(),
+                       // Level at which start and end boundaries diverged.
+                       minLevel = findMinLevel(),
+                       maxLevelLeft = startParents.length - 1,
+                       maxLevelRight = endParents.length - 1,
+                       // Keeps the frag/element which is parent of the level that we are currently cloning.
+                       levelParent = docFrag,
+                       nextLevelParent,
+                       leftNode,
+                       rightNode,
+                       nextSibling,
+                       // Keeps track of the last connected level (on which left and right branches are connected)
+                       // Usually this is minLevel, but not always.
+                       lastConnectedLevel = -1;
+
+               // THE LEFT BRANCH.
+               for ( var level = minLevel; level <= maxLevelLeft; level++ ) {
+                       leftNode = startParents[ level ];
+                       nextSibling = leftNode.getNext();
+
+                       // 1.
+                       // The first step is to handle partial selection of the left branch.
+
+                       // Max depth of the left branch. It means that ( leftSibling == endNode ).
+                       // We also check if the leftNode isn't only partially selected, because in this case
+                       // we want to make a shallow clone of it (the else part).
+                       if ( level == maxLevelLeft && !( leftNode.equals( endParents[ level ] ) && maxLevelLeft < maxLevelRight ) ) {
+                               if ( cloneStartNode ) {
+                                       consume( leftNode, levelParent, false, doNotRemoveStartNode );
+                               } else if ( cloneStartText ) {
+                                       levelParent.append( range.document.createText( leftNode.substring( startOffset ) ) );
+                               }
+                       } else if ( doClone ) {
+                               nextLevelParent = levelParent.append( leftNode.clone( 0, cloneId ) );
+                       }
+
+                       // 2.
+                       // The second step is to handle full selection of the content between the left branch and the right branch.
+
+                       while ( nextSibling ) {
+                               // We can't clone entire endParent just like we can't clone entire startParent -
+                               // - they are not fully selected with the range. Partial endParent selection
+                               // will be cloned in the next loop.
+                               if ( nextSibling.equals( endParents[ level ] ) ) {
+                                       lastConnectedLevel = level;
+                                       break;
+                               }
+
+                               nextSibling = consume( nextSibling, levelParent );
+                       }
+
+                       levelParent = nextLevelParent;
+               }
+
+               // Reset levelParent, because we reset the level.
+               levelParent = docFrag;
+
+               // THE RIGHT BRANCH.
+               for ( level = minLevel; level <= maxLevelRight; level++ ) {
+                       rightNode = endParents[ level ];
+                       nextSibling = rightNode.getPrevious();
+
+                       // Do not process this node if it is shared with the left branch
+                       // because it was already processed.
+                       //
+                       // Note: Don't worry about text nodes selection - if the entire range was placed in a single text node
+                       // it was handled as a special case at the beginning. In other cases when startNode == endNode
+                       // or when on this level leftNode == rightNode (so rightNode.equals( startParents[ level ] ))
+                       // this node was handled by the previous loop.
+                       if ( !rightNode.equals( startParents[ level ] ) ) {
+                               // 1.
+                               // The first step is to handle partial selection of the right branch.
+
+                               // Max depth of the right branch. It means that ( rightNode == endNode ).
+                               // We also check if the rightNode isn't only partially selected, because in this case
+                               // we want to make a shallow clone of it (the else part).
+                               if ( level == maxLevelRight && !( rightNode.equals( startParents[ level ] ) && maxLevelRight < maxLevelLeft ) ) {
+                                       if ( cloneEndNode ) {
+                                               consume( rightNode, levelParent, false, doNotRemoveEndNode );
+                                       } else if ( cloneEndText ) {
+                                               levelParent.append( range.document.createText( rightNode.substring( 0, endOffset ) ) );
+                                       }
+                               } else if ( doClone ) {
+                                       nextLevelParent = levelParent.append( rightNode.clone( 0, cloneId ) );
+                               }
+
+                               // 2.
+                               // The second step is to handle all left (selected) siblings of the rightNode which
+                               // have not yet been handled. If the level branches were connected, the previous loop
+                               // already copied all siblings (except the current rightNode).
+                               if ( level > lastConnectedLevel ) {
+                                       while ( nextSibling ) {
+                                               nextSibling = consume( nextSibling, levelParent, true );
+                                       }
+                               }
+
+                               levelParent = nextLevelParent;
+                       } else if ( doClone ) {
+                               // If this is "shared" node and we are in cloning mode we have to update levelParent to
+                               // reflect that we visited the node (even though we didn't process it).
+                               // If we don't do that, in next iterations nodes will be appended to wrong parent.
+                               //
+                               // We can just take first child because the algorithm guarantees
+                               // that this will be the only child on this level. (#13568)
+                               levelParent = levelParent.getChild( 0 );
+                       }
+               }
+
+               // Delete or Extract.
+               // We need to update the range and if mergeThen was passed do it.
+               if ( !isClone ) {
+                       mergeAndUpdate();
+               }
+
+               // Depending on an action:
+               // * clones node and adds to new parent,
+               // * removes node,
+               // * moves node to the new parent.
+               function consume( node, newParent, toStart, forceClone ) {
+                       var nextSibling = toStart ? node.getPrevious() : node.getNext();
+
+                       // We do not clone if we are only deleting, so do nothing.
+                       if ( forceClone && isDelete ) {
+                               return nextSibling;
+                       }
+
+                       // If cloning, just clone it.
+                       if ( isClone || forceClone ) {
+                               newParent.append( node.clone( true, cloneId ), toStart );
+                       } else {
+                               // Both Delete and Extract will remove the node.
+                               node.remove();
+
+                               // When Extracting, move the removed node to the docFrag.
+                               if ( isExtract ) {
+                                       newParent.append( node );
+                               }
+                       }
+
+                       return nextSibling;
+               }
+
+               // Finds a level number on which both branches starts diverging.
+               // If such level does not exist, return the last on which both branches have nodes.
+               function findMinLevel() {
+                       // Compare them, to find the top most siblings.
+                       var i, topStart, topEnd,
+                               maxLevel = Math.min( startParents.length, endParents.length );
+
+                       for ( i = 0; i < maxLevel; i++ ) {
+                               topStart = startParents[ i ];
+                               topEnd = endParents[ i ];
+
+                               // The compared nodes will match until we find the top most siblings (different nodes that have the same parent).
+                               // "i" will hold the index in the parents array for the top most element.
+                               if ( !topStart.equals( topEnd ) ) {
+                                       return i;
+                               }
+                       }
+
+                       // When startNode == endNode.
+                       return i - 1;
+               }
+
+               // Executed only when deleting or extracting to update range position
+               // and perform the merge operation.
+               function mergeAndUpdate() {
+                       var commonLevel = minLevel - 1,
+                               boundariesInEmptyNode = doNotRemoveStartNode && doNotRemoveEndNode && !startNode.equals( endNode );
+
+                       // If a node has been partially selected, collapse the range between
+                       // startParents[ minLevel + 1 ] and endParents[ minLevel + 1 ] (the first diverged elements).
+                       // Otherwise, simply collapse it to the start. (W3C specs).
+                       //
+                       // All clear, right?
+                       //
+                       // It took me few hours to truly understand a previous version of this condition.
+                       // Mine seems to be more straightforward (even if it doesn't look so) and I could leave you here
+                       // without additional comments, but I'm not that mean so here goes the explanation.
+                       //
+                       // We want to know if both ends of the range are anchored in the same element. Really. It's this simple.
+                       // But why? Because we need to differentiate situations like:
+                       //
+                       // <p>foo[<b>x</b>bar]y</p>             (commonLevel = p, maxLL = "foo", maxLR = "y")
+                       // from:
+                       // <p>foo<b>x[</b>bar]y</p>             (commonLevel = p, maxLL = "x", maxLR = "y")
+                       //
+                       // In the first case we can collapse the range to the left, because simply everything between range's
+                       // boundaries was removed.
+                       // In the second case we must place the range after </b>, because <b> was only **partially selected**.
+                       //
+                       // * <b> is our startParents[ commonLevel + 1 ]
+                       // * "y" is our endParents[ commonLevel + 1 ].
+                       //
+                       // By now "bar" is removed from the DOM so <b> is a direct sibling of "y":
+                       // <p>foo<b>x</b>y</p>
+                       //
+                       // Therefore it's enough to place the range between <b> and "y".
+                       //
+                       // Now, what does the comparison mean? Why not just taking startNode and endNode and checking
+                       // their parents? Because the tree is already changed and they may be gone. Plus, thanks to
+                       // cloneStartNode and cloneEndNode, that would be reaaaaly tricky.
+                       //
+                       // So we play with levels which can give us the same information:
+                       // * commonLevel - the level of common ancestor,
+                       // * maxLevel - 1 - the level of range boundary parent (range boundary is here like a bookmark span).
+                       // * commonLevel < maxLevel - 1 - whether the range boundary is not a child of common ancestor.
+                       //
+                       // There's also an edge case in which both range boundaries were placed in empty nodes like:
+                       // <p>[</p><p>]</p>
+                       // Those boundaries were not removed, but in this case start and end nodes are child of the common ancestor.
+                       // We handle this edge case separately.
+                       if ( commonLevel < ( maxLevelLeft - 1 ) || commonLevel < ( maxLevelRight - 1 ) || boundariesInEmptyNode ) {
+                               if ( boundariesInEmptyNode ) {
+                                       range.moveToPosition( endNode, CKEDITOR.POSITION_BEFORE_START );
+                               } else if ( ( maxLevelRight == commonLevel + 1 ) && cloneEndNode ) {
+                                       // The maxLevelRight + 1 element could be already removed so we use the fact that
+                                       // we know that it was the last element in its parent.
+                                       range.moveToPosition( endParents[ commonLevel ], CKEDITOR.POSITION_BEFORE_END );
+                               } else {
+                                       range.moveToPosition( endParents[ commonLevel + 1 ], CKEDITOR.POSITION_BEFORE_START );
+                               }
+
+                               // Merge split parents.
+                               if ( mergeThen ) {
+                                       // Find the first diverged node in the left branch.
+                                       var topLeft = startParents[ commonLevel + 1 ];
+
+                                       // TopLeft may simply not exist if commonLevel == maxLevel or may be a text node.
+                                       if ( topLeft && topLeft.type == CKEDITOR.NODE_ELEMENT ) {
+                                               var span = CKEDITOR.dom.element.createFromHtml( '<span ' +
+                                                       'data-cke-bookmark="1" style="display:none">&nbsp;</span>', range.document );
+                                               span.insertAfter( topLeft );
+                                               topLeft.mergeSiblings( false );
+                                               range.moveToBookmark( { startNode: span } );
+                                       }
+                               }
+                       } else {
+                               // Collapse it to the start.
+                               range.collapse( true );
+                       }
+               }
+       }
+
+       var inlineChildReqElements = {
+               abbr: 1, acronym: 1, b: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1,
+               dfn: 1, em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, q: 1, samp: 1, small: 1, span: 1, strike: 1,
+               strong: 1, sub: 1, sup: 1, tt: 1, u: 1, 'var': 1
+       };
+
+       // Creates the appropriate node evaluator for the dom walker used inside
+       // check(Start|End)OfBlock.
+       function getCheckStartEndBlockEvalFunction() {
+               var skipBogus = false,
+                       whitespaces = CKEDITOR.dom.walker.whitespaces(),
+                       bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true ),
+                       isBogus = CKEDITOR.dom.walker.bogus();
+
+               return function( node ) {
+                       // First skip empty nodes
+                       if ( bookmarkEvaluator( node ) || whitespaces( node ) )
+                               return true;
+
+                       // Skip the bogus node at the end of block.
+                       if ( isBogus( node ) && !skipBogus ) {
+                               skipBogus = true;
+                               return true;
+                       }
+
+                       // If there's any visible text, then we're not at the start.
+                       if ( node.type == CKEDITOR.NODE_TEXT &&
+                               ( node.hasAscendant( 'pre' ) ||
+                                       CKEDITOR.tools.trim( node.getText() ).length ) ) {
+                               return false;
+                       }
+
+                       // If there are non-empty inline elements (e.g. <img />), then we're not
+                       // at the start.
+                       if ( node.type == CKEDITOR.NODE_ELEMENT && !node.is( inlineChildReqElements ) )
+                               return false;
+
+                       return true;
+               };
+       }
+
+       var isBogus = CKEDITOR.dom.walker.bogus(),
+               nbspRegExp = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/,
+               editableEval = CKEDITOR.dom.walker.editable(),
+               notIgnoredEval = CKEDITOR.dom.walker.ignored( true );
+
+       // Evaluator for CKEDITOR.dom.element::checkBoundaryOfElement, reject any
+       // text node and non-empty elements unless it's being bookmark text.
+       function elementBoundaryEval( checkStart ) {
+               var whitespaces = CKEDITOR.dom.walker.whitespaces(),
+                       bookmark = CKEDITOR.dom.walker.bookmark( 1 );
+
+               return function( node ) {
+                       // First skip empty nodes.
+                       if ( bookmark( node ) || whitespaces( node ) )
+                               return true;
+
+                       // Tolerant bogus br when checking at the end of block.
+                       // Reject any text node unless it's being bookmark
+                       // OR it's spaces.
+                       // Reject any element unless it's being invisible empty. (#3883)
+                       return !checkStart && isBogus( node ) ||
+                               node.type == CKEDITOR.NODE_ELEMENT &&
+                               node.is( CKEDITOR.dtd.$removeEmpty );
+               };
+       }
+
+       function getNextEditableNode( isPrevious ) {
+               return function() {
+                       var first;
+
+                       return this[ isPrevious ? 'getPreviousNode' : 'getNextNode' ]( function( node ) {
+                               // Cache first not ignorable node.
+                               if ( !first && notIgnoredEval( node ) )
+                                       first = node;
+
+                               // Return true if found editable node, but not a bogus next to start of our lookup (first != bogus).
+                               return editableEval( node ) && !( isBogus( node ) && node.equals( first ) );
+                       } );
+               };
+       }
+
+       CKEDITOR.dom.range.prototype = {
+               /**
+                * Clones this range.
+                *
+                * @returns {CKEDITOR.dom.range}
+                */
+               clone: function() {
+                       var clone = new CKEDITOR.dom.range( this.root );
+
+                       clone._setStartContainer( this.startContainer );
+                       clone.startOffset = this.startOffset;
+                       clone._setEndContainer( this.endContainer );
+                       clone.endOffset = this.endOffset;
+                       clone.collapsed = this.collapsed;
+
+                       return clone;
+               },
+
+               /**
+                * Makes the range collapsed by moving its start point (or end point if `toStart==true`)
+                * to the second end.
+                *
+                * @param {Boolean} toStart Collapse range "to start".
+                */
+               collapse: function( toStart ) {
+                       if ( toStart ) {
+                               this._setEndContainer( this.startContainer );
+                               this.endOffset = this.startOffset;
+                       } else {
+                               this._setStartContainer( this.endContainer );
+                               this.startOffset = this.endOffset;
+                       }
+
+                       this.collapsed = true;
+               },
+
+               /**
+                * Clones content nodes of the range and adds them to a document fragment, which is returned.
+                *
+                * @param {Boolean} [cloneId=true] Whether to preserve ID attributes in the clone.
+                * @returns {CKEDITOR.dom.documentFragment} Document fragment containing a clone of range's content.
+                */
+               cloneContents: function( cloneId ) {
+                       var docFrag = new CKEDITOR.dom.documentFragment( this.document );
+
+                       cloneId = typeof cloneId == 'undefined' ? true : cloneId;
+
+                       if ( !this.collapsed )
+                               execContentsAction( this, 2, docFrag, false, cloneId );
+
+                       return docFrag;
+               },
+
+               /**
+                * Deletes the content nodes of the range permanently from the DOM tree.
+                *
+                * @param {Boolean} [mergeThen] Merge any split elements result in DOM true due to partial selection.
+                */
+               deleteContents: function( mergeThen ) {
+                       if ( this.collapsed )
+                               return;
+
+                       execContentsAction( this, 0, null, mergeThen );
+               },
+
+               /**
+                * The content nodes of the range are cloned and added to a document fragment,
+                * meanwhile they are removed permanently from the DOM tree.
+                *
+                * **Note:** Setting the `cloneId` parameter to `false` works for **partially** selected elements only.
+                * If an element with an ID attribute is **fully enclosed** in a range, it will keep the ID attribute
+                * regardless of the `cloneId` parameter value, because it is not cloned &mdash; it is moved to the returned
+                * document fragment.
+                *
+                * @param {Boolean} [mergeThen] Merge any split elements result in DOM true due to partial selection.
+                * @param {Boolean} [cloneId=true] Whether to preserve ID attributes in the extracted content.
+                * @returns {CKEDITOR.dom.documentFragment} Document fragment containing extracted content.
+                */
+               extractContents: function( mergeThen, cloneId ) {
+                       var docFrag = new CKEDITOR.dom.documentFragment( this.document );
+
+                       cloneId = typeof cloneId == 'undefined' ? true : cloneId;
+
+                       if ( !this.collapsed )
+                               execContentsAction( this, 1, docFrag, mergeThen, cloneId );
+
+                       return docFrag;
+               },
+
+               /**
+                * Creates a bookmark object, which can be later used to restore the
+                * range by using the {@link #moveToBookmark} function.
+                *
+                * This is an "intrusive" way to create a bookmark. It includes `<span>` tags
+                * in the range boundaries. The advantage of it is that it is possible to
+                * handle DOM mutations when moving back to the bookmark.
+                *
+                * **Note:** The inclusion of nodes in the DOM is a design choice and
+                * should not be changed as there are other points in the code that may be
+                * using those nodes to perform operations.
+                *
+                * @param {Boolean} [serializable] Indicates that the bookmark nodes
+                * must contain IDs, which can be used to restore the range even
+                * when these nodes suffer mutations (like cloning or `innerHTML` change).
+                * @returns {Object} And object representing a bookmark.
+                * @returns {CKEDITOR.dom.node/String} return.startNode Node or element ID.
+                * @returns {CKEDITOR.dom.node/String} return.endNode Node or element ID.
+                * @returns {Boolean} return.serializable
+                * @returns {Boolean} return.collapsed
+                */
+               createBookmark: function( serializable ) {
+                       var startNode, endNode;
+                       var baseId;
+                       var clone;
+                       var collapsed = this.collapsed;
+
+                       startNode = this.document.createElement( 'span' );
+                       startNode.data( 'cke-bookmark', 1 );
+                       startNode.setStyle( 'display', 'none' );
+
+                       // For IE, it must have something inside, otherwise it may be
+                       // removed during DOM operations.
+                       startNode.setHtml( '&nbsp;' );
+
+                       if ( serializable ) {
+                               baseId = 'cke_bm_' + CKEDITOR.tools.getNextNumber();
+                               startNode.setAttribute( 'id', baseId + ( collapsed ? 'C' : 'S' ) );
+                       }
+
+                       // If collapsed, the endNode will not be created.
+                       if ( !collapsed ) {
+                               endNode = startNode.clone();
+                               endNode.setHtml( '&nbsp;' );
+
+                               if ( serializable )
+                                       endNode.setAttribute( 'id', baseId + 'E' );
+
+                               clone = this.clone();
+                               clone.collapse();
+                               clone.insertNode( endNode );
+                       }
+
+                       clone = this.clone();
+                       clone.collapse( true );
+                       clone.insertNode( startNode );
+
+                       // Update the range position.
+                       if ( endNode ) {
+                               this.setStartAfter( startNode );
+                               this.setEndBefore( endNode );
+                       } else {
+                               this.moveToPosition( startNode, CKEDITOR.POSITION_AFTER_END );
+                       }
+
+                       return {
+                               startNode: serializable ? baseId + ( collapsed ? 'C' : 'S' ) : startNode,
+                               endNode: serializable ? baseId + 'E' : endNode,
+                               serializable: serializable,
+                               collapsed: collapsed
+                       };
+               },
+
+               /**
+                * Creates a "non intrusive" and "mutation sensible" bookmark. This
+                * kind of bookmark should be used only when the DOM is supposed to
+                * remain stable after its creation.
+                *
+                * @param {Boolean} [normalized] Indicates that the bookmark must
+                * be normalized. When normalized, the successive text nodes are
+                * considered a single node. To successfully load a normalized
+                * bookmark, the DOM tree must also be normalized before calling
+                * {@link #moveToBookmark}.
+                * @returns {Object} An object representing the bookmark.
+                * @returns {Array} return.start Start container's address (see {@link CKEDITOR.dom.node#getAddress}).
+                * @returns {Array} return.end Start container's address.
+                * @returns {Number} return.startOffset
+                * @returns {Number} return.endOffset
+                * @returns {Boolean} return.collapsed
+                * @returns {Boolean} return.normalized
+                * @returns {Boolean} return.is2 This is "bookmark2".
+                */
+               createBookmark2: ( function() {
+                       var isNotText = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_TEXT, true );
+
+                       // Returns true for limit anchored in element and placed between text nodes.
+                       //
+                       //               v
+                       // <p>[text node] [text node]</p> -> true
+                       //
+                       //    v
+                       // <p> [text node]</p> -> false
+                       //
+                       //              v
+                       // <p>[text node][text node]</p> -> false (limit is anchored in text node)
+                       function betweenTextNodes( container, offset ) {
+                               // Not anchored in element or limit is on the edge.
+                               if ( container.type != CKEDITOR.NODE_ELEMENT || offset === 0 || offset == container.getChildCount() )
+                                       return 0;
+
+                               return container.getChild( offset - 1 ).type == CKEDITOR.NODE_TEXT &&
+                                       container.getChild( offset ).type == CKEDITOR.NODE_TEXT;
+                       }
+
+                       // Sums lengths of all preceding text nodes.
+                       function getLengthOfPrecedingTextNodes( node ) {
+                               var sum = 0;
+
+                               while ( ( node = node.getPrevious() ) && node.type == CKEDITOR.NODE_TEXT )
+                                       sum += node.getText().replace( CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE, '' ).length;
+
+                               return sum;
+                       }
+
+                       function normalizeTextNodes( limit ) {
+                               var container = limit.container,
+                                       offset = limit.offset;
+
+                               // If limit is between text nodes move it to the end of preceding one,
+                               // because they will be merged.
+                               if ( betweenTextNodes( container, offset ) ) {
+                                       container = container.getChild( offset - 1 );
+                                       offset = container.getLength();
+                               }
+
+                               // Now, if limit is anchored in element and has at least one node before it,
+                               // it may happen that some of them will be merged. Normalize the offset
+                               // by setting it to normalized index of its preceding, safe node.
+                               // (safe == one for which getIndex(true) does not return -1, so one which won't disappear).
+                               if ( container.type == CKEDITOR.NODE_ELEMENT && offset > 0 ) {
+                                       offset = getPrecedingSafeNodeIndex( container, offset ) + 1;
+                               }
+
+                               // The last step - fix the offset inside text node by adding
+                               // lengths of preceding text nodes which will be merged with container.
+                               if ( container.type == CKEDITOR.NODE_TEXT ) {
+                                       var precedingLength = getLengthOfPrecedingTextNodes( container );
+
+                                       // Normal case - text node is not empty.
+                                       if ( container.getText() ) {
+                                               offset += precedingLength;
+
+                                       // Awful case - the text node is empty and thus will be totally lost.
+                                       // In this case we are trying to normalize the limit to the left:
+                                       // * either to the preceding text node,
+                                       // * or to the "gap" after the preceding element.
+                                       } else {
+                                               // Find the closest non-text sibling.
+                                               var precedingContainer = container.getPrevious( isNotText );
+
+                                               // If there are any characters on the left, that means that we can anchor
+                                               // there, because this text node will not be lost.
+                                               if ( precedingLength ) {
+                                                       offset = precedingLength;
+
+                                                       if ( precedingContainer ) {
+                                                               // The text node is the first node after the closest non-text sibling.
+                                                               container = precedingContainer.getNext();
+                                                       } else {
+                                                               // But if there was no non-text sibling, then the text node is the first child.
+                                                               container = container.getParent().getFirst();
+                                                       }
+
+                                               // If there are no characters on the left, then anchor after the previous non-text node.
+                                               // E.g. (see tests for a legend :D):
+                                               // <b>x</b>(foo)({}bar) -> <b>x</b>[](foo)(bar)
+                                               } else {
+                                                       container = container.getParent();
+                                                       offset = precedingContainer ? ( precedingContainer.getIndex( true ) + 1 ) : 0;
+                                               }
+                                       }
+                               }
+
+                               limit.container = container;
+                               limit.offset = offset;
+                       }
+
+                       function normalizeFCSeq( limit, root ) {
+                               var fcseq = root.getCustomData( 'cke-fillingChar' );
+
+                               if ( !fcseq ) {
+                                       return;
+                               }
+
+                               var container = limit.container;
+
+                               if ( fcseq.equals( container ) ) {
+                                       limit.offset -= CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE.length;
+
+                                       // == 0         handles case when limit was at the end of FCS.
+                                       //  < 0         handles all cases where limit was somewhere in the middle or at the beginning.
+                                       //  > 0         (the "else" case) means cases where there are some more characters in the FCS node (FCSabc^def).
+                                       if ( limit.offset <= 0 ) {
+                                               limit.offset = container.getIndex();
+                                               limit.container = container.getParent();
+                                       }
+                                       return;
+                               }
+
+                               // And here goes the funny part - all other cases are handled inside node.getAddress() and getIndex() thanks to
+                               // node.getIndex() being aware of FCS (handling it as an empty node).
+                       }
+
+                       // Finds a normalized index of a safe node preceding this one.
+                       // Safe == one that will not disappear, so one for which getIndex( true ) does not return -1.
+                       // Return -1 if there's no safe preceding node.
+                       function getPrecedingSafeNodeIndex( container, offset ) {
+                               var index;
+
+                               while ( offset-- ) {
+                                       index = container.getChild( offset ).getIndex( true );
+
+                                       if ( index >= 0 )
+                                               return index;
+                               }
+
+                               return -1;
+                       }
+
+                       return function( normalized ) {
+                               var collapsed = this.collapsed,
+                                       bmStart = {
+                                               container: this.startContainer,
+                                               offset: this.startOffset
+                                       },
+                                       bmEnd = {
+                                               container: this.endContainer,
+                                               offset: this.endOffset
+                                       };
+
+                               if ( normalized ) {
+                                       normalizeTextNodes( bmStart );
+                                       normalizeFCSeq( bmStart, this.root );
+
+                                       if ( !collapsed ) {
+                                               normalizeTextNodes( bmEnd );
+                                               normalizeFCSeq( bmEnd, this.root );
+                                       }
+                               }
+
+                               return {
+                                       start: bmStart.container.getAddress( normalized ),
+                                       end: collapsed ? null : bmEnd.container.getAddress( normalized ),
+                                       startOffset: bmStart.offset,
+                                       endOffset: bmEnd.offset,
+                                       normalized: normalized,
+                                       collapsed: collapsed,
+                                       is2: true // It's a createBookmark2 bookmark.
+                               };
+                       };
+               } )(),
+
+               /**
+                * Moves this range to the given bookmark. See {@link #createBookmark} and {@link #createBookmark2}.
+                *
+                * If serializable bookmark passed, then its `<span>` markers will be removed.
+                *
+                * @param {Object} bookmark
+                */
+               moveToBookmark: function( bookmark ) {
+                       // Created with createBookmark2().
+                       if ( bookmark.is2 ) {
+                               // Get the start information.
+                               var startContainer = this.document.getByAddress( bookmark.start, bookmark.normalized ),
+                                       startOffset = bookmark.startOffset;
+
+                               // Get the end information.
+                               var endContainer = bookmark.end && this.document.getByAddress( bookmark.end, bookmark.normalized ),
+                                       endOffset = bookmark.endOffset;
+
+                               // Set the start boundary.
+                               this.setStart( startContainer, startOffset );
+
+                               // Set the end boundary. If not available, collapse it.
+                               if ( endContainer )
+                                       this.setEnd( endContainer, endOffset );
+                               else
+                                       this.collapse( true );
+                       }
+                       // Created with createBookmark().
+                       else {
+                               var serializable = bookmark.serializable,
+                                       startNode = serializable ? this.document.getById( bookmark.startNode ) : bookmark.startNode,
+                                       endNode = serializable ? this.document.getById( bookmark.endNode ) : bookmark.endNode;
+
+                               // Set the range start at the bookmark start node position.
+                               this.setStartBefore( startNode );
+
+                               // Remove it, because it may interfere in the setEndBefore call.
+                               startNode.remove();
+
+                               // Set the range end at the bookmark end node position, or simply
+                               // collapse it if it is not available.
+                               if ( endNode ) {
+                                       this.setEndBefore( endNode );
+                                       endNode.remove();
+                               } else {
+                                       this.collapse( true );
+                               }
+                       }
+               },
+
+               /**
+                * Returns two nodes which are on the boundaries of this range.
+                *
+                * @returns {Object}
+                * @returns {CKEDITOR.dom.node} return.startNode
+                * @returns {CKEDITOR.dom.node} return.endNode
+                * @todo precise desc/algorithm
+                */
+               getBoundaryNodes: function() {
+                       var startNode = this.startContainer,
+                               endNode = this.endContainer,
+                               startOffset = this.startOffset,
+                               endOffset = this.endOffset,
+                               childCount;
+
+                       if ( startNode.type == CKEDITOR.NODE_ELEMENT ) {
+                               childCount = startNode.getChildCount();
+                               if ( childCount > startOffset ) {
+                                       startNode = startNode.getChild( startOffset );
+                               } else if ( childCount < 1 ) {
+                                       startNode = startNode.getPreviousSourceNode();
+                               }
+                               // startOffset > childCount but childCount is not 0
+                               else {
+                                       // Try to take the node just after the current position.
+                                       startNode = startNode.$;
+                                       while ( startNode.lastChild )
+                                               startNode = startNode.lastChild;
+                                       startNode = new CKEDITOR.dom.node( startNode );
+
+                                       // Normally we should take the next node in DFS order. But it
+                                       // is also possible that we've already reached the end of
+                                       // document.
+                                       startNode = startNode.getNextSourceNode() || startNode;
+                               }
+                       }
+
+                       if ( endNode.type == CKEDITOR.NODE_ELEMENT ) {
+                               childCount = endNode.getChildCount();
+                               if ( childCount > endOffset ) {
+                                       endNode = endNode.getChild( endOffset ).getPreviousSourceNode( true );
+                               } else if ( childCount < 1 ) {
+                                       endNode = endNode.getPreviousSourceNode();
+                               }
+                               // endOffset > childCount but childCount is not 0.
+                               else {
+                                       // Try to take the node just before the current position.
+                                       endNode = endNode.$;
+                                       while ( endNode.lastChild )
+                                               endNode = endNode.lastChild;
+                                       endNode = new CKEDITOR.dom.node( endNode );
+                               }
+                       }
+
+                       // Sometimes the endNode will come right before startNode for collapsed
+                       // ranges. Fix it. (#3780)
+                       if ( startNode.getPosition( endNode ) & CKEDITOR.POSITION_FOLLOWING )
+                               startNode = endNode;
+
+                       return { startNode: startNode, endNode: endNode };
+               },
+
+               /**
+                * Find the node which fully contains the range.
+                *
+                * @param {Boolean} [includeSelf=false]
+                * @param {Boolean} [ignoreTextNode=false] Whether ignore {@link CKEDITOR#NODE_TEXT} type.
+                * @returns {CKEDITOR.dom.element}
+                */
+               getCommonAncestor: function( includeSelf, ignoreTextNode ) {
+                       var start = this.startContainer,
+                               end = this.endContainer,
+                               ancestor;
+
+                       if ( start.equals( end ) ) {
+                               if ( includeSelf && start.type == CKEDITOR.NODE_ELEMENT && this.startOffset == this.endOffset - 1 )
+                                       ancestor = start.getChild( this.startOffset );
+                               else
+                                       ancestor = start;
+                       } else {
+                               ancestor = start.getCommonAncestor( end );
+                       }
+
+                       return ignoreTextNode && !ancestor.is ? ancestor.getParent() : ancestor;
+               },
+
+               /**
+                * Transforms the {@link #startContainer} and {@link #endContainer} properties from text
+                * nodes to element nodes, whenever possible. This is actually possible
+                * if either of the boundary containers point to a text node, and its
+                * offset is set to zero, or after the last char in the node.
+                */
+               optimize: function() {
+                       var container = this.startContainer;
+                       var offset = this.startOffset;
+
+                       if ( container.type != CKEDITOR.NODE_ELEMENT ) {
+                               if ( !offset )
+                                       this.setStartBefore( container );
+                               else if ( offset >= container.getLength() )
+                                       this.setStartAfter( container );
+                       }
+
+                       container = this.endContainer;
+                       offset = this.endOffset;
+
+                       if ( container.type != CKEDITOR.NODE_ELEMENT ) {
+                               if ( !offset )
+                                       this.setEndBefore( container );
+                               else if ( offset >= container.getLength() )
+                                       this.setEndAfter( container );
+                       }
+               },
+
+               /**
+                * Move the range out of bookmark nodes if they'd been the container.
+                */
+               optimizeBookmark: function() {
+                       var startNode = this.startContainer,
+                               endNode = this.endContainer;
+
+                       if ( startNode.is && startNode.is( 'span' ) && startNode.data( 'cke-bookmark' ) )
+                               this.setStartAt( startNode, CKEDITOR.POSITION_BEFORE_START );
+                       if ( endNode && endNode.is && endNode.is( 'span' ) && endNode.data( 'cke-bookmark' ) )
+                               this.setEndAt( endNode, CKEDITOR.POSITION_AFTER_END );
+               },
+
+               /**
+                * @param {Boolean} [ignoreStart=false]
+                * @param {Boolean} [ignoreEnd=false]
+                * @todo precise desc/algorithm
+                */
+               trim: function( ignoreStart, ignoreEnd ) {
+                       var startContainer = this.startContainer,
+                               startOffset = this.startOffset,
+                               collapsed = this.collapsed;
+                       if ( ( !ignoreStart || collapsed ) && startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
+                               // If the offset is zero, we just insert the new node before
+                               // the start.
+                               if ( !startOffset ) {
+                                       startOffset = startContainer.getIndex();
+                                       startContainer = startContainer.getParent();
+                               }
+                               // If the offset is at the end, we'll insert it after the text
+                               // node.
+                               else if ( startOffset >= startContainer.getLength() ) {
+                                       startOffset = startContainer.getIndex() + 1;
+                                       startContainer = startContainer.getParent();
+                               }
+                               // In other case, we split the text node and insert the new
+                               // node at the split point.
+                               else {
+                                       var nextText = startContainer.split( startOffset );
+
+                                       startOffset = startContainer.getIndex() + 1;
+                                       startContainer = startContainer.getParent();
+
+                                       // Check all necessity of updating the end boundary.
+                                       if ( this.startContainer.equals( this.endContainer ) )
+                                               this.setEnd( nextText, this.endOffset - this.startOffset );
+                                       else if ( startContainer.equals( this.endContainer ) )
+                                               this.endOffset += 1;
+                               }
+
+                               this.setStart( startContainer, startOffset );
+
+                               if ( collapsed ) {
+                                       this.collapse( true );
+                                       return;
+                               }
+                       }
+
+                       var endContainer = this.endContainer;
+                       var endOffset = this.endOffset;
+
+                       if ( !( ignoreEnd || collapsed ) && endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
+                               // If the offset is zero, we just insert the new node before
+                               // the start.
+                               if ( !endOffset ) {
+                                       endOffset = endContainer.getIndex();
+                                       endContainer = endContainer.getParent();
+                               }
+                               // If the offset is at the end, we'll insert it after the text
+                               // node.
+                               else if ( endOffset >= endContainer.getLength() ) {
+                                       endOffset = endContainer.getIndex() + 1;
+                                       endContainer = endContainer.getParent();
+                               }
+                               // In other case, we split the text node and insert the new
+                               // node at the split point.
+                               else {
+                                       endContainer.split( endOffset );
+
+                                       endOffset = endContainer.getIndex() + 1;
+                                       endContainer = endContainer.getParent();
+                               }
+
+                               this.setEnd( endContainer, endOffset );
+                       }
+               },
+
+               /**
+                * Expands the range so that partial units are completely contained.
+                *
+                * @param {Number} unit The unit type to expand with. Use one of following values: {@link CKEDITOR#ENLARGE_BLOCK_CONTENTS},
+                * {@link CKEDITOR#ENLARGE_ELEMENT}, {@link CKEDITOR#ENLARGE_INLINE}, {@link CKEDITOR#ENLARGE_LIST_ITEM_CONTENTS}.
+                * @param {Boolean} [excludeBrs=false] Whether include line-breaks when expanding.
+                */
+               enlarge: function( unit, excludeBrs ) {
+                       var leadingWhitespaceRegex = new RegExp( /[^\s\ufeff]/ );
+
+                       switch ( unit ) {
+                               case CKEDITOR.ENLARGE_INLINE:
+                                       var enlargeInlineOnly = 1;
+
+                               /* falls through */
+                               case CKEDITOR.ENLARGE_ELEMENT:
+
+                                       if ( this.collapsed )
+                                               return;
+
+                                       // Get the common ancestor.
+                                       var commonAncestor = this.getCommonAncestor();
+
+                                       var boundary = this.root;
+
+                                       // For each boundary
+                                       //              a. Depending on its position, find out the first node to be checked (a sibling) or,
+                                       //                      if not available, to be enlarge.
+                                       //              b. Go ahead checking siblings and enlarging the boundary as much as possible until the
+                                       //                      common ancestor is not reached. After reaching the common ancestor, just save the
+                                       //                      enlargeable node to be used later.
+
+                                       var startTop, endTop;
+
+                                       var enlargeable, sibling, commonReached;
+
+                                       // Indicates that the node can be added only if whitespace
+                                       // is available before it.
+                                       var needsWhiteSpace = false;
+                                       var isWhiteSpace;
+                                       var siblingText;
+
+                                       // Process the start boundary.
+
+                                       var container = this.startContainer;
+                                       var offset = this.startOffset;
+
+                                       if ( container.type == CKEDITOR.NODE_TEXT ) {
+                                               if ( offset ) {
+                                                       // Check if there is any non-space text before the
+                                                       // offset. Otherwise, container is null.
+                                                       container = !CKEDITOR.tools.trim( container.substring( 0, offset ) ).length && container;
+
+                                                       // If we found only whitespace in the node, it
+                                                       // means that we'll need more whitespace to be able
+                                                       // to expand. For example, <i> can be expanded in
+                                                       // "A <i> [B]</i>", but not in "A<i> [B]</i>".
+                                                       needsWhiteSpace = !!container;
+                                               }
+
+                                               if ( container ) {
+                                                       if ( !( sibling = container.getPrevious() ) )
+                                                               enlargeable = container.getParent();
+                                               }
+                                       } else {
+                                               // If we have offset, get the node preceeding it as the
+                                               // first sibling to be checked.
+                                               if ( offset )
+                                                       sibling = container.getChild( offset - 1 ) || container.getLast();
+
+                                               // If there is no sibling, mark the container to be
+                                               // enlarged.
+                                               if ( !sibling )
+                                                       enlargeable = container;
+                                       }
+
+                                       // Ensures that enlargeable can be indeed enlarged, if not it will be nulled.
+                                       enlargeable = getValidEnlargeable( enlargeable );
+
+                                       while ( enlargeable || sibling ) {
+                                               if ( enlargeable && !sibling ) {
+                                                       // If we reached the common ancestor, mark the flag
+                                                       // for it.
+                                                       if ( !commonReached && enlargeable.equals( commonAncestor ) )
+                                                               commonReached = true;
+
+                                                       if ( enlargeInlineOnly ? enlargeable.isBlockBoundary() : !boundary.contains( enlargeable ) )
+                                                               break;
+
+                                                       // If we don't need space or this element breaks
+                                                       // the line, then enlarge it.
+                                                       if ( !needsWhiteSpace || enlargeable.getComputedStyle( 'display' ) != 'inline' ) {
+                                                               needsWhiteSpace = false;
+
+                                                               // If the common ancestor has been reached,
+                                                               // we'll not enlarge it immediately, but just
+                                                               // mark it to be enlarged later if the end
+                                                               // boundary also enlarges it.
+                                                               if ( commonReached )
+                                                                       startTop = enlargeable;
+                                                               else
+                                                                       this.setStartBefore( enlargeable );
+                                                       }
+
+                                                       sibling = enlargeable.getPrevious();
+                                               }
+
+                                               // Check all sibling nodes preceeding the enlargeable
+                                               // node. The node wil lbe enlarged only if none of them
+                                               // blocks it.
+                                               while ( sibling ) {
+                                                       // This flag indicates that this node has
+                                                       // whitespaces at the end.
+                                                       isWhiteSpace = false;
+
+                                                       if ( sibling.type == CKEDITOR.NODE_COMMENT ) {
+                                                               sibling = sibling.getPrevious();
+                                                               continue;
+                                                       } else if ( sibling.type == CKEDITOR.NODE_TEXT ) {
+                                                               siblingText = sibling.getText();
+
+                                                               if ( leadingWhitespaceRegex.test( siblingText ) )
+                                                                       sibling = null;
+
+                                                               isWhiteSpace = /[\s\ufeff]$/.test( siblingText );
+                                                       } else {
+                                                               // #12221 (Chrome) plus #11111 (Safari).
+                                                               var offsetWidth0 = CKEDITOR.env.webkit ? 1 : 0;
+
+                                                               // If this is a visible element.
+                                                               // We need to check for the bookmark attribute because IE insists on
+                                                               // rendering the display:none nodes we use for bookmarks. (#3363)
+                                                               // Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
+                                                               if ( ( sibling.$.offsetWidth > offsetWidth0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
+                                                                       // We'll accept it only if we need
+                                                                       // whitespace, and this is an inline
+                                                                       // element with whitespace only.
+                                                                       if ( needsWhiteSpace && CKEDITOR.dtd.$removeEmpty[ sibling.getName() ] ) {
+                                                                               // It must contains spaces and inline elements only.
+
+                                                                               siblingText = sibling.getText();
+
+                                                                               if ( leadingWhitespaceRegex.test( siblingText ) ) // Spaces + Zero Width No-Break Space (U+FEFF)
+                                                                               sibling = null;
+                                                                               else {
+                                                                                       var allChildren = sibling.$.getElementsByTagName( '*' );
+                                                                                       for ( var i = 0, child; child = allChildren[ i++ ]; ) {
+                                                                                               if ( !CKEDITOR.dtd.$removeEmpty[ child.nodeName.toLowerCase() ] ) {
+                                                                                                       sibling = null;
+                                                                                                       break;
+                                                                                               }
+                                                                                       }
+                                                                               }
+
+                                                                               if ( sibling )
+                                                                                       isWhiteSpace = !!siblingText.length;
+                                                                       } else {
+                                                                               sibling = null;
+                                                                       }
+                                                               }
+                                                       }
+
+                                                       // A node with whitespaces has been found.
+                                                       if ( isWhiteSpace ) {
+                                                               // Enlarge the last enlargeable node, if we
+                                                               // were waiting for spaces.
+                                                               if ( needsWhiteSpace ) {
+                                                                       if ( commonReached )
+                                                                               startTop = enlargeable;
+                                                                       else if ( enlargeable )
+                                                                               this.setStartBefore( enlargeable );
+                                                               } else {
+                                                                       needsWhiteSpace = true;
+                                                               }
+                                                       }
+
+                                                       if ( sibling ) {
+                                                               var next = sibling.getPrevious();
+
+                                                               if ( !enlargeable && !next ) {
+                                                                       // Set the sibling as enlargeable, so it's
+                                                                       // parent will be get later outside this while.
+                                                                       enlargeable = sibling;
+                                                                       sibling = null;
+                                                                       break;
+                                                               }
+
+                                                               sibling = next;
+                                                       } else {
+                                                               // If sibling has been set to null, then we
+                                                               // need to stop enlarging.
+                                                               enlargeable = null;
+                                                       }
+                                               }
+
+                                               if ( enlargeable )
+                                                       enlargeable = getValidEnlargeable( enlargeable.getParent() );
+                                       }
+
+                                       // Process the end boundary. This is basically the same
+                                       // code used for the start boundary, with small changes to
+                                       // make it work in the oposite side (to the right). This
+                                       // makes it difficult to reuse the code here. So, fixes to
+                                       // the above code are likely to be replicated here.
+
+                                       container = this.endContainer;
+                                       offset = this.endOffset;
+
+                                       // Reset the common variables.
+                                       enlargeable = sibling = null;
+                                       commonReached = needsWhiteSpace = false;
+
+                                       // Function check if there are only whitespaces from the given starting point
+                                       // (startContainer and startOffset) till the end on block.
+                                       // Examples ("[" is the start point):
+                                       //  - <p>foo[ </p>           - will return true,
+                                       //  - <p><b>foo[ </b> </p>   - will return true,
+                                       //  - <p>foo[ bar</p>        - will return false,
+                                       //  - <p><b>foo[ </b>bar</p> - will return false,
+                                       //  - <p>foo[ <b></b></p>    - will return false.
+                                       function onlyWhiteSpaces( startContainer, startOffset ) {
+                                               // We need to enlarge range if there is white space at the end of the block,
+                                               // because it is not displayed in WYSIWYG mode and user can not select it. So
+                                               // "<p>foo[bar] </p>" should be changed to "<p>foo[bar ]</p>". On the other hand
+                                               // we should do nothing if we are not at the end of the block, so this should not
+                                               // be changed: "<p><i>[foo] </i>bar</p>".
+                                               var walkerRange = new CKEDITOR.dom.range( boundary );
+                                               walkerRange.setStart( startContainer, startOffset );
+                                               // The guard will find the end of range so I put boundary here.
+                                               walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
+
+                                               var walker = new CKEDITOR.dom.walker( walkerRange ),
+                                                       node;
+
+                                               walker.guard = function( node ) {
+                                                       // Stop if you exit block.
+                                                       return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() );
+                                               };
+
+                                               while ( ( node = walker.next() ) ) {
+                                                       if ( node.type != CKEDITOR.NODE_TEXT ) {
+                                                               // Stop if you enter to any node (walker.next() will return node only
+                                                               // it goes out, not if it is go into node).
+                                                               return false;
+                                                       } else {
+                                                               // Trim the first node to startOffset.
+                                                               if ( node != startContainer )
+                                                                       siblingText = node.getText();
+                                                               else
+                                                                       siblingText = node.substring( startOffset );
+
+                                                               // Check if it is white space.
+                                                               if ( leadingWhitespaceRegex.test( siblingText ) )
+                                                                       return false;
+                                                       }
+                                               }
+
+                                               return true;
+                                       }
+
+                                       if ( container.type == CKEDITOR.NODE_TEXT ) {
+                                               // Check if there is only white space after the offset.
+                                               if ( CKEDITOR.tools.trim( container.substring( offset ) ).length ) {
+                                                       // If we found only whitespace in the node, it
+                                                       // means that we'll need more whitespace to be able
+                                                       // to expand. For example, <i> can be expanded in
+                                                       // "A <i> [B]</i>", but not in "A<i> [B]</i>".
+                                                       needsWhiteSpace = true;
+                                               } else {
+                                                       needsWhiteSpace = !container.getLength();
+
+                                                       if ( offset == container.getLength() ) {
+                                                               // If we are at the end of container and this is the last text node,
+                                                               // we should enlarge end to the parent.
+                                                               if ( !( sibling = container.getNext() ) )
+                                                                       enlargeable = container.getParent();
+                                                       } else {
+                                                               // If we are in the middle on text node and there are only whitespaces
+                                                               // till the end of block, we should enlarge element.
+                                                               if ( onlyWhiteSpaces( container, offset ) )
+                                                                       enlargeable = container.getParent();
+                                                       }
+                                               }
+                                       } else {
+                                               // Get the node right after the boudary to be checked
+                                               // first.
+                                               sibling = container.getChild( offset );
+
+                                               if ( !sibling )
+                                                       enlargeable = container;
+                                       }
+
+                                       while ( enlargeable || sibling ) {
+                                               if ( enlargeable && !sibling ) {
+                                                       if ( !commonReached && enlargeable.equals( commonAncestor ) )
+                                                               commonReached = true;
+
+                                                       if ( enlargeInlineOnly ? enlargeable.isBlockBoundary() : !boundary.contains( enlargeable ) )
+                                                               break;
+
+                                                       if ( !needsWhiteSpace || enlargeable.getComputedStyle( 'display' ) != 'inline' ) {
+                                                               needsWhiteSpace = false;
+
+                                                               if ( commonReached )
+                                                                       endTop = enlargeable;
+                                                               else if ( enlargeable )
+                                                                       this.setEndAfter( enlargeable );
+                                                       }
+
+                                                       sibling = enlargeable.getNext();
+                                               }
+
+                                               while ( sibling ) {
+                                                       isWhiteSpace = false;
+
+                                                       if ( sibling.type == CKEDITOR.NODE_TEXT ) {
+                                                               siblingText = sibling.getText();
+
+                                                               // Check if there are not whitespace characters till the end of editable.
+                                                               // If so stop expanding.
+                                                               if ( !onlyWhiteSpaces( sibling, 0 ) )
+                                                                       sibling = null;
+
+                                                               isWhiteSpace = /^[\s\ufeff]/.test( siblingText );
+                                                       } else if ( sibling.type == CKEDITOR.NODE_ELEMENT ) {
+                                                               // If this is a visible element.
+                                                               // We need to check for the bookmark attribute because IE insists on
+                                                               // rendering the display:none nodes we use for bookmarks. (#3363)
+                                                               // Line-breaks (br) are rendered with zero width, which we don't want to include. (#7041)
+                                                               if ( ( sibling.$.offsetWidth > 0 || excludeBrs && sibling.is( 'br' ) ) && !sibling.data( 'cke-bookmark' ) ) {
+                                                                       // We'll accept it only if we need
+                                                                       // whitespace, and this is an inline
+                                                                       // element with whitespace only.
+                                                                       if ( needsWhiteSpace && CKEDITOR.dtd.$removeEmpty[ sibling.getName() ] ) {
+                                                                               // It must contains spaces and inline elements only.
+
+                                                                               siblingText = sibling.getText();
+
+                                                                               if ( leadingWhitespaceRegex.test( siblingText ) )
+                                                                                       sibling = null;
+                                                                               else {
+                                                                                       allChildren = sibling.$.getElementsByTagName( '*' );
+                                                                                       for ( i = 0; child = allChildren[ i++ ]; ) {
+                                                                                               if ( !CKEDITOR.dtd.$removeEmpty[ child.nodeName.toLowerCase() ] ) {
+                                                                                                       sibling = null;
+                                                                                                       break;
+                                                                                               }
+                                                                                       }
+                                                                               }
+
+                                                                               if ( sibling )
+                                                                                       isWhiteSpace = !!siblingText.length;
+                                                                       } else {
+                                                                               sibling = null;
+                                                                       }
+                                                               }
+                                                       } else {
+                                                               isWhiteSpace = 1;
+                                                       }
+
+                                                       if ( isWhiteSpace ) {
+                                                               if ( needsWhiteSpace ) {
+                                                                       if ( commonReached )
+                                                                               endTop = enlargeable;
+                                                                       else
+                                                                               this.setEndAfter( enlargeable );
+                                                               }
+                                                       }
+
+                                                       if ( sibling ) {
+                                                               next = sibling.getNext();
+
+                                                               if ( !enlargeable && !next ) {
+                                                                       enlargeable = sibling;
+                                                                       sibling = null;
+                                                                       break;
+                                                               }
+
+                                                               sibling = next;
+                                                       } else {
+                                                               // If sibling has been set to null, then we
+                                                               // need to stop enlarging.
+                                                               enlargeable = null;
+                                                       }
+                                               }
+
+                                               if ( enlargeable )
+                                                       enlargeable = getValidEnlargeable( enlargeable.getParent() );
+                                       }
+
+                                       // If the common ancestor can be enlarged by both boundaries, then include it also.
+                                       if ( startTop && endTop ) {
+                                               commonAncestor = startTop.contains( endTop ) ? endTop : startTop;
+
+                                               this.setStartBefore( commonAncestor );
+                                               this.setEndAfter( commonAncestor );
+                                       }
+                                       break;
+
+                               case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
+                               case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
+
+                                       // Enlarging the start boundary.
+                                       var walkerRange = new CKEDITOR.dom.range( this.root );
+
+                                       boundary = this.root;
+
+                                       walkerRange.setStartAt( boundary, CKEDITOR.POSITION_AFTER_START );
+                                       walkerRange.setEnd( this.startContainer, this.startOffset );
+
+                                       var walker = new CKEDITOR.dom.walker( walkerRange ),
+                                               blockBoundary, // The node on which the enlarging should stop.
+                                               tailBr, // In case BR as block boundary.
+                                               notBlockBoundary = CKEDITOR.dom.walker.blockBoundary( ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br: 1 } : null ),
+                                               inNonEditable = null,
+                                               // Record the encountered 'blockBoundary' for later use.
+                                               boundaryGuard = function( node ) {
+                                                       // We should not check contents of non-editable elements. It may happen
+                                                       // that inline widget has display:table child which should not block range#enlarge.
+                                                       // When encoutered non-editable element...
+                                                       if ( node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'false' ) {
+                                                               if ( inNonEditable ) {
+                                                                       // ... in which we already were, reset it (because we're leaving it) and return.
+                                                                       if ( inNonEditable.equals( node ) ) {
+                                                                               inNonEditable = null;
+                                                                               return;
+                                                                       }
+                                                               // ... which we're entering, remember it but check it (no return).
+                                                               } else {
+                                                                       inNonEditable = node;
+                                                               }
+                                                       // When we are in non-editable element, do not check if current node is a block boundary.
+                                                       } else if ( inNonEditable ) {
+                                                               return;
+                                                       }
+
+                                                       var retval = notBlockBoundary( node );
+                                                       if ( !retval )
+                                                               blockBoundary = node;
+                                                       return retval;
+                                               },
+                                               // Record the encounted 'tailBr' for later use.
+                                               tailBrGuard = function( node ) {
+                                                       var retval = boundaryGuard( node );
+                                                       if ( !retval && node.is && node.is( 'br' ) )
+                                                               tailBr = node;
+                                                       return retval;
+                                               };
+
+                                       walker.guard = boundaryGuard;
+
+                                       enlargeable = walker.lastBackward();
+
+                                       // It's the body which stop the enlarging if no block boundary found.
+                                       blockBoundary = blockBoundary || boundary;
+
+                                       // Start the range either after the end of found block (<p>...</p>[text)
+                                       // or at the start of block (<p>[text...), by comparing the document position
+                                       // with 'enlargeable' node.
+                                       this.setStartAt( blockBoundary, !blockBoundary.is( 'br' ) && ( !enlargeable && this.checkStartOfBlock() ||
+                                               enlargeable && blockBoundary.contains( enlargeable ) ) ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_AFTER_END );
+
+                                       // Avoid enlarging the range further when end boundary spans right after the BR. (#7490)
+                                       if ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) {
+                                               var theRange = this.clone();
+                                               walker = new CKEDITOR.dom.walker( theRange );
+
+                                               var whitespaces = CKEDITOR.dom.walker.whitespaces(),
+                                                       bookmark = CKEDITOR.dom.walker.bookmark();
+
+                                               walker.evaluator = function( node ) {
+                                                       return !whitespaces( node ) && !bookmark( node );
+                                               };
+                                               var previous = walker.previous();
+                                               if ( previous && previous.type == CKEDITOR.NODE_ELEMENT && previous.is( 'br' ) )
+                                                       return;
+                                       }
+
+                                       // Enlarging the end boundary.
+                                       // Set up new range and reset all flags (blockBoundary, inNonEditable, tailBr).
+
+                                       walkerRange = this.clone();
+                                       walkerRange.collapse();
+                                       walkerRange.setEndAt( boundary, CKEDITOR.POSITION_BEFORE_END );
+                                       walker = new CKEDITOR.dom.walker( walkerRange );
+
+                                       // tailBrGuard only used for on range end.
+                                       walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? tailBrGuard : boundaryGuard;
+                                       blockBoundary = inNonEditable = tailBr = null;
+
+                                       // End the range right before the block boundary node.
+                                       enlargeable = walker.lastForward();
+
+                                       // It's the body which stop the enlarging if no block boundary found.
+                                       blockBoundary = blockBoundary || boundary;
+
+                                       // Close the range either before the found block start (text]<p>...</p>) or at the block end (...text]</p>)
+                                       // by comparing the document position with 'enlargeable' node.
+                                       this.setEndAt( blockBoundary, ( !enlargeable && this.checkEndOfBlock() ||
+                                               enlargeable && blockBoundary.contains( enlargeable ) ) ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_BEFORE_START );
+                                       // We must include the <br> at the end of range if there's
+                                       // one and we're expanding list item contents
+                                       if ( tailBr ) {
+                                               this.setEndAfter( tailBr );
+                                       }
+                       }
+
+                       // Ensures that returned element can be enlarged by selection, null otherwise.
+                       // @param {CKEDITOR.dom.element} enlargeable
+                       // @returns {CKEDITOR.dom.element/null}
+                       function getValidEnlargeable( enlargeable ) {
+                               return enlargeable && enlargeable.type == CKEDITOR.NODE_ELEMENT && enlargeable.hasAttribute( 'contenteditable' ) ?
+                                       null : enlargeable;
+                       }
+               },
+
+               /**
+                * Descrease the range to make sure that boundaries
+                * always anchor beside text nodes or innermost element.
+                *
+                * @param {Number} mode The shrinking mode ({@link CKEDITOR#SHRINK_ELEMENT} or {@link CKEDITOR#SHRINK_TEXT}).
+                *
+                * * {@link CKEDITOR#SHRINK_ELEMENT} - Shrink the range boundaries to the edge of the innermost element.
+                * * {@link CKEDITOR#SHRINK_TEXT} - Shrink the range boudaries to anchor by the side of enclosed text
+                *     node, range remains if there's no text nodes on boundaries at all.
+                *
+                * @param {Boolean} selectContents Whether result range anchors at the inner OR outer boundary of the node.
+                */
+               shrink: function( mode, selectContents, shrinkOnBlockBoundary ) {
+                       // Unable to shrink a collapsed range.
+                       if ( !this.collapsed ) {
+                               mode = mode || CKEDITOR.SHRINK_TEXT;
+
+                               var walkerRange = this.clone();
+
+                               var startContainer = this.startContainer,
+                                       endContainer = this.endContainer,
+                                       startOffset = this.startOffset,
+                                       endOffset = this.endOffset;
+
+                               // Whether the start/end boundary is moveable.
+                               var moveStart = 1,
+                                       moveEnd = 1;
+
+                               if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
+                                       if ( !startOffset )
+                                               walkerRange.setStartBefore( startContainer );
+                                       else if ( startOffset >= startContainer.getLength() )
+                                               walkerRange.setStartAfter( startContainer );
+                                       else {
+                                               // Enlarge the range properly to avoid walker making
+                                               // DOM changes caused by triming the text nodes later.
+                                               walkerRange.setStartBefore( startContainer );
+                                               moveStart = 0;
+                                       }
+                               }
+
+                               if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
+                                       if ( !endOffset )
+                                               walkerRange.setEndBefore( endContainer );
+                                       else if ( endOffset >= endContainer.getLength() )
+                                               walkerRange.setEndAfter( endContainer );
+                                       else {
+                                               walkerRange.setEndAfter( endContainer );
+                                               moveEnd = 0;
+                                       }
+                               }
+
+                               var walker = new CKEDITOR.dom.walker( walkerRange ),
+                                       isBookmark = CKEDITOR.dom.walker.bookmark();
+
+                               walker.evaluator = function( node ) {
+                                       return node.type == ( mode == CKEDITOR.SHRINK_ELEMENT ? CKEDITOR.NODE_ELEMENT : CKEDITOR.NODE_TEXT );
+                               };
+
+                               var currentElement;
+                               walker.guard = function( node, movingOut ) {
+                                       if ( isBookmark( node ) )
+                                               return true;
+
+                                       // Stop when we're shrink in element mode while encountering a text node.
+                                       if ( mode == CKEDITOR.SHRINK_ELEMENT && node.type == CKEDITOR.NODE_TEXT )
+                                               return false;
+
+                                       // Stop when we've already walked "through" an element.
+                                       if ( movingOut && node.equals( currentElement ) )
+                                               return false;
+
+                                       if ( shrinkOnBlockBoundary === false && node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary() )
+                                               return false;
+
+                                       // Stop shrinking when encountering an editable border.
+                                       if ( node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'contenteditable' ) )
+                                               return false;
+
+                                       if ( !movingOut && node.type == CKEDITOR.NODE_ELEMENT )
+                                               currentElement = node;
+
+                                       return true;
+                               };
+
+                               if ( moveStart ) {
+                                       var textStart = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastForward' : 'next' ]();
+                                       textStart && this.setStartAt( textStart, selectContents ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_START );
+                               }
+
+                               if ( moveEnd ) {
+                                       walker.reset();
+                                       var textEnd = walker[ mode == CKEDITOR.SHRINK_ELEMENT ? 'lastBackward' : 'previous' ]();
+                                       textEnd && this.setEndAt( textEnd, selectContents ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_END );
+                               }
+
+                               return !!( moveStart || moveEnd );
+                       }
+               },
+
+               /**
+                * Inserts a node at the start of the range. The range will be expanded
+                * the contain the node.
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               insertNode: function( node ) {
+                       this.optimizeBookmark();
+                       this.trim( false, true );
+
+                       var startContainer = this.startContainer;
+                       var startOffset = this.startOffset;
+
+                       var nextNode = startContainer.getChild( startOffset );
+
+                       if ( nextNode )
+                               node.insertBefore( nextNode );
+                       else
+                               startContainer.append( node );
+
+                       // Check if we need to update the end boundary.
+                       if ( node.getParent() && node.getParent().equals( this.endContainer ) )
+                               this.endOffset++;
+
+                       // Expand the range to embrace the new node.
+                       this.setStartBefore( node );
+               },
+
+               /**
+                * Moves the range to given position according to specified node.
+                *
+                *              // HTML: <p>Foo <b>bar</b></p>
+                *              range.moveToPosition( elB, CKEDITOR.POSITION_BEFORE_START );
+                *              // Range will be moved to: <p>Foo ^<b>bar</b></p>
+                *
+                * See also {@link #setStartAt} and {@link #setEndAt}.
+                *
+                * @param {CKEDITOR.dom.node} node The node according to which position will be set.
+                * @param {Number} position One of {@link CKEDITOR#POSITION_BEFORE_START},
+                * {@link CKEDITOR#POSITION_AFTER_START}, {@link CKEDITOR#POSITION_BEFORE_END},
+                * {@link CKEDITOR#POSITION_AFTER_END}.
+                */
+               moveToPosition: function( node, position ) {
+                       this.setStartAt( node, position );
+                       this.collapse( true );
+               },
+
+               /**
+                * Moves the range to the exact position of the specified range.
+                *
+                * @param {CKEDITOR.dom.range} range
+                */
+               moveToRange: function( range ) {
+                       this.setStart( range.startContainer, range.startOffset );
+                       this.setEnd( range.endContainer, range.endOffset );
+               },
+
+               /**
+                * Select nodes content. Range will start and end inside this node.
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               selectNodeContents: function( node ) {
+                       this.setStart( node, 0 );
+                       this.setEnd( node, node.type == CKEDITOR.NODE_TEXT ? node.getLength() : node.getChildCount() );
+               },
+
+               /**
+                * Sets the start position of a range.
+                *
+                * @param {CKEDITOR.dom.node} startNode The node to start the range.
+                * @param {Number} startOffset An integer greater than or equal to zero
+                * representing the offset for the start of the range from the start
+                * of `startNode`.
+                */
+               setStart: function( startNode, startOffset ) {
+                       // W3C requires a check for the new position. If it is after the end
+                       // boundary, the range should be collapsed to the new start. It seams
+                       // we will not need this check for our use of this class so we can
+                       // ignore it for now.
+
+                       // Fixing invalid range start inside dtd empty elements.
+                       if ( startNode.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$empty[ startNode.getName() ] )
+                               startOffset = startNode.getIndex(), startNode = startNode.getParent();
+
+                       this._setStartContainer( startNode );
+                       this.startOffset = startOffset;
+
+                       if ( !this.endContainer ) {
+                               this._setEndContainer( startNode );
+                               this.endOffset = startOffset;
+                       }
+
+                       updateCollapsed( this );
+               },
+
+               /**
+                * Sets the end position of a Range.
+                *
+                * @param {CKEDITOR.dom.node} endNode The node to end the range.
+                * @param {Number} endOffset An integer greater than or equal to zero
+                * representing the offset for the end of the range from the start
+                * of `endNode`.
+                */
+               setEnd: function( endNode, endOffset ) {
+                       // W3C requires a check for the new position. If it is before the start
+                       // boundary, the range should be collapsed to the new end. It seams we
+                       // will not need this check for our use of this class so we can ignore
+                       // it for now.
+
+                       // Fixing invalid range end inside dtd empty elements.
+                       if ( endNode.type == CKEDITOR.NODE_ELEMENT && CKEDITOR.dtd.$empty[ endNode.getName() ] )
+                               endOffset = endNode.getIndex() + 1, endNode = endNode.getParent();
+
+                       this._setEndContainer( endNode );
+                       this.endOffset = endOffset;
+
+                       if ( !this.startContainer ) {
+                               this._setStartContainer( endNode );
+                               this.startOffset = endOffset;
+                       }
+
+                       updateCollapsed( this );
+               },
+
+               /**
+                * Sets start of this range after the specified node.
+                *
+                *              // Range: <p>foo<b>bar</b>^</p>
+                *              range.setStartAfter( textFoo );
+                *              // The range will be changed to:
+                *              // <p>foo[<b>bar</b>]</p>
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               setStartAfter: function( node ) {
+                       this.setStart( node.getParent(), node.getIndex() + 1 );
+               },
+
+               /**
+                * Sets start of this range after the specified node.
+                *
+                *              // Range: <p>foo<b>bar</b>^</p>
+                *              range.setStartBefore( elB );
+                *              // The range will be changed to:
+                *              // <p>foo[<b>bar</b>]</p>
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               setStartBefore: function( node ) {
+                       this.setStart( node.getParent(), node.getIndex() );
+               },
+
+               /**
+                * Sets end of this range after the specified node.
+                *
+                *              // Range: <p>foo^<b>bar</b></p>
+                *              range.setEndAfter( elB );
+                *              // The range will be changed to:
+                *              // <p>foo[<b>bar</b>]</p>
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               setEndAfter: function( node ) {
+                       this.setEnd( node.getParent(), node.getIndex() + 1 );
+               },
+
+               /**
+                * Sets end of this range before the specified node.
+                *
+                *              // Range: <p>^foo<b>bar</b></p>
+                *              range.setStartAfter( textBar );
+                *              // The range will be changed to:
+                *              // <p>[foo<b>]bar</b></p>
+                *
+                * @param {CKEDITOR.dom.node} node
+                */
+               setEndBefore: function( node ) {
+                       this.setEnd( node.getParent(), node.getIndex() );
+               },
+
+               /**
+                * Moves the start of this range to given position according to specified node.
+                *
+                *              // HTML: <p>Foo <b>bar</b>^</p>
+                *              range.setStartAt( elB, CKEDITOR.POSITION_AFTER_START );
+                *              // The range will be changed to:
+                *              // <p>Foo <b>[bar</b>]</p>
+                *
+                * See also {@link #setEndAt} and {@link #moveToPosition}.
+                *
+                * @param {CKEDITOR.dom.node} node The node according to which position will be set.
+                * @param {Number} position One of {@link CKEDITOR#POSITION_BEFORE_START},
+                * {@link CKEDITOR#POSITION_AFTER_START}, {@link CKEDITOR#POSITION_BEFORE_END},
+                * {@link CKEDITOR#POSITION_AFTER_END}.
+                */
+               setStartAt: function( node, position ) {
+                       switch ( position ) {
+                               case CKEDITOR.POSITION_AFTER_START:
+                                       this.setStart( node, 0 );
+                                       break;
+
+                               case CKEDITOR.POSITION_BEFORE_END:
+                                       if ( node.type == CKEDITOR.NODE_TEXT )
+                                               this.setStart( node, node.getLength() );
+                                       else
+                                               this.setStart( node, node.getChildCount() );
+                                       break;
+
+                               case CKEDITOR.POSITION_BEFORE_START:
+                                       this.setStartBefore( node );
+                                       break;
+
+                               case CKEDITOR.POSITION_AFTER_END:
+                                       this.setStartAfter( node );
+                       }
+
+                       updateCollapsed( this );
+               },
+
+               /**
+                * Moves the end of this range to given position according to specified node.
+                *
+                *              // HTML: <p>^Foo <b>bar</b></p>
+                *              range.setEndAt( textBar, CKEDITOR.POSITION_BEFORE_START );
+                *              // The range will be changed to:
+                *              // <p>[Foo <b>]bar</b></p>
+                *
+                * See also {@link #setStartAt} and {@link #moveToPosition}.
+                *
+                * @param {CKEDITOR.dom.node} node The node according to which position will be set.
+                * @param {Number} position One of {@link CKEDITOR#POSITION_BEFORE_START},
+                * {@link CKEDITOR#POSITION_AFTER_START}, {@link CKEDITOR#POSITION_BEFORE_END},
+                * {@link CKEDITOR#POSITION_AFTER_END}.
+                */
+               setEndAt: function( node, position ) {
+                       switch ( position ) {
+                               case CKEDITOR.POSITION_AFTER_START:
+                                       this.setEnd( node, 0 );
+                                       break;
+
+                               case CKEDITOR.POSITION_BEFORE_END:
+                                       if ( node.type == CKEDITOR.NODE_TEXT )
+                                               this.setEnd( node, node.getLength() );
+                                       else
+                                               this.setEnd( node, node.getChildCount() );
+                                       break;
+
+                               case CKEDITOR.POSITION_BEFORE_START:
+                                       this.setEndBefore( node );
+                                       break;
+
+                               case CKEDITOR.POSITION_AFTER_END:
+                                       this.setEndAfter( node );
+                       }
+
+                       updateCollapsed( this );
+               },
+
+               /**
+                * Wraps inline content found around the range's start or end boundary
+                * with a block element.
+                *
+                *              // Assuming the following range:
+                *              // <h1>foo</h1>ba^r<br />bom<p>foo</p>
+                *              // The result of executing:
+                *              range.fixBlock( true, 'p' );
+                *              // will be:
+                *              // <h1>foo</h1><p>ba^r<br />bom</p><p>foo</p>
+                *
+                * Non-collapsed range:
+                *
+                *              // Assuming the following range:
+                *              // ba[r<p>foo</p>bo]m
+                *              // The result of executing:
+                *              range.fixBlock( false, 'p' );
+                *              // will be:
+                *              // ba[r<p>foo</p><p>bo]m</p>
+                *
+                * @param {Boolean} isStart Whether the start or end boundary of a range should be checked.
+                * @param {String} blockTag The name of a block element in which content will be wrapped.
+                * For example: `'p'`.
+                * @returns {CKEDITOR.dom.element} Created block wrapper.
+                */
+               fixBlock: function( isStart, blockTag ) {
+                       var bookmark = this.createBookmark(),
+                               fixedBlock = this.document.createElement( blockTag );
+
+                       this.collapse( isStart );
+
+                       this.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
+
+                       this.extractContents().appendTo( fixedBlock );
+                       fixedBlock.trim();
+
+                       this.insertNode( fixedBlock );
+
+                       // Bogus <br> could already exist in the range's container before fixBlock() was called. In such case it was
+                       // extracted and appended to the fixBlock. However, we are not sure that it's at the end of
+                       // the fixedBlock, because of FF's terrible bug. When creating a bookmark in an empty editable
+                       // FF moves the bogus <br> before that bookmark (<editable><br /><bm />[]</editable>).
+                       // So even if the initial range was placed before the bogus <br>, after creating the bookmark it
+                       // is placed before the bookmark.
+                       // Fortunately, getBogus() is able to skip the bookmark so it finds the bogus <br> in this case.
+                       // We remove incorrectly placed one and add a brand new one. (#13001)
+                       var bogus = fixedBlock.getBogus();
+                       if ( bogus ) {
+                               bogus.remove();
+                       }
+                       fixedBlock.appendBogus();
+
+                       this.moveToBookmark( bookmark );
+
+                       return fixedBlock;
+               },
+
+               /**
+                * @todo
+                * @param {Boolean} [cloneId=false] Whether to preserve ID attributes in the result blocks.
+                */
+               splitBlock: function( blockTag, cloneId ) {
+                       var startPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root ),
+                               endPath = new CKEDITOR.dom.elementPath( this.endContainer, this.root );
+
+                       var startBlockLimit = startPath.blockLimit,
+                               endBlockLimit = endPath.blockLimit;
+
+                       var startBlock = startPath.block,
+                               endBlock = endPath.block;
+
+                       var elementPath = null;
+                       // Do nothing if the boundaries are in different block limits.
+                       if ( !startBlockLimit.equals( endBlockLimit ) )
+                               return null;
+
+                       // Get or fix current blocks.
+                       if ( blockTag != 'br' ) {
+                               if ( !startBlock ) {
+                                       startBlock = this.fixBlock( true, blockTag );
+                                       endBlock = new CKEDITOR.dom.elementPath( this.endContainer, this.root ).block;
+                               }
+
+                               if ( !endBlock )
+                                       endBlock = this.fixBlock( false, blockTag );
+                       }
+
+                       // Get the range position.
+                       var isStartOfBlock = startBlock && this.checkStartOfBlock(),
+                               isEndOfBlock = endBlock && this.checkEndOfBlock();
+
+                       // Delete the current contents.
+                       // TODO: Why is 2.x doing CheckIsEmpty()?
+                       this.deleteContents();
+
+                       if ( startBlock && startBlock.equals( endBlock ) ) {
+                               if ( isEndOfBlock ) {
+                                       elementPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
+                                       this.moveToPosition( endBlock, CKEDITOR.POSITION_AFTER_END );
+                                       endBlock = null;
+                               } else if ( isStartOfBlock ) {
+                                       elementPath = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
+                                       this.moveToPosition( startBlock, CKEDITOR.POSITION_BEFORE_START );
+                                       startBlock = null;
+                               } else {
+                                       endBlock = this.splitElement( startBlock, cloneId || false );
+
+                                       // In Gecko, the last child node must be a bogus <br>.
+                                       // Note: bogus <br> added under <ul> or <ol> would cause
+                                       // lists to be incorrectly rendered.
+                                       if ( !startBlock.is( 'ul', 'ol' ) )
+                                               startBlock.appendBogus();
+                               }
+                       }
+
+                       return {
+                               previousBlock: startBlock,
+                               nextBlock: endBlock,
+                               wasStartOfBlock: isStartOfBlock,
+                               wasEndOfBlock: isEndOfBlock,
+                               elementPath: elementPath
+                       };
+               },
+
+               /**
+                * Branch the specified element from the collapsed range position and
+                * place the caret between the two result branches.
+                *
+                * **Note:** The range must be collapsed and been enclosed by this element.
+                *
+                * @param {CKEDITOR.dom.element} element
+                * @param {Boolean} [cloneId=false] Whether to preserve ID attributes in the result elements.
+                * @returns {CKEDITOR.dom.element} Root element of the new branch after the split.
+                */
+               splitElement: function( toSplit, cloneId ) {
+                       if ( !this.collapsed )
+                               return null;
+
+                       // Extract the contents of the block from the selection point to the end
+                       // of its contents.
+                       this.setEndAt( toSplit, CKEDITOR.POSITION_BEFORE_END );
+                       var documentFragment = this.extractContents( false, cloneId || false );
+
+                       // Duplicate the element after it.
+                       var clone = toSplit.clone( false, cloneId || false );
+
+                       // Place the extracted contents into the duplicated element.
+                       documentFragment.appendTo( clone );
+                       clone.insertAfter( toSplit );
+                       this.moveToPosition( toSplit, CKEDITOR.POSITION_AFTER_END );
+                       return clone;
+               },
+
+               /**
+                * Recursively remove any empty path blocks at the range boundary.
+                *
+                * @method
+                * @param {Boolean} atEnd Removal to perform at the end boundary,
+                * otherwise to perform at the start.
+                */
+               removeEmptyBlocksAtEnd: ( function() {
+
+                       var whitespace = CKEDITOR.dom.walker.whitespaces(),
+                                       bookmark = CKEDITOR.dom.walker.bookmark( false );
+
+                       function childEval( parent ) {
+                               return function( node ) {
+                                       // Whitespace, bookmarks, empty inlines.
+                                       if ( whitespace( node ) || bookmark( node ) ||
+                                                       node.type == CKEDITOR.NODE_ELEMENT &&
+                                                       node.isEmptyInlineRemoveable() ) {
+                                               return false;
+                                       } else if ( parent.is( 'table' ) && node.is( 'caption' ) ) {
+                                               return false;
+                                       }
+
+                                       return true;
+                               };
+                       }
+
+                       return function( atEnd ) {
+
+                               var bm = this.createBookmark();
+                               var path = this[ atEnd ? 'endPath' : 'startPath' ]();
+                               var block = path.block || path.blockLimit, parent;
+
+                               // Remove any childless block, including list and table.
+                               while ( block && !block.equals( path.root ) &&
+                                               !block.getFirst( childEval( block ) ) ) {
+                                       parent = block.getParent();
+                                       this[ atEnd ? 'setEndAt' : 'setStartAt' ]( block, CKEDITOR.POSITION_AFTER_END );
+                                       block.remove( 1 );
+                                       block = parent;
+                               }
+
+                               this.moveToBookmark( bm );
+                       };
+
+               } )(),
+
+               /**
+                * Gets {@link CKEDITOR.dom.elementPath} for the {@link #startContainer}.
+                *
+                * @returns {CKEDITOR.dom.elementPath}
+                */
+               startPath: function() {
+                       return new CKEDITOR.dom.elementPath( this.startContainer, this.root );
+               },
+
+               /**
+                * Gets {@link CKEDITOR.dom.elementPath} for the {@link #endContainer}.
+                *
+                * @returns {CKEDITOR.dom.elementPath}
+                */
+               endPath: function() {
+                       return new CKEDITOR.dom.elementPath( this.endContainer, this.root );
+               },
+
+               /**
+                * Check whether a range boundary is at the inner boundary of a given
+                * element.
+                *
+                * @param {CKEDITOR.dom.element} element The target element to check.
+                * @param {Number} checkType The boundary to check for both the range
+                * and the element. It can be {@link CKEDITOR#START} or {@link CKEDITOR#END}.
+                * @returns {Boolean} `true` if the range boundary is at the inner
+                * boundary of the element.
+                */
+               checkBoundaryOfElement: function( element, checkType ) {
+                       var checkStart = ( checkType == CKEDITOR.START );
+
+                       // Create a copy of this range, so we can manipulate it for our checks.
+                       var walkerRange = this.clone();
+
+                       // Collapse the range at the proper size.
+                       walkerRange.collapse( checkStart );
+
+                       // Expand the range to element boundary.
+                       walkerRange[ checkStart ? 'setStartAt' : 'setEndAt' ]( element, checkStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
+
+                       // Create the walker, which will check if we have anything useful
+                       // in the range.
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = elementBoundaryEval( checkStart );
+
+                       return walker[ checkStart ? 'checkBackward' : 'checkForward' ]();
+               },
+
+               /**
+                * **Note:** Calls to this function may produce changes to the DOM. The range may
+                * be updated to reflect such changes.
+                *
+                * @returns {Boolean}
+                * @todo
+                */
+               checkStartOfBlock: function() {
+                       var startContainer = this.startContainer,
+                               startOffset = this.startOffset;
+
+                       // [IE] Special handling for range start in text with a leading NBSP,
+                       // we it to be isolated, for bogus check.
+                       if ( CKEDITOR.env.ie && startOffset && startContainer.type == CKEDITOR.NODE_TEXT ) {
+                               var textBefore = CKEDITOR.tools.ltrim( startContainer.substring( 0, startOffset ) );
+                               if ( nbspRegExp.test( textBefore ) )
+                                       this.trim( 0, 1 );
+                       }
+
+                       // Antecipate the trim() call here, so the walker will not make
+                       // changes to the DOM, which would not get reflected into this
+                       // range otherwise.
+                       this.trim();
+
+                       // We need to grab the block element holding the start boundary, so
+                       // let's use an element path for it.
+                       var path = new CKEDITOR.dom.elementPath( this.startContainer, this.root );
+
+                       // Creates a range starting at the block start until the range start.
+                       var walkerRange = this.clone();
+                       walkerRange.collapse( true );
+                       walkerRange.setStartAt( path.block || path.blockLimit, CKEDITOR.POSITION_AFTER_START );
+
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = getCheckStartEndBlockEvalFunction();
+
+                       return walker.checkBackward();
+               },
+
+               /**
+                * **Note:** Calls to this function may produce changes to the DOM. The range may
+                * be updated to reflect such changes.
+                *
+                * @returns {Boolean}
+                * @todo
+                */
+               checkEndOfBlock: function() {
+                       var endContainer = this.endContainer,
+                               endOffset = this.endOffset;
+
+                       // [IE] Special handling for range end in text with a following NBSP,
+                       // we it to be isolated, for bogus check.
+                       if ( CKEDITOR.env.ie && endContainer.type == CKEDITOR.NODE_TEXT ) {
+                               var textAfter = CKEDITOR.tools.rtrim( endContainer.substring( endOffset ) );
+                               if ( nbspRegExp.test( textAfter ) )
+                                       this.trim( 1, 0 );
+                       }
+
+                       // Antecipate the trim() call here, so the walker will not make
+                       // changes to the DOM, which would not get reflected into this
+                       // range otherwise.
+                       this.trim();
+
+                       // We need to grab the block element holding the start boundary, so
+                       // let's use an element path for it.
+                       var path = new CKEDITOR.dom.elementPath( this.endContainer, this.root );
+
+                       // Creates a range starting at the block start until the range start.
+                       var walkerRange = this.clone();
+                       walkerRange.collapse( false );
+                       walkerRange.setEndAt( path.block || path.blockLimit, CKEDITOR.POSITION_BEFORE_END );
+
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = getCheckStartEndBlockEvalFunction();
+
+                       return walker.checkForward();
+               },
+
+               /**
+                * Traverse with {@link CKEDITOR.dom.walker} to retrieve the previous element before the range start.
+                *
+                * @param {Function} evaluator Function used as the walker's evaluator.
+                * @param {Function} [guard] Function used as the walker's guard.
+                * @param {CKEDITOR.dom.element} [boundary] A range ancestor element in which the traversal is limited,
+                * default to the root editable if not defined.
+                * @returns {CKEDITOR.dom.element/null} The returned node from the traversal.
+                */
+               getPreviousNode: function( evaluator, guard, boundary ) {
+                       var walkerRange = this.clone();
+                       walkerRange.collapse( 1 );
+                       walkerRange.setStartAt( boundary || this.root, CKEDITOR.POSITION_AFTER_START );
+
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = evaluator;
+                       walker.guard = guard;
+                       return walker.previous();
+               },
+
+               /**
+                * Traverse with {@link CKEDITOR.dom.walker} to retrieve the next element before the range start.
+                *
+                * @param {Function} evaluator Function used as the walker's evaluator.
+                * @param {Function} [guard] Function used as the walker's guard.
+                * @param {CKEDITOR.dom.element} [boundary] A range ancestor element in which the traversal is limited,
+                * default to the root editable if not defined.
+                * @returns {CKEDITOR.dom.element/null} The returned node from the traversal.
+                */
+               getNextNode: function( evaluator, guard, boundary ) {
+                       var walkerRange = this.clone();
+                       walkerRange.collapse();
+                       walkerRange.setEndAt( boundary || this.root, CKEDITOR.POSITION_BEFORE_END );
+
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = evaluator;
+                       walker.guard = guard;
+                       return walker.next();
+               },
+
+               /**
+                * Check if elements at which the range boundaries anchor are read-only,
+                * with respect to `contenteditable` attribute.
+                *
+                * @returns {Boolean}
+                */
+               checkReadOnly: ( function() {
+                       function checkNodesEditable( node, anotherEnd ) {
+                               while ( node ) {
+                                       if ( node.type == CKEDITOR.NODE_ELEMENT ) {
+                                               if ( node.getAttribute( 'contentEditable' ) == 'false' && !node.data( 'cke-editable' ) )
+                                                       return 0;
+
+                                               // Range enclosed entirely in an editable element.
+                                               else if ( node.is( 'html' ) || node.getAttribute( 'contentEditable' ) == 'true' && ( node.contains( anotherEnd ) || node.equals( anotherEnd ) ) )
+                                                       break;
+
+                                       }
+                                       node = node.getParent();
+                               }
+
+                               return 1;
+                       }
+
+                       return function() {
+                               var startNode = this.startContainer,
+                                       endNode = this.endContainer;
+
+                               // Check if elements path at both boundaries are editable.
+                               return !( checkNodesEditable( startNode, endNode ) && checkNodesEditable( endNode, startNode ) );
+                       };
+               } )(),
+
+               /**
+                * Moves the range boundaries to the first/end editing point inside an
+                * element.
+                *
+                * For example, in an element tree like
+                * `<p><b><i></i></b> Text</p>`, the start editing point is
+                * `<p><b><i>^</i></b> Text</p>` (inside `<i>`).
+                *
+                * @param {CKEDITOR.dom.element} el The element into which look for the
+                * editing spot.
+                * @param {Boolean} isMoveToEnd Whether move to the end editable position.
+                * @returns {Boolean} Whether range was moved.
+                */
+               moveToElementEditablePosition: function( el, isMoveToEnd ) {
+
+                       function nextDFS( node, childOnly ) {
+                               var next;
+
+                               if ( node.type == CKEDITOR.NODE_ELEMENT && node.isEditable( false ) )
+                                       next = node[ isMoveToEnd ? 'getLast' : 'getFirst' ]( notIgnoredEval );
+
+                               if ( !childOnly && !next )
+                                       next = node[ isMoveToEnd ? 'getPrevious' : 'getNext' ]( notIgnoredEval );
+
+                               return next;
+                       }
+
+                       // Handle non-editable element e.g. HR.
+                       if ( el.type == CKEDITOR.NODE_ELEMENT && !el.isEditable( false ) ) {
+                               this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START );
+                               return true;
+                       }
+
+                       var found = 0;
+
+                       while ( el ) {
+                               // Stop immediately if we've found a text node.
+                               if ( el.type == CKEDITOR.NODE_TEXT ) {
+                                       // Put cursor before block filler.
+                                       if ( isMoveToEnd && this.endContainer && this.checkEndOfBlock() && nbspRegExp.test( el.getText() ) )
+                                               this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );
+                                       else
+                                               this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START );
+                                       found = 1;
+                                       break;
+                               }
+
+                               // If an editable element is found, move inside it, but not stop the searching.
+                               if ( el.type == CKEDITOR.NODE_ELEMENT ) {
+                                       if ( el.isEditable() ) {
+                                               this.moveToPosition( el, isMoveToEnd ? CKEDITOR.POSITION_BEFORE_END : CKEDITOR.POSITION_AFTER_START );
+                                               found = 1;
+                                       }
+                                       // Put cursor before padding block br.
+                                       else if ( isMoveToEnd && el.is( 'br' ) && this.endContainer && this.checkEndOfBlock() )
+                                               this.moveToPosition( el, CKEDITOR.POSITION_BEFORE_START );
+                                       // Special case - non-editable block. Select entire element, because it does not make sense
+                                       // to place collapsed selection next to it, because browsers can't handle that.
+                                       else if ( el.getAttribute( 'contenteditable' ) == 'false' && el.is( CKEDITOR.dtd.$block ) ) {
+                                               this.setStartBefore( el );
+                                               this.setEndAfter( el );
+                                               return true;
+                                       }
+                               }
+
+                               el = nextDFS( el, found );
+                       }
+
+                       return !!found;
+               },
+
+               /**
+                * Moves the range boundaries to the closest editing point after/before an
+                * element or the current range position (depends on whether the element was specified).
+                *
+                * For example, if the start element has `id="start"`,
+                * `<p><b>foo</b><span id="start">start</start></p>`, the closest previous editing point is
+                * `<p><b>foo</b>^<span id="start">start</start></p>` (between `<b>` and `<span>`).
+                *
+                * See also: {@link #moveToElementEditablePosition}.
+                *
+                * @since 4.3
+                * @param {CKEDITOR.dom.element} [element] The starting element. If not specified, the current range
+                * position will be used.
+                * @param {Boolean} [isMoveForward] Whether move to the end of editable. Otherwise, look back.
+                * @returns {Boolean} Whether the range was moved.
+                */
+               moveToClosestEditablePosition: function( element, isMoveForward ) {
+                       // We don't want to modify original range if there's no editable position.
+                       var range,
+                               found = 0,
+                               sibling,
+                               isElement,
+                               positions = [ CKEDITOR.POSITION_AFTER_END, CKEDITOR.POSITION_BEFORE_START ];
+
+                       if ( element ) {
+                               // Set collapsed range at one of ends of element.
+                               // Can't clone this range, because this range might not be yet positioned (no containers => errors).
+                               range = new CKEDITOR.dom.range( this.root );
+                               range.moveToPosition( element, positions[ isMoveForward ? 0 : 1 ] );
+                       } else {
+                               range = this.clone();
+                       }
+
+                       // Start element isn't a block, so we can automatically place range
+                       // next to it.
+                       if ( element && !element.is( CKEDITOR.dtd.$block ) )
+                               found = 1;
+                       else {
+                               // Look for first node that fulfills eval function and place range next to it.
+                               sibling = range[ isMoveForward ? 'getNextEditableNode' : 'getPreviousEditableNode' ]();
+                               if ( sibling ) {
+                                       found = 1;
+                                       isElement = sibling.type == CKEDITOR.NODE_ELEMENT;
+
+                                       // Special case - eval accepts block element only if it's a non-editable block,
+                                       // which we want to select, not place collapsed selection next to it (which browsers
+                                       // can't handle).
+                                       if ( isElement && sibling.is( CKEDITOR.dtd.$block ) && sibling.getAttribute( 'contenteditable' ) == 'false' ) {
+                                               range.setStartAt( sibling, CKEDITOR.POSITION_BEFORE_START );
+                                               range.setEndAt( sibling, CKEDITOR.POSITION_AFTER_END );
+                                       }
+                                       // Handle empty blocks which can be selection containers on old IEs.
+                                       else if ( !CKEDITOR.env.needsBrFiller && isElement && sibling.is( CKEDITOR.dom.walker.validEmptyBlockContainers ) ) {
+                                               range.setEnd( sibling, 0 );
+                                               range.collapse();
+                                       } else {
+                                               range.moveToPosition( sibling, positions[ isMoveForward ? 1 : 0 ] );
+                                       }
+                               }
+                       }
+
+                       if ( found )
+                               this.moveToRange( range );
+
+                       return !!found;
+               },
+
+               /**
+                * See {@link #moveToElementEditablePosition}.
+                *
+                * @returns {Boolean} Whether range was moved.
+                */
+               moveToElementEditStart: function( target ) {
+                       return this.moveToElementEditablePosition( target );
+               },
+
+               /**
+                * See {@link #moveToElementEditablePosition}.
+                *
+                * @returns {Boolean} Whether range was moved.
+                */
+               moveToElementEditEnd: function( target ) {
+                       return this.moveToElementEditablePosition( target, true );
+               },
+
+               /**
+                * Get the single node enclosed within the range if there's one.
+                *
+                * @returns {CKEDITOR.dom.node}
+                */
+               getEnclosedNode: function() {
+                       var walkerRange = this.clone();
+
+                       // Optimize and analyze the range to avoid DOM destructive nature of walker. (#5780)
+                       walkerRange.optimize();
+                       if ( walkerRange.startContainer.type != CKEDITOR.NODE_ELEMENT || walkerRange.endContainer.type != CKEDITOR.NODE_ELEMENT )
+                               return null;
+
+                       var walker = new CKEDITOR.dom.walker( walkerRange ),
+                               isNotBookmarks = CKEDITOR.dom.walker.bookmark( false, true ),
+                               isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true );
+
+                       walker.evaluator = function( node ) {
+                               return isNotWhitespaces( node ) && isNotBookmarks( node );
+                       };
+                       var node = walker.next();
+                       walker.reset();
+                       return node && node.equals( walker.previous() ) ? node : null;
+               },
+
+               /**
+                * Get the node adjacent to the range start or {@link #startContainer}.
+                *
+                * @returns {CKEDITOR.dom.node}
+                */
+               getTouchedStartNode: function() {
+                       var container = this.startContainer;
+
+                       if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
+                               return container;
+
+                       return container.getChild( this.startOffset ) || container;
+               },
+
+               /**
+                * Get the node adjacent to the range end or {@link #endContainer}.
+                *
+                * @returns {CKEDITOR.dom.node}
+                */
+               getTouchedEndNode: function() {
+                       var container = this.endContainer;
+
+                       if ( this.collapsed || container.type != CKEDITOR.NODE_ELEMENT )
+                               return container;
+
+                       return container.getChild( this.endOffset - 1 ) || container;
+               },
+
+               /**
+                * Gets next node which can be a container of a selection.
+                * This methods mimics a behavior of right/left arrow keys in case of
+                * collapsed selection. It does not return an exact position (with offset) though,
+                * but just a selection's container.
+                *
+                * Note: use this method on a collapsed range.
+                *
+                * @since 4.3
+                * @returns {CKEDITOR.dom.element/CKEDITOR.dom.text}
+                */
+               getNextEditableNode: getNextEditableNode(),
+
+               /**
+                * See {@link #getNextEditableNode}.
+                *
+                * @since 4.3
+                * @returns {CKEDITOR.dom.element/CKEDITOR.dom.text}
+                */
+               getPreviousEditableNode: getNextEditableNode( 1 ),
+
+               /**
+                * Scrolls the start of current range into view.
+                */
+               scrollIntoView: function() {
+
+                       // The reference element contains a zero-width space to avoid
+                       // a premature removal. The view is to be scrolled with respect
+                       // to this element.
+                       var reference = new CKEDITOR.dom.element.createFromHtml( '<span>&nbsp;</span>', this.document ),
+                               afterCaretNode, startContainerText, isStartText;
+
+                       var range = this.clone();
+
+                       // Work with the range to obtain a proper caret position.
+                       range.optimize();
+
+                       // Currently in a text node, so we need to split it into two
+                       // halves and put the reference between.
+                       if ( isStartText = range.startContainer.type == CKEDITOR.NODE_TEXT ) {
+                               // Keep the original content. It will be restored.
+                               startContainerText = range.startContainer.getText();
+
+                               // Split the startContainer at the this position.
+                               afterCaretNode = range.startContainer.split( range.startOffset );
+
+                               // Insert the reference between two text nodes.
+                               reference.insertAfter( range.startContainer );
+                       }
+
+                       // If not in a text node, simply insert the reference into the range.
+                       else {
+                               range.insertNode( reference );
+                       }
+
+                       // Scroll with respect to the reference element.
+                       reference.scrollIntoView();
+
+                       // Get rid of split parts if "in a text node" case.
+                       // Revert the original text of the startContainer.
+                       if ( isStartText ) {
+                               range.startContainer.setText( startContainerText );
+                               afterCaretNode.remove();
+                       }
+
+                       // Get rid of the reference node. It is no longer necessary.
+                       reference.remove();
+               },
+
+               /**
+                * Setter for the {@link #startContainer}.
+                *
+                * @since 4.4.6
+                * @private
+                * @param {CKEDITOR.dom.element} startContainer
+                */
+               _setStartContainer: function( startContainer ) {
+                       // %REMOVE_START%
+                       var isRootAscendantOrSelf = this.root.equals( startContainer ) || this.root.contains( startContainer );
+
+                       if ( !isRootAscendantOrSelf ) {
+                               CKEDITOR.warn( 'range-startcontainer', { startContainer: startContainer, root: this.root } );
+                       }
+                       // %REMOVE_END%
+                       this.startContainer = startContainer;
+               },
+
+               /**
+                * Setter for the {@link #endContainer}.
+                *
+                * @since 4.4.6
+                * @private
+                * @param {CKEDITOR.dom.element} endContainer
+                */
+               _setEndContainer: function( endContainer ) {
+                       // %REMOVE_START%
+                       var isRootAscendantOrSelf = this.root.equals( endContainer ) || this.root.contains( endContainer );
+
+                       if ( !isRootAscendantOrSelf ) {
+                               CKEDITOR.warn( 'range-endcontainer', { endContainer: endContainer, root: this.root } );
+                       }
+                       // %REMOVE_END%
+                       this.endContainer = endContainer;
+               },
+
+               /**
+                * Looks for elements matching the `query` selector within a range.
+                *
+                * @since 4.5.11
+                * @private
+                * @param {String} query
+                * @param {Boolean} [includeNonEditables=false] Whether elements with `contenteditable` set to `false` should
+                * be included.
+                * @returns {CKEDITOR.dom.element[]}
+                */
+               _find: function( query, includeNonEditables ) {
+                       var ancestor = this.getCommonAncestor(),
+                               boundaries = this.getBoundaryNodes(),
+                               // Contrary to CKEDITOR.dom.element#find we're returning array, that's because NodeList is immutable, and we need
+                               // to do some filtering in returned list.
+                               ret = [],
+                               curItem,
+                               i,
+                               initialMatches,
+                               isStartGood,
+                               isEndGood;
+
+                       if ( ancestor && ancestor.find ) {
+                               initialMatches = ancestor.find( query );
+
+                               for ( i = 0; i < initialMatches.count(); i++ ) {
+                                       curItem = initialMatches.getItem( i );
+
+                                       // Using isReadOnly() method to filterout non editables. It checks isContentEditable including all browser quirks.
+                                       if ( !includeNonEditables && curItem.isReadOnly() ) {
+                                               continue;
+                                       }
+
+                                       // It's not enough to get elements from common ancestor, because it migth contain too many matches.
+                                       // We need to ensure that returned items are between boundary points.
+                                       isStartGood = ( curItem.getPosition( boundaries.startNode ) & CKEDITOR.POSITION_FOLLOWING ) || boundaries.startNode.equals( curItem );
+                                       isEndGood = ( curItem.getPosition( boundaries.endNode ) & ( CKEDITOR.POSITION_PRECEDING + CKEDITOR.POSITION_IS_CONTAINED ) );
+
+                                       if ( isStartGood && isEndGood ) {
+                                               ret.push( curItem );
+                                       }
+                               }
+                       }
+
+                       return ret;
+               }
+       };
+
+
+} )();
+
+/**
+ * Indicates a position after start of a node.
+ *
+ *             // When used according to an element:
+ *             // <element>^contents</element>
+ *
+ *             // When used according to a text node:
+ *             // "^text" (range is anchored in the text node)
+ *
+ * It is used as a parameter of methods like: {@link CKEDITOR.dom.range#moveToPosition},
+ * {@link CKEDITOR.dom.range#setStartAt} and {@link CKEDITOR.dom.range#setEndAt}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=1]
+ */
+CKEDITOR.POSITION_AFTER_START = 1;
+
+/**
+ * Indicates a position before end of a node.
+ *
+ *             // When used according to an element:
+ *             // <element>contents^</element>
+ *
+ *             // When used according to a text node:
+ *             // "text^" (range is anchored in the text node)
+ *
+ * It is used as a parameter of methods like: {@link CKEDITOR.dom.range#moveToPosition},
+ * {@link CKEDITOR.dom.range#setStartAt} and {@link CKEDITOR.dom.range#setEndAt}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=2]
+ */
+CKEDITOR.POSITION_BEFORE_END = 2;
+
+/**
+ * Indicates a position before start of a node.
+ *
+ *             // When used according to an element:
+ *             // ^<element>contents</element> (range is anchored in element's parent)
+ *
+ *             // When used according to a text node:
+ *             // ^"text" (range is anchored in text node's parent)
+ *
+ * It is used as a parameter of methods like: {@link CKEDITOR.dom.range#moveToPosition},
+ * {@link CKEDITOR.dom.range#setStartAt} and {@link CKEDITOR.dom.range#setEndAt}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=3]
+ */
+CKEDITOR.POSITION_BEFORE_START = 3;
+
+/**
+ * Indicates a position after end of a node.
+ *
+ *             // When used according to an element:
+ *             // <element>contents</element>^ (range is anchored in element's parent)
+ *
+ *             // When used according to a text node:
+ *             // "text"^ (range is anchored in text node's parent)
+ *
+ * It is used as a parameter of methods like: {@link CKEDITOR.dom.range#moveToPosition},
+ * {@link CKEDITOR.dom.range#setStartAt} and {@link CKEDITOR.dom.range#setEndAt}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=4]
+ */
+CKEDITOR.POSITION_AFTER_END = 4;
+
+/**
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=1]
+ */
+CKEDITOR.ENLARGE_ELEMENT = 1;
+
+/**
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=2]
+ */
+CKEDITOR.ENLARGE_BLOCK_CONTENTS = 2;
+
+/**
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=3]
+ */
+CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS = 3;
+
+/**
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=4]
+ */
+CKEDITOR.ENLARGE_INLINE = 4;
+
+// Check boundary types.
+
+/**
+ * See {@link CKEDITOR.dom.range#checkBoundaryOfElement}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=1]
+ */
+CKEDITOR.START = 1;
+
+/**
+ * See {@link CKEDITOR.dom.range#checkBoundaryOfElement}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=2]
+ */
+CKEDITOR.END = 2;
+
+// Shrink range types.
+
+/**
+ * See {@link CKEDITOR.dom.range#shrink}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=1]
+ */
+CKEDITOR.SHRINK_ELEMENT = 1;
+
+/**
+ * See {@link CKEDITOR.dom.range#shrink}.
+ *
+ * @readonly
+ * @member CKEDITOR
+ * @property {Number} [=2]
+ */
+CKEDITOR.SHRINK_TEXT = 2;
diff --git a/sources/core/dom/rangelist.js b/sources/core/dom/rangelist.js
new file mode 100644 (file)
index 0000000..250dfd9
--- /dev/null
@@ -0,0 +1,199 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       /**
+        * Represents a list os CKEDITOR.dom.range objects, which can be easily
+        * iterated sequentially.
+        *
+        * @class
+        * @extends Array
+        * @constructor Creates a rangeList class instance.
+        * @param {CKEDITOR.dom.range/CKEDITOR.dom.range[]} [ranges] The ranges contained on this list.
+        * Note that, if an array of ranges is specified, the range sequence
+        * should match its DOM order. This class will not help to sort them.
+        */
+       CKEDITOR.dom.rangeList = function( ranges ) {
+               if ( ranges instanceof CKEDITOR.dom.rangeList )
+                       return ranges;
+
+               if ( !ranges )
+                       ranges = [];
+               else if ( ranges instanceof CKEDITOR.dom.range )
+                       ranges = [ ranges ];
+
+               return CKEDITOR.tools.extend( ranges, mixins );
+       };
+
+       var mixins = {
+               /**
+                * Creates an instance of the rangeList iterator, it should be used
+                * only when the ranges processing could be DOM intrusive, which
+                * means it may pollute and break other ranges in this list.
+                * Otherwise, it's enough to just iterate over this array in a for loop.
+                *
+                * @returns {CKEDITOR.dom.rangeListIterator}
+                */
+               createIterator: function() {
+                       var rangeList = this,
+                               bookmark = CKEDITOR.dom.walker.bookmark(),
+                               bookmarks = [],
+                               current;
+
+                       return {
+                               /**
+                                * Retrieves the next range in the list.
+                                *
+                                * @member CKEDITOR.dom.rangeListIterator
+                                * @param {Boolean} [mergeConsequent=false] Whether join two adjacent
+                                * ranges into single, e.g. consequent table cells.
+                                */
+                               getNextRange: function( mergeConsequent ) {
+                                       current = current === undefined ? 0 : current + 1;
+
+                                       var range = rangeList[ current ];
+
+                                       // Multiple ranges might be mangled by each other.
+                                       if ( range && rangeList.length > 1 ) {
+                                               // Bookmarking all other ranges on the first iteration,
+                                               // the range correctness after it doesn't matter since we'll
+                                               // restore them before the next iteration.
+                                               if ( !current ) {
+                                                       // Make sure bookmark correctness by reverse processing.
+                                                       for ( var i = rangeList.length - 1; i >= 0; i-- )
+                                                               bookmarks.unshift( rangeList[ i ].createBookmark( true ) );
+                                               }
+
+                                               if ( mergeConsequent ) {
+                                                       // Figure out how many ranges should be merged.
+                                                       var mergeCount = 0;
+                                                       while ( rangeList[ current + mergeCount + 1 ] ) {
+                                                               var doc = range.document,
+                                                                       found = 0,
+                                                                       left = doc.getById( bookmarks[ mergeCount ].endNode ),
+                                                                       right = doc.getById( bookmarks[ mergeCount + 1 ].startNode ),
+                                                                       next;
+
+                                                               // Check subsequent range.
+                                                               while ( 1 ) {
+                                                                       next = left.getNextSourceNode( false );
+                                                                       if ( !right.equals( next ) ) {
+                                                                               // This could be yet another bookmark or
+                                                                               // walking across block boundaries.
+                                                                               if ( bookmark( next ) || ( next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() ) ) {
+                                                                                       left = next;
+                                                                                       continue;
+                                                                               }
+                                                                       } else {
+                                                                               found = 1;
+                                                                       }
+
+                                                                       break;
+                                                               }
+
+                                                               if ( !found )
+                                                                       break;
+
+                                                               mergeCount++;
+                                                       }
+                                               }
+
+                                               range.moveToBookmark( bookmarks.shift() );
+
+                                               // Merge ranges finally after moving to bookmarks.
+                                               while ( mergeCount-- ) {
+                                                       next = rangeList[ ++current ];
+                                                       next.moveToBookmark( bookmarks.shift() );
+                                                       range.setEnd( next.endContainer, next.endOffset );
+                                               }
+                                       }
+
+                                       return range;
+                               }
+                       };
+               },
+
+               /**
+                * Create bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark}.
+                *
+                * @param {Boolean} [serializable=false] See {@link CKEDITOR.dom.range#createBookmark}.
+                * @returns {Array} Array of bookmarks.
+                */
+               createBookmarks: function( serializable ) {
+                       var retval = [],
+                               bookmark;
+                       for ( var i = 0; i < this.length; i++ ) {
+                               retval.push( bookmark = this[ i ].createBookmark( serializable, true ) );
+
+                               // Updating the container & offset values for ranges
+                               // that have been touched.
+                               for ( var j = i + 1; j < this.length; j++ ) {
+                                       this[ j ] = updateDirtyRange( bookmark, this[ j ] );
+                                       this[ j ] = updateDirtyRange( bookmark, this[ j ], true );
+                               }
+                       }
+                       return retval;
+               },
+
+               /**
+                * Create "unobtrusive" bookmarks for all ranges. See {@link CKEDITOR.dom.range#createBookmark2}.
+                *
+                * @param {Boolean} [normalized=false] See {@link CKEDITOR.dom.range#createBookmark2}.
+                * @returns {Array} Array of bookmarks.
+                */
+               createBookmarks2: function( normalized ) {
+                       var bookmarks = [];
+
+                       for ( var i = 0; i < this.length; i++ )
+                               bookmarks.push( this[ i ].createBookmark2( normalized ) );
+
+                       return bookmarks;
+               },
+
+               /**
+                * Move each range in the list to the position specified by a list of bookmarks.
+                *
+                * @param {Array} bookmarks The list of bookmarks, each one matching a range in the list.
+                */
+               moveToBookmarks: function( bookmarks ) {
+                       for ( var i = 0; i < this.length; i++ )
+                               this[ i ].moveToBookmark( bookmarks[ i ] );
+               }
+       };
+
+       // Update the specified range which has been mangled by previous insertion of
+       // range bookmark nodes.(#3256)
+       function updateDirtyRange( bookmark, dirtyRange, checkEnd ) {
+               var serializable = bookmark.serializable,
+                       container = dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ],
+                       offset = checkEnd ? 'endOffset' : 'startOffset';
+
+               var bookmarkStart = serializable ? dirtyRange.document.getById( bookmark.startNode ) : bookmark.startNode;
+
+               var bookmarkEnd = serializable ? dirtyRange.document.getById( bookmark.endNode ) : bookmark.endNode;
+
+               if ( container.equals( bookmarkStart.getPrevious() ) ) {
+                       dirtyRange.startOffset = dirtyRange.startOffset - container.getLength() - bookmarkEnd.getPrevious().getLength();
+                       container = bookmarkEnd.getNext();
+               } else if ( container.equals( bookmarkEnd.getPrevious() ) ) {
+                       dirtyRange.startOffset = dirtyRange.startOffset - container.getLength();
+                       container = bookmarkEnd.getNext();
+               }
+
+               container.equals( bookmarkStart.getParent() ) && dirtyRange[ offset ]++;
+               container.equals( bookmarkEnd.getParent() ) && dirtyRange[ offset ]++;
+
+               // Update and return this range.
+               dirtyRange[ checkEnd ? 'endContainer' : 'startContainer' ] = container;
+               return dirtyRange;
+       }
+} )();
+
+/**
+ * (Virtual Class) Do not call this constructor. This class is not really part
+ * of the API. It just describes the return type of {@link CKEDITOR.dom.rangeList#createIterator}.
+ *
+ * @class CKEDITOR.dom.rangeListIterator
+ */
diff --git a/sources/core/dom/text.js b/sources/core/dom/text.js
new file mode 100644 (file)
index 0000000..ce20ffe
--- /dev/null
@@ -0,0 +1,135 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.text} class, which represents
+ *             a DOM text node.
+ */
+
+/**
+ * Represents a DOM text node.
+ *
+ *             var nativeNode = document.createTextNode( 'Example' );
+ *             var text = new CKEDITOR.dom.text( nativeNode );
+ *
+ *             var text = new CKEDITOR.dom.text( 'Example' );
+ *
+ * @class
+ * @extends CKEDITOR.dom.node
+ * @constructor Creates a text class instance.
+ * @param {Object/String} text A native DOM text node or a string containing
+ * the text to use to create a new text node.
+ * @param {CKEDITOR.dom.document} [ownerDocument] The document that will contain
+ * the node in case of new node creation. Defaults to the current document.
+ */
+CKEDITOR.dom.text = function( text, ownerDocument ) {
+       if ( typeof text == 'string' )
+               text = ( ownerDocument ? ownerDocument.$ : document ).createTextNode( text );
+
+       // Theoretically, we should call the base constructor here
+       // (not CKEDITOR.dom.node though). But, IE doesn't support expando
+       // properties on text node, so the features provided by domObject will not
+       // work for text nodes (which is not a big issue for us).
+       //
+       // CKEDITOR.dom.domObject.call( this, element );
+
+       this.$ = text;
+};
+
+CKEDITOR.dom.text.prototype = new CKEDITOR.dom.node();
+
+CKEDITOR.tools.extend( CKEDITOR.dom.text.prototype, {
+       /**
+        * The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
+        *
+        * @readonly
+        * @property {Number} [=CKEDITOR.NODE_TEXT]
+        */
+       type: CKEDITOR.NODE_TEXT,
+
+       /**
+        * Gets length of node's value.
+        *
+        * @returns {Number}
+        */
+       getLength: function() {
+               return this.$.nodeValue.length;
+       },
+
+       /**
+        * Gets node's value.
+        *
+        * @returns {String}
+        */
+       getText: function() {
+               return this.$.nodeValue;
+       },
+
+       /**
+        * Sets node's value.
+        *
+        * @param {String} text
+        */
+       setText: function( text ) {
+               this.$.nodeValue = text;
+       },
+
+       /**
+        * Breaks this text node into two nodes at the specified offset,
+        * keeping both in the tree as siblings. This node then only contains
+        * all the content up to the offset point. A new text node, which is
+        * inserted as the next sibling of this node, contains all the content
+        * at and after the offset point. When the offset is equal to the
+        * length of this node, the new node has no data.
+        *
+        * @param {Number} The position at which to split, starting from zero.
+        * @returns {CKEDITOR.dom.text} The new text node.
+        */
+       split: function( offset ) {
+
+               // Saved the children count and text length beforehand.
+               var parent = this.$.parentNode,
+                       count = parent.childNodes.length,
+                       length = this.getLength();
+
+               var doc = this.getDocument();
+               var retval = new CKEDITOR.dom.text( this.$.splitText( offset ), doc );
+
+               if ( parent.childNodes.length == count ) {
+                       // If the offset is after the last char, IE creates the text node
+                       // on split, but don't include it into the DOM. So, we have to do
+                       // that manually here.
+                       if ( offset >= length ) {
+                               retval = doc.createText( '' );
+                               retval.insertAfter( this );
+                       } else {
+                               // IE BUG: IE8+ does not update the childNodes array in DOM after splitText(),
+                               // we need to make some DOM changes to make it update. (#3436)
+                               var workaround = doc.createText( '' );
+                               workaround.insertAfter( retval );
+                               workaround.remove();
+                       }
+               }
+
+               return retval;
+       },
+
+       /**
+        * Extracts characters from indexA up to but not including `indexB`.
+        *
+        * @param {Number} indexA An integer between `0` and one less than the
+        * length of the text.
+        * @param {Number} [indexB] An integer between `0` and the length of the
+        * string. If omitted, extracts characters to the end of the text.
+        */
+       substring: function( indexA, indexB ) {
+               // We need the following check due to a Firefox bug
+               // https://bugzilla.mozilla.org/show_bug.cgi?id=458886
+               if ( typeof indexB != 'number' )
+                       return this.$.nodeValue.substr( indexA );
+               else
+                       return this.$.nodeValue.substring( indexA, indexB );
+       }
+} );
diff --git a/sources/core/dom/walker.js b/sources/core/dom/walker.js
new file mode 100644 (file)
index 0000000..cec4574
--- /dev/null
@@ -0,0 +1,652 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       // This function is to be called under a "walker" instance scope.
+       function iterate( rtl, breakOnFalse ) {
+               var range = this.range;
+
+               // Return null if we have reached the end.
+               if ( this._.end )
+                       return null;
+
+               // This is the first call. Initialize it.
+               if ( !this._.start ) {
+                       this._.start = 1;
+
+                       // A collapsed range must return null at first call.
+                       if ( range.collapsed ) {
+                               this.end();
+                               return null;
+                       }
+
+                       // Move outside of text node edges.
+                       range.optimize();
+               }
+
+               var node,
+                       startCt = range.startContainer,
+                       endCt = range.endContainer,
+                       startOffset = range.startOffset,
+                       endOffset = range.endOffset,
+                       guard,
+                       userGuard = this.guard,
+                       type = this.type,
+                       getSourceNodeFn = ( rtl ? 'getPreviousSourceNode' : 'getNextSourceNode' );
+
+               // Create the LTR guard function, if necessary.
+               if ( !rtl && !this._.guardLTR ) {
+                       // The node that stops walker from moving up.
+                       var limitLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt : endCt.getParent();
+
+                       // The node that stops the walker from going to next.
+                       var blockerLTR = endCt.type == CKEDITOR.NODE_ELEMENT ? endCt.getChild( endOffset ) : endCt.getNext();
+
+                       this._.guardLTR = function( node, movingOut ) {
+                               return ( ( !movingOut || !limitLTR.equals( node ) ) && ( !blockerLTR || !node.equals( blockerLTR ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
+                       };
+               }
+
+               // Create the RTL guard function, if necessary.
+               if ( rtl && !this._.guardRTL ) {
+                       // The node that stops walker from moving up.
+                       var limitRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startCt : startCt.getParent();
+
+                       // The node that stops the walker from going to next.
+                       var blockerRTL = startCt.type == CKEDITOR.NODE_ELEMENT ? startOffset ? startCt.getChild( startOffset - 1 ) : null : startCt.getPrevious();
+
+                       this._.guardRTL = function( node, movingOut ) {
+                               return ( ( !movingOut || !limitRTL.equals( node ) ) && ( !blockerRTL || !node.equals( blockerRTL ) ) && ( node.type != CKEDITOR.NODE_ELEMENT || !movingOut || !node.equals( range.root ) ) );
+                       };
+               }
+
+               // Define which guard function to use.
+               var stopGuard = rtl ? this._.guardRTL : this._.guardLTR;
+
+               // Make the user defined guard function participate in the process,
+               // otherwise simply use the boundary guard.
+               if ( userGuard ) {
+                       guard = function( node, movingOut ) {
+                               if ( stopGuard( node, movingOut ) === false )
+                                       return false;
+
+                               return userGuard( node, movingOut );
+                       };
+               } else {
+                       guard = stopGuard;
+               }
+
+               if ( this.current )
+                       node = this.current[ getSourceNodeFn ]( false, type, guard );
+               else {
+                       // Get the first node to be returned.
+                       if ( rtl ) {
+                               node = endCt;
+
+                               if ( node.type == CKEDITOR.NODE_ELEMENT ) {
+                                       if ( endOffset > 0 )
+                                               node = node.getChild( endOffset - 1 );
+                                       else
+                                               node = ( guard( node, true ) === false ) ? null : node.getPreviousSourceNode( true, type, guard );
+                               }
+                       } else {
+                               node = startCt;
+
+                               if ( node.type == CKEDITOR.NODE_ELEMENT ) {
+                                       if ( !( node = node.getChild( startOffset ) ) )
+                                               node = ( guard( startCt, true ) === false ) ? null : startCt.getNextSourceNode( true, type, guard );
+                               }
+                       }
+
+                       if ( node && guard( node ) === false )
+                               node = null;
+               }
+
+               while ( node && !this._.end ) {
+                       this.current = node;
+
+                       if ( !this.evaluator || this.evaluator( node ) !== false ) {
+                               if ( !breakOnFalse )
+                                       return node;
+                       } else if ( breakOnFalse && this.evaluator ) {
+                               return false;
+                       }
+
+                       node = node[ getSourceNodeFn ]( false, type, guard );
+               }
+
+               this.end();
+               return this.current = null;
+       }
+
+       function iterateToLast( rtl ) {
+               var node,
+                       last = null;
+
+               while ( ( node = iterate.call( this, rtl ) ) )
+                       last = node;
+
+               return last;
+       }
+
+       /**
+        * Utility class to "walk" the DOM inside range boundaries. If the
+        * range starts or ends in the middle of the text node, this node will
+        * be included as a whole. Outside changes to the range may break the walker.
+        *
+        * The walker may return nodes that are not totally included in the
+        * range boundaries. Let us take the following range representation,
+        * where the square brackets indicate the boundaries:
+        *
+        *              [<p>Some <b>sample] text</b>
+        *
+        * While walking forward into the above range, the following nodes are
+        * returned: `<p>`, `"Some "`, `<b>` and `"sample"`. Going
+        * backwards instead we have: `"sample"` and `"Some "`. So note that the
+        * walker always returns nodes when "entering" them, but not when
+        * "leaving" them. The {@link #guard} function is instead called both when
+        * entering and when leaving nodes.
+        *
+        * @class
+        */
+       CKEDITOR.dom.walker = CKEDITOR.tools.createClass( {
+               /**
+                * Creates a walker class instance.
+                *
+                * @constructor
+                * @param {CKEDITOR.dom.range} range The range within which to walk.
+                */
+               $: function( range ) {
+                       this.range = range;
+
+                       /**
+                        * A function executed for every matched node to check whether
+                        * it is to be considered in the walk or not. If not provided, all
+                        * matched nodes are considered good.
+                        *
+                        * If the function returns `false`, the node is ignored.
+                        *
+                        * @property {Function} evaluator
+                        */
+                       // this.evaluator = null;
+
+                       /**
+                        * A function executed for every node the walk passes by to check
+                        * whether the walk is to be finished. It is called both when
+                        * entering and when exiting nodes, as well as for the matched nodes.
+                        *
+                        * If this function returns `false`, the walking ends and no more
+                        * nodes are evaluated.
+
+                        * @property {Function} guard
+                        */
+                       // this.guard = null;
+
+                       /** @private */
+                       this._ = {};
+               },
+
+               //              statics :
+               //              {
+               //                      /* Creates a CKEDITOR.dom.walker instance to walk inside DOM boundaries set by nodes.
+               //                       * @param {CKEDITOR.dom.node} startNode The node from which the walk
+               //                       *              will start.
+               //                       * @param {CKEDITOR.dom.node} [endNode] The last node to be considered
+               //                       *              in the walk. No more nodes are retrieved after touching or
+               //                       *              passing it. If not provided, the walker stops at the
+               //                       *              &lt;body&gt; closing boundary.
+               //                       * @returns {CKEDITOR.dom.walker} A DOM walker for the nodes between the
+               //                       *              provided nodes.
+               //                       */
+               //                      createOnNodes : function( startNode, endNode, startInclusive, endInclusive )
+               //                      {
+               //                              var range = new CKEDITOR.dom.range();
+               //                              if ( startNode )
+               //                                      range.setStartAt( startNode, startInclusive ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_END ) ;
+               //                              else
+               //                                      range.setStartAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_AFTER_START ) ;
+               //
+               //                              if ( endNode )
+               //                                      range.setEndAt( endNode, endInclusive ? CKEDITOR.POSITION_AFTER_END : CKEDITOR.POSITION_BEFORE_START ) ;
+               //                              else
+               //                                      range.setEndAt( startNode.getDocument().getBody(), CKEDITOR.POSITION_BEFORE_END ) ;
+               //
+               //                              return new CKEDITOR.dom.walker( range );
+               //                      }
+               //              },
+               //
+               proto: {
+                       /**
+                        * Stops walking. No more nodes are retrieved if this function is called.
+                        */
+                       end: function() {
+                               this._.end = 1;
+                       },
+
+                       /**
+                        * Retrieves the next node (on the right).
+                        *
+                        * @returns {CKEDITOR.dom.node} The next node or `null` if no more
+                        * nodes are available.
+                        */
+                       next: function() {
+                               return iterate.call( this );
+                       },
+
+                       /**
+                        * Retrieves the previous node (on the left).
+                        *
+                        * @returns {CKEDITOR.dom.node} The previous node or `null` if no more
+                        * nodes are available.
+                        */
+                       previous: function() {
+                               return iterate.call( this, 1 );
+                       },
+
+                       /**
+                        * Checks all nodes on the right, executing the evaluation function.
+                        *
+                        * @returns {Boolean} `false` if the evaluator function returned
+                        * `false` for any of the matched nodes. Otherwise `true`.
+                        */
+                       checkForward: function() {
+                               return iterate.call( this, 0, 1 ) !== false;
+                       },
+
+                       /**
+                        * Check all nodes on the left, executing the evaluation function.
+                        *
+                        * @returns {Boolean} `false` if the evaluator function returned
+                        * `false` for any of the matched nodes. Otherwise `true`.
+                        */
+                       checkBackward: function() {
+                               return iterate.call( this, 1, 1 ) !== false;
+                       },
+
+                       /**
+                        * Executes a full walk forward (to the right), until no more nodes
+                        * are available, returning the last valid node.
+                        *
+                        * @returns {CKEDITOR.dom.node} The last node on the right or `null`
+                        * if no valid nodes are available.
+                        */
+                       lastForward: function() {
+                               return iterateToLast.call( this );
+                       },
+
+                       /**
+                        * Executes a full walk backwards (to the left), until no more nodes
+                        * are available, returning the last valid node.
+                        *
+                        * @returns {CKEDITOR.dom.node} The last node on the left or `null`
+                        * if no valid nodes are available.
+                        */
+                       lastBackward: function() {
+                               return iterateToLast.call( this, 1 );
+                       },
+
+                       /**
+                        * Resets the walker.
+                        */
+                       reset: function() {
+                               delete this.current;
+                               this._ = {};
+                       }
+
+               }
+       } );
+
+       // Anything whose display computed style is block, list-item, table,
+       // table-row-group, table-header-group, table-footer-group, table-row,
+       // table-column-group, table-column, table-cell, table-caption, or whose node
+       // name is hr, br (when enterMode is br only) is a block boundary.
+       var blockBoundaryDisplayMatch = {
+                       block: 1, 'list-item': 1, table: 1, 'table-row-group': 1,
+                       'table-header-group': 1, 'table-footer-group': 1, 'table-row': 1, 'table-column-group': 1,
+                       'table-column': 1, 'table-cell': 1, 'table-caption': 1
+               },
+               outOfFlowPositions = { absolute: 1, fixed: 1 };
+
+       /**
+        * Checks whether an element is displayed as a block.
+        *
+        * @member CKEDITOR.dom.element
+        * @param [customNodeNames] Custom list of nodes which will extend
+        * the default {@link CKEDITOR.dtd#$block} list.
+        * @returns {Boolean}
+        */
+       CKEDITOR.dom.element.prototype.isBlockBoundary = function( customNodeNames ) {
+               // Whether element is in normal page flow. Floated or positioned elements are out of page flow.
+               // Don't consider floated or positioned formatting as block boundary, fall back to dtd check in that case. (#6297)
+               var inPageFlow = this.getComputedStyle( 'float' ) == 'none' && !( this.getComputedStyle( 'position' ) in outOfFlowPositions );
+
+               if ( inPageFlow && blockBoundaryDisplayMatch[ this.getComputedStyle( 'display' ) ] )
+                       return true;
+
+               // Either in $block or in customNodeNames if defined.
+               return !!( this.is( CKEDITOR.dtd.$block ) || customNodeNames && this.is( customNodeNames ) );
+       };
+
+       /**
+        * Returns a function which checks whether the node is a block boundary.
+        * See {@link CKEDITOR.dom.element#isBlockBoundary}.
+        *
+        * @static
+        * @param customNodeNames
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.blockBoundary = function( customNodeNames ) {
+               return function( node ) {
+                       return !( node.type == CKEDITOR.NODE_ELEMENT && node.isBlockBoundary( customNodeNames ) );
+               };
+       };
+
+       /**
+        * @static
+        * @todo
+        */
+       CKEDITOR.dom.walker.listItemBoundary = function() {
+               return this.blockBoundary( { br: 1 } );
+       };
+
+       /**
+        * Returns a function which checks whether the node is a bookmark node or the bookmark node
+        * inner content.
+        *
+        * @static
+        * @param {Boolean} [contentOnly=false] Whether only test against the text content of
+        * a bookmark node instead of the element itself (default).
+        * @param {Boolean} [isReject=false] Whether to return `false` for the bookmark
+        * node instead of `true` (default).
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject ) {
+               function isBookmarkNode( node ) {
+                       return ( node && node.getName && node.getName() == 'span' && node.data( 'cke-bookmark' ) );
+               }
+
+               return function( node ) {
+                       var isBookmark, parent;
+                       // Is bookmark inner text node?
+                       isBookmark = ( node && node.type != CKEDITOR.NODE_ELEMENT && ( parent = node.getParent() ) && isBookmarkNode( parent ) );
+                       // Is bookmark node?
+                       isBookmark = contentOnly ? isBookmark : isBookmark || isBookmarkNode( node );
+                       return !!( isReject ^ isBookmark );
+               };
+       };
+
+       /**
+        * Returns a function which checks whether the node is a text node containing only whitespace characters.
+        *
+        * @static
+        * @param {Boolean} [isReject=false]
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.whitespaces = function( isReject ) {
+               return function( node ) {
+                       var isWhitespace;
+                       if ( node && node.type == CKEDITOR.NODE_TEXT ) {
+                               // Whitespace, as well as the Filling Char Sequence text node used in Webkit. (#9384, #13816)
+                               isWhitespace = !CKEDITOR.tools.trim( node.getText() ) ||
+                                       CKEDITOR.env.webkit && node.getText() == CKEDITOR.dom.selection.FILLING_CHAR_SEQUENCE;
+                       }
+
+                       return !!( isReject ^ isWhitespace );
+               };
+       };
+
+       /**
+        * Returns a function which checks whether the node is invisible in the WYSIWYG mode.
+        *
+        * @static
+        * @param {Boolean} [isReject=false]
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.invisible = function( isReject ) {
+               var whitespace = CKEDITOR.dom.walker.whitespaces(),
+                       // #12221 (Chrome) plus #11111 (Safari).
+                       offsetWidth0 = CKEDITOR.env.webkit ? 1 : 0;
+
+               return function( node ) {
+                       var invisible;
+
+                       if ( whitespace( node ) )
+                               invisible = 1;
+                       else {
+                               // Visibility should be checked on element.
+                               if ( node.type == CKEDITOR.NODE_TEXT )
+                                       node = node.getParent();
+
+                               // Nodes that take no spaces in wysiwyg:
+                               // 1. White-spaces but not including NBSP.
+                               // 2. Empty inline elements, e.g. <b></b>.
+                               // 3. <br> elements (bogus, surrounded by text) (#12423).
+                               invisible = node.$.offsetWidth <= offsetWidth0;
+                       }
+
+                       return !!( isReject ^ invisible );
+               };
+       };
+
+       /**
+        * Returns a function which checks whether the node type is equal to the passed one.
+        *
+        * @static
+        * @param {Number} type
+        * @param {Boolean} [isReject=false]
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.nodeType = function( type, isReject ) {
+               return function( node ) {
+                       return !!( isReject ^ ( node.type == type ) );
+               };
+       };
+
+       /**
+        * Returns a function which checks whether the node is a bogus (filler) node from
+        * `contenteditable` element's point of view.
+        *
+        * @static
+        * @param {Boolean} [isReject=false]
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.bogus = function( isReject ) {
+               function nonEmpty( node ) {
+                       return !isWhitespaces( node ) && !isBookmark( node );
+               }
+
+               return function( node ) {
+                       var isBogus = CKEDITOR.env.needsBrFiller ? node.is && node.is( 'br' ) : node.getText && tailNbspRegex.test( node.getText() );
+
+                       if ( isBogus ) {
+                               var parent = node.getParent(),
+                                       next = node.getNext( nonEmpty );
+
+                               isBogus = parent.isBlockBoundary() && ( !next || next.type == CKEDITOR.NODE_ELEMENT && next.isBlockBoundary() );
+                       }
+
+                       return !!( isReject ^ isBogus );
+               };
+       };
+
+       /**
+        * Returns a function which checks whether the node is a temporary element
+        * (element with the `data-cke-temp` attribute) or its child.
+        *
+        * @since 4.3
+        * @static
+        * @param {Boolean} [isReject=false] Whether to return `false` for the
+        * temporary element instead of `true` (default).
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.temp = function( isReject ) {
+               return function( node ) {
+                       if ( node.type != CKEDITOR.NODE_ELEMENT )
+                               node = node.getParent();
+
+                       var isTemp = node && node.hasAttribute( 'data-cke-temp' );
+
+                       return !!( isReject ^ isTemp );
+               };
+       };
+
+       var tailNbspRegex = /^[\t\r\n ]*(?:&nbsp;|\xa0)$/,
+               isWhitespaces = CKEDITOR.dom.walker.whitespaces(),
+               isBookmark = CKEDITOR.dom.walker.bookmark(),
+               isTemp = CKEDITOR.dom.walker.temp(),
+               toSkip = function( node ) {
+                       return isBookmark( node ) ||
+                               isWhitespaces( node ) ||
+                               node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$inline ) && !node.is( CKEDITOR.dtd.$empty );
+               };
+
+       /**
+        * Returns a function which checks whether the node should be ignored in terms of "editability".
+        *
+        * This includes:
+        *
+        * * whitespaces (see {@link CKEDITOR.dom.walker#whitespaces}),
+        * * bookmarks (see {@link CKEDITOR.dom.walker#bookmark}),
+        * * temporary elements (see {@link CKEDITOR.dom.walker#temp}).
+        *
+        * @since 4.3
+        * @static
+        * @param {Boolean} [isReject=false] Whether to return `false` for the
+        * ignored element instead of `true` (default).
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.ignored = function( isReject ) {
+               return function( node ) {
+                       var isIgnored = isWhitespaces( node ) || isBookmark( node ) || isTemp( node );
+
+                       return !!( isReject ^ isIgnored );
+               };
+       };
+
+       var isIgnored = CKEDITOR.dom.walker.ignored();
+
+       /**
+        * Returns a function which checks whether the node is empty.
+        *
+        * @since 4.5
+        * @static
+        * @param {Boolean} [isReject=false] Whether to return `false` for the
+        * ignored element instead of `true` (default).
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.empty = function( isReject ) {
+               return function( node ) {
+                       var i = 0,
+                               l = node.getChildCount();
+
+                       for ( ; i < l; ++i ) {
+                               if ( !isIgnored( node.getChild( i ) ) ) {
+                                       return !!isReject;
+                               }
+                       }
+
+                       return !isReject;
+               };
+       };
+
+       var isEmpty = CKEDITOR.dom.walker.empty();
+
+       function filterTextContainers( dtd ) {
+               var hash = {},
+                       name;
+
+               for ( name in dtd ) {
+                       if ( CKEDITOR.dtd[ name ][ '#' ] )
+                               hash[ name ] = 1;
+               }
+               return hash;
+       }
+
+       /**
+        * A hash of element names which in browsers that {@link CKEDITOR.env#needsBrFiller do not need `<br>` fillers}
+        * can be selection containers despite being empty.
+        *
+        * @since 4.5
+        * @static
+        * @property {Object} validEmptyBlockContainers
+        */
+       var validEmptyBlocks = CKEDITOR.dom.walker.validEmptyBlockContainers = CKEDITOR.tools.extend(
+               filterTextContainers( CKEDITOR.dtd.$block ),
+               { caption: 1, td: 1, th: 1 }
+       );
+
+       function isEditable( node ) {
+               // Skip temporary elements, bookmarks and whitespaces.
+               if ( isIgnored( node ) )
+                       return false;
+
+               if ( node.type == CKEDITOR.NODE_TEXT )
+                       return true;
+
+               if ( node.type == CKEDITOR.NODE_ELEMENT ) {
+                       // All inline and non-editable elements are valid editable places.
+                       // Note: the <hr> is currently the only element in CKEDITOR.dtd.$empty and CKEDITOR.dtd.$block,
+                       // but generally speaking we need an intersection of these two sets.
+                       // Note: non-editable block has to be treated differently (should be selected entirely).
+                       if ( node.is( CKEDITOR.dtd.$inline ) || node.is( 'hr' ) || node.getAttribute( 'contenteditable' ) == 'false' )
+                               return true;
+
+                       // Empty blocks are editable on IE.
+                       if ( !CKEDITOR.env.needsBrFiller && node.is( validEmptyBlocks ) && isEmpty( node ) )
+                               return true;
+               }
+
+               // Skip all other nodes.
+               return false;
+       }
+
+       /**
+        * Returns a function which checks whether the node can be a container or a sibling
+        * of the selection end.
+        *
+        * This includes:
+        *
+        * * text nodes (but not whitespaces),
+        * * inline elements,
+        * * intersection of {@link CKEDITOR.dtd#$empty} and {@link CKEDITOR.dtd#$block} (currently
+        * it is only `<hr>`),
+        * * non-editable blocks (special case &mdash; such blocks cannot be containers nor
+        * siblings, they need to be selected entirely),
+        * * empty {@link #validEmptyBlockContainers blocks} which can contain text
+        * ({@link CKEDITOR.env#needsBrFiller old IEs only}).
+        *
+        * @since 4.3
+        * @static
+        * @param {Boolean} [isReject=false] Whether to return `false` for the
+        * ignored element instead of `true` (default).
+        * @returns {Function}
+        */
+       CKEDITOR.dom.walker.editable = function( isReject ) {
+               return function( node ) {
+                       return !!( isReject ^ isEditable( node ) );
+               };
+       };
+
+       /**
+        * Checks if there is a filler node at the end of an element, and returns it.
+        *
+        * @member CKEDITOR.dom.element
+        * @returns {CKEDITOR.dom.node/Boolean} Bogus node or `false`.
+        */
+       CKEDITOR.dom.element.prototype.getBogus = function() {
+               // Bogus are not always at the end, e.g. <p><a>text<br /></a></p> (#7070).
+               var tail = this;
+               do {
+                       tail = tail.getPreviousSourceNode();
+               }
+               while ( toSkip( tail ) );
+
+               if ( tail && ( CKEDITOR.env.needsBrFiller ? tail.is && tail.is( 'br' ) : tail.getText && tailNbspRegex.test( tail.getText() ) ) )
+                       return tail;
+
+               return false;
+       };
+
+} )();
diff --git a/sources/core/dom/window.js b/sources/core/dom/window.js
new file mode 100644 (file)
index 0000000..ceeaeff
--- /dev/null
@@ -0,0 +1,95 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dom.document} class, which
+ *             represents a DOM document.
+ */
+
+/**
+ * Represents a DOM window.
+ *
+ *             var document = new CKEDITOR.dom.window( window );
+ *
+ * @class
+ * @extends CKEDITOR.dom.domObject
+ * @constructor Creates a window class instance.
+ * @param {Object} domWindow A native DOM window.
+ */
+CKEDITOR.dom.window = function( domWindow ) {
+       CKEDITOR.dom.domObject.call( this, domWindow );
+};
+
+CKEDITOR.dom.window.prototype = new CKEDITOR.dom.domObject();
+
+CKEDITOR.tools.extend( CKEDITOR.dom.window.prototype, {
+       /**
+        * Moves the selection focus to this window.
+        *
+        *              var win = new CKEDITOR.dom.window( window );
+        *              win.focus();
+        */
+       focus: function() {
+               this.$.focus();
+       },
+
+       /**
+        * Gets the width and height of this window's viewable area.
+        *
+        *              var win = new CKEDITOR.dom.window( window );
+        *              var size = win.getViewPaneSize();
+        *              alert( size.width );
+        *              alert( size.height );
+        *
+        * @returns {Object} An object with the `width` and `height`
+        * properties containing the size.
+        */
+       getViewPaneSize: function() {
+               var doc = this.$.document,
+                       stdMode = doc.compatMode == 'CSS1Compat';
+               return {
+                       width: ( stdMode ? doc.documentElement.clientWidth : doc.body.clientWidth ) || 0,
+                       height: ( stdMode ? doc.documentElement.clientHeight : doc.body.clientHeight ) || 0
+               };
+       },
+
+       /**
+        * Gets the current position of the window's scroll.
+        *
+        *              var win = new CKEDITOR.dom.window( window );
+        *              var pos = win.getScrollPosition();
+        *              alert( pos.x );
+        *              alert( pos.y );
+        *
+        * @returns {Object} An object with the `x` and `y` properties
+        * containing the scroll position.
+        */
+       getScrollPosition: function() {
+               var $ = this.$;
+
+               if ( 'pageXOffset' in $ ) {
+                       return {
+                               x: $.pageXOffset || 0,
+                               y: $.pageYOffset || 0
+                       };
+               } else {
+                       var doc = $.document;
+                       return {
+                               x: doc.documentElement.scrollLeft || doc.body.scrollLeft || 0,
+                               y: doc.documentElement.scrollTop || doc.body.scrollTop || 0
+                       };
+               }
+       },
+
+       /**
+        * Gets the frame element containing this window context.
+        *
+        * @returns {CKEDITOR.dom.element} The frame element or `null` if not in a frame context.
+        */
+       getFrame: function() {
+               var iframe = this.$.frameElement;
+               return iframe ? new CKEDITOR.dom.element.get( iframe ) : null;
+       }
+} );
diff --git a/sources/core/dtd.js b/sources/core/dtd.js
new file mode 100644 (file)
index 0000000..6059d48
--- /dev/null
@@ -0,0 +1,349 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.dtd} object, which holds the DTD
+ *             mapping for XHTML 1.0 Transitional. This file was automatically
+ *             generated from the file: xhtml1-transitional.dtd.
+ */
+
+/**
+ * Holds and object representation of the HTML DTD to be used by the
+ * editor in its internal operations.
+ *
+ * Each element in the DTD is represented by a property in this object. Each
+ * property contains the list of elements that can be contained by the element.
+ * Text is represented by the `#` property.
+ *
+ * Several special grouping properties are also available. Their names start
+ * with the `$` character.
+ *
+ *             // Check if <div> can be contained in a <p> element.
+ *             alert( !!CKEDITOR.dtd[ 'p' ][ 'div' ] ); // false
+ *
+ *             // Check if <p> can be contained in a <div> element.
+ *             alert( !!CKEDITOR.dtd[ 'div' ][ 'p' ] ); // true
+ *
+ *             // Check if <p> is a block element.
+ *             alert( !!CKEDITOR.dtd.$block[ 'p' ] ); // true
+ *
+ * @class CKEDITOR.dtd
+ * @singleton
+ */
+CKEDITOR.dtd = ( function() {
+       'use strict';
+
+       var X = CKEDITOR.tools.extend,
+               // Subtraction rest of sets, from the first set.
+               Y = function( source, removed ) {
+                       var substracted = CKEDITOR.tools.clone( source );
+                       for ( var i = 1; i < arguments.length; i++ ) {
+                               removed = arguments[ i ];
+                               for ( var name in removed )
+                                       delete substracted[ name ];
+                       }
+                       return substracted;
+               };
+
+       // Phrasing elements.
+       // P = { a: 1, em: 1, strong: 1, small: 1, abbr: 1, dfn: 1, i: 1, b: 1, s: 1,
+       //              u: 1, code: 1, 'var': 1, samp: 1, kbd: 1, sup: 1, sub: 1, q: 1, cite: 1,
+       //              span: 1, bdo: 1, bdi: 1, br: 1, wbr: 1, ins: 1, del: 1, img: 1, embed: 1,
+       //              object: 1, iframe: 1, map: 1, area: 1, script: 1, noscript: 1, ruby: 1,
+       //              video: 1, audio: 1, input: 1, textarea: 1, select: 1, button: 1, label: 1,
+       //              output: 1, keygen: 1, progress: 1, command: 1, canvas: 1, time: 1,
+       //              meter: 1, detalist: 1 },
+
+       // Flow elements.
+       // F = { a: 1, p: 1, hr: 1, pre: 1, ul: 1, ol: 1, dl: 1, div: 1, h1: 1, h2: 1,
+       //              h3: 1, h4: 1, h5: 1, h6: 1, hgroup: 1, address: 1, blockquote: 1, ins: 1,
+       //              del: 1, object: 1, map: 1, noscript: 1, section: 1, nav: 1, article: 1,
+       //              aside: 1, header: 1, footer: 1, video: 1, audio: 1, figure: 1, table: 1,
+       //              form: 1, fieldset: 1, menu: 1, canvas: 1, details:1 },
+
+       // Text can be everywhere.
+       // X( P, T );
+       // Flow elements set consists of phrasing elements set.
+       // X( F, P );
+
+       var P = {}, F = {},
+               // Intersection of flow elements set and phrasing elements set.
+               PF = {
+                       a: 1, abbr: 1, area: 1, audio: 1, b: 1, bdi: 1, bdo: 1, br: 1, button: 1, canvas: 1, cite: 1,
+                       code: 1, command: 1, datalist: 1, del: 1, dfn: 1, em: 1, embed: 1, i: 1, iframe: 1, img: 1,
+                       input: 1, ins: 1, kbd: 1, keygen: 1, label: 1, map: 1, mark: 1, meter: 1, noscript: 1, object: 1,
+                       output: 1, progress: 1, q: 1, ruby: 1, s: 1, samp: 1, script: 1, select: 1, small: 1, span: 1,
+                       strong: 1, sub: 1, sup: 1, textarea: 1, time: 1, u: 1, 'var': 1, video: 1, wbr: 1
+               },
+               // F - PF (Flow Only).
+               FO = {
+                       address: 1, article: 1, aside: 1, blockquote: 1, details: 1, div: 1, dl: 1, fieldset: 1,
+                       figure: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
+                       hr: 1, main: 1, menu: 1, nav: 1, ol: 1, p: 1, pre: 1, section: 1, table: 1, ul: 1
+               },
+               // Metadata elements.
+               M = { command: 1, link: 1, meta: 1, noscript: 1, script: 1, style: 1 },
+               // Empty.
+               E = {},
+               // Text.
+               T = { '#': 1 },
+
+               // Deprecated phrasing elements.
+               DP = { acronym: 1, applet: 1, basefont: 1, big: 1, font: 1, isindex: 1, strike: 1, style: 1, tt: 1 }, // TODO remove "style".
+               // Deprecated flow only elements.
+               DFO = { center: 1, dir: 1, noframes: 1 };
+
+       // Phrasing elements := PF + T + DP
+       X( P, PF, T, DP );
+       // Flow elements := FO + P + DFO
+       X( F, FO, P, DFO );
+
+       var dtd = {
+               a: Y( P, { a: 1, button: 1 } ), // Treat as normal inline element (not a transparent one).
+               abbr: P,
+               address: F,
+               area: E,
+               article: F,
+               aside: F,
+               audio: X( { source: 1, track: 1 }, F ),
+               b: P,
+               base: E,
+               bdi: P,
+               bdo: P,
+               blockquote: F,
+               body: F,
+               br: E,
+               button: Y( P, { a: 1, button: 1 } ),
+               canvas: P, // Treat as normal inline element (not a transparent one).
+               caption: F,
+               cite: P,
+               code: P,
+               col: E,
+               colgroup: { col: 1 },
+               command: E,
+               datalist: X( { option: 1 }, P ),
+               dd: F,
+               del: P, // Treat as normal inline element (not a transparent one).
+               details: X( { summary: 1 }, F ),
+               dfn: P,
+               div: F,
+               dl: { dt: 1, dd: 1 },
+               dt: F,
+               em: P,
+               embed: E,
+               fieldset: X( { legend: 1 }, F ),
+               figcaption: F,
+               figure: X( { figcaption: 1 }, F ),
+               footer: F,
+               form: F,
+               h1: P,
+               h2: P,
+               h3: P,
+               h4: P,
+               h5: P,
+               h6: P,
+               head: X( { title: 1, base: 1 }, M ),
+               header: F,
+               hgroup: { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
+               hr: E,
+               html: X( { head: 1, body: 1 }, F, M ), // Head and body are optional...
+               i: P,
+               iframe: T,
+               img: E,
+               input: E,
+               ins: P, // Treat as normal inline element (not a transparent one).
+               kbd: P,
+               keygen: E,
+               label: P,
+               legend: P,
+               li: F,
+               link: E,
+               // Can't be a descendant of article, aside, footer, header, nav, but we don't need this
+               // complication. As well as checking if it's used only once.
+               main: F,
+               map: F,
+               mark: P, // Treat as normal inline element (not a transparent one).
+               menu: X( { li: 1 }, F ),
+               meta: E,
+               meter: Y( P, { meter: 1 } ),
+               nav: F,
+               noscript: X( { link: 1, meta: 1, style: 1 }, P ), // Treat as normal inline element (not a transparent one).
+               object: X( { param: 1 }, P ), // Treat as normal inline element (not a transparent one).
+               ol: { li: 1 },
+               optgroup: { option: 1 },
+               option: T,
+               output: P,
+               p: P,
+               param: E,
+               pre: P,
+               progress: Y( P, { progress: 1 } ),
+               q: P,
+               rp: P,
+               rt: P,
+               ruby: X( { rp: 1, rt: 1 }, P ),
+               s: P,
+               samp: P,
+               script: T,
+               section: F,
+               select: { optgroup: 1, option: 1 },
+               small: P,
+               source: E,
+               span: P,
+               strong: P,
+               style: T,
+               sub: P,
+               summary: X( { h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 }, P ),
+               sup: P,
+               table: { caption: 1, colgroup: 1, thead: 1, tfoot: 1, tbody: 1, tr: 1 },
+               tbody: { tr: 1 },
+               td: F,
+               textarea: T,
+               tfoot: { tr: 1 },
+               th: F,
+               thead: { tr: 1 },
+               time: Y( P, { time: 1 } ),
+               title: T,
+               tr: { th: 1, td: 1 },
+               track: E,
+               u: P,
+               ul: { li: 1 },
+               'var': P,
+               video: X( { source: 1, track: 1 }, F ),
+               wbr: E,
+
+               // Deprecated tags.
+               acronym: P,
+               applet: X( { param: 1 }, F ),
+               basefont: E,
+               big: P,
+               center: F,
+               dialog: E,
+               dir: { li: 1 },
+               font: P,
+               isindex: E,
+               noframes: F,
+               strike: P,
+               tt: P
+       };
+
+       X( dtd, {
+               /**
+                * List of block elements, like `<p>` or `<div>`.
+                */
+               $block: X( { audio: 1, dd: 1, dt: 1, figcaption: 1, li: 1, video: 1 }, FO, DFO ),
+
+               /**
+                * List of elements that contain other blocks, in which block-level operations should be limited,
+                * this property is not intended to be checked directly, use {@link CKEDITOR.dom.elementPath#blockLimit} instead.
+                *
+                * Some examples of editor behaviors that are impacted by block limits:
+                *
+                * * Enter key never split a block-limit element;
+                * * Style application is constraint by the block limit of the current selection.
+                * * Pasted html will be inserted into the block limit of the current selection.
+                *
+                * **Note:** As an exception `<li>` is not considered as a block limit, as it's generally used as a text block.
+                */
+               $blockLimit: {
+                       article: 1, aside: 1, audio: 1, body: 1, caption: 1, details: 1, dir: 1, div: 1, dl: 1,
+                       fieldset: 1, figcaption: 1, figure: 1, footer: 1, form: 1, header: 1, hgroup: 1, main: 1, menu: 1, nav: 1,
+                       ol: 1, section: 1, table: 1, td: 1, th: 1, tr: 1, ul: 1, video: 1
+               },
+
+               /**
+                * List of elements that contain character data.
+                */
+               $cdata: { script: 1, style: 1 },
+
+               /**
+                * List of elements that are accepted as inline editing hosts.
+                */
+               $editable: {
+                       address: 1, article: 1, aside: 1, blockquote: 1, body: 1, details: 1, div: 1, fieldset: 1,
+                       figcaption: 1, footer: 1, form: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, header: 1, hgroup: 1,
+                       main: 1, nav: 1, p: 1, pre: 1, section: 1
+               },
+
+               /**
+                * List of empty (self-closing) elements, like `<br>` or `<img>`.
+                */
+               $empty: {
+                       area: 1, base: 1, basefont: 1, br: 1, col: 1, command: 1, dialog: 1, embed: 1, hr: 1, img: 1,
+                       input: 1, isindex: 1, keygen: 1, link: 1, meta: 1, param: 1, source: 1, track: 1, wbr: 1
+               },
+
+               /**
+                * List of inline (`<span>` like) elements.
+                */
+               $inline: P,
+
+               /**
+                * List of list root elements.
+                */
+               $list: { dl: 1, ol: 1, ul: 1 },
+
+               /**
+                * List of list item elements, like `<li>` or `<dd>`.
+                */
+               $listItem: { dd: 1, dt: 1, li: 1 },
+
+               /**
+                * List of elements which may live outside body.
+                */
+               $nonBodyContent: X( { body: 1, head: 1, html: 1 }, dtd.head ),
+
+               /**
+                * Elements that accept text nodes, but are not possible to edit into the browser.
+                */
+               $nonEditable: {
+                       applet: 1, audio: 1, button: 1, embed: 1, iframe: 1, map: 1, object: 1, option: 1,
+                       param: 1, script: 1, textarea: 1, video: 1
+               },
+
+               /**
+                * Elements that are considered objects, therefore selected as a whole in the editor.
+                */
+               $object: {
+                       applet: 1, audio: 1, button: 1, hr: 1, iframe: 1, img: 1, input: 1, object: 1, select: 1,
+                       table: 1, textarea: 1, video: 1
+               },
+
+               /**
+                * List of elements that can be ignored if empty, like `<b>` or `<span>`.
+                */
+               $removeEmpty: {
+                       abbr: 1, acronym: 1, b: 1, bdi: 1, bdo: 1, big: 1, cite: 1, code: 1, del: 1, dfn: 1,
+                       em: 1, font: 1, i: 1, ins: 1, label: 1, kbd: 1, mark: 1, meter: 1, output: 1, q: 1, ruby: 1, s: 1,
+                       samp: 1, small: 1, span: 1, strike: 1, strong: 1, sub: 1, sup: 1, time: 1, tt: 1, u: 1, 'var': 1
+               },
+
+               /**
+                * List of elements that have tabindex set to zero by default.
+                */
+               $tabIndex: { a: 1, area: 1, button: 1, input: 1, object: 1, select: 1, textarea: 1 },
+
+               /**
+                * List of elements used inside the `<table>` element, like `<tbody>` or `<td>`.
+                */
+               $tableContent: { caption: 1, col: 1, colgroup: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1 },
+
+               /**
+                * List of "transparent" elements. See [W3C's definition of "transparent" element](http://dev.w3.org/html5/markup/terminology.html#transparent).
+                */
+               $transparent: { a: 1, audio: 1, canvas: 1, del: 1, ins: 1, map: 1, noscript: 1, object: 1, video: 1 },
+
+               /**
+                * List of elements that are not to exist standalone that must live under it's parent element.
+                */
+               $intermediate: {
+                       caption: 1, colgroup: 1, dd: 1, dt: 1, figcaption: 1, legend: 1, li: 1, optgroup: 1,
+                       option: 1, rp: 1, rt: 1, summary: 1, tbody: 1, td: 1, tfoot: 1, th: 1, thead: 1, tr: 1
+               }
+       } );
+
+       return dtd;
+} )();
+
+// PACKAGER_RENAME( CKEDITOR.dtd )
diff --git a/sources/core/editable.js b/sources/core/editable.js
new file mode 100644 (file)
index 0000000..c50ec7f
--- /dev/null
@@ -0,0 +1,3266 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       var isNotWhitespace, isNotBookmark, isEmpty, isBogus, emptyParagraphRegexp,
+               insert, fixTableAfterContentsDeletion, fixListAfterContentsDelete, getHtmlFromRangeHelpers, extractHtmlFromRangeHelpers;
+
+       /**
+        * Editable class which provides all editing related activities by
+        * the `contenteditable` element, dynamically get attached to editor instance.
+        *
+        * @class CKEDITOR.editable
+        * @extends CKEDITOR.dom.element
+        */
+       CKEDITOR.editable = CKEDITOR.tools.createClass( {
+               base: CKEDITOR.dom.element,
+               /**
+                * The constructor only stores generic editable creation logic that is commonly shared among
+                * all different editable elements.
+                *
+                * @constructor Creates an editable class instance.
+                * @param {CKEDITOR.editor} editor The editor instance on which the editable operates.
+                * @param {HTMLElement/CKEDITOR.dom.element} element Any DOM element that was as the editor's
+                * editing container, e.g. it could be either an HTML element with the `contenteditable` attribute
+                * set to the `true` that handles WYSIWYG editing or a `<textarea>` element that handles source editing.
+                */
+               $: function( editor, element ) {
+                       // Transform the element into a CKEDITOR.dom.element instance.
+                       this.base( element.$ || element );
+
+                       this.editor = editor;
+
+                       /**
+                        * Indicates the initialization status of the editable element. The following statuses are available:
+                        *
+                        *      * **unloaded** &ndash; the initial state. The editable's instance was created but
+                        *      is not fully loaded (in particular it has no data).
+                        *      * **ready** &ndash; the editable is fully initialized. The `ready` status is set after
+                        *      the first {@link CKEDITOR.editor#method-setData} is called.
+                        *      * **detached** &ndash; the editable was detached.
+                        *
+                        * @since 4.3.3
+                        * @readonly
+                        * @property {String}
+                        */
+                       this.status = 'unloaded';
+
+                       /**
+                        * Indicates whether the editable element gained focus.
+                        *
+                        * @property {Boolean} hasFocus
+                        */
+                       this.hasFocus = false;
+
+                       // The bootstrapping logic.
+                       this.setup();
+               },
+
+               proto: {
+                       focus: function() {
+
+                               var active;
+
+                               // [Webkit] When DOM focus is inside of nested contenteditable elements,
+                               // apply focus on the main editable will compromise it's text selection.
+                               if ( CKEDITOR.env.webkit && !this.hasFocus ) {
+                                       // Restore focus on element which we cached (on selectionCheck) as previously active.
+                                       active = this.editor._.previousActive || this.getDocument().getActive();
+                                       if ( this.contains( active ) ) {
+                                               active.focus();
+                                               return;
+                                       }
+                               }
+
+                               // [Edge] Starting from EdgeHTML 14.14393, it does not support `setActive`. We need to use focus which
+                               // causes unexpected scroll. Store scrollTop value so it can be restored after focusing editor.
+                               // Scroll only happens if the editor is focused for the first time. (#14825)
+                               if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 && !this.hasFocus && this.getDocument().equals( CKEDITOR.document ) ) {
+                                       this.editor._.previousScrollTop = this.$.scrollTop;
+                               }
+
+                               // [IE] Use instead "setActive" method to focus the editable if it belongs to the host page document,
+                               // to avoid bringing an unexpected scroll.
+                               try {
+                                       if ( CKEDITOR.env.ie && !( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) && this.getDocument().equals( CKEDITOR.document ) ) {
+                                               this.$.setActive();
+                                       } else {
+                                               this.$.focus();
+                                       }
+                               } catch ( e ) {
+                                       // IE throws unspecified error when focusing editable after closing dialog opened on nested editable.
+                                       if ( !CKEDITOR.env.ie )
+                                               throw e;
+                               }
+
+                               // Remedy if Safari doens't applies focus properly. (#279)
+                               if ( CKEDITOR.env.safari && !this.isInline() ) {
+                                       active = CKEDITOR.document.getActive();
+                                       if ( !active.equals( this.getWindow().getFrame() ) )
+                                               this.getWindow().focus();
+
+                               }
+                       },
+
+                       /**
+                        * Overrides {@link CKEDITOR.dom.element#on} to have special `focus/blur` handling.
+                        * The `focusin/focusout` events are used in IE to replace regular `focus/blur` events
+                        * because we want to avoid the asynchronous nature of later ones.
+                        */
+                       on: function( name, fn ) {
+                               var args = Array.prototype.slice.call( arguments, 0 );
+
+                               if ( CKEDITOR.env.ie && ( /^focus|blur$/ ).exec( name ) ) {
+                                       name = name == 'focus' ? 'focusin' : 'focusout';
+
+                                       // The "focusin/focusout" events bubbled, e.g. If there are elements with layout
+                                       // they fire this event when clicking in to edit them but it must be ignored
+                                       // to allow edit their contents. (#4682)
+                                       fn = isNotBubbling( fn, this );
+                                       args[ 0 ] = name;
+                                       args[ 1 ] = fn;
+                               }
+
+                               return CKEDITOR.dom.element.prototype.on.apply( this, args );
+                       },
+
+                       /**
+                        * Registers an event listener that needs to be removed when detaching this editable.
+                        * This means that it will be automatically removed when {@link #detach} is executed,
+                        * for example on {@link CKEDITOR.editor#setMode changing editor mode} or destroying editor.
+                        *
+                        * Except for `obj` all other arguments have the same meaning as in {@link CKEDITOR.event#on}.
+                        *
+                        * This method is strongly related to the {@link CKEDITOR.editor#contentDom} and
+                        * {@link CKEDITOR.editor#contentDomUnload} events, because they are fired
+                        * when an editable is being attached and detached. Therefore, this method is usually used
+                        * in the following way:
+                        *
+                        *              editor.on( 'contentDom', function() {
+                        *                      var editable = editor.editable();
+                        *                      editable.attachListener( editable, 'mousedown', function() {
+                        *                              // ...
+                        *                      } );
+                        *              } );
+                        *
+                        * This code will attach the `mousedown` listener every time a new editable is attached
+                        * to the editor, which in classic (`iframe`-based) editor happens every time the
+                        * data or the mode is set. This listener will also be removed when that editable is detached.
+                        *
+                        * It is also possible to attach a listener to another object (e.g. to a document).
+                        *
+                        *              editor.on( 'contentDom', function() {
+                        *                      editor.editable().attachListener( editor.document, 'mousedown', function() {
+                        *                              // ...
+                        *                      } );
+                        *              } );
+                        *
+                        * @param {CKEDITOR.event} obj The element/object to which the listener will be attached. Every object
+                        * which inherits from {@link CKEDITOR.event} may be used including {@link CKEDITOR.dom.element},
+                        * {@link CKEDITOR.dom.document}, and {@link CKEDITOR.editable}.
+                        * @param {String} eventName The name of the event that will be listened to.
+                        * @param {Function} listenerFunction The function listening to the
+                        * event. A single {@link CKEDITOR.eventInfo} object instance
+                        * containing all the event data is passed to this function.
+                        * @param {Object} [scopeObj] The object used to scope the listener
+                        * call (the `this` object). If omitted, the current object is used.
+                        * @param {Object} [listenerData] Data to be sent as the
+                        * {@link CKEDITOR.eventInfo#listenerData} when calling the listener.
+                        * @param {Number} [priority=10] The listener priority. Lower priority
+                        * listeners are called first. Listeners with the same priority
+                        * value are called in the registration order.
+                        * @returns {Object} An object containing the `removeListener`
+                        * function that can be used to remove the listener at any time.
+                        */
+                       attachListener: function( obj /*, event, fn, scope, listenerData, priority*/ ) {
+                               !this._.listeners && ( this._.listeners = [] );
+                               // Register the listener.
+                               var args = Array.prototype.slice.call( arguments, 1 ),
+                                       listener = obj.on.apply( obj, args );
+
+                               this._.listeners.push( listener );
+
+                               return listener;
+                       },
+
+                       /**
+                        * Remove all event listeners registered from {@link #attachListener}.
+                        */
+                       clearListeners: function() {
+                               var listeners = this._.listeners;
+                               // Don't get broken by this.
+                               try {
+                                       while ( listeners.length )
+                                               listeners.pop().removeListener();
+                               } catch ( e ) {}
+                       },
+
+                       /**
+                        * Restore all attribution changes made by {@link #changeAttr }.
+                        */
+                       restoreAttrs: function() {
+                               var changes = this._.attrChanges, orgVal;
+                               for ( var attr in changes ) {
+                                       if ( changes.hasOwnProperty( attr ) ) {
+                                               orgVal = changes[ attr ];
+                                               // Restore original attribute.
+                                               orgVal !== null ? this.setAttribute( attr, orgVal ) : this.removeAttribute( attr );
+                                       }
+                               }
+                       },
+
+                       /**
+                        * Adds a CSS class name to this editable that needs to be removed on detaching.
+                        *
+                        * @param {String} className The class name to be added.
+                        * @see CKEDITOR.dom.element#addClass
+                        */
+                       attachClass: function( cls ) {
+                               var classes = this.getCustomData( 'classes' );
+                               if ( !this.hasClass( cls ) ) {
+                                       !classes && ( classes = [] ), classes.push( cls );
+                                       this.setCustomData( 'classes', classes );
+                                       this.addClass( cls );
+                               }
+                       },
+
+                       /**
+                        * Make an attribution change that would be reverted on editable detaching.
+                        * @param {String} attr The attribute name to be changed.
+                        * @param {String} val The value of specified attribute.
+                        */
+                       changeAttr: function( attr, val ) {
+                               var orgVal = this.getAttribute( attr );
+                               if ( val !== orgVal ) {
+                                       !this._.attrChanges && ( this._.attrChanges = {} );
+
+                                       // Saved the original attribute val.
+                                       if ( !( attr in this._.attrChanges ) )
+                                               this._.attrChanges[ attr ] = orgVal;
+
+                                       this.setAttribute( attr, val );
+                               }
+                       },
+
+                       /**
+                        * Low-level method for inserting text into the editable.
+                        * See the {@link CKEDITOR.editor#method-insertText} method which is the editor-level API
+                        * for this purpose.
+                        *
+                        * @param {String} text
+                        */
+                       insertText: function( text ) {
+                               // Focus the editor before calling transformPlainTextToHtml. (#12726)
+                               this.editor.focus();
+                               this.insertHtml( this.transformPlainTextToHtml( text ), 'text' );
+                       },
+
+                       /**
+                        * Transforms plain text to HTML based on current selection and {@link CKEDITOR.editor#activeEnterMode}.
+                        *
+                        * @since 4.5
+                        * @param {String} text Text to transform.
+                        * @returns {String} HTML generated from the text.
+                        */
+                       transformPlainTextToHtml: function( text ) {
+                               var enterMode = this.editor.getSelection().getStartElement().hasAscendant( 'pre', true ) ?
+                                       CKEDITOR.ENTER_BR :
+                                       this.editor.activeEnterMode;
+
+                               return CKEDITOR.tools.transformPlainTextToHtml( text, enterMode );
+                       },
+
+                       /**
+                        * Low-level method for inserting HTML into the editable.
+                        * See the {@link CKEDITOR.editor#method-insertHtml} method which is the editor-level API
+                        * for this purpose.
+                        *
+                        * This method will insert HTML into the current selection or a given range. It also creates an undo snapshot,
+                        * scrolls the viewport to the insertion and selects the range next to the inserted content.
+                        * If you want to insert HTML without additional operations use {@link #method-insertHtmlIntoRange}.
+                        *
+                        * Fires the {@link CKEDITOR.editor#event-afterInsertHtml} event.
+                        *
+                        * @param {String} data The HTML to be inserted.
+                        * @param {String} [mode='html'] See {@link CKEDITOR.editor#method-insertHtml}'s param.
+                        * @param {CKEDITOR.dom.range} [range] If specified, the HTML will be inserted into the range
+                        * instead of into the selection. The selection will be placed at the end of the insertion (like in the normal case).
+                        * Introduced in CKEditor 4.5.
+                        */
+                       insertHtml: function( data, mode, range ) {
+                               var editor = this.editor;
+
+                               editor.focus();
+                               editor.fire( 'saveSnapshot' );
+
+                               if ( !range ) {
+                                       // HTML insertion only considers the first range.
+                                       // Note: getRanges will be overwritten for tests since we want to test
+                                       // custom ranges and bypass native selections.
+                                       range = editor.getSelection().getRanges()[ 0 ];
+                               }
+
+                               // Default mode is 'html'.
+                               insert( this, mode || 'html', data, range );
+
+                               // Make the final range selection.
+                               range.select();
+
+                               afterInsert( this );
+
+                               this.editor.fire( 'afterInsertHtml', {} );
+                       },
+
+                       /**
+                        * Inserts HTML into the position in the editor determined by the range.
+                        *
+                        * **Note:** This method does not {@link CKEDITOR.editor#saveSnapshot save undo snapshots} nor selects inserted
+                        * HTML. If you want to do it, use {@link #method-insertHtml}.
+                        *
+                        * Fires the {@link CKEDITOR.editor#event-afterInsertHtml} event.
+                        *
+                        * @since 4.5
+                        * @param {String} data HTML code to be inserted into the editor.
+                        * @param {CKEDITOR.dom.range} range The range as a place of insertion.
+                        * @param {String} [mode='html'] Mode in which HTML will be inserted.
+                        * See {@link CKEDITOR.editor#method-insertHtml}.
+                        */
+                       insertHtmlIntoRange: function( data, range, mode ) {
+                               // Default mode is 'html'
+                               insert( this, mode || 'html', data, range );
+
+                               this.editor.fire( 'afterInsertHtml', { intoRange: range } );
+                       },
+
+                       /**
+                        * Low-level method for inserting an element into the editable.
+                        * See the {@link CKEDITOR.editor#method-insertElement} method which is the editor-level API
+                        * for this purpose.
+                        *
+                        * This method will insert the element into the current selection or a given range. It also creates an undo
+                        * snapshot, scrolls the viewport to the insertion and selects the range next to the inserted content.
+                        * If you want to insert an element without additional operations use {@link #method-insertElementIntoRange}.
+                        *
+                        * @param {CKEDITOR.dom.element} element The element to insert.
+                        * @param {CKEDITOR.dom.range} [range] If specified, the element will be inserted into the range
+                        * instead of into the selection.
+                        */
+                       insertElement: function( element, range ) {
+                               var editor = this.editor;
+
+                               // Prepare for the insertion. For example - focus editor (#11848).
+                               editor.focus();
+                               editor.fire( 'saveSnapshot' );
+
+                               var enterMode = editor.activeEnterMode,
+                                       selection = editor.getSelection(),
+                                       elementName = element.getName(),
+                                       isBlock = CKEDITOR.dtd.$block[ elementName ];
+
+                               if ( !range ) {
+                                       range = selection.getRanges()[ 0 ];
+                               }
+
+                               // Insert element into first range only and ignore the rest (#11183).
+                               if ( this.insertElementIntoRange( element, range ) ) {
+                                       range.moveToPosition( element, CKEDITOR.POSITION_AFTER_END );
+
+                                       // If we're inserting a block element, the new cursor position must be
+                                       // optimized. (#3100,#5436,#8950)
+                                       if ( isBlock ) {
+                                               // Find next, meaningful element.
+                                               var next = element.getNext( function( node ) {
+                                                       return isNotEmpty( node ) && !isBogus( node );
+                                               } );
+
+                                               if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.is( CKEDITOR.dtd.$block ) ) {
+                                                       // If the next one is a text block, move cursor to the start of it's content.
+                                                       if ( next.getDtd()[ '#' ] )
+                                                               range.moveToElementEditStart( next );
+                                                       // Otherwise move cursor to the before end of the last element.
+                                                       else
+                                                               range.moveToElementEditEnd( element );
+                                               }
+                                               // Open a new line if the block is inserted at the end of parent.
+                                               else if ( !next && enterMode != CKEDITOR.ENTER_BR ) {
+                                                       next = range.fixBlock( true, enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
+                                                       range.moveToElementEditStart( next );
+                                               }
+                                       }
+                               }
+
+                               // Set up the correct selection.
+                               selection.selectRanges( [ range ] );
+
+                               afterInsert( this );
+                       },
+
+                       /**
+                        * Alias for {@link #insertElement}.
+                        *
+                        * @deprecated
+                        * @param {CKEDITOR.dom.element} element The element to be inserted.
+                        */
+                       insertElementIntoSelection: function( element ) {
+                               this.insertElement( element );
+                       },
+
+                       /**
+                        * Inserts an element into the position in the editor determined by the range.
+                        *
+                        * **Note:** This method does not {@link CKEDITOR.editor#saveSnapshot save undo snapshots} nor selects the inserted
+                        * element. If you want to do it, use the {@link #method-insertElement} method.
+                        *
+                        * @param {CKEDITOR.dom.element} element The element to be inserted.
+                        * @param {CKEDITOR.dom.range} range The range as a place of insertion.
+                        * @returns {Boolean} Informs whether the insertion was successful.
+                        */
+                       insertElementIntoRange: function( element, range ) {
+                               var editor = this.editor,
+                                       enterMode = editor.config.enterMode,
+                                       elementName = element.getName(),
+                                       isBlock = CKEDITOR.dtd.$block[ elementName ];
+
+                               if ( range.checkReadOnly() )
+                                       return false;
+
+                               // Remove the original contents, merge split nodes.
+                               range.deleteContents( 1 );
+
+                               if ( range.startContainer.type == CKEDITOR.NODE_ELEMENT ) {
+                                       // If range is placed in intermediate element (not td or th), we need to do three things:
+                                       // * fill emptied <td/th>s with if browser needs them,
+                                       // * remove empty text nodes so IE8 won't crash
+                                       // (http://dev.ckeditor.com/ticket/11183#comment:8),
+                                       // * fix structure and move range into the <td/th> element.
+                                       if ( range.startContainer.is( { tr: 1, table: 1, tbody: 1, thead: 1, tfoot: 1 } ) ) {
+                                               fixTableAfterContentsDeletion( range );
+                                       } else if ( range.startContainer.is( CKEDITOR.dtd.$list ) ) {
+                                               // Similarly there's a need for lists.
+                                               fixListAfterContentsDelete( range );
+                                       }
+                               }
+
+                               // If we're inserting a block at dtd-violated position, split
+                               // the parent blocks until we reach blockLimit.
+                               var current, dtd;
+
+                               if ( isBlock ) {
+                                       while ( ( current = range.getCommonAncestor( 0, 1 ) ) &&
+                                                       ( dtd = CKEDITOR.dtd[ current.getName() ] ) &&
+                                                       !( dtd && dtd[ elementName ] ) ) {
+                                               // Split up inline elements.
+                                               if ( current.getName() in CKEDITOR.dtd.span )
+                                                       range.splitElement( current );
+
+                                               // If we're in an empty block which indicate a new paragraph,
+                                               // simply replace it with the inserting block.(#3664)
+                                               else if ( range.checkStartOfBlock() && range.checkEndOfBlock() ) {
+                                                       range.setStartBefore( current );
+                                                       range.collapse( true );
+                                                       current.remove();
+                                               } else {
+                                                       range.splitBlock( enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p', editor.editable() );
+                                               }
+                                       }
+                               }
+
+                               // Insert the new node.
+                               range.insertNode( element );
+
+                               // Return true if insertion was successful.
+                               return true;
+                       },
+
+                       /**
+                        * @see CKEDITOR.editor#setData
+                        */
+                       setData: function( data, isSnapshot ) {
+                               if ( !isSnapshot )
+                                       data = this.editor.dataProcessor.toHtml( data );
+
+                               this.setHtml( data );
+                               this.fixInitialSelection();
+
+                               // Editable is ready after first setData.
+                               if ( this.status == 'unloaded' )
+                                       this.status = 'ready';
+
+                               this.editor.fire( 'dataReady' );
+                       },
+
+                       /**
+                        * @see CKEDITOR.editor#getData
+                        */
+                       getData: function( isSnapshot ) {
+                               var data = this.getHtml();
+
+                               if ( !isSnapshot )
+                                       data = this.editor.dataProcessor.toDataFormat( data );
+
+                               return data;
+                       },
+
+                       /**
+                        * Changes the read-only state of this editable.
+                        *
+                        * @param {Boolean} isReadOnly
+                        */
+                       setReadOnly: function( isReadOnly ) {
+                               this.setAttribute( 'contenteditable', !isReadOnly );
+                       },
+
+                       /**
+                        * Detaches this editable object from the DOM (removes classes, listeners, etc.)
+                        */
+                       detach: function() {
+                               // Cleanup the element.
+                               this.removeClass( 'cke_editable' );
+
+                               this.status = 'detached';
+
+                               // Save the editor reference which will be lost after
+                               // calling detach from super class.
+                               var editor = this.editor;
+
+                               this._.detach();
+
+                               delete editor.document;
+                               delete editor.window;
+                       },
+
+                       /**
+                        * Checks if the editable is one of the host page elements, indicates
+                        * an inline editing environment.
+                        *
+                        * @returns {Boolean}
+                        */
+                       isInline: function() {
+                               return this.getDocument().equals( CKEDITOR.document );
+                       },
+
+                       /**
+                        * Fixes the selection and focus which may be in incorrect state after
+                        * editable's inner HTML was overwritten.
+                        *
+                        * If the editable did not have focus, then the selection will be fixed when the editable
+                        * is focused for the first time. If the editable already had focus, then the selection will
+                        * be fixed immediately.
+                        *
+                        * To understand the problem see:
+                        *
+                        * * http://tests.ckeditor.dev:1030/tests/core/selection/manual/focusaftersettingdata
+                        * * http://tests.ckeditor.dev:1030/tests/core/selection/manual/focusafterundoing
+                        * * http://tests.ckeditor.dev:1030/tests/core/selection/manual/selectionafterfocusing
+                        * * http://tests.ckeditor.dev:1030/tests/plugins/newpage/manual/selectionafternewpage
+                        *
+                        * @since 4.4.6
+                        * @private
+                        */
+                       fixInitialSelection: function() {
+                               var that = this;
+
+                               // Deal with IE8- IEQM (the old MS selection) first.
+                               if ( CKEDITOR.env.ie && ( CKEDITOR.env.version < 9 || CKEDITOR.env.quirks ) ) {
+                                       if ( this.hasFocus ) {
+                                               this.focus();
+                                               fixMSSelection();
+                                       }
+
+                                       return;
+                               }
+
+                               // If editable did not have focus, fix the selection when it is first focused.
+                               if ( !this.hasFocus ) {
+                                       this.once( 'focus', function() {
+                                               fixSelection();
+                                       }, null, null, -999 );
+                               // If editable had focus, fix the selection immediately.
+                               } else {
+                                       this.focus();
+                                       fixSelection();
+                               }
+
+                               function fixSelection() {
+                                       var $doc = that.getDocument().$,
+                                               $sel = $doc.getSelection();
+
+                                       if ( requiresFix( $sel ) ) {
+                                               var range = new CKEDITOR.dom.range( that );
+                                               range.moveToElementEditStart( that );
+
+                                               var $range = $doc.createRange();
+                                               $range.setStart( range.startContainer.$, range.startOffset );
+                                               $range.collapse( true );
+
+                                               $sel.removeAllRanges();
+                                               $sel.addRange( $range );
+                                       }
+                               }
+
+                               function requiresFix( $sel ) {
+                                       // This condition covers most broken cases after setting data.
+                                       if ( $sel.anchorNode && $sel.anchorNode == that.$ ) {
+                                               return true;
+                                       }
+
+                                       // Fix for:
+                                       // http://tests.ckeditor.dev:1030/tests/core/selection/manual/focusaftersettingdata
+                                       // (the inline editor TC)
+                                       if ( CKEDITOR.env.webkit ) {
+                                               var active = that.getDocument().getActive();
+                                               if ( active && active.equals( that ) && !$sel.anchorNode ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+
+                               function fixMSSelection() {
+                                       var $doc = that.getDocument().$,
+                                               $sel = $doc.selection,
+                                               active = that.getDocument().getActive();
+
+                                       if ( $sel.type == 'None' && active.equals( that ) ) {
+                                               var range = new CKEDITOR.dom.range( that ),
+                                                       parentElement,
+                                                       $range = $doc.body.createTextRange();
+
+                                               range.moveToElementEditStart( that );
+
+                                               parentElement = range.startContainer;
+                                               if ( parentElement.type != CKEDITOR.NODE_ELEMENT ) {
+                                                       parentElement = parentElement.getParent();
+                                               }
+
+                                               $range.moveToElementText( parentElement.$ );
+                                               $range.collapse( true );
+                                               $range.select();
+                                       }
+                               }
+                       },
+
+                       /**
+                        * The base of the {@link CKEDITOR.editor#getSelectedHtml} method.
+                        *
+                        * @since 4.5
+                        * @method getHtmlFromRange
+                        * @param {CKEDITOR.dom.range} range
+                        * @returns {CKEDITOR.dom.documentFragment}
+                        */
+                       getHtmlFromRange: function( range ) {
+                               // There's nothing to return if range is collapsed.
+                               if ( range.collapsed )
+                                       return new CKEDITOR.dom.documentFragment( range.document );
+
+                               // Info object passed between methods.
+                               var that = {
+                                       doc: this.getDocument(),
+                                       // Leave original range object untouched.
+                                       range: range.clone()
+                               };
+
+                               getHtmlFromRangeHelpers.eol.detect( that, this );
+                               getHtmlFromRangeHelpers.bogus.exclude( that );
+                               getHtmlFromRangeHelpers.cell.shrink( that );
+
+                               that.fragment = that.range.cloneContents();
+
+                               getHtmlFromRangeHelpers.tree.rebuild( that, this );
+                               getHtmlFromRangeHelpers.eol.fix( that, this );
+
+                               return new CKEDITOR.dom.documentFragment( that.fragment.$ );
+                       },
+
+                       /**
+                        * The base of the {@link CKEDITOR.editor#extractSelectedHtml} method.
+                        *
+                        * **Note:** The range is modified so it matches the desired selection after extraction
+                        * even though the selection is not made.
+                        *
+                        * @since 4.5
+                        * @param {CKEDITOR.dom.range} range
+                        * @param {Boolean} [removeEmptyBlock=false] See {@link CKEDITOR.editor#extractSelectedHtml}'s parameter.
+                        * Note that the range will not be modified if this parameter is set to `true`.
+                        * @returns {CKEDITOR.dom.documentFragment} The extracted fragment of the editable content.
+                        */
+                       extractHtmlFromRange: function( range, removeEmptyBlock ) {
+                               var helpers = extractHtmlFromRangeHelpers,
+                                       that = {
+                                               range: range,
+                                               doc: range.document
+                                       },
+                                       // Since it is quite hard to build a valid documentFragment
+                                       // out of extracted contents because DOM changes, let's mimic
+                                       // extracted HTML with #getHtmlFromRange. Yep. It's a hack.
+                                       extractedFragment = this.getHtmlFromRange( range );
+
+                               // Collapsed range means that there's nothing to extract.
+                               if ( range.collapsed ) {
+                                       range.optimize();
+                                       return extractedFragment;
+                               }
+
+                               // Include inline element if possible.
+                               range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );
+
+                               // This got to be done before bookmarks are created because purging
+                               // depends on the position of the range at the boundaries of the table,
+                               // usually distorted by bookmark spans.
+                               helpers.table.detectPurge( that );
+
+                               // We'll play with DOM, let's hold the position of the range.
+                               that.bookmark = range.createBookmark();
+                               // While bookmarked, make unaccessible, to make sure that none of the methods
+                               // will try to use it (they should use that.bookmark).
+                               // This is done because ranges get desynchronized with the DOM when more bookmarks
+                               // is created (as for instance that.targetBookmark).
+                               delete that.range;
+
+                               // The range to be restored after extraction should be kept
+                               // outside of the range, so it's not removed by range.extractContents.
+                               var targetRange = this.editor.createRange();
+                               targetRange.moveToPosition( that.bookmark.startNode, CKEDITOR.POSITION_BEFORE_START );
+                               that.targetBookmark = targetRange.createBookmark();
+
+                               // Execute content-specific detections.
+                               helpers.list.detectMerge( that, this );
+                               helpers.table.detectRanges( that, this );
+                               helpers.block.detectMerge( that, this );
+
+                               // Simply, do the job.
+                               if ( that.tableContentsRanges ) {
+                                       helpers.table.deleteRanges( that );
+
+                                       // Done here only to remove bookmark's spans.
+                                       range.moveToBookmark( that.bookmark );
+                                       that.range = range;
+                               } else {
+                                       // To use the range we need to restore the bookmark and make
+                                       // the range accessible again.
+                                       range.moveToBookmark( that.bookmark );
+                                       that.range = range;
+                                       range.extractContents( helpers.detectExtractMerge( that ) );
+                               }
+
+                               // Move working range to desired, pre-computed position.
+                               range.moveToBookmark( that.targetBookmark );
+
+                               // Make sure range is always anchored in an element. For consistency.
+                               range.optimize();
+
+                               // It my happen that the uncollapsed range which referred to a valid selection,
+                               // will be placed in an uneditable location after being collapsed:
+                               // <tr>[<td>x</td>]</tr> -> <tr>[]<td>x</td></tr> -> <tr><td>[]x</td></tr>
+                               helpers.fixUneditableRangePosition( range );
+
+                               // Execute content-specific post-extract routines.
+                               helpers.list.merge( that, this );
+                               helpers.table.purge( that, this );
+                               helpers.block.merge( that, this );
+
+                               // Remove empty block, duh!
+                               if ( removeEmptyBlock ) {
+                                       var path = range.startPath();
+
+                                       // <p><b>^</b></p> is empty block.
+                                       if (
+                                               range.checkStartOfBlock() &&
+                                               range.checkEndOfBlock() &&
+                                               path.block &&
+                                               !range.root.equals( path.block ) &&
+                                               // Do not remove a block with bookmarks. (#13465)
+                                               !hasBookmarks( path.block ) ) {
+                                               range.moveToPosition( path.block, CKEDITOR.POSITION_BEFORE_START );
+                                               path.block.remove();
+                                       }
+                               } else {
+                                       // Auto paragraph, if needed.
+                                       helpers.autoParagraph( this.editor, range );
+
+                                       // Let's have a bogus next to the caret, if needed.
+                                       if ( isEmpty( range.startContainer ) )
+                                               range.startContainer.appendBogus();
+                               }
+
+                               // Merge inline siblings if any around the caret.
+                               range.startContainer.mergeSiblings();
+
+                               return extractedFragment;
+                       },
+
+                       /**
+                        * Editable element bootstrapping.
+                        *
+                        * @private
+                        */
+                       setup: function() {
+                               var editor = this.editor;
+
+                               // Handle the load/read of editor data/snapshot.
+                               this.attachListener( editor, 'beforeGetData', function() {
+                                       var data = this.getData();
+
+                                       // Post processing html output of wysiwyg editable.
+                                       if ( !this.is( 'textarea' ) ) {
+                                               // Reset empty if the document contains only one empty paragraph.
+                                               if ( editor.config.ignoreEmptyParagraph !== false )
+                                                       data = data.replace( emptyParagraphRegexp, function( match, lookback ) {
+                                                               return lookback;
+                                                       } );
+                                       }
+
+                                       editor.setData( data, null, 1 );
+                               }, this );
+
+                               this.attachListener( editor, 'getSnapshot', function( evt ) {
+                                       evt.data = this.getData( 1 );
+                               }, this );
+
+                               this.attachListener( editor, 'afterSetData', function() {
+                                       this.setData( editor.getData( 1 ) );
+                               }, this );
+                               this.attachListener( editor, 'loadSnapshot', function( evt ) {
+                                       this.setData( evt.data, 1 );
+                               }, this );
+
+                               // Delegate editor focus/blur to editable.
+                               this.attachListener( editor, 'beforeFocus', function() {
+                                       var sel = editor.getSelection(),
+                                               ieSel = sel && sel.getNative();
+
+                                       // IE considers control-type element as separate
+                                       // focus host when selected, avoid destroying the
+                                       // selection in such case. (#5812) (#8949)
+                                       if ( ieSel && ieSel.type == 'Control' )
+                                               return;
+
+                                       this.focus();
+                               }, this );
+
+                               this.attachListener( editor, 'insertHtml', function( evt ) {
+                                       this.insertHtml( evt.data.dataValue, evt.data.mode, evt.data.range );
+                               }, this );
+                               this.attachListener( editor, 'insertElement', function( evt ) {
+                                       this.insertElement( evt.data );
+                               }, this );
+                               this.attachListener( editor, 'insertText', function( evt ) {
+                                       this.insertText( evt.data );
+                               }, this );
+
+                               // Update editable state.
+                               this.setReadOnly( editor.readOnly );
+
+                               // The editable class.
+                               this.attachClass( 'cke_editable' );
+
+                               // The element mode css class.
+                               if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) {
+                                       this.attachClass( 'cke_editable_inline' );
+                               } else if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ||
+                                       editor.elementMode == CKEDITOR.ELEMENT_MODE_APPENDTO ) {
+                                       this.attachClass( 'cke_editable_themed' );
+                               }
+
+                               this.attachClass( 'cke_contents_' + editor.config.contentsLangDirection );
+
+                               // Setup editor keystroke handlers on this element.
+                               var keystrokeHandler = editor.keystrokeHandler;
+
+                               // If editor is read-only, then make sure that BACKSPACE key
+                               // is blocked to prevent browser history navigation.
+                               keystrokeHandler.blockedKeystrokes[ 8 ] = +editor.readOnly;
+
+                               editor.keystrokeHandler.attach( this );
+
+                               // Update focus states.
+                               this.on( 'blur', function() {
+                                       this.hasFocus = false;
+                               }, null, null, -1 );
+
+                               this.on( 'focus', function() {
+                                       this.hasFocus = true;
+                               }, null, null, -1 );
+
+                               if ( CKEDITOR.env.webkit ) {
+                                       // [WebKit] Save scrollTop value so it can be used when restoring locked selection. (#14659)
+                                       this.on( 'scroll', function() {
+                                               editor._.previousScrollTop = editor.editable().$.scrollTop;
+                                       }, null, null, -1 );
+                               }
+
+                               // [Edge] This is the other part of the workaround for Edge which restores saved
+                               // scrollTop value and removes listener which is not needed anymore. (#14825)
+                               if ( CKEDITOR.env.edge && CKEDITOR.env.version > 14 ) {
+
+                                       var fixScrollOnFocus = function() {
+                                               var editable = editor.editable();
+
+                                               if ( editor._.previousScrollTop != null && editable.getDocument().equals( CKEDITOR.document ) ) {
+                                                       editable.$.scrollTop = editor._.previousScrollTop;
+                                                       editor._.previousScrollTop = null;
+                                                       this.removeListener( 'scroll', fixScrollOnFocus );
+                                               }
+                                       };
+
+                                       this.on( 'scroll', fixScrollOnFocus );
+                               }
+
+                               // Register to focus manager.
+                               editor.focusManager.add( this );
+
+                               // Inherit the initial focus on editable element.
+                               if ( this.equals( CKEDITOR.document.getActive() ) ) {
+                                       this.hasFocus = true;
+                                       // Pending until this editable has attached.
+                                       editor.once( 'contentDom', function() {
+                                               editor.focusManager.focus( this );
+                                       }, this );
+                               }
+
+                               // Apply tab index on demand, with original direction saved.
+                               if ( this.isInline() ) {
+
+                                       // tabIndex of the editable is different than editor's one.
+                                       // Update the attribute of the editable.
+                                       this.changeAttr( 'tabindex', editor.tabIndex );
+                               }
+
+                               // The above is all we'll be doing for a <textarea> editable.
+                               if ( this.is( 'textarea' ) )
+                                       return;
+
+                               // The DOM document which the editing acts upon.
+                               editor.document = this.getDocument();
+                               editor.window = this.getWindow();
+
+                               var doc = editor.document;
+
+                               this.changeAttr( 'spellcheck', !editor.config.disableNativeSpellChecker );
+
+                               // Apply contents direction on demand, with original direction saved.
+                               var dir = editor.config.contentsLangDirection;
+                               if ( this.getDirection( 1 ) != dir )
+                                       this.changeAttr( 'dir', dir );
+
+                               // Create the content stylesheet for this document.
+                               var styles = CKEDITOR.getCss();
+                               if ( styles ) {
+                                       var head = doc.getHead(),
+                                               stylesElement = head.getCustomData( 'stylesheet' );
+
+                                       if ( !stylesElement ) {
+                                               var sheet = doc.appendStyleText( styles );
+                                               sheet = new CKEDITOR.dom.element( sheet.ownerNode || sheet.owningElement );
+                                               head.setCustomData( 'stylesheet', sheet );
+                                               sheet.data( 'cke-temp', 1 );
+                                       } else if ( styles != stylesElement.getText() ) {
+                                               CKEDITOR.env.ie && CKEDITOR.env.version < 9 ? stylesElement.$.styleSheet.cssText = styles : stylesElement.setText( styles );
+                                       }
+                               }
+
+                               // Update the stylesheet sharing count.
+                               var ref = doc.getCustomData( 'stylesheet_ref' ) || 0;
+                               doc.setCustomData( 'stylesheet_ref', ref + 1 );
+
+                               // Pass this configuration to styles system.
+                               this.setCustomData( 'cke_includeReadonly', !editor.config.disableReadonlyStyling );
+
+                               // Prevent the browser opening read-only links. (#6032 & #10912)
+                               this.attachListener( this, 'click', function( evt ) {
+                                       evt = evt.data;
+
+                                       var link = new CKEDITOR.dom.elementPath( evt.getTarget(), this ).contains( 'a' );
+
+                                       if ( link && evt.$.button != 2 && link.isReadOnly() )
+                                               evt.preventDefault();
+                               } );
+
+                               var backspaceOrDelete = { 8: 1, 46: 1 };
+
+                               // Override keystrokes which should have deletion behavior
+                               //  on fully selected element . (#4047) (#7645)
+                               this.attachListener( editor, 'key', function( evt ) {
+                                       if ( editor.readOnly )
+                                               return true;
+
+                                       // Use getKey directly in order to ignore modifiers.
+                                       // Justification: http://dev.ckeditor.com/ticket/11861#comment:13
+                                       var keyCode = evt.data.domEvent.getKey(),
+                                               isHandled;
+
+                                       // Backspace OR Delete.
+                                       if ( keyCode in backspaceOrDelete ) {
+                                               var sel = editor.getSelection(),
+                                                       selected,
+                                                       range = sel.getRanges()[ 0 ],
+                                                       path = range.startPath(),
+                                                       block,
+                                                       parent,
+                                                       next,
+                                                       rtl = keyCode == 8;
+
+                                               if (
+                                                               // [IE<11] Remove selected image/anchor/etc here to avoid going back in history. (#10055)
+                                                               ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && ( selected = sel.getSelectedElement() ) ) ||
+                                                               // Remove the entire list/table on fully selected content. (#7645)
+                                                               ( selected = getSelectedTableList( sel ) ) ) {
+                                                       // Make undo snapshot.
+                                                       editor.fire( 'saveSnapshot' );
+
+                                                       // Delete any element that 'hasLayout' (e.g. hr,table) in IE8 will
+                                                       // break up the selection, safely manage it here. (#4795)
+                                                       range.moveToPosition( selected, CKEDITOR.POSITION_BEFORE_START );
+                                                       // Remove the control manually.
+                                                       selected.remove();
+                                                       range.select();
+
+                                                       editor.fire( 'saveSnapshot' );
+
+                                                       isHandled = 1;
+                                               } else if ( range.collapsed ) {
+                                                       // Handle the following special cases: (#6217)
+                                                       // 1. Del/Backspace key before/after table;
+                                                       // 2. Backspace Key after start of table.
+                                                       if ( ( block = path.block ) &&
+                                                                       ( next = block[ rtl ? 'getPrevious' : 'getNext' ]( isNotWhitespace ) ) &&
+                                                                       ( next.type == CKEDITOR.NODE_ELEMENT ) &&
+                                                                       next.is( 'table' ) &&
+                                                                       range[ rtl ? 'checkStartOfBlock' : 'checkEndOfBlock' ]() ) {
+                                                               editor.fire( 'saveSnapshot' );
+
+                                                               // Remove the current empty block.
+                                                               if ( range[ rtl ? 'checkEndOfBlock' : 'checkStartOfBlock' ]() )
+                                                                       block.remove();
+
+                                                               // Move cursor to the beginning/end of table cell.
+                                                               range[ 'moveToElementEdit' + ( rtl ? 'End' : 'Start' ) ]( next );
+                                                               range.select();
+
+                                                               editor.fire( 'saveSnapshot' );
+
+                                                               isHandled = 1;
+                                                       }
+                                                       else if ( path.blockLimit && path.blockLimit.is( 'td' ) &&
+                                                                       ( parent = path.blockLimit.getAscendant( 'table' ) ) &&
+                                                                       range.checkBoundaryOfElement( parent, rtl ? CKEDITOR.START : CKEDITOR.END ) &&
+                                                                       ( next = parent[ rtl ? 'getPrevious' : 'getNext' ]( isNotWhitespace ) ) ) {
+                                                               editor.fire( 'saveSnapshot' );
+
+                                                               // Move cursor to the end of previous block.
+                                                               range[ 'moveToElementEdit' + ( rtl ? 'End' : 'Start' ) ]( next );
+
+                                                               // Remove any previous empty block.
+                                                               if ( range.checkStartOfBlock() && range.checkEndOfBlock() )
+                                                                       next.remove();
+                                                               else
+                                                                       range.select();
+
+                                                               editor.fire( 'saveSnapshot' );
+
+                                                               isHandled = 1;
+                                                       }
+                                                       // BACKSPACE/DEL pressed at the start/end of table cell.
+                                                       else if ( ( parent = path.contains( [ 'td', 'th', 'caption' ] ) ) &&
+                                                                       range.checkBoundaryOfElement( parent, rtl ? CKEDITOR.START : CKEDITOR.END ) ) {
+                                                               isHandled = 1;
+                                                       }
+                                               }
+
+                                       }
+
+                                       return !isHandled;
+                               } );
+
+                               // On IE>=11 we need to fill blockless editable with <br> if it was deleted.
+                               if ( editor.blockless && CKEDITOR.env.ie && CKEDITOR.env.needsBrFiller ) {
+                                       this.attachListener( this, 'keyup', function( evt ) {
+                                               if ( evt.data.getKeystroke() in backspaceOrDelete && !this.getFirst( isNotEmpty ) ) {
+                                                       this.appendBogus();
+
+                                                       // Set the selection before bogus, because IE tends to put it after.
+                                                       var range = editor.createRange();
+                                                       range.moveToPosition( this, CKEDITOR.POSITION_AFTER_START );
+                                                       range.select();
+                                               }
+                                       } );
+                               }
+
+                               this.attachListener( this, 'dblclick', function( evt ) {
+                                       if ( editor.readOnly )
+                                               return false;
+
+                                       var data = { element: evt.data.getTarget() };
+                                       editor.fire( 'doubleclick', data );
+                               } );
+
+                               // Prevent automatic submission in IE #6336
+                               CKEDITOR.env.ie && this.attachListener( this, 'click', blockInputClick );
+
+                               // Gecko/Webkit need some help when selecting control type elements. (#3448)
+                               // We apply same behavior for IE Edge. (#13386)
+                               if ( !CKEDITOR.env.ie || CKEDITOR.env.edge ) {
+                                       this.attachListener( this, 'mousedown', function( ev ) {
+                                               var control = ev.data.getTarget();
+                                               // #11727. Note: htmlDP assures that input/textarea/select have contenteditable=false
+                                               // attributes. However, they also have data-cke-editable attribute, so isReadOnly() returns false,
+                                               // and therefore those elements are correctly selected by this code.
+                                               if ( control.is( 'img', 'hr', 'input', 'textarea', 'select' ) && !control.isReadOnly() ) {
+                                                       editor.getSelection().selectElement( control );
+
+                                                       // Prevent focus from stealing from the editable. (#9515)
+                                                       if ( control.is( 'input', 'textarea', 'select' ) )
+                                                               ev.data.preventDefault();
+                                               }
+                                       } );
+                               }
+
+                               // For some reason, after click event is done, IE Edge loses focus on the selected element. (#13386)
+                               if ( CKEDITOR.env.edge ) {
+                                       this.attachListener( this, 'mouseup', function( ev ) {
+                                               var selectedElement = ev.data.getTarget();
+                                               if ( selectedElement && selectedElement.is( 'img' ) ) {
+                                                       editor.getSelection().selectElement( selectedElement );
+                                               }
+                                       } );
+                               }
+
+                               // Prevent right click from selecting an empty block even
+                               // when selection is anchored inside it. (#5845)
+                               if ( CKEDITOR.env.gecko ) {
+                                       this.attachListener( this, 'mouseup', function( ev ) {
+                                               if ( ev.data.$.button == 2 ) {
+                                                       var target = ev.data.getTarget();
+
+                                                       if ( !target.getOuterHtml().replace( emptyParagraphRegexp, '' ) ) {
+                                                               var range = editor.createRange();
+                                                               range.moveToElementEditStart( target );
+                                                               range.select( true );
+                                                       }
+                                               }
+                                       } );
+                               }
+
+                               // Webkit: avoid from editing form control elements content.
+                               if ( CKEDITOR.env.webkit ) {
+                                       // Prevent from tick checkbox/radiobox/select
+                                       this.attachListener( this, 'click', function( ev ) {
+                                               if ( ev.data.getTarget().is( 'input', 'select' ) )
+                                                       ev.data.preventDefault();
+                                       } );
+
+                                       // Prevent from editig textfield/textarea value.
+                                       this.attachListener( this, 'mouseup', function( ev ) {
+                                               if ( ev.data.getTarget().is( 'input', 'textarea' ) )
+                                                       ev.data.preventDefault();
+                                       } );
+                               }
+
+                               // Prevent Webkit/Blink from going rogue when joining
+                               // blocks on BACKSPACE/DEL (#11861,#9998).
+                               if ( CKEDITOR.env.webkit ) {
+                                       this.attachListener( editor, 'key', function( evt ) {
+                                               if ( editor.readOnly ) {
+                                                       return true;
+                                               }
+
+                                               // Use getKey directly in order to ignore modifiers.
+                                               // Justification: http://dev.ckeditor.com/ticket/11861#comment:13
+                                               var key = evt.data.domEvent.getKey();
+
+                                               if ( !( key in backspaceOrDelete ) )
+                                                       return;
+
+                                               var backspace = key == 8,
+                                                       range = editor.getSelection().getRanges()[ 0 ],
+                                                       startPath = range.startPath();
+
+                                               if ( range.collapsed ) {
+                                                       if ( !mergeBlocksCollapsedSelection( editor, range, backspace, startPath ) )
+                                                               return;
+                                               } else {
+                                                       if ( !mergeBlocksNonCollapsedSelection( editor, range, startPath ) )
+                                                               return;
+                                               }
+
+                                               // Scroll to the new position of the caret (#11960).
+                                               editor.getSelection().scrollIntoView();
+                                               editor.fire( 'saveSnapshot' );
+
+                                               return false;
+                                       }, this, null, 100 ); // Later is better – do not override existing listeners.
+                               }
+                       }
+               },
+
+               _: {
+                       detach: function() {
+                               // Update the editor cached data with current data.
+                               this.editor.setData( this.editor.getData(), 0, 1 );
+
+                               this.clearListeners();
+                               this.restoreAttrs();
+
+                               // Cleanup our custom classes.
+                               var classes;
+                               if ( ( classes = this.removeCustomData( 'classes' ) ) ) {
+                                       while ( classes.length )
+                                               this.removeClass( classes.pop() );
+                               }
+
+                               // Remove contents stylesheet from document if it's the last usage.
+                               if ( !this.is( 'textarea' ) ) {
+                                       var doc = this.getDocument(),
+                                               head = doc.getHead();
+                                       if ( head.getCustomData( 'stylesheet' ) ) {
+                                               var refs = doc.getCustomData( 'stylesheet_ref' );
+                                               if ( !( --refs ) ) {
+                                                       doc.removeCustomData( 'stylesheet_ref' );
+                                                       var sheet = head.removeCustomData( 'stylesheet' );
+                                                       sheet.remove();
+                                               } else {
+                                                       doc.setCustomData( 'stylesheet_ref', refs );
+                                               }
+                                       }
+                               }
+
+                               this.editor.fire( 'contentDomUnload' );
+
+                               // Free up the editor reference.
+                               delete this.editor;
+                       }
+               }
+       } );
+
+       /**
+        * Creates, retrieves or detaches an editable element of the editor.
+        * This method should always be used instead of calling {@link CKEDITOR.editable} directly.
+        *
+        * @method editable
+        * @member CKEDITOR.editor
+        * @param {CKEDITOR.dom.element/CKEDITOR.editable} [elementOrEditable] The
+        * DOM element to become the editable or a {@link CKEDITOR.editable} object.
+        */
+       CKEDITOR.editor.prototype.editable = function( element ) {
+               var editable = this._.editable;
+
+               // This editor has already associated with
+               // an editable element, silently fails.
+               if ( editable && element )
+                       return 0;
+
+               if ( arguments.length ) {
+                       editable = this._.editable = element ? ( element instanceof CKEDITOR.editable ? element : new CKEDITOR.editable( this, element ) ) :
+                       // Detach the editable from editor.
+                       ( editable && editable.detach(), null );
+               }
+
+               // Just retrieve the editable.
+               return editable;
+       };
+
+       CKEDITOR.on( 'instanceLoaded', function( evt ) {
+               var editor = evt.editor;
+
+               // and flag that the element was locked by our code so it'll be editable by the editor functions (#6046).
+               editor.on( 'insertElement', function( evt ) {
+                       var element = evt.data;
+                       if ( element.type == CKEDITOR.NODE_ELEMENT && ( element.is( 'input' ) || element.is( 'textarea' ) ) ) {
+                               // // The element is still not inserted yet, force attribute-based check.
+                               if ( element.getAttribute( 'contentEditable' ) != 'false' )
+                                       element.data( 'cke-editable', element.hasAttribute( 'contenteditable' ) ? 'true' : '1' );
+                               element.setAttribute( 'contentEditable', false );
+                       }
+               } );
+
+               editor.on( 'selectionChange', function( evt ) {
+                       if ( editor.readOnly )
+                               return;
+
+                       // Auto fixing on some document structure weakness to enhance usabilities. (#3190 and #3189)
+                       var sel = editor.getSelection();
+                       // Do it only when selection is not locked. (#8222)
+                       if ( sel && !sel.isLocked ) {
+                               var isDirty = editor.checkDirty();
+
+                               // Lock undoM before touching DOM to prevent
+                               // recording these changes as separate snapshot.
+                               editor.fire( 'lockSnapshot' );
+                               fixDom( evt );
+                               editor.fire( 'unlockSnapshot' );
+
+                               !isDirty && editor.resetDirty();
+                       }
+               } );
+       } );
+
+       CKEDITOR.on( 'instanceCreated', function( evt ) {
+               var editor = evt.editor;
+
+               editor.on( 'mode', function() {
+
+                       var editable = editor.editable();
+
+                       // Setup proper ARIA roles and properties for inline editable, classic
+                       // (iframe-based) editable is instead handled by plugin.
+                       if ( editable && editable.isInline() ) {
+
+                               var ariaLabel = editor.title;
+
+                               editable.changeAttr( 'role', 'textbox' );
+                               editable.changeAttr( 'aria-label', ariaLabel );
+
+                               if ( ariaLabel )
+                                       editable.changeAttr( 'title', ariaLabel );
+
+                               var helpLabel = editor.fire( 'ariaEditorHelpLabel', {} ).label;
+                               if ( helpLabel ) {
+                                       // Put the voice label in different spaces, depending on element mode, so
+                                       // the DOM element get auto detached on mode reload or editor destroy.
+                                       var ct = this.ui.space( this.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ? 'top' : 'contents' );
+                                       if ( ct ) {
+                                               var ariaDescId = CKEDITOR.tools.getNextId(),
+                                                       desc = CKEDITOR.dom.element.createFromHtml( '<span id="' + ariaDescId + '" class="cke_voice_label">' + helpLabel + '</span>' );
+                                               ct.append( desc );
+                                               editable.changeAttr( 'aria-describedby', ariaDescId );
+                                       }
+                               }
+                       }
+               } );
+       } );
+
+       // #9222: Show text cursor in Gecko.
+       // Show default cursor over control elements on all non-IEs.
+       CKEDITOR.addCss( '.cke_editable{cursor:text}.cke_editable img,.cke_editable input,.cke_editable textarea{cursor:default}' );
+
+       //
+       //
+       // Bazillion helpers for the editable class and above listeners.
+       //
+       //
+
+       isNotWhitespace = CKEDITOR.dom.walker.whitespaces( true ),
+       isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true ),
+       isEmpty = CKEDITOR.dom.walker.empty(),
+       isBogus = CKEDITOR.dom.walker.bogus(),
+       // Matching an empty paragraph at the end of document.
+       emptyParagraphRegexp = /(^|<body\b[^>]*>)\s*<(p|div|address|h\d|center|pre)[^>]*>\s*(?:<br[^>]*>|&nbsp;|\u00A0|&#160;)?\s*(:?<\/\2>)?\s*(?=$|<\/body>)/gi;
+
+       // Auto-fixing block-less content by wrapping paragraph (#3190), prevent
+       // non-exitable-block by padding extra br.(#3189)
+       // Returns truly value when dom was changed, falsy otherwise.
+       function fixDom( evt ) {
+               var editor = evt.editor,
+                       path = evt.data.path,
+                       blockLimit = path.blockLimit,
+                       selection = evt.data.selection,
+                       range = selection.getRanges()[ 0 ],
+                       selectionUpdateNeeded;
+
+               if ( CKEDITOR.env.gecko || ( CKEDITOR.env.ie && CKEDITOR.env.needsBrFiller ) ) {
+                       var blockNeedsFiller = needsBrFiller( selection, path );
+                       if ( blockNeedsFiller ) {
+                               blockNeedsFiller.appendBogus();
+                               // IE tends to place selection after appended bogus, so we need to
+                               // select the original range (placed before bogus).
+                               selectionUpdateNeeded = CKEDITOR.env.ie;
+                       }
+               }
+
+               // When we're in block enter mode, a new paragraph will be established
+               // to encapsulate inline contents inside editable. (#3657)
+               // Don't autoparagraph if browser (namely - IE) incorrectly anchored selection
+               // inside non-editable content. This happens e.g. if non-editable block is the only
+               // content of editable.
+               if ( shouldAutoParagraph( editor, path.block, blockLimit ) && range.collapsed && !range.getCommonAncestor().isReadOnly() ) {
+                       var testRng = range.clone();
+                       testRng.enlarge( CKEDITOR.ENLARGE_BLOCK_CONTENTS );
+                       var walker = new CKEDITOR.dom.walker( testRng );
+                       walker.guard = function( node ) {
+                               return !isNotEmpty( node ) ||
+                                       node.type == CKEDITOR.NODE_COMMENT ||
+                                       node.isReadOnly();
+                       };
+
+                       // 1. Inline content discovered under cursor;
+                       // 2. Empty editable.
+                       if ( !walker.checkForward() || testRng.checkStartOfBlock() && testRng.checkEndOfBlock() ) {
+                               var fixedBlock = range.fixBlock( true, editor.activeEnterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' );
+
+                               // For IE<11, we should remove any filler node which was introduced before.
+                               if ( !CKEDITOR.env.needsBrFiller ) {
+                                       var first = fixedBlock.getFirst( isNotEmpty );
+                                       if ( first && isNbsp( first ) )
+                                               first.remove();
+                               }
+
+                               selectionUpdateNeeded = 1;
+
+                               // Cancel this selection change in favor of the next (correct). (#6811)
+                               evt.cancel();
+                       }
+               }
+
+               if ( selectionUpdateNeeded )
+                       range.select();
+       }
+
+       // Checks whether current selection requires br filler to be appended.
+       // @returns Block which needs filler or falsy value.
+       function needsBrFiller( selection, path ) {
+               // Fake selection does not need filler, because it is fake.
+               if ( selection.isFake )
+                       return 0;
+
+               // Ensure bogus br could help to move cursor (out of styles) to the end of block. (#7041)
+               var pathBlock = path.block || path.blockLimit,
+                       lastNode = pathBlock && pathBlock.getLast( isNotEmpty );
+
+               // Check some specialities of the current path block:
+               // 1. It is really displayed as block; (#7221)
+               // 2. It doesn't end with one inner block; (#7467)
+               // 3. It doesn't have bogus br yet.
+               if (
+                       pathBlock && pathBlock.isBlockBoundary() &&
+                       !( lastNode && lastNode.type == CKEDITOR.NODE_ELEMENT && lastNode.isBlockBoundary() ) &&
+                       !pathBlock.is( 'pre' ) && !pathBlock.getBogus()
+               )
+                       return pathBlock;
+       }
+
+       function blockInputClick( evt ) {
+               var element = evt.data.getTarget();
+               if ( element.is( 'input' ) ) {
+                       var type = element.getAttribute( 'type' );
+                       if ( type == 'submit' || type == 'reset' )
+                               evt.data.preventDefault();
+               }
+       }
+
+       function isNotEmpty( node ) {
+               return isNotWhitespace( node ) && isNotBookmark( node );
+       }
+
+       function isNbsp( node ) {
+               return node.type == CKEDITOR.NODE_TEXT && CKEDITOR.tools.trim( node.getText() ).match( /^(?:&nbsp;|\xa0)$/ );
+       }
+
+       function isNotBubbling( fn, src ) {
+               return function( evt ) {
+                       var other = evt.data.$.toElement || evt.data.$.fromElement || evt.data.$.relatedTarget;
+
+                       // First of all, other may simply be null/undefined.
+                       // Second of all, at least early versions of Spartan returned empty objects from evt.relatedTarget,
+                       // so let's also check the node type.
+                       other = ( other && other.nodeType == CKEDITOR.NODE_ELEMENT ) ? new CKEDITOR.dom.element( other ) : null;
+
+                       if ( !( other && ( src.equals( other ) || src.contains( other ) ) ) )
+                               fn.call( this, evt );
+               };
+       }
+
+       function hasBookmarks( element ) {
+               // We use getElementsByTag() instead of find() to retain compatibility with IE quirks mode.
+               var potentialBookmarks = element.getElementsByTag( 'span' ),
+                       i = 0,
+                       child;
+
+               if ( potentialBookmarks ) {
+                       while ( ( child = potentialBookmarks.getItem( i++ ) ) ) {
+                               if ( !isNotBookmark( child ) ) {
+                                       return true;
+                               }
+                       }
+               }
+
+               return false;
+       }
+
+       // Check if the entire table/list contents is selected.
+       function getSelectedTableList( sel ) {
+               var selected,
+                       range = sel.getRanges()[ 0 ],
+                       editable = sel.root,
+                       path = range.startPath(),
+                       structural = { table: 1, ul: 1, ol: 1, dl: 1 };
+
+               if ( path.contains( structural ) ) {
+                       // Clone the original range.
+                       var walkerRng = range.clone();
+
+                       // Enlarge the range: X<ul><li>[Y]</li></ul>X => [X<ul><li>]Y</li></ul>X
+                       walkerRng.collapse( 1 );
+                       walkerRng.setStartAt( editable, CKEDITOR.POSITION_AFTER_START );
+
+                       // Create a new walker.
+                       var walker = new CKEDITOR.dom.walker( walkerRng );
+
+                       // Assign a new guard to the walker.
+                       walker.guard = guard();
+
+                       // Go backwards checking for selected structural node.
+                       walker.checkBackward();
+
+                       // If there's a selected structured element when checking backwards,
+                       // then check the same forwards.
+                       if ( selected ) {
+                               // Clone the original range.
+                               walkerRng = range.clone();
+
+                               // Enlarge the range (assuming <ul> is selected element from guard):
+                               //
+                               //         X<ul><li>[Y]</li></ul>X    =>    X<ul><li>Y[</li></ul>]X
+                               //
+                               // If the walker went deeper down DOM than a while ago when traversing
+                               // backwards, then it doesn't make sense: an element must be selected
+                               // symmetrically. By placing range end **after previously selected node**,
+                               // we make sure we don't go no deeper in DOM when going forwards.
+                               walkerRng.collapse();
+                               walkerRng.setEndAt( selected, CKEDITOR.POSITION_AFTER_END );
+
+                               // Create a new walker.
+                               walker = new CKEDITOR.dom.walker( walkerRng );
+
+                               // Assign a new guard to the walker.
+                               walker.guard = guard( true );
+
+                               // Reset selected node.
+                               selected = false;
+
+                               // Go forwards checking for selected structural node.
+                               walker.checkForward();
+
+                               return selected;
+                       }
+               }
+
+               return null;
+
+               function guard( forwardGuard ) {
+                       return function( node, isWalkOut ) {
+                               // Save the encountered node as selected if going down the DOM structure
+                               // and the node is structured element.
+                               if ( isWalkOut && node.type == CKEDITOR.NODE_ELEMENT && node.is( structural ) )
+                                       selected = node;
+
+                               // Stop the walker when either traversing another non-empty node at the same
+                               // DOM level as in previous step.
+                               // NOTE: When going forwards, stop if encountered a bogus.
+                               if ( !isWalkOut && isNotEmpty( node ) && !( forwardGuard && isBogus( node ) ) )
+                                       return false;
+                       };
+               }
+       }
+
+       // Whether in given context (pathBlock, pathBlockLimit and editor settings)
+       // editor should automatically wrap inline contents with blocks.
+       function shouldAutoParagraph( editor, pathBlock, pathBlockLimit ) {
+               // Check whether pathBlock equals pathBlockLimit to support nested editable (#12162).
+               return editor.config.autoParagraph !== false &&
+                       editor.activeEnterMode != CKEDITOR.ENTER_BR &&
+                       (
+                               ( editor.editable().equals( pathBlockLimit ) && !pathBlock ) ||
+                               ( pathBlock && pathBlock.getAttribute( 'contenteditable' ) == 'true' )
+                       );
+       }
+
+       function autoParagraphTag( editor ) {
+               return ( editor.activeEnterMode != CKEDITOR.ENTER_BR && editor.config.autoParagraph !== false ) ? editor.activeEnterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false;
+       }
+
+       //
+       // Functions related to insertXXX methods
+       //
+       insert = ( function() {
+               'use strict';
+
+               var DTD = CKEDITOR.dtd;
+
+               // Inserts the given (valid) HTML into the range position (with range content deleted),
+               // guarantee it's result to be a valid DOM tree.
+               function insert( editable, type, data, range ) {
+                       var editor = editable.editor,
+                               dontFilter = false;
+
+                       if ( type == 'unfiltered_html' ) {
+                               type = 'html';
+                               dontFilter = true;
+                       }
+
+                       // Check range spans in non-editable.
+                       if ( range.checkReadOnly() )
+                               return;
+
+                       // RANGE PREPARATIONS
+
+                       var path = new CKEDITOR.dom.elementPath( range.startContainer, range.root ),
+                               // Let root be the nearest block that's impossible to be split
+                               // during html processing.
+                               blockLimit = path.blockLimit || range.root,
+                               // The "state" value.
+                               that = {
+                                       type: type,
+                                       dontFilter: dontFilter,
+                                       editable: editable,
+                                       editor: editor,
+                                       range: range,
+                                       blockLimit: blockLimit,
+                                       // During pre-processing / preparations startContainer of affectedRange should be placed
+                                       // in this element in which inserted or moved (in case when we merge blocks) content
+                                       // could create situation that will need merging inline elements.
+                                       // Examples:
+                                       // <div><b>A</b>^B</div> + <b>C</b> => <div><b>A</b><b>C</b>B</div> - affected container is <div>.
+                                       // <p><b>A[B</b></p><p><b>C]D</b></p> + E => <p><b>AE</b></p><p><b>D</b></p> =>
+                                       //              <p><b>AE</b><b>D</b></p> - affected container is <p> (in text mode).
+                                       mergeCandidates: [],
+                                       zombies: []
+                               };
+
+                       prepareRangeToDataInsertion( that );
+
+                       // DATA PROCESSING
+
+                       // Select range and stop execution.
+                       // If data has been totally emptied after the filtering,
+                       // any insertion is pointless (#10339).
+                       if ( data && processDataForInsertion( that, data ) ) {
+                               // DATA INSERTION
+                               insertDataIntoRange( that );
+                       }
+
+                       // FINAL CLEANUP
+                       // Set final range position and clean up.
+
+                       cleanupAfterInsertion( that );
+               }
+
+               // Prepare range to its data deletion.
+               // Delete its contents.
+               // Prepare it to insertion.
+               function prepareRangeToDataInsertion( that ) {
+                       var range = that.range,
+                               mergeCandidates = that.mergeCandidates,
+                               node, marker, path, startPath, endPath, previous, bm;
+
+                       // If range starts in inline element then insert a marker, so empty
+                       // inline elements won't be removed while range.deleteContents
+                       // and we will be able to move range back into this element.
+                       // E.g. 'aa<b>[bb</b>]cc' -> (after deleting) 'aa<b><span/></b>cc'
+                       if ( that.type == 'text' && range.shrink( CKEDITOR.SHRINK_ELEMENT, true, false ) ) {
+                               marker = CKEDITOR.dom.element.createFromHtml( '<span>&nbsp;</span>', range.document );
+                               range.insertNode( marker );
+                               range.setStartAfter( marker );
+                       }
+
+                       // By using path we can recover in which element was startContainer
+                       // before deleting contents.
+                       // Start and endPathElements will be used to squash selected blocks, after removing
+                       // selection contents. See rule 5.
+                       startPath = new CKEDITOR.dom.elementPath( range.startContainer );
+                       that.endPath = endPath = new CKEDITOR.dom.elementPath( range.endContainer );
+
+                       if ( !range.collapsed ) {
+                               // Anticipate the possibly empty block at the end of range after deletion.
+                               node = endPath.block || endPath.blockLimit;
+                               var ancestor = range.getCommonAncestor();
+                               if ( node && !( node.equals( ancestor ) || node.contains( ancestor ) ) && range.checkEndOfBlock() ) {
+                                       that.zombies.push( node );
+                               }
+
+                               range.deleteContents();
+                       }
+
+                       // Rule 4.
+                       // Move range into the previous block.
+                       while (
+                               ( previous = getRangePrevious( range ) ) && checkIfElement( previous ) && previous.isBlockBoundary() &&
+                               // Check if previousNode was parent of range's startContainer before deleteContents.
+                               startPath.contains( previous )
+                       )
+                               range.moveToPosition( previous, CKEDITOR.POSITION_BEFORE_END );
+
+                       // Rule 5.
+                       mergeAncestorElementsOfSelectionEnds( range, that.blockLimit, startPath, endPath );
+
+                       // Rule 1.
+                       if ( marker ) {
+                               // If marker was created then move collapsed range into its place.
+                               range.setEndBefore( marker );
+                               range.collapse();
+                               marker.remove();
+                       }
+
+                       // Split inline elements so HTML will be inserted with its own styles.
+                       path = range.startPath();
+                       if ( ( node = path.contains( isInline, false, 1 ) ) ) {
+                               range.splitElement( node );
+                               that.inlineStylesRoot = node;
+                               that.inlineStylesPeak = path.lastElement;
+                       }
+
+                       // Record inline merging candidates for later cleanup in place.
+                       bm = range.createBookmark();
+
+                       // 1. Inline siblings.
+                       node = bm.startNode.getPrevious( isNotEmpty );
+                       node && checkIfElement( node ) && isInline( node ) && mergeCandidates.push( node );
+                       node = bm.startNode.getNext( isNotEmpty );
+                       node && checkIfElement( node ) && isInline( node ) && mergeCandidates.push( node );
+
+                       // 2. Inline parents.
+                       node = bm.startNode;
+                       while ( ( node = node.getParent() ) && isInline( node ) )
+                               mergeCandidates.push( node );
+
+                       range.moveToBookmark( bm );
+               }
+
+               function processDataForInsertion( that, data ) {
+                       var range = that.range;
+
+                       // Rule 8. - wrap entire data in inline styles.
+                       // (e.g. <p><b>x^z</b></p> + <p>a</p><p>b</p> -> <b><p>a</p><p>b</p></b>)
+                       // Incorrect tags order will be fixed by htmlDataProcessor.
+                       if ( that.type == 'text' && that.inlineStylesRoot )
+                               data = wrapDataWithInlineStyles( data, that );
+
+
+                       var context = that.blockLimit.getName();
+
+                       // Wrap data to be inserted, to avoid losing leading whitespaces
+                       // when going through the below procedure.
+                       if ( /^\s+|\s+$/.test( data ) && 'span' in CKEDITOR.dtd[ context ] ) {
+                               var protect = '<span data-cke-marker="1">&nbsp;</span>';
+                               data =  protect + data + protect;
+                       }
+
+                       // Process the inserted html, in context of the insertion root.
+                       // Don't use the "fix for body" feature as auto paragraphing must
+                       // be handled during insertion.
+                       data = that.editor.dataProcessor.toHtml( data, {
+                               context: null,
+                               fixForBody: false,
+                               protectedWhitespaces: !!protect,
+                               dontFilter: that.dontFilter,
+                               // Use the current, contextual settings.
+                               filter: that.editor.activeFilter,
+                               enterMode: that.editor.activeEnterMode
+                       } );
+
+
+                       // Build the node list for insertion.
+                       var doc = range.document,
+                               wrapper = doc.createElement( 'body' );
+
+                       wrapper.setHtml( data );
+
+                       // Eventually remove the temporaries.
+                       if ( protect ) {
+                               wrapper.getFirst().remove();
+                               wrapper.getLast().remove();
+                       }
+
+                       // Rule 7.
+                       var block = range.startPath().block;
+                       if ( block &&                                                                                                   // Apply when there exists path block after deleting selection's content...
+                               !( block.getChildCount() == 1 && block.getBogus() ) ) {         // ... and the only content of this block isn't a bogus.
+                               stripBlockTagIfSingleLine( wrapper );
+                       }
+
+                       that.dataWrapper = wrapper;
+
+                       return data;
+               }
+
+               function insertDataIntoRange( that ) {
+                       var range = that.range,
+                               doc = range.document,
+                               path,
+                               blockLimit = that.blockLimit,
+                               nodesData, nodeData, node,
+                               nodeIndex = 0,
+                               bogus,
+                               bogusNeededBlocks = [],
+                               pathBlock, fixBlock,
+                               splittingContainer = 0,
+                               dontMoveCaret = 0,
+                               insertionContainer, toSplit, newContainer,
+                               startContainer = range.startContainer,
+                               endContainer = that.endPath.elements[ 0 ],
+                               filteredNodes,
+                               // If endContainer was merged into startContainer: <p>a[b</p><p>c]d</p>
+                               // or it's equal to startContainer: <p>a^b</p>
+                               // or different situation happened :P
+                               // then there's no separate container for the end of selection.
+                               pos = endContainer.getPosition( startContainer ),
+                               separateEndContainer = !!endContainer.getCommonAncestor( startContainer ) && // endC is not detached.
+                                       pos != CKEDITOR.POSITION_IDENTICAL && !( pos & CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_IS_CONTAINED ); // endC & endS are in separate branches.
+
+                       nodesData = extractNodesData( that.dataWrapper, that );
+
+                       removeBrsAdjacentToPastedBlocks( nodesData, range );
+
+                       for ( ; nodeIndex < nodesData.length; nodeIndex++ ) {
+                               nodeData = nodesData[ nodeIndex ];
+
+                               // Ignore trailing <brs>
+                               if ( nodeData.isLineBreak && splitOnLineBreak( range, blockLimit, nodeData ) ) {
+                                       // Do not move caret towards the text (in cleanupAfterInsertion),
+                                       // because caret was placed after a line break.
+                                       dontMoveCaret = nodeIndex > 0;
+                                       continue;
+                               }
+
+                               path = range.startPath();
+
+                               // Auto paragraphing.
+                               if ( !nodeData.isBlock && shouldAutoParagraph( that.editor, path.block, path.blockLimit ) && ( fixBlock = autoParagraphTag( that.editor ) ) ) {
+                                       fixBlock = doc.createElement( fixBlock );
+                                       fixBlock.appendBogus();
+                                       range.insertNode( fixBlock );
+                                       if ( CKEDITOR.env.needsBrFiller && ( bogus = fixBlock.getBogus() ) )
+                                               bogus.remove();
+                                       range.moveToPosition( fixBlock, CKEDITOR.POSITION_BEFORE_END );
+                               }
+
+                               node = range.startPath().block;
+
+                               // Remove any bogus element on the current path block for now, and mark
+                               // it for later compensation.
+                               if ( node && !node.equals( pathBlock ) ) {
+                                       bogus = node.getBogus();
+                                       if ( bogus ) {
+                                               bogus.remove();
+                                               bogusNeededBlocks.push( node );
+                                       }
+
+                                       pathBlock = node;
+                               }
+
+                               // First not allowed node reached - start splitting original container
+                               if ( nodeData.firstNotAllowed )
+                                       splittingContainer = 1;
+
+                               if ( splittingContainer && nodeData.isElement ) {
+                                       insertionContainer = range.startContainer;
+                                       toSplit = null;
+
+                                       // Find the first ancestor that can contain current node.
+                                       // This one won't be split.
+                                       while ( insertionContainer && !DTD[ insertionContainer.getName() ][ nodeData.name ] ) {
+                                               if ( insertionContainer.equals( blockLimit ) ) {
+                                                       insertionContainer = null;
+                                                       break;
+                                               }
+
+                                               toSplit = insertionContainer;
+                                               insertionContainer = insertionContainer.getParent();
+                                       }
+
+                                       // If split has to be done - do it and mark both ends as a possible zombies.
+                                       if ( insertionContainer ) {
+                                               if ( toSplit ) {
+                                                       newContainer = range.splitElement( toSplit );
+                                                       that.zombies.push( newContainer );
+                                                       that.zombies.push( toSplit );
+                                               }
+                                       }
+                                       // Unable to make the insertion happen in place, resort to the content filter.
+                                       else {
+                                               // If everything worked fine insertionContainer == blockLimit here.
+                                               filteredNodes = filterElement( nodeData.node, blockLimit.getName(), !nodeIndex, nodeIndex == nodesData.length - 1 );
+                                       }
+                               }
+
+                               if ( filteredNodes ) {
+                                       while ( ( node = filteredNodes.pop() ) )
+                                               range.insertNode( node );
+                                       filteredNodes = 0;
+                               } else {
+                                       // Insert current node at the start of range.
+                                       range.insertNode( nodeData.node );
+                               }
+
+                               // Move range to the endContainer for the final allowed elements.
+                               if ( nodeData.lastNotAllowed && nodeIndex < nodesData.length - 1 ) {
+                                       // If separateEndContainer exists move range there.
+                                       // Otherwise try to move range to container created during splitting.
+                                       // If this doesn't work - don't move range.
+                                       newContainer = separateEndContainer ? endContainer : newContainer;
+                                       newContainer && range.setEndAt( newContainer, CKEDITOR.POSITION_AFTER_START );
+                                       splittingContainer = 0;
+                               }
+
+                               // Collapse range after insertion to end.
+                               range.collapse();
+                       }
+
+                       // Rule 9. Non-editable content should be selected as a whole.
+                       if ( isSingleNonEditableElement( nodesData ) ) {
+                               dontMoveCaret = true;
+                               node = nodesData[ 0 ].node;
+                               range.setStartAt( node, CKEDITOR.POSITION_BEFORE_START );
+                               range.setEndAt( node, CKEDITOR.POSITION_AFTER_END );
+                       }
+
+                       that.dontMoveCaret = dontMoveCaret;
+                       that.bogusNeededBlocks = bogusNeededBlocks;
+               }
+
+               function cleanupAfterInsertion( that ) {
+                       var range = that.range,
+                               node, testRange, movedIntoInline,
+                               bogusNeededBlocks = that.bogusNeededBlocks,
+                               // Create a bookmark to defend against the following range deconstructing operations.
+                               bm = range.createBookmark();
+
+                       // Remove all elements that could be created while splitting nodes
+                       // with ranges at its start|end.
+                       // E.g. remove <div><p></p></div>
+                       // But not <div><p> </p></div>
+                       // And replace <div><p><span data="cke-bookmark"/></p></div> with found bookmark.
+                       while ( ( node = that.zombies.pop() ) ) {
+                               // Detached element.
+                               if ( !node.getParent() )
+                                       continue;
+
+                               testRange = range.clone();
+                               testRange.moveToElementEditStart( node );
+                               testRange.removeEmptyBlocksAtEnd();
+                       }
+
+                       if ( bogusNeededBlocks ) {
+                               // Bring back all block bogus nodes.
+                               while ( ( node = bogusNeededBlocks.pop() ) ) {
+                                       if ( CKEDITOR.env.needsBrFiller )
+                                               node.appendBogus();
+                                       else
+                                               node.append( range.document.createText( '\u00a0' ) );
+                               }
+                       }
+
+                       // Eventually merge identical inline elements.
+                       while ( ( node = that.mergeCandidates.pop() ) )
+                               node.mergeSiblings();
+
+                       range.moveToBookmark( bm );
+
+                       // Rule 3.
+                       // Shrink range to the BEFOREEND of previous innermost editable node in source order.
+
+                       if ( !that.dontMoveCaret ) {
+                               node = getRangePrevious( range );
+
+                               while ( node && checkIfElement( node ) && !node.is( DTD.$empty ) ) {
+                                       if ( node.isBlockBoundary() )
+                                               range.moveToPosition( node, CKEDITOR.POSITION_BEFORE_END );
+                                       else {
+                                               // Don't move into inline element (which ends with a text node)
+                                               // found which contains white-space at its end.
+                                               // If not - move range's end to the end of this element.
+                                               if ( isInline( node ) && node.getHtml().match( /(\s|&nbsp;)$/g ) ) {
+                                                       movedIntoInline = null;
+                                                       break;
+                                               }
+
+                                               movedIntoInline = range.clone();
+                                               movedIntoInline.moveToPosition( node, CKEDITOR.POSITION_BEFORE_END );
+                                       }
+
+                                       node = node.getLast( isNotEmpty );
+                               }
+
+                               movedIntoInline && range.moveToRange( movedIntoInline );
+                       }
+
+               }
+
+               //
+               // HELPERS ------------------------------------------------------------
+               //
+
+               function checkIfElement( node ) {
+                       return node.type == CKEDITOR.NODE_ELEMENT;
+               }
+
+               function extractNodesData( dataWrapper, that ) {
+                       var node, sibling, nodeName, allowed,
+                               nodesData = [],
+                               startContainer = that.range.startContainer,
+                               path = that.range.startPath(),
+                               allowedNames = DTD[ startContainer.getName() ],
+                               nodeIndex = 0,
+                               nodesList = dataWrapper.getChildren(),
+                               nodesCount = nodesList.count(),
+                               firstNotAllowed = -1,
+                               lastNotAllowed = -1,
+                               lineBreak = 0,
+                               blockSibling;
+
+                       // Selection start within a list.
+                       var insideOfList = path.contains( DTD.$list );
+
+                       for ( ; nodeIndex < nodesCount; ++nodeIndex ) {
+                               node = nodesList.getItem( nodeIndex );
+
+                               if ( checkIfElement( node ) ) {
+                                       nodeName = node.getName();
+
+                                       // Extract only the list items, when insertion happens
+                                       // inside of a list, reads as rearrange list items. (#7957)
+                                       if ( insideOfList && nodeName in CKEDITOR.dtd.$list ) {
+                                               nodesData = nodesData.concat( extractNodesData( node, that ) );
+                                               continue;
+                                       }
+
+                                       allowed = !!allowedNames[ nodeName ];
+
+                                       // Mark <brs data-cke-eol="1"> at the beginning and at the end.
+                                       if ( nodeName == 'br' && node.data( 'cke-eol' ) && ( !nodeIndex || nodeIndex == nodesCount - 1 ) ) {
+                                               sibling = nodeIndex ? nodesData[ nodeIndex - 1 ].node : nodesList.getItem( nodeIndex + 1 );
+
+                                               // Line break has to have sibling which is not an <br>.
+                                               lineBreak = sibling && ( !checkIfElement( sibling ) || !sibling.is( 'br' ) );
+                                               // Line break has block element as a sibling.
+                                               blockSibling = sibling && checkIfElement( sibling ) && DTD.$block[ sibling.getName() ];
+                                       }
+
+                                       if ( firstNotAllowed == -1 && !allowed )
+                                               firstNotAllowed = nodeIndex;
+                                       if ( !allowed )
+                                               lastNotAllowed = nodeIndex;
+
+                                       nodesData.push( {
+                                               isElement: 1,
+                                               isLineBreak: lineBreak,
+                                               isBlock: node.isBlockBoundary(),
+                                               hasBlockSibling: blockSibling,
+                                               node: node,
+                                               name: nodeName,
+                                               allowed: allowed
+                                       } );
+
+                                       lineBreak = 0;
+                                       blockSibling = 0;
+                               } else {
+                                       nodesData.push( { isElement: 0, node: node, allowed: 1 } );
+                               }
+                       }
+
+                       // Mark first node that cannot be inserted directly into startContainer
+                       // and last node for which startContainer has to be split.
+                       if ( firstNotAllowed > -1 )
+                               nodesData[ firstNotAllowed ].firstNotAllowed = 1;
+                       if ( lastNotAllowed > -1 )
+                               nodesData[ lastNotAllowed ].lastNotAllowed = 1;
+
+                       return nodesData;
+               }
+
+               // TODO: Review content transformation rules on filtering element.
+               function filterElement( element, parentName, isFirst, isLast ) {
+                       var nodes = filterElementInner( element, parentName ),
+                               nodes2 = [],
+                               nodesCount = nodes.length,
+                               nodeIndex = 0,
+                               node,
+                               afterSpace = 0,
+                               lastSpaceIndex = -1;
+
+                       // Remove duplicated spaces and spaces at the:
+                       // * beginnig if filtered element isFirst (isFirst that's going to be inserted)
+                       // * end if filtered element isLast.
+                       for ( ; nodeIndex < nodesCount; nodeIndex++ ) {
+                               node = nodes[ nodeIndex ];
+
+                               if ( node == ' ' ) {
+                                       // Don't push doubled space and if it's leading space for insertion.
+                                       if ( !afterSpace && !( isFirst && !nodeIndex ) ) {
+                                               nodes2.push( new CKEDITOR.dom.text( ' ' ) );
+                                               lastSpaceIndex = nodes2.length;
+                                       }
+                                       afterSpace = 1;
+                               } else {
+                                       nodes2.push( node );
+                                       afterSpace = 0;
+                               }
+                       }
+
+                       // Remove trailing space.
+                       if ( isLast && lastSpaceIndex == nodes2.length )
+                               nodes2.pop();
+
+                       return nodes2;
+               }
+
+               function filterElementInner( element, parentName ) {
+                       var nodes = [],
+                               children = element.getChildren(),
+                               childrenCount = children.count(),
+                               child,
+                               childIndex = 0,
+                               allowedNames = DTD[ parentName ],
+                               surroundBySpaces = !element.is( DTD.$inline ) || element.is( 'br' );
+
+                       if ( surroundBySpaces )
+                               nodes.push( ' ' );
+
+                       for ( ; childIndex < childrenCount; childIndex++ ) {
+                               child = children.getItem( childIndex );
+
+                               if ( checkIfElement( child ) && !child.is( allowedNames ) )
+                                       nodes = nodes.concat( filterElementInner( child, parentName ) );
+                               else
+                                       nodes.push( child );
+                       }
+
+                       if ( surroundBySpaces )
+                               nodes.push( ' ' );
+
+                       return nodes;
+               }
+
+               function getRangePrevious( range ) {
+                       return checkIfElement( range.startContainer ) && range.startContainer.getChild( range.startOffset - 1 );
+               }
+
+               function isInline( node ) {
+                       return node && checkIfElement( node ) && ( node.is( DTD.$removeEmpty ) || node.is( 'a' ) && !node.isBlockBoundary() );
+               }
+
+               // Checks if only non-editable element is being inserted.
+               function isSingleNonEditableElement( nodesData ) {
+                       if ( nodesData.length != 1 )
+                               return false;
+
+                       var nodeData = nodesData[ 0 ];
+
+                       return nodeData.isElement && ( nodeData.node.getAttribute( 'contenteditable' ) == 'false' );
+               }
+
+               var blockMergedTags = { p: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, ul: 1, ol: 1, li: 1, pre: 1, dl: 1, blockquote: 1 };
+
+               // See rule 5. in TCs.
+               // Initial situation:
+               // <ul><li>AA^</li></ul><ul><li>BB</li></ul>
+               // We're looking for 2nd <ul>, comparing with 1st <ul> and merging.
+               // We're not merging if caret is between these elements.
+               function mergeAncestorElementsOfSelectionEnds( range, blockLimit, startPath, endPath ) {
+                       var walkerRange = range.clone(),
+                               walker, nextNode, previousNode;
+
+                       walkerRange.setEndAt( blockLimit, CKEDITOR.POSITION_BEFORE_END );
+                       walker = new CKEDITOR.dom.walker( walkerRange );
+
+                       if ( ( nextNode = walker.next() ) &&                                                    // Find next source node
+                               checkIfElement( nextNode ) &&                                                           // which is an element
+                               blockMergedTags[ nextNode.getName() ] &&                                        // that can be merged.
+                               ( previousNode = nextNode.getPrevious() ) &&                            // Take previous one
+                               checkIfElement( previousNode ) &&                                                       // which also has to be an element.
+                               !previousNode.getParent().equals( range.startContainer ) && // Fail if caret is on the same level.
+                                                                                                                                                       // This means that caret is between these nodes.
+                               startPath.contains( previousNode ) &&                                           // Elements path of start of selection has
+                               endPath.contains( nextNode ) &&                                                         // to contain prevNode and vice versa.
+                               nextNode.isIdentical( previousNode )                                            // Check if elements are identical.
+                       ) {
+                               // Merge blocks and repeat.
+                               nextNode.moveChildren( previousNode );
+                               nextNode.remove();
+                               mergeAncestorElementsOfSelectionEnds( range, blockLimit, startPath, endPath );
+                       }
+               }
+
+               // If last node that will be inserted is a block (but not a <br>)
+               // and it will be inserted right before <br> remove this <br>.
+               // Do the same for the first element that will be inserted and preceding <br>.
+               function removeBrsAdjacentToPastedBlocks( nodesData, range ) {
+                       var succeedingNode = range.endContainer.getChild( range.endOffset ),
+                               precedingNode = range.endContainer.getChild( range.endOffset - 1 );
+
+                       if ( succeedingNode )
+                               remove( succeedingNode, nodesData[ nodesData.length - 1 ] );
+
+                       if ( precedingNode && remove( precedingNode, nodesData[ 0 ] ) ) {
+                               // If preceding <br> was removed - move range left.
+                               range.setEnd( range.endContainer, range.endOffset - 1 );
+                               range.collapse();
+                       }
+
+                       function remove( maybeBr, maybeBlockData ) {
+                               if ( maybeBlockData.isBlock && maybeBlockData.isElement && !maybeBlockData.node.is( 'br' ) &&
+                                       checkIfElement( maybeBr ) && maybeBr.is( 'br' ) ) {
+                                       maybeBr.remove();
+                                       return 1;
+                               }
+                       }
+               }
+
+               // Return 1 if <br> should be skipped when inserting, 0 otherwise.
+               function splitOnLineBreak( range, blockLimit, nodeData ) {
+                       var firstBlockAscendant, pos;
+
+                       if ( nodeData.hasBlockSibling )
+                               return 1;
+
+                       firstBlockAscendant = range.startContainer.getAscendant( DTD.$block, 1 );
+                       if ( !firstBlockAscendant || !firstBlockAscendant.is( { div: 1, p: 1 } ) )
+                               return 0;
+
+                       pos = firstBlockAscendant.getPosition( blockLimit );
+
+                       if ( pos == CKEDITOR.POSITION_IDENTICAL || pos == CKEDITOR.POSITION_CONTAINS )
+                               return 0;
+
+                       var newContainer = range.splitElement( firstBlockAscendant );
+                       range.moveToPosition( newContainer, CKEDITOR.POSITION_AFTER_START );
+
+                       return 1;
+               }
+
+               var stripSingleBlockTags = { p: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1 },
+                       inlineButNotBr = CKEDITOR.tools.extend( {}, DTD.$inline );
+               delete inlineButNotBr.br;
+
+               // Rule 7.
+               function stripBlockTagIfSingleLine( dataWrapper ) {
+                       var block, children;
+
+                       if ( dataWrapper.getChildCount() == 1 &&                                        // Only one node bein inserted.
+                               checkIfElement( block = dataWrapper.getFirst() ) &&             // And it's an element.
+                               block.is( stripSingleBlockTags ) &&                                             // That's <p> or <div> or header.
+                               !block.hasAttribute( 'contenteditable' )                                // It's not a non-editable block or nested editable.
+                       ) {
+                               // Check children not containing block.
+                               children = block.getElementsByTag( '*' );
+                               for ( var i = 0, child, count = children.count(); i < count; i++ ) {
+                                       child = children.getItem( i );
+                                       if ( !child.is( inlineButNotBr ) )
+                                               return;
+                               }
+
+                               block.moveChildren( block.getParent( 1 ) );
+                               block.remove();
+                       }
+               }
+
+               function wrapDataWithInlineStyles( data, that ) {
+                       var element = that.inlineStylesPeak,
+                               doc = element.getDocument(),
+                               wrapper = doc.createText( '{cke-peak}' ),
+                               limit = that.inlineStylesRoot.getParent();
+
+                       while ( !element.equals( limit ) ) {
+                               wrapper = wrapper.appendTo( element.clone() );
+                               element = element.getParent();
+                       }
+
+                       // Don't use String.replace because it fails in IE7 if special replacement
+                       // characters ($$, $&, etc.) are in data (#10367).
+                       return wrapper.getOuterHtml().split( '{cke-peak}' ).join( data );
+               }
+
+               return insert;
+       } )();
+
+       function afterInsert( editable ) {
+               var editor = editable.editor;
+
+               // Scroll using selection, not ranges, to affect native pastes.
+               editor.getSelection().scrollIntoView();
+
+               // Save snaps after the whole execution completed.
+               // This's a workaround for make DOM modification's happened after
+               // 'insertElement' to be included either, e.g. Form-based dialogs' 'commitContents'
+               // call.
+               setTimeout( function() {
+                       editor.fire( 'saveSnapshot' );
+               }, 0 );
+       }
+
+       // 1. Fixes a range which is a result of deleteContents() and is placed in an intermediate element (see dtd.$intermediate),
+       // inside a table. A goal is to find a closest <td> or <th> element and when this fails, recreate the structure of the table.
+       // 2. Fixes empty cells by appending bogus <br>s or deleting empty text nodes in IE<=8 case.
+       fixTableAfterContentsDeletion = ( function() {
+               // Creates an element walker which can only "go deeper". It won't
+               // move out from any element. Therefore it can be used to find <td>x</td> in cases like:
+               // <table><tbody><tr><td>x</td></tr></tbody>^<tfoot>...
+               function getFixTableSelectionWalker( testRange ) {
+                       var walker = new CKEDITOR.dom.walker( testRange );
+                       walker.guard = function( node, isMovingOut ) {
+                               if ( isMovingOut )
+                                       return false;
+                               if ( node.type == CKEDITOR.NODE_ELEMENT )
+                                       return node.is( CKEDITOR.dtd.$tableContent );
+                       };
+                       walker.evaluator = function( node ) {
+                               return node.type == CKEDITOR.NODE_ELEMENT;
+                       };
+
+                       return walker;
+               }
+
+               function fixTableStructure( element, newElementName, appendToStart ) {
+                       var temp = element.getDocument().createElement( newElementName );
+                       element.append( temp, appendToStart );
+                       return temp;
+               }
+
+               // Fix empty cells. This means:
+               // * add bogus <br> if browser needs it
+               // * remove empty text nodes on IE8, because it will crash (http://dev.ckeditor.com/ticket/11183#comment:8).
+               function fixEmptyCells( cells ) {
+                       var i = cells.count(),
+                               cell;
+
+                       for ( i; i-- > 0; ) {
+                               cell = cells.getItem( i );
+
+                               if ( !CKEDITOR.tools.trim( cell.getHtml() ) ) {
+                                       cell.appendBogus();
+                                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && cell.getChildCount() )
+                                               cell.getFirst().remove();
+                               }
+                       }
+               }
+
+               return function( range ) {
+                       var container = range.startContainer,
+                               table = container.getAscendant( 'table', 1 ),
+                               testRange,
+                               deeperSibling,
+                               appendToStart = false;
+
+                       fixEmptyCells( table.getElementsByTag( 'td' ) );
+                       fixEmptyCells( table.getElementsByTag( 'th' ) );
+
+                       // Look left.
+                       testRange = range.clone();
+                       testRange.setStart( container, 0 );
+                       deeperSibling = getFixTableSelectionWalker( testRange ).lastBackward();
+
+                       // If left is empty, look right.
+                       if ( !deeperSibling ) {
+                               testRange = range.clone();
+                               testRange.setEndAt( container, CKEDITOR.POSITION_BEFORE_END );
+                               deeperSibling = getFixTableSelectionWalker( testRange ).lastForward();
+                               appendToStart = true;
+                       }
+
+                       // If there's no deeper nested element in both direction - container is empty - we'll use it then.
+                       if ( !deeperSibling )
+                               deeperSibling = container;
+
+                       // Fix structure...
+
+                       // We found a table what means that it's empty - remove it completely.
+                       if ( deeperSibling.is( 'table' ) ) {
+                               range.setStartAt( deeperSibling, CKEDITOR.POSITION_BEFORE_START );
+                               range.collapse( true );
+                               deeperSibling.remove();
+                               return;
+                       }
+
+                       // Found an empty txxx element - append tr.
+                       if ( deeperSibling.is( { tbody: 1, thead: 1, tfoot: 1 } ) )
+                               deeperSibling = fixTableStructure( deeperSibling, 'tr', appendToStart );
+
+                       // Found an empty tr element - append td/th.
+                       if ( deeperSibling.is( 'tr' ) )
+                               deeperSibling = fixTableStructure( deeperSibling, deeperSibling.getParent().is( 'thead' ) ? 'th' : 'td', appendToStart );
+
+                       // To avoid setting selection after bogus, remove it from the current cell.
+                       // We can safely do that, because we'll insert element into that cell.
+                       var bogus = deeperSibling.getBogus();
+                       if ( bogus )
+                               bogus.remove();
+
+                       range.moveToPosition( deeperSibling, appendToStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
+               };
+       } )();
+
+       fixListAfterContentsDelete = ( function() {
+               // Creates an element walker which operates only within lists.
+               function getFixListSelectionWalker( testRange ) {
+                       var walker = new CKEDITOR.dom.walker( testRange );
+                       walker.guard = function( node, isMovingOut ) {
+                               if ( isMovingOut )
+                                       return false;
+                               if ( node.type == CKEDITOR.NODE_ELEMENT )
+                                       return node.is( CKEDITOR.dtd.$list ) || node.is( CKEDITOR.dtd.$listItem );
+                       };
+                       walker.evaluator = function( node ) {
+                               return node.type == CKEDITOR.NODE_ELEMENT && node.is( CKEDITOR.dtd.$listItem );
+                       };
+
+                       return walker;
+               }
+
+               return function( range ) {
+                       var container = range.startContainer,
+                               appendToStart = false,
+                               testRange,
+                               deeperSibling;
+
+                       // Look left.
+                       testRange = range.clone();
+                       testRange.setStart( container, 0 );
+                       deeperSibling = getFixListSelectionWalker( testRange ).lastBackward();
+
+                       // If left is empty, look right.
+                       if ( !deeperSibling ) {
+                               testRange = range.clone();
+                               testRange.setEndAt( container, CKEDITOR.POSITION_BEFORE_END );
+                               deeperSibling = getFixListSelectionWalker( testRange ).lastForward();
+                               appendToStart = true;
+                       }
+
+                       // If there's no deeper nested element in both direction - container is empty - we'll use it then.
+                       if ( !deeperSibling )
+                               deeperSibling = container;
+
+                       // We found a list what means that it's empty - remove it completely.
+                       if ( deeperSibling.is( CKEDITOR.dtd.$list ) ) {
+                               range.setStartAt( deeperSibling, CKEDITOR.POSITION_BEFORE_START );
+                               range.collapse( true );
+                               deeperSibling.remove();
+                               return;
+                       }
+
+                       // To avoid setting selection after bogus, remove it from the target list item.
+                       // We can safely do that, because we'll insert element into that cell.
+                       var bogus = deeperSibling.getBogus();
+                       if ( bogus )
+                               bogus.remove();
+
+                       range.moveToPosition( deeperSibling, appendToStart ? CKEDITOR.POSITION_AFTER_START : CKEDITOR.POSITION_BEFORE_END );
+                       range.select();
+               };
+       } )();
+
+       function mergeBlocksCollapsedSelection( editor, range, backspace, startPath ) {
+               var startBlock = startPath.block;
+
+               // Selection must be collapsed and to be anchored in a block.
+               if ( !startBlock )
+                       return false;
+
+               // Exclude cases where, i.e. if pressed arrow key, selection
+               // would move within the same block (merge inside a block).
+               if ( !range[ backspace ? 'checkStartOfBlock' : 'checkEndOfBlock' ]() )
+                       return false;
+
+               // Make sure, there's an editable position to put selection,
+               // which i.e. would be used if pressed arrow key, but abort
+               // if such position exists but means a selected non-editable element.
+               if ( !range.moveToClosestEditablePosition( startBlock, !backspace ) || !range.collapsed )
+                       return false;
+
+               // Handle special case, when block's sibling is a <hr>. Delete it and keep selection
+               // in the same place (http://dev.ckeditor.com/ticket/11861#comment:9).
+               if ( range.startContainer.type == CKEDITOR.NODE_ELEMENT ) {
+                       var touched = range.startContainer.getChild( range.startOffset - ( backspace ? 1 : 0 ) );
+                       if ( touched && touched.type  == CKEDITOR.NODE_ELEMENT && touched.is( 'hr' ) ) {
+                               editor.fire( 'saveSnapshot' );
+                               touched.remove();
+                               return true;
+                       }
+               }
+
+               var siblingBlock = range.startPath().block;
+
+               // Abort if an editable position exists, but either it's not
+               // in a block or that block is the parent of the start block
+               // (merging child into parent).
+               if ( !siblingBlock || ( siblingBlock && siblingBlock.contains( startBlock ) ) )
+                       return;
+
+               editor.fire( 'saveSnapshot' );
+
+               // Remove bogus to avoid duplicated boguses.
+               var bogus;
+               if ( ( bogus = ( backspace ? siblingBlock : startBlock ).getBogus() ) )
+                       bogus.remove();
+
+               // Save selection. It will be restored.
+               var selection = editor.getSelection(),
+                       bookmarks = selection.createBookmarks();
+
+               // Merge blocks.
+               ( backspace ? startBlock : siblingBlock ).moveChildren( backspace ? siblingBlock : startBlock, false );
+
+               // Also merge children along with parents.
+               startPath.lastElement.mergeSiblings();
+
+               // Cut off removable branch of the DOM tree.
+               pruneEmptyDisjointAncestors( startBlock, siblingBlock, !backspace );
+
+               // Restore selection.
+               selection.selectBookmarks( bookmarks );
+
+               return true;
+       }
+
+       function mergeBlocksNonCollapsedSelection( editor, range, startPath ) {
+               var startBlock = startPath.block,
+                       endPath = range.endPath(),
+                       endBlock = endPath.block;
+
+               // Selection must be anchored in two different blocks.
+               if ( !startBlock || !endBlock || startBlock.equals( endBlock ) )
+                       return false;
+
+               editor.fire( 'saveSnapshot' );
+
+               // Remove bogus to avoid duplicated boguses.
+               var bogus;
+               if ( ( bogus = startBlock.getBogus() ) )
+                       bogus.remove();
+
+               // Changing end container to element from text node (#12503).
+               range.enlarge( CKEDITOR.ENLARGE_INLINE );
+
+               // Delete range contents. Do NOT merge. Merging is weird.
+               range.deleteContents();
+
+               // If something has left of the block to be merged, clean it up.
+               // It may happen when merging with list items.
+               if ( endBlock.getParent() ) {
+                       // Move children to the first block.
+                       endBlock.moveChildren( startBlock, false );
+
+                       // ...and merge them if that's possible.
+                       startPath.lastElement.mergeSiblings();
+
+                       // If expanded selection, things are always merged like with BACKSPACE.
+                       pruneEmptyDisjointAncestors( startBlock, endBlock, true );
+               }
+
+               // Make sure the result selection is collapsed.
+               range = editor.getSelection().getRanges()[ 0 ];
+               range.collapse( 1 );
+
+               // Optimizing range containers from text nodes to elements (#12503).
+               range.optimize();
+               if ( range.startContainer.getHtml() === '' ) {
+                       range.startContainer.appendBogus();
+               }
+
+               range.select();
+
+               return true;
+       }
+
+       // Finds the innermost child of common parent, which,
+       // if removed, removes nothing but the contents of the element.
+       //
+       //      before: <div><p><strong>first</strong></p><p>second</p></div>
+       //      after:  <div><p>second</p></div>
+       //
+       //      before: <div><p>x<strong>first</strong></p><p>second</p></div>
+       //      after:  <div><p>x</p><p>second</p></div>
+       //
+       //      isPruneToEnd=true
+       //      before: <div><p><strong>first</strong></p><p>second</p></div>
+       //      after:  <div><p><strong>first</strong></p></div>
+       //
+       // @param {CKEDITOR.dom.element} first
+       // @param {CKEDITOR.dom.element} second
+       // @param {Boolean} isPruneToEnd
+       function pruneEmptyDisjointAncestors( first, second, isPruneToEnd ) {
+               var commonParent = first.getCommonAncestor( second ),
+                       node = isPruneToEnd ? second : first,
+                       removableParent = node;
+
+               while ( ( node = node.getParent() ) && !commonParent.equals( node ) && node.getChildCount() == 1 )
+                       removableParent = node;
+
+               removableParent.remove();
+       }
+
+       //
+       // Helpers for editable.getHtmlFromRange.
+       //
+       getHtmlFromRangeHelpers = {
+               eol: {
+                       detect: function( that, editable ) {
+                               var range = that.range,
+                                       rangeStart = range.clone(),
+                                       rangeEnd = range.clone(),
+
+                                       startPath = new CKEDITOR.dom.elementPath( range.startContainer, editable ),
+                                       endPath = new CKEDITOR.dom.elementPath( range.endContainer, editable );
+
+                               // Note: checkBoundaryOfElement will not work on original range as CKEDITOR.START|END
+                               // means that range start|end must be literally anchored at block start|end, e.g.
+                               //
+                               //              <p>a{</p><p>}b</p>
+                               //
+                               // will return false for both paragraphs but two similar ranges
+                               //
+                               //              <p>a{}</p><p>{}b</p>
+                               //
+                               // will return true if checked separately.
+                               rangeStart.collapse( 1 );
+                               rangeEnd.collapse();
+
+                               if ( startPath.block && rangeStart.checkBoundaryOfElement( startPath.block, CKEDITOR.END ) ) {
+                                       range.setStartAfter( startPath.block );
+                                       that.prependEolBr = 1;
+                               }
+
+                               if ( endPath.block && rangeEnd.checkBoundaryOfElement( endPath.block, CKEDITOR.START ) ) {
+                                       range.setEndBefore( endPath.block );
+                                       that.appendEolBr = 1;
+                               }
+                       },
+
+                       fix: function( that, editable ) {
+                               var doc = editable.getDocument(),
+                                       appended;
+
+                               // Append <br data-cke-eol="1"> to the fragment.
+                               if ( that.appendEolBr ) {
+                                       appended = this.createEolBr( doc );
+                                       that.fragment.append( appended );
+                               }
+
+                               // Prepend <br data-cke-eol="1"> to the fragment but avoid duplicates. Such
+                               // elements should never follow each other in DOM.
+                               if ( that.prependEolBr && ( !appended || appended.getPrevious() ) ) {
+                                       that.fragment.append( this.createEolBr( doc ), 1 );
+                               }
+                       },
+
+                       createEolBr: function( doc ) {
+                               return doc.createElement( 'br', {
+                                       attributes: {
+                                               'data-cke-eol': 1
+                                       }
+                               } );
+                       }
+               },
+
+               bogus: {
+                       exclude: function( that ) {
+                               var boundaryNodes = that.range.getBoundaryNodes(),
+                                       startNode = boundaryNodes.startNode,
+                                       endNode = boundaryNodes.endNode;
+
+                               // If bogus is the last node in range but not the only node, exclude it.
+                               if ( endNode && isBogus( endNode ) && ( !startNode || !startNode.equals( endNode ) ) )
+                                       that.range.setEndBefore( endNode );
+                       }
+               },
+
+               tree: {
+                       rebuild: function( that, editable ) {
+                               var range = that.range,
+                                       node = range.getCommonAncestor(),
+
+                                       // A path relative to the common ancestor.
+                                       commonPath = new CKEDITOR.dom.elementPath( node, editable ),
+                                       startPath = new CKEDITOR.dom.elementPath( range.startContainer, editable ),
+                                       endPath = new CKEDITOR.dom.elementPath( range.endContainer, editable ),
+                                       limit;
+
+                               if ( node.type == CKEDITOR.NODE_TEXT )
+                                       node = node.getParent();
+
+                               // Fix DOM of partially enclosed tables
+                               //              <table><tbody><tr><td>a{b</td><td>c}d</td></tr></tbody></table>
+                               // Full table is returned
+                               //              <table><tbody><tr><td>b</td><td>c</td></tr></tbody></table>
+                               // instead of
+                               //              <td>b</td><td>c</td>
+                               if ( commonPath.blockLimit.is( { tr: 1, table: 1 } ) ) {
+                                       var tableParent = commonPath.contains( 'table' ).getParent();
+
+                                       limit = function( node ) {
+                                               return !node.equals( tableParent );
+                                       };
+                               }
+
+                               // Fix DOM in the following case
+                               //              <ol><li>a{b<ul><li>c}d</li></ul></li></ol>
+                               // Full list is returned
+                               //              <ol><li>b<ul><li>c</li></ul></li></ol>
+                               // instead of
+                               //              b<ul><li>c</li></ul>
+                               else if ( commonPath.block && commonPath.block.is( CKEDITOR.dtd.$listItem ) ) {
+                                       var startList = startPath.contains( CKEDITOR.dtd.$list ),
+                                               endList = endPath.contains( CKEDITOR.dtd.$list );
+
+                                       if ( !startList.equals( endList ) ) {
+                                               var listParent = commonPath.contains( CKEDITOR.dtd.$list ).getParent();
+
+                                               limit = function( node ) {
+                                                       return !node.equals( listParent );
+                                               };
+                                       }
+                               }
+
+                               // If not defined, use generic limit function.
+                               if ( !limit ) {
+                                       limit = function( node ) {
+                                               return !node.equals( commonPath.block ) && !node.equals( commonPath.blockLimit );
+                                       };
+                               }
+
+                               this.rebuildFragment( that, editable, node, limit );
+                       },
+
+                       rebuildFragment: function( that, editable, node, checkLimit ) {
+                               var clone;
+
+                               while ( node && !node.equals( editable ) && checkLimit( node ) ) {
+                                       // Don't clone children. Preserve element ids.
+                                       clone = node.clone( 0, 1 );
+                                       that.fragment.appendTo( clone );
+                                       that.fragment = clone;
+
+                                       node = node.getParent();
+                               }
+                       }
+               },
+
+               cell: {
+                       // Handle range anchored in table row with a single cell enclosed:
+                       //              <table><tbody><tr>[<td>a</td>]</tr></tbody></table>
+                       // becomes
+                       //              <table><tbody><tr><td>{a}</td></tr></tbody></table>
+                       shrink: function( that ) {
+                               var range = that.range,
+                                       startContainer = range.startContainer,
+                                       endContainer = range.endContainer,
+                                       startOffset = range.startOffset,
+                                       endOffset = range.endOffset;
+
+                               if ( startContainer.type == CKEDITOR.NODE_ELEMENT && startContainer.equals( endContainer ) && startContainer.is( 'tr' ) && ++startOffset == endOffset ) {
+                                       range.shrink( CKEDITOR.SHRINK_TEXT );
+                               }
+                       }
+               }
+       };
+
+       //
+       // Helpers for editable.extractHtmlFromRange.
+       //
+       extractHtmlFromRangeHelpers = ( function() {
+               function optimizeBookmarkNode( node, toStart ) {
+                       var parent = node.getParent();
+
+                       if ( parent.is( CKEDITOR.dtd.$inline ) )
+                               node[ toStart ? 'insertBefore' : 'insertAfter' ]( parent );
+               }
+
+               function mergeElements( merged, startBookmark, endBookmark ) {
+                       optimizeBookmarkNode( startBookmark );
+                       optimizeBookmarkNode( endBookmark, 1 );
+
+                       var next;
+                       while ( ( next = endBookmark.getNext() ) ) {
+                               next.insertAfter( startBookmark );
+
+                               // Update startBookmark after insertion to avoid the reversal of nodes (#13449).
+                               startBookmark = next;
+                       }
+
+                       if ( isEmpty( merged ) )
+                               merged.remove();
+               }
+
+               function getPath( startElement, root ) {
+                       return new CKEDITOR.dom.elementPath( startElement, root );
+               }
+
+               // Creates a range from a bookmark without removing the bookmark.
+               function createRangeFromBookmark( root, bookmark ) {
+                       var range = new CKEDITOR.dom.range( root );
+                       range.setStartAfter( bookmark.startNode );
+                       range.setEndBefore( bookmark.endNode );
+                       return range;
+               }
+
+               var list = {
+                       detectMerge: function( that, editable ) {
+                               var range = createRangeFromBookmark( editable, that.bookmark ),
+                                       startPath = range.startPath(),
+                                       endPath = range.endPath(),
+
+                                       startList = startPath.contains( CKEDITOR.dtd.$list ),
+                                       endList = endPath.contains( CKEDITOR.dtd.$list );
+
+                               that.mergeList =
+                                       // Both lists must exist
+                                       startList && endList &&
+                                       // ...and be of the same type
+                                       // startList.getName() == endList.getName() &&
+                                       // ...and share the same parent (same level in the tree)
+                                       startList.getParent().equals( endList.getParent() ) &&
+                                       // ...and must be different.
+                                       !startList.equals( endList );
+
+                               that.mergeListItems =
+                                       startPath.block && endPath.block &&
+                                       // Both containers must be list items
+                                       startPath.block.is( CKEDITOR.dtd.$listItem ) && endPath.block.is( CKEDITOR.dtd.$listItem );
+
+                               // Create merge bookmark.
+                               if ( that.mergeList || that.mergeListItems ) {
+                                       var rangeClone = range.clone();
+
+                                       rangeClone.setStartBefore( that.bookmark.startNode );
+                                       rangeClone.setEndAfter( that.bookmark.endNode );
+
+                                       that.mergeListBookmark = rangeClone.createBookmark();
+                               }
+                       },
+
+                       merge: function( that, editable ) {
+                               if ( !that.mergeListBookmark )
+                                       return;
+
+                               var startNode = that.mergeListBookmark.startNode,
+                                       endNode = that.mergeListBookmark.endNode,
+
+                                       startPath = getPath( startNode, editable ),
+                                       endPath = getPath( endNode, editable );
+
+                               if ( that.mergeList ) {
+                                       var firstList = startPath.contains( CKEDITOR.dtd.$list ),
+                                               secondList = endPath.contains( CKEDITOR.dtd.$list );
+
+                                       if ( !firstList.equals( secondList ) ) {
+                                               secondList.moveChildren( firstList );
+                                               secondList.remove();
+                                       }
+                               }
+
+                               if ( that.mergeListItems ) {
+                                       var firstListItem = startPath.contains( CKEDITOR.dtd.$listItem ),
+                                               secondListItem = endPath.contains( CKEDITOR.dtd.$listItem );
+
+                                       if ( !firstListItem.equals( secondListItem ) ) {
+                                               mergeElements( secondListItem, startNode, endNode );
+                                       }
+                               }
+
+                               // Remove bookmark nodes.
+                               startNode.remove();
+                               endNode.remove();
+                       }
+               };
+
+               var block = {
+                       // Detects whether blocks should be merged once contents are extracted.
+                       detectMerge: function( that, editable ) {
+                               // Don't merge blocks if lists or tables are already involved.
+                               if ( that.tableContentsRanges || that.mergeListBookmark )
+                                       return;
+
+                               var rangeClone = new CKEDITOR.dom.range( editable );
+
+                               rangeClone.setStartBefore( that.bookmark.startNode );
+                               rangeClone.setEndAfter( that.bookmark.endNode );
+
+                               that.mergeBlockBookmark = rangeClone.createBookmark();
+                       },
+
+                       merge: function( that, editable ) {
+                               if ( !that.mergeBlockBookmark || that.purgeTableBookmark )
+                                       return;
+
+                               var startNode = that.mergeBlockBookmark.startNode,
+                                       endNode = that.mergeBlockBookmark.endNode,
+
+                                       startPath = getPath( startNode, editable ),
+                                       endPath = getPath( endNode, editable ),
+
+                                       firstBlock = startPath.block,
+                                       secondBlock = endPath.block;
+
+                               if ( firstBlock && secondBlock && !firstBlock.equals( secondBlock ) ) {
+                                       mergeElements( secondBlock, startNode, endNode );
+                               }
+
+                               // Remove bookmark nodes.
+                               startNode.remove();
+                               endNode.remove();
+                       }
+               };
+
+               var table = ( function() {
+                       var tableEditable = { td: 1, th: 1, caption: 1 };
+
+                       // Returns an array of ranges which should be entirely extracted.
+                       //
+                       // <table><tr>[<td>xx</td><td>y}y</td></tr></table>
+                       // will find:
+                       // <table><tr><td>[xx]</td><td>[y}y</td></tr></table>
+                       function findTableContentsRanges( range ) {
+                               // Leaving the below for debugging purposes.
+                               //
+                               // console.log( 'findTableContentsRanges' );
+                               // console.log( bender.tools.range.getWithHtml( range.root, range ) );
+
+                               var contentsRanges = [],
+                                       editableRange,
+                                       walker = new CKEDITOR.dom.walker( range ),
+                                       startCell = range.startPath().contains( tableEditable ),
+                                       endCell = range.endPath().contains( tableEditable ),
+                                       database = {};
+
+                               walker.guard = function( node, leaving ) {
+                                       // Guard may be executed on some node boundaries multiple times,
+                                       // what results in creating more than one range for each selected cell. (#12964)
+                                       if ( node.type == CKEDITOR.NODE_ELEMENT ) {
+                                               var key = 'visited_' + ( leaving ? 'out' : 'in' );
+                                               if ( node.getCustomData( key ) ) {
+                                                       return;
+                                               }
+
+                                               CKEDITOR.dom.element.setMarker( database, node, key, 1 );
+                                       }
+
+                                       // Handle partial selection in a cell in which the range starts:
+                                       // <td><p>x{xx</p></td>...
+                                       // will store:
+                                       // <td><p>x{xx</p>]</td>
+                                       if ( leaving && startCell && node.equals( startCell ) ) {
+                                               editableRange = range.clone();
+                                               editableRange.setEndAt( startCell, CKEDITOR.POSITION_BEFORE_END );
+                                               contentsRanges.push( editableRange );
+                                               return;
+                                       }
+
+                                       // Handle partial selection in a cell in which the range ends.
+                                       if ( !leaving && endCell && node.equals( endCell ) ) {
+                                               editableRange = range.clone();
+                                               editableRange.setStartAt( endCell, CKEDITOR.POSITION_AFTER_START );
+                                               contentsRanges.push( editableRange );
+                                               return;
+                                       }
+
+                                       // Handle all other cells visited by the walker.
+                                       // We need to check whether the cell is disjoint with
+                                       // the start and end cells to correctly handle case like:
+                                       // <td>x{x</td><td><table>..<td>y}y</td>..</table></td>
+                                       // without the check the second cell's content would be entirely removed.
+                                       if ( !leaving && checkRemoveCellContents( node ) ) {
+                                               editableRange = range.clone();
+                                               editableRange.selectNodeContents( node );
+                                               contentsRanges.push( editableRange );
+                                       }
+                               };
+
+                               walker.lastForward();
+
+                               // Clear all markers so next extraction will not be affected by this one.
+                               CKEDITOR.dom.element.clearAllMarkers( database );
+
+                               return contentsRanges;
+
+                               function checkRemoveCellContents( node ) {
+                                       return (
+                                               // Must be a cell.
+                                               node.type == CKEDITOR.NODE_ELEMENT && node.is( tableEditable ) &&
+                                               // Must be disjoint with the range's startCell if exists.
+                                               ( !startCell || checkDisjointNodes( node, startCell ) ) &&
+                                               // Must be disjoint with the range's endCell if exists.
+                                               ( !endCell || checkDisjointNodes( node, endCell ) )
+                                       );
+                               }
+                       }
+
+                       // Returns a normalized common ancestor of a range.
+                       // If the real common ancestor is located somewhere in between a table and a td/th/caption,
+                       // then the table will be returned.
+                       function getNormalizedAncestor( range ) {
+                               var common = range.getCommonAncestor();
+
+                               if ( common.is( CKEDITOR.dtd.$tableContent ) && !common.is( tableEditable ) ) {
+                                       common = common.getAscendant( 'table', true );
+                               }
+
+                               return common;
+                       }
+
+                       // Check whether node1 and node2 are disjoint, so are:
+                       // * not identical,
+                       // * not contained in each other.
+                       function checkDisjointNodes( node1, node2 ) {
+                               var disallowedPositions = CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_IS_CONTAINED,
+                                       pos = node1.getPosition( node2 );
+
+                               // Baaah... IDENTICAL is 0, so we can't simplify this ;/.
+                               return pos === CKEDITOR.POSITION_IDENTICAL ?
+                                       false :
+                                       ( ( pos & disallowedPositions ) === 0 );
+                       }
+
+                       return {
+                               // Detects whether to purge entire list.
+                               detectPurge: function( that ) {
+                                       var range = that.range,
+                                               walkerRange = range.clone();
+
+                                       walkerRange.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+                                       var walker = new CKEDITOR.dom.walker( walkerRange ),
+                                               editablesCount = 0;
+
+                                       // Count the number of table editables in the range. If there's more than one,
+                                       // table MAY be removed completely (it's a cross-cell range). Otherwise, only
+                                       // the contents of the cell are usually removed.
+                                       walker.evaluator = function( node ) {
+                                               if ( node.type == CKEDITOR.NODE_ELEMENT && node.is( tableEditable ) ) {
+                                                       ++editablesCount;
+                                               }
+                                       };
+
+                                       walker.checkForward();
+
+                                       if ( editablesCount > 1 ) {
+                                               var startTable = range.startPath().contains( 'table' ),
+                                                       endTable = range.endPath().contains( 'table' );
+
+                                               if ( startTable && endTable && range.checkBoundaryOfElement( startTable, CKEDITOR.START ) && range.checkBoundaryOfElement( endTable, CKEDITOR.END ) ) {
+                                                       var rangeClone = that.range.clone();
+
+                                                       rangeClone.setStartBefore( startTable );
+                                                       rangeClone.setEndAfter( endTable );
+
+                                                       that.purgeTableBookmark = rangeClone.createBookmark();
+                                               }
+                                       }
+                               },
+
+                               // The magic.
+                               //
+                               // This method tries to discover whether the range starts or ends somewhere in a table
+                               // (it is not interested whether the range contains a table, because in such case
+                               // the extractContents() methods does the job correctly).
+                               // If the range meets these criteria, then the method tries to discover and store the following:
+                               //
+                               // * that.tableSurroundingRange - a part of the range which is located outside of any table which
+                               // will be touched (note: when range is located in a single cell it does not touch the table).
+                               // This range can be placed at:
+                               //              * at the beginning: <p>he{re</p><table>..]..</table>
+                               //              * in the middle: <table>..[..</table><p>here</p><table>..]..</table>
+                               //              * at the end: <table>..[..</table><p>he}re</p>
+                               // * that.tableContentsRanges - an array of ranges with contents of td/th/caption that should be removed.
+                               // This assures that calling extractContents() does not change the structure of the table(s).
+                               detectRanges: function( that, editable ) {
+                                       var range = createRangeFromBookmark( editable, that.bookmark ),
+                                               surroundingRange = range.clone(),
+                                               leftRange,
+                                               rightRange,
+
+                                               // Find a common ancestor and normalize it (so the following paths contain tables).
+                                               commonAncestor = getNormalizedAncestor( range ),
+
+                                               // Create paths using the normalized ancestor, so tables beyond the context
+                                               // of the input range are not found.
+                                               startPath = new CKEDITOR.dom.elementPath( range.startContainer, commonAncestor ),
+                                               endPath = new CKEDITOR.dom.elementPath( range.endContainer, commonAncestor ),
+
+                                               startTable = startPath.contains( 'table' ),
+                                               endTable = endPath.contains( 'table' ),
+
+                                               tableContentsRanges;
+
+                                       // Nothing to do here - the range doesn't touch any table or
+                                       // it contains a table, but that table is fully selected so it will be simply fully removed
+                                       // by the normal algorithm.
+                                       if ( !startTable && !endTable ) {
+                                               return;
+                                       }
+
+                                       // Handle two disjoint tables case:
+                                       // <table>..[..</table><p>ab</p><table>..]..</table>
+                                       // is handled as (respectively: findTableContents( left ), surroundingRange, findTableContents( right )):
+                                       // <table>..[..</table>][<p>ab</p>][<table>..]..</table>
+                                       // Check that tables are disjoint to exclude a case when start equals end or one is contained
+                                       // in the other.
+                                       if ( startTable && endTable && checkDisjointNodes( startTable, endTable ) ) {
+                                               that.tableSurroundingRange = surroundingRange;
+                                               surroundingRange.setStartAt( startTable, CKEDITOR.POSITION_AFTER_END );
+                                               surroundingRange.setEndAt( endTable, CKEDITOR.POSITION_BEFORE_START );
+
+                                               leftRange = range.clone();
+                                               leftRange.setEndAt( startTable, CKEDITOR.POSITION_AFTER_END );
+
+                                               rightRange = range.clone();
+                                               rightRange.setStartAt( endTable, CKEDITOR.POSITION_BEFORE_START );
+
+                                               tableContentsRanges = findTableContentsRanges( leftRange ).concat( findTableContentsRanges( rightRange ) );
+                                       }
+                                       // Divide the initial range into two parts:
+                                       // * range which contains the part containing the table,
+                                       // * surroundingRange which contains the part outside the table.
+                                       //
+                                       // The surroundingRange exists only if one of the range ends is
+                                       // located outside the table.
+                                       //
+                                       // <p>a{b</p><table>..]..</table><p>cd</p>
+                                       // becomes (respectively: surroundingRange, range):
+                                       // <p>a{b</p>][<table>..]..</table><p>cd</p>
+                                       else if ( !startTable ) {
+                                               that.tableSurroundingRange = surroundingRange;
+                                               surroundingRange.setEndAt( endTable, CKEDITOR.POSITION_BEFORE_START );
+
+                                               range.setStartAt( endTable, CKEDITOR.POSITION_AFTER_START );
+                                       }
+                                       // <p>ab</p><table>..[..</table><p>c}d</p>
+                                       // becomes (respectively range, surroundingRange):
+                                       // <p>ab</p><table>..[..</table>][<p>c}d</p>
+                                       else if ( !endTable ) {
+                                               that.tableSurroundingRange = surroundingRange;
+                                               surroundingRange.setStartAt( startTable, CKEDITOR.POSITION_AFTER_END );
+
+                                               range.setEndAt( startTable, CKEDITOR.POSITION_AFTER_END );
+                                       }
+
+                                       // Use already calculated or calculate for the remaining range.
+                                       that.tableContentsRanges = tableContentsRanges ? tableContentsRanges : findTableContentsRanges( range );
+
+                                       // Leaving the below for debugging purposes.
+                                       //
+                                       // if ( that.tableSurroundingRange ) {
+                                       //      console.log( 'tableSurroundingRange' );
+                                       //      console.log( bender.tools.range.getWithHtml( that.tableSurroundingRange.root, that.tableSurroundingRange ) );
+                                       // }
+                                       //
+                                       // console.log( 'tableContentsRanges' );
+                                       // that.tableContentsRanges.forEach( function( range ) {
+                                       //      console.log( bender.tools.range.getWithHtml( range.root, range ) );
+                                       // } );
+                               },
+
+                               deleteRanges: function( that ) {
+                                       var range;
+
+                                       // Delete table cell contents.
+                                       while ( ( range = that.tableContentsRanges.pop() ) ) {
+                                               range.extractContents();
+
+                                               if ( isEmpty( range.startContainer ) )
+                                                       range.startContainer.appendBogus();
+                                       }
+
+                                       // Finally delete surroundings of the table.
+                                       if ( that.tableSurroundingRange ) {
+                                               that.tableSurroundingRange.extractContents();
+                                       }
+                               },
+
+                               purge: function( that ) {
+                                       if ( !that.purgeTableBookmark )
+                                               return;
+
+                                       var doc = that.doc,
+                                               range = that.range,
+                                               rangeClone = range.clone(),
+                                               // How about different enter modes?
+                                               block = doc.createElement( 'p' );
+
+                                       block.insertBefore( that.purgeTableBookmark.startNode );
+
+                                       rangeClone.moveToBookmark( that.purgeTableBookmark );
+                                       rangeClone.deleteContents();
+
+                                       that.range.moveToPosition( block, CKEDITOR.POSITION_AFTER_START );
+                               }
+                       };
+               } )();
+
+               return {
+                       list: list,
+                       block: block,
+                       table: table,
+
+                       // Detects whether use "mergeThen" argument in range.extractContents().
+                       detectExtractMerge: function( that ) {
+                               // Don't merge if playing with lists.
+                               return !(
+                                       that.range.startPath().contains( CKEDITOR.dtd.$listItem ) &&
+                                       that.range.endPath().contains( CKEDITOR.dtd.$listItem )
+                               );
+                       },
+
+                       fixUneditableRangePosition: function( range ) {
+                               if ( !range.startContainer.getDtd()[ '#' ] ) {
+                                       range.moveToClosestEditablePosition( null, true );
+                               }
+                       },
+
+                       // Perform auto paragraphing if needed.
+                       autoParagraph: function( editor, range ) {
+                               var path = range.startPath(),
+                                       fixBlock;
+
+                               if ( shouldAutoParagraph( editor, path.block, path.blockLimit ) && ( fixBlock = autoParagraphTag( editor ) ) ) {
+                                       fixBlock = range.document.createElement( fixBlock );
+                                       fixBlock.appendBogus();
+                                       range.insertNode( fixBlock );
+                                       range.moveToPosition( fixBlock, CKEDITOR.POSITION_AFTER_START );
+                               }
+                       }
+               };
+       } )();
+
+} )();
+
+/**
+ * Whether the editor must output an empty value (`''`) if its content only consists
+ * of an empty paragraph.
+ *
+ *             config.ignoreEmptyParagraph = false;
+ *
+ * @cfg {Boolean} [ignoreEmptyParagraph=true]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Event fired by the editor in order to get accessibility help label.
+ * The event is responded to by a component which provides accessibility
+ * help (i.e. the `a11yhelp` plugin) hence the editor is notified whether
+ * accessibility help is available.
+ *
+ * Providing info:
+ *
+ *             editor.on( 'ariaEditorHelpLabel', function( evt ) {
+ *                             evt.data.label = editor.lang.common.editorHelp;
+ *             } );
+ *
+ * Getting label:
+ *
+ *             var helpLabel = editor.fire( 'ariaEditorHelpLabel', {} ).label;
+ *
+ * @since 4.4.3
+ * @event ariaEditorHelpLabel
+ * @param {String} label The label to be used.
+ * @member CKEDITOR.editor
+ */
+
+/**
+ * Event fired when the user double-clicks in the editable area.
+ * The event allows to open a dialog window for a clicked element in a convenient way:
+ *
+ *             editor.on( 'doubleclick', function( evt ) {
+ *                     var element = evt.data.element;
+ *
+ *                     if ( element.is( 'table' ) )
+ *                             evt.data.dialog = 'tableProperties';
+ *             } );
+ *
+ * **Note:** To handle double-click on a widget use {@link CKEDITOR.plugins.widget#doubleclick}.
+ *
+ * @event doubleclick
+ * @param data
+ * @param {CKEDITOR.dom.element} data.element The double-clicked element.
+ * @param {String} data.dialog The dialog window to be opened. If set by the listener,
+ * the specified dialog window will be opened.
+ * @member CKEDITOR.editor
+ */
diff --git a/sources/core/editor.js b/sources/core/editor.js
new file mode 100644 (file)
index 0000000..8dfce7f
--- /dev/null
@@ -0,0 +1,2039 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.editor} class that represents an
+ *             editor instance.
+ */
+
+( function() {
+       // Override the basic constructor defined at editor_basic.js.
+       Editor.prototype = CKEDITOR.editor.prototype;
+       CKEDITOR.editor = Editor;
+
+       /**
+        * Represents an editor instance. This constructor should be rarely
+        * used in favor of the {@link CKEDITOR} editor creation functions.
+        *
+        * @class CKEDITOR.editor
+        * @mixins CKEDITOR.event
+        * @constructor Creates an editor class instance.
+        * @param {Object} [instanceConfig] Configuration values for this specific instance.
+        * @param {CKEDITOR.dom.element} [element] The DOM element upon which this editor
+        * will be created.
+        * @param {Number} [mode] The element creation mode to be used by this editor.
+        */
+       function Editor( instanceConfig, element, mode ) {
+               // Call the CKEDITOR.event constructor to initialize this instance.
+               CKEDITOR.event.call( this );
+
+               // Make a clone of the config object, to avoid having it touched by our code. (#9636)
+               instanceConfig = instanceConfig && CKEDITOR.tools.clone( instanceConfig );
+
+               // if editor is created off one page element.
+               if ( element !== undefined ) {
+                       // Asserting element and mode not null.
+                       if ( !( element instanceof CKEDITOR.dom.element ) )
+                               throw new Error( 'Expect element of type CKEDITOR.dom.element.' );
+                       else if ( !mode )
+                               throw new Error( 'One of the element modes must be specified.' );
+
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && mode == CKEDITOR.ELEMENT_MODE_INLINE )
+                               throw new Error( 'Inline element mode is not supported on IE quirks.' );
+
+                       if ( !isSupportedElement( element, mode ) )
+                               throw new Error( 'The specified element mode is not supported on element: "' + element.getName() + '".' );
+
+                       /**
+                        * The original host page element upon which the editor is created. It is only
+                        * supposed to be provided by the particular editor creator and is not subject to
+                        * be modified.
+                        *
+                        * @readonly
+                        * @property {CKEDITOR.dom.element}
+                        */
+                       this.element = element;
+
+                       /**
+                        * This property indicates the way this instance is associated with the {@link #element}.
+                        * See also {@link CKEDITOR#ELEMENT_MODE_INLINE} and {@link CKEDITOR#ELEMENT_MODE_REPLACE}.
+                        *
+                        * @readonly
+                        * @property {Number}
+                        */
+                       this.elementMode = mode;
+
+                       this.name = ( this.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO ) && ( element.getId() || element.getNameAtt() );
+               } else {
+                       this.elementMode = CKEDITOR.ELEMENT_MODE_NONE;
+               }
+
+               // Declare the private namespace.
+               this._ = {};
+
+               this.commands = {};
+
+               /**
+                * Contains all UI templates created for this editor instance.
+                *
+                * @readonly
+                * @property {Object}
+                */
+               this.templates = {};
+
+               /**
+                * A unique identifier of this editor instance.
+                *
+                * **Note:** It will be originated from the `id` or `name`
+                * attribute of the {@link #element}, otherwise a name pattern of
+                * `'editor{n}'` will be used.
+                *
+                * @readonly
+                * @property {String}
+                */
+               this.name = this.name || genEditorName();
+
+               /**
+                * A unique random string assigned to each editor instance on the page.
+                *
+                * @readonly
+                * @property {String}
+                */
+               this.id = CKEDITOR.tools.getNextId();
+
+               /**
+                * Indicates editor initialization status. The following statuses are available:
+                *
+                *      * **unloaded**: The initial state &mdash; the editor instance was initialized,
+                *      but its components (configuration, plugins, language files) are not loaded yet.
+                *      * **loaded**: The editor components were loaded &mdash; see the {@link CKEDITOR.editor#loaded} event.
+                *      * **ready**: The editor is fully initialized and ready &mdash; see the {@link CKEDITOR.editor#instanceReady} event.
+                *      * **destroyed**: The editor was destroyed &mdash; see the {@link CKEDITOR.editor#method-destroy} method.
+                *
+                * @since 4.1
+                * @readonly
+                * @property {String}
+                */
+               this.status = 'unloaded';
+
+               /**
+                * The configuration for this editor instance. It inherits all
+                * settings defined in {@link CKEDITOR.config}, combined with settings
+                * loaded from custom configuration files and those defined inline in
+                * the page when creating the editor.
+                *
+                *              var editor = CKEDITOR.instances.editor1;
+                *              alert( editor.config.skin ); // e.g. 'moono'
+                *
+                * @readonly
+                * @property {CKEDITOR.config}
+                */
+               this.config = CKEDITOR.tools.prototypedCopy( CKEDITOR.config );
+
+               /**
+                * The namespace containing UI features related to this editor instance.
+                *
+                * @readonly
+                * @property {CKEDITOR.ui}
+                */
+               this.ui = new CKEDITOR.ui( this );
+
+               /**
+                * Controls the focus state of this editor instance. This property
+                * is rarely used for normal API operations. It is mainly
+                * targeted at developers adding UI elements to the editor interface.
+                *
+                * @readonly
+                * @property {CKEDITOR.focusManager}
+                */
+               this.focusManager = new CKEDITOR.focusManager( this );
+
+               /**
+                * Controls keystroke typing in this editor instance.
+                *
+                * @readonly
+                * @property {CKEDITOR.keystrokeHandler}
+                */
+               this.keystrokeHandler = new CKEDITOR.keystrokeHandler( this );
+
+               // Make the editor update its command states on mode change.
+               this.on( 'readOnly', updateCommands );
+               this.on( 'selectionChange', function( evt ) {
+                       updateCommandsContext( this, evt.data.path );
+               } );
+               this.on( 'activeFilterChange', function() {
+                       updateCommandsContext( this, this.elementPath(), true );
+               } );
+               this.on( 'mode', updateCommands );
+
+               // Handle startup focus.
+               this.on( 'instanceReady', function() {
+                       this.config.startupFocus && this.focus();
+               } );
+
+               CKEDITOR.fire( 'instanceCreated', null, this );
+
+               // Add this new editor to the CKEDITOR.instances collections.
+               CKEDITOR.add( this );
+
+               // Return the editor instance immediately to enable early stage event registrations.
+               CKEDITOR.tools.setTimeout( function() {
+                       if ( this.status !== 'destroyed' ) {
+                               initConfig( this, instanceConfig );
+                       } else {
+                               CKEDITOR.warn( 'editor-incorrect-destroy' );
+                       }
+               }, 0, this );
+       }
+
+       var nameCounter = 0;
+
+       function genEditorName() {
+               do {
+                       var name = 'editor' + ( ++nameCounter );
+               }
+               while ( CKEDITOR.instances[ name ] );
+
+               return name;
+       }
+
+       // Asserting element DTD depending on mode.
+       function isSupportedElement( element, mode ) {
+               if ( mode == CKEDITOR.ELEMENT_MODE_INLINE )
+                       return element.is( CKEDITOR.dtd.$editable ) || element.is( 'textarea' );
+               else if ( mode == CKEDITOR.ELEMENT_MODE_REPLACE )
+                       return !element.is( CKEDITOR.dtd.$nonBodyContent );
+               return 1;
+       }
+
+       function updateCommands() {
+               var commands = this.commands,
+                       name;
+
+               for ( name in commands )
+                       updateCommand( this, commands[ name ] );
+       }
+
+       function updateCommand( editor, cmd ) {
+               cmd[ cmd.startDisabled ? 'disable' : editor.readOnly && !cmd.readOnly ? 'disable' : cmd.modes[ editor.mode ] ? 'enable' : 'disable' ]();
+       }
+
+       function updateCommandsContext( editor, path, forceRefresh ) {
+               // Commands cannot be refreshed without a path. In edge cases
+               // it may happen that there's no selection when this function is executed.
+               // For example when active filter is changed in #10877.
+               if ( !path )
+                       return;
+
+               var command,
+                       name,
+                       commands = editor.commands;
+
+               for ( name in commands ) {
+                       command = commands[ name ];
+
+                       if ( forceRefresh || command.contextSensitive )
+                               command.refresh( editor, path );
+               }
+       }
+
+       // ##### START: Config Privates
+
+       // These function loads custom configuration files and cache the
+       // CKEDITOR.editorConfig functions defined on them, so there is no need to
+       // download them more than once for several instances.
+       var loadConfigLoaded = {};
+
+       function loadConfig( editor ) {
+               var customConfig = editor.config.customConfig;
+
+               // Check if there is a custom config to load.
+               if ( !customConfig )
+                       return false;
+
+               customConfig = CKEDITOR.getUrl( customConfig );
+
+               var loadedConfig = loadConfigLoaded[ customConfig ] || ( loadConfigLoaded[ customConfig ] = {} );
+
+               // If the custom config has already been downloaded, reuse it.
+               if ( loadedConfig.fn ) {
+                       // Call the cached CKEDITOR.editorConfig defined in the custom
+                       // config file for the editor instance depending on it.
+                       loadedConfig.fn.call( editor, editor.config );
+
+                       // If there is no other customConfig in the chain, fire the
+                       // "configLoaded" event.
+                       if ( CKEDITOR.getUrl( editor.config.customConfig ) == customConfig || !loadConfig( editor ) )
+                               editor.fireOnce( 'customConfigLoaded' );
+               } else {
+                       // Load the custom configuration file.
+                       // To resolve customConfig race conflicts, use scriptLoader#queue
+                       // instead of scriptLoader#load (#6504).
+                       CKEDITOR.scriptLoader.queue( customConfig, function() {
+                               // If the CKEDITOR.editorConfig function has been properly
+                               // defined in the custom configuration file, cache it.
+                               if ( CKEDITOR.editorConfig )
+                                       loadedConfig.fn = CKEDITOR.editorConfig;
+                               else
+                                       loadedConfig.fn = function() {};
+
+                               // Call the load config again. This time the custom
+                               // config is already cached and so it will get loaded.
+                               loadConfig( editor );
+                       } );
+               }
+
+               return true;
+       }
+
+       function initConfig( editor, instanceConfig ) {
+               // Setup the lister for the "customConfigLoaded" event.
+               editor.on( 'customConfigLoaded', function() {
+                       if ( instanceConfig ) {
+                               // Register the events that may have been set at the instance
+                               // configuration object.
+                               if ( instanceConfig.on ) {
+                                       for ( var eventName in instanceConfig.on ) {
+                                               editor.on( eventName, instanceConfig.on[ eventName ] );
+                                       }
+                               }
+
+                               // Overwrite the settings from the in-page config.
+                               CKEDITOR.tools.extend( editor.config, instanceConfig, true );
+
+                               delete editor.config.on;
+                       }
+
+                       onConfigLoaded( editor );
+               } );
+
+               // The instance config may override the customConfig setting to avoid
+               // loading the default ~/config.js file.
+               if ( instanceConfig && instanceConfig.customConfig != null )
+                       editor.config.customConfig = instanceConfig.customConfig;
+
+               // Load configs from the custom configuration files.
+               if ( !loadConfig( editor ) )
+                       editor.fireOnce( 'customConfigLoaded' );
+       }
+
+       // ##### END: Config Privates
+
+       // Set config related properties.
+       function onConfigLoaded( editor ) {
+               var config = editor.config;
+
+               /**
+                * Indicates the read-only state of this editor. This is a read-only property.
+                * See also {@link CKEDITOR.editor#setReadOnly}.
+                *
+                * @since 3.6
+                * @readonly
+                * @property {Boolean}
+                */
+               editor.readOnly = isEditorReadOnly();
+
+               function isEditorReadOnly() {
+                       if ( config.readOnly ) {
+                               return true;
+                       }
+
+                       if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ) {
+                               if ( editor.element.is( 'textarea' ) ) {
+                                       return editor.element.hasAttribute( 'disabled' ) || editor.element.hasAttribute( 'readonly' );
+                               } else {
+                                       return editor.element.isReadOnly();
+                               }
+                       } else if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
+                               return editor.element.hasAttribute( 'disabled' ) || editor.element.hasAttribute( 'readonly' );
+                       }
+
+                       return false;
+               }
+
+               /**
+                * Indicates that the editor is running in an environment where
+                * no block elements are accepted inside the content.
+                *
+                * This can be for example inline editor based on an `<h1>` element.
+                *
+                * @readonly
+                * @property {Boolean}
+                */
+               editor.blockless = editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ?
+                       !( editor.element.is( 'textarea' ) || CKEDITOR.dtd[ editor.element.getName() ].p ) :
+                       false;
+
+               /**
+                * The [tabbing navigation](http://en.wikipedia.org/wiki/Tabbing_navigation) order determined for this editor instance.
+                * This can be set by the <code>{@link CKEDITOR.config#tabIndex}</code>
+                * setting or taken from the `tabindex` attribute of the
+                * {@link #element} associated with the editor.
+                *
+                *              alert( editor.tabIndex ); // e.g. 0
+                *
+                * @readonly
+                * @property {Number} [=0]
+                */
+               editor.tabIndex = config.tabIndex || editor.element && editor.element.getAttribute( 'tabindex' ) || 0;
+
+               editor.activeEnterMode = editor.enterMode = validateEnterMode( editor, config.enterMode );
+               editor.activeShiftEnterMode = editor.shiftEnterMode = validateEnterMode( editor, config.shiftEnterMode );
+
+               // Set CKEDITOR.skinName. Note that it is not possible to have
+               // different skins on the same page, so the last one to set it "wins".
+               if ( config.skin )
+                       CKEDITOR.skinName = config.skin;
+
+               // Fire the "configLoaded" event.
+               editor.fireOnce( 'configLoaded' );
+
+               initComponents( editor );
+       }
+
+       // Various other core components that read editor configuration.
+       function initComponents( editor ) {
+               // Documented in dataprocessor.js.
+               editor.dataProcessor = new CKEDITOR.htmlDataProcessor( editor );
+
+               // Set activeFilter directly to avoid firing event.
+               editor.filter = editor.activeFilter = new CKEDITOR.filter( editor );
+
+               loadSkin( editor );
+       }
+
+       function loadSkin( editor ) {
+               CKEDITOR.skin.loadPart( 'editor', function() {
+                       loadLang( editor );
+               } );
+       }
+
+       function loadLang( editor ) {
+               CKEDITOR.lang.load( editor.config.language, editor.config.defaultLanguage, function( languageCode, lang ) {
+                       var configTitle = editor.config.title;
+
+                       /**
+                        * The code for the language resources that have been loaded
+                        * for the user interface elements of this editor instance.
+                        *
+                        *              alert( editor.langCode ); // e.g. 'en'
+                        *
+                        * @readonly
+                        * @property {String}
+                        */
+                       editor.langCode = languageCode;
+
+                       /**
+                        * An object that contains all language strings used by the editor interface.
+                        *
+                        *              alert( editor.lang.basicstyles.bold ); // e.g. 'Negrito' (if the language is set to Portuguese)
+                        *
+                        * @readonly
+                        * @property {Object} lang
+                        */
+                       // As we'll be adding plugin specific entries that could come
+                       // from different language code files, we need a copy of lang,
+                       // not a direct reference to it.
+                       editor.lang = CKEDITOR.tools.prototypedCopy( lang );
+
+                       /**
+                        * Indicates the human-readable title of this editor. Although this is a read-only property,
+                        * it can be initialized with {@link CKEDITOR.config#title}.
+                        *
+                        * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name editor.name}
+                        * which identifies the instance in the {@link CKEDITOR#instances} literal.
+                        *
+                        * @since 4.2
+                        * @readonly
+                        * @property {String/Boolean}
+                        */
+                       editor.title = typeof configTitle == 'string' || configTitle === false ? configTitle : [ editor.lang.editor, editor.name ].join( ', ' );
+
+                       if ( !editor.config.contentsLangDirection ) {
+                               // Fallback to either the editable element direction or editor UI direction depending on creators.
+                               editor.config.contentsLangDirection = editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE ? editor.element.getDirection( 1 ) : editor.lang.dir;
+                       }
+
+                       editor.fire( 'langLoaded' );
+
+                       preloadStylesSet( editor );
+               } );
+       }
+
+       // Preloads styles set file (config.stylesSet).
+       // If stylesSet was defined directly (by an array)
+       // this function will call loadPlugins fully synchronously.
+       // If stylesSet is a string (path) loadPlugins will
+       // be called asynchronously.
+       // In both cases - styles will be preload before plugins initialization.
+       function preloadStylesSet( editor ) {
+               editor.getStylesSet( function( styles ) {
+                       // Wait for editor#loaded, so plugins could add their listeners.
+                       // But listen with high priority to fire editor#stylesSet before editor#uiReady and editor#setData.
+                       editor.once( 'loaded', function() {
+                               // Note: we can't use fireOnce because this event may canceled and fired again.
+                               editor.fire( 'stylesSet', { styles: styles } );
+                       }, null, null, 1 );
+
+                       loadPlugins( editor );
+               } );
+       }
+
+       function loadPlugins( editor ) {
+               var config = editor.config,
+                       plugins = config.plugins,
+                       extraPlugins = config.extraPlugins,
+                       removePlugins = config.removePlugins;
+
+               if ( extraPlugins ) {
+                       // Remove them first to avoid duplications.
+                       var extraRegex = new RegExp( '(?:^|,)(?:' + extraPlugins.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
+                       plugins = plugins.replace( extraRegex, '' );
+
+                       plugins += ',' + extraPlugins;
+               }
+
+               if ( removePlugins ) {
+                       var removeRegex = new RegExp( '(?:^|,)(?:' + removePlugins.replace( /\s*,\s*/g, '|' ) + ')(?=,|$)', 'g' );
+                       plugins = plugins.replace( removeRegex, '' );
+               }
+
+               // Load the Adobe AIR plugin conditionally.
+               CKEDITOR.env.air && ( plugins += ',adobeair' );
+
+               // Load all plugins defined in the "plugins" setting.
+               CKEDITOR.plugins.load( plugins.split( ',' ), function( plugins ) {
+                       // The list of plugins.
+                       var pluginsArray = [];
+
+                       // The language code to get loaded for each plugin. Null
+                       // entries will be appended for plugins with no language files.
+                       var languageCodes = [];
+
+                       // The list of URLs to language files.
+                       var languageFiles = [];
+
+                       /**
+                        * An object that contains references to all plugins used by this
+                        * editor instance.
+                        *
+                        *              alert( editor.plugins.dialog.path ); // e.g. 'http://example.com/ckeditor/plugins/dialog/'
+                        *
+                        *              // Check if a plugin is available.
+                        *              if ( editor.plugins.image ) {
+                        *                      ...
+                        *              }
+                        *
+                        * @readonly
+                        * @property {Object}
+                        */
+                       editor.plugins = plugins;
+
+                       // Loop through all plugins, to build the list of language
+                       // files to get loaded.
+                       //
+                       // Check also whether any of loaded plugins doesn't require plugins
+                       // defined in config.removePlugins. Throw non-blocking error if this happens.
+                       for ( var pluginName in plugins ) {
+                               var plugin = plugins[ pluginName ],
+                                       pluginLangs = plugin.lang,
+                                       lang = null,
+                                       requires = plugin.requires,
+                                       match, name;
+
+                               // Transform it into a string, if it's not one.
+                               if ( CKEDITOR.tools.isArray( requires ) )
+                                       requires = requires.join( ',' );
+
+                               if ( requires && ( match = requires.match( removeRegex ) ) ) {
+                                       while ( ( name = match.pop() ) ) {
+                                               CKEDITOR.error( 'editor-plugin-required', { plugin: name.replace( ',', '' ), requiredBy: pluginName } );
+                                       }
+                               }
+
+                               // If the plugin has "lang".
+                               if ( pluginLangs && !editor.lang[ pluginName ] ) {
+                                       // Trasnform the plugin langs into an array, if it's not one.
+                                       if ( pluginLangs.split )
+                                               pluginLangs = pluginLangs.split( ',' );
+
+                                       // Resolve the plugin language. If the current language
+                                       // is not available, get English or the first one.
+                                       if ( CKEDITOR.tools.indexOf( pluginLangs, editor.langCode ) >= 0 )
+                                               lang = editor.langCode;
+                                       else {
+                                               // The language code may have the locale information (zh-cn).
+                                               // Fall back to locale-less in that case (zh).
+                                               var langPart = editor.langCode.replace( /-.*/, '' );
+                                               if ( langPart != editor.langCode && CKEDITOR.tools.indexOf( pluginLangs, langPart ) >= 0 )
+                                                       lang = langPart;
+                                               // Try the only "generic" option we have: English.
+                                               else if ( CKEDITOR.tools.indexOf( pluginLangs, 'en' ) >= 0 )
+                                                       lang = 'en';
+                                               else
+                                                       lang = pluginLangs[ 0 ];
+                                       }
+
+                                       if ( !plugin.langEntries || !plugin.langEntries[ lang ] ) {
+                                               // Put the language file URL into the list of files to
+                                               // get downloaded.
+                                               languageFiles.push( CKEDITOR.getUrl( plugin.path + 'lang/' + lang + '.js' ) );
+                                       } else {
+                                               editor.lang[ pluginName ] = plugin.langEntries[ lang ];
+                                               lang = null;
+                                       }
+                               }
+
+                               // Save the language code, so we know later which
+                               // language has been resolved to this plugin.
+                               languageCodes.push( lang );
+
+                               pluginsArray.push( plugin );
+                       }
+
+                       // Load all plugin specific language files in a row.
+                       CKEDITOR.scriptLoader.load( languageFiles, function() {
+                               // Initialize all plugins that have the "beforeInit" and "init" methods defined.
+                               var methods = [ 'beforeInit', 'init', 'afterInit' ];
+                               for ( var m = 0; m < methods.length; m++ ) {
+                                       for ( var i = 0; i < pluginsArray.length; i++ ) {
+                                               var plugin = pluginsArray[ i ];
+
+                                               // Uses the first loop to update the language entries also.
+                                               if ( m === 0 && languageCodes[ i ] && plugin.lang && plugin.langEntries )
+                                                       editor.lang[ plugin.name ] = plugin.langEntries[ languageCodes[ i ] ];
+
+                                               // Call the plugin method (beforeInit and init).
+                                               if ( plugin[ methods[ m ] ] )
+                                                       plugin[ methods[ m ] ]( editor );
+                                       }
+                               }
+
+                               editor.fireOnce( 'pluginsLoaded' );
+
+                               // Setup the configured keystrokes.
+                               config.keystrokes && editor.setKeystroke( editor.config.keystrokes );
+
+                               // Setup the configured blocked keystrokes.
+                               for ( i = 0; i < editor.config.blockedKeystrokes.length; i++ )
+                                       editor.keystrokeHandler.blockedKeystrokes[ editor.config.blockedKeystrokes[ i ] ] = 1;
+
+                               editor.status = 'loaded';
+                               editor.fireOnce( 'loaded' );
+                               CKEDITOR.fire( 'instanceLoaded', null, editor );
+                       } );
+               } );
+       }
+
+       // Send to data output back to editor's associated element.
+       function updateEditorElement() {
+               var element = this.element;
+
+               // Some editor creation mode will not have the
+               // associated element.
+               if ( element && this.elementMode != CKEDITOR.ELEMENT_MODE_APPENDTO ) {
+                       var data = this.getData();
+
+                       if ( this.config.htmlEncodeOutput )
+                               data = CKEDITOR.tools.htmlEncode( data );
+
+                       if ( element.is( 'textarea' ) )
+                               element.setValue( data );
+                       else
+                               element.setHtml( data );
+
+                       return true;
+               }
+               return false;
+       }
+
+       // Always returns ENTER_BR in case of blockless editor.
+       function validateEnterMode( editor, enterMode ) {
+               return editor.blockless ? CKEDITOR.ENTER_BR : enterMode;
+       }
+
+       // Create DocumentFragment from specified ranges. For now it handles only tables in Firefox
+       // and returns DocumentFragment from the 1. range for other cases. (#13884)
+       function createDocumentFragmentFromRanges( ranges, editable ) {
+               var docFragment = new CKEDITOR.dom.documentFragment(),
+                       tableClone,
+                       currentRow,
+                       currentRowClone;
+
+               for ( var i = 0; i < ranges.length; i++ ) {
+                       var range = ranges[ i ],
+                               container = range.startContainer;
+
+                       if ( container.getName && container.getName() == 'tr' ) {
+                               if ( !tableClone ) {
+                                       tableClone = container.getAscendant( 'table' ).clone();
+                                       tableClone.append( container.getAscendant( 'tbody' ).clone() );
+                                       docFragment.append( tableClone );
+                                       tableClone = tableClone.findOne( 'tbody' );
+                               }
+
+                               if ( !( currentRow && currentRow.equals( container ) ) ) {
+                                       currentRow = container;
+                                       currentRowClone = container.clone();
+                                       tableClone.append( currentRowClone );
+                               }
+
+                               currentRowClone.append( range.cloneContents() );
+                       } else {
+                               // If there was something else copied with table,
+                               // append it to DocumentFragment.
+                               docFragment.append( range.cloneContents() );
+                       }
+               }
+
+               if ( !tableClone ) {
+                       return editable.getHtmlFromRange( ranges[ 0 ] );
+               }
+
+               return docFragment;
+       }
+
+       CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
+               /**
+                * Adds a command definition to the editor instance. Commands added with
+                * this function can be executed later with the <code>{@link #execCommand}</code> method.
+                *
+                *              editorInstance.addCommand( 'sample', {
+                *                      exec: function( editor ) {
+                *                              alert( 'Executing a command for the editor name "' + editor.name + '"!' );
+                *                      }
+                *              } );
+                *
+                * @param {String} commandName The indentifier name of the command.
+                * @param {CKEDITOR.commandDefinition} commandDefinition The command definition.
+                */
+               addCommand: function( commandName, commandDefinition ) {
+                       commandDefinition.name = commandName.toLowerCase();
+                       var cmd = new CKEDITOR.command( this, commandDefinition );
+
+                       // Update command when mode is set.
+                       // This guarantees that commands added before first editor#mode
+                       // aren't immediately updated, but waits for editor#mode and that
+                       // commands added later are immediately refreshed, even when added
+                       // before instanceReady. #10103, #10249
+                       if ( this.mode )
+                               updateCommand( this, cmd );
+
+                       return this.commands[ commandName ] = cmd;
+               },
+
+               /**
+                * Attaches the editor to a form to call {@link #updateElement} before form submission.
+                * This method is called by both creators ({@link CKEDITOR#replace replace} and
+                * {@link CKEDITOR#inline inline}), so there is no reason to call it manually.
+                *
+                * @private
+                */
+               _attachToForm: function() {
+                       var editor = this,
+                               element = editor.element,
+                               form = new CKEDITOR.dom.element( element.$.form );
+
+                       // If are replacing a textarea, we must
+                       if ( element.is( 'textarea' ) ) {
+                               if ( form ) {
+                                       form.on( 'submit', onSubmit );
+
+                                       // Check if there is no element/elements input with name == "submit".
+                                       // If they exists they will overwrite form submit function (form.$.submit).
+                                       // If form.$.submit is overwritten we can not do anything with it.
+                                       if ( isFunction( form.$.submit ) ) {
+                                               // Setup the submit function because it doesn't fire the
+                                               // "submit" event.
+                                               form.$.submit = CKEDITOR.tools.override( form.$.submit, function( originalSubmit ) {
+                                                       return function() {
+                                                               onSubmit();
+
+                                                               // For IE, the DOM submit function is not a
+                                                               // function, so we need third check.
+                                                               if ( originalSubmit.apply )
+                                                                       originalSubmit.apply( this );
+                                                               else
+                                                                       originalSubmit();
+                                                       };
+                                               } );
+                                       }
+
+                                       // Remove 'submit' events registered on form element before destroying.(#3988)
+                                       editor.on( 'destroy', function() {
+                                               form.removeListener( 'submit', onSubmit );
+                                       } );
+                               }
+                       }
+
+                       function onSubmit( evt ) {
+                               editor.updateElement();
+
+                               // #8031 If textarea had required attribute and editor is empty fire 'required' event and if
+                               // it was cancelled, prevent submitting the form.
+                               if ( editor._.required && !element.getValue() && editor.fire( 'required' ) === false ) {
+                                       // When user press save button event (evt) is undefined (see save plugin).
+                                       // This method works because it throws error so originalSubmit won't be called.
+                                       // Also this error won't be shown because it will be caught in save plugin.
+                                       evt.data.preventDefault();
+                               }
+                       }
+
+                       function isFunction( f ) {
+                               // For IE8 typeof fun == object so we cannot use it.
+                               return !!( f && f.call && f.apply );
+                       }
+               },
+
+               /**
+                * Destroys the editor instance, releasing all resources used by it.
+                * If the editor replaced an element, the element will be recovered.
+                *
+                *              alert( CKEDITOR.instances.editor1 ); // e.g. object
+                *              CKEDITOR.instances.editor1.destroy();
+                *              alert( CKEDITOR.instances.editor1 ); // undefined
+                *
+                * @param {Boolean} [noUpdate] If the instance is replacing a DOM
+                * element, this parameter indicates whether or not to update the
+                * element with the instance content.
+                */
+               destroy: function( noUpdate ) {
+                       this.fire( 'beforeDestroy' );
+
+                       !noUpdate && updateEditorElement.call( this );
+
+                       this.editable( null );
+
+                       if ( this.filter ) {
+                               this.filter.destroy();
+                               delete this.filter;
+                       }
+
+                       delete this.activeFilter;
+
+                       this.status = 'destroyed';
+
+                       this.fire( 'destroy' );
+
+                       // Plug off all listeners to prevent any further events firing.
+                       this.removeAllListeners();
+
+                       CKEDITOR.remove( this );
+                       CKEDITOR.fire( 'instanceDestroyed', null, this );
+               },
+
+               /**
+                * Returns an {@link CKEDITOR.dom.elementPath element path} for the selection in the editor.
+                *
+                * @param {CKEDITOR.dom.node} [startNode] From which the path should start,
+                * if not specified defaults to editor selection's
+                * start element yielded by {@link CKEDITOR.dom.selection#getStartElement}.
+                * @returns {CKEDITOR.dom.elementPath}
+                */
+               elementPath: function( startNode ) {
+                       if ( !startNode ) {
+                               var sel = this.getSelection();
+                               if ( !sel )
+                                       return null;
+
+                               startNode = sel.getStartElement();
+                       }
+
+                       return startNode ? new CKEDITOR.dom.elementPath( startNode, this.editable() ) : null;
+               },
+
+               /**
+                * Shortcut to create a {@link CKEDITOR.dom.range} instance from the editable element.
+                *
+                * @returns {CKEDITOR.dom.range} The DOM range created if the editable has presented.
+                * @see CKEDITOR.dom.range
+                */
+               createRange: function() {
+                       var editable = this.editable();
+                       return editable ? new CKEDITOR.dom.range( editable ) : null;
+               },
+
+               /**
+                * Executes a command associated with the editor.
+                *
+                *              editorInstance.execCommand( 'bold' );
+                *
+                * @param {String} commandName The indentifier name of the command.
+                * @param {Object} [data] The data to be passed to the command.
+                * @returns {Boolean} `true` if the command was executed
+                * successfully, otherwise `false`.
+                * @see CKEDITOR.editor#addCommand
+                */
+               execCommand: function( commandName, data ) {
+                       var command = this.getCommand( commandName );
+
+                       var eventData = {
+                               name: commandName,
+                               commandData: data,
+                               command: command
+                       };
+
+                       if ( command && command.state != CKEDITOR.TRISTATE_DISABLED ) {
+                               if ( this.fire( 'beforeCommandExec', eventData ) !== false ) {
+                                       eventData.returnValue = command.exec( eventData.commandData );
+
+                                       // Fire the 'afterCommandExec' immediately if command is synchronous.
+                                       if ( !command.async && this.fire( 'afterCommandExec', eventData ) !== false )
+                                               return eventData.returnValue;
+                               }
+                       }
+
+                       // throw 'Unknown command name "' + commandName + '"';
+                       return false;
+               },
+
+               /**
+                * Gets one of the registered commands. Note that after registering a
+                * command definition with {@link #addCommand}, it is
+                * transformed internally into an instance of
+                * {@link CKEDITOR.command}, which will then be returned by this function.
+                *
+                * @param {String} commandName The name of the command to be returned.
+                * This is the same name that is used to register the command with `addCommand`.
+                * @returns {CKEDITOR.command} The command object identified by the provided name.
+                */
+               getCommand: function( commandName ) {
+                       return this.commands[ commandName ];
+               },
+
+               /**
+                * Gets the editor data. The data will be in "raw" format. It is the same
+                * data that is posted by the editor.
+                *
+                *              if ( CKEDITOR.instances.editor1.getData() == '' )
+                *                      alert( 'There is no data available.' );
+                *
+                * @param {Boolean} internal If set to `true`, it will prevent firing the
+                * {@link CKEDITOR.editor#beforeGetData} and {@link CKEDITOR.editor#event-getData} events, so
+                * the real content of the editor will not be read and cached data will be returned. The method will work
+                * much faster, but this may result in the editor returning the data that is not up to date. This parameter
+                * should thus only be set to `true` when you are certain that the cached data is up to date.
+                *
+                * @returns {String} The editor data.
+                */
+               getData: function( internal ) {
+                       !internal && this.fire( 'beforeGetData' );
+
+                       var eventData = this._.data;
+
+                       if ( typeof eventData != 'string' ) {
+                               var element = this.element;
+                               if ( element && this.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE )
+                                       eventData = element.is( 'textarea' ) ? element.getValue() : element.getHtml();
+                               else
+                                       eventData = '';
+                       }
+
+                       eventData = { dataValue: eventData };
+
+                       // Fire "getData" so data manipulation may happen.
+                       !internal && this.fire( 'getData', eventData );
+
+                       return eventData.dataValue;
+               },
+
+               /**
+                * Gets the "raw data" currently available in the editor. This is a
+                * fast method which returns the data as is, without processing, so it is
+                * not recommended to use it on resulting pages. Instead it can be used
+                * combined with the {@link #method-loadSnapshot} method in order
+                * to automatically save the editor data from time to time
+                * while the user is using the editor, to avoid data loss, without risking
+                * performance issues.
+                *
+                *              alert( editor.getSnapshot() );
+                *
+                * See also:
+                *
+                * * {@link CKEDITOR.editor#method-getData}.
+                *
+                * @returns {String} Editor "raw data".
+                */
+               getSnapshot: function() {
+                       var data = this.fire( 'getSnapshot' );
+
+                       if ( typeof data != 'string' ) {
+                               var element = this.element;
+
+                               if ( element && this.elementMode == CKEDITOR.ELEMENT_MODE_REPLACE ) {
+                                       data = element.is( 'textarea' ) ? element.getValue() : element.getHtml();
+                               }
+                               else {
+                                       // If we don't have a proper element, set data to an empty string,
+                                       // as this method is expected to return a string. (#13385)
+                                       data = '';
+                               }
+                       }
+
+                       return data;
+               },
+
+               /**
+                * Loads "raw data" into the editor. The data is loaded with processing
+                * straight to the editing area. It should not be used as a way to load
+                * any kind of data, but instead in combination with
+                * {@link #method-getSnapshot}-produced data.
+                *
+                *              var data = editor.getSnapshot();
+                *              editor.loadSnapshot( data );
+                *
+                * @see CKEDITOR.editor#setData
+                */
+               loadSnapshot: function( snapshot ) {
+                       this.fire( 'loadSnapshot', snapshot );
+               },
+
+               /**
+                * Sets the editor data. The data must be provided in the "raw" format (HTML).
+                *
+                * Note that this method is asynchronous. The `callback` parameter must
+                * be used if interaction with the editor is needed after setting the data.
+                *
+                *              CKEDITOR.instances.editor1.setData( '<p>This is the editor data.</p>' );
+                *
+                *              CKEDITOR.instances.editor1.setData( '<p>Some other editor data.</p>', {
+                *                      callback: function() {
+                *                              this.checkDirty(); // true
+                *                      }
+                *              } );
+                *
+                * Note: In **CKEditor 4.4.2** the signature of this method has changed. All arguments
+                * except `data` were wrapped into the `options` object. However, backward compatibility
+                * was preserved and it is still possible to use the `data, callback, internal` arguments.
+                *
+                *
+                * @param {String} data The HTML code to replace current editor content.
+                * @param {Object} [options]
+                * @param {Boolean} [options.internal=false] Whether to suppress any event firing when copying data internally inside the editor.
+                * @param {Function} [options.callback] Function to be called after `setData` is completed (on {@link #dataReady}).
+                * @param {Boolean} [options.noSnapshot=false] If set to `true`, it will prevent recording an undo snapshot.
+                * Introduced in CKEditor 4.4.2.
+                */
+               setData: function( data, options, internal ) {
+                       var fireSnapshot = true,
+                               // Backward compatibility.
+                               callback = options,
+                               eventData;
+
+                       if ( options && typeof options == 'object' ) {
+                               internal = options.internal;
+                               callback = options.callback;
+                               fireSnapshot = !options.noSnapshot;
+                       }
+
+                       if ( !internal && fireSnapshot )
+                               this.fire( 'saveSnapshot' );
+
+                       if ( callback || !internal ) {
+                               this.once( 'dataReady', function( evt ) {
+                                       if ( !internal && fireSnapshot )
+                                               this.fire( 'saveSnapshot' );
+
+                                       if ( callback )
+                                               callback.call( evt.editor );
+                               } );
+                       }
+
+                       // Fire "setData" so data manipulation may happen.
+                       eventData = { dataValue: data };
+                       !internal && this.fire( 'setData', eventData );
+
+                       this._.data = eventData.dataValue;
+
+                       !internal && this.fire( 'afterSetData', eventData );
+               },
+
+               /**
+                * Puts or restores the editor into the read-only state. When in read-only,
+                * the user is not able to change the editor content, but can still use
+                * some editor features. This function sets the {@link #property-readOnly}
+                * property of the editor, firing the {@link #event-readOnly} event.
+                *
+                * **Note:** The current editing area will be reloaded.
+                *
+                * @since 3.6
+                * @param {Boolean} [isReadOnly] Indicates that the editor must go
+                * read-only (`true`, default) or be restored and made editable (`false`).
+                */
+               setReadOnly: function( isReadOnly ) {
+                       isReadOnly = ( isReadOnly == null ) || isReadOnly;
+
+                       if ( this.readOnly != isReadOnly ) {
+                               this.readOnly = isReadOnly;
+
+                               // Block or release BACKSPACE key according to current read-only
+                               // state to prevent browser's history navigation (#9761).
+                               this.keystrokeHandler.blockedKeystrokes[ 8 ] = +isReadOnly;
+
+                               this.editable().setReadOnly( isReadOnly );
+
+                               // Fire the readOnly event so the editor features can update
+                               // their state accordingly.
+                               this.fire( 'readOnly' );
+                       }
+               },
+
+               /**
+                * Inserts HTML code into the currently selected position in the editor in WYSIWYG mode.
+                *
+                * Example:
+                *
+                *              CKEDITOR.instances.editor1.insertHtml( '<p>This is a new paragraph.</p>' );
+                *
+                * Fires the {@link #event-insertHtml} and {@link #event-afterInsertHtml} events. The HTML is inserted
+                * in the {@link #event-insertHtml} event's listener with a default priority (10) so you can add listeners with
+                * lower or higher priorities in order to execute some code before or after the HTML is inserted.
+                *
+                * @param {String} html HTML code to be inserted into the editor.
+                * @param {String} [mode='html'] The mode in which the HTML code will be inserted. One of the following:
+                *
+                * * `'html'` &ndash; The inserted content  will completely override the styles at the selected position.
+                * * `'unfiltered_html'` &ndash; Like `'html'` but the content is not filtered with {@link CKEDITOR.filter}.
+                * * `'text'` &ndash; The inserted content will inherit the styles applied in
+                *    the selected position. This mode should be used when inserting "htmlified" plain text
+                *    (HTML without inline styles and styling elements like `<b>`, `<strong>`, `<span style="...">`).
+                *
+                * @param {CKEDITOR.dom.range} [range] If specified, the HTML will be inserted into the range
+                * instead of into the selection. The selection will be placed at the end of the insertion (like in the normal case).
+                * Introduced in CKEditor 4.5.
+                */
+               insertHtml: function( html, mode, range ) {
+                       this.fire( 'insertHtml', { dataValue: html, mode: mode, range: range } );
+               },
+
+               /**
+                * Inserts text content into the currently selected position in the
+                * editor in WYSIWYG mode. The styles of the selected element will be applied to the inserted text.
+                * Spaces around the text will be left untouched.
+                *
+                *              CKEDITOR.instances.editor1.insertText( ' line1 \n\n line2' );
+                *
+                * Fires the {@link #event-insertText} and {@link #event-afterInsertHtml} events. The text is inserted
+                * in the {@link #event-insertText} event's listener with a default priority (10) so you can add listeners with
+                * lower or higher priorities in order to execute some code before or after the text is inserted.
+                *
+                * @since 3.5
+                * @param {String} text Text to be inserted into the editor.
+                */
+               insertText: function( text ) {
+                       this.fire( 'insertText', text );
+               },
+
+               /**
+                * Inserts an element into the currently selected position in the editor in WYSIWYG mode.
+                *
+                *              var element = CKEDITOR.dom.element.createFromHtml( '<img src="hello.png" border="0" title="Hello" />' );
+                *              CKEDITOR.instances.editor1.insertElement( element );
+                *
+                * Fires the {@link #event-insertElement} event. The element is inserted in the listener with a default priority (10),
+                * so you can add listeners with lower or higher priorities in order to execute some code before or after
+                * the element is inserted.
+                *
+                * @param {CKEDITOR.dom.element} element The element to be inserted into the editor.
+                */
+               insertElement: function( element ) {
+                       this.fire( 'insertElement', element );
+               },
+
+               /**
+                * Gets the selected HTML (it is returned as a {@link CKEDITOR.dom.documentFragment document fragment}
+                * or a string). This method is designed to work as the user would expect the copy functionality to work.
+                * For instance, if the following selection was made:
+                *
+                *              <p>a<b>b{c}d</b>e</p>
+                *
+                * The following HTML will be returned:
+                *
+                *              <b>c</b>
+                *
+                * As you can see, the information about the bold formatting was preserved, even though the selection was
+                * anchored inside the `<b>` element.
+                *
+                * See also:
+                *
+                * * the {@link #extractSelectedHtml} method,
+                * * the {@link CKEDITOR.editable#getHtmlFromRange} method.
+                *
+                * @since 4.5
+                * @param {Boolean} [toString] If `true`, then stringified HTML will be returned.
+                * @returns {CKEDITOR.dom.documentFragment/String}
+                */
+               getSelectedHtml: function( toString ) {
+                       var editable = this.editable(),
+                               selection = this.getSelection(),
+                               ranges = selection && selection.getRanges();
+
+                       if ( !editable || !ranges || ranges.length === 0 ) {
+                               return null;
+                       }
+
+                       var docFragment = createDocumentFragmentFromRanges( ranges, editable );
+
+                       return toString ? docFragment.getHtml() : docFragment;
+               },
+
+               /**
+                * Gets the selected HTML (it is returned as a {@link CKEDITOR.dom.documentFragment document fragment}
+                * or a string) and removes the selected part of the DOM. This method is designed to work as the user would
+                * expect the cut and delete functionalities to work.
+                *
+                * See also:
+                *
+                * * the {@link #getSelectedHtml} method,
+                * * the {@link CKEDITOR.editable#extractHtmlFromRange} method.
+                *
+                * @since 4.5
+                * @param {Boolean} [toString] If `true`, then stringified HTML will be returned.
+                * @param {Boolean} [removeEmptyBlock=false] Default `false` means that the function will keep an empty block (if the
+                * entire content was removed) or it will create it (if a block element was removed) and set the selection in that block.
+                * If `true`, the empty block will be removed or not created. In this case the function will not handle the selection.
+                * @returns {CKEDITOR.dom.documentFragment/String/null}
+                */
+               extractSelectedHtml: function( toString, removeEmptyBlock ) {
+                       var editable = this.editable(),
+                               ranges = this.getSelection().getRanges();
+
+                       if ( !editable || ranges.length === 0 ) {
+                               return null;
+                       }
+
+                       var range = ranges[ 0 ],
+                               docFragment = editable.extractHtmlFromRange( range, removeEmptyBlock );
+
+                       if ( !removeEmptyBlock ) {
+                               this.getSelection().selectRanges( [ range ] );
+                       }
+
+                       return toString ? docFragment.getHtml() : docFragment;
+               },
+
+               /**
+                * Moves the selection focus to the editing area space in the editor.
+                */
+               focus: function() {
+                       this.fire( 'beforeFocus' );
+               },
+
+               /**
+                * Checks whether the current editor content contains changes when
+                * compared to the content loaded into the editor at startup, or to
+                * the content available in the editor when {@link #resetDirty}
+                * was called.
+                *
+                *              function beforeUnload( evt ) {
+                *                      if ( CKEDITOR.instances.editor1.checkDirty() )
+                *                              return evt.returnValue = "You will lose the changes made in the editor.";
+                *              }
+                *
+                *              if ( window.addEventListener )
+                *                      window.addEventListener( 'beforeunload', beforeUnload, false );
+                *              else
+                *                      window.attachEvent( 'onbeforeunload', beforeUnload );
+                *
+                * @returns {Boolean} `true` if the content contains changes.
+                */
+               checkDirty: function() {
+                       return this.status == 'ready' && this._.previousValue !== this.getSnapshot();
+               },
+
+               /**
+                * Resets the "dirty state" of the editor so subsequent calls to
+                * {@link #checkDirty} will return `false` if the user will not
+                * have made further changes to the content.
+                *
+                *              alert( editor.checkDirty() ); // e.g. true
+                *              editor.resetDirty();
+                *              alert( editor.checkDirty() ); // false
+                */
+               resetDirty: function() {
+                       this._.previousValue = this.getSnapshot();
+               },
+
+               /**
+                * Updates the `<textarea>` element that was replaced by the editor with
+                * the current data available in the editor.
+                *
+                * **Note:** This method will only affect those editor instances created
+                * with the {@link CKEDITOR#ELEMENT_MODE_REPLACE} element mode or inline instances
+                * bound to `<textarea>` elements.
+                *
+                *              CKEDITOR.instances.editor1.updateElement();
+                *              alert( document.getElementById( 'editor1' ).value ); // The current editor data.
+                *
+                * @see CKEDITOR.editor#element
+                */
+               updateElement: function() {
+                       return updateEditorElement.call( this );
+               },
+
+               /**
+                * Assigns keystrokes associated with editor commands.
+                *
+                *              editor.setKeystroke( CKEDITOR.CTRL + 115, 'save' );     // Assigned Ctrl+S to the "save" command.
+                *              editor.setKeystroke( CKEDITOR.CTRL + 115, false );      // Disabled Ctrl+S keystroke assignment.
+                *              editor.setKeystroke( [
+                *                      [ CKEDITOR.ALT + 122, false ],
+                *                      [ CKEDITOR.CTRL + 121, 'link' ],
+                *                      [ CKEDITOR.SHIFT + 120, 'bold' ]
+                *              ] );
+                *
+                * This method may be used in the following cases:
+                *
+                * * By plugins (like `link` or `basicstyles`) to set their keystrokes when plugins are being loaded.
+                * * During the runtime to modify existing keystrokes.
+                *
+                * The editor handles keystroke configuration in the following order:
+                *
+                * 1. Plugins use this method to define default keystrokes.
+                * 2. Editor extends default keystrokes with {@link CKEDITOR.config#keystrokes}.
+                * 3. Editor blocks keystrokes defined in {@link CKEDITOR.config#blockedKeystrokes}.
+                *
+                * You can then set new keystrokes using this method during the runtime.
+                *
+                * @since 4.0
+                * @param {Number/Array} keystroke A keystroke or an array of keystroke definitions.
+                * @param {String/Boolean} [behavior] A command to be executed on the keystroke.
+                */
+               setKeystroke: function() {
+                       var keystrokes = this.keystrokeHandler.keystrokes,
+                               newKeystrokes = CKEDITOR.tools.isArray( arguments[ 0 ] ) ? arguments[ 0 ] : [ [].slice.call( arguments, 0 ) ],
+                               keystroke, behavior;
+
+                       for ( var i = newKeystrokes.length; i--; ) {
+                               keystroke = newKeystrokes[ i ];
+                               behavior = 0;
+
+                               // It may be a pair of: [ key, command ]
+                               if ( CKEDITOR.tools.isArray( keystroke ) ) {
+                                       behavior = keystroke[ 1 ];
+                                       keystroke = keystroke[ 0 ];
+                               }
+
+                               if ( behavior )
+                                       keystrokes[ keystroke ] = behavior;
+                               else
+                                       delete keystrokes[ keystroke ];
+                       }
+               },
+
+               /**
+                * Returns the keystroke that is assigned to a specified {@link CKEDITOR.command}. If no keystroke is assigned,
+                * it returns null.
+                *
+                * @since 4.6.0
+                * @param {CKEDITOR.command} command
+                * @returns {Number} The keystroke assigned to the provided command or null if there is no keystroke.
+                */
+               getCommandKeystroke: function( command ) {
+                       var commandName = command.name,
+                               keystrokes = this.keystrokeHandler.keystrokes,
+                               key;
+
+                       // Some commands have a fake keystroke - for example CUT/COPY/PASTE commands are handled natively.
+                       if ( command.fakeKeystroke ) {
+                               return command.fakeKeystroke;
+                       }
+
+                       for ( key in keystrokes ) {
+                               if ( keystrokes.hasOwnProperty( key ) && keystrokes[ key ] == commandName ) {
+                                       return key;
+                               }
+                       }
+
+                       return null;
+               },
+
+               /**
+                * Shorthand for {@link CKEDITOR.filter#addFeature}.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.feature} feature See {@link CKEDITOR.filter#addFeature}.
+                * @returns {Boolean} See {@link CKEDITOR.filter#addFeature}.
+                */
+               addFeature: function( feature ) {
+                       return this.filter.addFeature( feature );
+               },
+
+               /**
+                * Sets the active filter ({@link #activeFilter}). Fires the {@link #activeFilterChange} event.
+                *
+                *              // Set active filter which allows only 4 elements.
+                *              // Buttons like Bold, Italic will be disabled.
+                *              var filter = new CKEDITOR.filter( 'p strong em br' );
+                *              editor.setActiveFilter( filter );
+                *
+                * Setting a new filter will also change the {@link #setActiveEnterMode active Enter modes} to the first values
+                * allowed by the new filter (see {@link CKEDITOR.filter#getAllowedEnterMode}).
+                *
+                * @since 4.3
+                * @param {CKEDITOR.filter} filter Filter instance or a falsy value (e.g. `null`) to reset to the default one.
+                */
+               setActiveFilter: function( filter ) {
+                       if ( !filter )
+                               filter = this.filter;
+
+                       if ( this.activeFilter !== filter ) {
+                               this.activeFilter = filter;
+                               this.fire( 'activeFilterChange' );
+
+                               // Reset active filter to the main one - it resets enter modes, too.
+                               if ( filter === this.filter )
+                                       this.setActiveEnterMode( null, null );
+                               else
+                                       this.setActiveEnterMode(
+                                               filter.getAllowedEnterMode( this.enterMode ),
+                                               filter.getAllowedEnterMode( this.shiftEnterMode, true )
+                                       );
+                       }
+               },
+
+               /**
+                * Sets the active Enter modes: ({@link #enterMode} and {@link #shiftEnterMode}).
+                * Fires the {@link #activeEnterModeChange} event.
+                *
+                * Prior to CKEditor 4.3 Enter modes were static and it was enough to check {@link CKEDITOR.config#enterMode}
+                * and {@link CKEDITOR.config#shiftEnterMode} when implementing a feature which should depend on the Enter modes.
+                * Since CKEditor 4.3 these options are source of initial:
+                *
+                * * static {@link #enterMode} and {@link #shiftEnterMode} values,
+                * * dynamic {@link #activeEnterMode} and {@link #activeShiftEnterMode} values.
+                *
+                * However, the dynamic Enter modes can be changed during runtime by using this method, to reflect the selection context.
+                * For example, if selection is moved to the {@link CKEDITOR.plugins.widget widget}'s nested editable which
+                * is a {@link #blockless blockless one}, then the active Enter modes should be changed to {@link CKEDITOR#ENTER_BR}
+                * (in this case [Widget System](#!/guide/dev_widgets) takes care of that).
+                *
+                * **Note:** This method should not be used to configure the editor &ndash; use {@link CKEDITOR.config#enterMode} and
+                * {@link CKEDITOR.config#shiftEnterMode} instead. This method should only be used to dynamically change
+                * Enter modes during runtime based on selection changes.
+                * Keep in mind that changed Enter mode may be overwritten by another plugin/feature when it decided that
+                * the changed context requires this.
+                *
+                * **Note:** In case of blockless editor (inline editor based on an element which cannot contain block elements
+                * &mdash; see {@link CKEDITOR.editor#blockless}) only {@link CKEDITOR#ENTER_BR} is a valid Enter mode. Therefore
+                * this method will not allow to set other values.
+                *
+                * **Note:** Changing the {@link #activeFilter active filter} may cause the Enter mode to change if default Enter modes
+                * are not allowed by the new filter.
+                *
+                * @since 4.3
+                * @param {Number} enterMode One of {@link CKEDITOR#ENTER_P}, {@link CKEDITOR#ENTER_DIV}, {@link CKEDITOR#ENTER_BR}.
+                * Pass falsy value (e.g. `null`) to reset the Enter mode to the default value ({@link #enterMode} and/or {@link #shiftEnterMode}).
+                * @param {Number} shiftEnterMode See the `enterMode` argument.
+                */
+               setActiveEnterMode: function( enterMode, shiftEnterMode ) {
+                       // Validate passed modes or use default ones (validated on init).
+                       enterMode = enterMode ? validateEnterMode( this, enterMode ) : this.enterMode;
+                       shiftEnterMode = shiftEnterMode ? validateEnterMode( this, shiftEnterMode ) : this.shiftEnterMode;
+
+                       if ( this.activeEnterMode != enterMode || this.activeShiftEnterMode != shiftEnterMode ) {
+                               this.activeEnterMode = enterMode;
+                               this.activeShiftEnterMode = shiftEnterMode;
+                               this.fire( 'activeEnterModeChange' );
+                       }
+               },
+
+               /**
+                * Shows a notification to the user.
+                *
+                * If the [Notification](http://ckeditor.com/addons/notification) plugin is not enabled, this function shows
+                * a normal alert with the given `message`. The `type` and `progressOrDuration` parameters are supported
+                * only by the Notification plugin.
+                *
+                * If the Notification plugin is enabled, this method creates and shows a new notification.
+                * By default the notification is shown over the editor content, in the viewport if it is possible.
+                *
+                * See {@link CKEDITOR.plugins.notification}.
+                *
+                * @since 4.5
+                * @member CKEDITOR.editor
+                * @param {String} message The message displayed in the notification.
+                * @param {String} [type='info'] The type of the notification. Can be `'info'`, `'warning'`, `'success'` or `'progress'`.
+                * @param {Number} [progressOrDuration] If the type is `progress`, the third parameter may be a progress from `0` to `1`
+                * (defaults to `0`). Otherwise the third parameter may be a notification duration denoting after how many milliseconds
+                * the notification should be closed automatically. `0` means that the notification will not close automatically and the user
+                * needs to close it manually. See {@link CKEDITOR.plugins.notification#duration}.
+                * Note that `warning` notifications will not be closed automatically.
+                * @returns {CKEDITOR.plugins.notification} Created and shown notification.
+                */
+               showNotification: function( message ) {
+                       alert( message ); // jshint ignore:line
+               }
+       } );
+} )();
+
+/**
+ * The editor has no associated element.
+ *
+ * @readonly
+ * @property {Number} [=0]
+ * @member CKEDITOR
+ */
+CKEDITOR.ELEMENT_MODE_NONE = 0;
+
+/**
+ * The element is to be replaced by the editor instance.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.ELEMENT_MODE_REPLACE = 1;
+
+/**
+ * The editor is to be created inside the element.
+ *
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.ELEMENT_MODE_APPENDTO = 2;
+
+/**
+ * The editor is to be attached to the element, using it as the editing block.
+ *
+ * @readonly
+ * @property {Number} [=3]
+ * @member CKEDITOR
+ */
+CKEDITOR.ELEMENT_MODE_INLINE = 3;
+
+/**
+ * Whether to escape HTML when the editor updates the original input element.
+ *
+ *             config.htmlEncodeOutput = true;
+ *
+ * @since 3.1
+ * @cfg {Boolean} [htmlEncodeOutput=false]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * If `true`, makes the editor start in read-only state. Otherwise, it will check
+ * if the linked `<textarea>` element has the `disabled` attribute.
+ *
+ * Read more in the [documentation](#!/guide/dev_readonly)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/readonly.html).
+ *
+ *             config.readOnly = true;
+ *
+ * @since 3.6
+ * @cfg {Boolean} [readOnly=false]
+ * @member CKEDITOR.config
+ * @see CKEDITOR.editor#setReadOnly
+ */
+
+/**
+ * Whether an editable element should have focus when the editor is loading for the first time.
+ *
+ *             config.startupFocus = true;
+ *
+ * @cfg {Boolean} [startupFocus=false]
+ * @member CKEDITOR.config
+ */
+
+ /**
+ * Customizes the {@link CKEDITOR.editor#title human-readable title} of this editor. This title is displayed in
+ * tooltips and impacts various [accessibility aspects](#!/guide/dev_a11y-section-announcing-the-editor-on-the-page),
+ * e.g. it is commonly used by screen readers for distinguishing editor instances and for navigation.
+ * Accepted values are a string or `false`.
+ *
+ * **Note:** When `config.title` is set globally, the same value will be applied to all editor instances
+ * loaded with this config. This may adversely affect accessibility as screen reader users will be unable
+ * to distinguish particular editor instances and navigate between them.
+ *
+ * **Note:** Setting `config.title = false` may also impair accessibility in a similar way.
+ *
+ * **Note:** Please do not confuse this property with {@link CKEDITOR.editor#name}
+ * which identifies the instance in the {@link CKEDITOR#instances} literal.
+ *
+ *             // Sets the title to 'My WYSIWYG editor.'. The original title of the element (if it exists)
+ *             // will be restored once the editor instance is destroyed.
+ *             config.title = 'My WYSIWYG editor.';
+ *
+ *             // Do not touch the title. If the element already has a title, it remains unchanged.
+ *             // Also if no `title` attribute exists, nothing new will be added.
+ *             config.title = false;
+ *
+ * See also:
+ *
+ * * CKEDITOR.editor#name
+ * * CKEDITOR.editor#title
+ *
+ * @since 4.2
+ * @cfg {String/Boolean} [title=based on editor.name]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Sets listeners on editor events.
+ *
+ * **Note:** This property can only be set in the `config` object passed directly
+ * to {@link CKEDITOR#replace}, {@link CKEDITOR#inline}, and other creators.
+ *
+ *             CKEDITOR.replace( 'editor1', {
+ *                     on: {
+ *                             instanceReady: function() {
+ *                                     alert( this.name ); // 'editor1'
+ *                             },
+ *
+ *                             key: function() {
+ *                                     // ...
+ *                             }
+ *                     }
+ *             } );
+ *
+ * @cfg {Object} on
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The outermost element in the DOM tree in which the editable element resides. It is provided
+ * by a specific editor creator after the editor UI is created and is not intended to
+ * be modified.
+ *
+ *             var editor = CKEDITOR.instances.editor1;
+ *             alert( editor.container.getName() ); // 'span'
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.element} container
+ */
+
+/**
+ * The document that stores the editor content.
+ *
+ * * For the classic (`iframe`-based) editor it is equal to the document inside the
+ * `iframe` containing the editable element.
+ * * For the inline editor it is equal to {@link CKEDITOR#document}.
+ *
+ * The document object is available after the {@link #contentDom} event is fired
+ * and may be invalidated when the {@link #contentDomUnload} event is fired
+ * (classic editor only).
+ *
+ *             editor.on( 'contentDom', function() {
+ *                     console.log( editor.document );
+ *             } );
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.document} document
+ */
+
+/**
+ * The window instance related to the {@link #document} property.
+ *
+ * It is always equal to the `editor.document.getWindow()`.
+ *
+ * See the {@link #document} property documentation.
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.window} window
+ */
+
+/**
+ * The main filter instance used for input data filtering, data
+ * transformations, and activation of features.
+ *
+ * It points to a {@link CKEDITOR.filter} instance set up based on
+ * editor configuration.
+ *
+ * @since 4.1
+ * @readonly
+ * @property {CKEDITOR.filter} filter
+ */
+
+/**
+ * The active filter instance which should be used in the current context (location selection).
+ * This instance will be used to make a decision which commands, buttons and other
+ * {@link CKEDITOR.feature features} can be enabled.
+ *
+ * By default it equals the {@link #filter} and it can be changed by the {@link #setActiveFilter} method.
+ *
+ *             editor.on( 'activeFilterChange', function() {
+ *                     if ( editor.activeFilter.check( 'cite' ) )
+ *                             // Do something when <cite> was enabled - e.g. enable a button.
+ *                     else
+ *                             // Otherwise do something else.
+ *             } );
+ *
+ * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {CKEDITOR.filter} activeFilter
+ */
+
+/**
+ * The main (static) Enter mode which is a validated version of the {@link CKEDITOR.config#enterMode} setting.
+ * Currently only one rule exists &mdash; {@link #blockless blockless editors} may have
+ * Enter modes set only to {@link CKEDITOR#ENTER_BR}.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {Number} enterMode
+ */
+
+/**
+ * See the {@link #enterMode} property.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {Number} shiftEnterMode
+ */
+
+/**
+ * The dynamic Enter mode which should be used in the current context (selection location).
+ * By default it equals the {@link #enterMode} and it can be changed by the {@link #setActiveEnterMode} method.
+ *
+ * See also the {@link #setActiveEnterMode} method for an explanation of dynamic settings.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {Number} activeEnterMode
+ */
+
+/**
+ * See the {@link #activeEnterMode} property.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {Number} activeShiftEnterMode
+ */
+
+/**
+ * Event fired by the {@link #setActiveFilter} method when the {@link #activeFilter} is changed.
+ *
+ * @since 4.3
+ * @event activeFilterChange
+ */
+
+/**
+ * Event fired by the {@link #setActiveEnterMode} method when any of the active Enter modes is changed.
+ * See also the {@link #activeEnterMode} and {@link #activeShiftEnterMode} properties.
+ *
+ * @since 4.3
+ * @event activeEnterModeChange
+ */
+
+/**
+ * Event fired when a CKEDITOR instance is created, but still before initializing it.
+ * To interact with a fully initialized instance, use the
+ * {@link CKEDITOR#instanceReady} event instead.
+ *
+ * @event instanceCreated
+ * @member CKEDITOR
+ * @param {CKEDITOR.editor} editor The editor instance that has been created.
+ */
+
+/**
+ * Event fired when CKEDITOR instance's components (configuration, languages and plugins) are fully
+ * loaded and initialized. However, the editor will be fully ready for interaction
+ * on {@link CKEDITOR#instanceReady}.
+ *
+ * @event instanceLoaded
+ * @member CKEDITOR
+ * @param {CKEDITOR.editor} editor This editor instance that has been loaded.
+ */
+
+/**
+ * Event fired when a CKEDITOR instance is destroyed.
+ *
+ * @event instanceDestroyed
+ * @member CKEDITOR
+ * @param {CKEDITOR.editor} editor The editor instance that has been destroyed.
+ */
+
+/**
+ * Event fired when a CKEDITOR instance is created, fully initialized and ready for interaction.
+ *
+ * @event instanceReady
+ * @member CKEDITOR
+ * @param {CKEDITOR.editor} editor The editor instance that has been created.
+ */
+
+/**
+ * Event fired when the language is loaded into the editor instance.
+ *
+ * @since 3.6.1
+ * @event langLoaded
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when all plugins are loaded and initialized into the editor instance.
+ *
+ * @event pluginsLoaded
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when the styles set is loaded. During the editor initialization
+ * phase the {@link #getStylesSet} method returns only styles that
+ * are already loaded, which may not include e.g. styles parsed
+ * by the `stylesheetparser` plugin. Thus, to be notified when all
+ * styles are ready, you can listen on this event.
+ *
+ * @since 4.1
+ * @event stylesSet
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {Array} styles An array of styles definitions.
+ */
+
+/**
+ * Event fired before the command execution when {@link #execCommand} is called.
+ *
+ * @event beforeCommandExec
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.name The command name.
+ * @param {Object} data.commandData The data to be sent to the command. This
+ * can be manipulated by the event listener.
+ * @param {CKEDITOR.command} data.command The command itself.
+ */
+
+/**
+ * Event fired after the command execution when {@link #execCommand} is called.
+ *
+ * @event afterCommandExec
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.name The command name.
+ * @param {Object} data.commandData The data sent to the command.
+ * @param {CKEDITOR.command} data.command The command itself.
+ * @param {Object} data.returnValue The value returned by the command execution.
+ */
+
+/**
+ * Event fired when a custom configuration file is loaded, before the final
+ * configuration initialization.
+ *
+ * Custom configuration files can be loaded thorugh the
+ * {@link CKEDITOR.config#customConfig} setting. Several files can be loaded
+ * by changing this setting.
+ *
+ * @event customConfigLoaded
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired once the editor configuration is ready (loaded and processed).
+ *
+ * @event configLoaded
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when this editor instance is destroyed. The editor at this
+ * point is not usable and this event should be used to perform the clean-up
+ * in any plugin.
+ *
+ * @event destroy
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when the {@link #method-destroy} method is called,
+ * but before destroying the editor.
+ *
+ * @event beforeDestroy
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Internal event to get the current data.
+ *
+ * @event beforeGetData
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Internal event to perform the {@link #method-getSnapshot} call.
+ *
+ * @event getSnapshot
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Internal event to perform the {@link #method-loadSnapshot} call.
+ *
+ * @event loadSnapshot
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {String} data The data that will be used.
+ */
+
+/**
+ * Event fired before the {@link #method-getData} call returns, allowing for additional manipulation.
+ *
+ * @event getData
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.dataValue The data that will be returned.
+ */
+
+/**
+ * Event fired before the {@link #method-setData} call is executed, allowing for additional manipulation.
+ *
+ * @event setData
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.dataValue The data that will be used.
+ */
+
+/**
+ * Event fired at the end of the {@link #method-setData} call execution. Usually it is better to use the
+ * {@link #dataReady} event.
+ *
+ * @event afterSetData
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.dataValue The data that has been set.
+ */
+
+/**
+ * Event fired as an indicator of the editor data loading. It may be the result of
+ * calling {@link #method-setData} explicitly or an internal
+ * editor function, like the editor editing mode switching (move to Source and back).
+ *
+ * @event dataReady
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when the CKEDITOR instance is completely created, fully initialized
+ * and ready for interaction.
+ *
+ * @event instanceReady
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when editor components (configuration, languages and plugins) are fully
+ * loaded and initialized. However, the editor will be fully ready to for interaction
+ * on {@link #instanceReady}.
+ *
+ * @event loaded
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired by the {@link #method-insertHtml} method. See the method documentation for more information
+ * about how this event can be used.
+ *
+ * @event insertHtml
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.mode The mode in which the data is inserted (see {@link #method-insertHtml}).
+ * @param {String} data.dataValue The HTML code to insert.
+ * @param {CKEDITOR.dom.range} [data.range] See {@link #method-insertHtml}'s `range` parameter.
+ */
+
+/**
+ * Event fired by the {@link #method-insertText} method. See the method documentation for more information
+ * about how this event can be used.
+ *
+ * @event insertText
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {String} data The text to insert.
+ */
+
+/**
+ * Event fired by the {@link #method-insertElement} method. See the method documentation for more information
+ * about how this event can be used.
+ *
+ * @event insertElement
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param {CKEDITOR.dom.element} data The element to insert.
+ */
+
+/**
+ * Event fired after data insertion using the {@link #method-insertHtml}, {@link CKEDITOR.editable#insertHtml},
+ * or {@link CKEDITOR.editable#insertHtmlIntoRange} methods.
+ *
+ * @since 4.5
+ * @event afterInsertHtml
+ * @param data
+ * @param {CKEDITOR.dom.range} [data.intoRange] If set, the HTML was not inserted into the current selection, but into
+ * the specified range. This property is set if the {@link CKEDITOR.editable#insertHtmlIntoRange} method was used,
+ * but not if for the {@link CKEDITOR.editable#insertHtml} method.
+ */
+
+/**
+ * Event fired after the {@link #property-readOnly} property changes.
+ *
+ * @since 3.6
+ * @event readOnly
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when a UI template is added to the editor instance. It makes
+ * it possible to bring customizations to the template source.
+ *
+ * @event template
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String} data.name The template name.
+ * @param {String} data.source The source data for this template.
+ */
+
+/**
+ * Event fired when the editor content (its DOM structure) is ready.
+ * It is similar to the native `DOMContentLoaded` event, but it applies to
+ * the editor content. It is also the first event fired after
+ * the {@link CKEDITOR.editable} is initialized.
+ *
+ * This event is particularly important for classic (`iframe`-based)
+ * editor, because on editor initialization and every time the data are set
+ * (by {@link CKEDITOR.editor#method-setData}) content DOM structure
+ * is rebuilt. Thus, e.g. you need to attach DOM event listeners
+ * on editable one more time.
+ *
+ * For inline editor this event is fired only once &mdash; when the
+ * editor is initialized for the first time. This is because setting
+ * editor content does not cause editable destruction and creation.
+ *
+ * The {@link #contentDom} event goes along with {@link #contentDomUnload}
+ * which is fired before the content DOM structure is destroyed. This is the
+ * right moment to detach content DOM event listener. Otherwise
+ * browsers like IE or Opera may throw exceptions when accessing
+ * elements from the detached document.
+ *
+ * **Note:** {@link CKEDITOR.editable#attachListener} is a convenient
+ * way to attach listeners that will be detached on {@link #contentDomUnload}.
+ *
+ *             editor.on( 'contentDom', function() {
+ *                     var editable = editor.editable();
+ *
+ *                     editable.attachListener( editable, 'click', function() {
+ *                             console.log( 'The editable was clicked.' );
+ *                     });
+ *             });
+ *
+ * @event contentDom
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired before the content DOM structure is destroyed.
+ * See {@link #contentDom} documentation for more details.
+ *
+ * @event contentDomUnload
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Event fired when the content DOM changes and some of the references as well as
+ * the native DOM event listeners could be lost.
+ * This event is useful when it is important to keep track of references
+ * to elements in the editable content from code.
+ *
+ * @since 4.3
+ * @event contentDomInvalidated
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
diff --git a/sources/core/editor_basic.js b/sources/core/editor_basic.js
new file mode 100644 (file)
index 0000000..b7ab577
--- /dev/null
@@ -0,0 +1,36 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+if ( !CKEDITOR.editor ) {
+       // Documented at editor.js.
+       CKEDITOR.editor = function() {
+               // Push this editor to the pending list. It'll be processed later once
+               // the full editor code is loaded.
+               CKEDITOR._.pending.push( [ this, arguments ] );
+
+               // Call the CKEDITOR.event constructor to initialize this instance.
+               CKEDITOR.event.call( this );
+       };
+
+       // Both fire and fireOnce will always pass this editor instance as the
+       // "editor" param in CKEDITOR.event.fire. So, we override it to do that
+       // automaticaly.
+       CKEDITOR.editor.prototype.fire = function( eventName, data ) {
+               if ( eventName in { instanceReady: 1, loaded: 1 } )
+                       this[ eventName ] = true;
+
+               return CKEDITOR.event.prototype.fire.call( this, eventName, data, this );
+       };
+
+       CKEDITOR.editor.prototype.fireOnce = function( eventName, data ) {
+               if ( eventName in { instanceReady: 1, loaded: 1 } )
+                       this[ eventName ] = true;
+
+               return CKEDITOR.event.prototype.fireOnce.call( this, eventName, data, this );
+       };
+
+       // "Inherit" (copy actually) from CKEDITOR.event.
+       CKEDITOR.event.implementOn( CKEDITOR.editor.prototype );
+}
diff --git a/sources/core/env.js b/sources/core/env.js
new file mode 100644 (file)
index 0000000..43b608a
--- /dev/null
@@ -0,0 +1,361 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.env} object which contains
+ *             environment and browser information.
+ */
+
+if ( !CKEDITOR.env ) {
+       /**
+        * Environment and browser information.
+        *
+        * @class CKEDITOR.env
+        * @singleton
+        */
+       CKEDITOR.env = ( function() {
+               var agent = navigator.userAgent.toLowerCase(),
+                       edge = agent.match( /edge[ \/](\d+.?\d*)/ ),
+                       trident = agent.indexOf( 'trident/' ) > -1,
+                       ie = !!( edge || trident );
+
+               var env = {
+                       /**
+                        * Indicates that CKEditor is running in Internet Explorer.
+                        *
+                        *              if ( CKEDITOR.env.ie )
+                        *                      alert( 'I\'m running in IE!' );
+                        *
+                        * **Note:** This property is also set to `true` if CKEditor is running
+                        * in {@link #edge Microsoft Edge}.
+                        *
+                        * @property {Boolean}
+                        */
+                       ie: ie,
+
+                       /**
+                        * Indicates that CKEditor is running in Microsoft Edge.
+                        *
+                        *              if ( CKEDITOR.env.edge )
+                        *                      alert( 'I\'m running in Edge!' );
+                        *
+                        * See also {@link #ie}.
+                        *
+                        * @since 4.5
+                        * @property {Boolean}
+                        */
+                       edge: !!edge,
+
+                       /**
+                        * Indicates that CKEditor is running in a WebKit-based browser, like Safari,
+                        * or Blink-based browser, like Chrome.
+                        *
+                        *              if ( CKEDITOR.env.webkit )
+                        *                      alert( 'I\'m running in a WebKit browser!' );
+                        *
+                        * @property {Boolean}
+                        */
+                       webkit: !ie && ( agent.indexOf( ' applewebkit/' ) > -1 ),
+
+                       /**
+                        * Indicates that CKEditor is running in Adobe AIR.
+                        *
+                        *              if ( CKEDITOR.env.air )
+                        *                      alert( 'I\'m on AIR!' );
+                        *
+                        * @property {Boolean}
+                        */
+                       air: ( agent.indexOf( ' adobeair/' ) > -1 ),
+
+                       /**
+                        * Indicates that CKEditor is running on Macintosh.
+                        *
+                        *              if ( CKEDITOR.env.mac )
+                        *                      alert( 'I love apples!'' );
+                        *
+                        * @property {Boolean}
+                        */
+                       mac: ( agent.indexOf( 'macintosh' ) > -1 ),
+
+                       /**
+                        * Indicates that CKEditor is running in a Quirks Mode environment.
+                        *
+                        *              if ( CKEDITOR.env.quirks )
+                        *                      alert( 'Nooooo!' );
+                        *
+                        * Internet Explorer 10 introduced the _New Quirks Mode_, which is similar to the _Quirks Mode_
+                        * implemented in other modern browsers and defined in the HTML5 specification. It can be handled
+                        * as the Standards mode, so the value of this property will be set to `false`.
+                        *
+                        * The _Internet Explorer 5 Quirks_ mode which is still available in Internet Explorer 10+
+                        * sets this value to `true` and {@link #version} to `7`.
+                        *
+                        * Read more: [IEBlog](http://blogs.msdn.com/b/ie/archive/2011/12/14/interoperable-html5-quirks-mode-in-ie10.aspx)
+                        *
+                        * @property {Boolean}
+                        */
+                       quirks: ( document.compatMode == 'BackCompat' && ( !document.documentMode || document.documentMode < 10 ) ),
+
+                       /**
+                        * Indicates that CKEditor is running in a mobile environemnt.
+                        *
+                        *              if ( CKEDITOR.env.mobile )
+                        *                      alert( 'I\'m running with CKEditor today!' );
+                        *
+                        * @deprecated
+                        * @property {Boolean}
+                        */
+                       mobile: ( agent.indexOf( 'mobile' ) > -1 ),
+
+                       /**
+                        * Indicates that CKEditor is running on Apple iPhone/iPad/iPod devices.
+                        *
+                        *              if ( CKEDITOR.env.iOS )
+                        *                      alert( 'I like little apples!' );
+                        *
+                        * @property {Boolean}
+                        */
+                       iOS: /(ipad|iphone|ipod)/.test( agent ),
+
+                       /**
+                        * Indicates that the browser has a custom domain enabled. This has
+                        * been set with `document.domain`.
+                        *
+                        *              if ( CKEDITOR.env.isCustomDomain() )
+                        *                      alert( 'I\'m in a custom domain!' );
+                        *
+                        * @returns {Boolean} `true` if a custom domain is enabled.
+                        * @deprecated
+                        */
+                       isCustomDomain: function() {
+                               if ( !this.ie )
+                                       return false;
+
+                               var domain = document.domain,
+                                       hostname = window.location.hostname;
+
+                               return domain != hostname && domain != ( '[' + hostname + ']' ); // IPv6 IP support (#5434)
+                       },
+
+                       /**
+                        * Indicates that the page is running under an encrypted connection.
+                        *
+                        *              if ( CKEDITOR.env.secure )
+                        *                      alert( 'I\'m on SSL!' );
+                        *
+                        * @returns {Boolean} `true` if the page has an encrypted connection.
+                        */
+                       secure: location.protocol == 'https:'
+               };
+
+               /**
+                * Indicates that CKEditor is running in a Gecko-based browser, like
+                * Firefox.
+                *
+                *              if ( CKEDITOR.env.gecko )
+                *                      alert( 'I\'m riding a gecko!' );
+                *
+                * @property {Boolean}
+                */
+               env.gecko = ( navigator.product == 'Gecko' && !env.webkit && !env.ie );
+
+               /**
+                * Indicates that CKEditor is running in a Blink-based browser like Chrome.
+                *
+                *              if ( CKEDITOR.env.chrome )
+                *                      alert( 'I\'m running in Chrome!' );
+                *
+                * @property {Boolean} chrome
+                */
+
+               /**
+                * Indicates that CKEditor is running in Safari (including the mobile version).
+                *
+                *              if ( CKEDITOR.env.safari )
+                *                      alert( 'I\'m on Safari!' );
+                *
+                * @property {Boolean} safari
+                */
+               if ( env.webkit ) {
+                       if ( agent.indexOf( 'chrome' ) > -1 )
+                               env.chrome = true;
+                       else
+                               env.safari = true;
+               }
+
+               var version = 0;
+
+               // Internet Explorer 6.0+
+               if ( env.ie ) {
+                       // We use env.version for feature detection, so set it properly.
+                       if ( edge ) {
+                               version = parseFloat( edge[ 1 ] );
+                       } else if ( env.quirks || !document.documentMode ) {
+                               version = parseFloat( agent.match( /msie (\d+)/ )[ 1 ] );
+                       } else {
+                               version = document.documentMode;
+                       }
+
+                       // Deprecated features available just for backwards compatibility.
+                       env.ie9Compat = version == 9;
+                       env.ie8Compat = version == 8;
+                       env.ie7Compat = version == 7;
+                       env.ie6Compat = version < 7 || env.quirks;
+
+                       /**
+                        * Indicates that CKEditor is running in an IE6-like environment, which
+                        * includes IE6 itself as well as IE7, IE8 and IE9 in Quirks Mode.
+                        *
+                        * @deprecated
+                        * @property {Boolean} ie6Compat
+                        */
+
+                       /**
+                        * Indicates that CKEditor is running in an IE7-like environment, which
+                        * includes IE7 itself and IE8's IE7 Document Mode.
+                        *
+                        * @deprecated
+                        * @property {Boolean} ie7Compat
+                        */
+
+                       /**
+                        * Indicates that CKEditor is running in Internet Explorer 8 on
+                        * Standards Mode.
+                        *
+                        * @deprecated
+                        * @property {Boolean} ie8Compat
+                        */
+
+                       /**
+                        * Indicates that CKEditor is running in Internet Explorer 9 on
+                        * Standards Mode.
+                        *
+                        * @deprecated
+                        * @property {Boolean} ie9Compat
+                        */
+               }
+
+               // Gecko.
+               if ( env.gecko ) {
+                       var geckoRelease = agent.match( /rv:([\d\.]+)/ );
+                       if ( geckoRelease ) {
+                               geckoRelease = geckoRelease[ 1 ].split( '.' );
+                               version = geckoRelease[ 0 ] * 10000 + ( geckoRelease[ 1 ] || 0 ) * 100 + ( geckoRelease[ 2 ] || 0 ) * 1;
+                       }
+               }
+
+               // Adobe AIR 1.0+
+               // Checked before Safari because AIR have the WebKit rich text editor
+               // features from Safari 3.0.4, but the version reported is 420.
+               if ( env.air )
+                       version = parseFloat( agent.match( / adobeair\/(\d+)/ )[ 1 ] );
+
+               // WebKit 522+ (Safari 3+)
+               if ( env.webkit )
+                       version = parseFloat( agent.match( / applewebkit\/(\d+)/ )[ 1 ] );
+
+               /**
+                * Contains the browser version.
+                *
+                * For Gecko-based browsers (like Firefox) it contains the revision
+                * number with first three parts concatenated with a padding zero
+                * (e.g. for revision 1.9.0.2 we have 10900).
+                *
+                * For WebKit-based browsers (like Safari and Chrome) it contains the
+                * WebKit build version (e.g. 522).
+                *
+                * For IE browsers, it matches the "Document Mode".
+                *
+                *              if ( CKEDITOR.env.ie && CKEDITOR.env.version <= 6 )
+                *                      alert( 'Ouch!' );
+                *
+                * @property {Number}
+                */
+               env.version = version;
+
+               /**
+                * Since CKEditor 4.5 this property is a blacklist of browsers incompatible with CKEditor. It means that it is
+                * set to `false` only in browsers that are known to be incompatible. Before CKEditor 4.5 this
+                * property was a whitelist of browsers that were known to be compatible with CKEditor.
+                *
+                * The reason for this change is the rising fragmentation of the browser market (especially the mobile segment).
+                * It became too complicated to check in which new environments CKEditor is going to work.
+                *
+                * In order to enable CKEditor 4.4.x and below in unsupported environments see the
+                * [Enabling CKEditor in Unsupported Environments](#!/guide/dev_unsupported_environments) article.
+                *
+                *              if ( CKEDITOR.env.isCompatible )
+                *                      alert( 'Your browser is not known to be incompatible with CKEditor!' );
+                *
+                * @property {Boolean}
+                */
+               env.isCompatible =
+                       // IE 7+ (IE 7 is not supported, but IE Compat Mode is and it is recognized as IE7).
+                       !( env.ie && version < 7 ) &&
+                       // Firefox 4.0+.
+                       !( env.gecko && version < 40000 ) &&
+                       // Chrome 6+, Safari 5.1+, iOS 5+.
+                       !( env.webkit && version < 534 );
+
+               /**
+                * Indicates that CKEditor is running in the HiDPI environment.
+                *
+                *              if ( CKEDITOR.env.hidpi )
+                *                      alert( 'You are using a screen with high pixel density.' );
+                *
+                * @property {Boolean}
+                */
+               env.hidpi = window.devicePixelRatio >= 2;
+
+               /**
+                * Indicates that CKEditor is running in a browser which uses a bogus
+                * `<br>` filler in order to correctly display caret in empty blocks.
+                *
+                * @since 4.3
+                * @property {Boolean}
+                */
+               env.needsBrFiller = env.gecko || env.webkit || ( env.ie && version > 10 );
+
+               /**
+                * Indicates that CKEditor is running in a browser which needs a
+                * non-breaking space filler in order to correctly display caret in empty blocks.
+                *
+                * @since 4.3
+                * @property {Boolean}
+                */
+               env.needsNbspFiller = env.ie && version < 11;
+
+               /**
+                * A CSS class that denotes the browser where CKEditor runs and is appended
+                * to the HTML element that contains the editor. It makes it easier to apply
+                * browser-specific styles to editor instances.
+                *
+                *              myDiv.className = CKEDITOR.env.cssClass;
+                *
+                * @property {String}
+                */
+               env.cssClass = 'cke_browser_' + ( env.ie ? 'ie' : env.gecko ? 'gecko' : env.webkit ? 'webkit' : 'unknown' );
+
+               if ( env.quirks )
+                       env.cssClass += ' cke_browser_quirks';
+
+               if ( env.ie )
+                       env.cssClass += ' cke_browser_ie' + ( env.quirks ? '6 cke_browser_iequirks' : env.version );
+
+               if ( env.air )
+                       env.cssClass += ' cke_browser_air';
+
+               if ( env.iOS )
+                       env.cssClass += ' cke_browser_ios';
+
+               if ( env.hidpi )
+                       env.cssClass += ' cke_hidpi';
+
+               return env;
+       } )();
+}
+
+// PACKAGER_RENAME( CKEDITOR.env )
+// PACKAGER_RENAME( CKEDITOR.env.ie )
diff --git a/sources/core/event.js b/sources/core/event.js
new file mode 100644 (file)
index 0000000..89444b5
--- /dev/null
@@ -0,0 +1,389 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.event} class, which serves as the
+ *             base for classes and objects that require event handling features.
+ */
+
+if ( !CKEDITOR.event ) {
+       /**
+        * Creates an event class instance. This constructor is rarely used, being
+        * the {@link #implementOn} function used in class prototypes directly
+        * instead.
+        *
+        * This is a base class for classes and objects that require event
+        * handling features.
+        *
+        * Do not confuse this class with {@link CKEDITOR.dom.event} which is
+        * instead used for DOM events. The CKEDITOR.event class implements the
+        * internal event system used by the CKEditor to fire API related events.
+        *
+        * @class
+        * @constructor Creates an event class instance.
+        */
+       CKEDITOR.event = function() {};
+
+       /**
+        * Implements the {@link CKEDITOR.event} features in an object.
+        *
+        *              var myObject = { message: 'Example' };
+        *              CKEDITOR.event.implementOn( myObject );
+        *
+        *              myObject.on( 'testEvent', function() {
+        *                      alert( this.message );
+        *              } );
+        *              myObject.fire( 'testEvent' ); // 'Example'
+        *
+        * @static
+        * @param {Object} targetObject The object into which implement the features.
+        */
+       CKEDITOR.event.implementOn = function( targetObject ) {
+               var eventProto = CKEDITOR.event.prototype;
+
+               for ( var prop in eventProto ) {
+                       if ( targetObject[ prop ] == null )
+                               targetObject[ prop ] = eventProto[ prop ];
+               }
+       };
+
+       CKEDITOR.event.prototype = ( function() {
+               // Returns the private events object for a given object.
+               var getPrivate = function( obj ) {
+                               var _ = ( obj.getPrivate && obj.getPrivate() ) || obj._ || ( obj._ = {} );
+                               return _.events || ( _.events = {} );
+                       };
+
+               var eventEntry = function( eventName ) {
+                               this.name = eventName;
+                               this.listeners = [];
+                       };
+
+               eventEntry.prototype = {
+                       // Get the listener index for a specified function.
+                       // Returns -1 if not found.
+                       getListenerIndex: function( listenerFunction ) {
+                               for ( var i = 0, listeners = this.listeners; i < listeners.length; i++ ) {
+                                       if ( listeners[ i ].fn == listenerFunction )
+                                               return i;
+                               }
+                               return -1;
+                       }
+               };
+
+               // Retrieve the event entry on the event host (create it if needed).
+               function getEntry( name ) {
+                       // Get the event entry (create it if needed).
+                       var events = getPrivate( this );
+                       return events[ name ] || ( events[ name ] = new eventEntry( name ) );
+               }
+
+               return {
+                       /**
+                        * Predefine some intrinsic properties on a specific event name.
+                        *
+                        * @param {String} name The event name
+                        * @param meta
+                        * @param [meta.errorProof=false] Whether the event firing should catch error thrown from a per listener call.
+                        */
+                       define: function( name, meta ) {
+                               var entry = getEntry.call( this, name );
+                               CKEDITOR.tools.extend( entry, meta, true );
+                       },
+
+                       /**
+                        * Registers a listener to a specific event in the current object.
+                        *
+                        *              someObject.on( 'someEvent', function() {
+                        *                      alert( this == someObject );            // true
+                        *              } );
+                        *
+                        *              someObject.on( 'someEvent', function() {
+                        *                      alert( this == anotherObject );         // true
+                        *              }, anotherObject );
+                        *
+                        *              someObject.on( 'someEvent', function( event ) {
+                        *                      alert( event.listenerData );            // 'Example'
+                        *              }, null, 'Example' );
+                        *
+                        *              someObject.on( 'someEvent', function() { ... } );                                               // 2nd called
+                        *              someObject.on( 'someEvent', function() { ... }, null, null, 100 );              // 3rd called
+                        *              someObject.on( 'someEvent', function() { ... }, null, null, 1 );                // 1st called
+                        *
+                        * @param {String} eventName The event name to which listen.
+                        * @param {Function} listenerFunction The function listening to the
+                        * event. A single {@link CKEDITOR.eventInfo} object instanced
+                        * is passed to this function containing all the event data.
+                        * @param {Object} [scopeObj] The object used to scope the listener
+                        * call (the `this` object). If omitted, the current object is used.
+                        * @param {Object} [listenerData] Data to be sent as the
+                        * {@link CKEDITOR.eventInfo#listenerData} when calling the
+                        * listener.
+                        * @param {Number} [priority=10] The listener priority. Lower priority
+                        * listeners are called first. Listeners with the same priority
+                        * value are called in registration order.
+                        * @returns {Object} An object containing the `removeListener`
+                        * function, which can be used to remove the listener at any time.
+                        */
+                       on: function( eventName, listenerFunction, scopeObj, listenerData, priority ) {
+                               // Create the function to be fired for this listener.
+                               function listenerFirer( editor, publisherData, stopFn, cancelFn ) {
+                                       var ev = {
+                                               name: eventName,
+                                               sender: this,
+                                               editor: editor,
+                                               data: publisherData,
+                                               listenerData: listenerData,
+                                               stop: stopFn,
+                                               cancel: cancelFn,
+                                               removeListener: removeListener
+                                       };
+
+                                       var ret = listenerFunction.call( scopeObj, ev );
+
+                                       return ret === false ? false : ev.data;
+                               }
+
+                               function removeListener() {
+                                       me.removeListener( eventName, listenerFunction );
+                               }
+
+                               var event = getEntry.call( this, eventName );
+
+                               if ( event.getListenerIndex( listenerFunction ) < 0 ) {
+                                       // Get the listeners.
+                                       var listeners = event.listeners;
+
+                                       // Fill the scope.
+                                       if ( !scopeObj )
+                                               scopeObj = this;
+
+                                       // Default the priority, if needed.
+                                       if ( isNaN( priority ) )
+                                               priority = 10;
+
+                                       var me = this;
+
+                                       listenerFirer.fn = listenerFunction;
+                                       listenerFirer.priority = priority;
+
+                                       // Search for the right position for this new listener, based on its
+                                       // priority.
+                                       for ( var i = listeners.length - 1; i >= 0; i-- ) {
+                                               // Find the item which should be before the new one.
+                                               if ( listeners[ i ].priority <= priority ) {
+                                                       // Insert the listener in the array.
+                                                       listeners.splice( i + 1, 0, listenerFirer );
+                                                       return { removeListener: removeListener };
+                                               }
+                                       }
+
+                                       // If no position has been found (or zero length), put it in
+                                       // the front of list.
+                                       listeners.unshift( listenerFirer );
+                               }
+
+                               return { removeListener: removeListener };
+                       },
+
+                       /**
+                        * Similiar with {@link #on} but the listener will be called only once upon the next event firing.
+                        *
+                        * @see CKEDITOR.event#on
+                        */
+                       once: function() {
+                               var args = Array.prototype.slice.call( arguments ),
+                                       fn = args[ 1 ];
+
+                               args[ 1 ] = function( evt ) {
+                                       evt.removeListener();
+                                       return fn.apply( this, arguments );
+                               };
+
+                               return this.on.apply( this, args );
+                       },
+
+                       /**
+                        * @static
+                        * @property {Boolean} useCapture
+                        * @todo
+                        */
+
+                       /**
+                        * Register event handler under the capturing stage on supported target.
+                        */
+                       capture: function() {
+                               CKEDITOR.event.useCapture = 1;
+                               var retval = this.on.apply( this, arguments );
+                               CKEDITOR.event.useCapture = 0;
+                               return retval;
+                       },
+
+                       /**
+                        * Fires an specific event in the object. All registered listeners are
+                        * called at this point.
+                        *
+                        *              someObject.on( 'someEvent', function() { ... } );
+                        *              someObject.on( 'someEvent', function() { ... } );
+                        *              someObject.fire( 'someEvent' );                         // Both listeners are called.
+                        *
+                        *              someObject.on( 'someEvent', function( event ) {
+                        *                      alert( event.data );                                    // 'Example'
+                        *              } );
+                        *              someObject.fire( 'someEvent', 'Example' );
+                        *
+                        * @method
+                        * @param {String} eventName The event name to fire.
+                        * @param {Object} [data] Data to be sent as the
+                        * {@link CKEDITOR.eventInfo#data} when calling the listeners.
+                        * @param {CKEDITOR.editor} [editor] The editor instance to send as the
+                        * {@link CKEDITOR.eventInfo#editor} when calling the listener.
+                        * @returns {Boolean/Object} A boolean indicating that the event is to be
+                        * canceled, or data returned by one of the listeners.
+                        */
+                       fire: ( function() {
+                               // Create the function that marks the event as stopped.
+                               var stopped = 0;
+                               var stopEvent = function() {
+                                               stopped = 1;
+                                       };
+
+                               // Create the function that marks the event as canceled.
+                               var canceled = 0;
+                               var cancelEvent = function() {
+                                               canceled = 1;
+                                       };
+
+                               return function( eventName, data, editor ) {
+                                       // Get the event entry.
+                                       var event = getPrivate( this )[ eventName ];
+
+                                       // Save the previous stopped and cancelled states. We may
+                                       // be nesting fire() calls.
+                                       var previousStopped = stopped,
+                                               previousCancelled = canceled;
+
+                                       // Reset the stopped and canceled flags.
+                                       stopped = canceled = 0;
+
+                                       if ( event ) {
+                                               var listeners = event.listeners;
+
+                                               if ( listeners.length ) {
+                                                       // As some listeners may remove themselves from the
+                                                       // event, the original array length is dinamic. So,
+                                                       // let's make a copy of all listeners, so we are
+                                                       // sure we'll call all of them.
+                                                       listeners = listeners.slice( 0 );
+
+                                                       var retData;
+                                                       // Loop through all listeners.
+                                                       for ( var i = 0; i < listeners.length; i++ ) {
+                                                               // Call the listener, passing the event data.
+                                                               if ( event.errorProof ) {
+                                                                       try {
+                                                                               retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
+                                                                       } catch ( er ) {}
+                                                               } else {
+                                                                       retData = listeners[ i ].call( this, editor, data, stopEvent, cancelEvent );
+                                                               }
+
+                                                               if ( retData === false )
+                                                                       canceled = 1;
+                                                               else if ( typeof retData != 'undefined' )
+                                                                       data = retData;
+
+                                                               // No further calls is stopped or canceled.
+                                                               if ( stopped || canceled )
+                                                                       break;
+                                                       }
+                                               }
+                                       }
+
+                                       var ret = canceled ? false : ( typeof data == 'undefined' ? true : data );
+
+                                       // Restore the previous stopped and canceled states.
+                                       stopped = previousStopped;
+                                       canceled = previousCancelled;
+
+                                       return ret;
+                               };
+                       } )(),
+
+                       /**
+                        * Fires an specific event in the object, releasing all listeners
+                        * registered to that event. The same listeners are not called again on
+                        * successive calls of it or of {@link #fire}.
+                        *
+                        *              someObject.on( 'someEvent', function() { ... } );
+                        *              someObject.fire( 'someEvent' );                 // Above listener called.
+                        *              someObject.fireOnce( 'someEvent' );             // Above listener called.
+                        *              someObject.fire( 'someEvent' );                 // No listeners called.
+                        *
+                        * @param {String} eventName The event name to fire.
+                        * @param {Object} [data] Data to be sent as the
+                        * {@link CKEDITOR.eventInfo#data} when calling the listeners.
+                        * @param {CKEDITOR.editor} [editor] The editor instance to send as the
+                        * {@link CKEDITOR.eventInfo#editor} when calling the listener.
+                        * @returns {Boolean/Object} A booloan indicating that the event is to be
+                        * canceled, or data returned by one of the listeners.
+                        */
+                       fireOnce: function( eventName, data, editor ) {
+                               var ret = this.fire( eventName, data, editor );
+                               delete getPrivate( this )[ eventName ];
+                               return ret;
+                       },
+
+                       /**
+                        * Unregisters a listener function from being called at the specified
+                        * event. No errors are thrown if the listener has not been registered previously.
+                        *
+                        *              var myListener = function() { ... };
+                        *              someObject.on( 'someEvent', myListener );
+                        *              someObject.fire( 'someEvent' );                                 // myListener called.
+                        *              someObject.removeListener( 'someEvent', myListener );
+                        *              someObject.fire( 'someEvent' );                                 // myListener not called.
+                        *
+                        * @param {String} eventName The event name.
+                        * @param {Function} listenerFunction The listener function to unregister.
+                        */
+                       removeListener: function( eventName, listenerFunction ) {
+                               // Get the event entry.
+                               var event = getPrivate( this )[ eventName ];
+
+                               if ( event ) {
+                                       var index = event.getListenerIndex( listenerFunction );
+                                       if ( index >= 0 )
+                                               event.listeners.splice( index, 1 );
+                               }
+                       },
+
+                       /**
+                        * Remove all existing listeners on this object, for cleanup purpose.
+                        */
+                       removeAllListeners: function() {
+                               var events = getPrivate( this );
+                               for ( var i in events )
+                                       delete events[ i ];
+                       },
+
+                       /**
+                        * Checks if there is any listener registered to a given event.
+                        *
+                        *              var myListener = function() { ... };
+                        *              someObject.on( 'someEvent', myListener );
+                        *              alert( someObject.hasListeners( 'someEvent' ) );        // true
+                        *              alert( someObject.hasListeners( 'noEvent' ) );          // false
+                        *
+                        * @param {String} eventName The event name.
+                        * @returns {Boolean}
+                        */
+                       hasListeners: function( eventName ) {
+                               var event = getPrivate( this )[ eventName ];
+                               return ( event && event.listeners.length > 0 );
+                       }
+               };
+       } )();
+}
diff --git a/sources/core/eventInfo.js b/sources/core/eventInfo.js
new file mode 100644 (file)
index 0000000..ea62ac9
--- /dev/null
@@ -0,0 +1,115 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the "virtual" {@link CKEDITOR.eventInfo} class, which
+ *             contains the defintions of the event object passed to event listeners.
+ *             This file is for documentation purposes only.
+ */
+
+/**
+ * Virtual class that illustrates the features of the event object to be
+ * passed to event listeners by a {@link CKEDITOR.event} based object.
+ *
+ * This class is not really part of the API.
+ *
+ * @class CKEDITOR.eventInfo
+ * @abstract
+ */
+
+/**
+ * The event name.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     alert( event.name ); // 'someEvent'
+ *             } );
+ *             someObject.fire( 'someEvent' );
+ *
+ * @property {String} name
+ */
+
+/**
+ * The object that publishes (sends) the event.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     alert( event.sender == someObject ); // true
+ *             } );
+ *             someObject.fire( 'someEvent' );
+ *
+ * @property sender
+ */
+
+/**
+ * The editor instance that holds the sender. May be the same as sender. May be
+ * null if the sender is not part of an editor instance, like a component
+ * running in standalone mode.
+ *
+ *             myButton.on( 'someEvent', function( event ) {
+ *                     alert( event.editor == myEditor ); // true
+ *             } );
+ *             myButton.fire( 'someEvent', null, myEditor );
+ *
+ * @property {CKEDITOR.editor} editor
+ */
+
+/**
+ * Any kind of additional data. Its format and usage is event dependent.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     alert( event.data ); // 'Example'
+ *             } );
+ *             someObject.fire( 'someEvent', 'Example' );
+ *
+ * @property data
+ */
+
+/**
+ * Any extra data appended during the listener registration.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     alert( event.listenerData ); // 'Example'
+ *             }, null, 'Example' );
+ *
+ * @property listenerData
+ */
+
+/**
+ * Indicates that no further listeners are to be called.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     event.stop();
+ *             } );
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     // This one will not be called.
+ *             } );
+ *             alert( someObject.fire( 'someEvent' ) ); // true
+ *
+ * @method stop
+ */
+
+/**
+ * Indicates that the event is to be cancelled (if cancelable).
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     event.cancel();
+ *             } );
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     // This one will not be called.
+ *             } );
+ *             alert( someObject.fire( 'someEvent' ) ); // false
+ *
+ * @method cancel
+ */
+
+/**
+ * Removes the current listener.
+ *
+ *             someObject.on( 'someEvent', function( event ) {
+ *                     event.removeListener();
+ *                     // Now this function won't be called again by 'someEvent'.
+ *             } );
+ *
+ * @method removeListener
+ */
diff --git a/sources/core/filter.js b/sources/core/filter.js
new file mode 100644 (file)
index 0000000..db68530
--- /dev/null
@@ -0,0 +1,2540 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       'use strict';
+
+       var DTD = CKEDITOR.dtd,
+               // processElement flag - means that element has been somehow modified.
+               FILTER_ELEMENT_MODIFIED = 1,
+               // processElement flag - meaning explained in CKEDITOR.FILTER_SKIP_TREE doc.
+               FILTER_SKIP_TREE = 2,
+               copy = CKEDITOR.tools.copy,
+               trim = CKEDITOR.tools.trim,
+               TEST_VALUE = 'cke-test',
+               enterModeTags = [ '', 'p', 'br', 'div' ];
+
+       /**
+        * A flag indicating that the current element and all its ancestors
+        * should not be filtered.
+        *
+        * See {@link CKEDITOR.filter#addElementCallback} for more details.
+        *
+        * @since 4.4
+        * @readonly
+        * @property {Number} [=2]
+        * @member CKEDITOR
+        */
+       CKEDITOR.FILTER_SKIP_TREE = FILTER_SKIP_TREE;
+
+       /**
+        * Highly configurable class which implements input data filtering mechanisms
+        * and core functions used for the activation of editor features.
+        *
+        * A filter instance is always available under the {@link CKEDITOR.editor#filter}
+        * property and is used by the editor in its core features like filtering input data,
+        * applying data transformations, validating whether a feature may be enabled for
+        * the current setup. It may be configured in two ways:
+        *
+        *      * By the user, with the {@link CKEDITOR.config#allowedContent} setting.
+        *      * Automatically, by loaded features (toolbar items, commands, etc.).
+        *
+        * In both cases additional allowed content rules may be added by
+        * setting the {@link CKEDITOR.config#extraAllowedContent}
+        * configuration option.
+        *
+        * **Note**: Filter rules will be extended with the following elements
+        * depending on the {@link CKEDITOR.config#enterMode} and
+        * {@link CKEDITOR.config#shiftEnterMode} settings:
+        *
+        *      * `'p'` &ndash; for {@link CKEDITOR#ENTER_P},
+        *      * `'div'` &ndash; for {@link CKEDITOR#ENTER_DIV},
+        *      * `'br'` &ndash; for {@link CKEDITOR#ENTER_BR}.
+        *
+        * **Read more** about the Advanced Content Filter in [guides](#!/guide/dev_advanced_content_filter).
+        *
+        * Filter may also be used as a standalone instance by passing
+        * {@link CKEDITOR.filter.allowedContentRules} instead of {@link CKEDITOR.editor}
+        * to the constructor:
+        *
+        *              var filter = new CKEDITOR.filter( 'b' );
+        *
+        *              filter.check( 'b' ); // -> true
+        *              filter.check( 'i' ); // -> false
+        *              filter.allow( 'i' );
+        *              filter.check( 'i' ); // -> true
+        *
+        * @since 4.1
+        * @class
+        * @constructor Creates a filter class instance.
+        * @param {CKEDITOR.editor/CKEDITOR.filter.allowedContentRules} editorOrRules
+        */
+       CKEDITOR.filter = function( editorOrRules ) {
+               /**
+                * Whether custom {@link CKEDITOR.config#allowedContent} was set.
+                *
+                * This property does not apply to the standalone filter.
+                *
+                * @readonly
+                * @property {Boolean} customConfig
+                */
+
+               /**
+                * Array of rules added by the {@link #allow} method (including those
+                * loaded from {@link CKEDITOR.config#allowedContent} and
+                * {@link CKEDITOR.config#extraAllowedContent}).
+                *
+                * Rules in this array are in unified allowed content rules format.
+                *
+                * This property is useful for debugging issues with rules string parsing
+                * or for checking which rules were automatically added by editor features.
+                *
+                * @readonly
+                */
+               this.allowedContent = [];
+
+               /**
+                * Array of rules added by the {@link #disallow} method (including those
+                * loaded from {@link CKEDITOR.config#disallowedContent}).
+                *
+                * Rules in this array are in unified disallowed content rules format.
+                *
+                * This property is useful for debugging issues with rules string parsing
+                * or for checking which rules were automatically added by editor features.
+                *
+                * @since 4.4
+                * @readonly
+                */
+               this.disallowedContent = [];
+
+               /**
+                * Array of element callbacks. See {@link #addElementCallback}.
+                *
+                * @readonly
+                * @property {Function[]} [=null]
+                */
+               this.elementCallbacks = null;
+
+               /**
+                * Whether the filter is disabled.
+                *
+                * To disable the filter, set {@link CKEDITOR.config#allowedContent} to `true`
+                * or use the {@link #disable} method.
+                *
+                * @readonly
+                */
+               this.disabled = false;
+
+               /**
+                * Editor instance if not a standalone filter.
+                *
+                * @readonly
+                * @property {CKEDITOR.editor} [=null]
+                */
+               this.editor = null;
+
+               /**
+                * Filter's unique id. It can be used to find filter instance in
+                * {@link CKEDITOR.filter#instances CKEDITOR.filter.instance} object.
+                *
+                * @since 4.3
+                * @readonly
+                * @property {Number} id
+                */
+               this.id = CKEDITOR.tools.getNextNumber();
+
+               this._ = {
+                       // Optimized allowed content rules.
+                       allowedRules: {
+                               elements: {},
+                               generic: []
+                       },
+                       // Optimized disallowed content rules.
+                       disallowedRules: {
+                               elements: {},
+                               generic: []
+                       },
+                       // Object: element name => array of transformations groups.
+                       transformations: {},
+                       cachedTests: {}
+               };
+
+               // Register filter instance.
+               CKEDITOR.filter.instances[ this.id ] = this;
+
+               if ( editorOrRules instanceof CKEDITOR.editor ) {
+                       var editor = this.editor = editorOrRules;
+                       this.customConfig = true;
+
+                       var allowedContent = editor.config.allowedContent;
+
+                       // Disable filter completely by setting config.allowedContent = true.
+                       if ( allowedContent === true ) {
+                               this.disabled = true;
+                               return;
+                       }
+
+                       if ( !allowedContent )
+                               this.customConfig = false;
+
+                       this.allow( allowedContent, 'config', 1 );
+                       this.allow( editor.config.extraAllowedContent, 'extra', 1 );
+
+                       // Enter modes should extend filter rules (ENTER_P adds 'p' rule, etc.).
+                       this.allow( enterModeTags[ editor.enterMode ] + ' ' + enterModeTags[ editor.shiftEnterMode ], 'default', 1 );
+
+                       this.disallow( editor.config.disallowedContent );
+               }
+               // Rules object passed in editorOrRules argument - initialize standalone filter.
+               else {
+                       this.customConfig = false;
+                       this.allow( editorOrRules, 'default', 1 );
+               }
+       };
+
+       /**
+        * Object containing all filter instances stored under their
+        * {@link #id} properties.
+        *
+        *              var filter = new CKEDITOR.filter( 'p' );
+        *              filter === CKEDITOR.filter.instances[ filter.id ];
+        *
+        * @since 4.3
+        * @static
+        * @property instances
+        */
+       CKEDITOR.filter.instances = {};
+
+       CKEDITOR.filter.prototype = {
+               /**
+                * Adds allowed content rules to the filter.
+                *
+                * Read about rules formats in [Allowed Content Rules guide](#!/guide/dev_allowed_content_rules).
+                *
+                *              // Add a basic rule for custom image feature (e.g. 'MyImage' button).
+                *              editor.filter.allow( 'img[!src,alt]', 'MyImage' );
+                *
+                *              // Add rules for two header styles allowed by 'HeadersCombo'.
+                *              var header1Style = new CKEDITOR.style( { element: 'h1' } ),
+                *                      header2Style = new CKEDITOR.style( { element: 'h2' } );
+                *              editor.filter.allow( [ header1Style, header2Style ], 'HeadersCombo' );
+                *
+                * @param {CKEDITOR.filter.allowedContentRules} newRules Rule(s) to be added.
+                * @param {String} [featureName] Name of a feature that allows this content (most often plugin/button/command name).
+                * @param {Boolean} [overrideCustom] By default this method will reject any rules
+                * if {@link CKEDITOR.config#allowedContent} is defined to avoid overriding it.
+                * Pass `true` to force rules addition.
+                * @returns {Boolean} Whether the rules were accepted.
+                */
+               allow: function( newRules, featureName, overrideCustom ) {
+                       // Check arguments and constraints. Clear cache.
+                       if ( !beforeAddingRule( this, newRules, overrideCustom ) )
+                               return false;
+
+                       var i, ret;
+
+                       if ( typeof newRules == 'string' )
+                               newRules = parseRulesString( newRules );
+                       else if ( newRules instanceof CKEDITOR.style ) {
+                               // If style has the cast method defined, use it and abort.
+                               if ( newRules.toAllowedContentRules )
+                                       return this.allow( newRules.toAllowedContentRules( this.editor ), featureName, overrideCustom );
+
+                               newRules = convertStyleToRules( newRules );
+                       } else if ( CKEDITOR.tools.isArray( newRules ) ) {
+                               for ( i = 0; i < newRules.length; ++i )
+                                       ret = this.allow( newRules[ i ], featureName, overrideCustom );
+                               return ret; // Return last status.
+                       }
+
+                       addAndOptimizeRules( this, newRules, featureName, this.allowedContent, this._.allowedRules );
+
+                       return true;
+               },
+
+               /**
+                * Applies this filter to passed {@link CKEDITOR.htmlParser.fragment} or {@link CKEDITOR.htmlParser.element}.
+                * The result of filtering is a DOM tree without disallowed content.
+                *
+                *                      // Create standalone filter passing 'p' and 'b' elements.
+                *              var filter = new CKEDITOR.filter( 'p b' ),
+                *                      // Parse HTML string to pseudo DOM structure.
+                *                      fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p><b>foo</b> <i>bar</i></p>' ),
+                *                      writer = new CKEDITOR.htmlParser.basicWriter();
+                *
+                *              filter.applyTo( fragment );
+                *              fragment.writeHtml( writer );
+                *              writer.getHtml(); // -> '<p><b>foo</b> bar</p>'
+                *
+                * @param {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} fragment Node to be filtered.
+                * @param {Boolean} [toHtml] Set to `true` if the filter is used together with {@link CKEDITOR.htmlDataProcessor#toHtml}.
+                * @param {Boolean} [transformOnly] If set to `true` only transformations will be applied. Content
+                * will not be filtered with allowed content rules.
+                * @param {Number} [enterMode] Enter mode used by the filter when deciding how to strip disallowed element.
+                * Defaults to {@link CKEDITOR.editor#activeEnterMode} for a editor's filter or to {@link CKEDITOR#ENTER_P} for standalone filter.
+                * @returns {Boolean} Whether some part of the `fragment` was removed by the filter.
+                */
+               applyTo: function( fragment, toHtml, transformOnly, enterMode ) {
+                       if ( this.disabled )
+                               return false;
+
+                       var that = this,
+                               toBeRemoved = [],
+                               protectedRegexs = this.editor && this.editor.config.protectedSource,
+                               processRetVal,
+                               isModified = false,
+                               filterOpts = {
+                                       doFilter: !transformOnly,
+                                       doTransform: true,
+                                       doCallbacks: true,
+                                       toHtml: toHtml
+                               };
+
+                       // Filter all children, skip root (fragment or editable-like wrapper used by data processor).
+                       fragment.forEach( function( el ) {
+                               if ( el.type == CKEDITOR.NODE_ELEMENT ) {
+                                       // Do not filter element with data-cke-filter="off" and all their descendants.
+                                       if ( el.attributes[ 'data-cke-filter' ] == 'off' )
+                                               return false;
+
+                                       // (#10260) Don't touch elements like spans with data-cke-* attribute since they're
+                                       // responsible e.g. for placing markers, bookmarks, odds and stuff.
+                                       // We love 'em and we don't wanna lose anything during the filtering.
+                                       // '|' is to avoid tricky joints like data-="foo" + cke-="bar". Yes, they're possible.
+                                       //
+                                       // NOTE: data-cke-* assigned elements are preserved only when filter is used with
+                                       //       htmlDataProcessor.toHtml because we don't want to protect them when outputting data
+                                       //       (toDataFormat).
+                                       if ( toHtml && el.name == 'span' && ~CKEDITOR.tools.objectKeys( el.attributes ).join( '|' ).indexOf( 'data-cke-' ) )
+                                               return;
+
+                                       processRetVal = processElement( that, el, toBeRemoved, filterOpts );
+                                       if ( processRetVal & FILTER_ELEMENT_MODIFIED )
+                                               isModified = true;
+                                       else if ( processRetVal & FILTER_SKIP_TREE )
+                                               return false;
+                               }
+                               else if ( el.type == CKEDITOR.NODE_COMMENT && el.value.match( /^\{cke_protected\}(?!\{C\})/ ) ) {
+                                       if ( !processProtectedElement( that, el, protectedRegexs, filterOpts ) )
+                                               toBeRemoved.push( el );
+                               }
+                       }, null, true );
+
+                       if ( toBeRemoved.length )
+                               isModified = true;
+
+                       var node, element, check,
+                               toBeChecked = [],
+                               enterTag = enterModeTags[ enterMode || ( this.editor ? this.editor.enterMode : CKEDITOR.ENTER_P ) ],
+                               parentDtd;
+
+                       // Remove elements in reverse order - from leaves to root, to avoid conflicts.
+                       while ( ( node = toBeRemoved.pop() ) ) {
+                               if ( node.type == CKEDITOR.NODE_ELEMENT )
+                                       removeElement( node, enterTag, toBeChecked );
+                               // This is a comment securing rejected element - remove it completely.
+                               else
+                                       node.remove();
+                       }
+
+                       // Check elements that have been marked as possibly invalid.
+                       while ( ( check = toBeChecked.pop() ) ) {
+                               element = check.el;
+                               // Element has been already removed.
+                               if ( !element.parent )
+                                       continue;
+
+                               // Handle custom elements as inline elements (#12683).
+                               parentDtd = DTD[ element.parent.name ] || DTD.span;
+
+                               switch ( check.check ) {
+                                       // Check if element itself is correct.
+                                       case 'it':
+                                               // Check if element included in $removeEmpty has no children.
+                                               if ( DTD.$removeEmpty[ element.name ] && !element.children.length )
+                                                       removeElement( element, enterTag, toBeChecked );
+                                               // Check if that is invalid element.
+                                               else if ( !validateElement( element ) )
+                                                       removeElement( element, enterTag, toBeChecked );
+                                               break;
+
+                                       // Check if element is in correct context. If not - remove element.
+                                       case 'el-up':
+                                               // Check if e.g. li is a child of body after ul has been removed.
+                                               if ( element.parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT && !parentDtd[ element.name ] )
+                                                       removeElement( element, enterTag, toBeChecked );
+                                               break;
+
+                                       // Check if element is in correct context. If not - remove parent.
+                                       case 'parent-down':
+                                               if ( element.parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT && !parentDtd[ element.name ] )
+                                                       removeElement( element.parent, enterTag, toBeChecked );
+                                               break;
+                               }
+                       }
+
+                       return isModified;
+               },
+
+               /**
+                * Checks whether a {@link CKEDITOR.feature} can be enabled. Unlike {@link #addFeature},
+                * this method always checks the feature, even when the default configuration
+                * for {@link CKEDITOR.config#allowedContent} is used.
+                *
+                *              // TODO example
+                *
+                * @param {CKEDITOR.feature} feature The feature to be tested.
+                * @returns {Boolean} Whether this feature can be enabled.
+                */
+               checkFeature: function( feature ) {
+                       if ( this.disabled )
+                               return true;
+
+                       if ( !feature )
+                               return true;
+
+                       // Some features may want to register other features.
+                       // E.g. a button may return a command bound to it.
+                       if ( feature.toFeature )
+                               feature = feature.toFeature( this.editor );
+
+                       return !feature.requiredContent || this.check( feature.requiredContent );
+               },
+
+               /**
+                * Disables Advanced Content Filter.
+                *
+                * This method is meant to be used by plugins which are not
+                * compatible with the filter and in other cases in which the filter
+                * has to be disabled during the initialization phase or runtime.
+                *
+                * In other cases the filter can be disabled by setting
+                * {@link CKEDITOR.config#allowedContent} to `true`.
+                */
+               disable: function() {
+                       this.disabled = true;
+               },
+
+               /**
+                * Adds disallowed content rules to the filter.
+                *
+                * Read about rules formats in the [Allowed Content Rules guide](#!/guide/dev_allowed_content_rules).
+                *
+                *              // Disallow all styles on the image elements.
+                *              editor.filter.disallow( 'img{*}' );
+                *
+                *              // Disallow all span and div elements.
+                *              editor.filter.disallow( 'span div' );
+                *
+                * @since 4.4
+                * @param {CKEDITOR.filter.disallowedContentRules} newRules Rule(s) to be added.
+                */
+               disallow: function( newRules ) {
+                       // Check arguments and constraints. Clear cache.
+                       // Note: we pass true in the 3rd argument, because disallow() should never
+                       // be blocked by custom configuration.
+                       if ( !beforeAddingRule( this, newRules, true ) )
+                               return false;
+
+                       if ( typeof newRules == 'string' )
+                               newRules = parseRulesString( newRules );
+
+                       addAndOptimizeRules( this, newRules, null, this.disallowedContent, this._.disallowedRules );
+
+                       return true;
+               },
+
+               /**
+                * Adds an array of {@link CKEDITOR.feature} content forms. All forms
+                * will then be transformed to the first form which is allowed by the filter.
+                *
+                *              editor.filter.allow( 'i; span{!font-style}' );
+                *              editor.filter.addContentForms( [
+                *                      'em',
+                *                      'i',
+                *                      [ 'span', function( el ) {
+                *                              return el.styles[ 'font-style' ] == 'italic';
+                *                      } ]
+                *              ] );
+                *              // Now <em> and <span style="font-style:italic"> will be replaced with <i>
+                *              // because this is the first allowed form.
+                *              // <span> is allowed too, but it is the last form and
+                *              // additionaly, the editor cannot transform an element based on
+                *              // the array+function form).
+                *
+                * This method is used by the editor to register {@link CKEDITOR.feature#contentForms}
+                * when adding a feature with {@link #addFeature} or {@link CKEDITOR.editor#addFeature}.
+                *
+                * @param {Array} forms The content forms of a feature.
+                */
+               addContentForms: function( forms ) {
+                       if ( this.disabled )
+                               return;
+
+                       if ( !forms )
+                               return;
+
+                       var i, form,
+                               transfGroups = [],
+                               preferredForm;
+
+                       // First, find preferred form - this is, first allowed.
+                       for ( i = 0; i < forms.length && !preferredForm; ++i ) {
+                               form = forms[ i ];
+
+                               // Check only strings and styles - array format isn't supported by #check().
+                               if ( ( typeof form == 'string' || form instanceof CKEDITOR.style ) && this.check( form ) )
+                                       preferredForm = form;
+                       }
+
+                       // This feature doesn't have preferredForm, so ignore it.
+                       if ( !preferredForm )
+                               return;
+
+                       for ( i = 0; i < forms.length; ++i )
+                               transfGroups.push( getContentFormTransformationGroup( forms[ i ], preferredForm ) );
+
+                       this.addTransformations( transfGroups );
+               },
+
+               /**
+                * Adds a callback which will be executed on every element
+                * that the filter reaches when filtering, before the element is filtered.
+                *
+                * By returning {@link CKEDITOR#FILTER_SKIP_TREE} it is possible to
+                * skip filtering of the current element and all its ancestors.
+                *
+                *              editor.filter.addElementCallback( function( el ) {
+                *                      if ( el.hasClass( 'protected' ) )
+                *                              return CKEDITOR.FILTER_SKIP_TREE;
+                *              } );
+                *
+                * **Note:** At this stage the element passed to the callback does not
+                * contain `attributes`, `classes`, and `styles` properties which are available
+                * temporarily on later stages of the filtering process. Therefore you need to
+                *  use the pure {@link CKEDITOR.htmlParser.element} interface.
+                *
+                * @since 4.4
+                * @param {Function} callback The callback to be executed.
+                */
+               addElementCallback: function( callback ) {
+                       // We want to keep it a falsy value, to speed up finding whether there are any callbacks.
+                       if ( !this.elementCallbacks )
+                               this.elementCallbacks = [];
+
+                       this.elementCallbacks.push( callback );
+               },
+
+               /**
+                * Checks whether a feature can be enabled for the HTML restrictions in place
+                * for the current CKEditor instance, based on the HTML code the feature might
+                * generate and the minimal HTML code the feature needs to be able to generate.
+                *
+                *              // TODO example
+                *
+                * @param {CKEDITOR.feature} feature
+                * @returns {Boolean} Whether this feature can be enabled.
+                */
+               addFeature: function( feature ) {
+                       if ( this.disabled )
+                               return true;
+
+                       if ( !feature )
+                               return true;
+
+                       // Some features may want to register other features.
+                       // E.g. a button may return a command bound to it.
+                       if ( feature.toFeature )
+                               feature = feature.toFeature( this.editor );
+
+                       // If default configuration (will be checked inside #allow()),
+                       // then add allowed content rules.
+                       this.allow( feature.allowedContent, feature.name );
+
+                       this.addTransformations( feature.contentTransformations );
+                       this.addContentForms( feature.contentForms );
+
+                       // If custom configuration or any DACRs, then check if required content is allowed.
+                       if ( feature.requiredContent && ( this.customConfig || this.disallowedContent.length ) )
+                               return this.check( feature.requiredContent );
+
+                       return true;
+               },
+
+               /**
+                * Adds an array of content transformation groups. One group
+                * may contain many transformation rules, but only the first
+                * matching rule in a group is executed.
+                *
+                * A single transformation rule is an object with four properties:
+                *
+                *      * `check` (optional) &ndash; if set and {@link CKEDITOR.filter} does
+                *              not accept this {@link CKEDITOR.filter.contentRule}, this transformation rule
+                *              will not be executed (it does not *match*). This value is passed
+                *              to {@link #check}.
+                *      * `element` (optional) &ndash; this string property tells the filter on which
+                *              element this transformation can be run. It is optional, because
+                *              the element name can be obtained from `check` (if it is a String format)
+                *              or `left` (if it is a {@link CKEDITOR.style} instance).
+                *      * `left` (optional) &ndash; a function accepting an element or a {@link CKEDITOR.style}
+                *              instance verifying whether the transformation should be
+                *              executed on this specific element. If it returns `false` or if an element
+                *              does not match this style, this transformation rule does not *match*.
+                *      * `right` &ndash; a function accepting an element and {@link CKEDITOR.filter.transformationsTools}
+                *              or a string containing the name of the {@link CKEDITOR.filter.transformationsTools} method
+                *              that should be called on an element.
+                *
+                * A shorthand format is also available. A transformation rule can be defined by
+                * a single string `'check:right'`. The string before `':'` will be used as
+                * the `check` property and the second part as the `right` property.
+                *
+                * Transformation rules can be grouped. The filter will try to apply
+                * the first rule in a group. If it *matches*, the filter will ignore subsequent rules and
+                * will move to the next group. If it does not *match*, the next rule will be checked.
+                *
+                * Examples:
+                *
+                *              editor.filter.addTransformations( [
+                *                      // First group.
+                *                      [
+                *                              // First rule. If table{width} is allowed, it
+                *                              // executes {@link CKEDITOR.filter.transformationsTools#sizeToStyle} on a table element.
+                *                              'table{width}: sizeToStyle',
+                *                              // Second rule should not be executed if the first was.
+                *                              'table[width]: sizeToAttribute'
+                *                      ],
+                *                      // Second group.
+                *                      [
+                *                              // This rule will add the foo="1" attribute to all images that
+                *                              // do not have it.
+                *                              {
+                *                                      element: 'img',
+                *                                      left: function( el ) {
+                *                                              return !el.attributes.foo;
+                *                                      },
+                *                                      right: function( el, tools ) {
+                *                                              el.attributes.foo = '1';
+                *                                      }
+                *                              }
+                *                      ]
+                *              ] );
+                *
+                *              // Case 1:
+                *              // config.allowedContent = 'table{height,width}; tr td'.
+                *              //
+                *              // '<table style="height:100px; width:200px">...</table>'               -> '<table style="height:100px; width:200px">...</table>'
+                *              // '<table height="100" width="200">...</table>'                                -> '<table style="height:100px; width:200px">...</table>'
+                *
+                *              // Case 2:
+                *              // config.allowedContent = 'table[height,width]; tr td'.
+                *              //
+                *              // '<table style="height:100px; width:200px">...</table>'               -> '<table height="100" width="200">...</table>'
+                *              // '<table height="100" width="200">...</table>'                                -> '<table height="100" width="200"">...</table>'
+                *
+                *              // Case 3:
+                *              // config.allowedContent = 'table{width,height}[height,width]; tr td'.
+                *              //
+                *              // '<table style="height:100px; width:200px">...</table>'               -> '<table style="height:100px; width:200px">...</table>'
+                *              // '<table height="100" width="200">...</table>'                                -> '<table style="height:100px; width:200px">...</table>'
+                *              //
+                *              // Note: Both forms are allowed (size set by style and by attributes), but only
+                *              // the first transformation is applied &mdash; the size is always transformed to a style.
+                *              // This is because only the first transformation matching allowed content rules is applied.
+                *
+                * This method is used by the editor to add {@link CKEDITOR.feature#contentTransformations}
+                * when adding a feature by {@link #addFeature} or {@link CKEDITOR.editor#addFeature}.
+                *
+                * @param {Array} transformations
+                */
+               addTransformations: function( transformations ) {
+                       if ( this.disabled )
+                               return;
+
+                       if ( !transformations )
+                               return;
+
+                       var optimized = this._.transformations,
+                               group, i;
+
+                       for ( i = 0; i < transformations.length; ++i ) {
+                               group = optimizeTransformationsGroup( transformations[ i ] );
+
+                               if ( !optimized[ group.name ] )
+                                       optimized[ group.name ] = [];
+
+                               optimized[ group.name ].push( group.rules );
+                       }
+               },
+
+               /**
+                * Checks whether the content defined in the `test` argument is allowed
+                * by this filter.
+                *
+                * If `strictCheck` is set to `false` (default value), this method checks
+                * if all parts of the `test` (styles, attributes, and classes) are
+                * accepted by the filter. If `strictCheck` is set to `true`, the test
+                * must also contain the required attributes, styles, and classes.
+                *
+                * For example:
+                *
+                *              // Rule: 'img[!src,alt]'.
+                *              filter.check( 'img[alt]' ); // -> true
+                *              filter.check( 'img[alt]', true, true ); // -> false
+                *
+                * Second `check()` call returned `false` because `src` is required.
+                *
+                * **Note:** The `test` argument is of {@link CKEDITOR.filter.contentRule} type, which is
+                * a limited version of {@link CKEDITOR.filter.allowedContentRules}. Read more about it
+                * in the {@link CKEDITOR.filter.contentRule}'s documentation.
+                *
+                * @param {CKEDITOR.filter.contentRule} test
+                * @param {Boolean} [applyTransformations=true] Whether to use registered transformations.
+                * @param {Boolean} [strictCheck] Whether the filter should check if an element with exactly
+                * these properties is allowed.
+                * @returns {Boolean} Returns `true` if the content is allowed.
+                */
+               check: function( test, applyTransformations, strictCheck ) {
+                       if ( this.disabled )
+                               return true;
+
+                       // If rules are an array, expand it and return the logical OR value of
+                       // the rules.
+                       if ( CKEDITOR.tools.isArray( test ) ) {
+                               for ( var i = test.length ; i-- ; ) {
+                                       if ( this.check( test[ i ], applyTransformations, strictCheck ) )
+                                               return true;
+                               }
+                               return false;
+                       }
+
+                       var element, result, cacheKey;
+
+                       if ( typeof test == 'string' ) {
+                               cacheKey = test + '<' + ( applyTransformations === false ? '0' : '1' ) + ( strictCheck ? '1' : '0' ) + '>';
+
+                               // Check if result of this check hasn't been already cached.
+                               if ( cacheKey in this._.cachedChecks )
+                                       return this._.cachedChecks[ cacheKey ];
+
+                               // Create test element from string.
+                               element = mockElementFromString( test );
+                       } else {
+                               // Create test element from CKEDITOR.style.
+                               element = mockElementFromStyle( test );
+                       }
+
+                       // Make a deep copy.
+                       var clone = CKEDITOR.tools.clone( element ),
+                               toBeRemoved = [],
+                               transformations;
+
+                       // Apply transformations to original element.
+                       // Transformations will be applied to clone by the filter function.
+                       if ( applyTransformations !== false && ( transformations = this._.transformations[ element.name ] ) ) {
+                               for ( i = 0; i < transformations.length; ++i )
+                                       applyTransformationsGroup( this, element, transformations[ i ] );
+
+                               // Transformations could modify styles or classes, so they need to be copied
+                               // to attributes object.
+                               updateAttributes( element );
+                       }
+
+                       // Filter clone of mocked element.
+                       processElement( this, clone, toBeRemoved, {
+                               doFilter: true,
+                               doTransform: applyTransformations !== false,
+                               skipRequired: !strictCheck,
+                               skipFinalValidation: !strictCheck
+                       } );
+
+                       // Element has been marked for removal.
+                       if ( toBeRemoved.length > 0 ) {
+                               result = false;
+                       // Compare only left to right, because clone may be only trimmed version of original element.
+                       } else if ( !CKEDITOR.tools.objectCompare( element.attributes, clone.attributes, true ) ) {
+                               result = false;
+                       } else {
+                               result = true;
+                       }
+
+                       // Cache result of this test - we can build cache only for string tests.
+                       if ( typeof test == 'string' )
+                               this._.cachedChecks[ cacheKey ] = result;
+
+                       return result;
+               },
+
+               /**
+                * Returns first enter mode allowed by this filter rules. Modes are checked in `p`, `div`, `br` order.
+                * If none of tags is allowed this method will return {@link CKEDITOR#ENTER_BR}.
+                *
+                * @since 4.3
+                * @param {Number} defaultMode The default mode which will be checked as the first one.
+                * @param {Boolean} [reverse] Whether to check modes in reverse order (used for shift enter mode).
+                * @returns {Number} Allowed enter mode.
+                */
+               getAllowedEnterMode: ( function() {
+                       var tagsToCheck = [ 'p', 'div', 'br' ],
+                               enterModes = {
+                                       p: CKEDITOR.ENTER_P,
+                                       div: CKEDITOR.ENTER_DIV,
+                                       br: CKEDITOR.ENTER_BR
+                               };
+
+                       return function( defaultMode, reverse ) {
+                               // Clone the array first.
+                               var tags = tagsToCheck.slice(),
+                                       tag;
+
+                               // Check the default mode first.
+                               if ( this.check( enterModeTags[ defaultMode ] ) )
+                                       return defaultMode;
+
+                               // If not reverse order, reverse array so we can pop() from it.
+                               if ( !reverse )
+                                       tags = tags.reverse();
+
+                               while ( ( tag = tags.pop() ) ) {
+                                       if ( this.check( tag ) )
+                                               return enterModes[ tag ];
+                               }
+
+                               return CKEDITOR.ENTER_BR;
+                       };
+               } )(),
+
+               /**
+                * Destroys the filter instance and removes it from the global {@link CKEDITOR.filter#instances} object.
+                *
+                * @since 4.4.5
+                */
+               destroy: function() {
+                       delete CKEDITOR.filter.instances[ this.id ];
+                       // Deleting reference to filter instance should be enough,
+                       // but since these are big objects it's safe to clean them up too.
+                       delete this._;
+                       delete this.allowedContent;
+                       delete this.disallowedContent;
+               }
+       };
+
+       function addAndOptimizeRules( that, newRules, featureName, standardizedRules, optimizedRules ) {
+               var groupName, rule,
+                       rulesToOptimize = [];
+
+               for ( groupName in newRules ) {
+                       rule = newRules[ groupName ];
+
+                       // { 'p h1': true } => { 'p h1': {} }.
+                       if ( typeof rule == 'boolean' )
+                               rule = {};
+                       // { 'p h1': func } => { 'p h1': { match: func } }.
+                       else if ( typeof rule == 'function' )
+                               rule = { match: rule };
+                       // Clone (shallow) rule, because we'll modify it later.
+                       else
+                               rule = copy( rule );
+
+                       // If this is not an unnamed rule ({ '$1' => { ... } })
+                       // move elements list to property.
+                       if ( groupName.charAt( 0 ) != '$' )
+                               rule.elements = groupName;
+
+                       if ( featureName )
+                               rule.featureName = featureName.toLowerCase();
+
+                       standardizeRule( rule );
+
+                       // Save rule and remember to optimize it.
+                       standardizedRules.push( rule );
+                       rulesToOptimize.push( rule );
+               }
+
+               optimizeRules( optimizedRules, rulesToOptimize );
+       }
+
+       // Apply ACR to an element.
+       // @param rule
+       // @param element
+       // @param status Object containing status of element's filtering.
+       // @param {Boolean} skipRequired If true don't check if element has all required properties.
+       function applyAllowedRule( rule, element, status, skipRequired ) {
+               // This rule doesn't match this element - skip it.
+               if ( rule.match && !rule.match( element ) )
+                       return;
+
+               // If element doesn't have all required styles/attrs/classes
+               // this rule doesn't match it.
+               if ( !skipRequired && !hasAllRequired( rule, element ) )
+                       return;
+
+               // If this rule doesn't validate properties only mark element as valid.
+               if ( !rule.propertiesOnly )
+                       status.valid = true;
+
+               // Apply rule only when all attrs/styles/classes haven't been marked as valid.
+               if ( !status.allAttributes )
+                       status.allAttributes = applyAllowedRuleToHash( rule.attributes, element.attributes, status.validAttributes );
+
+               if ( !status.allStyles )
+                       status.allStyles = applyAllowedRuleToHash( rule.styles, element.styles, status.validStyles );
+
+               if ( !status.allClasses )
+                       status.allClasses = applyAllowedRuleToArray( rule.classes, element.classes, status.validClasses );
+       }
+
+       // Apply itemsRule to items (only classes are kept in array).
+       // Push accepted items to validItems array.
+       // Return true when all items are valid.
+       function applyAllowedRuleToArray( itemsRule, items, validItems ) {
+               if ( !itemsRule )
+                       return false;
+
+               // True means that all elements of array are accepted (the asterix was used for classes).
+               if ( itemsRule === true )
+                       return true;
+
+               for ( var i = 0, l = items.length, item; i < l; ++i ) {
+                       item = items[ i ];
+                       if ( !validItems[ item ] )
+                               validItems[ item ] = itemsRule( item );
+               }
+
+               return false;
+       }
+
+       function applyAllowedRuleToHash( itemsRule, items, validItems ) {
+               if ( !itemsRule )
+                       return false;
+
+               if ( itemsRule === true )
+                       return true;
+
+               for ( var name in items ) {
+                       if ( !validItems[ name ] )
+                               validItems[ name ] = itemsRule( name );
+               }
+
+               return false;
+       }
+
+       // Apply DACR rule to an element.
+       function applyDisallowedRule( rule, element, status ) {
+               // This rule doesn't match this element - skip it.
+               if ( rule.match && !rule.match( element ) )
+                       return;
+
+               // No properties - it's an element only rule so it disallows entire element.
+               // Early return is handled in filterElement.
+               if ( rule.noProperties )
+                       return false;
+
+               // Apply rule to attributes, styles and classes. Switch hadInvalid* to true if method returned true.
+               status.hadInvalidAttribute = applyDisallowedRuleToHash( rule.attributes, element.attributes ) || status.hadInvalidAttribute;
+               status.hadInvalidStyle = applyDisallowedRuleToHash( rule.styles, element.styles ) || status.hadInvalidStyle;
+               status.hadInvalidClass = applyDisallowedRuleToArray( rule.classes, element.classes ) || status.hadInvalidClass;
+       }
+
+       // Apply DACR to items (only classes are kept in array).
+       // @returns {Boolean} True if at least one of items was invalid (disallowed).
+       function applyDisallowedRuleToArray( itemsRule, items ) {
+               if ( !itemsRule )
+                       return false;
+
+               var hadInvalid = false,
+                       allDisallowed = itemsRule === true;
+
+               for ( var i = items.length; i--; ) {
+                       if ( allDisallowed || itemsRule( items[ i ] ) ) {
+                               items.splice( i, 1 );
+                               hadInvalid = true;
+                       }
+               }
+
+               return hadInvalid;
+       }
+
+       // Apply DACR to items (styles and attributes).
+       // @returns {Boolean} True if at least one of items was invalid (disallowed).
+       function applyDisallowedRuleToHash( itemsRule, items ) {
+               if ( !itemsRule )
+                       return false;
+
+               var hadInvalid = false,
+                       allDisallowed = itemsRule === true;
+
+               for ( var name in items ) {
+                       if ( allDisallowed || itemsRule( name ) ) {
+                               delete items[ name ];
+                               hadInvalid = true;
+                       }
+               }
+
+               return hadInvalid;
+       }
+
+       function beforeAddingRule( that, newRules, overrideCustom ) {
+               if ( that.disabled )
+                       return false;
+
+               // Don't override custom user's configuration if not explicitly requested.
+               if ( that.customConfig && !overrideCustom )
+                       return false;
+
+               if ( !newRules )
+                       return false;
+
+               // Clear cache, because new rules could change results of checks.
+               that._.cachedChecks = {};
+
+               return true;
+       }
+
+       // Convert CKEDITOR.style to filter's rule.
+       function convertStyleToRules( style ) {
+               var styleDef = style.getDefinition(),
+                       rules = {},
+                       rule,
+                       attrs = styleDef.attributes;
+
+               rules[ styleDef.element ] = rule = {
+                       styles: styleDef.styles,
+                       requiredStyles: styleDef.styles && CKEDITOR.tools.objectKeys( styleDef.styles )
+               };
+
+               if ( attrs ) {
+                       attrs = copy( attrs );
+                       rule.classes = attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : null;
+                       rule.requiredClasses = rule.classes;
+                       delete attrs[ 'class' ];
+                       rule.attributes = attrs;
+                       rule.requiredAttributes = attrs && CKEDITOR.tools.objectKeys( attrs );
+               }
+
+               return rules;
+       }
+
+       // Convert all validator formats (string, array, object, boolean) to hash or boolean:
+       // * true is returned for '*'/true validator,
+       // * false is returned for empty validator (no validator at all (false/null) or e.g. empty array),
+       // * object is returned in other cases.
+       function convertValidatorToHash( validator, delimiter ) {
+               if ( !validator )
+                       return false;
+
+               if ( validator === true )
+                       return validator;
+
+               if ( typeof validator == 'string' ) {
+                       validator = trim( validator );
+                       if ( validator == '*' )
+                               return true;
+                       else
+                               return CKEDITOR.tools.convertArrayToObject( validator.split( delimiter ) );
+               }
+               else if ( CKEDITOR.tools.isArray( validator ) ) {
+                       if ( validator.length )
+                               return CKEDITOR.tools.convertArrayToObject( validator );
+                       else
+                               return false;
+               }
+               // If object.
+               else {
+                       var obj = {},
+                               len = 0;
+
+                       for ( var i in validator ) {
+                               obj[ i ] = validator[ i ];
+                               len++;
+                       }
+
+                       return len ? obj : false;
+               }
+       }
+
+       function executeElementCallbacks( element, callbacks ) {
+               for ( var i = 0, l = callbacks.length, retVal; i < l; ++i ) {
+                       if ( ( retVal = callbacks[ i ]( element ) ) )
+                               return retVal;
+               }
+       }
+
+       // Extract required properties from "required" validator and "all" properties.
+       // Remove exclamation marks from "all" properties.
+       //
+       // E.g.:
+       // requiredClasses = { cl1: true }
+       // (all) classes = { cl1: true, cl2: true, '!cl3': true }
+       //
+       // result:
+       // returned = { cl1: true, cl3: true }
+       // all = { cl1: true, cl2: true, cl3: true }
+       //
+       // This function returns false if nothing is required.
+       function extractRequired( required, all ) {
+               var unbang = [],
+                       empty = true,
+                       i;
+
+               if ( required )
+                       empty = false;
+               else
+                       required = {};
+
+               for ( i in all ) {
+                       if ( i.charAt( 0 ) == '!' ) {
+                               i = i.slice( 1 );
+                               unbang.push( i );
+                               required[ i ] = true;
+                               empty = false;
+                       }
+               }
+
+               while ( ( i = unbang.pop() ) ) {
+                       all[ i ] = all[ '!' + i ];
+                       delete all[ '!' + i ];
+               }
+
+               return empty ? false : required;
+       }
+
+       // Does the actual filtering by appling allowed content rules
+       // to the element.
+       //
+       // @param {CKEDITOR.filter} that The context.
+       // @param {CKEDITOR.htmlParser.element} element
+       // @param {Object} opts The same as in processElement.
+       function filterElement( that, element, opts ) {
+               var name = element.name,
+                       privObj = that._,
+                       allowedRules = privObj.allowedRules.elements[ name ],
+                       genericAllowedRules = privObj.allowedRules.generic,
+                       disallowedRules = privObj.disallowedRules.elements[ name ],
+                       genericDisallowedRules = privObj.disallowedRules.generic,
+                       skipRequired = opts.skipRequired,
+                       status = {
+                               // Whether any of rules accepted element.
+                               // If not - it will be stripped.
+                               valid: false,
+                               // Objects containing accepted attributes, classes and styles.
+                               validAttributes: {},
+                               validClasses: {},
+                               validStyles: {},
+                               // Whether all are valid.
+                               // If we know that all element's attrs/classes/styles are valid
+                               // we can skip their validation, to improve performance.
+                               allAttributes: false,
+                               allClasses: false,
+                               allStyles: false,
+                               // Whether element had (before applying DACRs) at least one invalid attribute/class/style.
+                               hadInvalidAttribute: false,
+                               hadInvalidClass: false,
+                               hadInvalidStyle: false
+                       },
+                       i, l;
+
+               // Early return - if there are no rules for this element (specific or generic), remove it.
+               if ( !allowedRules && !genericAllowedRules )
+                       return null;
+
+               // Could not be done yet if there were no transformations and if this
+               // is real (not mocked) object.
+               populateProperties( element );
+
+               // Note - this step modifies element's styles, classes and attributes.
+               if ( disallowedRules ) {
+                       for ( i = 0, l = disallowedRules.length; i < l; ++i ) {
+                               // Apply rule and make an early return if false is returned what means
+                               // that element is completely disallowed.
+                               if ( applyDisallowedRule( disallowedRules[ i ], element, status ) === false )
+                                       return null;
+                       }
+               }
+
+               // Note - this step modifies element's styles, classes and attributes.
+               if ( genericDisallowedRules ) {
+                       for ( i = 0, l = genericDisallowedRules.length; i < l; ++i )
+                               applyDisallowedRule( genericDisallowedRules[ i ], element, status );
+               }
+
+               if ( allowedRules ) {
+                       for ( i = 0, l = allowedRules.length; i < l; ++i )
+                               applyAllowedRule( allowedRules[ i ], element, status, skipRequired );
+               }
+
+               if ( genericAllowedRules ) {
+                       for ( i = 0, l = genericAllowedRules.length; i < l; ++i )
+                               applyAllowedRule( genericAllowedRules[ i ], element, status, skipRequired );
+               }
+
+               return status;
+       }
+
+       // Check whether element has all properties (styles,classes,attrs) required by a rule.
+       function hasAllRequired( rule, element ) {
+               if ( rule.nothingRequired )
+                       return true;
+
+               var i, req, reqs, existing;
+
+               if ( ( reqs = rule.requiredClasses ) ) {
+                       existing = element.classes;
+                       for ( i = 0; i < reqs.length; ++i ) {
+                               req = reqs[ i ];
+                               if ( typeof req == 'string' ) {
+                                       if ( CKEDITOR.tools.indexOf( existing, req ) == -1 )
+                                               return false;
+                               }
+                               // This means regexp.
+                               else {
+                                       if ( !CKEDITOR.tools.checkIfAnyArrayItemMatches( existing, req ) )
+                                               return false;
+                               }
+                       }
+               }
+
+               return hasAllRequiredInHash( element.styles, rule.requiredStyles ) &&
+                       hasAllRequiredInHash( element.attributes, rule.requiredAttributes );
+       }
+
+       // Check whether all items in required (array) exist in existing (object).
+       function hasAllRequiredInHash( existing, required ) {
+               if ( !required )
+                       return true;
+
+               for ( var i = 0, req; i < required.length; ++i ) {
+                       req = required[ i ];
+                       if ( typeof req == 'string' ) {
+                               if ( !( req in existing ) )
+                                       return false;
+                       }
+                       // This means regexp.
+                       else {
+                               if ( !CKEDITOR.tools.checkIfAnyObjectPropertyMatches( existing, req ) )
+                                       return false;
+                       }
+               }
+
+               return true;
+       }
+
+       // Create pseudo element that will be passed through filter
+       // to check if tested string is allowed.
+       function mockElementFromString( str ) {
+               var element = parseRulesString( str ).$1,
+                       styles = element.styles,
+                       classes = element.classes;
+
+               element.name = element.elements;
+               element.classes = classes = ( classes ? classes.split( /\s*,\s*/ ) : [] );
+               element.styles = mockHash( styles );
+               element.attributes = mockHash( element.attributes );
+               element.children = [];
+
+               if ( classes.length )
+                       element.attributes[ 'class' ] = classes.join( ' ' );
+               if ( styles )
+                       element.attributes.style = CKEDITOR.tools.writeCssText( element.styles );
+
+               return element;
+       }
+
+       // Create pseudo element that will be passed through filter
+       // to check if tested style is allowed.
+       function mockElementFromStyle( style ) {
+               var styleDef = style.getDefinition(),
+                       styles = styleDef.styles,
+                       attrs = styleDef.attributes || {};
+
+               if ( styles && !CKEDITOR.tools.isEmpty( styles ) ) {
+                       styles = copy( styles );
+                       attrs.style = CKEDITOR.tools.writeCssText( styles, true );
+               } else {
+                       styles = {};
+               }
+
+               return {
+                       name: styleDef.element,
+                       attributes: attrs,
+                       classes: attrs[ 'class' ] ? attrs[ 'class' ].split( /\s+/ ) : [],
+                       styles: styles,
+                       children: []
+               };
+       }
+
+       // Mock hash based on string.
+       // 'a,b,c' => { a: 'cke-test', b: 'cke-test', c: 'cke-test' }
+       // Used to mock styles and attributes objects.
+       function mockHash( str ) {
+               // It may be a null or empty string.
+               if ( !str )
+                       return {};
+
+               var keys = str.split( /\s*,\s*/ ).sort(),
+                       obj = {};
+
+               while ( keys.length )
+                       obj[ keys.shift() ] = TEST_VALUE;
+
+               return obj;
+       }
+
+       // Extract properties names from the object
+       // and replace those containing wildcards with regexps.
+       // Note: there's a room for performance improvement. Array of mixed types
+       // breaks JIT-compiler optiomization what may invalidate compilation of pretty a lot of code.
+       //
+       // @returns An array of strings and regexps.
+       function optimizeRequiredProperties( requiredProperties ) {
+               var arr = [];
+               for ( var propertyName in requiredProperties ) {
+                       if ( propertyName.indexOf( '*' ) > -1 )
+                               arr.push( new RegExp( '^' + propertyName.replace( /\*/g, '.*' ) + '$' ) );
+                       else
+                               arr.push( propertyName );
+               }
+               return arr;
+       }
+
+       var validators = { styles: 1, attributes: 1, classes: 1 },
+               validatorsRequired = {
+                       styles: 'requiredStyles',
+                       attributes: 'requiredAttributes',
+                       classes: 'requiredClasses'
+               };
+
+       // Optimize a rule by replacing validators with functions
+       // and rewriting requiredXXX validators to arrays.
+       function optimizeRule( rule ) {
+               var validatorName,
+                       requiredProperties,
+                       i;
+
+               for ( validatorName in validators )
+                       rule[ validatorName ] = validatorFunction( rule[ validatorName ] );
+
+               var nothingRequired = true;
+               for ( i in validatorsRequired ) {
+                       validatorName = validatorsRequired[ i ];
+                       requiredProperties = optimizeRequiredProperties( rule[ validatorName ] );
+                       // Don't set anything if there are no required properties. This will allow to
+                       // save some memory by GCing all empty arrays (requiredProperties).
+                       if ( requiredProperties.length ) {
+                               rule[ validatorName ] = requiredProperties;
+                               nothingRequired = false;
+                       }
+               }
+
+               rule.nothingRequired = nothingRequired;
+               rule.noProperties = !( rule.attributes || rule.classes || rule.styles );
+       }
+
+       // Add optimized version of rule to optimizedRules object.
+       function optimizeRules( optimizedRules, rules ) {
+               var elementsRules = optimizedRules.elements,
+                       genericRules = optimizedRules.generic,
+                       i, l, rule, element, priority;
+
+               for ( i = 0, l = rules.length; i < l; ++i ) {
+                       // Shallow copy. Do not modify original rule.
+                       rule = copy( rules[ i ] );
+                       priority = rule.classes === true || rule.styles === true || rule.attributes === true;
+                       optimizeRule( rule );
+
+                       // E.g. "*(xxx)[xxx]" - it's a generic rule that
+                       // validates properties only.
+                       // Or '$1': { match: function() {...} }
+                       if ( rule.elements === true || rule.elements === null ) {
+                               // Add priority rules at the beginning.
+                               genericRules[ priority ? 'unshift' : 'push' ]( rule );
+                       }
+                       // If elements list was explicitly defined,
+                       // add this rule for every defined element.
+                       else {
+                               // We don't need elements validator for this kind of rule.
+                               var elements = rule.elements;
+                               delete rule.elements;
+
+                               for ( element in elements ) {
+                                       if ( !elementsRules[ element ] )
+                                               elementsRules[ element ] = [ rule ];
+                                       else
+                                               elementsRules[ element ][ priority ? 'unshift' : 'push' ]( rule );
+                               }
+                       }
+               }
+       }
+
+       //                  <   elements   ><                       styles, attributes and classes                        >< separator >
+       var rulePattern = /^([a-z0-9\-*\s]+)((?:\s*\{[!\w\-,\s\*]+\}\s*|\s*\[[!\w\-,\s\*]+\]\s*|\s*\([!\w\-,\s\*]+\)\s*){0,3})(?:;\s*|$)/i,
+               groupsPatterns = {
+                       styles: /{([^}]+)}/,
+                       attrs: /\[([^\]]+)\]/,
+                       classes: /\(([^\)]+)\)/
+               };
+
+       function parseRulesString( input ) {
+               var match,
+                       props, styles, attrs, classes,
+                       rules = {},
+                       groupNum = 1;
+
+               input = trim( input );
+
+               while ( ( match = input.match( rulePattern ) ) ) {
+                       if ( ( props = match[ 2 ] ) ) {
+                               styles = parseProperties( props, 'styles' );
+                               attrs = parseProperties( props, 'attrs' );
+                               classes = parseProperties( props, 'classes' );
+                       } else {
+                               styles = attrs = classes = null;
+                       }
+
+                       // Add as an unnamed rule, because there can be two rules
+                       // for one elements set defined in string format.
+                       rules[ '$' + groupNum++ ] = {
+                               elements: match[ 1 ],
+                               classes: classes,
+                               styles: styles,
+                               attributes: attrs
+                       };
+
+                       // Move to the next group.
+                       input = input.slice( match[ 0 ].length );
+               }
+
+               return rules;
+       }
+
+       // Extract specified properties group (styles, attrs, classes) from
+       // what stands after the elements list in string format of allowedContent.
+       function parseProperties( properties, groupName ) {
+               var group = properties.match( groupsPatterns[ groupName ] );
+               return group ? trim( group[ 1 ] ) : null;
+       }
+
+       function populateProperties( element ) {
+                       // Backup styles and classes, because they may be removed by DACRs.
+                       // We'll need them in updateElement().
+               var styles = element.styleBackup = element.attributes.style,
+                       classes = element.classBackup = element.attributes[ 'class' ];
+
+               // Parse classes and styles if that hasn't been done before.
+               if ( !element.styles )
+                       element.styles = CKEDITOR.tools.parseCssText( styles || '', 1 );
+               if ( !element.classes )
+                       element.classes = classes ? classes.split( /\s+/ ) : [];
+       }
+
+       // Filter element protected with a comment.
+       // Returns true if protected content is ok, false otherwise.
+       function processProtectedElement( that, comment, protectedRegexs, filterOpts ) {
+               var source = decodeURIComponent( comment.value.replace( /^\{cke_protected\}/, '' ) ),
+                       protectedFrag,
+                       toBeRemoved = [],
+                       node, i, match;
+
+               // Protected element's and protected source's comments look exactly the same.
+               // Check if what we have isn't a protected source instead of protected script/noscript.
+               if ( protectedRegexs ) {
+                       for ( i = 0; i < protectedRegexs.length; ++i ) {
+                               if ( ( match = source.match( protectedRegexs[ i ] ) ) &&
+                                       match[ 0 ].length == source.length      // Check whether this pattern matches entire source
+                                                                                                               // to avoid '<script>alert("<? 1 ?>")</script>' matching
+                                                                                                               // the PHP's protectedSource regexp.
+                               )
+                                       return true;
+                       }
+               }
+
+               protectedFrag = CKEDITOR.htmlParser.fragment.fromHtml( source );
+
+               if ( protectedFrag.children.length == 1 && ( node = protectedFrag.children[ 0 ] ).type == CKEDITOR.NODE_ELEMENT )
+                       processElement( that, node, toBeRemoved, filterOpts );
+
+               // If protected element has been marked to be removed, return 'false' - comment was rejected.
+               return !toBeRemoved.length;
+       }
+
+       var unprotectElementsNamesRegexp = /^cke:(object|embed|param)$/,
+               protectElementsNamesRegexp = /^(object|embed|param)$/;
+
+       // The actual function which filters, transforms and does other funny things with an element.
+       //
+       // @param {CKEDITOR.filter} that Context.
+       // @param {CKEDITOR.htmlParser.element} element The element to be processed.
+       // @param {Array} toBeRemoved Array into which elements rejected by the filter will be pushed.
+       // @param {Boolean} [opts.doFilter] Whether element should be filtered.
+       // @param {Boolean} [opts.doTransform] Whether transformations should be applied.
+       // @param {Boolean} [opts.doCallbacks] Whether to execute element callbacks.
+       // @param {Boolean} [opts.toHtml] Set to true if filter used together with htmlDP#toHtml
+       // @param {Boolean} [opts.skipRequired] Whether element's required properties shouldn't be verified.
+       // @param {Boolean} [opts.skipFinalValidation] Whether to not perform final element validation (a,img).
+       // @returns {Number} Possible flags:
+       //  * FILTER_ELEMENT_MODIFIED,
+       //  * FILTER_SKIP_TREE.
+       function processElement( that, element, toBeRemoved, opts ) {
+               var status,
+                       retVal = 0,
+                       callbacksRetVal;
+
+               // Unprotect elements names previously protected by htmlDataProcessor
+               // (see protectElementNames and protectSelfClosingElements functions).
+               // Note: body, title, etc. are not protected by htmlDataP (or are protected and then unprotected).
+               if ( opts.toHtml )
+                       element.name = element.name.replace( unprotectElementsNamesRegexp, '$1' );
+
+               // Execute element callbacks and return if one of them returned any value.
+               if ( opts.doCallbacks && that.elementCallbacks ) {
+                       // For now we only support here FILTER_SKIP_TREE, so we can early return if retVal is truly value.
+                       if ( ( callbacksRetVal = executeElementCallbacks( element, that.elementCallbacks ) ) )
+                               return callbacksRetVal;
+               }
+
+               // If transformations are set apply all groups.
+               if ( opts.doTransform )
+                       transformElement( that, element );
+
+               if ( opts.doFilter ) {
+                       // Apply all filters.
+                       status = filterElement( that, element, opts );
+
+                       // Handle early return from filterElement.
+                       if ( !status ) {
+                               toBeRemoved.push( element );
+                               return FILTER_ELEMENT_MODIFIED;
+                       }
+
+                       // Finally, if after running all filter rules it still hasn't been allowed - remove it.
+                       if ( !status.valid ) {
+                               toBeRemoved.push( element );
+                               return FILTER_ELEMENT_MODIFIED;
+                       }
+
+                       // Update element's attributes based on status of filtering.
+                       if ( updateElement( element, status ) )
+                               retVal = FILTER_ELEMENT_MODIFIED;
+
+                       if ( !opts.skipFinalValidation && !validateElement( element ) ) {
+                               toBeRemoved.push( element );
+                               return FILTER_ELEMENT_MODIFIED;
+                       }
+               }
+
+               // Protect previously unprotected elements.
+               if ( opts.toHtml )
+                       element.name = element.name.replace( protectElementsNamesRegexp, 'cke:$1' );
+
+               return retVal;
+       }
+
+       // Returns a regexp object which can be used to test if a property
+       // matches one of wildcard validators.
+       function regexifyPropertiesWithWildcards( validators ) {
+               var patterns = [],
+                       i;
+
+               for ( i in validators ) {
+                       if ( i.indexOf( '*' ) > -1 )
+                               patterns.push( i.replace( /\*/g, '.*' ) );
+               }
+
+               if ( patterns.length )
+                       return new RegExp( '^(?:' + patterns.join( '|' ) + ')$' );
+               else
+                       return null;
+       }
+
+       // Standardize a rule by converting all validators to hashes.
+       function standardizeRule( rule ) {
+               rule.elements = convertValidatorToHash( rule.elements, /\s+/ ) || null;
+               rule.propertiesOnly = rule.propertiesOnly || ( rule.elements === true );
+
+               var delim = /\s*,\s*/,
+                       i;
+
+               for ( i in validators ) {
+                       rule[ i ] = convertValidatorToHash( rule[ i ], delim ) || null;
+                       rule[ validatorsRequired[ i ] ] = extractRequired( convertValidatorToHash(
+                               rule[ validatorsRequired[ i ] ], delim ), rule[ i ] ) || null;
+               }
+
+               rule.match = rule.match || null;
+       }
+
+       // Does the element transformation by applying registered
+       // transformation rules.
+       function transformElement( that, element ) {
+               var transformations = that._.transformations[ element.name ],
+                       i;
+
+               if ( !transformations )
+                       return;
+
+               populateProperties( element );
+
+               for ( i = 0; i < transformations.length; ++i )
+                       applyTransformationsGroup( that, element, transformations[ i ] );
+
+               // Do not count on updateElement() which is called in processElement, because it:
+               // * may not be called,
+               // * may skip some properties when all are marked as valid.
+               updateAttributes( element );
+       }
+
+       // Copy element's styles and classes back to attributes array.
+       function updateAttributes( element ) {
+               var attrs = element.attributes,
+                       styles;
+
+               // Will be recreated later if any of styles/classes exists.
+               delete attrs.style;
+               delete attrs[ 'class' ];
+
+               if ( ( styles = CKEDITOR.tools.writeCssText( element.styles, true ) ) )
+                       attrs.style = styles;
+
+               if ( element.classes.length )
+                       attrs[ 'class' ] = element.classes.sort().join( ' ' );
+       }
+
+       // Update element object based on status of filtering.
+       // @returns Whether element was modified.
+       function updateElement( element, status ) {
+               var validAttrs = status.validAttributes,
+                       validStyles = status.validStyles,
+                       validClasses = status.validClasses,
+                       attrs = element.attributes,
+                       styles = element.styles,
+                       classes = element.classes,
+                       origClasses = element.classBackup,
+                       origStyles = element.styleBackup,
+                       name, origName, i,
+                       stylesArr = [],
+                       classesArr = [],
+                       internalAttr = /^data-cke-/,
+                       isModified = false;
+
+               // Will be recreated later if any of styles/classes were passed.
+               delete attrs.style;
+               delete attrs[ 'class' ];
+               // Clean up.
+               delete element.classBackup;
+               delete element.styleBackup;
+
+               if ( !status.allAttributes ) {
+                       for ( name in attrs ) {
+                               // If not valid and not internal attribute delete it.
+                               if ( !validAttrs[ name ] ) {
+                                       // Allow all internal attibutes...
+                                       if ( internalAttr.test( name ) ) {
+                                               // ... unless this is a saved attribute and the original one isn't allowed.
+                                               if ( name != ( origName = name.replace( /^data-cke-saved-/, '' ) ) &&
+                                                       !validAttrs[ origName ]
+                                               ) {
+                                                       delete attrs[ name ];
+                                                       isModified = true;
+                                               }
+                                       } else {
+                                               delete attrs[ name ];
+                                               isModified = true;
+                                       }
+                               }
+
+                       }
+               }
+
+               if ( !status.allStyles || status.hadInvalidStyle ) {
+                       for ( name in styles ) {
+                               // We check status.allStyles because when there was a '*' ACR and some
+                               // DACR we have now both properties true - status.allStyles and status.hadInvalidStyle.
+                               // However unlike in the case when we only have '*' ACR, in which we can just copy original
+                               // styles, in this case we must copy only those styles which were not removed by DACRs.
+                               if ( status.allStyles || validStyles[ name ] )
+                                       stylesArr.push( name + ':' + styles[ name ] );
+                               else
+                                       isModified = true;
+                       }
+                       if ( stylesArr.length )
+                               attrs.style = stylesArr.sort().join( '; ' );
+               }
+               else if ( origStyles ) {
+                       attrs.style = origStyles;
+               }
+
+               if ( !status.allClasses || status.hadInvalidClass ) {
+                       for ( i = 0; i < classes.length; ++i ) {
+                               // See comment for styles.
+                               if ( status.allClasses || validClasses[ classes[ i ] ] )
+                                       classesArr.push( classes[ i ] );
+                       }
+                       if ( classesArr.length )
+                               attrs[ 'class' ] = classesArr.sort().join( ' ' );
+
+                       if ( origClasses && classesArr.length < origClasses.split( /\s+/ ).length )
+                               isModified = true;
+               }
+               else if ( origClasses ) {
+                       attrs[ 'class' ] = origClasses;
+               }
+
+               return isModified;
+       }
+
+       function validateElement( element ) {
+               switch ( element.name ) {
+                       case 'a':
+                               // Code borrowed from htmlDataProcessor, so ACF does the same clean up.
+                               if ( !( element.children.length || element.attributes.name || element.attributes.id ) )
+                                       return false;
+                               break;
+                       case 'img':
+                               if ( !element.attributes.src )
+                                       return false;
+                               break;
+               }
+
+               return true;
+       }
+
+       function validatorFunction( validator ) {
+               if ( !validator )
+                       return false;
+               if ( validator === true )
+                       return true;
+
+               // Note: We don't need to remove properties with wildcards from the validator object.
+               // E.g. data-* is actually an edge case of /^data-.*$/, so when it's accepted
+               // by `value in validator` it's ok.
+               var regexp = regexifyPropertiesWithWildcards( validator );
+
+               return function( value ) {
+                       return value in validator || ( regexp && value.match( regexp ) );
+               };
+       }
+
+       //
+       // REMOVE ELEMENT ---------------------------------------------------------
+       //
+
+       // Check whether all children will be valid in new context.
+       // Note: it doesn't verify if text node is valid, because
+       // new parent should accept them.
+       function checkChildren( children, newParentName ) {
+               var allowed = DTD[ newParentName ];
+
+               for ( var i = 0, l = children.length, child; i < l; ++i ) {
+                       child = children[ i ];
+                       if ( child.type == CKEDITOR.NODE_ELEMENT && !allowed[ child.name ] )
+                               return false;
+               }
+
+               return true;
+       }
+
+       function createBr() {
+               return new CKEDITOR.htmlParser.element( 'br' );
+       }
+
+       // Whether this is an inline element or text.
+       function inlineNode( node ) {
+               return node.type == CKEDITOR.NODE_TEXT ||
+                       node.type == CKEDITOR.NODE_ELEMENT && DTD.$inline[ node.name ];
+       }
+
+       function isBrOrBlock( node ) {
+               return node.type == CKEDITOR.NODE_ELEMENT &&
+                       ( node.name == 'br' || DTD.$block[ node.name ] );
+       }
+
+       // Try to remove element in the best possible way.
+       //
+       // @param {Array} toBeChecked After executing this function
+       // this array will contain elements that should be checked
+       // because they were marked as potentially:
+       // * in wrong context (e.g. li in body),
+       // * empty elements from $removeEmpty,
+       // * incorrect img/a/other element validated by validateElement().
+       function removeElement( element, enterTag, toBeChecked ) {
+               var name = element.name;
+
+               if ( DTD.$empty[ name ] || !element.children.length ) {
+                       // Special case - hr in br mode should be replaced with br, not removed.
+                       if ( name == 'hr' && enterTag == 'br' )
+                               element.replaceWith( createBr() );
+                       else {
+                               // Parent might become an empty inline specified in $removeEmpty or empty a[href].
+                               if ( element.parent )
+                                       toBeChecked.push( { check: 'it', el: element.parent } );
+
+                               element.remove();
+                       }
+               } else if ( DTD.$block[ name ] || name == 'tr' ) {
+                       if ( enterTag == 'br' )
+                               stripBlockBr( element, toBeChecked );
+                       else
+                               stripBlock( element, enterTag, toBeChecked );
+               }
+               // Special case - elements that may contain CDATA should be removed completely.
+               else if ( name in { style: 1, script: 1 } )
+                       element.remove();
+               // The rest of inline elements. May also be the last resort
+               // for some special elements.
+               else {
+                       // Parent might become an empty inline specified in $removeEmpty or empty a[href].
+                       if ( element.parent )
+                               toBeChecked.push( { check: 'it', el: element.parent } );
+                       element.replaceWithChildren();
+               }
+       }
+
+       // Strip element block, but leave its content.
+       // Works in 'div' and 'p' enter modes.
+       function stripBlock( element, enterTag, toBeChecked ) {
+               var children = element.children;
+
+               // First, check if element's children may be wrapped with <p/div>.
+               // Ignore that <p/div> may not be allowed in element.parent.
+               // This will be fixed when removing parent or by toBeChecked rule.
+               if ( checkChildren( children, enterTag ) ) {
+                       element.name = enterTag;
+                       element.attributes = {};
+                       // Check if this p/div was put in correct context.
+                       // If not - strip parent.
+                       toBeChecked.push( { check: 'parent-down', el: element } );
+                       return;
+               }
+
+               var parent = element.parent,
+                       shouldAutoP = parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT || parent.name == 'body',
+                       i, child, p, parentDtd;
+
+               for ( i = children.length; i > 0; ) {
+                       child = children[ --i ];
+
+                       // If parent requires auto paragraphing and child is inline node,
+                       // insert this child into newly created paragraph.
+                       if ( shouldAutoP && inlineNode( child )  ) {
+                               if ( !p ) {
+                                       p = new CKEDITOR.htmlParser.element( enterTag );
+                                       p.insertAfter( element );
+
+                                       // Check if this p/div was put in correct context.
+                                       // If not - strip parent.
+                                       toBeChecked.push( { check: 'parent-down', el: p } );
+                               }
+                               p.add( child, 0 );
+                       }
+                       // Child which doesn't need to be auto paragraphed.
+                       else {
+                               p = null;
+                               parentDtd = DTD[ parent.name ] || DTD.span;
+
+                               child.insertAfter( element );
+                               // If inserted into invalid context, mark it and check
+                               // after removing all elements.
+                               if ( parent.type != CKEDITOR.NODE_DOCUMENT_FRAGMENT &&
+                                       child.type == CKEDITOR.NODE_ELEMENT &&
+                                       !parentDtd[ child.name ]
+                               )
+                                       toBeChecked.push( { check: 'el-up', el: child } );
+                       }
+               }
+
+               // All children have been moved to element's parent, so remove it.
+               element.remove();
+       }
+
+       // Prepend/append block with <br> if isn't
+       // already prepended/appended with <br> or block and
+       // isn't first/last child of its parent.
+       // Then replace element with its children.
+       // <p>a</p><p>b</p> => <p>a</p><br>b => a<br>b
+       function stripBlockBr( element ) {
+               var br;
+
+               if ( element.previous && !isBrOrBlock( element.previous ) ) {
+                       br = createBr();
+                       br.insertBefore( element );
+               }
+
+               if ( element.next && !isBrOrBlock( element.next ) ) {
+                       br = createBr();
+                       br.insertAfter( element );
+               }
+
+               element.replaceWithChildren();
+       }
+
+       //
+       // TRANSFORMATIONS --------------------------------------------------------
+       //
+       var transformationsTools;
+
+       // Apply given transformations group to the element.
+       function applyTransformationsGroup( filter, element, group ) {
+               var i, rule;
+
+               for ( i = 0; i < group.length; ++i ) {
+                       rule = group[ i ];
+
+                       // Test with #check or #left only if it's set.
+                       // Do not apply transformations because that creates infinite loop.
+                       if ( ( !rule.check || filter.check( rule.check, false ) ) &&
+                               ( !rule.left || rule.left( element ) ) ) {
+                               rule.right( element, transformationsTools );
+                               return; // Only first matching rule in a group is executed.
+                       }
+               }
+       }
+
+       // Check whether element matches CKEDITOR.style.
+       // The element can be a "superset" of style,
+       // e.g. it may have more classes, but need to have
+       // at least those defined in style.
+       function elementMatchesStyle( element, style ) {
+               var def = style.getDefinition(),
+                       defAttrs = def.attributes,
+                       defStyles = def.styles,
+                       attrName, styleName,
+                       classes, classPattern, cl;
+
+               if ( element.name != def.element )
+                       return false;
+
+               for ( attrName in defAttrs ) {
+                       if ( attrName == 'class' ) {
+                               classes = defAttrs[ attrName ].split( /\s+/ );
+                               classPattern = element.classes.join( '|' );
+                               while ( ( cl = classes.pop() ) ) {
+                                       if ( classPattern.indexOf( cl ) == -1 )
+                                               return false;
+                               }
+                       } else {
+                               if ( element.attributes[ attrName ] != defAttrs[ attrName ] )
+                                       return false;
+                       }
+               }
+
+               for ( styleName in defStyles ) {
+                       if ( element.styles[ styleName ] != defStyles[ styleName ] )
+                               return false;
+               }
+
+               return true;
+       }
+
+       // Return transformation group for content form.
+       // One content form makes one transformation rule in one group.
+       function getContentFormTransformationGroup( form, preferredForm ) {
+               var element, left;
+
+               if ( typeof form == 'string' )
+                       element = form;
+               else if ( form instanceof CKEDITOR.style )
+                       left = form;
+               else {
+                       element = form[ 0 ];
+                       left = form[ 1 ];
+               }
+
+               return [ {
+                       element: element,
+                       left: left,
+                       right: function( el, tools ) {
+                               tools.transform( el, preferredForm );
+                       }
+               } ];
+       }
+
+       // Obtain element's name from transformation rule.
+       // It will be defined by #element, or #check or #left (styleDef.element).
+       function getElementNameForTransformation( rule, check ) {
+               if ( rule.element )
+                       return rule.element;
+               if ( check )
+                       return check.match( /^([a-z0-9]+)/i )[ 0 ];
+               return rule.left.getDefinition().element;
+       }
+
+       function getMatchStyleFn( style ) {
+               return function( el ) {
+                       return elementMatchesStyle( el, style );
+               };
+       }
+
+       function getTransformationFn( toolName ) {
+               return function( el, tools ) {
+                       tools[ toolName ]( el );
+               };
+       }
+
+       function optimizeTransformationsGroup( rules ) {
+               var groupName, i, rule,
+                       check, left, right,
+                       optimizedRules = [];
+
+               for ( i = 0; i < rules.length; ++i ) {
+                       rule = rules[ i ];
+
+                       if ( typeof rule == 'string' ) {
+                               rule = rule.split( /\s*:\s*/ );
+                               check = rule[ 0 ];
+                               left = null;
+                               right = rule[ 1 ];
+                       } else {
+                               check = rule.check;
+                               left = rule.left;
+                               right = rule.right;
+                       }
+
+                       // Extract element name.
+                       if ( !groupName )
+                               groupName = getElementNameForTransformation( rule, check );
+
+                       if ( left instanceof CKEDITOR.style )
+                               left = getMatchStyleFn( left );
+
+                       optimizedRules.push( {
+                               // It doesn't make sense to test against name rule (e.g. 'table'), so don't save it.
+                               check: check == groupName ? null : check,
+
+                               left: left,
+
+                               // Handle shorthand format. E.g.: 'table[width]:sizeToAttribute'.
+                               right: typeof right == 'string' ? getTransformationFn( right ) : right
+                       } );
+               }
+
+               return {
+                       name: groupName,
+                       rules: optimizedRules
+               };
+       }
+
+       /**
+        * Singleton containing tools useful for transformation rules.
+        *
+        * @class CKEDITOR.filter.transformationsTools
+        * @singleton
+        */
+       transformationsTools = CKEDITOR.filter.transformationsTools = {
+               /**
+                * Converts `width` and `height` attributes to styles.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               sizeToStyle: function( element ) {
+                       this.lengthToStyle( element, 'width' );
+                       this.lengthToStyle( element, 'height' );
+               },
+
+               /**
+                * Converts `width` and `height` styles to attributes.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               sizeToAttribute: function( element ) {
+                       this.lengthToAttribute( element, 'width' );
+                       this.lengthToAttribute( element, 'height' );
+               },
+
+               /**
+                * Converts length in the `attrName` attribute to a valid CSS length (like `width` or `height`).
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                * @param {String} attrName Name of the attribute that will be converted.
+                * @param {String} [styleName=attrName] Name of the style into which the attribute will be converted.
+                */
+               lengthToStyle: function( element, attrName, styleName ) {
+                       styleName = styleName || attrName;
+
+                       if ( !( styleName in element.styles ) ) {
+                               var value = element.attributes[ attrName ];
+
+                               if ( value ) {
+                                       if ( ( /^\d+$/ ).test( value ) )
+                                               value += 'px';
+
+                                       element.styles[ styleName ] = value;
+                               }
+                       }
+
+                       delete element.attributes[ attrName ];
+               },
+
+               /**
+                * Converts length in the `styleName` style to a valid length attribute (like `width` or `height`).
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                * @param {String} styleName The name of the style that will be converted.
+                * @param {String} [attrName=styleName] The name of the attribute into which the style will be converted.
+                */
+               lengthToAttribute: function( element, styleName, attrName ) {
+                       attrName = attrName || styleName;
+
+                       if ( !( attrName in element.attributes ) ) {
+                               var value = element.styles[ styleName ],
+                                       match = value && value.match( /^(\d+)(?:\.\d*)?px$/ );
+
+                               if ( match )
+                                       element.attributes[ attrName ] = match[ 1 ];
+                               // Pass the TEST_VALUE used by filter#check when mocking element.
+                               else if ( value == TEST_VALUE )
+                                       element.attributes[ attrName ] = TEST_VALUE;
+                       }
+
+                       delete element.styles[ styleName ];
+               },
+
+               /**
+                * Converts the `align` attribute to the `float` style if not set. The attribute
+                * is always removed.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               alignmentToStyle: function( element ) {
+                       if ( !( 'float' in element.styles ) ) {
+                               var value = element.attributes.align;
+
+                               if ( value == 'left' || value == 'right' )
+                                       element.styles[ 'float' ] = value; // Uh... GCC doesn't like the 'float' prop name.
+                       }
+
+                       delete element.attributes.align;
+               },
+
+               /**
+                * Converts the `float` style to the `align` attribute if not set.
+                * The style is always removed.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               alignmentToAttribute: function( element ) {
+                       if ( !( 'align' in element.attributes ) ) {
+                               var value = element.styles[ 'float' ];
+
+                               if ( value == 'left' || value == 'right' )
+                                       element.attributes.align = value;
+                       }
+
+                       delete element.styles[ 'float' ]; // Uh... GCC doesn't like the 'float' prop name.
+               },
+
+               /**
+                * Converts the shorthand form of the `border` style to seperate styles.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               splitBorderShorthand: function( element ) {
+                       if ( !element.styles.border ) {
+                               return;
+                       }
+
+                       var widths = element.styles.border.match( /([\.\d]+\w+)/g ) || [ '0px' ];
+                       switch ( widths.length ) {
+                               case 1:
+                                       element.styles[ 'border-width' ] = widths[0];
+                                       break;
+                               case 2:
+                                       mapStyles( [ 0, 1, 0, 1 ] );
+                                       break;
+                               case 3:
+                                       mapStyles( [ 0, 1, 2, 1 ] );
+                                       break;
+                               case 4:
+                                       mapStyles( [ 0, 1, 2, 3 ] );
+                                       break;
+                       }
+
+                       element.styles[ 'border-style' ] = element.styles[ 'border-style' ] ||
+                               ( element.styles.border.match( /(none|hidden|dotted|dashed|solid|double|groove|ridge|inset|outset|initial|inherit)/ ) || [] )[ 0 ];
+                       if ( !element.styles[ 'border-style' ] )
+                               delete element.styles[ 'border-style' ];
+
+                       delete element.styles.border;
+
+                       function mapStyles( map ) {
+                               element.styles['border-top-width'] = widths[ map[0] ];
+                               element.styles['border-right-width'] = widths[ map[1] ];
+                               element.styles['border-bottom-width'] = widths[ map[2] ];
+                               element.styles['border-left-width'] = widths[ map[3] ];
+                       }
+               },
+
+               listTypeToStyle: function( element ) {
+                       if ( element.attributes.type ) {
+                               switch ( element.attributes.type ) {
+                                       case 'a':
+                                               element.styles[ 'list-style-type' ] = 'lower-alpha';
+                                               break;
+                                       case 'A':
+                                               element.styles[ 'list-style-type' ] = 'upper-alpha';
+                                               break;
+                                       case 'i':
+                                               element.styles[ 'list-style-type' ] = 'lower-roman';
+                                               break;
+                                       case 'I':
+                                               element.styles[ 'list-style-type' ] = 'upper-roman';
+                                               break;
+                                       case '1':
+                                               element.styles[ 'list-style-type' ] = 'decimal';
+                                               break;
+                                       default:
+                                               element.styles[ 'list-style-type' ] = element.attributes.type;
+                               }
+                       }
+               },
+
+               /**
+                * Converts the shorthand form of the `margin` style to seperate styles.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                */
+               splitMarginShorthand: function( element ) {
+                       if ( !element.styles.margin ) {
+                               return;
+                       }
+
+                       var widths = element.styles.margin.match( /(\-?[\.\d]+\w+)/g ) || [ '0px' ];
+                       switch ( widths.length ) {
+                               case 1:
+                                       element.styles.margin = widths[0];
+                                       break;
+                               case 2:
+                                       mapStyles( [ 0, 1, 0, 1 ] );
+                                       break;
+                               case 3:
+                                       mapStyles( [ 0, 1, 2, 1 ] );
+                                       break;
+                               case 4:
+                                       mapStyles( [ 0, 1, 2, 3 ] );
+                                       break;
+                       }
+
+                       delete element.styles.margin;
+
+                       function mapStyles( map ) {
+                               element.styles['margin-top'] = widths[ map[0] ];
+                               element.styles['margin-right'] = widths[ map[1] ];
+                               element.styles['margin-bottom'] = widths[ map[2] ];
+                               element.styles['margin-left'] = widths[ map[3] ];
+                       }
+               },
+
+               /**
+                * Checks whether an element matches a given {@link CKEDITOR.style}.
+                * The element can be a "superset" of a style, e.g. it may have
+                * more classes, but needs to have at least those defined in the style.
+                *
+                * @param {CKEDITOR.htmlParser.element} element
+                * @param {CKEDITOR.style} style
+                */
+               matchesStyle: elementMatchesStyle,
+
+               /**
+                * Transforms an element to a given form.
+                *
+                * Form may be a:
+                *
+                *      * {@link CKEDITOR.style},
+                *      * string &ndash; the new name of the element.
+                *
+                * @param {CKEDITOR.htmlParser.element} el
+                * @param {CKEDITOR.style/String} form
+                */
+               transform: function( el, form ) {
+                       if ( typeof form == 'string' )
+                               el.name = form;
+                       // Form is an instance of CKEDITOR.style.
+                       else {
+                               var def = form.getDefinition(),
+                                       defStyles = def.styles,
+                                       defAttrs = def.attributes,
+                                       attrName, styleName,
+                                       existingClassesPattern, defClasses, cl;
+
+                               el.name = def.element;
+
+                               for ( attrName in defAttrs ) {
+                                       if ( attrName == 'class' ) {
+                                               existingClassesPattern = el.classes.join( '|' );
+                                               defClasses = defAttrs[ attrName ].split( /\s+/ );
+
+                                               while ( ( cl = defClasses.pop() ) ) {
+                                                       if ( existingClassesPattern.indexOf( cl ) == -1 )
+                                                               el.classes.push( cl );
+                                               }
+                                       } else {
+                                               el.attributes[ attrName ] = defAttrs[ attrName ];
+                                       }
+
+                               }
+
+                               for ( styleName in defStyles ) {
+                                       el.styles[ styleName ] = defStyles[ styleName ];
+                               }
+                       }
+               }
+       };
+
+} )();
+
+/**
+ * Allowed content rules. This setting is used when
+ * instantiating {@link CKEDITOR.editor#filter}.
+ *
+ * The following values are accepted:
+ *
+ *     * {@link CKEDITOR.filter.allowedContentRules} &ndash; defined rules will be added
+ *     to the {@link CKEDITOR.editor#filter}.
+ *     * `true` &ndash; will disable the filter (data will not be filtered,
+ *     all features will be activated).
+ *     * default &ndash; the filter will be configured by loaded features
+ *     (toolbar items, commands, etc.).
+ *
+ * In all cases filter configuration may be extended by
+ * {@link CKEDITOR.config#extraAllowedContent}. This option may be especially
+ * useful when you want to use the default `allowedContent` value
+ * along with some additional rules.
+ *
+ *             CKEDITOR.replace( 'textarea_id', {
+ *                     allowedContent: 'p b i; a[!href]',
+ *                     on: {
+ *                             instanceReady: function( evt ) {
+ *                                     var editor = evt.editor;
+ *
+ *                                     editor.filter.check( 'h1' ); // -> false
+ *                                     editor.setData( '<h1><i>Foo</i></h1><p class="left"><span>Bar</span> <a href="http://foo.bar">foo</a></p>' );
+ *                                     // Editor contents will be:
+ *                                     '<p><i>Foo</i></p><p>Bar <a href="http://foo.bar">foo</a></p>'
+ *                             }
+ *                     }
+ *             } );
+ *
+ * It is also possible to disallow some already allowed content. It is especially
+ * useful when you want to "trim down" the content allowed by default by
+ * editor features. To do that, use the {@link #disallowedContent} option.
+ *
+ * Read more in the [documentation](#!/guide/dev_acf)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/acf.html).
+ *
+ * @since 4.1
+ * @cfg {CKEDITOR.filter.allowedContentRules/Boolean} [allowedContent=null]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * This option makes it possible to set additional allowed
+ * content rules for {@link CKEDITOR.editor#filter}.
+ *
+ * It is especially useful in combination with the default
+ * {@link CKEDITOR.config#allowedContent} value:
+ *
+ *             CKEDITOR.replace( 'textarea_id', {
+ *                     plugins: 'wysiwygarea,toolbar,format',
+ *                     extraAllowedContent: 'b i',
+ *                     on: {
+ *                             instanceReady: function( evt ) {
+ *                                     var editor = evt.editor;
+ *
+ *                                     editor.filter.check( 'h1' ); // -> true (thanks to Format combo)
+ *                                     editor.filter.check( 'b' ); // -> true (thanks to extraAllowedContent)
+ *                                     editor.setData( '<h1><i>Foo</i></h1><p class="left"><b>Bar</b> <a href="http://foo.bar">foo</a></p>' );
+ *                                     // Editor contents will be:
+ *                                     '<h1><i>Foo</i></h1><p><b>Bar</b> foo</p>'
+ *                             }
+ *                     }
+ *             } );
+ *
+ * Read more in the [documentation](#!/guide/dev_acf-section-automatic-mode-and-allow-additional-tags%2Fproperties)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/acf.html).
+ * See also {@link CKEDITOR.config#allowedContent} for more details.
+ *
+ * @since 4.1
+ * @cfg {Object/String} extraAllowedContent
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Disallowed content rules. They have precedence over {@link #allowedContent allowed content rules}.
+ * Read more in the [Disallowed Content guide](#!/guide/dev_disallowed_content).
+ *
+ * Read more in the [documentation](#!/guide/dev_acf-section-automatic-mode-but-disallow-certain-tags%2Fproperties)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/acf.html).
+ * See also {@link CKEDITOR.config#allowedContent} and {@link CKEDITOR.config#extraAllowedContent}.
+ *
+ * @since 4.4
+ * @cfg {CKEDITOR.filter.disallowedContentRules} disallowedContent
+ * @member CKEDITOR.config
+ */
+
+/**
+ * This event is fired when {@link CKEDITOR.filter} has stripped some
+ * content from the data that was loaded (e.g. by {@link CKEDITOR.editor#method-setData}
+ * method or in the source mode) or inserted (e.g. when pasting or using the
+ * {@link CKEDITOR.editor#method-insertHtml} method).
+ *
+ * This event is useful when testing whether the {@link CKEDITOR.config#allowedContent}
+ * setting is sufficient and correct for a system that is migrating to CKEditor 4.1
+ * (where the [Advanced Content Filter](#!/guide/dev_advanced_content_filter) was introduced).
+ *
+ * @since 4.1
+ * @event dataFiltered
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
+
+/**
+ * Virtual class which is the [Allowed Content Rules](#!/guide/dev_allowed_content_rules) formats type.
+ *
+ * Possible formats are:
+ *
+ *     * the [string format](#!/guide/dev_allowed_content_rules-section-2),
+ *     * the [object format](#!/guide/dev_allowed_content_rules-section-3),
+ *     * a {@link CKEDITOR.style} instance &ndash; used mainly for integrating plugins with Advanced Content Filter,
+ *     * an array of the above formats.
+ *
+ * @since 4.1
+ * @class CKEDITOR.filter.allowedContentRules
+ * @abstract
+ */
+
+/**
+ * Virtual class representing the {@link CKEDITOR.filter#disallow} argument and a type of
+ * the {@link CKEDITOR.config#disallowedContent} option.
+ *
+ * This is a simplified version of the {@link CKEDITOR.filter.allowedContentRules} type.
+ * Only the string format and object format are accepted. Required properties
+ * are not allowed in this format.
+ *
+ * Read more in the [Disallowed Content guide](#!/guide/dev_disallowed_content).
+ *
+ * @since 4.4
+ * @class CKEDITOR.filter.disallowedContentRules
+ * @abstract
+ */
+
+/**
+ * Virtual class representing {@link CKEDITOR.filter#check} argument.
+ *
+ * This is a simplified version of the {@link CKEDITOR.filter.allowedContentRules} type.
+ * It may contain only one element and its styles, classes, and attributes. Only the
+ * string format and a {@link CKEDITOR.style} instances are accepted. Required properties
+ * are not allowed in this format.
+ *
+ * Example:
+ *
+ *             'img[src,alt](foo)'     // Correct rule.
+ *             'ol, ul(!foo)'          // Incorrect rule. Multiple elements and required
+ *                                                     // properties are not supported.
+ *
+ * @since 4.1
+ * @class CKEDITOR.filter.contentRule
+ * @abstract
+ */
+
+/**
+ * Interface that may be automatically implemented by any
+ * instance of any class which has at least the `name` property and
+ * can be meant as an editor feature.
+ *
+ * For example:
+ *
+ *     * "Bold" command, button, and keystroke &ndash; it does not mean exactly
+ * `<strong>` or `<b>` but just the ability to create bold text.
+ *     * "Format" drop-down list &ndash; it also does not imply any HTML tag.
+ *     * "Link" command, button, and keystroke.
+ *     * "Image" command, button, and dialog window.
+ *
+ * Thus most often a feature is an instance of one of the following classes:
+ *
+ *     * {@link CKEDITOR.command}
+ *     * {@link CKEDITOR.ui.button}
+ *     * {@link CKEDITOR.ui.richCombo}
+ *
+ * None of them have a `name` property explicitly defined, but
+ * it is set by {@link CKEDITOR.editor#addCommand} and {@link CKEDITOR.ui#add}.
+ *
+ * During editor initialization all features that the editor should activate
+ * should be passed to {@link CKEDITOR.editor#addFeature} (shorthand for {@link CKEDITOR.filter#addFeature}).
+ *
+ * This method checks if a feature can be activated (see {@link #requiredContent}) and if yes,
+ * then it registers allowed content rules required by this feature (see {@link #allowedContent}) along
+ * with two kinds of transformations: {@link #contentForms} and {@link #contentTransformations}.
+ *
+ * By default all buttons that are included in [toolbar layout configuration](#!/guide/dev_toolbar)
+ * are checked and registered with {@link CKEDITOR.editor#addFeature}, all styles available in the
+ * 'Format' and 'Styles' drop-down lists are checked and registered too and so on.
+ *
+ * @since 4.1
+ * @class CKEDITOR.feature
+ * @abstract
+ */
+
+/**
+ * HTML code that can be generated by this feature.
+ *
+ * For example a basic image feature (image button displaying the image dialog window)
+ * may allow `'img[!src,alt,width,height]'`.
+ *
+ * During the feature activation this value is passed to {@link CKEDITOR.filter#allow}.
+ *
+ * @property {CKEDITOR.filter.allowedContentRules} [allowedContent=null]
+ */
+
+/**
+ * Minimal HTML code that this feature must be allowed to
+ * generate in order to work.
+ *
+ * For example a basic image feature (image button displaying the image dialog window)
+ * needs `'img[src,alt]'` in order to be activated.
+ *
+ * During the feature validation this value is passed to {@link CKEDITOR.filter#check}.
+ *
+ * If this value is not provided, a feature will be always activated.
+ *
+ * @property {CKEDITOR.filter.contentRule} [requiredContent=null]
+ */
+
+/**
+ * The name of the feature.
+ *
+ * It is used for example to identify which {@link CKEDITOR.filter#allowedContent}
+ * rule was added for which feature.
+ *
+ * @property {String} name
+ */
+
+/**
+ * Feature content forms to be registered in the {@link CKEDITOR.editor#filter}
+ * during the feature activation.
+ *
+ * See {@link CKEDITOR.filter#addContentForms} for more details.
+ *
+ * @property [contentForms=null]
+ */
+
+/**
+ * Transformations (usually for content generated by this feature, but not necessarily)
+ * that will be registered in the {@link CKEDITOR.editor#filter} during the feature activation.
+ *
+ * See {@link CKEDITOR.filter#addTransformations} for more details.
+ *
+ * @property [contentTransformations=null]
+ */
+
+/**
+ * Returns a feature that this feature needs to register.
+ *
+ * In some cases, during activation, one feature may need to register
+ * another feature. For example a {@link CKEDITOR.ui.button} often registers
+ * a related command. See {@link CKEDITOR.ui.button#toFeature}.
+ *
+ * This method is executed when a feature is passed to the {@link CKEDITOR.editor#addFeature}.
+ *
+ * @method toFeature
+ * @returns {CKEDITOR.feature}
+ */
diff --git a/sources/core/focusmanager.js b/sources/core/focusmanager.js
new file mode 100644 (file)
index 0000000..6fc9969
--- /dev/null
@@ -0,0 +1,281 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.focusManager} class, which is used
+ *             to handle the focus in editor instances.
+ */
+
+( function() {
+       /**
+        * Manages the focus activity in an editor instance. This class is to be
+        * used mainly by UI element coders when adding interface elements that need
+        * to set the focus state of the editor.
+        *
+        *              var focusManager = new CKEDITOR.focusManager( editor );
+        *              focusManager.focus();
+        *
+        * @class
+        * @constructor Creates a focusManager class instance.
+        * @param {CKEDITOR.editor} editor The editor instance.
+        */
+       CKEDITOR.focusManager = function( editor ) {
+               if ( editor.focusManager )
+                       return editor.focusManager;
+
+               /**
+                * Indicates that the editor instance has focus.
+                *
+                *              alert( CKEDITOR.instances.editor1.focusManager.hasFocus ); // e.g. true
+                */
+               this.hasFocus = false;
+
+               /**
+                * Indicates the currently focused DOM element that makes the editor activated.
+                *
+                * @property {CKEDITOR.dom.domObject}
+                */
+               this.currentActive = null;
+
+               /**
+                * Object used to store private stuff.
+                *
+                * @private
+                */
+               this._ = {
+                       editor: editor
+               };
+
+               return this;
+       };
+
+       var SLOT_NAME = 'focusmanager',
+               SLOT_NAME_LISTENERS = 'focusmanager_handlers';
+
+       /**
+        * Object used to store private stuff.
+        *
+        * @private
+        * @class
+        * @singleton
+        */
+       CKEDITOR.focusManager._ = {
+               /**
+                * The delay (in milliseconds) to deactivate the editor when a UI DOM element has lost focus.
+                *
+                * @private
+                * @property {Number} [blurDelay=200]
+                * @member CKEDITOR.focusManager._
+                */
+               blurDelay: 200
+       };
+
+       CKEDITOR.focusManager.prototype = {
+
+               /**
+                * Indicates that this editor instance is activated (due to a DOM focus change).
+                * The `activated` state is a symbolic indicator of an active user
+                * interaction session.
+                *
+                * **Note:** This method will not introduce UI focus
+                * impact on DOM, it is here to record the editor UI focus state internally.
+                * If you want to make the cursor blink inside the editable, use
+                * {@link CKEDITOR.editor#method-focus} instead.
+                *
+                *              var editor = CKEDITOR.instances.editor1;
+                *              editor.focusManage.focus( editor.editable() );
+                *
+                * @param {CKEDITOR.dom.element} [currentActive] The new value of the {@link #currentActive} property.
+                * @member CKEDITOR.focusManager
+                */
+               focus: function( currentActive ) {
+                       if ( this._.timer )
+                               clearTimeout( this._.timer );
+
+                       if ( currentActive )
+                               this.currentActive = currentActive;
+
+                       if ( !( this.hasFocus || this._.locked ) ) {
+                               // If another editor has the current focus, we first "blur" it. In
+                               // this way the events happen in a more logical sequence, like:
+                               //              "focus 1" > "blur 1" > "focus 2"
+                               // ... instead of:
+                               //              "focus 1" > "focus 2" > "blur 1"
+                               var current = CKEDITOR.currentInstance;
+                               current && current.focusManager.blur( 1 );
+
+                               this.hasFocus = true;
+
+                               var ct = this._.editor.container;
+                               ct && ct.addClass( 'cke_focus' );
+                               this._.editor.fire( 'focus' );
+                       }
+               },
+
+               /**
+                * Prevents from changing the focus manager state until the next {@link #unlock} is called.
+                *
+                * @member CKEDITOR.focusManager
+                */
+               lock: function() {
+                       this._.locked = 1;
+               },
+
+               /**
+                * Restores the automatic focus management if {@link #lock} is called.
+                *
+                * @member CKEDITOR.focusManager
+                */
+               unlock: function() {
+                       delete this._.locked;
+               },
+
+               /**
+                * Used to indicate that the editor instance has been deactivated by the specified
+                * element which has just lost focus.
+                *
+                * **Note:** This function acts asynchronously with a delay of 100ms to
+                * avoid temporary deactivation. Use the `noDelay` parameter instead
+                * to deactivate immediately.
+                *
+                *              var editor = CKEDITOR.instances.editor1;
+                *              editor.focusManager.blur();
+                *
+                * @param {Boolean} [noDelay=false] Immediately deactivate the editor instance synchronously.
+                * @member CKEDITOR.focusManager
+                */
+               blur: function( noDelay ) {
+                       if ( this._.locked )
+                               return;
+
+                       function doBlur() {
+                               var editor = this._.editor;
+
+                               if ( this.hasFocus ) {
+                                       this.hasFocus = false;
+
+                                       // Blink browsers leave selection in `[contenteditable=true]`
+                                       // when it's blurred and it's neccessary to remove it manually for inline editor. (#13446)
+                                       if ( CKEDITOR.env.chrome && editor.editable().isInline() ) {
+                                               editor.window.$.getSelection().removeAllRanges();
+                                       }
+
+                                       var ct = this._.editor.container;
+                                       ct && ct.removeClass( 'cke_focus' );
+                                       this._.editor.fire( 'blur' );
+                               }
+                       }
+
+                       if ( this._.timer )
+                               clearTimeout( this._.timer );
+
+                       var delay = CKEDITOR.focusManager._.blurDelay;
+                       if ( noDelay || !delay )
+                               doBlur.call( this );
+                       else {
+                               this._.timer = CKEDITOR.tools.setTimeout( function() {
+                                       delete this._.timer;
+                                       doBlur.call( this );
+                               }, delay, this );
+                       }
+               },
+
+               /**
+                * Registers a UI DOM element to the focus manager, which will make the focus manager "hasFocus"
+                * once the input focus is relieved on the element.
+                * This method is designed to be used by plugins to expand the jurisdiction of the editor focus.
+                *
+                * @param {CKEDITOR.dom.element} element The container (topmost) element of one UI part.
+                * @param {Boolean} isCapture If specified, {@link CKEDITOR.event#useCapture} will be used when listening to the focus event.
+                * @member CKEDITOR.focusManager
+                */
+               add: function( element, isCapture ) {
+                       var fm = element.getCustomData( SLOT_NAME );
+                       if ( !fm || fm != this ) {
+                               // If this element is already taken by another instance, dismiss it first.
+                               fm && fm.remove( element );
+
+                               var focusEvent = 'focus',
+                                       blurEvent = 'blur';
+
+                               // Bypass the element's internal DOM focus change.
+                               if ( isCapture ) {
+
+                                       // Use "focusin/focusout" events instead of capture phase in IEs,
+                                       // which fires synchronously.
+                                       if ( CKEDITOR.env.ie ) {
+                                               focusEvent = 'focusin';
+                                               blurEvent = 'focusout';
+                                       } else {
+                                               CKEDITOR.event.useCapture = 1;
+                                       }
+                               }
+
+                               var listeners = {
+                                       blur: function() {
+                                               if ( element.equals( this.currentActive ) )
+                                                       this.blur();
+                                       },
+                                       focus: function() {
+                                               this.focus( element );
+                                       }
+                               };
+
+                               element.on( focusEvent, listeners.focus, this );
+                               element.on( blurEvent, listeners.blur, this );
+
+                               if ( isCapture )
+                                       CKEDITOR.event.useCapture = 0;
+
+                               element.setCustomData( SLOT_NAME, this );
+                               element.setCustomData( SLOT_NAME_LISTENERS, listeners );
+                       }
+               },
+
+               /**
+                * Dismisses an element from the focus manager delegations added by {@link #add}.
+                *
+                * @param {CKEDITOR.dom.element} element The element to be removed from the focus manager.
+                * @member CKEDITOR.focusManager
+                */
+               remove: function( element ) {
+                       element.removeCustomData( SLOT_NAME );
+                       var listeners = element.removeCustomData( SLOT_NAME_LISTENERS );
+                       element.removeListener( 'blur', listeners.blur );
+                       element.removeListener( 'focus', listeners.focus );
+               }
+
+       };
+
+} )();
+
+/**
+ * Fired when the editor instance receives the input focus.
+ *
+ *             editor.on( 'focus', function( e ) {
+ *                     alert( 'The editor named ' + e.editor.name + ' is now focused' );
+ *             } );
+ *
+ * @event focus
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+
+/**
+ * Fired when the editor instance loses the input focus.
+ *
+ * **Note:** This event will **NOT** be triggered when focus is moved internally, e.g. from
+ * an editable to another part of the editor UI like a dialog window.
+ * If you are interested only in the focus state of the editable, listen to the `focus`
+ * and `blur` events of the {@link CKEDITOR.editable} instead.
+ *
+ *             editor.on( 'blur', function( e ) {
+ *                     alert( 'The editor named ' + e.editor.name + ' lost the focus' );
+ *             } );
+ *
+ * @event blur
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
diff --git a/sources/core/htmldataprocessor.js b/sources/core/htmldataprocessor.js
new file mode 100644 (file)
index 0000000..56764be
--- /dev/null
@@ -0,0 +1,1036 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       /**
+        * Represents an HTML data processor, which is responsible for translating and
+        * transforming the editor data on input and output.
+        *
+        * @class
+        * @extends CKEDITOR.dataProcessor
+        * @constructor Creates an htmlDataProcessor class instance.
+        * @param {CKEDITOR.editor} editor
+        */
+       CKEDITOR.htmlDataProcessor = function( editor ) {
+               var dataFilter, htmlFilter,
+                       that = this;
+
+               this.editor = editor;
+
+               /**
+                * Data filter used when processing input by {@link #toHtml}.
+                *
+                * @property {CKEDITOR.htmlParser.filter}
+                */
+               this.dataFilter = dataFilter = new CKEDITOR.htmlParser.filter();
+
+               /**
+                * HTML filter used when processing output by {@link #toDataFormat}.
+                *
+                * @property {CKEDITOR.htmlParser.filter}
+                */
+               this.htmlFilter = htmlFilter = new CKEDITOR.htmlParser.filter();
+
+               /**
+                * The HTML writer used by this data processor to format the output.
+                *
+                * @property {CKEDITOR.htmlParser.basicWriter}
+                */
+               this.writer = new CKEDITOR.htmlParser.basicWriter();
+
+               dataFilter.addRules( defaultDataFilterRulesEditableOnly );
+               dataFilter.addRules( defaultDataFilterRulesForAll, { applyToAll: true } );
+               dataFilter.addRules( createBogusAndFillerRules( editor, 'data' ), { applyToAll: true } );
+               htmlFilter.addRules( defaultHtmlFilterRulesEditableOnly );
+               htmlFilter.addRules( defaultHtmlFilterRulesForAll, { applyToAll: true } );
+               htmlFilter.addRules( createBogusAndFillerRules( editor, 'html' ), { applyToAll: true } );
+
+               editor.on( 'toHtml', function( evt ) {
+                       var evtData = evt.data,
+                               data = evtData.dataValue,
+                               fixBodyTag;
+
+                       // The source data is already HTML, but we need to clean
+                       // it up and apply the filter.
+                       data = protectSource( data, editor );
+
+                       // Protect content of textareas. (#9995)
+                       // Do this before protecting attributes to avoid breaking:
+                       // <textarea><img src="..." /></textarea>
+                       data = protectElements( data, protectTextareaRegex );
+
+                       // Before anything, we must protect the URL attributes as the
+                       // browser may changing them when setting the innerHTML later in
+                       // the code.
+                       data = protectAttributes( data );
+
+                       // Protect elements than can't be set inside a DIV. E.g. IE removes
+                       // style tags from innerHTML. (#3710)
+                       data = protectElements( data, protectElementsRegex );
+
+                       // Certain elements has problem to go through DOM operation, protect
+                       // them by prefixing 'cke' namespace. (#3591)
+                       data = protectElementsNames( data );
+
+                       // All none-IE browsers ignore self-closed custom elements,
+                       // protecting them into open-close. (#3591)
+                       data = protectSelfClosingElements( data );
+
+                       // Compensate one leading line break after <pre> open as browsers
+                       // eat it up. (#5789)
+                       data = protectPreFormatted( data );
+
+                       // There are attributes which may execute JavaScript code inside fixBin.
+                       // Encode them greedily. They will be unprotected right after getting HTML from fixBin. (#10)
+                       data = protectInsecureAttributes( data );
+
+                       var fixBin = evtData.context || editor.editable().getName(),
+                               isPre;
+
+                       // Old IEs loose formats when load html into <pre>.
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 && fixBin == 'pre' ) {
+                               fixBin = 'div';
+                               data = '<pre>' + data + '</pre>';
+                               isPre = 1;
+                       }
+
+                       // Call the browser to help us fixing a possibly invalid HTML
+                       // structure.
+                       var el = editor.document.createElement( fixBin );
+                       // Add fake character to workaround IE comments bug. (#3801)
+                       el.setHtml( 'a' + data );
+                       data = el.getHtml().substr( 1 );
+
+                       // Restore shortly protected attribute names.
+                       data = data.replace( new RegExp( 'data-cke-' + CKEDITOR.rnd + '-', 'ig' ), '' );
+
+                       isPre && ( data = data.replace( /^<pre>|<\/pre>$/gi, '' ) );
+
+                       // Unprotect "some" of the protected elements at this point.
+                       data = unprotectElementNames( data );
+
+                       data = unprotectElements( data );
+
+                       // Restore the comments that have been protected, in this way they
+                       // can be properly filtered.
+                       data = unprotectRealComments( data );
+
+                       if ( evtData.fixForBody === false ) {
+                               fixBodyTag = false;
+                       } else {
+                               fixBodyTag = getFixBodyTag( evtData.enterMode, editor.config.autoParagraph );
+                       }
+
+                       // Now use our parser to make further fixes to the structure, as
+                       // well as apply the filter.
+                       data = CKEDITOR.htmlParser.fragment.fromHtml( data, evtData.context, fixBodyTag );
+
+                       // The empty root element needs to be fixed by adding 'p' or 'div' into it.
+                       // This avoids the need to create that element on the first focus (#12630).
+                       if ( fixBodyTag ) {
+                               fixEmptyRoot( data, fixBodyTag );
+                       }
+
+                       evtData.dataValue = data;
+               }, null, null, 5 );
+
+               // Filter incoming "data".
+               // Add element filter before htmlDataProcessor.dataFilter when purifying input data to correct html.
+               editor.on( 'toHtml', function( evt ) {
+                       if ( evt.data.filter.applyTo( evt.data.dataValue, true, evt.data.dontFilter, evt.data.enterMode ) )
+                               editor.fire( 'dataFiltered' );
+               }, null, null, 6 );
+
+               editor.on( 'toHtml', function( evt ) {
+                       evt.data.dataValue.filterChildren( that.dataFilter, true );
+               }, null, null, 10 );
+
+               editor.on( 'toHtml', function( evt ) {
+                       var evtData = evt.data,
+                               data = evtData.dataValue,
+                               writer = new CKEDITOR.htmlParser.basicWriter();
+
+                       data.writeChildrenHtml( writer );
+                       data = writer.getHtml( true );
+
+                       // Protect the real comments again.
+                       evtData.dataValue = protectRealComments( data );
+               }, null, null, 15 );
+
+
+               editor.on( 'toDataFormat', function( evt ) {
+                       var data = evt.data.dataValue;
+
+                       // #10854 - we need to strip leading blockless <br> which FF adds
+                       // automatically when editable contains only non-editable content.
+                       // We do that for every browser (so it's a constant behavior) and
+                       // not in BR mode, in which chance of valid leading blockless <br> is higher.
+                       if ( evt.data.enterMode != CKEDITOR.ENTER_BR )
+                               data = data.replace( /^<br *\/?>/i, '' );
+
+                       evt.data.dataValue = CKEDITOR.htmlParser.fragment.fromHtml(
+                               data, evt.data.context, getFixBodyTag( evt.data.enterMode, editor.config.autoParagraph ) );
+               }, null, null, 5 );
+
+               editor.on( 'toDataFormat', function( evt ) {
+                       evt.data.dataValue.filterChildren( that.htmlFilter, true );
+               }, null, null, 10 );
+
+               // Transform outcoming "data".
+               // Add element filter after htmlDataProcessor.htmlFilter when preparing output data HTML.
+               editor.on( 'toDataFormat', function( evt ) {
+                       evt.data.filter.applyTo( evt.data.dataValue, false, true );
+               }, null, null, 11 );
+
+               editor.on( 'toDataFormat', function( evt ) {
+                       var data = evt.data.dataValue,
+                               writer = that.writer;
+
+                       writer.reset();
+                       data.writeChildrenHtml( writer );
+                       data = writer.getHtml( true );
+
+                       // Restore those non-HTML protected source. (#4475,#4880)
+                       data = unprotectRealComments( data );
+                       data = unprotectSource( data, editor );
+
+                       evt.data.dataValue = data;
+               }, null, null, 15 );
+       };
+
+       CKEDITOR.htmlDataProcessor.prototype = {
+               /**
+                * Processes the (potentially malformed) input HTML to a purified form which
+                * is suitable for using in the WYSIWYG editable.
+                *
+                * This method fires the {@link CKEDITOR.editor#toHtml} event which makes it possible
+                * to hook into the process at various stages.
+                *
+                * **Note:** Since CKEditor 4.3 the signature of this method changed and all options
+                * are now grouped in one `options` object. Previously `context`, `fixForBody` and `dontFilter`
+                * were passed separately.
+                *
+                * @param {String} data The raw data.
+                * @param {Object} [options] The options object.
+                * @param {String} [options.context] The tag name of a context element within which
+                * the input is to be processed, defaults to the editable element.
+                * If `null` is passed, then data will be parsed without context (as children of {@link CKEDITOR.htmlParser.fragment}).
+                * See {@link CKEDITOR.htmlParser.fragment#fromHtml} for more details.
+                * @param {Boolean} [options.fixForBody=true] Whether to trigger the auto paragraph for non-block content.
+                * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter},
+                * the passed instance will be used to filter the content.
+                * @param {Boolean} [options.dontFilter] Do not filter data with {@link CKEDITOR.filter} (note: transformations
+                * will still be applied).
+                * @param {Number} [options.enterMode] When specified, it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}.
+                * @param {Boolean} [options.protectedWhitespaces] Indicates that content was wrapped with `<span>` elements to preserve
+                * leading and trailing whitespaces. Option used by the {@link CKEDITOR.editor#method-insertHtml} method.
+                * @returns {String}
+                */
+               toHtml: function( data, options, fixForBody, dontFilter ) {
+                       var editor = this.editor,
+                               context, filter, enterMode, protectedWhitespaces;
+
+                       // Typeof null == 'object', so check truthiness of options too.
+                       if ( options && typeof options == 'object' ) {
+                               context = options.context;
+                               fixForBody = options.fixForBody;
+                               dontFilter = options.dontFilter;
+                               filter = options.filter;
+                               enterMode = options.enterMode;
+                               protectedWhitespaces = options.protectedWhitespaces;
+                       }
+                       // Backward compatibility. Since CKEDITOR 4.3 every option was a separate argument.
+                       else {
+                               context = options;
+                       }
+
+                       // Fall back to the editable as context if not specified.
+                       if ( !context && context !== null )
+                               context = editor.editable().getName();
+
+                       return editor.fire( 'toHtml', {
+                               dataValue: data,
+                               context: context,
+                               fixForBody: fixForBody,
+                               dontFilter: dontFilter,
+                               filter: filter || editor.filter,
+                               enterMode: enterMode || editor.enterMode,
+                               protectedWhitespaces: protectedWhitespaces
+                       } ).dataValue;
+               },
+
+               /**
+                * See {@link CKEDITOR.dataProcessor#toDataFormat}.
+                *
+                * This method fires the {@link CKEDITOR.editor#toDataFormat} event which makes it possible
+                * to hook into the process at various stages.
+                *
+                * @param {String} html
+                * @param {Object} [options] The options object.
+                * @param {String} [options.context] The tag name of the context element within which
+                * the input is to be processed, defaults to the editable element.
+                * @param {CKEDITOR.filter} [options.filter] When specified, instead of using the {@link CKEDITOR.editor#filter main filter},
+                * the passed instance will be used to apply content transformations to the content.
+                * @param {Number} [options.enterMode] When specified, it will be used instead of the {@link CKEDITOR.editor#enterMode main enterMode}.
+                * @returns {String}
+                */
+               toDataFormat: function( html, options ) {
+                       var context, filter, enterMode;
+
+                       // Do not shorten this to `options && options.xxx`, because
+                       // falsy `options` will be passed instead of undefined.
+                       if ( options ) {
+                               context = options.context;
+                               filter = options.filter;
+                               enterMode = options.enterMode;
+                       }
+
+                       // Fall back to the editable as context if not specified.
+                       if ( !context && context !== null )
+                               context = this.editor.editable().getName();
+
+                       return this.editor.fire( 'toDataFormat', {
+                               dataValue: html,
+                               filter: filter || this.editor.filter,
+                               context: context,
+                               enterMode: enterMode || this.editor.enterMode
+                       } ).dataValue;
+               }
+       };
+
+       // Produce a set of filtering rules that handles bogus and filler node at the
+       // end of block/pseudo block, in the following consequence:
+       // 1. elements:<block> - this filter removes any bogus node, then check
+       // if it's an empty block that requires a filler.
+       // 2. elements:<br> - After cleaned with bogus, this filter checks the real
+       // line-break BR to compensate a filler after it.
+       //
+       // Terms definitions:
+       // filler: An element that's either <BR> or &NBSP; at the end of block that established line height.
+       // bogus: Whenever a filler is proceeded with inline content, it becomes a bogus which is subjected to be removed.
+       //
+       // Various forms of the filler:
+       // In output HTML: Filler should be consistently &NBSP; <BR> at the end of block is always considered as bogus.
+       // In Wysiwyg HTML: Browser dependent - see env.needsBrFiller. Either BR for when needsBrFiller is true, or &NBSP; otherwise.
+       // <BR> is NEVER considered as bogus when needsBrFiller is true.
+       function createBogusAndFillerRules( editor, type ) {
+               function createFiller( isOutput ) {
+                       return isOutput || CKEDITOR.env.needsNbspFiller ?
+                               new CKEDITOR.htmlParser.text( '\xa0' ) :
+                               new CKEDITOR.htmlParser.element( 'br', { 'data-cke-bogus': 1 } );
+               }
+
+               // This text block filter, remove any bogus and create the filler on demand.
+               function blockFilter( isOutput, fillEmptyBlock ) {
+
+                       return function( block ) {
+                               // DO NOT apply the filler if it's a fragment node.
+                               if ( block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
+                                       return;
+
+                               cleanBogus( block );
+
+                               // Add fillers to input (always) and to output (if fillEmptyBlock is ok with that).
+                               var shouldFillBlock = !isOutput ||
+                                       ( typeof fillEmptyBlock == 'function' ? fillEmptyBlock( block ) : fillEmptyBlock ) !== false;
+
+                               if ( shouldFillBlock && isEmptyBlockNeedFiller( block ) ) {
+                                       block.add( createFiller( isOutput ) );
+                               }
+                       };
+               }
+
+               // Append a filler right after the last line-break BR, found at the end of block.
+               function brFilter( isOutput ) {
+                       return function( br ) {
+                               // DO NOT apply the filer if parent's a fragment node.
+                               if ( br.parent.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
+                                       return;
+
+                               var attrs = br.attributes;
+                               // Dismiss BRs that are either bogus or eol marker.
+                               if ( 'data-cke-bogus' in attrs || 'data-cke-eol' in attrs ) {
+                                       delete attrs [ 'data-cke-bogus' ];
+                                       return;
+                               }
+
+                               // Judge the tail line-break BR, and to insert bogus after it.
+                               var next = getNext( br ), previous = getPrevious( br );
+
+                               if ( !next && isBlockBoundary( br.parent ) )
+                                       append( br.parent, createFiller( isOutput ) );
+                               else if ( isBlockBoundary( next ) && previous && !isBlockBoundary( previous ) )
+                                       createFiller( isOutput ).insertBefore( next );
+                       };
+               }
+
+               // Determinate whether this node is potentially a bogus node.
+               function maybeBogus( node, atBlockEnd ) {
+
+                       // BR that's not from IE<11 DOM, except for a EOL marker.
+                       if ( !( isOutput && !CKEDITOR.env.needsBrFiller ) &&
+                                       node.type == CKEDITOR.NODE_ELEMENT && node.name == 'br' &&
+                                       !node.attributes[ 'data-cke-eol' ] ) {
+                               return true;
+                       }
+
+                       var match;
+
+                       // NBSP, possibly.
+                       if ( node.type == CKEDITOR.NODE_TEXT && ( match = node.value.match( tailNbspRegex ) ) ) {
+                               // We need to separate tail NBSP out of a text node, for later removal.
+                               if ( match.index ) {
+                                       ( new CKEDITOR.htmlParser.text( node.value.substring( 0, match.index ) ) ).insertBefore( node );
+                                       node.value = match[ 0 ];
+                               }
+
+                               // From IE<11 DOM, at the end of a text block, or before block boundary.
+                               if ( !CKEDITOR.env.needsBrFiller && isOutput && ( !atBlockEnd || node.parent.name in textBlockTags ) )
+                                       return true;
+
+                               // From the output.
+                               if ( !isOutput ) {
+                                       var previous = node.previous;
+
+                                       // Following a line-break at the end of block.
+                                       if ( previous && previous.name == 'br' )
+                                               return true;
+
+                                       // Or a single NBSP between two blocks.
+                                       if ( !previous || isBlockBoundary( previous ) )
+                                               return true;
+                               }
+                       }
+
+                       return false;
+               }
+
+               // Removes all bogus inside of this block, and to convert fillers into the proper form.
+               function cleanBogus( block ) {
+                       var bogus = [];
+                       var last = getLast( block ), node, previous;
+
+                       if ( last ) {
+                               // Check for bogus at the end of this block.
+                               // e.g. <p>foo<br /></p>
+                               maybeBogus( last, 1 ) && bogus.push( last );
+
+                               while ( last ) {
+                                       // Check for bogus at the end of any pseudo block contained.
+                                       if ( isBlockBoundary( last ) && ( node = getPrevious( last ) ) && maybeBogus( node ) ) {
+                                               // Bogus must have inline proceeding, instead single BR between two blocks,
+                                               // is considered as filler, e.g. <hr /><br /><hr />
+                                               if ( ( previous = getPrevious( node ) ) && !isBlockBoundary( previous ) )
+                                                       bogus.push( node );
+                                               // Convert the filler into appropriate form.
+                                               else {
+                                                       createFiller( isOutput ).insertAfter( node );
+                                                       node.remove();
+                                               }
+                                       }
+
+                                       last = last.previous;
+                               }
+                       }
+
+                       // Now remove all bogus collected from above.
+                       for ( var i = 0 ; i < bogus.length ; i++ )
+                               bogus[ i ].remove();
+               }
+
+               // Judge whether it's an empty block that requires a filler node.
+               function isEmptyBlockNeedFiller( block ) {
+
+                       // DO NOT fill empty editable in IE<11.
+                       if ( !isOutput && !CKEDITOR.env.needsBrFiller && block.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT )
+                               return false;
+
+                       // 1. For IE version >=8,  empty blocks are displayed correctly themself in wysiwiyg;
+                       // 2. For the rest, at least table cell and list item need no filler space. (#6248)
+                       if ( !isOutput && !CKEDITOR.env.needsBrFiller &&
+                               ( document.documentMode > 7 ||
+                                       block.name in CKEDITOR.dtd.tr ||
+                                       block.name in CKEDITOR.dtd.$listItem ) ) {
+                               return false;
+                       }
+
+                       var last = getLast( block );
+                       return !last || block.name == 'form' && last.name == 'input' ;
+               }
+
+               var rules = { elements: {} },
+                       isOutput = type == 'html',
+                       textBlockTags = CKEDITOR.tools.extend( {}, blockLikeTags );
+
+               // Build the list of text blocks.
+               for ( var i in textBlockTags ) {
+                       if ( !( '#' in dtd[ i ] ) )
+                               delete textBlockTags[ i ];
+               }
+
+               for ( i in textBlockTags )
+                       rules.elements[ i ] = blockFilter( isOutput, editor.config.fillEmptyBlocks );
+
+               // Editable element has to be checked separately.
+               rules.root = blockFilter( isOutput, false );
+               rules.elements.br = brFilter( isOutput );
+               return rules;
+       }
+
+       function getFixBodyTag( enterMode, autoParagraph ) {
+               return ( enterMode != CKEDITOR.ENTER_BR && autoParagraph !== false ) ? enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'p' : false;
+       }
+
+       // Regex to scan for &nbsp; at the end of blocks, which are actually placeholders.
+       // Safari transforms the &nbsp; to \xa0. (#4172)
+       var tailNbspRegex = /(?:&nbsp;|\xa0)$/;
+
+       var protectedSourceMarker = '{cke_protected}';
+
+       function getLast( node ) {
+               var last = node.children[ node.children.length - 1 ];
+               while ( last && isEmpty( last ) )
+                       last = last.previous;
+               return last;
+       }
+
+       function getNext( node ) {
+               var next = node.next;
+               while ( next && isEmpty( next ) )
+                       next = next.next;
+               return next;
+       }
+
+       function getPrevious( node ) {
+               var previous = node.previous;
+               while ( previous && isEmpty( previous ) )
+                       previous = previous.previous;
+               return previous;
+       }
+
+       // Judge whether the node is an ghost node to be ignored, when traversing.
+       function isEmpty( node ) {
+               return node.type == CKEDITOR.NODE_TEXT &&
+                       !CKEDITOR.tools.trim( node.value ) ||
+                       node.type == CKEDITOR.NODE_ELEMENT &&
+                       node.attributes[ 'data-cke-bookmark' ];
+       }
+
+       // Judge whether the node is a block-like element.
+       function isBlockBoundary( node ) {
+               return node &&
+                       ( node.type == CKEDITOR.NODE_ELEMENT && node.name in blockLikeTags ||
+                       node.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT );
+       }
+
+       function append( parent, node ) {
+               var last = parent.children[ parent.children.length - 1 ];
+               parent.children.push( node );
+               node.parent = parent;
+               if ( last ) {
+                       last.next = node;
+                       node.previous = last;
+               }
+       }
+
+       function getNodeIndex( node ) {
+               return node.parent ? node.getIndex() : -1;
+       }
+
+       var dtd = CKEDITOR.dtd,
+               // Define orders of table elements.
+               tableOrder = [ 'caption', 'colgroup', 'col', 'thead', 'tfoot', 'tbody' ],
+               // List of all block elements.
+               blockLikeTags = CKEDITOR.tools.extend( {}, dtd.$blockLimit, dtd.$block );
+
+       //
+       // DATA filter rules ------------------------------------------------------
+       //
+
+       var defaultDataFilterRulesEditableOnly = {
+               elements: {
+                       input: protectReadOnly,
+                       textarea: protectReadOnly
+               }
+       };
+
+       // These rules will also be applied to non-editable content.
+       var defaultDataFilterRulesForAll = {
+               attributeNames: [
+                       // Event attributes (onXYZ) must not be directly set. They can become
+                       // active in the editing area (IE|WebKit).
+                       [ ( /^on/ ), 'data-cke-pa-on' ],
+
+                       // Don't let some old expando enter editor. Concerns only IE8,
+                       // but for consistency remove on all browsers.
+                       [ ( /^data-cke-expando$/ ), '' ]
+               ]
+       };
+
+       // Disable form elements editing mode provided by some browsers. (#5746)
+       function protectReadOnly( element ) {
+               var attrs = element.attributes;
+
+               // We should flag that the element was locked by our code so
+               // it'll be editable by the editor functions (#6046).
+               if ( attrs.contenteditable != 'false' )
+                       attrs[ 'data-cke-editable' ] = attrs.contenteditable ? 'true' : 1;
+
+               attrs.contenteditable = 'false';
+       }
+
+       //
+       // HTML filter rules ------------------------------------------------------
+       //
+
+       var defaultHtmlFilterRulesEditableOnly = {
+               elements: {
+                       embed: function( element ) {
+                               var parent = element.parent;
+
+                               // If the <embed> is child of a <object>, copy the width
+                               // and height attributes from it.
+                               if ( parent && parent.name == 'object' ) {
+                                       var parentWidth = parent.attributes.width,
+                                               parentHeight = parent.attributes.height;
+                                       if ( parentWidth )
+                                               element.attributes.width = parentWidth;
+                                       if ( parentHeight )
+                                               element.attributes.height = parentHeight;
+                               }
+                       },
+
+                       // Remove empty link but not empty anchor. (#3829, #13516)
+                       a: function( element ) {
+                               var attrs = element.attributes;
+
+                               if ( !( element.children.length || attrs.name || attrs.id || element.attributes[ 'data-cke-saved-name' ] ) )
+                                       return false;
+                       }
+               }
+       };
+
+       // These rules will also be applied to non-editable content.
+       var defaultHtmlFilterRulesForAll = {
+               elementNames: [
+                       // Remove the "cke:" namespace prefix.
+                       [ ( /^cke:/ ), '' ],
+
+                       // Ignore <?xml:namespace> tags.
+                       [ ( /^\?xml:namespace$/ ), '' ]
+               ],
+
+               attributeNames: [
+                       // Attributes saved for changes and protected attributes.
+                       [ ( /^data-cke-(saved|pa)-/ ), '' ],
+
+                       // All "data-cke-" attributes are to be ignored.
+                       [ ( /^data-cke-.*/ ), '' ],
+
+                       [ 'hidefocus', '' ]
+               ],
+
+               elements: {
+                       $: function( element ) {
+                               var attribs = element.attributes;
+
+                               if ( attribs ) {
+                                       // Elements marked as temporary are to be ignored.
+                                       if ( attribs[ 'data-cke-temp' ] )
+                                               return false;
+
+                                       // Remove duplicated attributes - #3789.
+                                       var attributeNames = [ 'name', 'href', 'src' ],
+                                               savedAttributeName;
+                                       for ( var i = 0; i < attributeNames.length; i++ ) {
+                                               savedAttributeName = 'data-cke-saved-' + attributeNames[ i ];
+                                               savedAttributeName in attribs && ( delete attribs[ attributeNames[ i ] ] );
+                                       }
+                               }
+
+                               return element;
+                       },
+
+                       // The contents of table should be in correct order (#4809).
+                       table: function( element ) {
+                               // Clone the array as it would become empty during the sort call.
+                               var children = element.children.slice( 0 );
+
+                               children.sort( function( node1, node2 ) {
+                                       var index1, index2;
+
+                                       // Compare in the predefined order.
+                                       if ( node1.type == CKEDITOR.NODE_ELEMENT && node2.type == node1.type ) {
+                                               index1 = CKEDITOR.tools.indexOf( tableOrder, node1.name );
+                                               index2 = CKEDITOR.tools.indexOf( tableOrder, node2.name );
+                                       }
+
+                                       // Make sure the sort is stable, if no order can be established above.
+                                       if ( !( index1 > -1 && index2 > -1 && index1 != index2 ) ) {
+                                               index1 = getNodeIndex( node1 );
+                                               index2 = getNodeIndex( node2 );
+                                       }
+
+                                       return index1 > index2 ? 1 : -1;
+                               } );
+                       },
+
+                       // Restore param elements into self-closing.
+                       param: function( param ) {
+                               param.children = [];
+                               param.isEmpty = true;
+                               return param;
+                       },
+
+                       // Remove dummy span in webkit.
+                       span: function( element ) {
+                               if ( element.attributes[ 'class' ] == 'Apple-style-span' )
+                                       delete element.name;
+                       },
+
+                       html: function( element ) {
+                               delete element.attributes.contenteditable;
+                               delete element.attributes[ 'class' ];
+                       },
+
+                       body: function( element ) {
+                               delete element.attributes.spellcheck;
+                               delete element.attributes.contenteditable;
+                       },
+
+                       style: function( element ) {
+                               var child = element.children[ 0 ];
+                               if ( child && child.value )
+                                       child.value = CKEDITOR.tools.trim( child.value );
+
+                               if ( !element.attributes.type )
+                                       element.attributes.type = 'text/css';
+                       },
+
+                       title: function( element ) {
+                               var titleText = element.children[ 0 ];
+
+                               // Append text-node to title tag if not present (i.e. non-IEs) (#9882).
+                               !titleText && append( element, titleText = new CKEDITOR.htmlParser.text() );
+
+                               // Transfer data-saved title to title tag.
+                               titleText.value = element.attributes[ 'data-cke-title' ] || '';
+                       },
+
+                       input: unprotectReadyOnly,
+                       textarea: unprotectReadyOnly
+               },
+
+               attributes: {
+                       'class': function( value ) {
+                               // Remove all class names starting with "cke_".
+                               return CKEDITOR.tools.ltrim( value.replace( /(?:^|\s+)cke_[^\s]*/g, '' ) ) || false;
+                       }
+               }
+       };
+
+       if ( CKEDITOR.env.ie ) {
+               // IE outputs style attribute in capital letters. We should convert
+               // them back to lower case, while not hurting the values (#5930)
+               defaultHtmlFilterRulesForAll.attributes.style = function( value ) {
+                       return value.replace( /(^|;)([^\:]+)/g, function( match ) {
+                               return match.toLowerCase();
+                       } );
+               };
+       }
+
+       // Disable form elements editing mode provided by some browsers. (#5746)
+       function unprotectReadyOnly( element ) {
+               var attrs = element.attributes;
+               switch ( attrs[ 'data-cke-editable' ] ) {
+                       case 'true':
+                               attrs.contenteditable = 'true';
+                               break;
+                       case '1':
+                               delete attrs.contenteditable;
+                               break;
+               }
+       }
+
+       //
+       // Preprocessor filters ---------------------------------------------------
+       //
+
+       var protectElementRegex = /<(a|area|img|input|source)\b([^>]*)>/gi,
+               // Be greedy while looking for protected attributes. This will let us avoid an unfortunate
+               // situation when "nested attributes", which may appear valid, are also protected.
+               // I.e. if we consider the following HTML:
+               //
+               //      <img data-x="&lt;a href=&quot;X&quot;" />
+               //
+               // then the "non-greedy match" returns:
+               //
+               //      'href' => '&quot;X&quot;' // It's wrong! Href is not an attribute of <img>.
+               //
+               // while greedy match returns:
+               //
+               //      'data-x' => '&lt;a href=&quot;X&quot;'
+               //
+               // which, can be easily filtered out (#11508).
+               protectAttributeRegex = /([\w-:]+)\s*=\s*(?:(?:"[^"]*")|(?:'[^']*')|(?:[^ "'>]+))/gi,
+               protectAttributeNameRegex = /^(href|src|name)$/i;
+
+               // Note: we use lazy star '*?' to prevent eating everything up to the last occurrence of </style> or </textarea>.
+       var protectElementsRegex = /(?:<style(?=[ >])[^>]*>[\s\S]*?<\/style>)|(?:<(:?link|meta|base)[^>]*>)/gi,
+               protectTextareaRegex = /(<textarea(?=[ >])[^>]*>)([\s\S]*?)(?:<\/textarea>)/gi,
+               encodedElementsRegex = /<cke:encoded>([^<]*)<\/cke:encoded>/gi;
+
+       var protectElementNamesRegex = /(<\/?)((?:object|embed|param|html|body|head|title)[^>]*>)/gi,
+               unprotectElementNamesRegex = /(<\/?)cke:((?:html|body|head|title)[^>]*>)/gi;
+
+       var protectSelfClosingRegex = /<cke:(param|embed)([^>]*?)\/?>(?!\s*<\/cke:\1)/gi;
+
+       function protectAttributes( html ) {
+               return html.replace( protectElementRegex, function( element, tag, attributes ) {
+                       return '<' + tag + attributes.replace( protectAttributeRegex, function( fullAttr, attrName ) {
+                               // Avoid corrupting the inline event attributes (#7243).
+                               // We should not rewrite the existed protected attributes, e.g. clipboard content from editor. (#5218)
+                               if ( protectAttributeNameRegex.test( attrName ) && attributes.indexOf( 'data-cke-saved-' + attrName ) == -1 )
+                                       return ' data-cke-saved-' + fullAttr + ' data-cke-' + CKEDITOR.rnd + '-' + fullAttr;
+
+                               return fullAttr;
+                       } ) + '>';
+               } );
+       }
+
+       function protectElements( html, regex ) {
+               return html.replace( regex, function( match, tag, content ) {
+                       // Encode < and > in textarea because this won't be done by a browser, since
+                       // textarea will be protected during passing data through fix bin.
+                       if ( match.indexOf( '<textarea' ) === 0 )
+                               match = tag + unprotectRealComments( content ).replace( /</g, '&lt;' ).replace( />/g, '&gt;' ) + '</textarea>';
+
+                       return '<cke:encoded>' + encodeURIComponent( match ) + '</cke:encoded>';
+               } );
+       }
+
+       function unprotectElements( html ) {
+               return html.replace( encodedElementsRegex, function( match, encoded ) {
+                       return decodeURIComponent( encoded );
+               } );
+       }
+
+       function protectElementsNames( html ) {
+               return html.replace( protectElementNamesRegex, '$1cke:$2' );
+       }
+
+       function unprotectElementNames( html ) {
+               return html.replace( unprotectElementNamesRegex, '$1$2' );
+       }
+
+       function protectSelfClosingElements( html ) {
+               return html.replace( protectSelfClosingRegex, '<cke:$1$2></cke:$1>' );
+       }
+
+       function protectPreFormatted( html ) {
+               return html.replace( /(<pre\b[^>]*>)(\r\n|\n)/g, '$1$2$2' );
+       }
+
+       function protectRealComments( html ) {
+               return html.replace( /<!--(?!{cke_protected})[\s\S]+?-->/g, function( match ) {
+                       return '<!--' + protectedSourceMarker +
+                               '{C}' +
+                               encodeURIComponent( match ).replace( /--/g, '%2D%2D' ) +
+                               '-->';
+               } );
+       }
+
+       // Replace all "on\w{3,}" strings which are not:
+       // * opening tags - e.g. `<onfoo`,
+       // * closing tags - e.g. </onfoo> (tested in "false positive 1"),
+       // * part of other attribute - e.g. `data-onfoo` or `fonfoo`.
+       function protectInsecureAttributes( html ) {
+               return html.replace( /([^a-z0-9<\-])(on\w{3,})(?!>)/gi, '$1data-cke-' + CKEDITOR.rnd + '-$2' );
+       }
+
+       function unprotectRealComments( html ) {
+               return html.replace( /<!--\{cke_protected\}\{C\}([\s\S]+?)-->/g, function( match, data ) {
+                       return decodeURIComponent( data );
+               } );
+       }
+
+       function unprotectSource( html, editor ) {
+               var store = editor._.dataStore;
+
+               return html.replace( /<!--\{cke_protected\}([\s\S]+?)-->/g, function( match, data ) {
+                       return decodeURIComponent( data );
+               } ).replace( /\{cke_protected_(\d+)\}/g, function( match, id ) {
+                       return store && store[ id ] || '';
+               } );
+       }
+
+       function protectSource( data, editor ) {
+               var protectedHtml = [],
+                       protectRegexes = editor.config.protectedSource,
+                       store = editor._.dataStore || ( editor._.dataStore = { id: 1 } ),
+                       tempRegex = /<\!--\{cke_temp(comment)?\}(\d*?)-->/g;
+
+               var regexes = [
+                       // Script tags will also be forced to be protected, otherwise
+                       // IE will execute them.
+                       ( /<script[\s\S]*?(<\/script>|$)/gi ),
+
+                       // <noscript> tags (get lost in IE and messed up in FF).
+                       /<noscript[\s\S]*?<\/noscript>/gi,
+
+                       // Avoid meta tags being stripped (#8117).
+                       /<meta[\s\S]*?\/?>/gi
+               ].concat( protectRegexes );
+
+               // First of any other protection, we must protect all comments
+               // to avoid loosing them (of course, IE related).
+               // Note that we use a different tag for comments, as we need to
+               // transform them when applying filters.
+               data = data.replace( ( /<!--[\s\S]*?-->/g ), function( match ) {
+                       return '<!--{cke_tempcomment}' + ( protectedHtml.push( match ) - 1 ) + '-->';
+               } );
+
+               for ( var i = 0; i < regexes.length; i++ ) {
+                       data = data.replace( regexes[ i ], function( match ) {
+                               match = match.replace( tempRegex, // There could be protected source inside another one. (#3869).
+                               function( $, isComment, id ) {
+                                       return protectedHtml[ id ];
+                               } );
+
+                               // Avoid protecting over protected, e.g. /\{.*?\}/
+                               return ( /cke_temp(comment)?/ ).test( match ) ? match : '<!--{cke_temp}' + ( protectedHtml.push( match ) - 1 ) + '-->';
+                       } );
+               }
+               data = data.replace( tempRegex, function( $, isComment, id ) {
+                       return '<!--' + protectedSourceMarker +
+                               ( isComment ? '{C}' : '' ) +
+                               encodeURIComponent( protectedHtml[ id ] ).replace( /--/g, '%2D%2D' ) +
+                               '-->';
+               } );
+
+               // Different protection pattern is used for those that
+               // live in attributes to avoid from being HTML encoded.
+               // Why so serious? See #9205, #8216, #7805, #11754, #11846.
+               data = data.replace( /<\w+(?:\s+(?:(?:[^\s=>]+\s*=\s*(?:[^'"\s>]+|'[^']*'|"[^"]*"))|[^\s=\/>]+))+\s*\/?>/g, function( match ) {
+                       return match.replace( /<!--\{cke_protected\}([^>]*)-->/g, function( match, data ) {
+                               store[ store.id ] = decodeURIComponent( data );
+                               return '{cke_protected_' + ( store.id++ ) + '}';
+                       } );
+               } );
+
+               // This RegExp searches for innerText in all the title/iframe/textarea elements.
+               // This is because browser doesn't allow HTML in these elements, that's why we can't
+               // nest comments in there. (#11223)
+               data = data.replace( /<(title|iframe|textarea)([^>]*)>([\s\S]*?)<\/\1>/g, function( match, tagName, tagAttributes, innerText ) {
+                       return '<' + tagName + tagAttributes + '>' + unprotectSource( unprotectRealComments( innerText ), editor ) + '</' + tagName + '>';
+               } );
+
+               return data;
+       }
+
+       // Creates a block if the root element is empty.
+       function fixEmptyRoot( root, fixBodyTag ) {
+               if ( !root.children.length && CKEDITOR.dtd[ root.name ][ fixBodyTag ] ) {
+                       var fixBodyElement = new CKEDITOR.htmlParser.element( fixBodyTag );
+                       root.add( fixBodyElement );
+               }
+       }
+} )();
+
+/**
+ * Whether a filler text (non-breaking space entity &mdash; `&nbsp;`) will be
+ * inserted into empty block elements in HTML output.
+ * This is used to render block elements properly with `line-height`.
+ * When a function is specified instead, it will be passed a {@link CKEDITOR.htmlParser.element}
+ * to decide whether adding the filler text by expecting a Boolean return value.
+ *
+ *             config.fillEmptyBlocks = false; // Prevent filler nodes in all empty blocks.
+ *
+ *             // Prevent filler node only in float cleaners.
+ *             config.fillEmptyBlocks = function( element ) {
+ *                     if ( element.attributes[ 'class' ].indexOf( 'clear-both' ) != -1 )
+ *                             return false;
+ *             };
+ *
+ * @since 3.5
+ * @cfg {Boolean/Function} [fillEmptyBlocks=true]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * This event is fired by the {@link CKEDITOR.htmlDataProcessor} when input HTML
+ * is to be purified by the {@link CKEDITOR.htmlDataProcessor#toHtml} method.
+ *
+ * By adding listeners with different priorities it is possible
+ * to process input HTML on different stages:
+ *
+ *     * 1-4: Data is available in the original string format.
+ *     * 5: Data is initially filtered with regexp patterns and parsed to
+ *             {@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
+ *     * 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#dataFilter}
+ *             is not applied yet.
+ *     * 6: Data is filtered with the {CKEDITOR.filter content filter}.
+ *     * 10: Data is processed with {@link CKEDITOR.htmlDataProcessor#dataFilter}.
+ *     * 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#dataFilter}
+ *             has already been applied.
+ *     * 15: Data is written back to an HTML string.
+ *     * 15-*: Data is available in an HTML string.
+ *
+ * For example to be able to process parsed, but not yet filtered data add listener this way:
+ *
+ *             editor.on( 'toHtml', function( evt) {
+ *                     evt.data.dataValue; // -> CKEDITOR.htmlParser.fragment instance
+ *             }, null, null, 7 );
+ *
+ * @since 4.1
+ * @event toHtml
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String/CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} data.dataValue Input data to be purified.
+ * @param {String} data.context See {@link CKEDITOR.htmlDataProcessor#toHtml} The `context` argument.
+ * @param {Boolean} data.fixForBody See {@link CKEDITOR.htmlDataProcessor#toHtml} The `fixForBody` argument.
+ * @param {Boolean} data.dontFilter See {@link CKEDITOR.htmlDataProcessor#toHtml} The `dontFilter` argument.
+ * @param {Boolean} data.filter See {@link CKEDITOR.htmlDataProcessor#toHtml} The `filter` argument.
+ * @param {Boolean} data.enterMode See {@link CKEDITOR.htmlDataProcessor#toHtml} The `enterMode` argument.
+ * @param {Boolean} [data.protectedWhitespaces] See {@link CKEDITOR.htmlDataProcessor#toHtml} The `protectedWhitespaces` argument.
+ */
+
+/**
+ * This event is fired when {@link CKEDITOR.htmlDataProcessor} is converting
+ * internal HTML to output data HTML.
+ *
+ * By adding listeners with different priorities it is possible
+ * to process input HTML on different stages:
+ *
+ *     * 1-4: Data is available in the original string format.
+ *     * 5: Data is initially filtered with regexp patterns and parsed to
+ *             {@link CKEDITOR.htmlParser.fragment} {@link CKEDITOR.htmlParser.element}.
+ *     * 5-9: Data is available in the parsed format, but {@link CKEDITOR.htmlDataProcessor#htmlFilter}
+ *             is not applied yet.
+ *     * 10: Data is filtered with {@link CKEDITOR.htmlDataProcessor#htmlFilter}.
+ *  * 11: Data is filtered with the {CKEDITOR.filter content filter} (on output the content filter makes
+ *             only transformations, without filtering).
+ *     * 10-14: Data is available in the parsed format and {@link CKEDITOR.htmlDataProcessor#htmlFilter}
+ *             has already been applied.
+ *     * 15: Data is written back to an HTML string.
+ *     * 15-*: Data is available in an HTML string.
+ *
+ * For example to be able to process parsed and already processed data add listener this way:
+ *
+ *             editor.on( 'toDataFormat', function( evt) {
+ *                     evt.data.dataValue; // -> CKEDITOR.htmlParser.fragment instance
+ *             }, null, null, 12 );
+ *
+ * @since 4.1
+ * @event toDataFormat
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {String/CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} data.dataValue Output data to be prepared.
+ * @param {String} data.context See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `context` argument.
+ * @param {Boolean} data.filter See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `filter` argument.
+ * @param {Boolean} data.enterMode See {@link CKEDITOR.htmlDataProcessor#toDataFormat} The `enterMode` argument.
+ */
diff --git a/sources/core/htmlparser.js b/sources/core/htmlparser.js
new file mode 100644 (file)
index 0000000..8c30992
--- /dev/null
@@ -0,0 +1,205 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Provides an "event like" system to parse strings of HTML data.
+ *
+ *             var parser = new CKEDITOR.htmlParser();
+ *             parser.onTagOpen = function( tagName, attributes, selfClosing ) {
+ *                     alert( tagName );
+ *             };
+ *             parser.parse( '<p>Some <b>text</b>.</p>' ); // Alerts 'p', 'b'.
+ *
+ * @class
+ * @constructor Creates a htmlParser class instance.
+ */
+CKEDITOR.htmlParser = function() {
+       this._ = {
+               htmlPartsRegex: /<(?:(?:\/([^>]+)>)|(?:!--([\S|\s]*?)-->)|(?:([^\/\s>]+)((?:\s+[\w\-:.]+(?:\s*=\s*?(?:(?:"[^"]*")|(?:'[^']*')|[^\s"'\/>]+))?)*)[\S\s]*?(\/?)>))/g
+       };
+};
+
+( function() {
+       var attribsRegex = /([\w\-:.]+)(?:(?:\s*=\s*(?:(?:"([^"]*)")|(?:'([^']*)')|([^\s>]+)))|(?=\s|$))/g,
+               emptyAttribs = { checked: 1, compact: 1, declare: 1, defer: 1, disabled: 1, ismap: 1, multiple: 1, nohref: 1, noresize: 1, noshade: 1, nowrap: 1, readonly: 1, selected: 1 };
+
+       CKEDITOR.htmlParser.prototype = {
+               /**
+                * Function to be fired when a tag opener is found. This function
+                * should be overriden when using this class.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              parser.onTagOpen = function( tagName, attributes, selfClosing ) {
+                *                      alert( tagName ); // e.g. 'b'
+                *              } );
+                *              parser.parse( '<!-- Example --><b>Hello</b>' );
+                *
+                * @param {String} tagName The tag name. The name is guarantted to be lowercased.
+                * @param {Object} attributes An object containing all tag attributes. Each
+                * property in this object represent and attribute name and its value is the attribute value.
+                * @param {Boolean} selfClosing `true` if the tag closes itself, false if the tag doesn't.
+                */
+               onTagOpen: function() {},
+
+               /**
+                * Function to be fired when a tag closer is found. This function
+                * should be overriden when using this class.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              parser.onTagClose = function( tagName ) {
+                *                      alert( tagName ); // 'b'
+                *              } );
+                *              parser.parse( '<!-- Example --><b>Hello</b>' );
+                *
+                * @param {String} tagName The tag name. The name is guarantted to be lowercased.
+                */
+               onTagClose: function() {},
+
+               /**
+                * Function to be fired when text is found. This function
+                * should be overriden when using this class.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              parser.onText = function( text ) {
+                *                      alert( text ); // 'Hello'
+                *              } );
+                *              parser.parse( '<!-- Example --><b>Hello</b>' );
+                *
+                * @param {String} text The text found.
+                */
+               onText: function() {},
+
+               /**
+                * Function to be fired when CDATA section is found. This function
+                * should be overriden when using this class.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              parser.onCDATA = function( cdata ) {
+                *                      alert( cdata ); // 'var hello;'
+                *              } );
+                *              parser.parse( '<script>var hello;</script>' );
+                *
+                * @param {String} cdata The CDATA been found.
+                */
+               onCDATA: function() {},
+
+               /**
+                * Function to be fired when a commend is found. This function
+                * should be overriden when using this class.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              parser.onComment = function( comment ) {
+                *                      alert( comment ); // ' Example '
+                *              } );
+                *              parser.parse( '<!-- Example --><b>Hello</b>' );
+                *
+                * @param {String} comment The comment text.
+                */
+               onComment: function() {},
+
+               /**
+                * Parses text, looking for HTML tokens, like tag openers or closers,
+                * or comments. This function fires the onTagOpen, onTagClose, onText
+                * and onComment function during its execution.
+                *
+                *              var parser = new CKEDITOR.htmlParser();
+                *              // The onTagOpen, onTagClose, onText and onComment should be overriden
+                *              // at this point.
+                *              parser.parse( '<!-- Example --><b>Hello</b>' );
+                *
+                * @param {String} html The HTML to be parsed.
+                */
+               parse: function( html ) {
+                       var parts, tagName,
+                               nextIndex = 0,
+                               cdata; // The collected data inside a CDATA section.
+
+                       while ( ( parts = this._.htmlPartsRegex.exec( html ) ) ) {
+                               var tagIndex = parts.index;
+                               if ( tagIndex > nextIndex ) {
+                                       var text = html.substring( nextIndex, tagIndex );
+
+                                       if ( cdata )
+                                               cdata.push( text );
+                                       else
+                                               this.onText( text );
+                               }
+
+                               nextIndex = this._.htmlPartsRegex.lastIndex;
+
+                               // "parts" is an array with the following items:
+                               //              0 : The entire match for opening/closing tags and comments.
+                               //                : Group filled with the tag name for closing tags.
+                               //              2 : Group filled with the comment text.
+                               //              3 : Group filled with the tag name for opening tags.
+                               //              4 : Group filled with the attributes part of opening tags.
+
+                               // Closing tag
+                               if ( ( tagName = parts[ 1 ] ) ) {
+                                       tagName = tagName.toLowerCase();
+
+                                       if ( cdata && CKEDITOR.dtd.$cdata[ tagName ] ) {
+                                               // Send the CDATA data.
+                                               this.onCDATA( cdata.join( '' ) );
+                                               cdata = null;
+                                       }
+
+                                       if ( !cdata ) {
+                                               this.onTagClose( tagName );
+                                               continue;
+                                       }
+                               }
+
+                               // If CDATA is enabled, just save the raw match.
+                               if ( cdata ) {
+                                       cdata.push( parts[ 0 ] );
+                                       continue;
+                               }
+
+                               // Opening tag
+                               if ( ( tagName = parts[ 3 ] ) ) {
+                                       tagName = tagName.toLowerCase();
+
+                                       // There are some tag names that can break things, so let's
+                                       // simply ignore them when parsing. (#5224)
+                                       if ( /="/.test( tagName ) )
+                                               continue;
+
+                                       var attribs = {},
+                                               attribMatch,
+                                               attribsPart = parts[ 4 ],
+                                               selfClosing = !!parts[ 5 ];
+
+                                       if ( attribsPart ) {
+                                               while ( ( attribMatch = attribsRegex.exec( attribsPart ) ) ) {
+                                                       var attName = attribMatch[ 1 ].toLowerCase(),
+                                                               attValue = attribMatch[ 2 ] || attribMatch[ 3 ] || attribMatch[ 4 ] || '';
+
+                                                       if ( !attValue && emptyAttribs[ attName ] )
+                                                               attribs[ attName ] = attName;
+                                                       else
+                                                               attribs[ attName ] = CKEDITOR.tools.htmlDecodeAttr( attValue );
+                                               }
+                                       }
+
+                                       this.onTagOpen( tagName, attribs, selfClosing );
+
+                                       // Open CDATA mode when finding the appropriate tags.
+                                       if ( !cdata && CKEDITOR.dtd.$cdata[ tagName ] )
+                                               cdata = [];
+
+                                       continue;
+                               }
+
+                               // Comment
+                               if ( ( tagName = parts[ 2 ] ) )
+                                       this.onComment( tagName );
+                       }
+
+                       if ( html.length > nextIndex )
+                               this.onText( html.substring( nextIndex, html.length ) );
+               }
+       };
+} )();
diff --git a/sources/core/htmlparser/basicwriter.js b/sources/core/htmlparser/basicwriter.js
new file mode 100644 (file)
index 0000000..529fbf1
--- /dev/null
@@ -0,0 +1,152 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * TODO
+ *
+ * @class
+ * @todo
+ */
+CKEDITOR.htmlParser.basicWriter = CKEDITOR.tools.createClass( {
+       /**
+        * Creates a basicWriter class instance.
+        *
+        * @constructor
+        */
+       $: function() {
+               this._ = {
+                       output: []
+               };
+       },
+
+       proto: {
+               /**
+                * Writes the tag opening part for a opener tag.
+                *
+                *              // Writes '<p'.
+                *              writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );
+                *
+                * @param {String} tagName The element name for this tag.
+                * @param {Object} attributes The attributes defined for this tag. The
+                * attributes could be used to inspect the tag.
+                */
+               openTag: function( tagName ) {
+                       this._.output.push( '<', tagName );
+               },
+
+               /**
+                * Writes the tag closing part for a opener tag.
+                *
+                *              // Writes '>'.
+                *              writer.openTagClose( 'p', false );
+                *
+                *              // Writes ' />'.
+                *              writer.openTagClose( 'br', true );
+                *
+                * @param {String} tagName The element name for this tag.
+                * @param {Boolean} isSelfClose Indicates that this is a self-closing tag,
+                * like `<br>` or `<img>`.
+                */
+               openTagClose: function( tagName, isSelfClose ) {
+                       if ( isSelfClose )
+                               this._.output.push( ' />' );
+                       else
+                               this._.output.push( '>' );
+               },
+
+               /**
+                * Writes an attribute. This function should be called after opening the
+                * tag with {@link #openTagClose}.
+                *
+                *              // Writes ' class="MyClass"'.
+                *              writer.attribute( 'class', 'MyClass' );
+                *
+                * @param {String} attName The attribute name.
+                * @param {String} attValue The attribute value.
+                */
+               attribute: function( attName, attValue ) {
+                       // Browsers don't always escape special character in attribute values. (#4683, #4719).
+                       if ( typeof attValue == 'string' )
+                               attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );
+
+                       this._.output.push( ' ', attName, '="', attValue, '"' );
+               },
+
+               /**
+                * Writes a closer tag.
+                *
+                *              // Writes '</p>'.
+                *              writer.closeTag( 'p' );
+                *
+                * @param {String} tagName The element name for this tag.
+                */
+               closeTag: function( tagName ) {
+                       this._.output.push( '</', tagName, '>' );
+               },
+
+               /**
+                * Writes text.
+                *
+                *              // Writes 'Hello Word'.
+                *              writer.text( 'Hello Word' );
+                *
+                * @param {String} text The text value.
+                */
+               text: function( text ) {
+                       this._.output.push( text );
+               },
+
+               /**
+                * Writes a comment.
+                *
+                *              // Writes '<!-- My comment -->'.
+                *              writer.comment( ' My comment ' );
+                *
+                * @param {String} comment The comment text.
+                */
+               comment: function( comment ) {
+                       this._.output.push( '<!--', comment, '-->' );
+               },
+
+               /**
+                * Writes any kind of data to the ouput.
+                *
+                *              writer.write( 'This is an <b>example</b>.' );
+                *
+                * @param {String} data
+                */
+               write: function( data ) {
+                       this._.output.push( data );
+               },
+
+               /**
+                * Empties the current output buffer.
+                *
+                *              writer.reset();
+                */
+               reset: function() {
+                       this._.output = [];
+                       this._.indent = false;
+               },
+
+               /**
+                * Empties the current output buffer.
+                *
+                *              var html = writer.getHtml();
+                *
+                * @param {Boolean} reset Indicates that the {@link #reset} method is to
+                * be automatically called after retrieving the HTML.
+                * @returns {String} The HTML written to the writer so far.
+                */
+               getHtml: function( reset ) {
+                       var html = this._.output.join( '' );
+
+                       if ( reset )
+                               this.reset();
+
+                       return html;
+               }
+       }
+} );
diff --git a/sources/core/htmlparser/cdata.js b/sources/core/htmlparser/cdata.js
new file mode 100644 (file)
index 0000000..be8c5cf
--- /dev/null
@@ -0,0 +1,48 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+ 'use strict';
+
+( function() {
+
+       /**
+        * A lightweight representation of HTML CDATA.
+        *
+        * @class
+        * @extends CKEDITOR.htmlParser.node
+        * @constructor Creates a cdata class instance.
+        * @param {String} value The CDATA section value.
+        */
+       CKEDITOR.htmlParser.cdata = function( value ) {
+               /**
+                * The CDATA value.
+                *
+                * @property {String}
+                */
+               this.value = value;
+       };
+
+       CKEDITOR.htmlParser.cdata.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
+               /**
+                * CDATA has the same type as {@link CKEDITOR.htmlParser.text} This is
+                * a constant value set to {@link CKEDITOR#NODE_TEXT}.
+                *
+                * @readonly
+                * @property {Number} [=CKEDITOR.NODE_TEXT]
+                */
+               type: CKEDITOR.NODE_TEXT,
+
+               filter: function() {},
+
+               /**
+                * Writes the CDATA with no special manipulations.
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
+                */
+               writeHtml: function( writer ) {
+                       writer.write( this.value );
+               }
+       } );
+} )();
diff --git a/sources/core/htmlparser/comment.js b/sources/core/htmlparser/comment.js
new file mode 100644 (file)
index 0000000..14a38f3
--- /dev/null
@@ -0,0 +1,80 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+ 'use strict';
+
+/**
+ * A lightweight representation of an HTML comment.
+ *
+ * @class
+ * @extends CKEDITOR.htmlParser.node
+ * @constructor Creates a comment class instance.
+ * @param {String} value The comment text value.
+ */
+CKEDITOR.htmlParser.comment = function( value ) {
+       /**
+        * The comment text.
+        *
+        * @property {String}
+        */
+       this.value = value;
+
+       /** @private */
+       this._ = {
+               isBlockLike: false
+       };
+};
+
+CKEDITOR.htmlParser.comment.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
+       /**
+        * The node type. This is a constant value set to {@link CKEDITOR#NODE_COMMENT}.
+        *
+        * @readonly
+        * @property {Number} [=CKEDITOR.NODE_COMMENT]
+        */
+       type: CKEDITOR.NODE_COMMENT,
+
+       /**
+        * Filter this comment with given filter.
+        *
+        * @since 4.1
+        * @param {CKEDITOR.htmlParser.filter} filter
+        * @returns {Boolean} Method returns `false` when this comment has
+        * been removed or replaced with other node. This is an information for
+        * {@link CKEDITOR.htmlParser.element#filterChildren} that it has
+        * to repeat filter on current position in parent's children array.
+        */
+       filter: function( filter, context ) {
+               var comment = this.value;
+
+               if ( !( comment = filter.onComment( context, comment, this ) ) ) {
+                       this.remove();
+                       return false;
+               }
+
+               if ( typeof comment != 'string' ) {
+                       this.replaceWith( comment );
+                       return false;
+               }
+
+               this.value = comment;
+
+               return true;
+       },
+
+       /**
+        * Writes the HTML representation of this comment to a CKEDITOR.htmlWriter.
+        *
+        * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
+        * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
+        * **Note:** it's unsafe to filter offline (not appended) node.
+        */
+       writeHtml: function( writer, filter ) {
+               if ( filter )
+                       this.filter( filter );
+
+               writer.comment( this.value );
+       }
+} );
diff --git a/sources/core/htmlparser/element.js b/sources/core/htmlparser/element.js
new file mode 100644 (file)
index 0000000..0ed750e
--- /dev/null
@@ -0,0 +1,568 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+/**
+ * A lightweight representation of an HTML element.
+ *
+ * @class
+ * @extends CKEDITOR.htmlParser.node
+ * @constructor Creates an element class instance.
+ * @param {String} name The element name.
+ * @param {Object} attributes An object storing all attributes defined for
+ * this element.
+ */
+CKEDITOR.htmlParser.element = function( name, attributes ) {
+       /**
+        * The element name.
+        *
+        * @property {String}
+        */
+       this.name = name;
+
+       /**
+        * Stores the attributes defined for this element.
+        *
+        * @property {Object}
+        */
+       this.attributes = attributes || {};
+
+       /**
+        * The nodes that are direct children of this element.
+        */
+       this.children = [];
+
+       // Reveal the real semantic of our internal custom tag name (#6639),
+       // when resolving whether it's block like.
+       var realName = name || '',
+               prefixed = realName.match( /^cke:(.*)/ );
+       prefixed && ( realName = prefixed[ 1 ] );
+
+       var isBlockLike = !!( CKEDITOR.dtd.$nonBodyContent[ realName ] || CKEDITOR.dtd.$block[ realName ] ||
+               CKEDITOR.dtd.$listItem[ realName ] || CKEDITOR.dtd.$tableContent[ realName ] ||
+               CKEDITOR.dtd.$nonEditable[ realName ] || realName == 'br' );
+
+       this.isEmpty = !!CKEDITOR.dtd.$empty[ name ];
+       this.isUnknown = !CKEDITOR.dtd[ name ];
+
+       /** @private */
+       this._ = {
+               isBlockLike: isBlockLike,
+               hasInlineStarted: this.isEmpty || !isBlockLike
+       };
+};
+
+/**
+ * Object presentation of the CSS style declaration text.
+ *
+ * @class
+ * @constructor Creates a `cssStyle` class instance.
+ * @param {CKEDITOR.htmlParser.element/String} elementOrStyleText
+ * An HTML parser element or the inline style text.
+ */
+CKEDITOR.htmlParser.cssStyle = function() {
+       var styleText,
+               arg = arguments[ 0 ],
+               rules = {};
+
+       styleText = arg instanceof CKEDITOR.htmlParser.element ? arg.attributes.style : arg;
+
+       // html-encoded quote might be introduced by 'font-family'
+       // from MS-Word which confused the following regexp. e.g.
+       //'font-family: &quot;Lucida, Console&quot;'
+       // TODO reuse CSS methods from tools.
+       ( styleText || '' ).replace( /&quot;/g, '"' ).replace( /\s*([^ :;]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
+               name == 'font-family' && ( value = value.replace( /["']/g, '' ) );
+               rules[ name.toLowerCase() ] = value;
+       } );
+
+       return {
+
+               rules: rules,
+
+               /**
+                * Applies the styles to the specified element or object.
+                *
+                * @param {CKEDITOR.htmlParser.element/CKEDITOR.dom.element/Object} obj
+                */
+               populate: function( obj ) {
+                       var style = this.toString();
+                       if ( style )
+                               obj instanceof CKEDITOR.dom.element ? obj.setAttribute( 'style', style ) : obj instanceof CKEDITOR.htmlParser.element ? obj.attributes.style = style : obj.style = style;
+
+               },
+
+               /**
+                * Serializes CSS style declaration to a string.
+                *
+                * @returns {String}
+                */
+               toString: function() {
+                       var output = [];
+                       for ( var i in rules )
+                               rules[ i ] && output.push( i, ':', rules[ i ], ';' );
+                       return output.join( '' );
+               }
+       };
+};
+
+/** @class CKEDITOR.htmlParser.element */
+( function() {
+       // Used to sort attribute entries in an array, where the first element of
+       // each object is the attribute name.
+       var sortAttribs = function( a, b ) {
+                       a = a[ 0 ];
+                       b = b[ 0 ];
+                       return a < b ? -1 : a > b ? 1 : 0;
+               },
+               fragProto = CKEDITOR.htmlParser.fragment.prototype;
+
+       CKEDITOR.htmlParser.element.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
+               /**
+                * The node type. This is a constant value set to {@link CKEDITOR#NODE_ELEMENT}.
+                *
+                * @readonly
+                * @property {Number} [=CKEDITOR.NODE_ELEMENT]
+                */
+               type: CKEDITOR.NODE_ELEMENT,
+
+               /**
+                * Adds a node to the element children list.
+                *
+                * @method
+                * @param {CKEDITOR.htmlParser.node} node The node to be added.
+                * @param {Number} [index] From where the insertion happens.
+                */
+               add: fragProto.add,
+
+               /**
+                * Clones this element.
+                *
+                * @returns {CKEDITOR.htmlParser.element} The element clone.
+                */
+               clone: function() {
+                       return new CKEDITOR.htmlParser.element( this.name, this.attributes );
+               },
+
+               /**
+                * Filters this element and its children with the given filter.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.filter} filter
+                * @returns {Boolean} The method returns `false` when this element has
+                * been removed or replaced with another. This information means that
+                * {@link #filterChildren} has to repeat the filter on the current
+                * position in parent's children array.
+                */
+               filter: function( filter, context ) {
+                       var element = this,
+                               originalName, name;
+
+                       context = element.getFilterContext( context );
+
+                       // Do not process elements with data-cke-processor attribute set to off.
+                       if ( context.off )
+                               return true;
+
+                       // Filtering if it's the root node.
+                       if ( !element.parent )
+                               filter.onRoot( context, element );
+
+                       while ( true ) {
+                               originalName = element.name;
+
+                               if ( !( name = filter.onElementName( context, originalName ) ) ) {
+                                       this.remove();
+                                       return false;
+                               }
+
+                               element.name = name;
+
+                               if ( !( element = filter.onElement( context, element ) ) ) {
+                                       this.remove();
+                                       return false;
+                               }
+
+                               // New element has been returned - replace current one
+                               // and process it (stop processing this and return false, what
+                               // means that element has been removed).
+                               if ( element !== this ) {
+                                       this.replaceWith( element );
+                                       return false;
+                               }
+
+                               // If name has been changed - continue loop, so in next iteration
+                               // filters for new name will be applied to this element.
+                               // If name hasn't been changed - stop.
+                               if ( element.name == originalName )
+                                       break;
+
+                               // If element has been replaced with something of a
+                               // different type, then make the replacement filter itself.
+                               if ( element.type != CKEDITOR.NODE_ELEMENT ) {
+                                       this.replaceWith( element );
+                                       return false;
+                               }
+
+                               // This indicate that the element has been dropped by
+                               // filter but not the children.
+                               if ( !element.name ) {
+                                       this.replaceWithChildren();
+                                       return false;
+                               }
+                       }
+
+                       var attributes = element.attributes,
+                               a, value, newAttrName;
+
+                       for ( a in attributes ) {
+                               newAttrName = a;
+                               value = attributes[ a ];
+
+                               // Loop until name isn't modified.
+                               // A little bit senseless, but IE would do that anyway
+                               // because it iterates with for-in loop even over properties
+                               // created during its run.
+                               while ( true ) {
+                                       if ( !( newAttrName = filter.onAttributeName( context, a ) ) ) {
+                                               delete attributes[ a ];
+                                               break;
+                                       } else if ( newAttrName != a ) {
+                                               delete attributes[ a ];
+                                               a = newAttrName;
+                                               continue;
+                                       } else {
+                                               break;
+                                       }
+                               }
+
+                               if ( newAttrName ) {
+                                       if ( ( value = filter.onAttribute( context, element, newAttrName, value ) ) === false )
+                                               delete attributes[ newAttrName ];
+                                       else
+                                               attributes[ newAttrName ] = value;
+                               }
+                       }
+
+                       if ( !element.isEmpty )
+                               this.filterChildren( filter, false, context );
+
+                       return true;
+               },
+
+               /**
+                * Filters this element's children with the given filter.
+                *
+                * Element's children may only be filtered once by one
+                * instance of the filter.
+                *
+                * @method filterChildren
+                * @param {CKEDITOR.htmlParser.filter} filter
+                */
+               filterChildren: fragProto.filterChildren,
+
+               /**
+                * Writes the element HTML to the CKEDITOR.htmlWriter.
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
+                * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
+                * **Note:** It is unsafe to filter an offline (not appended) node.
+                */
+               writeHtml: function( writer, filter ) {
+                       if ( filter )
+                               this.filter( filter );
+
+                       var name = this.name,
+                               attribsArray = [],
+                               attributes = this.attributes,
+                               attrName,
+                               attr, i, l;
+
+                       // Open element tag.
+                       writer.openTag( name, attributes );
+
+                       // Copy all attributes to an array.
+                       for ( attrName in attributes )
+                               attribsArray.push( [ attrName, attributes[ attrName ] ] );
+
+                       // Sort the attributes by name.
+                       if ( writer.sortAttributes )
+                               attribsArray.sort( sortAttribs );
+
+                       // Send the attributes.
+                       for ( i = 0, l = attribsArray.length; i < l; i++ ) {
+                               attr = attribsArray[ i ];
+                               writer.attribute( attr[ 0 ], attr[ 1 ] );
+                       }
+
+                       // Close the tag.
+                       writer.openTagClose( name, this.isEmpty );
+
+                       this.writeChildrenHtml( writer );
+
+                       // Close the element.
+                       if ( !this.isEmpty )
+                               writer.closeTag( name );
+               },
+
+               /**
+                * Sends children of this element to the writer.
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which HTML will be written.
+                * @param {CKEDITOR.htmlParser.filter} [filter]
+                */
+               writeChildrenHtml: fragProto.writeChildrenHtml,
+
+               /**
+                * Replaces this element with its children.
+                *
+                * @since 4.1
+                */
+               replaceWithChildren: function() {
+                       var children = this.children;
+
+                       for ( var i = children.length; i; )
+                               children[ --i ].insertAfter( this );
+
+                       this.remove();
+               },
+
+               /**
+                * Executes a callback on each node (of the given type) in this element.
+                *
+                *              // Create a <p> element with foo<b>bar</b>bom as its content.
+                *              var elP = CKEDITOR.htmlParser.fragment.fromHtml( 'foo<b>bar</b>bom', 'p' );
+                *              elP.forEach( function( node ) {
+                *                      console.log( node );
+                *              } );
+                *              // Will log:
+                *              // 1. document fragment,
+                *              // 2. <p> element,
+                *              // 3. "foo" text node,
+                *              // 4. <b> element,
+                *              // 5. "bar" text node,
+                *              // 6. "bom" text node.
+                *
+                * @since 4.1
+                * @param {Function} callback Function to be executed on every node.
+                * **Since 4.3**: If `callback` returned `false`, the descendants of the current node will be ignored.
+                * @param {CKEDITOR.htmlParser.node} callback.node Node passed as an argument.
+                * @param {Number} [type] Whether the specified `callback` will be executed only on nodes of this type.
+                * @param {Boolean} [skipRoot] Do not execute `callback` on this element.
+                */
+               forEach: fragProto.forEach,
+
+               /**
+                * Gets this element's first child. If `condition` is given, this method returns
+                * the first child which satisfies that condition.
+                *
+                * @since 4.3
+                * @param {String/Object/Function} condition Name of a child, a hash of names, or a validator function.
+                * @returns {CKEDITOR.htmlParser.node}
+                */
+               getFirst: function( condition ) {
+                       if ( !condition )
+                               return this.children.length ? this.children[ 0 ] : null;
+
+                       if ( typeof condition != 'function' )
+                               condition = nameCondition( condition );
+
+                       for ( var i = 0, l = this.children.length; i < l; ++i ) {
+                               if ( condition( this.children[ i ] ) )
+                                       return this.children[ i ];
+                       }
+                       return null;
+               },
+
+               /**
+                * Gets this element's inner HTML.
+                *
+                * @since 4.3
+                * @returns {String}
+                */
+               getHtml: function() {
+                       var writer = new CKEDITOR.htmlParser.basicWriter();
+                       this.writeChildrenHtml( writer );
+                       return writer.getHtml();
+               },
+
+               /**
+                * Sets this element's inner HTML.
+                *
+                * @since 4.3
+                * @param {String} html
+                */
+               setHtml: function( html ) {
+                       var children = this.children = CKEDITOR.htmlParser.fragment.fromHtml( html ).children;
+
+                       for ( var i = 0, l = children.length; i < l; ++i )
+                               children[ i ].parent = this;
+               },
+
+               /**
+                * Gets this element's outer HTML.
+                *
+                * @since 4.3
+                * @returns {String}
+                */
+               getOuterHtml: function() {
+                       var writer = new CKEDITOR.htmlParser.basicWriter();
+                       this.writeHtml( writer );
+                       return writer.getHtml();
+               },
+
+               /**
+                * Splits this element at the given index.
+                *
+                * @since 4.3
+                * @param {Number} index Index at which the element will be split &mdash; `0` means the beginning,
+                * `1` after the first child node, etc.
+                * @returns {CKEDITOR.htmlParser.element} The new element following this one.
+                */
+               split: function( index ) {
+                       var cloneChildren = this.children.splice( index, this.children.length - index ),
+                               clone = this.clone();
+
+                       for ( var i = 0; i < cloneChildren.length; ++i )
+                               cloneChildren[ i ].parent = clone;
+
+                       clone.children = cloneChildren;
+
+                       if ( cloneChildren[ 0 ] )
+                               cloneChildren[ 0 ].previous = null;
+
+                       if ( index > 0 )
+                               this.children[ index - 1 ].next = null;
+
+                       this.parent.add( clone, this.getIndex() + 1 );
+
+                       return clone;
+               },
+
+               /**
+                * Searches through the current node children to find nodes matching the `criteria`.
+                *
+                * @param {String/Function} criteria Tag name or evaluator function.
+                * @param {Boolean} [recursive=false]
+                * @returns {CKEDITOR.htmlParser.node[]}
+                */
+               find: function( criteria, recursive ) {
+                       if ( recursive === undefined ) {
+                               recursive = false;
+                       }
+
+                       var ret = [],
+                               i;
+
+                       for     ( i = 0; i < this.children.length; i++ ) {
+                               var curChild = this.children[ i ];
+
+                               if ( typeof criteria == 'function' && criteria( curChild ) ) {
+                                       ret.push( curChild );
+                               } else if ( typeof criteria == 'string' && curChild.name === criteria ) {
+                                       ret.push( curChild );
+                               }
+
+                               if ( recursive && curChild.find ) {
+                                       ret = ret.concat( curChild.find( criteria, recursive ) );
+                               }
+                       }
+
+                       return ret;
+               },
+
+               /**
+                * Adds a class name to the list of classes.
+                *
+                * @since 4.4
+                * @param {String} className The class name to be added.
+                */
+               addClass: function( className ) {
+                       if ( this.hasClass( className ) )
+                               return;
+
+                       var c = this.attributes[ 'class' ] || '';
+
+                       this.attributes[ 'class' ] = c + ( c ? ' ' : '' ) + className;
+               },
+
+               /**
+                * Removes a class name from the list of classes.
+                *
+                * @since 4.3
+                * @param {String} className The class name to be removed.
+                */
+               removeClass: function( className ) {
+                       var classes = this.attributes[ 'class' ];
+
+                       if ( !classes )
+                               return;
+
+                       // We can safely assume that className won't break regexp.
+                       // http://stackoverflow.com/questions/448981/what-characters-are-valid-in-css-class-names
+                       classes = CKEDITOR.tools.trim( classes.replace( new RegExp( '(?:\\s+|^)' + className + '(?:\\s+|$)' ), ' ' ) );
+
+                       if ( classes )
+                               this.attributes[ 'class' ] = classes;
+                       else
+                               delete this.attributes[ 'class' ];
+               },
+
+               /**
+                * Checkes whether this element has a class name.
+                *
+                * @since 4.3
+                * @param {String} className The class name to be checked.
+                * @returns {Boolean} Whether this element has a `className`.
+                */
+               hasClass: function( className ) {
+                       var classes = this.attributes[ 'class' ];
+
+                       if ( !classes )
+                               return false;
+
+                       return ( new RegExp( '(?:^|\\s)' + className + '(?=\\s|$)' ) ).test( classes );
+               },
+
+               getFilterContext: function( ctx ) {
+                       var changes = [];
+
+                       if ( !ctx ) {
+                               ctx = {
+                                       off: false,
+                                       nonEditable: false,
+                                       nestedEditable: false
+                               };
+                       }
+
+                       if ( !ctx.off && this.attributes[ 'data-cke-processor' ] == 'off' )
+                               changes.push( 'off', true );
+
+                       if ( !ctx.nonEditable && this.attributes.contenteditable == 'false' )
+                               changes.push( 'nonEditable', true );
+                       // A context to be given nestedEditable must be nonEditable first (by inheritance) (#11372, #11698).
+                       // Special case: #11504 - filter starts on <body contenteditable=true>,
+                       // so ctx.nonEditable has not been yet set to true.
+                       else if ( ctx.nonEditable && !ctx.nestedEditable && this.attributes.contenteditable == 'true' )
+                               changes.push( 'nestedEditable', true );
+
+                       if ( changes.length ) {
+                               ctx = CKEDITOR.tools.copy( ctx );
+                               for ( var i = 0; i < changes.length; i += 2 )
+                                       ctx[ changes[ i ] ] = changes[ i + 1 ];
+                       }
+
+                       return ctx;
+               }
+       }, true );
+
+       function nameCondition( condition ) {
+               return function( el ) {
+                       return el.type == CKEDITOR.NODE_ELEMENT &&
+                               ( typeof condition == 'string' ? el.name == condition : el.name in condition );
+               };
+       }
+} )();
diff --git a/sources/core/htmlparser/filter.js b/sources/core/htmlparser/filter.js
new file mode 100644 (file)
index 0000000..db6b91c
--- /dev/null
@@ -0,0 +1,407 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+( function() {
+       /**
+        * Filter is a configurable tool for transforming and filtering {@link CKEDITOR.htmlParser.node nodes}.
+        * It is mainly used during data processing phase which is done not on real DOM nodes,
+        * but on their simplified form represented by {@link CKEDITOR.htmlParser.node} class and its subclasses.
+        *
+        *              var filter = new CKEDITOR.htmlParser.filter( {
+        *                      text: function( value ) {
+        *                              return '@' + value + '@';
+        *                      },
+        *                      elements: {
+        *                              p: function( element ) {
+        *                                      element.attributes.foo = '1';
+        *                              }
+        *                      }
+        *              } );
+        *
+        *              var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>Foo<b>bar!</b></p>' ),
+        *                      writer = new CKEDITOR.htmlParser.basicWriter();
+        *              filter.applyTo( fragment );
+        *              fragment.writeHtml( writer );
+        *              writer.getHtml(); // '<p foo="1">@Foo@<b>@bar!@</b></p>'
+        *
+        * @class
+        */
+       CKEDITOR.htmlParser.filter = CKEDITOR.tools.createClass( {
+               /**
+                * @constructor Creates a filter class instance.
+                * @param {CKEDITOR.htmlParser.filterRulesDefinition} [rules]
+                */
+               $: function( rules ) {
+                       /**
+                        * ID of filter instance, which is used to mark elements
+                        * to which this filter has been already applied.
+                        *
+                        * @property {Number} id
+                        * @readonly
+                        */
+                       this.id = CKEDITOR.tools.getNextNumber();
+
+                       /**
+                        * Rules for element names.
+                        *
+                        * @property {CKEDITOR.htmlParser.filterRulesGroup}
+                        * @readonly
+                        */
+                       this.elementNameRules = new filterRulesGroup();
+
+                       /**
+                        * Rules for attribute names.
+                        *
+                        * @property {CKEDITOR.htmlParser.filterRulesGroup}
+                        * @readonly
+                        */
+                       this.attributeNameRules = new filterRulesGroup();
+
+                       /**
+                        * Hash of elementName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for elements}.
+                        *
+                        * @readonly
+                        */
+                       this.elementsRules = {};
+
+                       /**
+                        * Hash of attributeName => {@link CKEDITOR.htmlParser.filterRulesGroup rules for attributes}.
+                        *
+                        * @readonly
+                        */
+                       this.attributesRules = {};
+
+                       /**
+                        * Rules for text nodes.
+                        *
+                        * @property {CKEDITOR.htmlParser.filterRulesGroup}
+                        * @readonly
+                        */
+                       this.textRules = new filterRulesGroup();
+
+                       /**
+                        * Rules for comment nodes.
+                        *
+                        * @property {CKEDITOR.htmlParser.filterRulesGroup}
+                        * @readonly
+                        */
+                       this.commentRules = new filterRulesGroup();
+
+                       /**
+                        * Rules for a root node.
+                        *
+                        * @property {CKEDITOR.htmlParser.filterRulesGroup}
+                        * @readonly
+                        */
+                       this.rootRules = new filterRulesGroup();
+
+                       if ( rules )
+                               this.addRules( rules, 10 );
+               },
+
+               proto: {
+                       /**
+                        * Add rules to this filter.
+                        *
+                        * @param {CKEDITOR.htmlParser.filterRulesDefinition} rules Object containing filter rules.
+                        * @param {Object/Number} [options] Object containing rules' options or a priority
+                        * (for a backward compatibility with CKEditor versions up to 4.2.x).
+                        * @param {Number} [options.priority=10] The priority of a rule.
+                        * @param {Boolean} [options.applyToAll=false] Whether to apply rule to non-editable
+                        * elements and their descendants too.
+                        */
+                       addRules: function( rules, options ) {
+                               var priority;
+
+                               // Backward compatibility.
+                               if ( typeof options == 'number' )
+                                       priority = options;
+                               // New version - try reading from options.
+                               else if ( options && ( 'priority' in options ) )
+                                       priority = options.priority;
+
+                               // Defaults.
+                               if ( typeof priority != 'number' )
+                                       priority = 10;
+                               if ( typeof options != 'object' )
+                                       options = {};
+
+                               // Add the elementNames.
+                               if ( rules.elementNames )
+                                       this.elementNameRules.addMany( rules.elementNames, priority, options );
+
+                               // Add the attributeNames.
+                               if ( rules.attributeNames )
+                                       this.attributeNameRules.addMany( rules.attributeNames, priority, options );
+
+                               // Add the elements.
+                               if ( rules.elements )
+                                       addNamedRules( this.elementsRules, rules.elements, priority, options );
+
+                               // Add the attributes.
+                               if ( rules.attributes )
+                                       addNamedRules( this.attributesRules, rules.attributes, priority, options );
+
+                               // Add the text.
+                               if ( rules.text )
+                                       this.textRules.add( rules.text, priority, options );
+
+                               // Add the comment.
+                               if ( rules.comment )
+                                       this.commentRules.add( rules.comment, priority, options );
+
+                               // Add root node rules.
+                               if ( rules.root )
+                                       this.rootRules.add( rules.root, priority, options );
+                       },
+
+                       /**
+                        * Apply this filter to given node.
+                        *
+                        * @param {CKEDITOR.htmlParser.node} node The node to be filtered.
+                        */
+                       applyTo: function( node ) {
+                               node.filter( this );
+                       },
+
+                       onElementName: function( context, name ) {
+                               return this.elementNameRules.execOnName( context, name );
+                       },
+
+                       onAttributeName: function( context, name ) {
+                               return this.attributeNameRules.execOnName( context, name );
+                       },
+
+                       onText: function( context, text, node ) {
+                               return this.textRules.exec( context, text, node );
+                       },
+
+                       onComment: function( context, commentText, comment ) {
+                               return this.commentRules.exec( context, commentText, comment );
+                       },
+
+                       onRoot: function( context, element ) {
+                               return this.rootRules.exec( context, element );
+                       },
+
+                       onElement: function( context, element ) {
+                               // We must apply filters set to the specific element name as
+                               // well as those set to the generic ^/$ name. So, add both to an
+                               // array and process them in a small loop.
+                               var rulesGroups = [ this.elementsRules[ '^' ], this.elementsRules[ element.name ], this.elementsRules.$ ],
+                                       rulesGroup, ret;
+
+                               for ( var i = 0; i < 3; i++ ) {
+                                       rulesGroup = rulesGroups[ i ];
+                                       if ( rulesGroup ) {
+                                               ret = rulesGroup.exec( context, element, this );
+
+                                               if ( ret === false )
+                                                       return null;
+
+                                               if ( ret && ret != element )
+                                                       return this.onNode( context, ret );
+
+                                               // The non-root element has been dismissed by one of the filters.
+                                               if ( element.parent && !element.name )
+                                                       break;
+                                       }
+                               }
+
+                               return element;
+                       },
+
+                       onNode: function( context, node ) {
+                               var type = node.type;
+
+                               return type == CKEDITOR.NODE_ELEMENT ? this.onElement( context, node ) :
+                                       type == CKEDITOR.NODE_TEXT ? new CKEDITOR.htmlParser.text( this.onText( context, node.value ) ) :
+                                       type == CKEDITOR.NODE_COMMENT ? new CKEDITOR.htmlParser.comment( this.onComment( context, node.value ) ) : null;
+                       },
+
+                       onAttribute: function( context, element, name, value ) {
+                               var rulesGroup = this.attributesRules[ name ];
+
+                               if ( rulesGroup )
+                                       return rulesGroup.exec( context, value, element, this );
+                               return value;
+                       }
+               }
+       } );
+
+       /**
+        * Class grouping filter rules for one subject (like element or attribute names).
+        *
+        * @class CKEDITOR.htmlParser.filterRulesGroup
+        */
+       function filterRulesGroup() {
+               /**
+                * Array of objects containing rule, priority and options.
+                *
+                * @property {Object[]}
+                * @readonly
+                */
+               this.rules = [];
+       }
+
+       CKEDITOR.htmlParser.filterRulesGroup = filterRulesGroup;
+
+       filterRulesGroup.prototype = {
+               /**
+                * Adds specified rule to this group.
+                *
+                * @param {Function/Array} rule Function for function based rule or [ pattern, replacement ] array for
+                * rule applicable to names.
+                * @param {Number} priority
+                * @param options
+                */
+               add: function( rule, priority, options ) {
+                       this.rules.splice( this.findIndex( priority ), 0, {
+                               value: rule,
+                               priority: priority,
+                               options: options
+                       } );
+               },
+
+               /**
+                * Adds specified rules to this group.
+                *
+                * @param {Array} rules Array of rules - see {@link #add}.
+                * @param {Number} priority
+                * @param options
+                */
+               addMany: function( rules, priority, options ) {
+                       var args = [ this.findIndex( priority ), 0 ];
+
+                       for ( var i = 0, len = rules.length; i < len; i++ ) {
+                               args.push( {
+                                       value: rules[ i ],
+                                       priority: priority,
+                                       options: options
+                               } );
+                       }
+
+                       this.rules.splice.apply( this.rules, args );
+               },
+
+               /**
+                * Finds an index at which rule with given priority should be inserted.
+                *
+                * @param {Number} priority
+                * @returns {Number} Index.
+                */
+               findIndex: function( priority ) {
+                       var rules = this.rules,
+                               len = rules.length,
+                               i = len - 1;
+
+                       // Search from the end, because usually rules will be added with default priority, so
+                       // we will be able to stop loop quickly.
+                       while ( i >= 0 && priority < rules[ i ].priority )
+                               i--;
+
+                       return i + 1;
+               },
+
+               /**
+                * Executes this rules group on given value. Applicable only if function based rules were added.
+                *
+                * All arguments passed to this function will be forwarded to rules' functions.
+                *
+                * @param {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} currentValue The value to be filtered.
+                * @returns {CKEDITOR.htmlParser.node/CKEDITOR.htmlParser.fragment/String} Filtered value.
+                */
+               exec: function( context, currentValue ) {
+                       var isNode = currentValue instanceof CKEDITOR.htmlParser.node || currentValue instanceof CKEDITOR.htmlParser.fragment,
+                               // Splice '1' to remove context, which we don't want to pass to filter rules.
+                               args = Array.prototype.slice.call( arguments, 1 ),
+                               rules = this.rules,
+                               len = rules.length,
+                               orgType, orgName, ret, i, rule;
+
+                       for ( i = 0; i < len; i++ ) {
+                               // Backup the node info before filtering.
+                               if ( isNode ) {
+                                       orgType = currentValue.type;
+                                       orgName = currentValue.name;
+                               }
+
+                               rule = rules[ i ];
+                               if ( isRuleApplicable( context, rule ) ) {
+                                       ret = rule.value.apply( null, args );
+
+                                       if ( ret === false )
+                                               return ret;
+
+                                       // We're filtering node (element/fragment).
+                                       // No further filtering if it's not anymore fitable for the subsequent filters.
+                                       if ( isNode && ret && ( ret.name != orgName || ret.type != orgType ) )
+                                               return ret;
+
+                                       // Update currentValue and corresponding argument in args array.
+                                       // Updated values will be used in next for-loop step.
+                                       if ( ret != null )
+                                               args[ 0 ] = currentValue = ret;
+
+                                       // ret == undefined will continue loop as nothing has happened.
+                               }
+                       }
+
+                       return currentValue;
+               },
+
+               /**
+                * Executes this rules group on name. Applicable only if filter rules for names were added.
+                *
+                * @param {String} currentName The name to be filtered.
+                * @returns {String} Filtered name.
+                */
+               execOnName: function( context, currentName ) {
+                       var i = 0,
+                               rules = this.rules,
+                               len = rules.length,
+                               rule;
+
+                       for ( ; currentName && i < len; i++ ) {
+                               rule = rules[ i ];
+                               if ( isRuleApplicable( context, rule ) )
+                                       currentName = currentName.replace( rule.value[ 0 ], rule.value[ 1 ] );
+                       }
+
+                       return currentName;
+               }
+       };
+
+       function addNamedRules( rulesGroups, newRules, priority, options ) {
+               var ruleName, rulesGroup;
+
+               for ( ruleName in newRules ) {
+                       rulesGroup = rulesGroups[ ruleName ];
+
+                       if ( !rulesGroup )
+                               rulesGroup = rulesGroups[ ruleName ] = new filterRulesGroup();
+
+                       rulesGroup.add( newRules[ ruleName ], priority, options );
+               }
+       }
+
+       function isRuleApplicable( context, rule ) {
+               if ( context.nonEditable && !rule.options.applyToAll )
+                       return false;
+
+               if ( context.nestedEditable && rule.options.excludeNestedEditable )
+                       return false;
+
+               return true;
+       }
+
+} )();
+
+/**
+ * @class CKEDITOR.htmlParser.filterRulesDefinition
+ * @abstract
+ */
diff --git a/sources/core/htmlparser/fragment.js b/sources/core/htmlparser/fragment.js
new file mode 100644 (file)
index 0000000..f696a12
--- /dev/null
@@ -0,0 +1,646 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+/**
+ * A lightweight representation of an HTML DOM structure.
+ *
+ * @class
+ * @constructor Creates a fragment class instance.
+ */
+CKEDITOR.htmlParser.fragment = function() {
+       /**
+        * The nodes contained in the root of this fragment.
+        *
+        *              var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
+        *              alert( fragment.children.length ); // 2
+        */
+       this.children = [];
+
+       /**
+        * Get the fragment parent. Should always be null.
+        *
+        * @property {Object} [=null]
+        */
+       this.parent = null;
+
+       /** @private */
+       this._ = {
+               isBlockLike: true,
+               hasInlineStarted: false
+       };
+};
+
+( function() {
+       // Block-level elements whose internal structure should be respected during
+       // parser fixing.
+       var nonBreakingBlocks = CKEDITOR.tools.extend( { table: 1, ul: 1, ol: 1, dl: 1 }, CKEDITOR.dtd.table, CKEDITOR.dtd.ul, CKEDITOR.dtd.ol, CKEDITOR.dtd.dl );
+
+       var listBlocks = { ol: 1, ul: 1 };
+
+       // Dtd of the fragment element, basically it accept anything except for intermediate structure, e.g. orphan <li>.
+       var rootDtd = CKEDITOR.tools.extend( {}, { html: 1 }, CKEDITOR.dtd.html, CKEDITOR.dtd.body, CKEDITOR.dtd.head, { style: 1, script: 1 } );
+
+       // Which element to create when encountered not allowed content.
+       var structureFixes = {
+               ul: 'li',
+               ol: 'li',
+               dl: 'dd',
+               table: 'tbody',
+               tbody: 'tr',
+               thead: 'tr',
+               tfoot: 'tr',
+               tr: 'td'
+       };
+
+       function isRemoveEmpty( node ) {
+               // Keep marked element event if it is empty.
+               if ( node.attributes[ 'data-cke-survive' ] )
+                       return false;
+
+               // Empty link is to be removed when empty but not anchor. (#7894)
+               return node.name == 'a' && node.attributes.href || CKEDITOR.dtd.$removeEmpty[ node.name ];
+       }
+
+       /**
+        * Creates a {@link CKEDITOR.htmlParser.fragment} from an HTML string.
+        *
+        *              var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<b>Sample</b> Text' );
+        *              alert( fragment.children[ 0 ].name );           // 'b'
+        *              alert( fragment.children[ 1 ].value );  // ' Text'
+        *
+        * @static
+        * @param {String} fragmentHtml The HTML to be parsed, filling the fragment.
+        * @param {CKEDITOR.htmlParser.element/String} [parent] Optional contextual
+        * element which makes the content been parsed as the content of this element and fix
+        * to match it.
+        * If not provided, then {@link CKEDITOR.htmlParser.fragment} will be used
+        * as the parent and it will be returned.
+        * @param {String/Boolean} [fixingBlock] When `parent` is a block limit element,
+        * and the param is a string value other than `false`, it is to
+        * avoid having block-less content as the direct children of parent by wrapping
+        * the content with a block element of the specified tag, e.g.
+        * when `fixingBlock` specified as `p`, the content `<body><i>foo</i></body>`
+        * will be fixed into `<body><p><i>foo</i></p></body>`.
+        * @returns {CKEDITOR.htmlParser.fragment/CKEDITOR.htmlParser.element} The created fragment or passed `parent`.
+        */
+       CKEDITOR.htmlParser.fragment.fromHtml = function( fragmentHtml, parent, fixingBlock ) {
+               var parser = new CKEDITOR.htmlParser();
+
+               var root = parent instanceof CKEDITOR.htmlParser.element ? parent : typeof parent == 'string' ? new CKEDITOR.htmlParser.element( parent ) : new CKEDITOR.htmlParser.fragment();
+
+               var pendingInline = [],
+                       pendingBRs = [],
+                       currentNode = root,
+                       // Indicate we're inside a <textarea> element, spaces should be touched differently.
+                       inTextarea = root.name == 'textarea',
+                       // Indicate we're inside a <pre> element, spaces should be touched differently.
+                       inPre = root.name == 'pre';
+
+               function checkPending( newTagName ) {
+                       var pendingBRsSent;
+
+                       if ( pendingInline.length > 0 ) {
+                               for ( var i = 0; i < pendingInline.length; i++ ) {
+                                       var pendingElement = pendingInline[ i ],
+                                               pendingName = pendingElement.name,
+                                               pendingDtd = CKEDITOR.dtd[ pendingName ],
+                                               currentDtd = currentNode.name && CKEDITOR.dtd[ currentNode.name ];
+
+                                       if ( ( !currentDtd || currentDtd[ pendingName ] ) && ( !newTagName || !pendingDtd || pendingDtd[ newTagName ] || !CKEDITOR.dtd[ newTagName ] ) ) {
+                                               if ( !pendingBRsSent ) {
+                                                       sendPendingBRs();
+                                                       pendingBRsSent = 1;
+                                               }
+
+                                               // Get a clone for the pending element.
+                                               pendingElement = pendingElement.clone();
+
+                                               // Add it to the current node and make it the current,
+                                               // so the new element will be added inside of it.
+                                               pendingElement.parent = currentNode;
+                                               currentNode = pendingElement;
+
+                                               // Remove the pending element (back the index by one
+                                               // to properly process the next entry).
+                                               pendingInline.splice( i, 1 );
+                                               i--;
+                                       } else {
+                                               // Some element of the same type cannot be nested, flat them,
+                                               // e.g. <a href="#">foo<a href="#">bar</a></a>. (#7894)
+                                               if ( pendingName == currentNode.name )
+                                                       addElement( currentNode, currentNode.parent, 1 ), i--;
+                                       }
+                               }
+                       }
+               }
+
+               function sendPendingBRs() {
+                       while ( pendingBRs.length )
+                               addElement( pendingBRs.shift(), currentNode );
+               }
+
+               // Rtrim empty spaces on block end boundary. (#3585)
+               function removeTailWhitespace( element ) {
+                       if ( element._.isBlockLike && element.name != 'pre' && element.name != 'textarea' ) {
+
+                               var length = element.children.length,
+                                       lastChild = element.children[ length - 1 ],
+                                       text;
+                               if ( lastChild && lastChild.type == CKEDITOR.NODE_TEXT ) {
+                                       if ( !( text = CKEDITOR.tools.rtrim( lastChild.value ) ) )
+                                               element.children.length = length - 1;
+                                       else
+                                               lastChild.value = text;
+                               }
+                       }
+               }
+
+               // Beside of simply append specified element to target, this function also takes
+               // care of other dirty lifts like forcing block in body, trimming spaces at
+               // the block boundaries etc.
+               //
+               // @param {Element} element  The element to be added as the last child of {@link target}.
+               // @param {Element} target The parent element to relieve the new node.
+               // @param {Boolean} [moveCurrent=false] Don't change the "currentNode" global unless
+               // there's a return point node specified on the element, otherwise move current onto {@link target} node.
+               //
+               function addElement( element, target, moveCurrent ) {
+                       target = target || currentNode || root;
+
+                       // Current element might be mangled by fix body below,
+                       // save it for restore later.
+                       var savedCurrent = currentNode;
+
+                       // Ignore any element that has already been added.
+                       if ( element.previous === undefined ) {
+                               if ( checkAutoParagraphing( target, element ) ) {
+                                       // Create a <p> in the fragment.
+                                       currentNode = target;
+                                       parser.onTagOpen( fixingBlock, {} );
+
+                                       // The new target now is the <p>.
+                                       element.returnPoint = target = currentNode;
+                               }
+
+                               removeTailWhitespace( element );
+
+                               // Avoid adding empty inline.
+                               if ( !( isRemoveEmpty( element ) && !element.children.length ) )
+                                       target.add( element );
+
+                               if ( element.name == 'pre' )
+                                       inPre = false;
+
+                               if ( element.name == 'textarea' )
+                                       inTextarea = false;
+                       }
+
+                       if ( element.returnPoint ) {
+                               currentNode = element.returnPoint;
+                               delete element.returnPoint;
+                       } else {
+                               currentNode = moveCurrent ? target : savedCurrent;
+                       }
+               }
+
+               // Auto paragraphing should happen when inline content enters the root element.
+               function checkAutoParagraphing( parent, node ) {
+
+                       // Check for parent that can contain block.
+                       if ( ( parent == root || parent.name == 'body' ) && fixingBlock &&
+                                       ( !parent.name || CKEDITOR.dtd[ parent.name ][ fixingBlock ] ) ) {
+                               var name, realName;
+
+                               if ( node.attributes && ( realName = node.attributes[ 'data-cke-real-element-type' ] ) )
+                                       name = realName;
+                               else
+                                       name = node.name;
+
+                               // Text node, inline elements are subjected, except for <script>/<style>.
+                               return name && name in CKEDITOR.dtd.$inline &&
+                                       !( name in CKEDITOR.dtd.head ) &&
+                                       !node.isOrphan ||
+                                       node.type == CKEDITOR.NODE_TEXT;
+                       }
+               }
+
+               // Judge whether two element tag names are likely the siblings from the same
+               // structural element.
+               function possiblySibling( tag1, tag2 ) {
+
+                       if ( tag1 in CKEDITOR.dtd.$listItem || tag1 in CKEDITOR.dtd.$tableContent )
+                               return tag1 == tag2 || tag1 == 'dt' && tag2 == 'dd' || tag1 == 'dd' && tag2 == 'dt';
+
+                       return false;
+               }
+
+               parser.onTagOpen = function( tagName, attributes, selfClosing, optionalClose ) {
+                       var element = new CKEDITOR.htmlParser.element( tagName, attributes );
+
+                       // "isEmpty" will be always "false" for unknown elements, so we
+                       // must force it if the parser has identified it as a selfClosing tag.
+                       if ( element.isUnknown && selfClosing )
+                               element.isEmpty = true;
+
+                       // Check for optional closed elements, including browser quirks and manually opened blocks.
+                       element.isOptionalClose = optionalClose;
+
+                       // This is a tag to be removed if empty, so do not add it immediately.
+                       if ( isRemoveEmpty( element ) ) {
+                               pendingInline.push( element );
+                               return;
+                       } else if ( tagName == 'pre' )
+                               inPre = true;
+                       else if ( tagName == 'br' && inPre ) {
+                               currentNode.add( new CKEDITOR.htmlParser.text( '\n' ) );
+                               return;
+                       } else if ( tagName == 'textarea' ) {
+                               inTextarea = true;
+                       }
+
+                       if ( tagName == 'br' ) {
+                               pendingBRs.push( element );
+                               return;
+                       }
+
+                       while ( 1 ) {
+                               var currentName = currentNode.name;
+
+                               var currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
+
+                               // If the element cannot be child of the current element.
+                               if ( !element.isUnknown && !currentNode.isUnknown && !currentDtd[ tagName ] ) {
+                                       // Current node doesn't have a close tag, time for a close
+                                       // as this element isn't fit in. (#7497)
+                                       if ( currentNode.isOptionalClose )
+                                               parser.onTagClose( currentName );
+                                       // Fixing malformed nested lists by moving it into a previous list item. (#3828)
+                                       else if ( tagName in listBlocks && currentName in listBlocks ) {
+                                               var children = currentNode.children,
+                                                       lastChild = children[ children.length - 1 ];
+
+                                               // Establish the list item if it's not existed.
+                                               if ( !( lastChild && lastChild.name == 'li' ) )
+                                                       addElement( ( lastChild = new CKEDITOR.htmlParser.element( 'li' ) ), currentNode );
+
+                                               !element.returnPoint && ( element.returnPoint = currentNode );
+                                               currentNode = lastChild;
+                                       }
+                                       // Establish new list root for orphan list items, but NOT to create
+                                       // new list for the following ones, fix them instead. (#6975)
+                                       // <dl><dt>foo<dd>bar</dl>
+                                       // <ul><li>foo<li>bar</ul>
+                                       else if ( tagName in CKEDITOR.dtd.$listItem &&
+                                                       !possiblySibling( tagName, currentName ) ) {
+                                               parser.onTagOpen( tagName == 'li' ? 'ul' : 'dl', {}, 0, 1 );
+                                       }
+                                       // We're inside a structural block like table and list, AND the incoming element
+                                       // is not of the same type (e.g. <td>td1<td>td2</td>), we simply add this new one before it,
+                                       // and most importantly, return back to here once this element is added,
+                                       // e.g. <table><tr><td>td1</td><p>p1</p><td>td2</td></tr></table>
+                                       else if ( currentName in nonBreakingBlocks &&
+                                                       !possiblySibling( tagName, currentName ) ) {
+                                               !element.returnPoint && ( element.returnPoint = currentNode );
+                                               currentNode = currentNode.parent;
+                                       } else {
+                                               // The current element is an inline element, which
+                                               // need to be continued even after the close, so put
+                                               // it in the pending list.
+                                               if ( currentName in CKEDITOR.dtd.$inline )
+                                                       pendingInline.unshift( currentNode );
+
+                                               // The most common case where we just need to close the
+                                               // current one and append the new one to the parent.
+                                               if ( currentNode.parent )
+                                                       addElement( currentNode, currentNode.parent, 1 );
+                                               // We've tried our best to fix the embarrassment here, while
+                                               // this element still doesn't find it's parent, mark it as
+                                               // orphan and show our tolerance to it.
+                                               else {
+                                                       element.isOrphan = 1;
+                                                       break;
+                                               }
+                                       }
+                               } else {
+                                       break;
+                               }
+                       }
+
+                       checkPending( tagName );
+                       sendPendingBRs();
+
+                       element.parent = currentNode;
+
+                       if ( element.isEmpty )
+                               addElement( element );
+                       else
+                               currentNode = element;
+               };
+
+               parser.onTagClose = function( tagName ) {
+                       // Check if there is any pending tag to be closed.
+                       for ( var i = pendingInline.length - 1; i >= 0; i-- ) {
+                               // If found, just remove it from the list.
+                               if ( tagName == pendingInline[ i ].name ) {
+                                       pendingInline.splice( i, 1 );
+                                       return;
+                               }
+                       }
+
+                       var pendingAdd = [],
+                               newPendingInline = [],
+                               candidate = currentNode;
+
+                       while ( candidate != root && candidate.name != tagName ) {
+                               // If this is an inline element, add it to the pending list, if we're
+                               // really closing one of the parents element later, they will continue
+                               // after it.
+                               if ( !candidate._.isBlockLike )
+                                       newPendingInline.unshift( candidate );
+
+                               // This node should be added to it's parent at this point. But,
+                               // it should happen only if the closing tag is really closing
+                               // one of the nodes. So, for now, we just cache it.
+                               pendingAdd.push( candidate );
+
+                               // Make sure return point is properly restored.
+                               candidate = candidate.returnPoint || candidate.parent;
+                       }
+
+                       if ( candidate != root ) {
+                               // Add all elements that have been found in the above loop.
+                               for ( i = 0; i < pendingAdd.length; i++ ) {
+                                       var node = pendingAdd[ i ];
+                                       addElement( node, node.parent );
+                               }
+
+                               currentNode = candidate;
+
+                               if ( candidate._.isBlockLike )
+                                       sendPendingBRs();
+
+                               addElement( candidate, candidate.parent );
+
+                               // The parent should start receiving new nodes now, except if
+                               // addElement changed the currentNode.
+                               if ( candidate == currentNode )
+                                       currentNode = currentNode.parent;
+
+                               pendingInline = pendingInline.concat( newPendingInline );
+                       }
+
+                       if ( tagName == 'body' )
+                               fixingBlock = false;
+               };
+
+               parser.onText = function( text ) {
+                       // Trim empty spaces at beginning of text contents except <pre> and <textarea>.
+                       if ( ( !currentNode._.hasInlineStarted || pendingBRs.length ) && !inPre && !inTextarea ) {
+                               text = CKEDITOR.tools.ltrim( text );
+
+                               if ( text.length === 0 )
+                                       return;
+                       }
+
+                       var currentName = currentNode.name,
+                               currentDtd = currentName ? ( CKEDITOR.dtd[ currentName ] || ( currentNode._.isBlockLike ? CKEDITOR.dtd.div : CKEDITOR.dtd.span ) ) : rootDtd;
+
+                       // Fix orphan text in list/table. (#8540) (#8870)
+                       if ( !inTextarea && !currentDtd[ '#' ] && currentName in nonBreakingBlocks ) {
+                               parser.onTagOpen( structureFixes[ currentName ] || '' );
+                               parser.onText( text );
+                               return;
+                       }
+
+                       sendPendingBRs();
+                       checkPending();
+
+                       // Shrinking consequential spaces into one single for all elements
+                       // text contents.
+                       if ( !inPre && !inTextarea )
+                               text = text.replace( /[\t\r\n ]{2,}|[\t\r\n]/g, ' ' );
+
+                       text = new CKEDITOR.htmlParser.text( text );
+
+
+                       if ( checkAutoParagraphing( currentNode, text ) )
+                               this.onTagOpen( fixingBlock, {}, 0, 1 );
+
+                       currentNode.add( text );
+               };
+
+               parser.onCDATA = function( cdata ) {
+                       currentNode.add( new CKEDITOR.htmlParser.cdata( cdata ) );
+               };
+
+               parser.onComment = function( comment ) {
+                       sendPendingBRs();
+                       checkPending();
+                       currentNode.add( new CKEDITOR.htmlParser.comment( comment ) );
+               };
+
+               // Parse it.
+               parser.parse( fragmentHtml );
+
+               sendPendingBRs();
+
+               // Close all pending nodes, make sure return point is properly restored.
+               while ( currentNode != root )
+                       addElement( currentNode, currentNode.parent, 1 );
+
+               removeTailWhitespace( root );
+
+               return root;
+       };
+
+       CKEDITOR.htmlParser.fragment.prototype = {
+
+               /**
+                * The node type. This is a constant value set to {@link CKEDITOR#NODE_DOCUMENT_FRAGMENT}.
+                *
+                * @readonly
+                * @property {Number} [=CKEDITOR.NODE_DOCUMENT_FRAGMENT]
+                */
+               type: CKEDITOR.NODE_DOCUMENT_FRAGMENT,
+
+               /**
+                * Adds a node to this fragment.
+                *
+                * @param {CKEDITOR.htmlParser.node} node The node to be added.
+                * @param {Number} [index] From where the insertion happens.
+                */
+               add: function( node, index ) {
+                       isNaN( index ) && ( index = this.children.length );
+
+                       var previous = index > 0 ? this.children[ index - 1 ] : null;
+                       if ( previous ) {
+                               // If the block to be appended is following text, trim spaces at
+                               // the right of it.
+                               if ( node._.isBlockLike && previous.type == CKEDITOR.NODE_TEXT ) {
+                                       previous.value = CKEDITOR.tools.rtrim( previous.value );
+
+                                       // If we have completely cleared the previous node.
+                                       if ( previous.value.length === 0 ) {
+                                               // Remove it from the list and add the node again.
+                                               this.children.pop();
+                                               this.add( node );
+                                               return;
+                                       }
+                               }
+
+                               previous.next = node;
+                       }
+
+                       node.previous = previous;
+                       node.parent = this;
+
+                       this.children.splice( index, 0, node );
+
+                       if ( !this._.hasInlineStarted )
+                               this._.hasInlineStarted = node.type == CKEDITOR.NODE_TEXT || ( node.type == CKEDITOR.NODE_ELEMENT && !node._.isBlockLike );
+               },
+
+               /**
+                * Filter this fragment's content with given filter.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.filter} filter
+                */
+               filter: function( filter, context ) {
+                       context = this.getFilterContext( context );
+
+                       // Apply the root filter.
+                       filter.onRoot( context, this );
+
+                       this.filterChildren( filter, false, context );
+               },
+
+               /**
+                * Filter this fragment's children with given filter.
+                *
+                * Element's children may only be filtered once by one
+                * instance of filter.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.filter} filter
+                * @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
+                */
+               filterChildren: function( filter, filterRoot, context ) {
+                       // If this element's children were already filtered
+                       // by current filter, don't filter them 2nd time.
+                       // This situation may occur when filtering bottom-up
+                       // (filterChildren() called manually in element's filter),
+                       // or in unpredictable edge cases when filter
+                       // is manipulating DOM structure.
+                       if ( this.childrenFilteredBy == filter.id )
+                               return;
+
+                       context = this.getFilterContext( context );
+
+                       // Filtering root if enforced.
+                       if ( filterRoot && !this.parent )
+                               filter.onRoot( context, this );
+
+                       this.childrenFilteredBy = filter.id;
+
+                       // Don't cache anything, children array may be modified by filter rule.
+                       for ( var i = 0; i < this.children.length; i++ ) {
+                               // Stay in place if filter returned false, what means
+                               // that node has been removed.
+                               if ( this.children[ i ].filter( filter, context ) === false )
+                                       i--;
+                       }
+               },
+
+               /**
+                * Writes the fragment HTML to a {@link CKEDITOR.htmlParser.basicWriter}.
+                *
+                *              var writer = new CKEDITOR.htmlWriter();
+                *              var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<P><B>Example' );
+                *              fragment.writeHtml( writer );
+                *              alert( writer.getHtml() ); // '<p><b>Example</b></p>'
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
+                * @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
+                */
+               writeHtml: function( writer, filter ) {
+                       if ( filter )
+                               this.filter( filter );
+
+                       this.writeChildrenHtml( writer );
+               },
+
+               /**
+                * Write and filtering the child nodes of this fragment.
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
+                * @param {CKEDITOR.htmlParser.filter} [filter] The filter to use when writing the HTML.
+                * @param {Boolean} [filterRoot] Whether to apply the "root" filter rule specified in the `filter`.
+                */
+               writeChildrenHtml: function( writer, filter, filterRoot ) {
+                       var context = this.getFilterContext();
+
+                       // Filtering root if enforced.
+                       if ( filterRoot && !this.parent && filter )
+                               filter.onRoot( context, this );
+
+                       if ( filter )
+                               this.filterChildren( filter, false, context );
+
+                       for ( var i = 0, children = this.children, l = children.length; i < l; i++ )
+                               children[ i ].writeHtml( writer );
+               },
+
+               /**
+                * Execute callback on each node (of given type) in this document fragment.
+                *
+                *              var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>foo<b>bar</b>bom</p>' );
+                *              fragment.forEach( function( node ) {
+                *                      console.log( node );
+                *              } );
+                *              // Will log:
+                *              // 1. document fragment,
+                *              // 2. <p> element,
+                *              // 3. "foo" text node,
+                *              // 4. <b> element,
+                *              // 5. "bar" text node,
+                *              // 6. "bom" text node.
+                *
+                * @since 4.1
+                * @param {Function} callback Function to be executed on every node.
+                * **Since 4.3** if `callback` returned `false` descendants of current node will be ignored.
+                * @param {CKEDITOR.htmlParser.node} callback.node Node passed as argument.
+                * @param {Number} [type] If specified `callback` will be executed only on nodes of this type.
+                * @param {Boolean} [skipRoot] Don't execute `callback` on this fragment.
+                */
+               forEach: function( callback, type, skipRoot ) {
+                       if ( !skipRoot && ( !type || this.type == type ) )
+                               var ret = callback( this );
+
+                       // Do not filter children if callback returned false.
+                       if ( ret === false )
+                               return;
+
+                       var children = this.children,
+                               node,
+                               i = 0;
+
+                       // We do not cache the size, because the list of nodes may be changed by the callback.
+                       for ( ; i < children.length; i++ ) {
+                               node = children[ i ];
+                               if ( node.type == CKEDITOR.NODE_ELEMENT )
+                                       node.forEach( callback, type );
+                               else if ( !type || node.type == type )
+                                       callback( node );
+                       }
+               },
+
+               getFilterContext: function( context ) {
+                       return context || {};
+               }
+       };
+} )();
diff --git a/sources/core/htmlparser/node.js b/sources/core/htmlparser/node.js
new file mode 100644 (file)
index 0000000..b38c8a8
--- /dev/null
@@ -0,0 +1,156 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+( function() {
+       /**
+        * A lightweight representation of HTML node.
+        *
+        * @since 4.1
+        * @class
+        * @constructor Creates a node class instance.
+        */
+       CKEDITOR.htmlParser.node = function() {};
+
+       CKEDITOR.htmlParser.node.prototype = {
+               /**
+                * Remove this node from a tree.
+                *
+                * @since 4.1
+                */
+               remove: function() {
+                       var children = this.parent.children,
+                               index = CKEDITOR.tools.indexOf( children, this ),
+                               previous = this.previous,
+                               next = this.next;
+
+                       previous && ( previous.next = next );
+                       next && ( next.previous = previous );
+                       children.splice( index, 1 );
+                       this.parent = null;
+               },
+
+               /**
+                * Replace this node with given one.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.node} node The node that will replace this one.
+                */
+               replaceWith: function( node ) {
+                       var children = this.parent.children,
+                               index = CKEDITOR.tools.indexOf( children, this ),
+                               previous = node.previous = this.previous,
+                               next = node.next = this.next;
+
+                       previous && ( previous.next = node );
+                       next && ( next.previous = node );
+
+                       children[ index ] = node;
+
+                       node.parent = this.parent;
+                       this.parent = null;
+               },
+
+               /**
+                * Insert this node after given one.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.node} node The node that will precede this element.
+                */
+               insertAfter: function( node ) {
+                       var children = node.parent.children,
+                               index = CKEDITOR.tools.indexOf( children, node ),
+                               next = node.next;
+
+                       children.splice( index + 1, 0, this );
+
+                       this.next = node.next;
+                       this.previous = node;
+                       node.next = this;
+                       next && ( next.previous = this );
+
+                       this.parent = node.parent;
+               },
+
+               /**
+                * Insert this node before given one.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.node} node The node that will follow this element.
+                */
+               insertBefore: function( node ) {
+                       var children = node.parent.children,
+                               index = CKEDITOR.tools.indexOf( children, node );
+
+                       children.splice( index, 0, this );
+
+                       this.next = node;
+                       this.previous = node.previous;
+                       node.previous && ( node.previous.next = this );
+                       node.previous = this;
+
+                       this.parent = node.parent;
+               },
+
+               /**
+                * Gets the closest ancestor element of this element which satisfies given condition
+                *
+                * @since 4.3
+                * @param {String/Object/Function} condition Name of an ancestor, hash of names or validator function.
+                * @returns {CKEDITOR.htmlParser.element} The closest ancestor which satisfies given condition or `null`.
+                */
+               getAscendant: function( condition ) {
+                       var checkFn =
+                               typeof condition == 'function' ?
+                                       condition :
+                               typeof condition == 'string' ?
+                                       function( el ) {
+                                               return el.name == condition;
+                                       } :
+                                       function( el ) {
+                                               return el.name in condition;
+                                       };
+
+                       var parent = this.parent;
+
+                       // Parent has to be an element - don't check doc fragment.
+                       while ( parent && parent.type == CKEDITOR.NODE_ELEMENT ) {
+                               if ( checkFn( parent ) )
+                                       return parent;
+                               parent = parent.parent;
+                       }
+
+                       return null;
+               },
+
+               /**
+                * Wraps this element with given `wrapper`.
+                *
+                * @since 4.3
+                * @param {CKEDITOR.htmlParser.element} wrapper The element which will be this element's new parent.
+                * @returns {CKEDITOR.htmlParser.element} Wrapper.
+                */
+               wrapWith: function( wrapper ) {
+                       this.replaceWith( wrapper );
+                       wrapper.add( this );
+                       return wrapper;
+               },
+
+               /**
+                * Gets this node's index in its parent's children array.
+                *
+                * @since 4.3
+                * @returns {Number}
+                */
+               getIndex: function() {
+                       return CKEDITOR.tools.indexOf( this.parent.children, this );
+               },
+
+               getFilterContext: function( context ) {
+                       return context || {};
+               }
+       };
+} )();
diff --git a/sources/core/htmlparser/text.js b/sources/core/htmlparser/text.js
new file mode 100644 (file)
index 0000000..190e85a
--- /dev/null
@@ -0,0 +1,70 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+ 'use strict';
+
+( function() {
+       /**
+        * A lightweight representation of HTML text.
+        *
+        * @class
+        * @extends CKEDITOR.htmlParser.node
+        * @constructor Creates a text class instance.
+        * @param {String} value The text node value.
+        */
+       CKEDITOR.htmlParser.text = function( value ) {
+               /**
+                * The text value.
+                *
+                * @property {String}
+                */
+               this.value = value;
+
+               /** @private */
+               this._ = {
+                       isBlockLike: false
+               };
+       };
+
+       CKEDITOR.htmlParser.text.prototype = CKEDITOR.tools.extend( new CKEDITOR.htmlParser.node(), {
+               /**
+                * The node type. This is a constant value set to {@link CKEDITOR#NODE_TEXT}.
+                *
+                * @readonly
+                * @property {Number} [=CKEDITOR.NODE_TEXT]
+                */
+               type: CKEDITOR.NODE_TEXT,
+
+               /**
+                * Filter this text node with given filter.
+                *
+                * @since 4.1
+                * @param {CKEDITOR.htmlParser.filter} filter
+                * @returns {Boolean} Method returns `false` when this text node has
+                * been removed. This is an information for {@link CKEDITOR.htmlParser.element#filterChildren}
+                * that it has to repeat filter on current position in parent's children array.
+                */
+               filter: function( filter, context ) {
+                       if ( !( this.value = filter.onText( context, this.value, this ) ) ) {
+                               this.remove();
+                               return false;
+                       }
+               },
+
+               /**
+                * Writes the HTML representation of this text to a {CKEDITOR.htmlParser.basicWriter}.
+                *
+                * @param {CKEDITOR.htmlParser.basicWriter} writer The writer to which write the HTML.
+                * @param {CKEDITOR.htmlParser.filter} [filter] The filter to be applied to this node.
+                * **Note:** it's unsafe to filter offline (not appended) node.
+                */
+               writeHtml: function( writer, filter ) {
+                       if ( filter )
+                               this.filter( filter );
+
+                       writer.text( this.value );
+               }
+       } );
+} )();
diff --git a/sources/core/keystrokehandler.js b/sources/core/keystrokehandler.js
new file mode 100644 (file)
index 0000000..c84089b
--- /dev/null
@@ -0,0 +1,169 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Controls keystrokes typing in an editor instance.
+ *
+ * @class
+ * @constructor Creates a keystrokeHandler class instance.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+CKEDITOR.keystrokeHandler = function( editor ) {
+       if ( editor.keystrokeHandler )
+               return editor.keystrokeHandler;
+
+       /**
+        * A list of keystrokes associated with commands. Each entry points to the
+        * command to be executed.
+        *
+        * Since CKEditor 4 there is no need to modify this property directly during the runtime.
+        * Use {@link CKEDITOR.editor#setKeystroke} instead.
+        */
+       this.keystrokes = {};
+
+       /**
+        * A list of keystrokes that should be blocked if not defined in
+        * {@link #keystrokes}. In this way it is possible to block the default
+        * browser behavior for those keystrokes.
+        */
+       this.blockedKeystrokes = {};
+
+       this._ = {
+               editor: editor
+       };
+
+       return this;
+};
+
+( function() {
+       var cancel;
+
+       var onKeyDown = function( event ) {
+                       // The DOM event object is passed by the "data" property.
+                       event = event.data;
+
+                       var keyCombination = event.getKeystroke();
+                       var command = this.keystrokes[ keyCombination ];
+                       var editor = this._.editor;
+
+                       cancel = ( editor.fire( 'key', { keyCode: keyCombination, domEvent: event } ) === false );
+
+                       if ( !cancel ) {
+                               if ( command ) {
+                                       var data = { from: 'keystrokeHandler' };
+                                       cancel = ( editor.execCommand( command, data ) !== false );
+                               }
+
+                               if ( !cancel )
+                                       cancel = !!this.blockedKeystrokes[ keyCombination ];
+                       }
+
+                       if ( cancel )
+                               event.preventDefault( true );
+
+                       return !cancel;
+               };
+
+       var onKeyPress = function( event ) {
+                       if ( cancel ) {
+                               cancel = false;
+                               event.data.preventDefault( true );
+                       }
+               };
+
+       CKEDITOR.keystrokeHandler.prototype = {
+               /**
+                * Attaches this keystroke handle to a DOM object. Keystrokes typed
+                * over this object will be handled by this keystrokeHandler.
+                *
+                * @param {CKEDITOR.dom.domObject} domObject The DOM object to attach to.
+                */
+               attach: function( domObject ) {
+                       // For most browsers, it is enough to listen to the keydown event
+                       // only.
+                       domObject.on( 'keydown', onKeyDown, this );
+
+                       // Some browsers instead, don't cancel key events in the keydown, but in the
+                       // keypress. So we must do a longer trip in those cases.
+                       if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )
+                               domObject.on( 'keypress', onKeyPress, this );
+               }
+       };
+} )();
+
+/**
+ * A list associating keystrokes with editor commands. Each element in the list
+ * is an array where the first item is the keystroke, and the second is the
+ * name of the command to be executed.
+ *
+ * This setting should be used to define (as well as to overwrite or remove) keystrokes
+ * set by plugins (like `link` and `basicstyles`). If you want to set a keystroke
+ * for your plugin or during the runtime, use {@link CKEDITOR.editor#setKeystroke} instead.
+ *
+ * Since default keystrokes are set by the {@link CKEDITOR.editor#setKeystroke}
+ * method, by default `config.keystrokes` is an empty array.
+ *
+ * See {@link CKEDITOR.editor#setKeystroke} documentation for more details
+ * regarding the start up order.
+ *
+ *             // Change default Ctrl+L keystroke for 'link' command to Ctrl+Shift+L.
+ *             config.keystrokes = [
+ *                     ...
+ *                     [ CKEDITOR.CTRL + CKEDITOR.SHIFT + 76, 'link' ],        // Ctrl+Shift+L
+ *                     ...
+ *             ];
+ *
+ * To reset a particular keystroke, the following approach can be used:
+ *
+ *             // Disable default Ctrl+L keystroke which executes the 'link' command by default.
+ *             config.keystrokes = [
+ *                     ...
+ *                     [ CKEDITOR.CTRL + 76, null ],                                           // Ctrl+L
+ *                     ...
+ *             ];
+ *
+ * In order to reset all default keystrokes, a {@link CKEDITOR#instanceReady} callback should be
+ * used. This is since editor defaults are merged rather than overwritten by
+ * user keystrokes.
+ *
+ * **Note**: This can be potentially harmful for the editor. Avoid this unless you are
+ * aware of the consequences.
+ *
+ *             // Reset all default keystrokes.
+ *             config.on.instanceReady = function() {
+ *                     this.keystrokeHandler.keystrokes = [];
+ *             };
+ *
+ * @cfg {Array} [keystrokes=[]]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * Fired when any keyboard key (or a combination thereof) is pressed in the editing area.
+ *
+ *             editor.on( 'key', function( evt ) {
+ *                     if ( evt.data.keyCode == CKEDITOR.CTRL + 90 ) {
+ *                             // Do something...
+ *
+ *                             // Cancel the event, so other listeners will not be executed and
+ *                             // the keydown's default behavior will be prevented.
+ *                             evt.cancel();
+ *                     }
+ *             } );
+ *
+ * Usually you will want to use the {@link CKEDITOR.editor#setKeystroke} method or
+ * the {@link CKEDITOR.config#keystrokes} option to attach a keystroke to some {@link CKEDITOR.command command}.
+ * Key event listeners are usuful when some action should be executed conditionally, based
+ * for example on precise selection location.
+ *
+ * @event key
+ * @member CKEDITOR.editor
+ * @param data
+ * @param {Number} data.keyCode A number representing the key code (or a combination thereof).
+ * It is the sum of the current key code and the {@link CKEDITOR#CTRL}, {@link CKEDITOR#SHIFT}
+ * and {@link CKEDITOR#ALT} constants, if those are pressed.
+ * @param {CKEDITOR.dom.event} data.domEvent A `keydown` DOM event instance. Available since CKEditor 4.4.1.
+ * @param {CKEDITOR.editor} editor This editor instance.
+ */
diff --git a/sources/core/lang.js b/sources/core/lang.js
new file mode 100644 (file)
index 0000000..8766055
--- /dev/null
@@ -0,0 +1,103 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       /**
+        * Stores language-related functions.
+        *
+        * @class
+        * @singleton
+        */
+       CKEDITOR.lang = {
+               /**
+                * The list of languages available in the editor core.
+                *
+                *              alert( CKEDITOR.lang.languages.en ); // 1
+                */
+               languages: {
+                       af: 1, ar: 1, az: 1, bg: 1, bn: 1, bs: 1, ca: 1, cs: 1, cy: 1, da: 1, de: 1, 'de-ch': 1, el: 1,
+                       'en-au': 1, 'en-ca': 1, 'en-gb': 1, en: 1, eo: 1, es: 1, et: 1, eu: 1, fa: 1, fi: 1, fo: 1,
+                       'fr-ca': 1, fr: 1, gl: 1, gu: 1, he: 1, hi: 1, hr: 1, hu: 1, id: 1, is: 1, it: 1, ja: 1, ka: 1,
+                       km: 1, ko: 1, ku: 1, lt: 1, lv: 1, mk: 1, mn: 1, ms: 1, nb: 1, nl: 1, no: 1, oc: 1, pl: 1, 'pt-br': 1,
+                       pt: 1, ro: 1, ru: 1, si: 1, sk: 1, sl: 1, sq: 1, 'sr-latn': 1, sr: 1, sv: 1, th: 1, tr: 1, tt: 1, ug: 1,
+                       uk: 1, vi: 1, 'zh-cn': 1, zh: 1
+               },
+
+               /**
+                * The list of languages that are written Right-To-Left (RTL) and are supported by the editor.
+                */
+               rtl: { ar: 1, fa: 1, he: 1, ku: 1, ug: 1 },
+
+               /**
+                * Loads a specific language file, or auto detects it. A callback is
+                * then called when the file gets loaded.
+                *
+                * @param {String} languageCode The code of the language file to be
+                * loaded. If null or empty, autodetection will be performed. The
+                * same happens if the language is not supported.
+                * @param {String} defaultLanguage The language to be used if
+                * `languageCode` is not supported or if the autodetection fails.
+                * @param {Function} callback A function to be called once the
+                * language file is loaded. Two parameters are passed to this
+                * function: the language code and the loaded language entries.
+                */
+               load: function( languageCode, defaultLanguage, callback ) {
+                       // If no languageCode - fallback to browser or default.
+                       // If languageCode - fallback to no-localized version or default.
+                       if ( !languageCode || !CKEDITOR.lang.languages[ languageCode ] )
+                               languageCode = this.detect( defaultLanguage, languageCode );
+
+                       var that = this,
+                               loadedCallback = function() {
+                                       that[ languageCode ].dir = that.rtl[ languageCode ] ? 'rtl' : 'ltr';
+                                       callback( languageCode, that[ languageCode ] );
+                               };
+
+                       if ( !this[ languageCode ] )
+                               CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( 'lang/' + languageCode + '.js' ), loadedCallback, this );
+                       else
+                               loadedCallback();
+               },
+
+               /**
+                * Returns the language that best fits the user language. For example,
+                * suppose that the user language is "pt-br". If this language is
+                * supported by the editor, it is returned. Otherwise, if only "pt" is
+                * supported, it is returned instead. If none of the previous are
+                * supported, a default language is then returned.
+                *
+                *              alert( CKEDITOR.lang.detect( 'en' ) ); // e.g., in a German browser: 'de'
+                *
+                * @param {String} defaultLanguage The default language to be returned
+                * if the user language is not supported.
+                * @param {String} [probeLanguage] A language code to try to use,
+                * instead of the browser-based autodetection.
+                * @returns {String} The detected language code.
+                */
+               detect: function( defaultLanguage, probeLanguage ) {
+                       var languages = this.languages;
+                       probeLanguage = probeLanguage || navigator.userLanguage || navigator.language || defaultLanguage;
+
+                       var parts = probeLanguage.toLowerCase().match( /([a-z]+)(?:-([a-z]+))?/ ),
+                               lang = parts[ 1 ],
+                               locale = parts[ 2 ];
+
+                       if ( languages[ lang + '-' + locale ] )
+                               lang = lang + '-' + locale;
+                       else if ( !languages[ lang ] )
+                               lang = null;
+
+                       CKEDITOR.lang.detect = lang ?
+                       function() {
+                               return lang;
+                       } : function( defaultLanguage ) {
+                               return defaultLanguage;
+                       };
+
+                       return lang || defaultLanguage;
+               }
+       };
+
+} )();
diff --git a/sources/core/loader.js b/sources/core/loader.js
new file mode 100644 (file)
index 0000000..249a8cf
--- /dev/null
@@ -0,0 +1,225 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.loader} objects, which is used to
+ *             load core scripts and their dependencies from _source.
+ */
+
+if ( typeof CKEDITOR == 'undefined' )
+       CKEDITOR = {}; // jshint ignore:line
+
+if ( !CKEDITOR.loader ) {
+       /**
+        * Load core scripts and their dependencies from _source.
+        *
+        * @class
+        * @singleton
+        */
+       CKEDITOR.loader = ( function() {
+               // Table of script names and their dependencies.
+               var scripts = {
+                       '_bootstrap': [
+                               'config', 'creators/inline', 'creators/themedui', 'editable', 'ckeditor', 'plugins',
+                               'scriptloader', 'style', 'tools',
+                               // The following are entries that we want to force loading at the end to avoid dependence recursion.
+                               'dom/comment', 'dom/elementpath', 'dom/text', 'dom/rangelist', 'skin'
+                       ],
+                       'ckeditor': [
+                               'ckeditor_basic', 'log', 'dom', 'dtd', 'dom/document', 'dom/element', 'dom/iterator', 'editor', 'event',
+                               'htmldataprocessor', 'htmlparser', 'htmlparser/element', 'htmlparser/fragment', 'htmlparser/filter',
+                               'htmlparser/basicwriter', 'template', 'tools'
+                       ],
+                       'ckeditor_base': [],
+                       'ckeditor_basic': [ 'editor_basic', 'env', 'event' ],
+                       'command': [],
+                       'config': [ 'ckeditor_base' ],
+                       'dom': [],
+                       'dom/comment': [ 'dom/node' ],
+                       'dom/document': [ 'dom/node', 'dom/window' ],
+                       'dom/documentfragment': [ 'dom/element' ],
+                       'dom/element': [ 'dom', 'dom/document', 'dom/domobject', 'dom/node', 'dom/nodelist', 'tools' ],
+                       'dom/elementpath': [ 'dom/element' ],
+                       'dom/event': [],
+                       'dom/iterator': [ 'dom/range' ],
+                       'dom/node': [ 'dom/domobject', 'tools' ],
+                       'dom/nodelist': [ 'dom/node' ],
+                       'dom/domobject': [ 'dom/event' ],
+                       'dom/range': [ 'dom/document', 'dom/documentfragment', 'dom/element', 'dom/walker' ],
+                       'dom/rangelist': [ 'dom/range' ],
+                       'dom/text': [ 'dom/node', 'dom/domobject' ],
+                       'dom/walker': [ 'dom/node' ],
+                       'dom/window': [ 'dom/domobject' ],
+                       'dtd': [ 'tools' ],
+                       'editable': [ 'editor', 'tools' ],
+                       'editor': [
+                               'command', 'config', 'editor_basic', 'filter', 'focusmanager', 'keystrokehandler', 'lang',
+                               'plugins', 'tools', 'ui'
+                       ],
+                       'editor_basic': [ 'event' ],
+                       'env': [],
+                       'event': [],
+                       'filter': [ 'dtd', 'tools' ],
+                       'focusmanager': [],
+                       'htmldataprocessor': [ 'htmlparser', 'htmlparser/basicwriter', 'htmlparser/fragment', 'htmlparser/filter' ],
+                       'htmlparser': [],
+                       'htmlparser/comment': [ 'htmlparser', 'htmlparser/node' ],
+                       'htmlparser/element': [ 'htmlparser', 'htmlparser/fragment', 'htmlparser/node' ],
+                       'htmlparser/fragment': [ 'htmlparser', 'htmlparser/comment', 'htmlparser/text', 'htmlparser/cdata' ],
+                       'htmlparser/text': [ 'htmlparser', 'htmlparser/node' ],
+                       'htmlparser/cdata': [ 'htmlparser', 'htmlparser/node' ],
+                       'htmlparser/filter': [ 'htmlparser' ],
+                       'htmlparser/basicwriter': [ 'htmlparser' ],
+                       'htmlparser/node': [ 'htmlparser' ],
+                       'keystrokehandler': [ 'event' ],
+                       'lang': [],
+                       'log': [ 'ckeditor_basic' ],
+                       'plugins': [ 'resourcemanager' ],
+                       'resourcemanager': [ 'scriptloader', 'tools' ],
+                       'scriptloader': [ 'dom/element', 'env' ],
+                       'selection': [ 'dom/range', 'dom/walker' ],
+                       'skin': [],
+                       'style': [ 'selection' ],
+                       'template': [],
+                       'tools': [ 'env' ],
+                       'ui': [],
+                       'creators/themedui': [],
+                       'creators/inline': []
+               };
+
+               // The production implementation contains a fixed timestamp generated by the releaser.
+               var timestamp = '%TIMESTAMP%';
+               // The development implementation contains a current timestamp.                                 // %REMOVE_LINE%
+               timestamp = ( CKEDITOR && CKEDITOR.timestamp ) || ( new Date() ).valueOf();             // %REMOVE_LINE%
+
+               var getUrl = function( resource ) {
+                               if ( CKEDITOR && CKEDITOR.getUrl )
+                                       return CKEDITOR.getUrl( resource );
+
+                               return CKEDITOR.basePath + resource + ( resource.indexOf( '?' ) >= 0 ? '&' : '?' ) + 't=' + timestamp;
+                       };
+
+               var pendingLoad = [];
+
+               return {
+                       /**
+                        * The list of loaded scripts in their loading order.
+                        *
+                        *              // Alert the loaded script names.
+                        *              alert( CKEDITOR.loader.loadedScripts );
+                        */
+                       loadedScripts: [],
+                       /**
+                        * Table of script names and their dependencies.
+                        *
+                        * @property {Array}
+                        */
+                       scripts: scripts,
+
+                       /**
+                        * @todo
+                        */
+                       loadPending: function() {
+                               var scriptName = pendingLoad.shift();
+
+                               if ( !scriptName )
+                                       return;
+
+                               var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
+
+                               var script = document.createElement( 'script' );
+                               script.type = 'text/javascript';
+                               script.src = scriptSrc;
+
+                               function onScriptLoaded() {
+                                       // Append this script to the list of loaded scripts.
+                                       CKEDITOR.loader.loadedScripts.push( scriptName );
+
+                                       // Load the next.
+                                       CKEDITOR.loader.loadPending();
+                               }
+
+                               // We must guarantee the execution order of the scripts, so we
+                               // need to load them one by one. (#4145)
+                               // The following if/else block has been taken from the scriptloader core code.
+                               if ( typeof script.onreadystatechange !== 'undefined' ) {
+                                       /** @ignore */
+                                       script.onreadystatechange = function() {
+                                               if ( script.readyState == 'loaded' || script.readyState == 'complete' ) {
+                                                       script.onreadystatechange = null;
+                                                       onScriptLoaded();
+                                               }
+                                       };
+                               } else {
+                                       /** @ignore */
+                                       script.onload = function() {
+                                               // Some browsers, such as Safari, may call the onLoad function
+                                               // immediately. Which will break the loading sequence. (#3661)
+                                               setTimeout( function() {
+                                                       onScriptLoaded( scriptName );
+                                               }, 0 );
+                                       };
+                               }
+
+                               document.body.appendChild( script );
+                       },
+
+                       /**
+                        * Loads a specific script, including its dependencies. This is not a
+                        * synchronous loading, which means that the code to be loaded will
+                        * not necessarily be available after this call.
+                        *
+                        *              CKEDITOR.loader.load( 'dom/element' );
+                        *
+                        * @param {String} scriptName
+                        * @param {Boolean} [defer=false]
+                        * @todo params
+                        */
+                       load: function( scriptName, defer ) {
+                               // Check if the script has already been loaded.
+                               if ( ( 's:' + scriptName ) in this.loadedScripts )
+                                       return;
+
+                               // Get the script dependencies list.
+                               var dependencies = scripts[ scriptName ];
+                               if ( !dependencies )
+                                       throw 'The script name"' + scriptName + '" is not defined.';
+
+                               // Mark the script as loaded, even before really loading it, to
+                               // avoid cross references recursion.
+                               // Prepend script name with 's:' to avoid conflict with Array's methods.
+                               this.loadedScripts[ 's:' + scriptName ] = true;
+
+                               // Load all dependencies first.
+                               for ( var i = 0; i < dependencies.length; i++ )
+                                       this.load( dependencies[ i ], true );
+
+                               var scriptSrc = getUrl( 'core/' + scriptName + '.js' );
+
+                               // Append the <script> element to the DOM.
+                               // If the page is fully loaded, we can't use document.write
+                               // but if the script is run while the body is loading then it's safe to use it
+                               // Unfortunately, Firefox <3.6 doesn't support document.readyState, so it won't get this improvement
+                               if ( document.body && ( !document.readyState || document.readyState == 'complete' ) ) {
+                                       pendingLoad.push( scriptName );
+
+                                       if ( !defer )
+                                               this.loadPending();
+                               } else {
+                                       // Append this script to the list of loaded scripts.
+                                       this.loadedScripts.push( scriptName );
+
+                                       document.write( '<script src="' + scriptSrc + '" type="text/javascript"><\/script>' );
+                               }
+                       }
+               };
+       } )();
+}
+
+// Check if any script has been defined for autoload.
+if ( CKEDITOR._autoLoad ) {
+       CKEDITOR.loader.load( CKEDITOR._autoLoad );
+       delete CKEDITOR._autoLoad;
+}
diff --git a/sources/core/log.js b/sources/core/log.js
new file mode 100644 (file)
index 0000000..228789e
--- /dev/null
@@ -0,0 +1,127 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines {@link CKEDITOR#verbosity} and binary flags {@link CKEDITOR#VERBOSITY_WARN} and
+ * {@link CKEDITOR#VERBOSITY_ERROR}. Defines also the {@link CKEDITOR#error} and {@link CKEDITOR#warn} functions
+ * and the default handler for the {@link CKEDITOR#log} event.
+ */
+
+/* global console */
+
+'use strict';
+
+/**
+ * Warning reporting verbosity level. When {@link CKEDITOR#verbosity} is set to this value, only {@link CKEDITOR#warn}
+ * messages will be output to the console. It is a binary flag so it might be combined with
+ * the {@link CKEDITOR#VERBOSITY_ERROR} flag.
+ *
+ * @since 4.5.4
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.VERBOSITY_WARN = 1;
+
+/**
+ * Error reporting verbosity level. When {@link CKEDITOR#verbosity} is set to this value, only {@link CKEDITOR#error}
+ * messages will be output to the console. It is a binary flag so it might be combined with
+ * the {@link CKEDITOR#VERBOSITY_WARN} flag.
+ *
+ * @since 4.5.4
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.VERBOSITY_ERROR = 2;
+
+/**
+ * Verbosity of {@link CKEDITOR#error} and {@link CKEDITOR#warn} methods. Accepts binary flags
+ * {@link CKEDITOR#VERBOSITY_WARN} and {@link CKEDITOR#VERBOSITY_ERROR}.
+ *
+ *                     CKEDITOR.verbosity = 0; // No console output after CKEDITOR.warn and CKEDITOR.error methods.
+ *                     CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN; // Console output after CKEDITOR.warn only.
+ *                     CKEDITOR.verbosity = CKEDITOR.VERBOSITY_ERROR; // Console output after CKEDITOR.error only.
+ *                     CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN | CKEDITOR.VERBOSITY_ERROR; // Console output after both methods.
+ *
+ * Default value enables both {@link CKEDITOR#VERBOSITY_WARN} and {@link CKEDITOR#VERBOSITY_ERROR}.
+ *
+ * @since 4.5.4
+ * @member CKEDITOR
+ * @type {Number}
+ */
+CKEDITOR.verbosity = CKEDITOR.VERBOSITY_WARN | CKEDITOR.VERBOSITY_ERROR;
+
+/**
+ * Warning reporting function. When {@link CKEDITOR#verbosity} has the {@link CKEDITOR#VERBOSITY_WARN} flag set, it fires
+ * the {@link CKEDITOR#log} event with type set to `warn`. Fired event contains also provided `errorCode` and `additionalData`.
+ *
+ * @since 4.5.4
+ * @member CKEDITOR
+ * @param {String} errorCode Error code describing reported problem.
+ * @param {Object} [additionalData] Additional data associated with reported problem.
+ */
+CKEDITOR.warn = function( errorCode, additionalData ) {
+       if ( CKEDITOR.verbosity & CKEDITOR.VERBOSITY_WARN ) {
+               CKEDITOR.fire( 'log', { type: 'warn', errorCode: errorCode, additionalData: additionalData } );
+       }
+};
+
+/**
+ * Error reporting function. When {@link CKEDITOR#verbosity} has {@link CKEDITOR#VERBOSITY_ERROR} flag set, it fires
+ * {@link CKEDITOR#log} event with the type set to `error`. The fired event also contains the provided `errorCode` and
+ * `additionalData`.
+ *
+ * @since 4.5.4
+ * @member CKEDITOR
+ * @param {String} errorCode Error code describing the reported problem.
+ * @param {Object} [additionalData] Additional data associated with the reported problem.
+ */
+CKEDITOR.error = function( errorCode, additionalData ) {
+       if ( CKEDITOR.verbosity & CKEDITOR.VERBOSITY_ERROR ) {
+               CKEDITOR.fire( 'log', { type: 'error', errorCode: errorCode, additionalData: additionalData } );
+       }
+};
+
+/**
+ * Fired by {@link CKEDITOR#warn} and {@link CKEDITOR#error} methods.
+ * Default listener logs provided information to the console.
+ *
+ * This event can be used to provide a custom error/warning handler:
+ *
+ *                     CKEDTIOR.on( 'log', function( evt ) {
+ *                             // Cancel default listener.
+ *                                     evt.cancel();
+ *                                     // Log event data.
+ *                                     console.log( evt.data.type, evt.data.errorCode, evt.data.additionalData );
+ *                     } );
+ *
+ * @since 4.5.4
+ * @event log
+ * @member CKEDITOR
+ * @param data
+ * @param {String} data.type Log type. Can be `error` or `warn`.
+ * @param {String} data.errorCode Error code describing the reported problem.
+ * @param {Object} [data.additionalData] Additional data associated with this log event.
+ */
+CKEDITOR.on( 'log', function( evt ) {
+       if ( !window.console || !window.console.log ) {
+               return;
+       }
+
+       var type = console[ evt.data.type ] ? evt.data.type : 'log',
+               errorCode = evt.data.errorCode,
+               additionalData = evt.data.additionalData,
+               prefix = '[CKEDITOR] ',
+               errorCodeLabel = 'Error code: ';
+
+       if ( additionalData ) {
+               console[ type ]( prefix + errorCodeLabel + errorCode + '.', additionalData );
+       } else {
+               console[ type ]( prefix + errorCodeLabel + errorCode + '.' );
+       }
+
+       console[ type ]( prefix + 'For more information about this error go to http://docs.ckeditor.com/#!/guide/dev_errors-section-' + errorCode );
+}, null, null, 999 );
diff --git a/sources/core/plugindefinition.js b/sources/core/plugindefinition.js
new file mode 100644 (file)
index 0000000..9ff7683
--- /dev/null
@@ -0,0 +1,177 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the "virtual" {@link CKEDITOR.pluginDefinition} class which
+ *             contains the defintion of a plugin. This file serves documentation
+ *             purposes only.
+ */
+
+/**
+ * A virtual class that just illustrates the features of plugin objects which are
+ * passed to the {@link CKEDITOR.plugins#add} method.
+ *
+ * This class is not really a part of the API, so its constructor should not be called.
+ *
+ * See also:
+ *
+ * * [The Plugin SDK](#!/guide/plugin_sdk_intro)
+ * * [Creating a CKEditor plugin in 20 Lines of Code](#!/guide/plugin_sdk_sample)
+ * * [Creating a Simple Plugin Tutorial](#!/guide/plugin_sdk_sample_1)
+ *
+ * @class CKEDITOR.pluginDefinition
+ * @abstract
+ */
+
+/**
+ * A list of plugins that are required by this plugin. Note that this property
+ * does not determine the loading order of the plugins.
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     requires: 'button,selection'
+ *             } );
+ *
+ * Or:
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     requires: [ 'button', 'selection' ]
+ *             } );
+ *
+ * @property {String/String[]} requires
+ */
+
+/**
+ * The list of language files available for this plugin. These files are stored inside
+ * the `lang` directory in the plugin directory, follow the name
+ * pattern of `langCode.js`, and contain the language definition created with
+ * {@link CKEDITOR.plugins#setLang}.
+ *
+ * When the plugin is being loaded, the editor checks this list to see if
+ * a language file in the current editor language ({@link CKEDITOR.editor#langCode})
+ * is available, and if so, loads it. Otherwise, the file represented by the first item
+ * in the list is loaded.
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     lang: 'en,fr'
+ *             } );
+ *
+ * Or:
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     lang: [ 'en', 'fr' ]
+ *             } );
+ *
+ * @property {String/String[]} lang
+ */
+
+/**
+ * A function called when the plugin definition is loaded for the first time.
+ * It is usually used to execute some code once for the entire page,
+ * for instance code that uses the {@link CKEDITOR}'s methods such as the {@link CKEDITOR#addCss} method.
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     onLoad: function() {
+ *                             CKEDITOR.addCss( '.cke_some_class { ... }' );
+ *                     }
+ *             } );
+ *
+ * Read more about the initialization order in the {@link #init} method documentation.
+ *
+ * @method onLoad
+ */
+
+/**
+ * A function called on initialization of every editor instance created on the
+ * page before the {@link #init} call task. This feature makes it possible to
+ * initialize things that could be used in the `init` function of other plugins.
+ *
+ *             CKEDITOR.plugins.add( 'sample1', {
+ *                     beforeInit: function( editor ) {
+ *                             editor.foo = 'bar';
+ *                     }
+ *             } );
+ *
+ *             CKEDITOR.plugins.add( 'sample2', {
+ *                     init: function( editor ) {
+ *                             // This will work regardless of order in which
+ *                             // plugins sample1 and sample2 where initialized.
+ *                             console.log( editor.foo ); // 'bar'
+ *                     }
+ *             } );
+ *
+ * Read more about the initialization order in the {@link #init} method documentation.
+ *
+ * @method beforeInit
+ * @param {CKEDITOR.editor} editor The editor instance being initialized.
+ */
+
+/**
+ * A function called on initialization of every editor instance created on the page.
+ *
+ *             CKEDITOR.plugins.add( 'sample', {
+ *                     init: function( editor ) {
+ *                             console.log( 'Editor "' + editor.name + '" is being initialized!' );
+ *                     }
+ *             } );
+ *
+ * Initialization order:
+ *
+ * 1. The {@link #beforeInit} methods of all enabled plugins are executed.
+ * 2. The {@link #init} methods of all enabled plugins are executed.
+ * 3. The {@link #afterInit} methods of all enabled plugins are executed.
+ * 4. The {@link CKEDITOR.editor#pluginsLoaded} event is fired.
+ *
+ * **Note:** The order in which the `init` methods are called does not depend on the plugins' {@link #requires requirements}
+ * or the order set in the {@link CKEDITOR.config#plugins} option. It may be random and therefore it is
+ * recommended to use the {@link #beforeInit} and {@link #afterInit} methods in order to ensure
+ * the right execution sequence.
+ *
+ * See also the {@link #onLoad} method.
+ *
+ * @method init
+ * @param {CKEDITOR.editor} editor The editor instance being initialized.
+ */
+
+/**
+ * A function called on initialization of every editor instance created on the
+ * page after the {@link #init} call task. This feature makes it possible to use things
+ * that were initialized in the `init` function of other plugins.
+ *
+ *             CKEDITOR.plugins.add( 'sample1', {
+ *                     afterInit: function( editor ) {
+ *                             // This will work regardless of order in which
+ *                             // plugins sample1 and sample2 where initialized.
+ *                             console.log( editor.foo ); // 'bar'
+ *                     }
+ *             } );
+ *
+ *             CKEDITOR.plugins.add( 'sample2', {
+ *                     init: function( editor ) {
+ *                             editor.foo = 'bar';
+ *                     }
+ *             } );
+ *
+ * Read more about the initialization order in the {@link #init} method documentation.
+ *
+ * @method afterInit
+ * @param {CKEDITOR.editor} editor The editor instance being initialized.
+ */
+
+/**
+ * Announces the plugin as HiDPI-ready (optimized for high pixel density screens, e.g. *Retina*)
+ * by providing high-resolution icons and images. HiDPI icons must be twice as big
+ * (defaults are `16px x 16px`) and stored under `plugin_name/icons/hidpi/` directory.
+ *
+ * The common place for additional HiDPI images used by the plugin (**but not icons**)
+ * is the `plugin_name/images/hidpi/` directory.
+ *
+ * This property is optional and only makes sense if `32px x 32px` icons
+ * and high-resolution images actually exist. If this flag is set to `true`, the editor
+ * will automatically detect the HiDPI environment and attempt to load the
+ * high-resolution resources.
+ *
+ * @since 4.2
+ * @property {Boolean} hidpi
+ */
diff --git a/sources/core/plugins.js b/sources/core/plugins.js
new file mode 100644 (file)
index 0000000..75cc41e
--- /dev/null
@@ -0,0 +1,119 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.plugins} object, which is used to
+ *             manage plugins registration and loading.
+ */
+
+/**
+ * Manages plugins registration and loading.
+ *
+ * @class
+ * @extends CKEDITOR.resourceManager
+ * @singleton
+ */
+CKEDITOR.plugins = new CKEDITOR.resourceManager( 'plugins/', 'plugin' );
+
+// PACKAGER_RENAME( CKEDITOR.plugins )
+
+CKEDITOR.plugins.load = CKEDITOR.tools.override( CKEDITOR.plugins.load, function( originalLoad ) {
+       var initialized = {};
+
+       return function( name, callback, scope ) {
+               var allPlugins = {};
+
+               var loadPlugins = function( names ) {
+                               originalLoad.call( this, names, function( plugins ) {
+                                       CKEDITOR.tools.extend( allPlugins, plugins );
+
+                                       var requiredPlugins = [];
+                                       for ( var pluginName in plugins ) {
+                                               var plugin = plugins[ pluginName ],
+                                                       requires = plugin && plugin.requires;
+
+                                               if ( !initialized[ pluginName ] ) {
+                                                       // Register all icons eventually defined by this plugin.
+                                                       if ( plugin.icons ) {
+                                                               var icons = plugin.icons.split( ',' );
+                                                               for ( var ic = icons.length; ic--; ) {
+                                                                       CKEDITOR.skin.addIcon( icons[ ic ],
+                                                                               plugin.path +
+                                                                               'icons/' +
+                                                                               ( CKEDITOR.env.hidpi && plugin.hidpi ? 'hidpi/' : '' ) +
+                                                                               icons[ ic ] +
+                                                                               '.png' );
+                                                               }
+                                                       }
+                                                       initialized[ pluginName ] = 1;
+                                               }
+
+                                               if ( requires ) {
+                                                       // Trasnform it into an array, if it's not one.
+                                                       if ( requires.split )
+                                                               requires = requires.split( ',' );
+
+                                                       for ( var i = 0; i < requires.length; i++ ) {
+                                                               if ( !allPlugins[ requires[ i ] ] )
+                                                                       requiredPlugins.push( requires[ i ] );
+                                                       }
+                                               }
+                                       }
+
+                                       if ( requiredPlugins.length )
+                                               loadPlugins.call( this, requiredPlugins );
+                                       else {
+                                               // Call the "onLoad" function for all plugins.
+                                               for ( pluginName in allPlugins ) {
+                                                       plugin = allPlugins[ pluginName ];
+                                                       if ( plugin.onLoad && !plugin.onLoad._called ) {
+                                                               // Make it possible to return false from plugin::onLoad to disable it.
+                                                               if ( plugin.onLoad() === false )
+                                                                       delete allPlugins[ pluginName ];
+
+                                                               plugin.onLoad._called = 1;
+                                                       }
+                                               }
+
+                                               // Call the callback.
+                                               if ( callback )
+                                                       callback.call( scope || window, allPlugins );
+                                       }
+                               }, this );
+
+                       };
+
+               loadPlugins.call( this, name );
+       };
+} );
+
+/**
+ * Loads a specific language file, or auto detect it. A callback is
+ * then called when the file gets loaded.
+ *
+ *             CKEDITOR.plugins.setLang( 'myPlugin', 'en', {
+ *                     title: 'My plugin',
+ *                     selectOption: 'Please select an option'
+ *             } );
+ *
+ * @param {String} pluginName The name of the plugin to which the provided translation
+ * should be attached.
+ * @param {String} languageCode The code of the language translation provided.
+ * @param {Object} languageEntries An object that contains pairs of label and
+ * the respective translation.
+ */
+CKEDITOR.plugins.setLang = function( pluginName, languageCode, languageEntries ) {
+       var plugin = this.get( pluginName ),
+               pluginLangEntries = plugin.langEntries || ( plugin.langEntries = {} ),
+               pluginLang = plugin.lang || ( plugin.lang = [] );
+
+       if ( pluginLang.split )
+               pluginLang = pluginLang.split( ',' );
+
+       if ( CKEDITOR.tools.indexOf( pluginLang, languageCode ) == -1 )
+               pluginLang.push( languageCode );
+
+       pluginLangEntries[ languageCode ] = languageEntries;
+};
diff --git a/sources/core/resourcemanager.js b/sources/core/resourcemanager.js
new file mode 100644 (file)
index 0000000..c33c0f8
--- /dev/null
@@ -0,0 +1,228 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.resourceManager} class, which is
+ *             the base for resource managers, like plugins.
+ */
+
+/**
+ * Base class for resource managers, like plugins. This class is not
+ * intended to be used out of the CKEditor core code.
+ *
+ * @class
+ * @constructor Creates a resourceManager class instance.
+ * @param {String} basePath The path for the resources folder.
+ * @param {String} fileName The name used for resource files.
+ */
+CKEDITOR.resourceManager = function( basePath, fileName ) {
+       /**
+        * The base directory containing all resources.
+        *
+        * @property {String}
+        */
+       this.basePath = basePath;
+
+       /**
+        * The name used for resource files.
+        *
+        * @property {String}
+        */
+       this.fileName = fileName;
+
+       /**
+        * Contains references to all resources that have already been registered
+        * with {@link #add}.
+        */
+       this.registered = {};
+
+       /**
+        * Contains references to all resources that have already been loaded
+        * with {@link #load}.
+        */
+       this.loaded = {};
+
+       /**
+        * Contains references to all resources that have already been registered
+        * with {@link #addExternal}.
+        */
+       this.externals = {};
+
+       /**
+        * @private
+        */
+       this._ = {
+               // List of callbacks waiting for plugins to be loaded.
+               waitingList: {}
+       };
+};
+
+CKEDITOR.resourceManager.prototype = {
+       /**
+        * Registers a resource.
+        *
+        *              CKEDITOR.plugins.add( 'sample', { ... plugin definition ... } );
+        *
+        * @param {String} name The resource name.
+        * @param {Object} [definition] The resource definition.
+        * @see CKEDITOR.pluginDefinition
+        */
+       add: function( name, definition ) {
+               if ( this.registered[ name ] )
+                       throw new Error( '[CKEDITOR.resourceManager.add] The resource name "' + name + '" is already registered.' );
+
+               var resource = this.registered[ name ] = definition || {};
+               resource.name = name;
+               resource.path = this.getPath( name );
+
+               CKEDITOR.fire( name + CKEDITOR.tools.capitalize( this.fileName ) + 'Ready', resource );
+
+               return this.get( name );
+       },
+
+       /**
+        * Gets the definition of a specific resource.
+        *
+        *              var definition = CKEDITOR.plugins.get( 'sample' );
+        *
+        * @param {String} name The resource name.
+        * @returns {Object} The registered object.
+        */
+       get: function( name ) {
+               return this.registered[ name ] || null;
+       },
+
+       /**
+        * Get the folder path for a specific loaded resource.
+        *
+        *              alert( CKEDITOR.plugins.getPath( 'sample' ) ); // '<editor path>/plugins/sample/'
+        *
+        * @param {String} name The resource name.
+        * @returns {String}
+        */
+       getPath: function( name ) {
+               var external = this.externals[ name ];
+               return CKEDITOR.getUrl( ( external && external.dir ) || this.basePath + name + '/' );
+       },
+
+       /**
+        * Get the file path for a specific loaded resource.
+        *
+        *              alert( CKEDITOR.plugins.getFilePath( 'sample' ) ); // '<editor path>/plugins/sample/plugin.js'
+        *
+        * @param {String} name The resource name.
+        * @returns {String}
+        */
+       getFilePath: function( name ) {
+               var external = this.externals[ name ];
+               return CKEDITOR.getUrl( this.getPath( name ) + ( external ? external.file : this.fileName + '.js' ) );
+       },
+
+       /**
+        * Registers one or more resources to be loaded from an external path
+        * instead of the core base path.
+        *
+        *              // Loads a plugin from '/myplugins/sample/plugin.js'.
+        *              CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/' );
+        *
+        *              // Loads a plugin from '/myplugins/sample/my_plugin.js'.
+        *              CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/', 'my_plugin.js' );
+        *
+        *              // Loads a plugin from '/myplugins/sample/my_plugin.js'.
+        *              CKEDITOR.plugins.addExternal( 'sample', '/myplugins/sample/my_plugin.js', '' );
+        *
+        * @param {String} names The resource names, separated by commas.
+        * @param {String} path The path of the folder containing the resource.
+        * @param {String} [fileName] The resource file name. If not provided, the
+        * default name is used. If provided with a empty string, will implicitly indicates that `path` argument
+        * is already the full path.
+        */
+       addExternal: function( names, path, fileName ) {
+               names = names.split( ',' );
+               for ( var i = 0; i < names.length; i++ ) {
+                       var name = names[ i ];
+
+                       // If "fileName" is not provided, we assume that it may be available
+                       // in "path". Try to extract it in this case.
+                       if ( !fileName ) {
+                               path = path.replace( /[^\/]+$/, function( match ) {
+                                       fileName = match;
+                                       return '';
+                               } );
+                       }
+
+                       this.externals[ name ] = {
+                               dir: path,
+
+                               // Use the default file name if there is no "fileName" and it
+                               // was not found in "path".
+                               file: fileName || ( this.fileName + '.js' )
+                       };
+               }
+       },
+
+       /**
+        * Loads one or more resources.
+        *
+        *              CKEDITOR.plugins.load( 'myplugin', function( plugins ) {
+        *                      alert( plugins[ 'myplugin' ] ); // object
+        *              } );
+        *
+        * @param {String/Array} name The name of the resource to load. It may be a
+        * string with a single resource name, or an array with several names.
+        * @param {Function} callback A function to be called when all resources
+        * are loaded. The callback will receive an array containing all loaded names.
+        * @param {Object} [scope] The scope object to be used for the callback call.
+        */
+       load: function( names, callback, scope ) {
+               // Ensure that we have an array of names.
+               if ( !CKEDITOR.tools.isArray( names ) )
+                       names = names ? [ names ] : [];
+
+               var loaded = this.loaded,
+                       registered = this.registered,
+                       urls = [],
+                       urlsNames = {},
+                       resources = {};
+
+               // Loop through all names.
+               for ( var i = 0; i < names.length; i++ ) {
+                       var name = names[ i ];
+
+                       if ( !name )
+                               continue;
+
+                       // If not available yet.
+                       if ( !loaded[ name ] && !registered[ name ] ) {
+                               var url = this.getFilePath( name );
+                               urls.push( url );
+                               if ( !( url in urlsNames ) )
+                                       urlsNames[ url ] = [];
+                               urlsNames[ url ].push( name );
+                       } else {
+                               resources[ name ] = this.get( name );
+                       }
+               }
+
+               CKEDITOR.scriptLoader.load( urls, function( completed, failed ) {
+                       if ( failed.length ) {
+                               throw new Error( '[CKEDITOR.resourceManager.load] Resource name "' + urlsNames[ failed[ 0 ] ].join( ',' ) +
+                                       '" was not found at "' + failed[ 0 ] + '".' );
+                       }
+
+                       for ( var i = 0; i < completed.length; i++ ) {
+                               var nameList = urlsNames[ completed[ i ] ];
+                               for ( var j = 0; j < nameList.length; j++ ) {
+                                       var name = nameList[ j ];
+                                       resources[ name ] = this.get( name );
+
+                                       loaded[ name ] = 1;
+                               }
+                       }
+
+                       callback.call( scope, resources );
+               }, this );
+       }
+};
diff --git a/sources/core/scriptloader.js b/sources/core/scriptloader.js
new file mode 100644 (file)
index 0000000..a2b9cca
--- /dev/null
@@ -0,0 +1,202 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.scriptLoader} object, used to load scripts
+ *             asynchronously.
+ */
+
+/**
+ * Load scripts asynchronously.
+ *
+ * @class
+ * @singleton
+ */
+CKEDITOR.scriptLoader = ( function() {
+       var uniqueScripts = {},
+               waitingList = {};
+
+       return {
+               /**
+                * Loads one or more external script checking if not already loaded
+                * previously by this function.
+                *
+                *              CKEDITOR.scriptLoader.load( '/myscript.js' );
+                *
+                *              CKEDITOR.scriptLoader.load( '/myscript.js', function( success ) {
+                *                      // Alerts true if the script has been properly loaded.
+                *                      // HTTP error 404 should return false.
+                *                      alert( success );
+                *              } );
+                *
+                *              CKEDITOR.scriptLoader.load( [ '/myscript1.js', '/myscript2.js' ], function( completed, failed ) {
+                *                      alert( 'Number of scripts loaded: ' + completed.length );
+                *                      alert( 'Number of failures: ' + failed.length );
+                *              } );
+                *
+                * @param {String/Array} scriptUrl One or more URLs pointing to the
+                * scripts to be loaded.
+                * @param {Function} [callback] A function to be called when the script
+                * is loaded and executed. If a string is passed to `scriptUrl`, a
+                * boolean parameter is passed to the callback, indicating the
+                * success of the load. If an array is passed instead, two arrays
+                * parameters are passed to the callback - the first contains the
+                * URLs that have been properly loaded and the second the failed ones.
+                * @param {Object} [scope] The scope (`this` reference) to be used for
+                * the callback call. Defaults to {@link CKEDITOR}.
+                * @param {Boolean} [showBusy] Changes the cursor of the document while
+                * the script is loaded.
+                */
+               load: function( scriptUrl, callback, scope, showBusy ) {
+                       var isString = ( typeof scriptUrl == 'string' );
+
+                       if ( isString )
+                               scriptUrl = [ scriptUrl ];
+
+                       if ( !scope )
+                               scope = CKEDITOR;
+
+                       var scriptCount = scriptUrl.length,
+                               completed = [],
+                               failed = [];
+
+                       var doCallback = function( success ) {
+                                       if ( callback ) {
+                                               if ( isString )
+                                                       callback.call( scope, success );
+                                               else
+                                                       callback.call( scope, completed, failed );
+                                       }
+                               };
+
+                       if ( scriptCount === 0 ) {
+                               doCallback( true );
+                               return;
+                       }
+
+                       var checkLoaded = function( url, success ) {
+                                       ( success ? completed : failed ).push( url );
+
+                                       if ( --scriptCount <= 0 ) {
+                                               showBusy && CKEDITOR.document.getDocumentElement().removeStyle( 'cursor' );
+                                               doCallback( success );
+                                       }
+                               };
+
+                       var onLoad = function( url, success ) {
+                                       // Mark this script as loaded.
+                                       uniqueScripts[ url ] = 1;
+
+                                       // Get the list of callback checks waiting for this file.
+                                       var waitingInfo = waitingList[ url ];
+                                       delete waitingList[ url ];
+
+                                       // Check all callbacks waiting for this file.
+                                       for ( var i = 0; i < waitingInfo.length; i++ )
+                                               waitingInfo[ i ]( url, success );
+                               };
+
+                       var loadScript = function( url ) {
+                                       if ( uniqueScripts[ url ] ) {
+                                               checkLoaded( url, true );
+                                               return;
+                                       }
+
+                                       var waitingInfo = waitingList[ url ] || ( waitingList[ url ] = [] );
+                                       waitingInfo.push( checkLoaded );
+
+                                       // Load it only for the first request.
+                                       if ( waitingInfo.length > 1 )
+                                               return;
+
+                                       // Create the <script> element.
+                                       var script = new CKEDITOR.dom.element( 'script' );
+                                       script.setAttributes( {
+                                               type: 'text/javascript',
+                                               src: url
+                                       } );
+
+                                       if ( callback ) {
+                                               // The onload or onerror event does not fire in IE8 and IE9 Quirks Mode (#14849).
+                                               if ( CKEDITOR.env.ie && ( CKEDITOR.env.version <= 8 || CKEDITOR.env.ie9Compat ) ) {
+                                                       script.$.onreadystatechange = function() {
+                                                               if ( script.$.readyState == 'loaded' || script.$.readyState == 'complete' ) {
+                                                                       script.$.onreadystatechange = null;
+                                                                       onLoad( url, true );
+                                                               }
+                                                       };
+                                               } else {
+                                                       script.$.onload = function() {
+                                                               // Some browsers, such as Safari, may call the onLoad function
+                                                               // immediately. Which will break the loading sequence. (#3661)
+                                                               setTimeout( function() {
+                                                                       onLoad( url, true );
+                                                               }, 0 );
+                                                       };
+
+                                                       script.$.onerror = function() {
+                                                               onLoad( url, false );
+                                                       };
+                                               }
+                                       }
+
+                                       // Append it to <head>.
+                                       script.appendTo( CKEDITOR.document.getHead() );
+
+                                       CKEDITOR.fire( 'download', url ); // %REMOVE_LINE%
+                               };
+
+                       showBusy && CKEDITOR.document.getDocumentElement().setStyle( 'cursor', 'wait' );
+                       for ( var i = 0; i < scriptCount; i++ ) {
+                               loadScript( scriptUrl[ i ] );
+                       }
+               },
+
+               /**
+                * Loads a script in a queue, so only one is loaded at the same time.
+                *
+                * @since 4.1.2
+                * @param {String} scriptUrl URL pointing to the script to be loaded.
+                * @param {Function} [callback] A function to be called when the script
+                * is loaded and executed. A boolean parameter is passed to the callback,
+                * indicating the success of the load.
+                *
+                * @see CKEDITOR.scriptLoader#load
+                */
+               queue: ( function() {
+                       var pending = [];
+
+                       // Loads the very first script from queue and removes it.
+                       function loadNext() {
+                               var script;
+
+                               if ( ( script = pending[ 0 ] ) )
+                                       this.load( script.scriptUrl, script.callback, CKEDITOR, 0 );
+                       }
+
+                       return function( scriptUrl, callback ) {
+                               var that = this;
+
+                               // This callback calls the standard callback for the script
+                               // and loads the very next script from pending list.
+                               function callbackWrapper() {
+                                       callback && callback.apply( this, arguments );
+
+                                       // Removed the just loaded script from the queue.
+                                       pending.shift();
+
+                                       loadNext.call( that );
+                               }
+
+                               // Let's add this script to the queue
+                               pending.push( { scriptUrl: scriptUrl, callback: callbackWrapper } );
+
+                               // If the queue was empty, then start loading.
+                               if ( pending.length == 1 )
+                                       loadNext.call( this );
+                       };
+               } )()
+       };
+} )();
diff --git a/sources/core/selection.js b/sources/core/selection.js
new file mode 100644 (file)
index 0000000..eef28a3
--- /dev/null
@@ -0,0 +1,2204 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+( function() {
+       var isMSSelection = typeof window.getSelection != 'function',
+               nextRev = 1,
+               // #13816
+               fillingCharSequence = CKEDITOR.tools.repeat( '\u200b', 7 ),
+               fillingCharSequenceRegExp = new RegExp( fillingCharSequence + '( )?', 'g' );
+
+       // #### checkSelectionChange : START
+
+       // The selection change check basically saves the element parent tree of
+       // the current node and check it on successive requests. If there is any
+       // change on the tree, then the selectionChange event gets fired.
+       function checkSelectionChange() {
+               // A possibly available fake-selection.
+               var sel = this._.fakeSelection,
+                       realSel;
+
+               if ( sel ) {
+                       realSel = this.getSelection( 1 );
+
+                       // If real (not locked/stored) selection was moved from hidden container,
+                       // then the fake-selection must be invalidated.
+                       if ( !realSel || !realSel.isHidden() ) {
+                               // Remove the cache from fake-selection references in use elsewhere.
+                               sel.reset();
+
+                               // Have the code using the native selection.
+                               sel = 0;
+                       }
+               }
+
+               // If not fake-selection is available then get the native selection.
+               if ( !sel ) {
+                       sel = realSel || this.getSelection( 1 );
+
+                       // Editor may have no selection at all.
+                       if ( !sel || sel.getType() == CKEDITOR.SELECTION_NONE )
+                               return;
+               }
+
+               this.fire( 'selectionCheck', sel );
+
+               var currentPath = this.elementPath();
+               if ( !currentPath.compare( this._.selectionPreviousPath ) ) {
+                       // Handle case when dialog inserts new element but parent block and path (so also focus context) does not change. (#13362)
+                       var sameBlockParent = this._.selectionPreviousPath && this._.selectionPreviousPath.blockLimit.equals( currentPath.blockLimit );
+                       // Cache the active element, which we'll eventually lose on Webkit.
+                       if ( CKEDITOR.env.webkit && !sameBlockParent )
+                               this._.previousActive = this.document.getActive();
+
+                       this._.selectionPreviousPath = currentPath;
+                       this.fire( 'selectionChange', { selection: sel, path: currentPath } );
+               }
+       }
+
+       var checkSelectionChangeTimer, checkSelectionChangeTimeoutPending;
+
+       function checkSelectionChangeTimeout() {
+               // Firing the "OnSelectionChange" event on every key press started to
+               // be too slow. This function guarantees that there will be at least
+               // 200ms delay between selection checks.
+
+               checkSelectionChangeTimeoutPending = true;
+
+               if ( checkSelectionChangeTimer )
+                       return;
+
+               checkSelectionChangeTimeoutExec.call( this );
+
+               checkSelectionChangeTimer = CKEDITOR.tools.setTimeout( checkSelectionChangeTimeoutExec, 200, this );
+       }
+
+       function checkSelectionChangeTimeoutExec() {
+               checkSelectionChangeTimer = null;
+
+               if ( checkSelectionChangeTimeoutPending ) {
+                       // Call this with a timeout so the browser properly moves the
+                       // selection after the mouseup. It happened that the selection was
+                       // being moved after the mouseup when clicking inside selected text
+                       // with Firefox.
+                       CKEDITOR.tools.setTimeout( checkSelectionChange, 0, this );
+
+                       checkSelectionChangeTimeoutPending = false;
+               }
+       }
+
+       // #### checkSelectionChange : END
+
+       var isVisible = CKEDITOR.dom.walker.invisible( 1 );
+
+       // May absorb the caret if:
+       // * is a visible node,
+       // * is a non-empty element (this rule will accept elements like <strong></strong> because they
+       //      they were not accepted by the isVisible() check, not not <br> which cannot absorb the caret).
+       //      See #12621.
+       function mayAbsorbCaret( node ) {
+               if ( isVisible( node ) )
+                       return true;
+
+               if ( node.type == CKEDITOR.NODE_ELEMENT && !node.is( CKEDITOR.dtd.$empty ) )
+                       return true;
+
+               return false;
+       }
+
+       function rangeRequiresFix( range ) {
+               // Whether we must prevent from absorbing caret by this context node.
+               // Also checks whether there's an editable position next to that node.
+               function ctxRequiresFix( node, isAtEnd ) {
+                       // It's ok for us if a text node absorbs the caret, because
+                       // the caret container element isn't changed then.
+                       if ( !node || node.type == CKEDITOR.NODE_TEXT )
+                               return false;
+
+                       var testRng = range.clone();
+                       return testRng[ 'moveToElementEdit' + ( isAtEnd ? 'End' : 'Start' ) ]( node );
+               }
+
+               // Range root must be the editable element, it's to avoid creating filler char
+               // on any temporary internal selection.
+               if ( !( range.root instanceof CKEDITOR.editable ) )
+                       return false;
+
+               var ct = range.startContainer;
+
+               var previous = range.getPreviousNode( mayAbsorbCaret, null, ct ),
+                       next = range.getNextNode( mayAbsorbCaret, null, ct );
+
+               // Any adjacent text container may absorb the caret, e.g.
+               // <p><strong>text</strong>^foo</p>
+               // <p>foo^<strong>text</strong></p>
+               // <div>^<p>foo</p></div>
+               if ( ctxRequiresFix( previous ) || ctxRequiresFix( next, 1 ) )
+                       return true;
+
+               // Empty block/inline element is also affected. <span>^</span>, <p>^</p> (#7222)
+               // If you found this line confusing check #12655.
+               if ( !( previous || next ) && !( ct.type == CKEDITOR.NODE_ELEMENT && ct.isBlockBoundary() && ct.getBogus() ) )
+                       return true;
+
+               return false;
+       }
+
+       function createFillingCharSequenceNode( editable ) {
+               removeFillingCharSequenceNode( editable, false );
+
+               var fillingChar = editable.getDocument().createText( fillingCharSequence );
+               editable.setCustomData( 'cke-fillingChar', fillingChar );
+
+               return fillingChar;
+       }
+
+       // Checks if a filling char has been used, eventualy removing it (#1272).
+       function checkFillingCharSequenceNodeReady( editable ) {
+               var fillingChar = editable.getCustomData( 'cke-fillingChar' );
+
+               if ( fillingChar ) {
+                       // Use this flag to avoid removing the filling char right after
+                       // creating it.
+                       if ( fillingChar.getCustomData( 'ready' ) ) {
+                               removeFillingCharSequenceNode( editable );
+                       } else {
+                               fillingChar.setCustomData( 'ready', 1 );
+                       }
+               }
+       }
+
+       function removeFillingCharSequenceNode( editable, keepSelection ) {
+               var fillingChar = editable && editable.removeCustomData( 'cke-fillingChar' );
+
+               if ( fillingChar ) {
+                       // Text selection position might get mangled by
+                       // subsequent dom modification, save it now for restoring. (#8617)
+                       if ( keepSelection !== false ) {
+                               var sel = editable.getDocument().getSelection().getNative(),
+                                       // Be error proof.
+                                       range = sel && sel.type != 'None' && sel.getRangeAt( 0 ),
+                                       fillingCharSeqLength = fillingCharSequence.length;
+
+                               // If there's some text other than the sequence in the FC text node and the range
+                               // intersects with that node...
+                               if ( fillingChar.getLength() > fillingCharSeqLength && range && range.intersectsNode( fillingChar.$ ) ) {
+                                       var bm = createNativeSelectionBookmark( sel );
+
+                                       // Correct start offset anticipating the removal of FC.
+                                       if ( sel.anchorNode == fillingChar.$ && sel.anchorOffset > fillingCharSeqLength ) {
+                                               bm[ 0 ].offset -= fillingCharSeqLength;
+                                       }
+
+                                       // Correct end offset anticipating the removal of FC.
+                                       if ( sel.focusNode == fillingChar.$ && sel.focusOffset > fillingCharSeqLength ) {
+                                               bm[ 1 ].offset -= fillingCharSeqLength;
+                                       }
+                               }
+                       }
+
+                       // We can't simply remove the filling node because the user
+                       // will actually enlarge it when typing, so we just remove the
+                       // invisible char from it.
+                       fillingChar.setText( removeFillingCharSequenceString( fillingChar.getText(), 1 ) );
+
+                       // Restore the bookmark preserving selection's direction.
+                       if ( bm ) {
+                               moveNativeSelectionToBookmark( editable.getDocument().$, bm );
+                       }
+               }
+       }
+
+       // #13816
+       function removeFillingCharSequenceString( str, nbspAware ) {
+               if ( nbspAware ) {
+                       return str.replace( fillingCharSequenceRegExp, function( m, p ) {
+                               // #10291 if filling char is followed by a space replace it with NBSP.
+                               return p ? '\xa0' : '';
+                       } );
+               } else {
+                       return str.replace( fillingCharSequence, '' );
+               }
+       }
+
+       function createNativeSelectionBookmark( sel ) {
+               return [
+                       { node: sel.anchorNode, offset: sel.anchorOffset },
+                       { node: sel.focusNode, offset: sel.focusOffset }
+               ];
+       }
+
+       function moveNativeSelectionToBookmark( document, bm ) {
+               var sel = document.getSelection(),
+                       range = document.createRange();
+
+               range.setStart( bm[ 0 ].node, bm[ 0 ].offset );
+               range.collapse( true );
+               sel.removeAllRanges();
+               sel.addRange( range );
+               sel.extend( bm[ 1 ].node, bm[ 1 ].offset );
+       }
+
+       // Creates cke_hidden_sel container and puts real selection there.
+       function hideSelection( editor, ariaLabel ) {
+               var content = ariaLabel || '&nbsp;',
+                       style = CKEDITOR.env.ie && CKEDITOR.env.version < 14 ? 'display:none' : 'position:fixed;top:0;left:-1000px',
+                       hiddenEl = CKEDITOR.dom.element.createFromHtml(
+                               '<div data-cke-hidden-sel="1" data-cke-temp="1" style="' + style + '">' + content + '</div>',
+                               editor.document );
+
+               editor.fire( 'lockSnapshot' );
+
+               editor.editable().append( hiddenEl );
+
+                       // Always use real selection to avoid overriding locked one (http://dev.ckeditor.com/ticket/11104#comment:13).
+               var sel = editor.getSelection( 1 ),
+                       range = editor.createRange(),
+                       // Cancel selectionchange fired by selectRanges - prevent from firing selectionChange.
+                       listener = sel.root.on( 'selectionchange', function( evt ) {
+                               evt.cancel();
+                       }, null, null, 0 );
+
+               range.setStartAt( hiddenEl, CKEDITOR.POSITION_AFTER_START );
+               range.setEndAt( hiddenEl, CKEDITOR.POSITION_BEFORE_END );
+               sel.selectRanges( [ range ] );
+
+               listener.removeListener();
+
+               editor.fire( 'unlockSnapshot' );
+
+               // Set this value at the end, so reset() executed by selectRanges()
+               // will clean up old hidden selection container.
+               editor._.hiddenSelectionContainer = hiddenEl;
+       }
+
+       function removeHiddenSelectionContainer( editor ) {
+               var hiddenEl = editor._.hiddenSelectionContainer;
+
+               if ( hiddenEl ) {
+                       var isDirty = editor.checkDirty();
+
+                       editor.fire( 'lockSnapshot' );
+                       hiddenEl.remove();
+                       editor.fire( 'unlockSnapshot' );
+
+                       !isDirty && editor.resetDirty();
+               }
+
+               delete editor._.hiddenSelectionContainer;
+       }
+
+       // Object containing keystroke handlers for fake selection.
+       var fakeSelectionDefaultKeystrokeHandlers = ( function() {
+               function leave( right ) {
+                       return function( evt ) {
+                               var range = evt.editor.createRange();
+
+                               // Move selection only if there's a editable place for it.
+                               // It no, then do nothing (keystroke will be blocked, widget selection kept).
+                               if ( range.moveToClosestEditablePosition( evt.selected, right ) )
+                                       evt.editor.getSelection().selectRanges( [ range ] );
+
+                               // Prevent default.
+                               return false;
+                       };
+               }
+
+               function del( right ) {
+                       return function( evt ) {
+                               var editor = evt.editor,
+                                       range = editor.createRange(),
+                                       found;
+
+                               // If haven't found place for caret on the default side,
+                               // try to find it on the other side.
+                               if ( !( found = range.moveToClosestEditablePosition( evt.selected, right ) ) )
+                                       found = range.moveToClosestEditablePosition( evt.selected, !right );
+
+                               if ( found )
+                                       editor.getSelection().selectRanges( [ range ] );
+
+                               // Save the state before removing selected element.
+                               editor.fire( 'saveSnapshot' );
+
+                               evt.selected.remove();
+
+                               // Haven't found any editable space before removing element,
+                               // try to place the caret anywhere (most likely, in empty editable).
+                               if ( !found ) {
+                                       range.moveToElementEditablePosition( editor.editable() );
+                                       editor.getSelection().selectRanges( [ range ] );
+                               }
+
+                               editor.fire( 'saveSnapshot' );
+
+                               // Prevent default.
+                               return false;
+                       };
+               }
+
+               var leaveLeft = leave(),
+                       leaveRight = leave( 1 );
+
+               return {
+                       37: leaveLeft,          // LEFT
+                       38: leaveLeft,          // UP
+                       39: leaveRight,         // RIGHT
+                       40: leaveRight,         // DOWN
+                       8: del(),                       // BACKSPACE
+                       46: del( 1 )            // DELETE
+               };
+       } )();
+
+       // Handle left, right, delete and backspace keystrokes next to non-editable elements
+       // by faking selection on them.
+       function getOnKeyDownListener( editor ) {
+               var keystrokes = { 37: 1, 39: 1, 8: 1, 46: 1 };
+
+               return function( evt ) {
+                       var keystroke = evt.data.getKeystroke();
+
+                       // Handle only left/right/del/bspace keys.
+                       if ( !keystrokes[ keystroke ] )
+                               return;
+
+                       var sel = editor.getSelection(),
+                               ranges = sel.getRanges(),
+                               range = ranges[ 0 ];
+
+                       // Handle only single range and it has to be collapsed.
+                       if ( ranges.length != 1 || !range.collapsed )
+                               return;
+
+                       var next = range[ keystroke < 38 ? 'getPreviousEditableNode' : 'getNextEditableNode' ]();
+
+                       if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getAttribute( 'contenteditable' ) == 'false' ) {
+                               editor.getSelection().fake( next );
+                               evt.data.preventDefault();
+                               evt.cancel();
+                       }
+               };
+       }
+
+       // If fake selection should be applied this function will return instance of
+       // CKEDITOR.dom.element which should gain fake selection.
+       function getNonEditableFakeSelectionReceiver( ranges ) {
+               var enclosedNode, shrinkedNode, clone, range;
+
+               if ( ranges.length == 1 && !( range = ranges[ 0 ] ).collapsed &&
+                       ( enclosedNode = range.getEnclosedNode() ) && enclosedNode.type == CKEDITOR.NODE_ELEMENT ) {
+                       // So far we can't say that enclosed element is non-editable. Before checking,
+                       // we'll shrink range (clone). Shrinking will stop on non-editable range, or
+                       // innermost element (#11114).
+                       clone = range.clone();
+                       clone.shrink( CKEDITOR.SHRINK_ELEMENT, true );
+
+                       // If shrinked range still encloses an element, check this one (shrink stops only on non-editable elements).
+                       if ( ( shrinkedNode = clone.getEnclosedNode() ) && shrinkedNode.type == CKEDITOR.NODE_ELEMENT )
+                               enclosedNode = shrinkedNode;
+
+                       if ( enclosedNode.getAttribute( 'contenteditable' ) == 'false' )
+                               return enclosedNode;
+               }
+       }
+
+       // Fix ranges which may end after hidden selection container.
+       // Note: this function may only be used if hidden selection container
+       // is not in DOM any more.
+       function fixRangesAfterHiddenSelectionContainer( ranges, root ) {
+               var range;
+               for ( var i = 0; i < ranges.length; ++i ) {
+                       range = ranges[ i ];
+                       if ( range.endContainer.equals( root ) ) {
+                               // We can use getChildCount() because hidden selection container is not in DOM.
+                               range.endOffset = Math.min( range.endOffset, root.getChildCount() );
+                       }
+               }
+       }
+
+       // Extract only editable part or ranges.
+       // Note: this function modifies ranges list!
+       // @param {CKEDITOR.dom.rangeList} ranges
+       function extractEditableRanges( ranges ) {
+               for ( var i = 0; i < ranges.length; i++ ) {
+                       var range = ranges[ i ];
+
+                       // Drop range spans inside one ready-only node.
+                       var parent = range.getCommonAncestor();
+                       if ( parent.isReadOnly() )
+                               ranges.splice( i, 1 );
+
+                       if ( range.collapsed )
+                               continue;
+
+                       // Range may start inside a non-editable element,
+                       // replace the range start after it.
+                       if ( range.startContainer.isReadOnly() ) {
+                               var current = range.startContainer,
+                                       isElement;
+
+                               while ( current ) {
+                                       isElement = current.type == CKEDITOR.NODE_ELEMENT;
+
+                                       if ( ( isElement && current.is( 'body' ) ) || !current.isReadOnly() )
+                                               break;
+
+                                       if ( isElement && current.getAttribute( 'contentEditable' ) == 'false' )
+                                               range.setStartAfter( current );
+
+                                       current = current.getParent();
+                               }
+                       }
+
+                       var startContainer = range.startContainer,
+                               endContainer = range.endContainer,
+                               startOffset = range.startOffset,
+                               endOffset = range.endOffset,
+                               walkerRange = range.clone();
+
+                       // Enlarge range start/end with text node to avoid walker
+                       // being DOM destructive, it doesn't interfere our checking
+                       // of elements below as well.
+                       if ( startContainer && startContainer.type == CKEDITOR.NODE_TEXT ) {
+                               if ( startOffset >= startContainer.getLength() )
+                                       walkerRange.setStartAfter( startContainer );
+                               else
+                                       walkerRange.setStartBefore( startContainer );
+                       }
+
+                       if ( endContainer && endContainer.type == CKEDITOR.NODE_TEXT ) {
+                               if ( !endOffset )
+                                       walkerRange.setEndBefore( endContainer );
+                               else
+                                       walkerRange.setEndAfter( endContainer );
+                       }
+
+                       // Looking for non-editable element inside the range.
+                       var walker = new CKEDITOR.dom.walker( walkerRange );
+                       walker.evaluator = function( node ) {
+                               if ( node.type == CKEDITOR.NODE_ELEMENT && node.isReadOnly() ) {
+                                       var newRange = range.clone();
+                                       range.setEndBefore( node );
+
+                                       // Drop collapsed range around read-only elements,
+                                       // it make sure the range list empty when selecting
+                                       // only non-editable elements.
+                                       if ( range.collapsed )
+                                               ranges.splice( i--, 1 );
+
+                                       // Avoid creating invalid range.
+                                       if ( !( node.getPosition( walkerRange.endContainer ) & CKEDITOR.POSITION_CONTAINS ) ) {
+                                               newRange.setStartAfter( node );
+                                               if ( !newRange.collapsed )
+                                                       ranges.splice( i + 1, 0, newRange );
+                                       }
+
+                                       return true;
+                               }
+
+                               return false;
+                       };
+
+                       walker.next();
+               }
+
+               return ranges;
+       }
+
+       // Setup all editor instances for the necessary selection hooks.
+       CKEDITOR.on( 'instanceCreated', function( ev ) {
+               var editor = ev.editor;
+
+               editor.on( 'contentDom', function() {
+                       var doc = editor.document,
+                               outerDoc = CKEDITOR.document,
+                               editable = editor.editable(),
+                               body = doc.getBody(),
+                               html = doc.getDocumentElement();
+
+                       var isInline = editable.isInline();
+
+                       var restoreSel,
+                               lastSel;
+
+                       // Give the editable an initial selection on first focus,
+                       // put selection at a consistent position at the start
+                       // of the contents. (#9507)
+                       if ( CKEDITOR.env.gecko ) {
+                               editable.attachListener( editable, 'focus', function( evt ) {
+                                       evt.removeListener();
+
+                                       if ( restoreSel !== 0 ) {
+                                               var nativ = editor.getSelection().getNative();
+                                               // Do it only if the native selection is at an unwanted
+                                               // place (at the very start of the editable). #10119
+                                               if ( nativ && nativ.isCollapsed && nativ.anchorNode == editable.$ ) {
+                                                       var rng = editor.createRange();
+                                                       rng.moveToElementEditStart( editable );
+                                                       rng.select();
+                                               }
+                                       }
+                               }, null, null, -2 );
+                       }
+
+                       // Plays the magic here to restore/save dom selection on editable focus/blur.
+                       editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusIn' : 'focus', function() {
+                               // On Webkit we use DOMFocusIn which is fired more often than focus - e.g. when moving from main editable
+                               // to nested editable (or the opposite). Unlock selection all, but restore only when it was locked
+                               // for the same active element, what will e.g. mean restoring after displaying dialog.
+                               if ( restoreSel && CKEDITOR.env.webkit ) {
+                                       restoreSel = editor._.previousActive && editor._.previousActive.equals( doc.getActive() );
+
+                                       // On Webkit when editor uses divarea, native focus causes editable viewport to scroll
+                                       // to the top (when there is no active selection inside while focusing) so the scroll
+                                       // position should be restored after focusing back editable area. (#14659)
+                                       if ( restoreSel && editor._.previousScrollTop != null && editor._.previousScrollTop != editable.$.scrollTop ) {
+                                               editable.$.scrollTop = editor._.previousScrollTop;
+                                       }
+                               }
+
+                               editor.unlockSelection( restoreSel );
+                               restoreSel = 0;
+                       }, null, null, -1 );
+
+                       // Disable selection restoring when clicking in.
+                       editable.attachListener( editable, 'mousedown', function() {
+                               restoreSel = 0;
+                       } );
+
+                       // Save a cloned version of current selection.
+                       function saveSel() {
+                               lastSel = new CKEDITOR.dom.selection( editor.getSelection() );
+                               lastSel.lock();
+                       }
+
+                       // Browsers could loose the selection once the editable lost focus,
+                       // in such case we need to reproduce it by saving a locked selection
+                       // and restoring it upon focus gain.
+                       if ( CKEDITOR.env.ie || isInline ) {
+                               // For old IEs, we can retrieve the last correct DOM selection upon the "beforedeactivate" event.
+                               // For the rest, a more frequent check is required for each selection change made.
+                               if ( isMSSelection )
+                                       editable.attachListener( editable, 'beforedeactivate', saveSel, null, null, -1 );
+                               else
+                                       editable.attachListener( editor, 'selectionCheck', saveSel, null, null, -1 );
+
+                               // Lock the selection and mark it to be restored.
+                               // On Webkit we use DOMFocusOut which is fired more often than blur. I.e. it will also be
+                               // fired when nested editable is blurred.
+                               editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusOut' : 'blur', function() {
+                                       editor.lockSelection( lastSel );
+                                       restoreSel = 1;
+                               }, null, null, -1 );
+
+                               // Disable selection restoring when clicking in.
+                               editable.attachListener( editable, 'mousedown', function() {
+                                       restoreSel = 0;
+                               } );
+                       }
+
+                       // The following selection-related fixes only apply to classic (`iframe`-based) editable.
+                       if ( CKEDITOR.env.ie && !isInline ) {
+                               var scroll;
+                               editable.attachListener( editable, 'mousedown', function( evt ) {
+                                       // IE scrolls document to top on right mousedown
+                                       // when editor has no focus, remember this scroll
+                                       // position and revert it before context menu opens. (#5778)
+                                       if ( evt.data.$.button == 2 ) {
+                                               var sel = editor.document.getSelection();
+                                               if ( !sel || sel.getType() == CKEDITOR.SELECTION_NONE )
+                                                       scroll = editor.window.getScrollPosition();
+                                       }
+                               } );
+
+                               editable.attachListener( editable, 'mouseup', function( evt ) {
+                                       // Restore recorded scroll position when needed on right mouseup.
+                                       if ( evt.data.$.button == 2 && scroll ) {
+                                               editor.document.$.documentElement.scrollLeft = scroll.x;
+                                               editor.document.$.documentElement.scrollTop = scroll.y;
+                                       }
+                                       scroll = null;
+                               } );
+
+                               // When content doc is in standards mode, IE doesn't focus the editor when
+                               // clicking at the region below body (on html element) content, we emulate
+                               // the normal behavior on old IEs. (#1659, #7932)
+                               if ( doc.$.compatMode != 'BackCompat' ) {
+                                       if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) {
+                                               var textRng,
+                                                       startRng;
+
+                                               html.on( 'mousedown', function( evt ) {
+                                                       evt = evt.data;
+
+                                                       // Expand the text range along with mouse move.
+                                                       function onHover( evt ) {
+                                                               evt = evt.data.$;
+                                                               if ( textRng ) {
+                                                                       // Read the current cursor.
+                                                                       var rngEnd = body.$.createTextRange();
+
+                                                                       moveRangeToPoint( rngEnd, evt.clientX, evt.clientY );
+
+                                                                       // Handle drag directions.
+                                                                       textRng.setEndPoint(
+                                                                               startRng.compareEndPoints( 'StartToStart', rngEnd ) < 0 ?
+                                                                               'EndToEnd' : 'StartToStart', rngEnd );
+
+                                                                       // Update selection with new range.
+                                                                       textRng.select();
+                                                               }
+                                                       }
+
+                                                       function removeListeners() {
+                                                               outerDoc.removeListener( 'mouseup', onSelectEnd );
+                                                               html.removeListener( 'mouseup', onSelectEnd );
+                                                       }
+
+                                                       function onSelectEnd() {
+                                                               html.removeListener( 'mousemove', onHover );
+                                                               removeListeners();
+
+                                                               // Make it in effect on mouse up. (#9022)
+                                                               textRng.select();
+                                                       }
+
+
+                                                       // We're sure that the click happens at the region
+                                                       // below body, but not on scrollbar.
+                                                       if ( evt.getTarget().is( 'html' ) &&
+                                                                       evt.$.y < html.$.clientHeight &&
+                                                                       evt.$.x < html.$.clientWidth ) {
+                                                               // Start to build the text range.
+                                                               textRng = body.$.createTextRange();
+                                                               moveRangeToPoint( textRng, evt.$.clientX, evt.$.clientY );
+
+                                                               // Records the dragging start of the above text range.
+                                                               startRng = textRng.duplicate();
+
+                                                               html.on( 'mousemove', onHover );
+                                                               outerDoc.on( 'mouseup', onSelectEnd );
+                                                               html.on( 'mouseup', onSelectEnd );
+                                                       }
+                                               } );
+                                       }
+
+                                       // It's much simpler for IE8+, we just need to reselect the reported range.
+                                       // This hack does not work on IE>=11 because there's no old selection&range APIs.
+                                       if ( CKEDITOR.env.version > 7 && CKEDITOR.env.version < 11 ) {
+                                               html.on( 'mousedown', function( evt ) {
+                                                       if ( evt.data.getTarget().is( 'html' ) ) {
+                                                               // Limit the text selection mouse move inside of editable. (#9715)
+                                                               outerDoc.on( 'mouseup', onSelectEnd );
+                                                               html.on( 'mouseup', onSelectEnd );
+                                                       }
+                                               } );
+                                       }
+                               }
+                       }
+
+                       // We check the selection change:
+                       // 1. Upon "selectionchange" event from the editable element. (which might be faked event fired by our code)
+                       // 2. After the accomplish of keyboard and mouse events.
+                       editable.attachListener( editable, 'selectionchange', checkSelectionChange, editor );
+                       editable.attachListener( editable, 'keyup', checkSelectionChangeTimeout, editor );
+                       // Always fire the selection change on focus gain.
+                       // On Webkit do this on DOMFocusIn, because the selection is unlocked on it too and
+                       // we need synchronization between those listeners to not lost cached editor._.previousActive property
+                       // (which is updated on selectionCheck).
+                       editable.attachListener( editable, CKEDITOR.env.webkit ? 'DOMFocusIn' : 'focus', function() {
+                               editor.forceNextSelectionCheck();
+                               editor.selectionChange( 1 );
+                       } );
+
+                       // #9699: On Webkit&Gecko in inline editor we have to check selection when it was changed
+                       // by dragging and releasing mouse button outside editable. Dragging (mousedown)
+                       // has to be initialized in editable, but for mouseup we listen on document element.
+                       if ( isInline && ( CKEDITOR.env.webkit || CKEDITOR.env.gecko ) ) {
+                               var mouseDown;
+                               editable.attachListener( editable, 'mousedown', function() {
+                                       mouseDown = 1;
+                               } );
+                               editable.attachListener( doc.getDocumentElement(), 'mouseup', function() {
+                                       if ( mouseDown )
+                                               checkSelectionChangeTimeout.call( editor );
+                                       mouseDown = 0;
+                               } );
+                       }
+                       // In all other cases listen on simple mouseup over editable, as we did before #9699.
+                       //
+                       // Use document instead of editable in non-IEs for observing mouseup
+                       // since editable won't fire the event if selection process started within iframe and ended out
+                       // of the editor (#9851).
+                       else {
+                               editable.attachListener( CKEDITOR.env.ie ? editable : doc.getDocumentElement(), 'mouseup', checkSelectionChangeTimeout, editor );
+                       }
+
+                       if ( CKEDITOR.env.webkit ) {
+                               // Before keystroke is handled by editor, check to remove the filling char.
+                               editable.attachListener( doc, 'keydown', function( evt ) {
+                                       var key = evt.data.getKey();
+                                       // Remove the filling char before some keys get
+                                       // executed, so they'll not get blocked by it.
+                                       switch ( key ) {
+                                               case 13: // ENTER
+                                               case 33: // PAGEUP
+                                               case 34: // PAGEDOWN
+                                               case 35: // HOME
+                                               case 36: // END
+                                               case 37: // LEFT-ARROW
+                                               case 39: // RIGHT-ARROW
+                                               case 8: // BACKSPACE
+                                               case 45: // INS
+                                               case 46: // DEl
+                                                       removeFillingCharSequenceNode( editable );
+                                       }
+
+                               }, null, null, -1 );
+                       }
+
+                       // Automatically select non-editable element when navigating into
+                       // it by left/right or backspace/del keys.
+                       editable.attachListener( editable, 'keydown', getOnKeyDownListener( editor ), null, null, -1 );
+
+                       function moveRangeToPoint( range, x, y ) {
+                               // Error prune in IE7. (#9034, #9110)
+                               try {
+                                       range.moveToPoint( x, y );
+                               } catch ( e ) {}
+                       }
+
+                       function removeListeners() {
+                               outerDoc.removeListener( 'mouseup', onSelectEnd );
+                               html.removeListener( 'mouseup', onSelectEnd );
+                       }
+
+                       function onSelectEnd() {
+                               removeListeners();
+
+                               // The event is not fired when clicking on the scrollbars,
+                               // so we can safely check the following to understand
+                               // whether the empty space following <body> has been clicked.
+                               var sel = CKEDITOR.document.$.selection,
+                                       range = sel.createRange();
+
+                               // The selection range is reported on host, but actually it should applies to the content doc.
+                               if ( sel.type != 'None' && range.parentElement().ownerDocument == doc.$ )
+                                       range.select();
+                       }
+               } );
+
+               editor.on( 'setData', function() {
+                       // Invalidate locked selection when unloading DOM.
+                       // (#9521, #5217#comment:32 and #11500#comment:11)
+                       editor.unlockSelection();
+
+                       // Webkit's selection will mess up after the data loading.
+                       if ( CKEDITOR.env.webkit )
+                               clearSelection();
+               } );
+
+               // Catch all the cases which above setData listener couldn't catch.
+               // For example: switching to source mode and destroying editor.
+               editor.on( 'contentDomUnload', function() {
+                       editor.unlockSelection();
+               } );
+
+               // IE9 might cease to work if there's an object selection inside the iframe (#7639).
+               if ( CKEDITOR.env.ie9Compat )
+                       editor.on( 'beforeDestroy', clearSelection, null, null, 9 );
+
+               // Check selection change on data reload.
+               editor.on( 'dataReady', function() {
+                       // Clean up fake selection after setting data.
+                       delete editor._.fakeSelection;
+                       delete editor._.hiddenSelectionContainer;
+
+                       editor.selectionChange( 1 );
+               } );
+
+               // When loaded data are ready check whether hidden selection container was not loaded.
+               editor.on( 'loadSnapshot', function() {
+                       var isElement = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT ),
+                               // TODO replace with el.find() which will be introduced in #9764,
+                               // because it may happen that hidden sel container won't be the last element.
+                               last = editor.editable().getLast( isElement );
+
+                       if ( last && last.hasAttribute( 'data-cke-hidden-sel' ) ) {
+                               last.remove();
+
+                               // Firefox does a very unfortunate thing. When a non-editable element is the only
+                               // element in the editable, when we remove the hidden selection container, Firefox
+                               // will insert a bogus <br> at the beginning of the editable...
+                               // See: https://bugzilla.mozilla.org/show_bug.cgi?id=911201
+                               //
+                               // This behavior is never desired because this <br> pushes the content lower, but in
+                               // this case it is especially dangerous, because it happens when a bookmark is being restored.
+                               // Since this <br> is inserted at the beginning it changes indexes and thus breaks the bookmark2
+                               // what results in errors.
+                               //
+                               // So... let's revert what Firefox broke.
+                               if ( CKEDITOR.env.gecko ) {
+                                       var first = editor.editable().getFirst( isElement );
+                                       if ( first && first.is( 'br' ) && first.getAttribute( '_moz_editor_bogus_node' ) ) {
+                                               first.remove();
+                                       }
+                               }
+                       }
+               }, null, null, 100 );
+
+               editor.on( 'key', function( evt ) {
+                       if ( editor.mode != 'wysiwyg' )
+                               return;
+
+                       var sel = editor.getSelection();
+                       if ( !sel.isFake )
+                               return;
+
+                       var handler = fakeSelectionDefaultKeystrokeHandlers[ evt.data.keyCode ];
+                       if ( handler )
+                               return handler( { editor: editor, selected: sel.getSelectedElement(), selection: sel, keyEvent: evt } );
+               } );
+
+               function clearSelection() {
+                       var sel = editor.getSelection();
+                       sel && sel.removeAllRanges();
+               }
+       } );
+
+       // On WebKit only, we need a special "filling" char on some situations
+       // (#1272). Here we set the events that should invalidate that char.
+       if ( CKEDITOR.env.webkit ) {
+               CKEDITOR.on( 'instanceReady', function( evt ) {
+                       var editor = evt.editor;
+
+                       editor.on( 'selectionChange', function() {
+                               checkFillingCharSequenceNodeReady( editor.editable() );
+                       }, null, null, -1 );
+
+                       editor.on( 'beforeSetMode', function() {
+                               removeFillingCharSequenceNode( editor.editable() );
+                       }, null, null, -1 );
+
+                       // Filter Undo snapshot's HTML to get rid of Filling Char Sequence.
+                       // Note: CKEDITOR.dom.range.createBookmark2() normalizes snapshot's
+                       // bookmarks to anticipate the removal of FCSeq from the snapshot's HTML (#13816).
+                       editor.on( 'getSnapshot', function( evt ) {
+                               if ( evt.data ) {
+                                       evt.data = removeFillingCharSequenceString( evt.data );
+                               }
+                       }, editor, null, 20 );
+
+                       // Filter data to get rid of Filling Char Sequence. Filter on #toDataFormat
+                       // instead of #getData because once removed, FCSeq may leave an empty element,
+                       // which should be pruned by the dataProcessor (#13816).
+                       // Note: Used low priority to filter when dataProcessor works on strings,
+                       // not pseudo–DOM.
+                       editor.on( 'toDataFormat', function( evt ) {
+                               evt.data.dataValue = removeFillingCharSequenceString( evt.data.dataValue );
+                       }, null, null, 0 );
+               } );
+       }
+
+       /**
+        * Check the selection change in editor and potentially fires
+        * the {@link CKEDITOR.editor#event-selectionChange} event.
+        *
+        * @method
+        * @member CKEDITOR.editor
+        * @param {Boolean} [checkNow=false] Force the check to happen immediately
+        * instead of coming with a timeout delay (default).
+        */
+       CKEDITOR.editor.prototype.selectionChange = function( checkNow ) {
+               ( checkNow ? checkSelectionChange : checkSelectionChangeTimeout ).call( this );
+       };
+
+       /**
+        * Retrieve the editor selection in scope of editable element.
+        *
+        * **Note:** Since the native browser selection provides only one single
+        * selection at a time per document, so if editor's editable element has lost focus,
+        * this method will return a null value unless the {@link CKEDITOR.editor#lockSelection}
+        * has been called beforehand so the saved selection is retrieved.
+        *
+        *              var selection = CKEDITOR.instances.editor1.getSelection();
+        *              alert( selection.getType() );
+        *
+        * @method
+        * @member CKEDITOR.editor
+        * @param {Boolean} forceRealSelection Return real selection, instead of saved or fake one.
+        * @returns {CKEDITOR.dom.selection} A selection object or null if not available for the moment.
+        */
+       CKEDITOR.editor.prototype.getSelection = function( forceRealSelection ) {
+
+               // Check if there exists a locked or fake selection.
+               if ( ( this._.savedSelection || this._.fakeSelection ) && !forceRealSelection )
+                       return this._.savedSelection || this._.fakeSelection;
+
+               // Editable element might be absent or editor might not be in a wysiwyg mode.
+               var editable = this.editable();
+               return editable && this.mode == 'wysiwyg' ? new CKEDITOR.dom.selection( editable ) : null;
+       };
+
+       /**
+        * Locks the selection made in the editor in order to make it possible to
+        * manipulate it without browser interference. A locked selection is
+        * cached and remains unchanged until it is released with the
+        * {@link CKEDITOR.editor#unlockSelection} method.
+        *
+        * @method
+        * @member CKEDITOR.editor
+        * @param {CKEDITOR.dom.selection} [sel] Specify the selection to be locked.
+        * @returns {Boolean} `true` if selection was locked.
+        */
+       CKEDITOR.editor.prototype.lockSelection = function( sel ) {
+               sel = sel || this.getSelection( 1 );
+               if ( sel.getType() != CKEDITOR.SELECTION_NONE ) {
+                       !sel.isLocked && sel.lock();
+                       this._.savedSelection = sel;
+                       return true;
+               }
+               return false;
+       };
+
+       /**
+        * Unlocks the selection made in the editor and locked with the
+        * {@link CKEDITOR.editor#unlockSelection} method. An unlocked selection
+        * is no longer cached and can be changed.
+        *
+        * @method
+        * @member CKEDITOR.editor
+        * @param {Boolean} [restore] If set to `true`, the selection is
+        * restored back to the selection saved earlier by using the
+        * {@link CKEDITOR.dom.selection#lock} method.
+        */
+       CKEDITOR.editor.prototype.unlockSelection = function( restore ) {
+               var sel = this._.savedSelection;
+               if ( sel ) {
+                       sel.unlock( restore );
+                       delete this._.savedSelection;
+                       return true;
+               }
+
+               return false;
+       };
+
+       /**
+        * @method
+        * @member CKEDITOR.editor
+        * @todo
+        */
+       CKEDITOR.editor.prototype.forceNextSelectionCheck = function() {
+               delete this._.selectionPreviousPath;
+       };
+
+       /**
+        * Gets the current selection in context of the document's body element.
+        *
+        *              var selection = CKEDITOR.instances.editor1.document.getSelection();
+        *              alert( selection.getType() );
+        *
+        * @method
+        * @member CKEDITOR.dom.document
+        * @returns {CKEDITOR.dom.selection} A selection object.
+        */
+       CKEDITOR.dom.document.prototype.getSelection = function() {
+               return new CKEDITOR.dom.selection( this );
+       };
+
+       /**
+        * Select this range as the only one with {@link CKEDITOR.dom.selection#selectRanges}.
+        *
+        * @method
+        * @returns {CKEDITOR.dom.selection}
+        * @member CKEDITOR.dom.range
+        */
+       CKEDITOR.dom.range.prototype.select = function() {
+               var sel = this.root instanceof CKEDITOR.editable ? this.root.editor.getSelection() : new CKEDITOR.dom.selection( this.root );
+
+               sel.selectRanges( [ this ] );
+
+               return sel;
+       };
+
+       /**
+        * No selection.
+        *
+        *              if ( editor.getSelection().getType() == CKEDITOR.SELECTION_NONE )
+        *                      alert( 'Nothing is selected' );
+        *
+        * @readonly
+        * @property {Number} [=1]
+        * @member CKEDITOR
+        */
+       CKEDITOR.SELECTION_NONE = 1;
+
+       /**
+        * A text or a collapsed selection.
+        *
+        *              if ( editor.getSelection().getType() == CKEDITOR.SELECTION_TEXT )
+        *                      alert( 'A text is selected' );
+        *
+        * @readonly
+        * @property {Number} [=2]
+        * @member CKEDITOR
+        */
+       CKEDITOR.SELECTION_TEXT = 2;
+
+       /**
+        * Element selection.
+        *
+        *              if ( editor.getSelection().getType() == CKEDITOR.SELECTION_ELEMENT )
+        *                      alert( 'An element is selected' );
+        *
+        * @readonly
+        * @property {Number} [=3]
+        * @member CKEDITOR
+        */
+       CKEDITOR.SELECTION_ELEMENT = 3;
+
+       /**
+        * Manipulates the selection within a DOM element. If the current browser selection
+        * spans outside of the element, an empty selection object is returned.
+        *
+        * Despite the fact that selection's constructor allows to create selection instances,
+        * usually it's better to get selection from the editor instance:
+        *
+        *              var sel = editor.getSelection();
+        *
+        * See {@link CKEDITOR.editor#getSelection}.
+        *
+        * @class
+        * @constructor Creates a selection class instance.
+        *
+        *              // Selection scoped in document.
+        *              var sel = new CKEDITOR.dom.selection( CKEDITOR.document );
+        *
+        *              // Selection scoped in element with 'editable' id.
+        *              var sel = new CKEDITOR.dom.selection( CKEDITOR.document.getById( 'editable' ) );
+        *
+        *              // Cloning selection.
+        *              var clone = new CKEDITOR.dom.selection( sel );
+        *
+        * @param {CKEDITOR.dom.document/CKEDITOR.dom.element/CKEDITOR.dom.selection} target
+        * The DOM document/element that the DOM selection is restrained to. Only selection which spans
+        * within the target element is considered as valid.
+        *
+        * If {@link CKEDITOR.dom.selection} is passed, then its clone will be created.
+        */
+       CKEDITOR.dom.selection = function( target ) {
+               // Target is a selection - clone it.
+               if ( target instanceof CKEDITOR.dom.selection ) {
+                       var selection = target;
+                       target = target.root;
+               }
+
+               var isElement = target instanceof CKEDITOR.dom.element,
+                       root;
+
+               this.rev = selection ? selection.rev : nextRev++;
+               this.document = target instanceof CKEDITOR.dom.document ? target : target.getDocument();
+               this.root = root = isElement ? target : this.document.getBody();
+               this.isLocked = 0;
+               this._ = {
+                       cache: {}
+               };
+
+               // Clone selection.
+               if ( selection ) {
+                       CKEDITOR.tools.extend( this._.cache, selection._.cache );
+                       this.isFake = selection.isFake;
+                       this.isLocked = selection.isLocked;
+                       return this;
+               }
+
+               // Check whether browser focus is really inside of the editable element.
+
+               var nativeSel = this.getNative(),
+                       rangeParent,
+                       range;
+
+               if ( nativeSel ) {
+                       if ( nativeSel.getRangeAt ) {
+                               range = nativeSel.rangeCount && nativeSel.getRangeAt( 0 );
+                               rangeParent = range && new CKEDITOR.dom.node( range.commonAncestorContainer );
+                       }
+                       // For old IEs.
+                       else {
+                               // Sometimes, mostly when selection is close to the table or hr,
+                               // IE throws "Unspecified error".
+                               try {
+                                       range = nativeSel.createRange();
+                               } catch ( err ) {}
+                               rangeParent = range && CKEDITOR.dom.element.get( range.item && range.item( 0 ) || range.parentElement() );
+                       }
+               }
+
+               // Selection out of concerned range, empty the selection.
+               // TODO check whether this condition cannot be reverted to its old
+               // form (commented out) after we closed #10438.
+               //if ( !( rangeParent && ( root.equals( rangeParent ) || root.contains( rangeParent ) ) ) ) {
+               if ( !(
+                       rangeParent &&
+                       ( rangeParent.type == CKEDITOR.NODE_ELEMENT || rangeParent.type == CKEDITOR.NODE_TEXT ) &&
+                       ( this.root.equals( rangeParent ) || this.root.contains( rangeParent ) )
+               ) ) {
+
+                       this._.cache.type = CKEDITOR.SELECTION_NONE;
+                       this._.cache.startElement = null;
+                       this._.cache.selectedElement = null;
+                       this._.cache.selectedText = '';
+                       this._.cache.ranges = new CKEDITOR.dom.rangeList();
+               }
+
+               return this;
+       };
+
+       var styleObjectElements = { img: 1, hr: 1, li: 1, table: 1, tr: 1, td: 1, th: 1, embed: 1, object: 1, ol: 1, ul: 1,
+                       a: 1, input: 1, form: 1, select: 1, textarea: 1, button: 1, fieldset: 1, thead: 1, tfoot: 1 };
+
+       CKEDITOR.tools.extend( CKEDITOR.dom.selection, {
+               _removeFillingCharSequenceString: removeFillingCharSequenceString,
+               _createFillingCharSequenceNode: createFillingCharSequenceNode,
+
+               /**
+                * The sequence used in a WebKit-based browser to create a Filling Character. By default it is
+                * a string of 7 zero-width space characters (U+200B).
+                *
+                * @since 4.5.7
+                * @readonly
+                * @property {String}
+                */
+               FILLING_CHAR_SEQUENCE: fillingCharSequence
+       } );
+
+       CKEDITOR.dom.selection.prototype = {
+               /**
+                * Gets the native selection object from the browser.
+                *
+                *              var selection = editor.getSelection().getNative();
+                *
+                * @returns {Object} The native browser selection object.
+                */
+               getNative: function() {
+                       if ( this._.cache.nativeSel !== undefined )
+                               return this._.cache.nativeSel;
+
+                       return ( this._.cache.nativeSel = isMSSelection ? this.document.$.selection : this.document.getWindow().$.getSelection() );
+               },
+
+               /**
+                * Gets the type of the current selection. The following values are
+                * available:
+                *
+                * * {@link CKEDITOR#SELECTION_NONE} (1): No selection.
+                * * {@link CKEDITOR#SELECTION_TEXT} (2): A text or a collapsed selection is selected.
+                * * {@link CKEDITOR#SELECTION_ELEMENT} (3): An element is selected.
+                *
+                * Example:
+                *
+                *              if ( editor.getSelection().getType() == CKEDITOR.SELECTION_TEXT )
+                *                      alert( 'A text is selected' );
+                *
+                * @method
+                * @returns {Number} One of the following constant values: {@link CKEDITOR#SELECTION_NONE},
+                * {@link CKEDITOR#SELECTION_TEXT} or {@link CKEDITOR#SELECTION_ELEMENT}.
+                */
+               getType: isMSSelection ?
+               function() {
+                       var cache = this._.cache;
+                       if ( cache.type )
+                               return cache.type;
+
+                       var type = CKEDITOR.SELECTION_NONE;
+
+                       try {
+                               var sel = this.getNative(),
+                                       ieType = sel.type;
+
+                               if ( ieType == 'Text' )
+                                       type = CKEDITOR.SELECTION_TEXT;
+
+                               if ( ieType == 'Control' )
+                                       type = CKEDITOR.SELECTION_ELEMENT;
+
+                               // It is possible that we can still get a text range
+                               // object even when type == 'None' is returned by IE.
+                               // So we'd better check the object returned by
+                               // createRange() rather than by looking at the type.
+                               if ( sel.createRange().parentElement() )
+                                       type = CKEDITOR.SELECTION_TEXT;
+                       } catch ( e ) {}
+
+                       return ( cache.type = type );
+               } : function() {
+                       var cache = this._.cache;
+                       if ( cache.type )
+                               return cache.type;
+
+                       var type = CKEDITOR.SELECTION_TEXT;
+
+                       var sel = this.getNative();
+
+                       if ( !( sel && sel.rangeCount ) )
+                               type = CKEDITOR.SELECTION_NONE;
+                       else if ( sel.rangeCount == 1 ) {
+                               // Check if the actual selection is a control (IMG,
+                               // TABLE, HR, etc...).
+
+                               var range = sel.getRangeAt( 0 ),
+                                       startContainer = range.startContainer;
+
+                               if ( startContainer == range.endContainer && startContainer.nodeType == 1 &&
+                                       ( range.endOffset - range.startOffset ) == 1 &&
+                                       styleObjectElements[ startContainer.childNodes[ range.startOffset ].nodeName.toLowerCase() ] ) {
+                                       type = CKEDITOR.SELECTION_ELEMENT;
+                               }
+
+                       }
+
+                       return ( cache.type = type );
+               },
+
+               /**
+                * Retrieves the {@link CKEDITOR.dom.range} instances that represent the current selection.
+                *
+                * Note: Some browsers return multiple ranges even for a continuous selection. Firefox, for example, returns
+                * one range for each table cell when one or more table rows are selected.
+                *
+                *              var ranges = selection.getRanges();
+                *              alert( ranges.length );
+                *
+                * @method
+                * @param {Boolean} [onlyEditables] If set to `true`, this function retrives editable ranges only.
+                * @returns {Array} Range instances that represent the current selection.
+                */
+               getRanges: ( function() {
+                       var func = isMSSelection ? ( function() {
+                               function getNodeIndex( node ) {
+                                       return new CKEDITOR.dom.node( node ).getIndex();
+                               }
+
+                               // Finds the container and offset for a specific boundary
+                               // of an IE range.
+                               var getBoundaryInformation = function( range, start ) {
+                                       // Creates a collapsed range at the requested boundary.
+                                       range = range.duplicate();
+                                       range.collapse( start );
+
+                                       // Gets the element that encloses the range entirely.
+                                       var parent = range.parentElement();
+
+                                       // Empty parent element, e.g. <i>^</i>
+                                       if ( !parent.hasChildNodes() )
+                                               return { container: parent, offset: 0 };
+
+                                       var siblings = parent.children,
+                                               child, sibling,
+                                               testRange = range.duplicate(),
+                                               startIndex = 0,
+                                               endIndex = siblings.length - 1,
+                                               index = -1,
+                                               position, distance, container;
+
+                                       // Binary search over all element childs to test the range to see whether
+                                       // range is right on the boundary of one element.
+                                       while ( startIndex <= endIndex ) {
+                                               index = Math.floor( ( startIndex + endIndex ) / 2 );
+                                               child = siblings[ index ];
+                                               testRange.moveToElementText( child );
+                                               position = testRange.compareEndPoints( 'StartToStart', range );
+
+                                               if ( position > 0 )
+                                                       endIndex = index - 1;
+                                               else if ( position < 0 )
+                                                       startIndex = index + 1;
+                                               else
+                                                       return { container: parent, offset: getNodeIndex( child ) };
+                                       }
+
+                                       // All childs are text nodes,
+                                       // or to the right hand of test range are all text nodes. (#6992)
+                                       if ( index == -1 || index == siblings.length - 1 && position < 0 ) {
+                                               // Adapt test range to embrace the entire parent contents.
+                                               testRange.moveToElementText( parent );
+                                               testRange.setEndPoint( 'StartToStart', range );
+
+                                               // IE report line break as CRLF with range.text but
+                                               // only LF with textnode.nodeValue, normalize them to avoid
+                                               // breaking character counting logic below. (#3949)
+                                               distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
+
+                                               siblings = parent.childNodes;
+
+                                               // Actual range anchor right beside test range at the boundary of text node.
+                                               if ( !distance ) {
+                                                       child = siblings[ siblings.length - 1 ];
+
+                                                       if ( child.nodeType != CKEDITOR.NODE_TEXT )
+                                                               return { container: parent, offset: siblings.length };
+                                                       else
+                                                               return { container: child, offset: child.nodeValue.length };
+                                               }
+
+                                               // Start the measuring until distance overflows, meanwhile count the text nodes.
+                                               var i = siblings.length;
+                                               while ( distance > 0 && i > 0 ) {
+                                                       sibling = siblings[ --i ];
+                                                       if ( sibling.nodeType == CKEDITOR.NODE_TEXT ) {
+                                                               container = sibling;
+                                                               distance -= sibling.nodeValue.length;
+                                                       }
+                                               }
+
+                                               return { container: container, offset: -distance };
+                                       }
+                                       // Test range was one offset beyond OR behind the anchored text node.
+                                       else {
+                                               // Adapt one side of test range to the actual range
+                                               // for measuring the offset between them.
+                                               testRange.collapse( position > 0 ? true : false );
+                                               testRange.setEndPoint( position > 0 ? 'StartToStart' : 'EndToStart', range );
+
+                                               // IE report line break as CRLF with range.text but
+                                               // only LF with textnode.nodeValue, normalize them to avoid
+                                               // breaking character counting logic below. (#3949)
+                                               distance = testRange.text.replace( /(\r\n|\r)/g, '\n' ).length;
+
+                                               // Actual range anchor right beside test range at the inner boundary of text node.
+                                               if ( !distance )
+                                                       return { container: parent, offset: getNodeIndex( child ) + ( position > 0 ? 0 : 1 ) };
+
+                                               // Start the measuring until distance overflows, meanwhile count the text nodes.
+                                               while ( distance > 0 ) {
+                                                       try {
+                                                               sibling = child[ position > 0 ? 'previousSibling' : 'nextSibling' ];
+                                                               if ( sibling.nodeType == CKEDITOR.NODE_TEXT ) {
+                                                                       distance -= sibling.nodeValue.length;
+                                                                       container = sibling;
+                                                               }
+                                                               child = sibling;
+                                                       }
+                                                       // Measurement in IE could be somtimes wrong because of <select> element. (#4611)
+                                                       catch ( e ) {
+                                                               return { container: parent, offset: getNodeIndex( child ) };
+                                                       }
+                                               }
+
+                                               return { container: container, offset: position > 0 ? -distance : container.nodeValue.length + distance };
+                                       }
+                               };
+
+                               return function() {
+                                       // IE doesn't have range support (in the W3C way), so we
+                                       // need to do some magic to transform selections into
+                                       // CKEDITOR.dom.range instances.
+
+                                       var sel = this.getNative(),
+                                               nativeRange = sel && sel.createRange(),
+                                               type = this.getType(),
+                                               range;
+
+                                       if ( !sel )
+                                               return [];
+
+                                       if ( type == CKEDITOR.SELECTION_TEXT ) {
+                                               range = new CKEDITOR.dom.range( this.root );
+
+                                               var boundaryInfo = getBoundaryInformation( nativeRange, true );
+                                               range.setStart( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset );
+
+                                               boundaryInfo = getBoundaryInformation( nativeRange );
+                                               range.setEnd( new CKEDITOR.dom.node( boundaryInfo.container ), boundaryInfo.offset );
+
+                                               // Correct an invalid IE range case on empty list item. (#5850)
+                                               if ( range.endContainer.getPosition( range.startContainer ) & CKEDITOR.POSITION_PRECEDING && range.endOffset <= range.startContainer.getIndex() )
+                                                       range.collapse();
+
+                                               return [ range ];
+                                       } else if ( type == CKEDITOR.SELECTION_ELEMENT ) {
+                                               var retval = [];
+
+                                               for ( var i = 0; i < nativeRange.length; i++ ) {
+                                                       var element = nativeRange.item( i ),
+                                                               parentElement = element.parentNode,
+                                                               j = 0;
+
+                                                       range = new CKEDITOR.dom.range( this.root );
+
+                                                       for ( ; j < parentElement.childNodes.length && parentElement.childNodes[ j ] != element; j++ ) {
+
+                                                       }
+
+                                                       range.setStart( new CKEDITOR.dom.node( parentElement ), j );
+                                                       range.setEnd( new CKEDITOR.dom.node( parentElement ), j + 1 );
+                                                       retval.push( range );
+                                               }
+
+                                               return retval;
+                                       }
+
+                                       return [];
+                               };
+                       } )() :
+                       function() {
+                               // On browsers implementing the W3C range, we simply
+                               // tranform the native ranges in CKEDITOR.dom.range
+                               // instances.
+
+                               var ranges = [],
+                                       range,
+                                       sel = this.getNative();
+
+                               if ( !sel )
+                                       return ranges;
+
+                               for ( var i = 0; i < sel.rangeCount; i++ ) {
+                                       var nativeRange = sel.getRangeAt( i );
+
+                                       range = new CKEDITOR.dom.range( this.root );
+
+                                       range.setStart( new CKEDITOR.dom.node( nativeRange.startContainer ), nativeRange.startOffset );
+                                       range.setEnd( new CKEDITOR.dom.node( nativeRange.endContainer ), nativeRange.endOffset );
+                                       ranges.push( range );
+                               }
+                               return ranges;
+                       };
+
+                       return function( onlyEditables ) {
+                               var cache = this._.cache,
+                                       ranges = cache.ranges;
+
+                               if ( !ranges )
+                                       cache.ranges = ranges = new CKEDITOR.dom.rangeList( func.call( this ) );
+
+                               if ( !onlyEditables )
+                                       return ranges;
+
+                               // Split range into multiple by read-only nodes.
+                               // Clone ranges array to avoid changing cached ranges (#11493).
+                               return extractEditableRanges( new CKEDITOR.dom.rangeList( ranges.slice() ) );
+                       };
+               } )(),
+
+               /**
+                * Gets the DOM element in which the selection starts.
+                *
+                *              var element = editor.getSelection().getStartElement();
+                *              alert( element.getName() );
+                *
+                * @returns {CKEDITOR.dom.element} The element at the beginning of the selection.
+                */
+               getStartElement: function() {
+                       var cache = this._.cache;
+                       if ( cache.startElement !== undefined )
+                               return cache.startElement;
+
+                       var node;
+
+                       switch ( this.getType() ) {
+                               case CKEDITOR.SELECTION_ELEMENT:
+                                       return this.getSelectedElement();
+
+                               case CKEDITOR.SELECTION_TEXT:
+
+                                       var range = this.getRanges()[ 0 ];
+
+                                       if ( range ) {
+                                               if ( !range.collapsed ) {
+                                                       range.optimize();
+
+                                                       // Decrease the range content to exclude particial
+                                                       // selected node on the start which doesn't have
+                                                       // visual impact. ( #3231 )
+                                                       while ( 1 ) {
+                                                               var startContainer = range.startContainer,
+                                                                       startOffset = range.startOffset;
+                                                               // Limit the fix only to non-block elements.(#3950)
+                                                               if ( startOffset == ( startContainer.getChildCount ? startContainer.getChildCount() : startContainer.getLength() ) && !startContainer.isBlockBoundary() )
+                                                                       range.setStartAfter( startContainer );
+                                                               else
+                                                                       break;
+                                                       }
+
+                                                       node = range.startContainer;
+
+                                                       if ( node.type != CKEDITOR.NODE_ELEMENT )
+                                                               return node.getParent();
+
+                                                       node = node.getChild( range.startOffset );
+
+                                                       if ( !node || node.type != CKEDITOR.NODE_ELEMENT )
+                                                               node = range.startContainer;
+                                                       else {
+                                                               var child = node.getFirst();
+                                                               while ( child && child.type == CKEDITOR.NODE_ELEMENT ) {
+                                                                       node = child;
+                                                                       child = child.getFirst();
+                                                               }
+                                                       }
+                                               } else {
+                                                       node = range.startContainer;
+                                                       if ( node.type != CKEDITOR.NODE_ELEMENT )
+                                                               node = node.getParent();
+                                               }
+
+                                               node = node.$;
+                                       }
+                       }
+
+                       return cache.startElement = ( node ? new CKEDITOR.dom.element( node ) : null );
+               },
+
+               /**
+                * Gets the currently selected element.
+                *
+                *              var element = editor.getSelection().getSelectedElement();
+                *              alert( element.getName() );
+                *
+                * @returns {CKEDITOR.dom.element} The selected element. Null if no
+                * selection is available or the selection type is not {@link CKEDITOR#SELECTION_ELEMENT}.
+                */
+               getSelectedElement: function() {
+                       var cache = this._.cache;
+                       if ( cache.selectedElement !== undefined )
+                               return cache.selectedElement;
+
+                       var self = this;
+
+                       var node = CKEDITOR.tools.tryThese(
+                               // Is it native IE control type selection?
+                               function() {
+                                       return self.getNative().createRange().item( 0 );
+                               },
+                               // Figure it out by checking if there's a single enclosed
+                               // node of the range.
+                               function() {
+                                       var range = self.getRanges()[ 0 ].clone(),
+                                               enclosed, selected;
+
+                                       // Check first any enclosed element, e.g. <ul>[<li><a href="#">item</a></li>]</ul>
+                                       for ( var i = 2; i && !( ( enclosed = range.getEnclosedNode() ) && ( enclosed.type == CKEDITOR.NODE_ELEMENT ) && styleObjectElements[ enclosed.getName() ] && ( selected = enclosed ) ); i-- ) {
+                                               // Then check any deep wrapped element, e.g. [<b><i><img /></i></b>]
+                                               range.shrink( CKEDITOR.SHRINK_ELEMENT );
+                                       }
+
+                                       return selected && selected.$;
+                               }
+                       );
+
+                       return cache.selectedElement = ( node ? new CKEDITOR.dom.element( node ) : null );
+               },
+
+               /**
+                * Retrieves the text contained within the range. An empty string is returned for non-text selection.
+                *
+                *              var text = editor.getSelection().getSelectedText();
+                *              alert( text );
+                *
+                * @since 3.6.1
+                * @returns {String} A string of text within the current selection.
+                */
+               getSelectedText: function() {
+                       var cache = this._.cache;
+                       if ( cache.selectedText !== undefined )
+                               return cache.selectedText;
+
+                       var nativeSel = this.getNative(),
+                               text = isMSSelection ? nativeSel.type == 'Control' ? '' : nativeSel.createRange().text : nativeSel.toString();
+
+                       return ( cache.selectedText = text );
+               },
+
+               /**
+                * Locks the selection made in the editor in order to make it possible to
+                * manipulate it without browser interference. A locked selection is
+                * cached and remains unchanged until it is released with the {@link #unlock} method.
+                *
+                *              editor.getSelection().lock();
+                */
+               lock: function() {
+                       // Call all cacheable function.
+                       this.getRanges();
+                       this.getStartElement();
+                       this.getSelectedElement();
+                       this.getSelectedText();
+
+                       // The native selection is not available when locked.
+                       this._.cache.nativeSel = null;
+
+                       this.isLocked = 1;
+               },
+
+               /**
+                * @todo
+                */
+               unlock: function( restore ) {
+                       if ( !this.isLocked )
+                               return;
+
+                       if ( restore ) {
+                               var selectedElement = this.getSelectedElement(),
+                                       ranges = !selectedElement && this.getRanges(),
+                                       faked = this.isFake;
+                       }
+
+                       this.isLocked = 0;
+                       this.reset();
+
+                       if ( restore ) {
+                               // Saved selection may be outdated (e.g. anchored in offline nodes).
+                               // Avoid getting broken by such.
+                               var common = selectedElement || ranges[ 0 ] && ranges[ 0 ].getCommonAncestor();
+                               if ( !( common && common.getAscendant( 'body', 1 ) ) )
+                                       return;
+
+                               if ( faked )
+                                       this.fake( selectedElement );
+                               else if ( selectedElement )
+                                       this.selectElement( selectedElement );
+                               else
+                                       this.selectRanges( ranges );
+                       }
+               },
+
+               /**
+                * Clears the selection cache.
+                *
+                *              editor.getSelection().reset();
+                */
+               reset: function() {
+                       this._.cache = {};
+                       this.isFake = 0;
+
+                       var editor = this.root.editor;
+
+                       // Invalidate any fake selection available in the editor.
+                       if ( editor && editor._.fakeSelection ) {
+                               // Test whether this selection is the one that was
+                               // faked or its clone.
+                               if ( this.rev == editor._.fakeSelection.rev ) {
+                                       delete editor._.fakeSelection;
+
+                                       removeHiddenSelectionContainer( editor );
+                               }
+                               else {
+                                       CKEDITOR.warn( 'selection-fake-reset' );
+                               }
+                       }
+
+                       this.rev = nextRev++;
+               },
+
+               /**
+                * Makes the current selection of type {@link CKEDITOR#SELECTION_ELEMENT} by enclosing the specified element.
+                *
+                *              var element = editor.document.getById( 'sampleElement' );
+                *              editor.getSelection().selectElement( element );
+                *
+                * @param {CKEDITOR.dom.element} element The element to enclose in the selection.
+                */
+               selectElement: function( element ) {
+                       var range = new CKEDITOR.dom.range( this.root );
+                       range.setStartBefore( element );
+                       range.setEndAfter( element );
+                       this.selectRanges( [ range ] );
+               },
+
+               /**
+                * Clears the original selection and adds the specified ranges to the document selection.
+                *
+                *              // Move selection to the end of the editable element.
+                *              var range = editor.createRange();
+                *              range.moveToPosition( range.root, CKEDITOR.POSITION_BEFORE_END );
+                *              editor.getSelection().selectRanges( [ ranges ] );
+                *
+                * @param {Array} ranges An array of {@link CKEDITOR.dom.range} instances
+                * representing ranges to be added to the document.
+                */
+               selectRanges: function( ranges ) {
+                       var editor = this.root.editor,
+                               hadHiddenSelectionContainer = editor && editor._.hiddenSelectionContainer;
+
+                       this.reset();
+
+                       // Check if there's a hiddenSelectionContainer in editable at some index.
+                       // Some ranges may be anchored after the hiddenSelectionContainer and,
+                       // once the container is removed while resetting the selection, they
+                       // may need new endOffset (one element less within the range) (#11021 #11393).
+                       if ( hadHiddenSelectionContainer )
+                               fixRangesAfterHiddenSelectionContainer( ranges, this.root );
+
+                       if ( !ranges.length )
+                               return;
+
+                       // Refresh the locked selection.
+                       if ( this.isLocked ) {
+                               // making a new DOM selection will force the focus on editable in certain situation,
+                               // we have to save the currently focused element for later recovery.
+                               var focused = CKEDITOR.document.getActive();
+                               this.unlock();
+                               this.selectRanges( ranges );
+                               this.lock();
+                               // Return to the previously focused element.
+                               focused && !focused.equals( this.root ) && focused.focus();
+                               return;
+                       }
+
+                       // Handle special case - automatic fake selection on non-editable elements.
+                       var receiver = getNonEditableFakeSelectionReceiver( ranges );
+
+                       if ( receiver ) {
+                               this.fake( receiver );
+                               return;
+                       }
+
+                       if ( isMSSelection ) {
+                               var notWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),
+                                       fillerTextRegex = /\ufeff|\u00a0/,
+                                       nonCells = { table: 1, tbody: 1, tr: 1 };
+
+                               if ( ranges.length > 1 ) {
+                                       // IE doesn't accept multiple ranges selection, so we join all into one.
+                                       var last = ranges[ ranges.length - 1 ];
+                                       ranges[ 0 ].setEnd( last.endContainer, last.endOffset );
+                               }
+
+                               var range = ranges[ 0 ];
+                               var collapsed = range.collapsed,
+                                       isStartMarkerAlone, dummySpan, ieRange;
+
+                               // Try to make a object selection, be careful with selecting phase element in IE
+                               // will breaks the selection in non-framed environment.
+                               var selected = range.getEnclosedNode();
+                               if ( selected && selected.type == CKEDITOR.NODE_ELEMENT && selected.getName() in styleObjectElements &&
+                                       !( selected.is( 'a' ) && selected.getText() ) ) {
+                                       try {
+                                               ieRange = selected.$.createControlRange();
+                                               ieRange.addElement( selected.$ );
+                                               ieRange.select();
+                                               return;
+                                       } catch ( er ) {}
+                               }
+
+                               // IE doesn't support selecting the entire table row/cell, move the selection into cells, e.g.
+                               // <table><tbody><tr>[<td>cell</b></td>... => <table><tbody><tr><td>[cell</td>...
+                               if ( range.startContainer.type == CKEDITOR.NODE_ELEMENT && range.startContainer.getName() in nonCells ||
+                                       range.endContainer.type == CKEDITOR.NODE_ELEMENT && range.endContainer.getName() in nonCells ) {
+                                       range.shrink( CKEDITOR.NODE_ELEMENT, true );
+                                       // The range might get collapsed (#7975). Update cached variable.
+                                       collapsed = range.collapsed;
+                               }
+
+                               var bookmark = range.createBookmark();
+
+                               // Create marker tags for the start and end boundaries.
+                               var startNode = bookmark.startNode;
+
+                               var endNode;
+                               if ( !collapsed )
+                                       endNode = bookmark.endNode;
+
+                               // Create the main range which will be used for the selection.
+                               ieRange = range.document.$.body.createTextRange();
+
+                               // Position the range at the start boundary.
+                               ieRange.moveToElementText( startNode.$ );
+                               ieRange.moveStart( 'character', 1 );
+
+                               if ( endNode ) {
+                                       // Create a tool range for the end.
+                                       var ieRangeEnd = range.document.$.body.createTextRange();
+
+                                       // Position the tool range at the end.
+                                       ieRangeEnd.moveToElementText( endNode.$ );
+
+                                       // Move the end boundary of the main range to match the tool range.
+                                       ieRange.setEndPoint( 'EndToEnd', ieRangeEnd );
+                                       ieRange.moveEnd( 'character', -1 );
+                               } else {
+                                       // The isStartMarkerAlone logic comes from V2. It guarantees that the lines
+                                       // will expand and that the cursor will be blinking on the right place.
+                                       // Actually, we are using this flag just to avoid using this hack in all
+                                       // situations, but just on those needed.
+                                       var next = startNode.getNext( notWhitespaces );
+                                       var inPre = startNode.hasAscendant( 'pre' );
+                                       isStartMarkerAlone = ( !( next && next.getText && next.getText().match( fillerTextRegex ) ) && // already a filler there?
+                                               ( inPre || !startNode.hasPrevious() || ( startNode.getPrevious().is && startNode.getPrevious().is( 'br' ) ) ) );
+
+                                       // Append a temporary <span>&#65279;</span> before the selection.
+                                       // This is needed to avoid IE destroying selections inside empty
+                                       // inline elements, like <b></b> (#253).
+                                       // It is also needed when placing the selection right after an inline
+                                       // element to avoid the selection moving inside of it.
+                                       dummySpan = range.document.createElement( 'span' );
+                                       dummySpan.setHtml( '&#65279;' ); // Zero Width No-Break Space (U+FEFF). See #1359.
+                                       dummySpan.insertBefore( startNode );
+
+                                       if ( isStartMarkerAlone ) {
+                                               // To expand empty blocks or line spaces after <br>, we need
+                                               // instead to have any char, which will be later deleted using the
+                                               // selection.
+                                               // \ufeff = Zero Width No-Break Space (U+FEFF). (#1359)
+                                               range.document.createText( '\ufeff' ).insertBefore( startNode );
+                                       }
+                               }
+
+                               // Remove the markers (reset the position, because of the changes in the DOM tree).
+                               range.setStartBefore( startNode );
+                               startNode.remove();
+
+                               if ( collapsed ) {
+                                       if ( isStartMarkerAlone ) {
+                                               // Move the selection start to include the temporary \ufeff.
+                                               ieRange.moveStart( 'character', -1 );
+
+                                               ieRange.select();
+
+                                               // Remove our temporary stuff.
+                                               range.document.$.selection.clear();
+                                       } else {
+                                               ieRange.select();
+                                       }
+
+                                       range.moveToPosition( dummySpan, CKEDITOR.POSITION_BEFORE_START );
+                                       dummySpan.remove();
+                               } else {
+                                       range.setEndBefore( endNode );
+                                       endNode.remove();
+                                       ieRange.select();
+                               }
+                       } else {
+                               var sel = this.getNative();
+
+                               // getNative() returns null if iframe is "display:none" in FF. (#6577)
+                               if ( !sel )
+                                       return;
+
+                               this.removeAllRanges();
+
+                               for ( var i = 0; i < ranges.length; i++ ) {
+                                       // Joining sequential ranges introduced by
+                                       // readonly elements protection.
+                                       if ( i < ranges.length - 1 ) {
+                                               var left = ranges[ i ],
+                                                       right = ranges[ i + 1 ],
+                                                       between = left.clone();
+                                               between.setStart( left.endContainer, left.endOffset );
+                                               between.setEnd( right.startContainer, right.startOffset );
+
+                                               // Don't confused by Firefox adjancent multi-ranges
+                                               // introduced by table cells selection.
+                                               if ( !between.collapsed ) {
+                                                       between.shrink( CKEDITOR.NODE_ELEMENT, true );
+                                                       var ancestor = between.getCommonAncestor(),
+                                                               enclosed = between.getEnclosedNode();
+
+                                                       // The following cases has to be considered:
+                                                       // 1. <span contenteditable="false">[placeholder]</span>
+                                                       // 2. <input contenteditable="false"  type="radio"/> (#6621)
+                                                       if ( ancestor.isReadOnly() || enclosed && enclosed.isReadOnly() ) {
+                                                               right.setStart( left.startContainer, left.startOffset );
+                                                               ranges.splice( i--, 1 );
+                                                               continue;
+                                                       }
+                                               }
+                                       }
+
+                                       range = ranges[ i ];
+
+                                       var nativeRange = this.document.$.createRange();
+
+                                       if ( range.collapsed && CKEDITOR.env.webkit && rangeRequiresFix( range ) ) {
+                                               // Append a zero-width space so WebKit will not try to
+                                               // move the selection by itself (#1272).
+                                               var fillingChar = createFillingCharSequenceNode( this.root );
+                                               range.insertNode( fillingChar );
+
+                                               next = fillingChar.getNext();
+
+                                               // If the filling char is followed by a <br>, whithout
+                                               // having something before it, it'll not blink.
+                                               // Let's remove it in this case.
+                                               if ( next && !fillingChar.getPrevious() && next.type == CKEDITOR.NODE_ELEMENT && next.getName() == 'br' ) {
+                                                       removeFillingCharSequenceNode( this.root );
+                                                       range.moveToPosition( next, CKEDITOR.POSITION_BEFORE_START );
+                                               } else {
+                                                       range.moveToPosition( fillingChar, CKEDITOR.POSITION_AFTER_END );
+                                               }
+                                       }
+
+                                       nativeRange.setStart( range.startContainer.$, range.startOffset );
+
+                                       try {
+                                               nativeRange.setEnd( range.endContainer.$, range.endOffset );
+                                       } catch ( e ) {
+                                               // There is a bug in Firefox implementation (it would be too easy
+                                               // otherwise). The new start can't be after the end (W3C says it can).
+                                               // So, let's create a new range and collapse it to the desired point.
+                                               if ( e.toString().indexOf( 'NS_ERROR_ILLEGAL_VALUE' ) >= 0 ) {
+                                                       range.collapse( 1 );
+                                                       nativeRange.setEnd( range.endContainer.$, range.endOffset );
+                                               } else {
+                                                       throw e;
+                                               }
+                                       }
+
+                                       // Select the range.
+                                       sel.addRange( nativeRange );
+                               }
+                       }
+
+                       this.reset();
+
+                       // Fakes the IE DOM event "selectionchange" on editable.
+                       this.root.fire( 'selectionchange' );
+               },
+
+               /**
+                * Makes a "fake selection" of an element.
+                *
+                * A fake selection does not render UI artifacts over the selected
+                * element. Additionally, the browser native selection system is not
+                * aware of the fake selection. In practice, the native selection is
+                * moved to a hidden place where no native selection UI artifacts are
+                * displayed to the user.
+                *
+                * @param {CKEDITOR.dom.element} element The element to be "selected".
+                * @param {String} [ariaLabel] A string to be used by the screen reader to describe the selection.
+                */
+               fake: function( element, ariaLabel ) {
+                       var editor = this.root.editor;
+
+                       // Attempt to retreive aria-label if possible (#14539).
+                       if ( ariaLabel === undefined && element.hasAttribute( 'aria-label' ) ) {
+                               ariaLabel = element.getAttribute( 'aria-label' );
+                       }
+
+                       // Cleanup after previous selection - e.g. remove hidden sel container.
+                       this.reset();
+
+                       hideSelection( editor, ariaLabel );
+
+                       // Set this value after executing hiseSelection, because it may
+                       // cause reset() which overwrites cache.
+                       var cache = this._.cache;
+
+                       // Caches a range than holds the element.
+                       var range = new CKEDITOR.dom.range( this.root );
+                       range.setStartBefore( element );
+                       range.setEndAfter( element );
+                       cache.ranges = new CKEDITOR.dom.rangeList( range );
+
+                       // Put this element in the cache.
+                       cache.selectedElement = cache.startElement = element;
+                       cache.type = CKEDITOR.SELECTION_ELEMENT;
+
+                       // Properties that will not be available when isFake.
+                       cache.selectedText = cache.nativeSel = null;
+
+                       this.isFake = 1;
+                       this.rev = nextRev++;
+
+                       // Save this selection, so it can be returned by editor.getSelection().
+                       editor._.fakeSelection = this;
+
+                       // Fire selectionchange, just like a normal selection.
+                       this.root.fire( 'selectionchange' );
+               },
+
+               /**
+                * Checks whether selection is placed in hidden element.
+                *
+                * This method is to be used to verify whether fake selection
+                * (see {@link #fake}) is still hidden.
+                *
+                * **Note:** this method should be executed on real selection - e.g.:
+                *
+                *              editor.getSelection( true ).isHidden();
+                *
+                * @returns {Boolean}
+                */
+               isHidden: function() {
+                       var el = this.getCommonAncestor();
+
+                       if ( el && el.type == CKEDITOR.NODE_TEXT )
+                               el = el.getParent();
+
+                       return !!( el && el.data( 'cke-hidden-sel' ) );
+               },
+
+               /**
+                * Creates a bookmark for each range of this selection (from {@link #getRanges})
+                * by calling the {@link CKEDITOR.dom.range#createBookmark} method,
+                * with extra care taken to avoid interference among those ranges. The arguments
+                * received are the same as with the underlying range method.
+                *
+                *              var bookmarks = editor.getSelection().createBookmarks();
+                *
+                * @returns {Array} Array of bookmarks for each range.
+                */
+               createBookmarks: function( serializable ) {
+                       var bookmark = this.getRanges().createBookmarks( serializable );
+                       this.isFake && ( bookmark.isFake = 1 );
+                       return bookmark;
+               },
+
+               /**
+                * Creates a bookmark for each range of this selection (from {@link #getRanges})
+                * by calling the {@link CKEDITOR.dom.range#createBookmark2} method,
+                * with extra care taken to avoid interference among those ranges. The arguments
+                * received are the same as with the underlying range method.
+                *
+                *              var bookmarks = editor.getSelection().createBookmarks2();
+                *
+                * @returns {Array} Array of bookmarks for each range.
+                */
+               createBookmarks2: function( normalized ) {
+                       var bookmark = this.getRanges().createBookmarks2( normalized );
+                       this.isFake && ( bookmark.isFake = 1 );
+                       return bookmark;
+               },
+
+               /**
+                * Selects the virtual ranges denoted by the bookmarks by calling {@link #selectRanges}.
+                *
+                *              var bookmarks = editor.getSelection().createBookmarks();
+                *              editor.getSelection().selectBookmarks( bookmarks );
+                *
+                * @param {Array} bookmarks The bookmarks representing ranges to be selected.
+                * @returns {CKEDITOR.dom.selection} This selection object, after the ranges were selected.
+                */
+               selectBookmarks: function( bookmarks ) {
+                       var ranges = [],
+                               node;
+
+                       for ( var i = 0; i < bookmarks.length; i++ ) {
+                               var range = new CKEDITOR.dom.range( this.root );
+                               range.moveToBookmark( bookmarks[ i ] );
+                               ranges.push( range );
+                       }
+
+                       // It may happen that the content change during loading, before selection is set so bookmark leads to text node.
+                       if ( bookmarks.isFake ) {
+                               node = ranges[ 0 ].getEnclosedNode();
+                               if ( !node || node.type != CKEDITOR.NODE_ELEMENT ) {
+                                       CKEDITOR.warn( 'selection-not-fake' );
+                                       bookmarks.isFake = 0;
+                               }
+                       }
+
+                       if ( bookmarks.isFake )
+                               this.fake( node );
+                       else
+                               this.selectRanges( ranges );
+
+                       return this;
+               },
+
+               /**
+                * Retrieves the common ancestor node of the first range and the last range.
+                *
+                *              var ancestor = editor.getSelection().getCommonAncestor();
+                *
+                * @returns {CKEDITOR.dom.element} The common ancestor of the selection or `null` if selection is empty.
+                */
+               getCommonAncestor: function() {
+                       var ranges = this.getRanges();
+                       if ( !ranges.length )
+                               return null;
+
+                       var startNode = ranges[ 0 ].startContainer,
+                               endNode = ranges[ ranges.length - 1 ].endContainer;
+                       return startNode.getCommonAncestor( endNode );
+               },
+
+               /**
+                * Moves the scrollbar to the starting position of the current selection.
+                *
+                *              editor.getSelection().scrollIntoView();
+                */
+               scrollIntoView: function() {
+                       // Scrolls the first range into view.
+                       if ( this.type != CKEDITOR.SELECTION_NONE )
+                               this.getRanges()[ 0 ].scrollIntoView();
+               },
+
+               /**
+                * Remove all the selection ranges from the document.
+                */
+               removeAllRanges: function() {
+                       // Don't clear selection outside this selection's root (#11500).
+                       if ( this.getType() == CKEDITOR.SELECTION_NONE )
+                               return;
+
+                       var nativ = this.getNative();
+
+                       try {
+                               nativ && nativ[ isMSSelection ? 'empty' : 'removeAllRanges' ]();
+                       } catch ( er ) {}
+
+                       this.reset();
+               }
+       };
+
+} )();
+
+
+/**
+ * Fired when selection inside editor has been changed. Note that this event
+ * is fired only when selection's start element (container of a selecion start)
+ * changes, not on every possible selection change. Thanks to that `selectionChange`
+ * is fired less frequently, but on every context
+ * (the {@link CKEDITOR.editor#elementPath elements path} holding selection's start) change.
+ *
+ * @event selectionChange
+ * @member CKEDITOR.editor
+ * @param {CKEDITOR.editor} editor This editor instance.
+ * @param data
+ * @param {CKEDITOR.dom.selection} data.selection
+ * @param {CKEDITOR.dom.elementPath} data.path
+ */
+
+/**
+ * Selection's revision. This value is incremented every time new
+ * selection is created or existing one is modified.
+ *
+ * @since 4.3
+ * @readonly
+ * @property {Number} rev
+ */
+
+/**
+ * Document in which selection is anchored.
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.document} document
+ */
+
+/**
+ * Selection's root element.
+ *
+ * @readonly
+ * @property {CKEDITOR.dom.element} root
+ */
+
+/**
+ * Whether selection is locked (cannot be modified).
+ *
+ * See {@link #lock} and {@link #unlock} methods.
+ *
+ * @readonly
+ * @property {Boolean} isLocked
+ */
+
+/**
+ * Whether selection is a fake selection.
+ *
+ * See {@link #fake} method.
+ *
+ * @readonly
+ * @property {Boolean} isFake
+ */
diff --git a/sources/core/skin.js b/sources/core/skin.js
new file mode 100644 (file)
index 0000000..4f0ee7c
--- /dev/null
@@ -0,0 +1,350 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.skin} class that is used to manage skin parts.
+ */
+
+( function() {
+       var cssLoaded = {};
+
+       function getName() {
+               return CKEDITOR.skinName.split( ',' )[ 0 ];
+       }
+
+       function getConfigPath() {
+               return CKEDITOR.getUrl( CKEDITOR.skinName.split( ',' )[ 1 ] || ( 'skins/' + getName() + '/' ) );
+       }
+
+       /**
+        * Manages the loading of skin parts among all editor instances.
+        *
+        * @class
+        * @singleton
+        */
+       CKEDITOR.skin = {
+               /**
+                * Returns the root path to the skin directory.
+                *
+                * @method
+                * @todo
+                */
+               path: getConfigPath,
+
+               /**
+                * Loads a skin part into the page. Does nothing if the part has already been loaded.
+                *
+                * **Note:** The "editor" part is always auto loaded upon instance creation,
+                * thus this function is mainly used to **lazy load** other parts of the skin
+                * that do not have to be displayed until requested.
+                *
+                *              // Load the dialog part.
+                *              editor.skin.loadPart( 'dialog' );
+                *
+                * @param {String} part The name of the skin part CSS file that resides in the skin directory.
+                * @param {Function} fn The provided callback function which is invoked after the part is loaded.
+                */
+               loadPart: function( part, fn ) {
+                       if ( CKEDITOR.skin.name != getName() ) {
+                               CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( getConfigPath() + 'skin.js' ), function() {
+                                       loadCss( part, fn );
+                               } );
+                       } else {
+                               loadCss( part, fn );
+                       }
+               },
+
+               /**
+                * Retrieves the real URL of a (CSS) skin part.
+                *
+                * @param {String} part
+                */
+               getPath: function( part ) {
+                       return CKEDITOR.getUrl( getCssPath( part ) );
+               },
+
+               /**
+                * The list of registered icons. To add new icons to this list, use {@link #addIcon}.
+                */
+               icons: {},
+
+               /**
+                * Registers an icon.
+                *
+                * @param {String} name The icon name.
+                * @param {String} path The path to the icon image file.
+                * @param {Number} [offset] The vertical offset position of the icon, if
+                * available inside a strip image.
+                * @param {String} [bgsize] The value of the CSS "background-size" property to
+                * use for this icon
+                */
+               addIcon: function( name, path, offset, bgsize ) {
+                       name = name.toLowerCase();
+                       if ( !this.icons[ name ] ) {
+                               this.icons[ name ] = {
+                                       path: path,
+                                       offset: offset || 0,
+                                       bgsize: bgsize || '16px'
+                               };
+                       }
+               },
+
+               /**
+                * Gets the CSS background styles to be used to render a specific icon.
+                *
+                * @param {String} name The icon name, as registered with {@link #addIcon}.
+                * @param {Boolean} [rtl] Indicates that the RTL version of the icon is
+                * to be used, if available.
+                * @param {String} [overridePath] The path to the icon image file. It
+                * overrides the path defined by the named icon, if available, and is
+                * used if the named icon was not registered.
+                * @param {Number} [overrideOffset] The vertical offset position of the
+                * icon. It overrides the offset defined by the named icon, if
+                * available, and is used if the named icon was not registered.
+                * @param {String} [overrideBgsize] The value of the CSS "background-size" property
+                * to use for the icon. It overrides the value defined by the named icon,
+                * if available, and is used if the named icon was not registered.
+                */
+               getIconStyle: function( name, rtl, overridePath, overrideOffset, overrideBgsize ) {
+                       var icon, path, offset, bgsize;
+
+                       if ( name ) {
+                               name = name.toLowerCase();
+                               // If we're in RTL, try to get the RTL version of the icon.
+                               if ( rtl )
+                                       icon = this.icons[ name + '-rtl' ];
+
+                               // If not in LTR or no RTL version available, get the generic one.
+                               if ( !icon )
+                                       icon = this.icons[ name ];
+                       }
+
+                       path = overridePath || ( icon && icon.path ) || '';
+                       offset = overrideOffset || ( icon && icon.offset );
+                       bgsize = overrideBgsize || ( icon && icon.bgsize ) || '16px';
+
+                       // If we use apostrophes in background-image, we must escape apostrophes in path (just to be sure). (#13361)
+                       if ( path )
+                               path = path.replace( /'/g, '\\\'' );
+
+                       return path &&
+                               ( 'background-image:url(\'' + CKEDITOR.getUrl( path ) + '\');background-position:0 ' + offset + 'px;background-size:' + bgsize + ';' );
+               }
+       };
+
+       function getCssPath( part ) {
+               // Check for ua-specific version of skin part.
+               var uas = CKEDITOR.skin[ 'ua_' + part ], env = CKEDITOR.env;
+               if ( uas ) {
+
+                       // Having versioned UA checked first.
+                       uas = uas.split( ',' ).sort( function( a, b ) {
+                               return a > b ? -1 : 1;
+                       } );
+
+                       // Loop through all ua entries, checking is any of them match the current ua.
+                       for ( var i = 0, ua; i < uas.length; i++ ) {
+                               ua = uas[ i ];
+
+                               if ( env.ie ) {
+                                       if ( ( ua.replace( /^ie/, '' ) == env.version ) || ( env.quirks && ua == 'iequirks' ) )
+                                               ua = 'ie';
+                               }
+
+                               if ( env[ ua ] ) {
+                                       part += '_' + uas[ i ];
+                                       break;
+                               }
+                       }
+               }
+               return CKEDITOR.getUrl( getConfigPath() + part + '.css' );
+       }
+
+       function loadCss( part, callback ) {
+               // Avoid reload.
+               if ( !cssLoaded[ part ] ) {
+                       CKEDITOR.document.appendStyleSheet( getCssPath( part ) );
+                       cssLoaded[ part ] = 1;
+               }
+
+               // CSS loading should not be blocking.
+               callback && callback();
+       }
+
+       CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
+               /** Gets the color of the editor user interface.
+                *
+                *              CKEDITOR.instances.editor1.getUiColor();
+                *
+                * @method
+                * @member CKEDITOR.editor
+                * @returns {String} uiColor The editor UI color or `undefined` if the UI color is not set.
+                */
+               getUiColor: function() {
+                       return this.uiColor;
+               },
+
+               /** Sets the color of the editor user interface. This method accepts a color value in
+                * hexadecimal notation, with a `#` character (e.g. #ffffff).
+                *
+                *              CKEDITOR.instances.editor1.setUiColor( '#ff00ff' );
+                *
+                * @method
+                * @member CKEDITOR.editor
+                * @param {String} color The desired editor UI color in hexadecimal notation.
+                */
+               setUiColor: function( color ) {
+                       var uiStyle = getStylesheet( CKEDITOR.document );
+
+                       return ( this.setUiColor = function( color ) {
+                               this.uiColor = color;
+
+                               var chameleon = CKEDITOR.skin.chameleon,
+                                       editorStyleContent = '',
+                                       panelStyleContent = '';
+
+                               if ( typeof chameleon == 'function' ) {
+                                       editorStyleContent = chameleon( this, 'editor' );
+                                       panelStyleContent = chameleon( this, 'panel' );
+                               }
+
+                               var replace = [ [ uiColorRegexp, color ] ];
+
+                               // Update general style.
+                               updateStylesheets( [ uiStyle ], editorStyleContent, replace );
+
+                               // Update panel styles.
+                               updateStylesheets( uiColorMenus, panelStyleContent, replace );
+                       } ).call( this, color );
+               }
+       } );
+
+       var uiColorStylesheetId = 'cke_ui_color',
+               uiColorMenus = [],
+               uiColorRegexp = /\$color/g;
+
+       function getStylesheet( document ) {
+               var node = document.getById( uiColorStylesheetId );
+               if ( !node ) {
+                       node = document.getHead().append( 'style' );
+                       node.setAttribute( 'id', uiColorStylesheetId );
+                       node.setAttribute( 'type', 'text/css' );
+               }
+               return node;
+       }
+
+       function updateStylesheets( styleNodes, styleContent, replace ) {
+               var r, i, content;
+
+               // We have to split CSS declarations for webkit.
+               if ( CKEDITOR.env.webkit ) {
+                       styleContent = styleContent.split( '}' ).slice( 0, -1 );
+                       for ( i = 0; i < styleContent.length; i++ )
+                               styleContent[ i ] = styleContent[ i ].split( '{' );
+               }
+
+               for ( var id = 0; id < styleNodes.length; id++ ) {
+                       if ( CKEDITOR.env.webkit ) {
+                               for ( i = 0; i < styleContent.length; i++ ) {
+                                       content = styleContent[ i ][ 1 ];
+                                       for ( r = 0; r < replace.length; r++ )
+                                               content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
+
+                                       styleNodes[ id ].$.sheet.addRule( styleContent[ i ][ 0 ], content );
+                               }
+                       } else {
+                               content = styleContent;
+                               for ( r = 0; r < replace.length; r++ )
+                                       content = content.replace( replace[ r ][ 0 ], replace[ r ][ 1 ] );
+
+                               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 )
+                                       styleNodes[ id ].$.styleSheet.cssText += content;
+                               else
+                                       styleNodes[ id ].$.innerHTML += content;
+                       }
+               }
+       }
+
+       CKEDITOR.on( 'instanceLoaded', function( evt ) {
+               // The chameleon feature is not for IE quirks.
+               if ( CKEDITOR.env.ie && CKEDITOR.env.quirks )
+                       return;
+
+               var editor = evt.editor,
+                       showCallback = function( event ) {
+                               var panel = event.data[ 0 ] || event.data;
+                               var iframe = panel.element.getElementsByTag( 'iframe' ).getItem( 0 ).getFrameDocument();
+
+                               // Add stylesheet if missing.
+                               if ( !iframe.getById( 'cke_ui_color' ) ) {
+                                       var node = getStylesheet( iframe );
+                                       uiColorMenus.push( node );
+
+                                       var color = editor.getUiColor();
+                                       // Set uiColor for new panel.
+                                       if ( color )
+                                               updateStylesheets( [ node ], CKEDITOR.skin.chameleon( editor, 'panel' ), [ [ uiColorRegexp, color ] ] );
+
+                               }
+                       };
+
+               editor.on( 'panelShow', showCallback );
+               editor.on( 'menuShow', showCallback );
+
+               // Apply UI color if specified in config.
+               if ( editor.config.uiColor )
+                       editor.setUiColor( editor.config.uiColor );
+       } );
+} )();
+
+/**
+ * The list of file names matching the browser user agent string from
+ * {@link CKEDITOR.env}. This is used to load the skin part file in addition
+ * to the "main" skin file for a particular browser.
+ *
+ * **Note:** For each of the defined skin parts the corresponding
+ * CSS file with the same name as the user agent must exist inside
+ * the skin directory.
+ *
+ * @property ua
+ * @todo type?
+ */
+
+/**
+ * The name of the skin that is currently used.
+ *
+ * @property {String} name
+ * @todo
+ */
+
+/**
+ * The editor skin name. Note that it is not possible to have editors with
+ * different skin settings in the same page. In such case just one of the
+ * skins will be used for all editors.
+ *
+ * This is a shortcut to {@link CKEDITOR#skinName}.
+ *
+ * It is possible to install skins outside the default `skin` folder in the
+ * editor installation. In that case, the absolute URL path to that folder
+ * should be provided, separated by a comma (`'skin_name,skin_path'`).
+ *
+ *             config.skin = 'moono';
+ *
+ *             config.skin = 'myskin,/customstuff/myskin/';
+ *
+ * @cfg {String} skin
+ * @member CKEDITOR.config
+ */
+
+/**
+ * A function that supports the chameleon (skin color switch) feature, providing
+ * the skin color style updates to be applied in runtime.
+ *
+ * **Note:** The embedded `$color` variable is to be substituted with a specific UI color.
+ *
+ * @method chameleon
+ * @param {String} editor The editor instance that the color changes apply to.
+ * @param {String} part The name of the skin part where the color changes take place.
+ */
diff --git a/sources/core/style.js b/sources/core/style.js
new file mode 100644 (file)
index 0000000..efb9d7f
--- /dev/null
@@ -0,0 +1,2102 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+'use strict';
+
+/**
+ * Block style type.
+ *
+ * Read more in the {@link CKEDITOR.style} class documentation.
+ *
+ * @readonly
+ * @property {Number} [=1]
+ * @member CKEDITOR
+ */
+CKEDITOR.STYLE_BLOCK = 1;
+
+/**
+ * Inline style type.
+ *
+ * Read more in the {@link CKEDITOR.style} class documentation.
+ *
+ * @readonly
+ * @property {Number} [=2]
+ * @member CKEDITOR
+ */
+CKEDITOR.STYLE_INLINE = 2;
+
+/**
+ * Object style type.
+ *
+ * Read more in the {@link CKEDITOR.style} class documentation.
+ *
+ * @readonly
+ * @property {Number} [=3]
+ * @member CKEDITOR
+ */
+CKEDITOR.STYLE_OBJECT = 3;
+
+( function() {
+       var blockElements = {
+                       address: 1, div: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, p: 1,
+                       pre: 1, section: 1, header: 1, footer: 1, nav: 1, article: 1, aside: 1, figure: 1,
+                       dialog: 1, hgroup: 1, time: 1, meter: 1, menu: 1, command: 1, keygen: 1, output: 1,
+                       progress: 1, details: 1, datagrid: 1, datalist: 1
+               },
+
+               objectElements = {
+                       a: 1, blockquote: 1, embed: 1, hr: 1, img: 1, li: 1, object: 1, ol: 1, table: 1, td: 1,
+                       tr: 1, th: 1, ul: 1, dl: 1, dt: 1, dd: 1, form: 1, audio: 1, video: 1
+               };
+
+       var semicolonFixRegex = /\s*(?:;\s*|$)/,
+               varRegex = /#\((.+?)\)/g;
+
+       var notBookmark = CKEDITOR.dom.walker.bookmark( 0, 1 ),
+               nonWhitespaces = CKEDITOR.dom.walker.whitespaces( 1 );
+
+       /**
+        * A class representing a style instance for the specific style definition.
+        * In this approach, a style is a set of properties, like attributes and styles,
+        * which can be applied to and removed from a {@link CKEDITOR.dom.selection selection} through
+        * {@link CKEDITOR.editor editor} methods: {@link CKEDITOR.editor#applyStyle} and {@link CKEDITOR.editor#removeStyle},
+        * respectively.
+        *
+        * Three default style types are available: {@link CKEDITOR#STYLE_BLOCK STYLE_BLOCK}, {@link CKEDITOR#STYLE_INLINE STYLE_INLINE},
+        * and {@link CKEDITOR#STYLE_OBJECT STYLE_OBJECT}. Based on its type, a style heavily changes its behavior.
+        * You can read more about style types in the [Style Types section of the Styles guide](#!/guide/dev_styles-section-style-types).
+        *
+        * It is possible to define a custom style type by subclassing this class by using the {@link #addCustomHandler} method.
+        * However, because of great complexity of the styles handling job, it is only possible in very specific cases.
+        *
+        * ### Usage
+        *
+        * Basic usage:
+        *
+        *              // Define a block style.
+        *              var style = new CKEDITOR.style( { element: 'h1' } );
+        *
+        *              // Considering the following selection:
+        *              // <p>Foo</p><p>Bar^</p>
+        *              // Executing:
+        *              editor.applyStyle( style );
+        *              // Will give:
+        *              // <p>Foo</p><h1>Bar^</h1>
+        *              style.checkActive( editor.elementPath(), editor ); // -> true
+        *
+        *              editor.removeStyle( style );
+        *              // Will give:
+        *              // <p>Foo</p><p>Bar^</p>
+        *
+        *              style.checkActive( editor.elementPath(), editor ); // -> false
+        *
+        * Object style:
+        *
+        *              // Define an object style.
+        *              var style = new CKEDITOR.style( { element: 'img', attributes: { 'class': 'foo' } } );
+        *
+        *              // Considering the following selection:
+        *              // <p><img src="bar.png" alt="" />Foo^</p>
+        *              // Executing:
+        *              editor.applyStyle( style );
+        *              // Will not apply the style, because the image is not selected.
+        *              // You can check if a style can be applied on the current selection with:
+        *              style.checkApplicable( editor.elementPath(), editor ); // -> false
+        *
+        *              // Considering the following selection:
+        *              // <p>[<img src="bar.png" alt="" />]Foo</p>
+        *              // Executing
+        *              editor.applyStyle( style );
+        *              // Will give:
+        *              // <p>[<img src="bar.png" alt="" class="foo" />]Foo</p>
+        *
+        * ### API changes introduced in CKEditor 4.4
+        *
+        * Before CKEditor 4.4 all style instances had no access at all to the {@link CKEDITOR.editor editor instance}
+        * within which the style is used. Neither the style constructor, nor style methods were requiring
+        * passing the editor instance which made styles independent of the editor and hence its settings and state.
+        * This design decision came from CKEditor 3; it started causing problems and became an unsolvable obstacle for
+        * the {@link CKEDITOR.style.customHandlers.widget widget style handler} which we introduced in CKEditor 4.4.
+        *
+        * There were two possible solutions. Passing an editor instance to the style constructor or to every method.
+        * The first approach would be clean, however, having in mind the backward compatibility, we did not decide
+        * to go for it. It would bind the style to one editor instance, making it unusable with other editor instances.
+        * That could break many implementations reusing styles between editors. Therefore, we decided to take the longer
+        * but safer path &mdash; the editor instance became an argument for nearly all style methods, however,
+        * for backward compatibility reasons, all these methods will work without it. Even the newly
+        * implemented {@link CKEDITOR.style.customHandlers.widget widget style handler}'s methods will not fail,
+        * although they will also not work by aborting at an early stage.
+        *
+        * Therefore, you can safely upgrade to CKEditor 4.4 even if you use style methods without providing
+        * the editor instance. You must only align your code if your implementation should handle widget styles
+        * or any other custom style handler. Of course, we recommend doing this in any case to avoid potential
+        * problems in the future.
+        *
+        * @class
+        * @constructor Creates a style class instance.
+        * @param styleDefinition
+        * @param variablesValues
+        */
+       CKEDITOR.style = function( styleDefinition, variablesValues ) {
+               if ( typeof styleDefinition.type == 'string' )
+                       return new CKEDITOR.style.customHandlers[ styleDefinition.type ]( styleDefinition );
+
+               // Inline style text as attribute should be converted
+               // to styles object.
+               var attrs = styleDefinition.attributes;
+               if ( attrs && attrs.style ) {
+                       styleDefinition.styles = CKEDITOR.tools.extend( {},
+                               styleDefinition.styles, CKEDITOR.tools.parseCssText( attrs.style ) );
+                       delete attrs.style;
+               }
+
+               if ( variablesValues ) {
+                       styleDefinition = CKEDITOR.tools.clone( styleDefinition );
+
+                       replaceVariables( styleDefinition.attributes, variablesValues );
+                       replaceVariables( styleDefinition.styles, variablesValues );
+               }
+
+               var element = this.element = styleDefinition.element ?
+                       (
+                               typeof styleDefinition.element == 'string' ?
+                                       styleDefinition.element.toLowerCase() : styleDefinition.element
+                       ) : '*';
+
+               this.type = styleDefinition.type ||
+                       (
+                               blockElements[ element ] ? CKEDITOR.STYLE_BLOCK :
+                               objectElements[ element ] ? CKEDITOR.STYLE_OBJECT :
+                               CKEDITOR.STYLE_INLINE
+                       );
+
+               // If the 'element' property is an object with a set of possible element, it will be applied like an object style: only to existing elements
+               if ( typeof this.element == 'object' )
+                       this.type = CKEDITOR.STYLE_OBJECT;
+
+               this._ = {
+                       definition: styleDefinition
+               };
+       };
+
+       CKEDITOR.style.prototype = {
+               /**
+                * Applies the style on the editor's current selection.
+                *
+                * Before the style is applied, the method checks if the {@link #checkApplicable style is applicable}.
+                *
+                * **Note:** The recommended way of applying the style is by using the
+                * {@link CKEDITOR.editor#applyStyle} method, which is a shorthand for this method.
+                *
+                * @param {CKEDITOR.editor/CKEDITOR.dom.document} editor The editor instance in which
+                * the style will be applied.
+                * A {@link CKEDITOR.dom.document} instance is accepted for backward compatibility
+                * reasons, although since CKEditor 4.4 this type of argument is deprecated. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                */
+               apply: function( editor ) {
+                       // Backward compatibility.
+                       if ( editor instanceof CKEDITOR.dom.document )
+                               return applyStyleOnSelection.call( this, editor.getSelection() );
+
+                       if ( this.checkApplicable( editor.elementPath(), editor ) ) {
+                               var initialEnterMode = this._.enterMode;
+
+                               // See comment in removeStyle.
+                               if ( !initialEnterMode )
+                                       this._.enterMode = editor.activeEnterMode;
+                               applyStyleOnSelection.call( this, editor.getSelection(), 0, editor );
+                               this._.enterMode = initialEnterMode;
+                       }
+               },
+
+               /**
+                * Removes the style from the editor's current selection.
+                *
+                * Before the style is applied, the method checks if {@link #checkApplicable style could be applied}.
+                *
+                * **Note:** The recommended way of removing the style is by using the
+                * {@link CKEDITOR.editor#removeStyle} method, which is a shorthand for this method.
+                *
+                * @param {CKEDITOR.editor/CKEDITOR.dom.document} editor The editor instance in which
+                * the style will be removed.
+                * A {@link CKEDITOR.dom.document} instance is accepted for backward compatibility
+                * reasons, although since CKEditor 4.4 this type of argument is deprecated. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                */
+               remove: function( editor ) {
+                       // Backward compatibility.
+                       if ( editor instanceof CKEDITOR.dom.document )
+                               return applyStyleOnSelection.call( this, editor.getSelection(), 1 );
+
+                       if ( this.checkApplicable( editor.elementPath(), editor ) ) {
+                               var initialEnterMode = this._.enterMode;
+
+                               // Before CKEditor 4.4 style knew nothing about editor, so in order to provide enterMode
+                               // which should be used developers were forced to hack the style object (see #10190).
+                               // Since CKEditor 4.4 style knows about editor (at least when it's being applied/removed), but we
+                               // use _.enterMode for backward compatibility with those hacks.
+                               // Note: we should not change style's enter mode if it was already set.
+                               if ( !initialEnterMode )
+                                       this._.enterMode = editor.activeEnterMode;
+                               applyStyleOnSelection.call( this, editor.getSelection(), 1, editor );
+                               this._.enterMode = initialEnterMode;
+                       }
+               },
+
+               /**
+                * Applies the style on the provided range. Unlike {@link #apply} this
+                * method does not take care of setting the selection, however, the range
+                * is updated to the correct place.
+                *
+                * **Note:** If you want to apply the style on the editor selection,
+                * you probably want to use {@link CKEDITOR.editor#applyStyle}.
+                *
+                * @param {CKEDITOR.dom.range} range
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features.  Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                */
+               applyToRange: function( range ) {
+                       this.applyToRange =
+                               this.type == CKEDITOR.STYLE_INLINE ? applyInlineStyle :
+                               this.type == CKEDITOR.STYLE_BLOCK ? applyBlockStyle :
+                               this.type == CKEDITOR.STYLE_OBJECT ? applyObjectStyle :
+                               null;
+
+                       return this.applyToRange( range );
+               },
+
+               /**
+                * Removes the style from the provided range. Unlike {@link #remove} this
+                * method does not take care of setting the selection, however, the range
+                * is updated to the correct place.
+                *
+                * **Note:** If you want to remove the style from the editor selection,
+                * you probably want to use {@link CKEDITOR.editor#removeStyle}.
+                *
+                * @param {CKEDITOR.dom.range} range
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                */
+               removeFromRange: function( range ) {
+                       this.removeFromRange =
+                               this.type == CKEDITOR.STYLE_INLINE ? removeInlineStyle :
+                               this.type == CKEDITOR.STYLE_BLOCK ? removeBlockStyle :
+                               this.type == CKEDITOR.STYLE_OBJECT ? removeObjectStyle :
+                               null;
+
+                       return this.removeFromRange( range );
+               },
+
+               /**
+                * Applies the style to the element. This method bypasses all checks
+                * and applies the style attributes directly on the provided element. Use with caution.
+                *
+                * See {@link CKEDITOR.editor#applyStyle}.
+                *
+                * @param {CKEDITOR.dom.element} element
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                */
+               applyToObject: function( element ) {
+                       setupElement( element, this );
+               },
+
+               /**
+                * Gets the style state inside the elements path.
+                *
+                * @param {CKEDITOR.dom.elementPath} elementPath
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                * @returns {Boolean} `true` if the element is active in the elements path.
+                */
+               checkActive: function( elementPath, editor ) {
+                       switch ( this.type ) {
+                               case CKEDITOR.STYLE_BLOCK:
+                                       return this.checkElementRemovable( elementPath.block || elementPath.blockLimit, true, editor );
+
+                               case CKEDITOR.STYLE_OBJECT:
+                               case CKEDITOR.STYLE_INLINE:
+
+                                       var elements = elementPath.elements;
+
+                                       for ( var i = 0, element; i < elements.length; i++ ) {
+                                               element = elements[ i ];
+
+                                               if ( this.type == CKEDITOR.STYLE_INLINE && ( element == elementPath.block || element == elementPath.blockLimit ) )
+                                                       continue;
+
+                                               if ( this.type == CKEDITOR.STYLE_OBJECT ) {
+                                                       var name = element.getName();
+                                                       if ( !( typeof this.element == 'string' ? name == this.element : name in this.element ) )
+                                                               continue;
+                                               }
+
+                                               if ( this.checkElementRemovable( element, true, editor ) )
+                                                       return true;
+                                       }
+                       }
+                       return false;
+               },
+
+               /**
+                * Whether this style can be applied at the specified elements path.
+                *
+                * @param {CKEDITOR.dom.elementPath} elementPath The elements path to
+                * check the style against.
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                * @param {CKEDITOR.filter} [filter] If defined, the style will be
+                * checked against this filter as well.
+                * @returns {Boolean} `true` if this style can be applied at the elements path.
+                */
+               checkApplicable: function( elementPath, editor, filter ) {
+                       // Backward compatibility.
+                       if ( editor && editor instanceof CKEDITOR.filter )
+                               filter = editor;
+
+                       if ( filter && !filter.check( this ) )
+                               return false;
+
+                       switch ( this.type ) {
+                               case CKEDITOR.STYLE_OBJECT:
+                                       return !!elementPath.contains( this.element );
+                               case CKEDITOR.STYLE_BLOCK:
+                                       return !!elementPath.blockLimit.getDtd()[ this.element ];
+                       }
+
+                       return true;
+               },
+
+               /**
+                * Checks if the element matches the current style definition.
+                *
+                * @param {CKEDITOR.dom.element} element
+                * @param {Boolean} fullMatch
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                * @returns {Boolean}
+                */
+               checkElementMatch: function( element, fullMatch ) {
+                       var def = this._.definition;
+
+                       if ( !element || !def.ignoreReadonly && element.isReadOnly() )
+                               return false;
+
+                       var attribs,
+                               name = element.getName();
+
+                       // If the element name is the same as the style name.
+                       if ( typeof this.element == 'string' ? name == this.element : name in this.element ) {
+                               // If no attributes are defined in the element.
+                               if ( !fullMatch && !element.hasAttributes() )
+                                       return true;
+
+                               attribs = getAttributesForComparison( def );
+
+                               if ( attribs._length ) {
+                                       for ( var attName in attribs ) {
+                                               if ( attName == '_length' )
+                                                       continue;
+
+                                               var elementAttr = element.getAttribute( attName ) || '';
+
+                                               // Special treatment for 'style' attribute is required.
+                                               if ( attName == 'style' ? compareCssText( attribs[ attName ], elementAttr ) : attribs[ attName ] == elementAttr ) {
+                                                       if ( !fullMatch )
+                                                               return true;
+                                               } else if ( fullMatch ) {
+                                                       return false;
+                                               }
+                                       }
+                                       if ( fullMatch )
+                                               return true;
+                               } else {
+                                       return true;
+                               }
+                       }
+
+                       return false;
+               },
+
+               /**
+                * Checks if an element, or any of its attributes, is removable by the
+                * current style definition.
+                *
+                * @param {CKEDITOR.dom.element} element
+                * @param {Boolean} fullMatch
+                * @param {CKEDITOR.editor} editor The editor instance. Required argument since
+                * CKEditor 4.4. The style system will work without it, but it is highly
+                * recommended to provide it for integration with all features. Read more about
+                * the signature change in the {@link CKEDITOR.style} documentation.
+                * @returns {Boolean}
+                */
+               checkElementRemovable: function( element, fullMatch, editor ) {
+                       // Check element matches the style itself.
+                       if ( this.checkElementMatch( element, fullMatch, editor ) )
+                               return true;
+
+                       // Check if the element matches the style overrides.
+                       var override = getOverrides( this )[ element.getName() ];
+                       if ( override ) {
+                               var attribs, attName;
+
+                               // If no attributes have been defined, remove the element.
+                               if ( !( attribs = override.attributes ) )
+                                       return true;
+
+                               for ( var i = 0; i < attribs.length; i++ ) {
+                                       attName = attribs[ i ][ 0 ];
+                                       var actualAttrValue = element.getAttribute( attName );
+                                       if ( actualAttrValue ) {
+                                               var attValue = attribs[ i ][ 1 ];
+
+                                               // Remove the attribute if:
+                                               //    - The override definition value is null;
+                                               //    - The override definition value is a string that
+                                               //      matches the attribute value exactly.
+                                               //    - The override definition value is a regex that
+                                               //      has matches in the attribute value.
+                                               if ( attValue === null )
+                                                       return true;
+                                               if ( typeof attValue == 'string' ) {
+                                                       if ( actualAttrValue == attValue )
+                                                               return true;
+                                               } else if ( attValue.test( actualAttrValue ) ) {
+                                                       return true;
+                                               }
+                                       }
+                               }
+                       }
+                       return false;
+               },
+
+               /**
+                * Builds the preview HTML based on the styles definition.
+                *
+                * @param {String} [label] The label used in the style preview.
+                * @return {String} The HTML of preview.
+                */
+               buildPreview: function( label ) {
+                       var styleDefinition = this._.definition,
+                               html = [],
+                               elementName = styleDefinition.element;
+
+                       // Avoid <bdo> in the preview.
+                       if ( elementName == 'bdo' )
+                               elementName = 'span';
+
+                       html = [ '<', elementName ];
+
+                       // Assign all defined attributes.
+                       var attribs = styleDefinition.attributes;
+                       if ( attribs ) {
+                               for ( var att in attribs )
+                                       html.push( ' ', att, '="', attribs[ att ], '"' );
+                       }
+
+                       // Assign the style attribute.
+                       var cssStyle = CKEDITOR.style.getStyleText( styleDefinition );
+                       if ( cssStyle )
+                               html.push( ' style="', cssStyle, '"' );
+
+                       html.push( '>', ( label || styleDefinition.name ), '</', elementName, '>' );
+
+                       return html.join( '' );
+               },
+
+               /**
+                * Returns the style definition.
+                *
+                * @since 4.1
+                * @returns {Object}
+                */
+               getDefinition: function() {
+                       return this._.definition;
+               }
+
+               /**
+                * If defined (for example by {@link CKEDITOR.style#addCustomHandler custom style handler}), it returns
+                * the {@link CKEDITOR.filter.allowedContentRules allowed content rules} which should be added to the
+                * {@link CKEDITOR.filter} when enabling this style.
+                *
+                * **Note:** This method is not defined in the {@link CKEDITOR.style} class.
+                *
+                * @since 4.4
+                * @method toAllowedContentRules
+                * @param {CKEDITOR.editor} [editor] The editor instance.
+                * @returns {CKEDITOR.filter.allowedContentRules} The rules that should represent this style in the {@link CKEDITOR.filter}.
+                */
+       };
+
+       /**
+        * Builds the inline style text based on the style definition.
+        *
+        * @static
+        * @param styleDefinition
+        * @returns {String} Inline style text.
+        */
+       CKEDITOR.style.getStyleText = function( styleDefinition ) {
+               // If we have already computed it, just return it.
+               var stylesDef = styleDefinition._ST;
+               if ( stylesDef )
+                       return stylesDef;
+
+               stylesDef = styleDefinition.styles;
+
+               // Builds the StyleText.
+               var stylesText = ( styleDefinition.attributes && styleDefinition.attributes.style ) || '',
+                       specialStylesText = '';
+
+               if ( stylesText.length )
+                       stylesText = stylesText.replace( semicolonFixRegex, ';' );
+
+               for ( var style in stylesDef ) {
+                       var styleVal = stylesDef[ style ],
+                               text = ( style + ':' + styleVal ).replace( semicolonFixRegex, ';' );
+
+                       // Some browsers don't support 'inherit' property value, leave them intact. (#5242)
+                       if ( styleVal == 'inherit' )
+                               specialStylesText += text;
+                       else
+                               stylesText += text;
+               }
+
+               // Browsers make some changes to the style when applying them. So, here
+               // we normalize it to the browser format.
+               if ( stylesText.length )
+                       stylesText = CKEDITOR.tools.normalizeCssText( stylesText, true );
+
+               stylesText += specialStylesText;
+
+               // Return it, saving it to the next request.
+               return ( styleDefinition._ST = stylesText );
+       };
+
+       /**
+        * Namespace containing custom style handlers added with {@link CKEDITOR.style#addCustomHandler}.
+        *
+        * @since 4.4
+        * @class
+        * @singleton
+        */
+       CKEDITOR.style.customHandlers = {};
+
+       /**
+        * Creates a {@link CKEDITOR.style} subclass and registers it in the style system.
+        * Registered class will be used as a handler for a style of this type. This allows
+        * to extend the styles system, which by default uses only the {@link CKEDITOR.style}, with
+        * new functionality. Registered classes are accessible in the {@link CKEDITOR.style.customHandlers}.
+        *
+        * ### The Style Class Definition
+        *
+        * The definition object is used to override properties in a prototype inherited
+        * from the {@link CKEDITOR.style} class. It must contain a `type` property which is
+        * a name of the new type and therefore it must be unique. The default style types
+        * ({@link CKEDITOR#STYLE_BLOCK STYLE_BLOCK}, {@link CKEDITOR#STYLE_INLINE STYLE_INLINE},
+        * and {@link CKEDITOR#STYLE_OBJECT STYLE_OBJECT}) are integers, but for easier identification
+        * it is recommended to use strings as custom type names.
+        *
+        * Besides `type`, the definition may contain two more special properties:
+        *
+        *  * `setup {Function}` &ndash; An optional callback executed when a style instance is created.
+        * Like the style constructor, it is executed in style context and with the style definition as an argument.
+        *  * `assignedTo {Number}` &ndash; Can be set to one of the default style types. Some editor
+        * features like the Styles drop-down assign styles to one of the default groups based on
+        * the style type. By using this property it is possible to notify them to which group this
+        * custom style should be assigned. It defaults to the {@link CKEDITOR#STYLE_OBJECT}.
+        *
+        * Other properties of the definition object will just be used to extend the prototype inherited
+        * from the {@link CKEDITOR.style} class. So if the definition contains an `apply` method, it will
+        * override the {@link CKEDITOR.style#apply} method.
+        *
+        * ### Usage
+        *
+        * Registering a basic handler:
+        *
+        *              var styleClass = CKEDITOR.style.addCustomHandler( {
+        *                      type: 'custom'
+        *              } );
+        *
+        *              var style = new styleClass( { ... } );
+        *              style instanceof styleClass; // -> true
+        *              style instanceof CKEDITOR.style; // -> true
+        *              style.type; // -> 'custom'
+        *
+        * The {@link CKEDITOR.style} constructor used as a factory:
+        *
+        *              var styleClass = CKEDITOR.style.addCustomHandler( {
+        *                      type: 'custom'
+        *              } );
+        *
+        *              // Style constructor accepts style definition (do not confuse with style class definition).
+        *              var style = new CKEDITOR.style( { type: 'custom', attributes: ... } );
+        *              style instanceof styleClass; // -> true
+        *
+        * Thanks to that, integration code using styles does not need to know
+        * which style handler it should use. It is determined by the {@link CKEDITOR.style} constructor.
+        *
+        * Overriding existing {@link CKEDITOR.style} methods:
+        *
+        *              var styleClass = CKEDITOR.style.addCustomHandler( {
+        *                      type: 'custom',
+        *                      apply: function( editor ) {
+        *                              console.log( 'apply' );
+        *                      },
+        *                      remove: function( editor ) {
+        *                              console.log( 'remove' );
+        *                      }
+        *              } );
+        *
+        *              var style = new CKEDITOR.style( { type: 'custom', attributes: ... } );
+        *              editor.applyStyle( style ); // logged 'apply'
+        *
+        *              style = new CKEDITOR.style( { element: 'img', attributes: { 'class': 'foo' } } );
+        *              editor.applyStyle( style ); // style is really applied if image was selected
+        *
+        * ### Practical Recommendations
+        *
+        * The style handling job, which includes such tasks as applying, removing, checking state, and
+        * checking if a style can be applied, is very complex. Therefore without deep knowledge
+        * about DOM and especially {@link CKEDITOR.dom.range ranges} and {@link CKEDITOR.dom.walker DOM walker} it is impossible
+        * to implement a completely custom style handler able to handle block, inline, and object type styles.
+        * However, it is possible to customize the default implementation by overriding default methods and
+        * reusing them.
+        *
+        * The only style handler which can be implemented from scratch without huge effort is a style
+        * applicable to objects ([read more about types](http://docs.ckeditor.com/#!/guide/dev_styles-section-style-types)).
+        * Such style can only be applied when a specific object is selected. An example implementation can
+        * be found in the [widget plugin](https://github.com/ckeditor/ckeditor-dev/blob/master/plugins/widget/plugin.js).
+        *
+        * When implementing a style handler from scratch at least the following methods must be defined:
+        *
+        * * {@link CKEDITOR.style#apply apply} and {@link CKEDITOR.style#remove remove},
+        * * {@link CKEDITOR.style#checkElementRemovable checkElementRemovable} and
+        * {@link CKEDITOR.style#checkElementMatch checkElementMatch} &ndash; Note that both methods reuse the same logic,
+        * * {@link CKEDITOR.style#checkActive checkActive} &ndash; Reuses
+        * {@link CKEDITOR.style#checkElementMatch checkElementMatch},
+        * * {@link CKEDITOR.style#toAllowedContentRules toAllowedContentRules} &ndash; Not required, but very useful in
+        * case of a custom style that has to notify the {@link CKEDITOR.filter} which rules it allows when registered.
+        *
+        * @since 4.4
+        * @static
+        * @member CKEDITOR.style
+        * @param definition The style class definition.
+        * @returns {CKEDITOR.style} The new style class created for the provided definition.
+        */
+       CKEDITOR.style.addCustomHandler = function( definition ) {
+               var styleClass = function( styleDefinition ) {
+                       this._ = {
+                               definition: styleDefinition
+                       };
+
+                       if ( this.setup )
+                               this.setup( styleDefinition );
+               };
+
+               styleClass.prototype = CKEDITOR.tools.extend(
+                       // Prototype of CKEDITOR.style.
+                       CKEDITOR.tools.prototypedCopy( CKEDITOR.style.prototype ),
+                       // Defaults.
+                       {
+                               assignedTo: CKEDITOR.STYLE_OBJECT
+                       },
+                       // Passed definition - overrides.
+                       definition,
+                       true
+               );
+
+               this.customHandlers[ definition.type ] = styleClass;
+
+               return styleClass;
+       };
+
+       // Gets the parent element which blocks the styling for an element. This
+       // can be done through read-only elements (contenteditable=false) or
+       // elements with the "data-nostyle" attribute.
+       function getUnstylableParent( element, root ) {
+               var unstylable, editable;
+
+               while ( ( element = element.getParent() ) ) {
+                       if ( element.equals( root ) )
+                               break;
+
+                       if ( element.getAttribute( 'data-nostyle' ) )
+                               unstylable = element;
+                       else if ( !editable ) {
+                               var contentEditable = element.getAttribute( 'contentEditable' );
+
+                               if ( contentEditable == 'false' )
+                                       unstylable = element;
+                               else if ( contentEditable == 'true' )
+                                       editable = 1;
+                       }
+               }
+
+               return unstylable;
+       }
+
+       var posPrecedingIdenticalContained =
+                       CKEDITOR.POSITION_PRECEDING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED,
+               posFollowingIdenticalContained =
+                       CKEDITOR.POSITION_FOLLOWING | CKEDITOR.POSITION_IDENTICAL | CKEDITOR.POSITION_IS_CONTAINED;
+
+       // Checks if the current node can be a child of the style element.
+       function checkIfNodeCanBeChildOfStyle( def, currentNode, lastNode, nodeName, dtd, nodeIsNoStyle, nodeIsReadonly, includeReadonly ) {
+               // Style can be applied to text node.
+               if ( !nodeName )
+                       return 1;
+
+               // Style definitely cannot be applied if DTD or data-nostyle do not allow.
+               if ( !dtd[ nodeName ] || nodeIsNoStyle  )
+                       return 0;
+
+               // Non-editable element cannot be styled is we shouldn't include readonly elements.
+               if ( nodeIsReadonly && !includeReadonly  )
+                       return 0;
+
+               // Check that we haven't passed lastNode yet and that style's childRule allows this style on current element.
+               return checkPositionAndRule( currentNode, lastNode, def, posPrecedingIdenticalContained );
+       }
+
+       // Check if the style element can be a child of the current
+       // node parent or if the element is not defined in the DTD.
+       function checkIfStyleCanBeChildOf( def, currentParent, elementName, isUnknownElement ) {
+               return currentParent &&
+                       ( ( currentParent.getDtd() || CKEDITOR.dtd.span )[ elementName ] || isUnknownElement ) &&
+                       ( !def.parentRule || def.parentRule( currentParent ) );
+       }
+
+       function checkIfStartsRange( nodeName, currentNode, lastNode ) {
+               return (
+                       !nodeName || !CKEDITOR.dtd.$removeEmpty[ nodeName ] ||
+                       ( currentNode.getPosition( lastNode ) | posPrecedingIdenticalContained ) == posPrecedingIdenticalContained
+               );
+       }
+
+       function checkIfTextOrReadonlyOrEmptyElement( currentNode, nodeIsReadonly ) {
+               var nodeType = currentNode.type;
+               return nodeType == CKEDITOR.NODE_TEXT || nodeIsReadonly || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() );
+       }
+
+       // Checks if position is a subset of posBitFlags and that nodeA fulfills style def rule.
+       function checkPositionAndRule( nodeA, nodeB, def, posBitFlags ) {
+               return ( nodeA.getPosition( nodeB ) | posBitFlags ) == posBitFlags &&
+                       ( !def.childRule || def.childRule( nodeA ) );
+       }
+
+       function applyInlineStyle( range ) {
+               var document = range.document;
+
+               if ( range.collapsed ) {
+                       // Create the element to be inserted in the DOM.
+                       var collapsedElement = getElement( this, document );
+
+                       // Insert the empty element into the DOM at the range position.
+                       range.insertNode( collapsedElement );
+
+                       // Place the selection right inside the empty element.
+                       range.moveToPosition( collapsedElement, CKEDITOR.POSITION_BEFORE_END );
+
+                       return;
+               }
+
+               var elementName = this.element,
+                       def = this._.definition,
+                       isUnknownElement;
+
+               // Indicates that fully selected read-only elements are to be included in the styling range.
+               var ignoreReadonly = def.ignoreReadonly,
+                       includeReadonly = ignoreReadonly || def.includeReadonly;
+
+               // If the read-only inclusion is not available in the definition, try
+               // to get it from the root data (most often it's the editable).
+               if ( includeReadonly == null )
+                       includeReadonly = range.root.getCustomData( 'cke_includeReadonly' );
+
+               // Get the DTD definition for the element. Defaults to "span".
+               var dtd = CKEDITOR.dtd[ elementName ];
+               if ( !dtd ) {
+                       isUnknownElement = true;
+                       dtd = CKEDITOR.dtd.span;
+               }
+
+               // Expand the range.
+               range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );
+               range.trim();
+
+               // Get the first node to be processed and the last, which concludes the processing.
+               var boundaryNodes = range.createBookmark(),
+                       firstNode = boundaryNodes.startNode,
+                       lastNode = boundaryNodes.endNode,
+                       currentNode = firstNode,
+                       styleRange;
+
+               if ( !ignoreReadonly ) {
+                       // Check if the boundaries are inside non stylable elements.
+                       var root = range.getCommonAncestor(),
+                               firstUnstylable = getUnstylableParent( firstNode, root ),
+                               lastUnstylable = getUnstylableParent( lastNode, root );
+
+                       // If the first element can't be styled, we'll start processing right
+                       // after its unstylable root.
+                       if ( firstUnstylable )
+                               currentNode = firstUnstylable.getNextSourceNode( true );
+
+                       // If the last element can't be styled, we'll stop processing on its
+                       // unstylable root.
+                       if ( lastUnstylable )
+                               lastNode = lastUnstylable;
+               }
+
+               // Do nothing if the current node now follows the last node to be processed.
+               if ( currentNode.getPosition( lastNode ) == CKEDITOR.POSITION_FOLLOWING )
+                       currentNode = 0;
+
+               while ( currentNode ) {
+                       var applyStyle = false;
+
+                       if ( currentNode.equals( lastNode ) ) {
+                               currentNode = null;
+                               applyStyle = true;
+                       } else {
+                               var nodeName = currentNode.type == CKEDITOR.NODE_ELEMENT ? currentNode.getName() : null,
+                                       nodeIsReadonly = nodeName && ( currentNode.getAttribute( 'contentEditable' ) == 'false' ),
+                                       nodeIsNoStyle = nodeName && currentNode.getAttribute( 'data-nostyle' );
+
+                               // Skip bookmarks.
+                               if ( nodeName && currentNode.data( 'cke-bookmark' ) ) {
+                                       currentNode = currentNode.getNextSourceNode( true );
+                                       continue;
+                               }
+
+                               // Find all nested editables of a non-editable block and apply this style inside them.
+                               if ( nodeIsReadonly && includeReadonly && CKEDITOR.dtd.$block[ nodeName ] )
+                                       applyStyleOnNestedEditables.call( this, currentNode );
+
+                               // Check if the current node can be a child of the style element.
+                               if ( checkIfNodeCanBeChildOfStyle( def, currentNode, lastNode, nodeName, dtd, nodeIsNoStyle, nodeIsReadonly, includeReadonly ) ) {
+                                       var currentParent = currentNode.getParent();
+
+                                       // Check if the style element can be a child of the current
+                                       // node parent or if the element is not defined in the DTD.
+                                       if ( checkIfStyleCanBeChildOf( def, currentParent, elementName, isUnknownElement ) ) {
+                                               // This node will be part of our range, so if it has not
+                                               // been started, place its start right before the node.
+                                               // In the case of an element node, it will be included
+                                               // only if it is entirely inside the range.
+                                               if ( !styleRange && checkIfStartsRange( nodeName, currentNode, lastNode ) ) {
+                                                       styleRange = range.clone();
+                                                       styleRange.setStartBefore( currentNode );
+                                               }
+
+                                               // Non element nodes, readonly elements, or empty
+                                               // elements can be added completely to the range.
+                                               if ( checkIfTextOrReadonlyOrEmptyElement( currentNode, nodeIsReadonly ) ) {
+                                                       var includedNode = currentNode;
+                                                       var parentNode;
+
+                                                       // This node is about to be included completelly, but,
+                                                       // if this is the last node in its parent, we must also
+                                                       // check if the parent itself can be added completelly
+                                                       // to the range, otherwise apply the style immediately.
+                                                       while (
+                                                               ( applyStyle = !includedNode.getNext( notBookmark ) ) &&
+                                                               ( parentNode = includedNode.getParent(), dtd[ parentNode.getName() ] ) &&
+                                                               checkPositionAndRule( parentNode, firstNode, def, posFollowingIdenticalContained )
+                                                       ) {
+                                                               includedNode = parentNode;
+                                                       }
+
+                                                       styleRange.setEndAfter( includedNode );
+
+                                               }
+                                       } else {
+                                               applyStyle = true;
+                                       }
+                               }
+                               // Style isn't applicable to current element, so apply style to
+                               // range ending at previously chosen position, or nowhere if we haven't
+                               // yet started styleRange.
+                               else {
+                                       applyStyle = true;
+                               }
+
+                               // Get the next node to be processed.
+                               // If we're currently on a non-editable element or non-styleable element,
+                               // then we'll be moved to current node's sibling (or even further), so we'll
+                               // avoid messing up its content.
+                               currentNode = currentNode.getNextSourceNode( nodeIsNoStyle || nodeIsReadonly );
+                       }
+
+                       // Apply the style if we have something to which apply it.
+                       if ( applyStyle && styleRange && !styleRange.collapsed ) {
+                               // Build the style element, based on the style object definition.
+                               var styleNode = getElement( this, document ),
+                                       styleHasAttrs = styleNode.hasAttributes();
+
+                               // Get the element that holds the entire range.
+                               var parent = styleRange.getCommonAncestor();
+
+                               var removeList = {
+                                       styles: {},
+                                       attrs: {},
+                                       // Styles cannot be removed.
+                                       blockedStyles: {},
+                                       // Attrs cannot be removed.
+                                       blockedAttrs: {}
+                               };
+
+                               var attName, styleName, value;
+
+                               // Loop through the parents, removing the redundant attributes
+                               // from the element to be applied.
+                               while ( styleNode && parent ) {
+                                       if ( parent.getName() == elementName ) {
+                                               for ( attName in def.attributes ) {
+                                                       if ( removeList.blockedAttrs[ attName ] || !( value = parent.getAttribute( styleName ) ) )
+                                                               continue;
+
+                                                       if ( styleNode.getAttribute( attName ) == value )
+                                                               removeList.attrs[ attName ] = 1;
+                                                       else
+                                                               removeList.blockedAttrs[ attName ] = 1;
+                                               }
+
+                                               for ( styleName in def.styles ) {
+                                                       if ( removeList.blockedStyles[ styleName ] || !( value = parent.getStyle( styleName ) ) )
+                                                               continue;
+
+                                                       if ( styleNode.getStyle( styleName ) == value )
+                                                               removeList.styles[ styleName ] = 1;
+                                                       else
+                                                               removeList.blockedStyles[ styleName ] = 1;
+                                               }
+                                       }
+
+                                       parent = parent.getParent();
+                               }
+
+                               for ( attName in removeList.attrs )
+                                       styleNode.removeAttribute( attName );
+
+                               for ( styleName in removeList.styles )
+                                       styleNode.removeStyle( styleName );
+
+                               if ( styleHasAttrs && !styleNode.hasAttributes() )
+                                       styleNode = null;
+
+                               if ( styleNode ) {
+                                       // Move the contents of the range to the style element.
+                                       styleRange.extractContents().appendTo( styleNode );
+
+                                       // Insert it into the range position (it is collapsed after
+                                       // extractContents.
+                                       styleRange.insertNode( styleNode );
+
+                                       // Here we do some cleanup, removing all duplicated
+                                       // elements from the style element.
+                                       removeFromInsideElement.call( this, styleNode );
+
+                                       // Let's merge our new style with its neighbors, if possible.
+                                       styleNode.mergeSiblings();
+
+                                       // As the style system breaks text nodes constantly, let's normalize
+                                       // things for performance.
+                                       // With IE, some paragraphs get broken when calling normalize()
+                                       // repeatedly. Also, for IE, we must normalize body, not documentElement.
+                                       // IE is also known for having a "crash effect" with normalize().
+                                       // We should try to normalize with IE too in some way, somewhere.
+                                       if ( !CKEDITOR.env.ie )
+                                               styleNode.$.normalize();
+                               }
+                               // Style already inherit from parents, left just to clear up any internal overrides. (#5931)
+                               else {
+                                       styleNode = new CKEDITOR.dom.element( 'span' );
+                                       styleRange.extractContents().appendTo( styleNode );
+                                       styleRange.insertNode( styleNode );
+                                       removeFromInsideElement.call( this, styleNode );
+                                       styleNode.remove( true );
+                               }
+
+                               // Style applied, let's release the range, so it gets
+                               // re-initialization in the next loop.
+                               styleRange = null;
+                       }
+               }
+
+               // Remove the bookmark nodes.
+               range.moveToBookmark( boundaryNodes );
+
+               // Minimize the result range to exclude empty text nodes. (#5374)
+               range.shrink( CKEDITOR.SHRINK_TEXT );
+
+               // Get inside the remaining element if range.shrink( TEXT ) has failed because of non-editable elements inside.
+               // E.g. range.shrink( TEXT ) will not get inside:
+               // [<b><i contenteditable="false">x</i></b>]
+               // but range.shrink( ELEMENT ) will.
+               range.shrink( CKEDITOR.NODE_ELEMENT, true );
+       }
+
+       function removeInlineStyle( range ) {
+               // Make sure our range has included all "collpased" parent inline nodes so
+               // that our operation logic can be simpler.
+               range.enlarge( CKEDITOR.ENLARGE_INLINE, 1 );
+
+               var bookmark = range.createBookmark(),
+                       startNode = bookmark.startNode;
+
+               if ( range.collapsed ) {
+                       var startPath = new CKEDITOR.dom.elementPath( startNode.getParent(), range.root ),
+                               // The topmost element in elementspatch which we should jump out of.
+                               boundaryElement;
+
+
+                       for ( var i = 0, element; i < startPath.elements.length && ( element = startPath.elements[ i ] ); i++ ) {
+                               // 1. If it's collaped inside text nodes, try to remove the style from the whole element.
+                               //
+                               // 2. Otherwise if it's collapsed on element boundaries, moving the selection
+                               //  outside the styles instead of removing the whole tag,
+                               //  also make sure other inner styles were well preserverd.(#3309)
+                               if ( element == startPath.block || element == startPath.blockLimit )
+                                       break;
+
+                               if ( this.checkElementRemovable( element ) ) {
+                                       var isStart;
+
+                                       if ( range.collapsed && ( range.checkBoundaryOfElement( element, CKEDITOR.END ) || ( isStart = range.checkBoundaryOfElement( element, CKEDITOR.START ) ) ) ) {
+                                               boundaryElement = element;
+                                               boundaryElement.match = isStart ? 'start' : 'end';
+                                       } else {
+                                               // Before removing the style node, there may be a sibling to the style node
+                                               // that's exactly the same to the one to be removed. To the user, it makes
+                                               // no difference that they're separate entities in the DOM tree. So, merge
+                                               // them before removal.
+                                               element.mergeSiblings();
+                                               if ( element.is( this.element ) )
+                                                       removeFromElement.call( this, element );
+                                               else
+                                                       removeOverrides( element, getOverrides( this )[ element.getName() ] );
+                                       }
+                               }
+                       }
+
+                       // Re-create the style tree after/before the boundary element,
+                       // the replication start from bookmark start node to define the
+                       // new range.
+                       if ( boundaryElement ) {
+                               var clonedElement = startNode;
+                               for ( i = 0; ; i++ ) {
+                                       var newElement = startPath.elements[ i ];
+                                       if ( newElement.equals( boundaryElement ) )
+                                               break;
+                                       // Avoid copying any matched element.
+                                       else if ( newElement.match )
+                                               continue;
+                                       else
+                                               newElement = newElement.clone();
+                                       newElement.append( clonedElement );
+                                       clonedElement = newElement;
+                               }
+                               clonedElement[ boundaryElement.match == 'start' ? 'insertBefore' : 'insertAfter' ]( boundaryElement );
+                       }
+               } else {
+                       // Now our range isn't collapsed. Lets walk from the start node to the end
+                       // node via DFS and remove the styles one-by-one.
+                       var endNode = bookmark.endNode,
+                               me = this;
+
+                       breakNodes();
+
+                       // Now, do the DFS walk.
+                       var currentNode = startNode;
+                       while ( !currentNode.equals( endNode ) ) {
+                               // Need to get the next node first because removeFromElement() can remove
+                               // the current node from DOM tree.
+                               var nextNode = currentNode.getNextSourceNode();
+                               if ( currentNode.type == CKEDITOR.NODE_ELEMENT && this.checkElementRemovable( currentNode ) ) {
+                                       // Remove style from element or overriding element.
+                                       if ( currentNode.getName() == this.element )
+                                               removeFromElement.call( this, currentNode );
+                                       else
+                                               removeOverrides( currentNode, getOverrides( this )[ currentNode.getName() ] );
+
+                                       // removeFromElement() may have merged the next node with something before
+                                       // the startNode via mergeSiblings(). In that case, the nextNode would
+                                       // contain startNode and we'll have to call breakNodes() again and also
+                                       // reassign the nextNode to something after startNode.
+                                       if ( nextNode.type == CKEDITOR.NODE_ELEMENT && nextNode.contains( startNode ) ) {
+                                               breakNodes();
+                                               nextNode = startNode.getNext();
+                                       }
+                               }
+                               currentNode = nextNode;
+                       }
+               }
+
+               range.moveToBookmark( bookmark );
+               // See the comment for range.shrink in applyInlineStyle.
+               range.shrink( CKEDITOR.NODE_ELEMENT, true );
+
+               // Find out the style ancestor that needs to be broken down at startNode
+               // and endNode.
+               function breakNodes() {
+                       var startPath = new CKEDITOR.dom.elementPath( startNode.getParent() ),
+                               endPath = new CKEDITOR.dom.elementPath( endNode.getParent() ),
+                               breakStart = null,
+                               breakEnd = null;
+
+                       for ( var i = 0; i < startPath.elements.length; i++ ) {
+                               var element = startPath.elements[ i ];
+
+                               if ( element == startPath.block || element == startPath.blockLimit )
+                                       break;
+
+                               if ( me.checkElementRemovable( element, true ) )
+                                       breakStart = element;
+                       }
+
+                       for ( i = 0; i < endPath.elements.length; i++ ) {
+                               element = endPath.elements[ i ];
+
+                               if ( element == endPath.block || element == endPath.blockLimit )
+                                       break;
+
+                               if ( me.checkElementRemovable( element, true ) )
+                                       breakEnd = element;
+                       }
+
+                       if ( breakEnd )
+                               endNode.breakParent( breakEnd );
+                       if ( breakStart )
+                               startNode.breakParent( breakStart );
+               }
+       }
+
+       // Apply style to nested editables inside editablesContainer.
+       // @param {CKEDITOR.dom.element} editablesContainer
+       // @context CKEDITOR.style
+       function applyStyleOnNestedEditables( editablesContainer ) {
+               var editables = findNestedEditables( editablesContainer ),
+                       editable,
+                       l = editables.length,
+                       i = 0,
+                       range = l && new CKEDITOR.dom.range( editablesContainer.getDocument() );
+
+               for ( ; i < l; ++i ) {
+                       editable = editables[ i ];
+                       // Check if style is allowed by this editable's ACF.
+                       if ( checkIfAllowedInEditable( editable, this ) ) {
+                               range.selectNodeContents( editable );
+                               applyInlineStyle.call( this, range );
+                       }
+               }
+       }
+
+       // Finds nested editables within container. Does not return
+       // editables nested in another editable (twice).
+       function findNestedEditables( container ) {
+               var editables = [];
+
+               container.forEach( function( element ) {
+                       if ( element.getAttribute( 'contenteditable' ) == 'true' ) {
+                               editables.push( element );
+                               return false; // Skip children.
+                       }
+               }, CKEDITOR.NODE_ELEMENT, true );
+
+               return editables;
+       }
+
+       // Checks if style is allowed in this editable.
+       function checkIfAllowedInEditable( editable, style ) {
+               var filter = CKEDITOR.filter.instances[ editable.data( 'cke-filter' ) ];
+
+               return filter ? filter.check( style ) : 1;
+       }
+
+       // Checks if style is allowed by iterator's active filter.
+       function checkIfAllowedByIterator( iterator, style ) {
+               return iterator.activeFilter ? iterator.activeFilter.check( style ) : 1;
+       }
+
+       function applyObjectStyle( range ) {
+               // Selected or parent element. (#9651)
+               var start = range.getEnclosedNode() || range.getCommonAncestor( false, true ),
+                       element = new CKEDITOR.dom.elementPath( start, range.root ).contains( this.element, 1 );
+
+               element && !element.isReadOnly() && setupElement( element, this );
+       }
+
+       function removeObjectStyle( range ) {
+               var parent = range.getCommonAncestor( true, true ),
+                       element = new CKEDITOR.dom.elementPath( parent, range.root ).contains( this.element, 1 );
+
+               if ( !element )
+                       return;
+
+               var style = this,
+                       def = style._.definition,
+                       attributes = def.attributes;
+
+               // Remove all defined attributes.
+               if ( attributes ) {
+                       for ( var att in attributes )
+                               element.removeAttribute( att, attributes[ att ] );
+               }
+
+               // Assign all defined styles.
+               if ( def.styles ) {
+                       for ( var i in def.styles ) {
+                               if ( def.styles.hasOwnProperty( i ) )
+                                       element.removeStyle( i );
+                       }
+               }
+       }
+
+       function applyBlockStyle( range ) {
+               // Serializible bookmarks is needed here since
+               // elements may be merged.
+               var bookmark = range.createBookmark( true );
+
+               var iterator = range.createIterator();
+               iterator.enforceRealBlocks = true;
+
+               // make recognize <br /> tag as a separator in ENTER_BR mode (#5121)
+               if ( this._.enterMode )
+                       iterator.enlargeBr = ( this._.enterMode != CKEDITOR.ENTER_BR );
+
+               var block,
+                       doc = range.document,
+                       newBlock;
+
+               while ( ( block = iterator.getNextParagraph() ) ) {
+                       if ( !block.isReadOnly() && checkIfAllowedByIterator( iterator, this ) ) {
+                               newBlock = getElement( this, doc, block );
+                               replaceBlock( block, newBlock );
+                       }
+               }
+
+               range.moveToBookmark( bookmark );
+       }
+
+       function removeBlockStyle( range ) {
+               // Serializible bookmarks is needed here since
+               // elements may be merged.
+               var bookmark = range.createBookmark( 1 );
+
+               var iterator = range.createIterator();
+               iterator.enforceRealBlocks = true;
+               iterator.enlargeBr = this._.enterMode != CKEDITOR.ENTER_BR;
+
+               var block,
+                       newBlock;
+
+               while ( ( block = iterator.getNextParagraph() ) ) {
+                       if ( this.checkElementRemovable( block ) ) {
+                               // <pre> get special treatment.
+                               if ( block.is( 'pre' ) ) {
+                                       newBlock = this._.enterMode == CKEDITOR.ENTER_BR ? null :
+                                                       range.document.createElement( this._.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
+
+                                       newBlock && block.copyAttributes( newBlock );
+                                       replaceBlock( block, newBlock );
+                               } else {
+                                       removeFromElement.call( this, block );
+                               }
+                       }
+               }
+
+               range.moveToBookmark( bookmark );
+       }
+
+       // Replace the original block with new one, with special treatment
+       // for <pre> blocks to make sure content format is well preserved, and merging/splitting adjacent
+       // when necessary. (#3188)
+       function replaceBlock( block, newBlock ) {
+               // Block is to be removed, create a temp element to
+               // save contents.
+               var removeBlock = !newBlock;
+               if ( removeBlock ) {
+                       newBlock = block.getDocument().createElement( 'div' );
+                       block.copyAttributes( newBlock );
+               }
+
+               var newBlockIsPre = newBlock && newBlock.is( 'pre' ),
+                       blockIsPre = block.is( 'pre' ),
+                       isToPre = newBlockIsPre && !blockIsPre,
+                       isFromPre = !newBlockIsPre && blockIsPre;
+
+               if ( isToPre )
+                       newBlock = toPre( block, newBlock );
+               else if ( isFromPre )
+                       // Split big <pre> into pieces before start to convert.
+                       newBlock = fromPres( removeBlock ? [ block.getHtml() ] : splitIntoPres( block ), newBlock );
+               else
+                       block.moveChildren( newBlock );
+
+               newBlock.replace( block );
+
+               if ( newBlockIsPre ) {
+                       // Merge previous <pre> blocks.
+                       mergePre( newBlock );
+               } else if ( removeBlock ) {
+                       removeNoAttribsElement( newBlock );
+               }
+       }
+
+       // Merge a <pre> block with a previous sibling if available.
+       function mergePre( preBlock ) {
+               var previousBlock;
+               if ( !( ( previousBlock = preBlock.getPrevious( nonWhitespaces ) ) && previousBlock.type == CKEDITOR.NODE_ELEMENT && previousBlock.is( 'pre' ) ) )
+                       return;
+
+               // Merge the previous <pre> block contents into the current <pre>
+               // block.
+               //
+               // Another thing to be careful here is that currentBlock might contain
+               // a '\n' at the beginning, and previousBlock might contain a '\n'
+               // towards the end. These new lines are not normally displayed but they
+               // become visible after merging.
+               var mergedHtml = replace( previousBlock.getHtml(), /\n$/, '' ) + '\n\n' +
+                       replace( preBlock.getHtml(), /^\n/, '' );
+
+               // Krugle: IE normalizes innerHTML from <pre>, breaking whitespaces.
+               if ( CKEDITOR.env.ie )
+                       preBlock.$.outerHTML = '<pre>' + mergedHtml + '</pre>';
+               else
+                       preBlock.setHtml( mergedHtml );
+
+               previousBlock.remove();
+       }
+
+       // Split into multiple <pre> blocks separated by double line-break.
+       function splitIntoPres( preBlock ) {
+               // Exclude the ones at header OR at tail,
+               // and ignore bookmark content between them.
+               var duoBrRegex = /(\S\s*)\n(?:\s|(<span[^>]+data-cke-bookmark.*?\/span>))*\n(?!$)/gi,
+                       pres = [],
+                       splitedHtml = replace( preBlock.getOuterHtml(), duoBrRegex, function( match, charBefore, bookmark ) {
+                               return charBefore + '</pre>' + bookmark + '<pre>';
+                       } );
+
+               splitedHtml.replace( /<pre\b.*?>([\s\S]*?)<\/pre>/gi, function( match, preContent ) {
+                       pres.push( preContent );
+               } );
+               return pres;
+       }
+
+       // Wrapper function of String::replace without considering of head/tail bookmarks nodes.
+       function replace( str, regexp, replacement ) {
+               var headBookmark = '',
+                       tailBookmark = '';
+
+               str = str.replace( /(^<span[^>]+data-cke-bookmark.*?\/span>)|(<span[^>]+data-cke-bookmark.*?\/span>$)/gi, function( str, m1, m2 ) {
+                       m1 && ( headBookmark = m1 );
+                       m2 && ( tailBookmark = m2 );
+                       return '';
+               } );
+               return headBookmark + str.replace( regexp, replacement ) + tailBookmark;
+       }
+
+       // Converting a list of <pre> into blocks with format well preserved.
+       function fromPres( preHtmls, newBlock ) {
+               var docFrag;
+               if ( preHtmls.length > 1 )
+                       docFrag = new CKEDITOR.dom.documentFragment( newBlock.getDocument() );
+
+               for ( var i = 0; i < preHtmls.length; i++ ) {
+                       var blockHtml = preHtmls[ i ];
+
+                       // 1. Trim the first and last line-breaks immediately after and before <pre>,
+                       // they're not visible.
+                       blockHtml = blockHtml.replace( /(\r\n|\r)/g, '\n' );
+                       blockHtml = replace( blockHtml, /^[ \t]*\n/, '' );
+                       blockHtml = replace( blockHtml, /\n$/, '' );
+                       // 2. Convert spaces or tabs at the beginning or at the end to &nbsp;
+                       blockHtml = replace( blockHtml, /^[ \t]+|[ \t]+$/g, function( match, offset ) {
+                               if ( match.length == 1 ) // one space, preserve it
+                                       return '&nbsp;';
+                               else if ( !offset ) // beginning of block
+                                       return CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 ) + ' ';
+                               else // end of block
+                                       return ' ' + CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 );
+                       } );
+
+                       // 3. Convert \n to <BR>.
+                       // 4. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp;
+                       blockHtml = blockHtml.replace( /\n/g, '<br>' );
+                       blockHtml = blockHtml.replace( /[ \t]{2,}/g, function( match ) {
+                               return CKEDITOR.tools.repeat( '&nbsp;', match.length - 1 ) + ' ';
+                       } );
+
+                       if ( docFrag ) {
+                               var newBlockClone = newBlock.clone();
+                               newBlockClone.setHtml( blockHtml );
+                               docFrag.append( newBlockClone );
+                       } else {
+                               newBlock.setHtml( blockHtml );
+                       }
+               }
+
+               return docFrag || newBlock;
+       }
+
+       // Converting from a non-PRE block to a PRE block in formatting operations.
+       function toPre( block, newBlock ) {
+               var bogus = block.getBogus();
+               bogus && bogus.remove();
+
+               // First trim the block content.
+               var preHtml = block.getHtml();
+
+               // 1. Trim head/tail spaces, they're not visible.
+               preHtml = replace( preHtml, /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g, '' );
+               // 2. Delete ANSI whitespaces immediately before and after <BR> because
+               //    they are not visible.
+               preHtml = preHtml.replace( /[ \t\r\n]*(<br[^>]*>)[ \t\r\n]*/gi, '$1' );
+               // 3. Compress other ANSI whitespaces since they're only visible as one
+               //    single space previously.
+               // 4. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>.
+               preHtml = preHtml.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' );
+               // 5. Convert any <BR /> to \n. This must not be done earlier because
+               //    the \n would then get compressed.
+               preHtml = preHtml.replace( /<br\b[^>]*>/gi, '\n' );
+
+               // Krugle: IE normalizes innerHTML to <pre>, breaking whitespaces.
+               if ( CKEDITOR.env.ie ) {
+                       var temp = block.getDocument().createElement( 'div' );
+                       temp.append( newBlock );
+                       newBlock.$.outerHTML = '<pre>' + preHtml + '</pre>';
+                       newBlock.copyAttributes( temp.getFirst() );
+                       newBlock = temp.getFirst().remove();
+               } else {
+                       newBlock.setHtml( preHtml );
+               }
+
+               return newBlock;
+       }
+
+       // Removes a style from an element itself, don't care about its subtree.
+       function removeFromElement( element, keepDataAttrs ) {
+               var def = this._.definition,
+                       attributes = def.attributes,
+                       styles = def.styles,
+                       overrides = getOverrides( this )[ element.getName() ],
+                       // If the style is only about the element itself, we have to remove the element.
+                       removeEmpty = CKEDITOR.tools.isEmpty( attributes ) && CKEDITOR.tools.isEmpty( styles );
+
+               // Remove definition attributes/style from the elemnt.
+               for ( var attName in attributes ) {
+                       // The 'class' element value must match (#1318).
+                       if ( ( attName == 'class' || this._.definition.fullMatch ) && element.getAttribute( attName ) != normalizeProperty( attName, attributes[ attName ] ) )
+                               continue;
+
+                       // Do not touch data-* attributes (#11011) (#11258).
+                       if ( keepDataAttrs && attName.slice( 0, 5 ) == 'data-' )
+                               continue;
+
+                       removeEmpty = element.hasAttribute( attName );
+                       element.removeAttribute( attName );
+               }
+
+               for ( var styleName in styles ) {
+                       // Full match style insist on having fully equivalence. (#5018)
+                       if ( this._.definition.fullMatch && element.getStyle( styleName ) != normalizeProperty( styleName, styles[ styleName ], true ) )
+                               continue;
+
+                       removeEmpty = removeEmpty || !!element.getStyle( styleName );
+                       element.removeStyle( styleName );
+               }
+
+               // Remove overrides, but don't remove the element if it's a block element
+               removeOverrides( element, overrides, blockElements[ element.getName() ] );
+
+               if ( removeEmpty ) {
+                       if ( this._.definition.alwaysRemoveElement )
+                               removeNoAttribsElement( element, 1 );
+                       else {
+                               if ( !CKEDITOR.dtd.$block[ element.getName() ] || this._.enterMode == CKEDITOR.ENTER_BR && !element.hasAttributes() )
+                                       removeNoAttribsElement( element );
+                               else
+                                       element.renameNode( this._.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );
+                       }
+               }
+       }
+
+       // Removes a style from inside an element. Called on applyStyle to make cleanup
+       // before apply. During clean up this function keep data-* attribute in contrast
+       // to removeFromElement.
+       function removeFromInsideElement( element ) {
+               var overrides = getOverrides( this ),
+                       innerElements = element.getElementsByTag( this.element ),
+                       innerElement;
+
+               for ( var i = innerElements.count(); --i >= 0; ) {
+                       innerElement = innerElements.getItem( i );
+
+                       // Do not remove elements which are read only (e.g. duplicates inside widgets).
+                       if ( !innerElement.isReadOnly() )
+                               removeFromElement.call( this, innerElement, true );
+               }
+
+               // Now remove any other element with different name that is
+               // defined to be overriden.
+               for ( var overrideElement in overrides ) {
+                       if ( overrideElement != this.element ) {
+                               innerElements = element.getElementsByTag( overrideElement );
+
+                               for ( i = innerElements.count() - 1; i >= 0; i-- ) {
+                                       innerElement = innerElements.getItem( i );
+
+                                       // Do not remove elements which are read only (e.g. duplicates inside widgets).
+                                       if ( !innerElement.isReadOnly() )
+                                               removeOverrides( innerElement, overrides[ overrideElement ] );
+                               }
+                       }
+               }
+       }
+
+       // Remove overriding styles/attributes from the specific element.
+       // Note: Remove the element if no attributes remain.
+       // @param {Object} element
+       // @param {Object} overrides
+       // @param {Boolean} Don't remove the element
+       function removeOverrides( element, overrides, dontRemove ) {
+               var attributes = overrides && overrides.attributes;
+
+               if ( attributes ) {
+                       for ( var i = 0; i < attributes.length; i++ ) {
+                               var attName = attributes[ i ][ 0 ],
+                                       actualAttrValue;
+
+                               if ( ( actualAttrValue = element.getAttribute( attName ) ) ) {
+                                       var attValue = attributes[ i ][ 1 ];
+
+                                       // Remove the attribute if:
+                                       //    - The override definition value is null ;
+                                       //    - The override definition valie is a string that
+                                       //      matches the attribute value exactly.
+                                       //    - The override definition value is a regex that
+                                       //      has matches in the attribute value.
+                                       if ( attValue === null || ( attValue.test && attValue.test( actualAttrValue ) ) || ( typeof attValue == 'string' && actualAttrValue == attValue ) )
+                                               element.removeAttribute( attName );
+                               }
+                       }
+               }
+
+               if ( !dontRemove )
+                       removeNoAttribsElement( element );
+       }
+
+       // If the element has no more attributes, remove it.
+       function removeNoAttribsElement( element, forceRemove ) {
+               // If no more attributes remained in the element, remove it,
+               // leaving its children.
+               if ( !element.hasAttributes() || forceRemove ) {
+                       if ( CKEDITOR.dtd.$block[ element.getName() ] ) {
+                               var previous = element.getPrevious( nonWhitespaces ),
+                                       next = element.getNext( nonWhitespaces );
+
+                               if ( previous && ( previous.type == CKEDITOR.NODE_TEXT || !previous.isBlockBoundary( { br: 1 } ) ) )
+                                       element.append( 'br', 1 );
+                               if ( next && ( next.type == CKEDITOR.NODE_TEXT || !next.isBlockBoundary( { br: 1 } ) ) )
+                                       element.append( 'br' );
+
+                               element.remove( true );
+                       } else {
+                               // Removing elements may open points where merging is possible,
+                               // so let's cache the first and last nodes for later checking.
+                               var firstChild = element.getFirst();
+                               var lastChild = element.getLast();
+
+                               element.remove( true );
+
+                               if ( firstChild ) {
+                                       // Check the cached nodes for merging.
+                                       firstChild.type == CKEDITOR.NODE_ELEMENT && firstChild.mergeSiblings();
+
+                                       if ( lastChild && !firstChild.equals( lastChild ) && lastChild.type == CKEDITOR.NODE_ELEMENT )
+                                               lastChild.mergeSiblings();
+                               }
+
+                       }
+               }
+       }
+
+       function getElement( style, targetDocument, element ) {
+               var el,
+                       elementName = style.element;
+
+               // The "*" element name will always be a span for this function.
+               if ( elementName == '*' )
+                       elementName = 'span';
+
+               // Create the element.
+               el = new CKEDITOR.dom.element( elementName, targetDocument );
+
+               // #6226: attributes should be copied before the new ones are applied
+               if ( element )
+                       element.copyAttributes( el );
+
+               el = setupElement( el, style );
+
+               // Avoid ID duplication.
+               if ( targetDocument.getCustomData( 'doc_processing_style' ) && el.hasAttribute( 'id' ) )
+                       el.removeAttribute( 'id' );
+               else
+                       targetDocument.setCustomData( 'doc_processing_style', 1 );
+
+               return el;
+       }
+
+       function setupElement( el, style ) {
+               var def = style._.definition,
+                       attributes = def.attributes,
+                       styles = CKEDITOR.style.getStyleText( def );
+
+               // Assign all defined attributes.
+               if ( attributes ) {
+                       for ( var att in attributes )
+                               el.setAttribute( att, attributes[ att ] );
+               }
+
+               // Assign all defined styles.
+               if ( styles )
+                       el.setAttribute( 'style', styles );
+
+               return el;
+       }
+
+       function replaceVariables( list, variablesValues ) {
+               for ( var item in list ) {
+                       list[ item ] = list[ item ].replace( varRegex, function( match, varName ) {
+                               return variablesValues[ varName ];
+                       } );
+               }
+       }
+
+       // Returns an object that can be used for style matching comparison.
+       // Attributes names and values are all lowercased, and the styles get
+       // merged with the style attribute.
+       function getAttributesForComparison( styleDefinition ) {
+               // If we have already computed it, just return it.
+               var attribs = styleDefinition._AC;
+               if ( attribs )
+                       return attribs;
+
+               attribs = {};
+
+               var length = 0;
+
+               // Loop through all defined attributes.
+               var styleAttribs = styleDefinition.attributes;
+               if ( styleAttribs ) {
+                       for ( var styleAtt in styleAttribs ) {
+                               length++;
+                               attribs[ styleAtt ] = styleAttribs[ styleAtt ];
+                       }
+               }
+
+               // Includes the style definitions.
+               var styleText = CKEDITOR.style.getStyleText( styleDefinition );
+               if ( styleText ) {
+                       if ( !attribs.style )
+                               length++;
+                       attribs.style = styleText;
+               }
+
+               // Appends the "length" information to the object.
+               attribs._length = length;
+
+               // Return it, saving it to the next request.
+               return ( styleDefinition._AC = attribs );
+       }
+
+       // Get the the collection used to compare the elements and attributes,
+       // defined in this style overrides, with other element. All information in
+       // it is lowercased.
+       // @param {CKEDITOR.style} style
+       function getOverrides( style ) {
+               if ( style._.overrides )
+                       return style._.overrides;
+
+               var overrides = ( style._.overrides = {} ),
+                       definition = style._.definition.overrides;
+
+               if ( definition ) {
+                       // The override description can be a string, object or array.
+                       // Internally, well handle arrays only, so transform it if needed.
+                       if ( !CKEDITOR.tools.isArray( definition ) )
+                               definition = [ definition ];
+
+                       // Loop through all override definitions.
+                       for ( var i = 0; i < definition.length; i++ ) {
+                               var override = definition[ i ],
+                                       elementName,
+                                       overrideEl,
+                                       attrs;
+
+                               // If can be a string with the element name.
+                               if ( typeof override == 'string' )
+                                       elementName = override.toLowerCase();
+                               // Or an object.
+                               else {
+                                       elementName = override.element ? override.element.toLowerCase() : style.element;
+                                       attrs = override.attributes;
+                               }
+
+                               // We can have more than one override definition for the same
+                               // element name, so we attempt to simply append information to
+                               // it if it already exists.
+                               overrideEl = overrides[ elementName ] || ( overrides[ elementName ] = {} );
+
+                               if ( attrs ) {
+                                       // The returning attributes list is an array, because we
+                                       // could have different override definitions for the same
+                                       // attribute name.
+                                       var overrideAttrs = ( overrideEl.attributes = overrideEl.attributes || [] );
+                                       for ( var attName in attrs ) {
+                                               // Each item in the attributes array is also an array,
+                                               // where [0] is the attribute name and [1] is the
+                                               // override value.
+                                               overrideAttrs.push( [ attName.toLowerCase(), attrs[ attName ] ] );
+                                       }
+                               }
+                       }
+               }
+
+               return overrides;
+       }
+
+       // Make the comparison of attribute value easier by standardizing it.
+       function normalizeProperty( name, value, isStyle ) {
+               var temp = new CKEDITOR.dom.element( 'span' );
+               temp[ isStyle ? 'setStyle' : 'setAttribute' ]( name, value );
+               return temp[ isStyle ? 'getStyle' : 'getAttribute' ]( name );
+       }
+
+       // Compare two bunch of styles, with the speciality that value 'inherit'
+       // is treated as a wildcard which will match any value.
+       // @param {Object/String} source
+       // @param {Object/String} target
+       // @returns {Boolean}
+       function compareCssText( source, target ) {
+               function filter( string, propertyName ) {
+                       // In case of font-families we'll skip quotes. (#10750)
+                       return propertyName.toLowerCase() == 'font-family' ? string.replace( /["']/g, '' ) : string;
+               }
+
+               if ( typeof source == 'string' )
+                       source = CKEDITOR.tools.parseCssText( source );
+               if ( typeof target == 'string' )
+                       target = CKEDITOR.tools.parseCssText( target, true );
+
+               for ( var name in source ) {
+                       if ( !( name in target ) ) {
+                               return false;
+                       }
+
+                       if ( !( filter( target[ name ], name ) == filter( source[ name ], name ) ||
+                               source[ name ] == 'inherit' ||
+                               target[ name ] == 'inherit' ) ) {
+                               return false;
+                       }
+               }
+               return true;
+       }
+
+       function applyStyleOnSelection( selection, remove, editor ) {
+               var doc = selection.document,
+                       ranges = selection.getRanges(),
+                       func = remove ? this.removeFromRange : this.applyToRange,
+                       range;
+
+               var iterator = ranges.createIterator();
+               while ( ( range = iterator.getNextRange() ) )
+                       func.call( this, range, editor );
+
+               selection.selectRanges( ranges );
+               doc.removeCustomData( 'doc_processing_style' );
+       }
+} )();
+
+/**
+ * Generic style command. It applies a specific style when executed.
+ *
+ *             var boldStyle = new CKEDITOR.style( { element: 'strong' } );
+ *             // Register the "bold" command, which applies the bold style.
+ *             editor.addCommand( 'bold', new CKEDITOR.styleCommand( boldStyle ) );
+ *
+ * @class
+ * @constructor Creates a styleCommand class instance.
+ * @extends CKEDITOR.commandDefinition
+ * @param {CKEDITOR.style} style The style to be applied when command is executed.
+ * @param {Object} [ext] Additional command definition's properties.
+ */
+CKEDITOR.styleCommand = function( style, ext ) {
+       this.style = style;
+       this.allowedContent = style;
+       this.requiredContent = style;
+
+       CKEDITOR.tools.extend( this, ext, true );
+};
+
+/**
+ * @param {CKEDITOR.editor} editor
+ * @todo
+ */
+CKEDITOR.styleCommand.prototype.exec = function( editor ) {
+       editor.focus();
+
+       if ( this.state == CKEDITOR.TRISTATE_OFF )
+               editor.applyStyle( this.style );
+       else if ( this.state == CKEDITOR.TRISTATE_ON )
+               editor.removeStyle( this.style );
+};
+
+/**
+ * Manages styles registration and loading. See also {@link CKEDITOR.config#stylesSet}.
+ *
+ *             // The set of styles for the <b>Styles</b> drop-down list.
+ *             CKEDITOR.stylesSet.add( 'default', [
+ *                     // Block Styles
+ *                     { name: 'Blue Title',           element: 'h3',          styles: { 'color': 'Blue' } },
+ *                     { name: 'Red Title',            element: 'h3',          styles: { 'color': 'Red' } },
+ *
+ *                     // Inline Styles
+ *                     { name: 'Marker: Yellow',       element: 'span',        styles: { 'background-color': 'Yellow' } },
+ *                     { name: 'Marker: Green',        element: 'span',        styles: { 'background-color': 'Lime' } },
+ *
+ *                     // Object Styles
+ *                     {
+ *                             name: 'Image on Left',
+ *                             element: 'img',
+ *                             attributes: {
+ *                                     style: 'padding: 5px; margin-right: 5px',
+ *                                     border: '2',
+ *                                     align: 'left'
+ *                             }
+ *                     }
+ *             ] );
+ *
+ * @since 3.2
+ * @class
+ * @singleton
+ * @extends CKEDITOR.resourceManager
+ */
+CKEDITOR.stylesSet = new CKEDITOR.resourceManager( '', 'stylesSet' );
+
+// Backward compatibility (#5025).
+CKEDITOR.addStylesSet = CKEDITOR.tools.bind( CKEDITOR.stylesSet.add, CKEDITOR.stylesSet );
+CKEDITOR.loadStylesSet = function( name, url, callback ) {
+       CKEDITOR.stylesSet.addExternal( name, url, '' );
+       CKEDITOR.stylesSet.load( name, callback );
+};
+
+CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {
+       /**
+        * Registers a function to be called whenever the selection position changes in the
+        * editing area. The current state is passed to the function. The possible
+        * states are {@link CKEDITOR#TRISTATE_ON} and {@link CKEDITOR#TRISTATE_OFF}.
+        *
+        *              // Create a style object for the <b> element.
+        *              var style = new CKEDITOR.style( { element: 'b' } );
+        *              var editor = CKEDITOR.instances.editor1;
+        *              editor.attachStyleStateChange( style, function( state ) {
+        *                      if ( state == CKEDITOR.TRISTATE_ON )
+        *                              alert( 'The current state for the B element is ON' );
+        *                      else
+        *                              alert( 'The current state for the B element is OFF' );
+        *              } );
+        *
+        * @member CKEDITOR.editor
+        * @param {CKEDITOR.style} style The style to be watched.
+        * @param {Function} callback The function to be called.
+        */
+       attachStyleStateChange: function( style, callback ) {
+               // Try to get the list of attached callbacks.
+               var styleStateChangeCallbacks = this._.styleStateChangeCallbacks;
+
+               // If it doesn't exist, it means this is the first call. So, let's create
+               // all the structure to manage the style checks and the callback calls.
+               if ( !styleStateChangeCallbacks ) {
+                       // Create the callbacks array.
+                       styleStateChangeCallbacks = this._.styleStateChangeCallbacks = [];
+
+                       // Attach to the selectionChange event, so we can check the styles at
+                       // that point.
+                       this.on( 'selectionChange', function( ev ) {
+                               // Loop throw all registered callbacks.
+                               for ( var i = 0; i < styleStateChangeCallbacks.length; i++ ) {
+                                       var callback = styleStateChangeCallbacks[ i ];
+
+                                       // Check the current state for the style defined for that callback.
+                                       var currentState = callback.style.checkActive( ev.data.path, this ) ?
+                                               CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
+
+                                       // Call the callback function, passing the current state to it.
+                                       callback.fn.call( this, currentState );
+                               }
+                       } );
+               }
+
+               // Save the callback info, so it can be checked on the next occurrence of
+               // selectionChange.
+               styleStateChangeCallbacks.push( { style: style, fn: callback } );
+       },
+
+       /**
+        * Applies the style upon the editor's current selection. Shorthand for
+        * {@link CKEDITOR.style#apply}.
+        *
+        * @member CKEDITOR.editor
+        * @param {CKEDITOR.style} style
+        */
+       applyStyle: function( style ) {
+               style.apply( this );
+       },
+
+       /**
+        * Removes the style from the editor's current selection. Shorthand for
+        * {@link CKEDITOR.style#remove}.
+        *
+        * @member CKEDITOR.editor
+        * @param {CKEDITOR.style} style
+        */
+       removeStyle: function( style ) {
+               style.remove( this );
+       },
+
+       /**
+        * Gets the current `stylesSet` for this instance.
+        *
+        *              editor.getStylesSet( function( stylesDefinitions ) {} );
+        *
+        * See also {@link CKEDITOR.editor#stylesSet} event.
+        *
+        * @member CKEDITOR.editor
+        * @param {Function} callback The function to be called with the styles data.
+        */
+       getStylesSet: function( callback ) {
+               if ( !this._.stylesDefinitions ) {
+                       var editor = this,
+                               // Respect the backwards compatible definition entry
+                               configStyleSet = editor.config.stylesCombo_stylesSet || editor.config.stylesSet;
+
+                       // The false value means that none styles should be loaded.
+                       if ( configStyleSet === false ) {
+                               callback( null );
+                               return;
+                       }
+
+                       // #5352 Allow to define the styles directly in the config object
+                       if ( configStyleSet instanceof Array ) {
+                               editor._.stylesDefinitions = configStyleSet;
+                               callback( configStyleSet );
+                               return;
+                       }
+
+                       // Default value is 'default'.
+                       if ( !configStyleSet )
+                               configStyleSet = 'default';
+
+                       var partsStylesSet = configStyleSet.split( ':' ),
+                               styleSetName = partsStylesSet[ 0 ],
+                               externalPath = partsStylesSet[ 1 ];
+
+                       CKEDITOR.stylesSet.addExternal( styleSetName, externalPath ? partsStylesSet.slice( 1 ).join( ':' ) : CKEDITOR.getUrl( 'styles.js' ), '' );
+
+                       CKEDITOR.stylesSet.load( styleSetName, function( stylesSet ) {
+                               editor._.stylesDefinitions = stylesSet[ styleSetName ];
+                               callback( editor._.stylesDefinitions );
+                       } );
+               } else {
+                       callback( this._.stylesDefinitions );
+               }
+       }
+} );
+
+/**
+ * Indicates that fully selected read-only elements will be included when
+ * applying the style (for inline styles only).
+ *
+ * @since 3.5
+ * @property {Boolean} [includeReadonly=false]
+ * @member CKEDITOR.style
+ */
+
+/**
+ * Indicates that any matches element of this style will be eventually removed
+ * when calling {@link CKEDITOR.editor#removeStyle}.
+ *
+ * @since 4.0
+ * @property {Boolean} [alwaysRemoveElement=false]
+ * @member CKEDITOR.style
+ */
+
+/**
+ * Disables inline styling on read-only elements.
+ *
+ * @since 3.5
+ * @cfg {Boolean} [disableReadonlyStyling=false]
+ * @member CKEDITOR.config
+ */
+
+/**
+ * The "styles definition set" to use in the editor. They will be used in the
+ * styles combo and the style selector of the div container.
+ *
+ * The styles may be defined in the page containing the editor, or can be
+ * loaded on demand from an external file. In the second case, if this setting
+ * contains only a name, the `styles.js` file will be loaded from the
+ * CKEditor root folder (what ensures backward compatibility with CKEditor 4.0).
+ *
+ * Otherwise, this setting has the `name:url` syntax, making it
+ * possible to set the URL from which the styles file will be loaded.
+ * Note that the `name` has to be equal to the name used in
+ * {@link CKEDITOR.stylesSet#add} while registering the styles set.
+ *
+ * **Note**: Since 4.1 it is possible to set `stylesSet` to `false`
+ * to prevent loading any styles set.
+ *
+ * Read more in the [documentation](#!/guide/dev_styles)
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/styles.html).
+ *
+ *             // Do not load any file. The styles set is empty.
+ *             config.stylesSet = false;
+ *
+ *             // Load the 'mystyles' styles set from the styles.js file.
+ *             config.stylesSet = 'mystyles';
+ *
+ *             // Load the 'mystyles' styles set from a relative URL.
+ *             config.stylesSet = 'mystyles:/editorstyles/styles.js';
+ *
+ *             // Load the 'mystyles' styles set from a full URL.
+ *             config.stylesSet = 'mystyles:http://www.example.com/editorstyles/styles.js';
+ *
+ *             // Load from a list of definitions.
+ *             config.stylesSet = [
+ *                     { name: 'Strong Emphasis', element: 'strong' },
+ *                     { name: 'Emphasis', element: 'em' },
+ *                     ...
+ *             ];
+ *
+ * @since 3.3
+ * @cfg {String/Array/Boolean} [stylesSet='default']
+ * @member CKEDITOR.config
+ */
diff --git a/sources/core/template.js b/sources/core/template.js
new file mode 100644 (file)
index 0000000..2b9e932
--- /dev/null
@@ -0,0 +1,68 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.template} class, which represents
+ * an UI template for an editor instance.
+ */
+
+( function() {
+       var cache = {},
+               rePlaceholder = /{([^}]+)}/g,
+               reEscapableChars = /([\\'])/g,
+               reNewLine = /\n/g,
+               reCarriageReturn = /\r/g;
+
+       /**
+        * Lightweight template used to build the output string from variables.
+        *
+        *              // HTML template for presenting a label UI.
+        *              var tpl = new CKEDITOR.template( '<div class="{cls}">{label}</div>' );
+        *              alert( tpl.output( { cls: 'cke-label', label: 'foo'} ) ); // '<div class="cke-label">foo</div>'
+        *
+        * @class
+        * @constructor Creates a template class instance.
+        * @param {String} source The template source.
+        */
+       CKEDITOR.template = function( source ) {
+               // Builds an optimized function body for the output() method, focused on performance.
+               // For example, if we have this "source":
+               //      '<div style="{style}">{editorName}</div>'
+               // ... the resulting function body will be (apart from the "buffer" handling):
+               //      return [ '<div style="', data['style'] == undefined ? '{style}' : data['style'], '">', data['editorName'] == undefined ? '{editorName}' : data['editorName'], '</div>' ].join('');
+
+               // Try to read from the cache.
+               if ( cache[ source ] )
+                       this.output = cache[ source ];
+               else {
+                       var fn = source
+                               // Escape chars like slash "\" or single quote "'".
+                               .replace( reEscapableChars, '\\$1' )
+                               .replace( reNewLine, '\\n' )
+                               .replace( reCarriageReturn, '\\r' )
+                               // Inject the template keys replacement.
+                               .replace( rePlaceholder, function( m, key ) {
+                                       return "',data['" + key + "']==undefined?'{" + key + "}':data['" + key + "'],'";
+                               } );
+
+                       fn = "return buffer?buffer.push('" + fn + "'):['" + fn + "'].join('');";
+                       this.output = cache[ source ] = Function( 'data', 'buffer', fn );
+               }
+       };
+} )();
+
+/**
+ * Processes the template, filling its variables with the provided data.
+ *
+ * @method output
+ * @param {Object} data An object containing properties which values will be
+ * used to fill the template variables. The property names must match the
+ * template variables names. Variables without matching properties will be
+ * kept untouched.
+ * @param {Array} [buffer] An array into which the output data will be pushed into.
+ * The number of entries appended to the array is unknown.
+ * @returns {String/Number} If `buffer` has not been provided, the processed
+ * template output data, otherwise the new length of `buffer`.
+ */
diff --git a/sources/core/tools.js b/sources/core/tools.js
new file mode 100644 (file)
index 0000000..7e0083f
--- /dev/null
@@ -0,0 +1,1916 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.tools} object that contains
+ *             utility functions.
+ */
+
+( function() {
+       var functions = [],
+               cssVendorPrefix =
+                       CKEDITOR.env.gecko ? '-moz-' :
+                       CKEDITOR.env.webkit ? '-webkit-' :
+                       CKEDITOR.env.ie ? '-ms-' :
+                       '',
+               ampRegex = /&/g,
+               gtRegex = />/g,
+               ltRegex = /</g,
+               quoteRegex = /"/g,
+               tokenCharset = 'abcdefghijklmnopqrstuvwxyz0123456789',
+               TOKEN_COOKIE_NAME = 'ckCsrfToken',
+               TOKEN_LENGTH = 40,
+
+               allEscRegex = /&(lt|gt|amp|quot|nbsp|shy|#\d{1,5});/g,
+               namedEntities = {
+                       lt: '<',
+                       gt: '>',
+                       amp: '&',
+                       quot: '"',
+                       nbsp: '\u00a0',
+                       shy: '\u00ad'
+               },
+               allEscDecode = function( match, code ) {
+                       if ( code[ 0 ] == '#' ) {
+                               return String.fromCharCode( parseInt( code.slice( 1 ), 10 ) );
+                       } else {
+                               return namedEntities[ code ];
+                       }
+               };
+
+       CKEDITOR.on( 'reset', function() {
+               functions = [];
+       } );
+
+       /**
+        * Utility functions.
+        *
+        * @class
+        * @singleton
+        */
+       CKEDITOR.tools = {
+               /**
+                * Compares the elements of two arrays.
+                *
+                *              var a = [ 1, 'a', 3 ];
+                *              var b = [ 1, 3, 'a' ];
+                *              var c = [ 1, 'a', 3 ];
+                *              var d = [ 1, 'a', 3, 4 ];
+                *
+                *              alert( CKEDITOR.tools.arrayCompare( a, b ) );  // false
+                *              alert( CKEDITOR.tools.arrayCompare( a, c ) );  // true
+                *              alert( CKEDITOR.tools.arrayCompare( a, d ) );  // false
+                *
+                * @param {Array} arrayA An array to be compared.
+                * @param {Array} arrayB The other array to be compared.
+                * @returns {Boolean} `true` if the arrays have the same length and
+                * their elements match.
+                */
+               arrayCompare: function( arrayA, arrayB ) {
+                       if ( !arrayA && !arrayB )
+                               return true;
+
+                       if ( !arrayA || !arrayB || arrayA.length != arrayB.length )
+                               return false;
+
+                       for ( var i = 0; i < arrayA.length; i++ ) {
+                               if ( arrayA[ i ] != arrayB[ i ] )
+                                       return false;
+                       }
+
+                       return true;
+               },
+
+               /**
+                * Finds the index of the first element in an array for which the `compareFunction` returns `true`.
+                *
+                *              CKEDITOR.tools.getIndex( [ 1, 2, 4, 3, 5 ], function( el ) {
+                *                      return el >= 3;
+                *              } ); // 2
+                *
+                * @since 4.5
+                * @param {Array} array Array to search in.
+                * @param {Function} compareFunction Compare function.
+                * @returns {Number} The index of the first matching element or `-1` if none matches.
+                */
+               getIndex: function( arr, compareFunction ) {
+                       for ( var i = 0; i < arr.length; ++i ) {
+                               if ( compareFunction( arr[ i ] ) )
+                                       return i;
+                       }
+                       return -1;
+               },
+
+               /**
+                * Creates a deep copy of an object.
+                *
+                * **Note**: Recursive references are not supported.
+                *
+                *              var obj = {
+                *                      name: 'John',
+                *                      cars: {
+                *                              Mercedes: { color: 'blue' },
+                *                              Porsche: { color: 'red' }
+                *                      }
+                *              };
+                *              var clone = CKEDITOR.tools.clone( obj );
+                *              clone.name = 'Paul';
+                *              clone.cars.Porsche.color = 'silver';
+                *
+                *              alert( obj.name );                                      // 'John'
+                *              alert( clone.name );                            // 'Paul'
+                *              alert( obj.cars.Porsche.color );        // 'red'
+                *              alert( clone.cars.Porsche.color );      // 'silver'
+                *
+                * @param {Object} object The object to be cloned.
+                * @returns {Object} The object clone.
+                */
+               clone: function( obj ) {
+                       var clone;
+
+                       // Array.
+                       if ( obj && ( obj instanceof Array ) ) {
+                               clone = [];
+
+                               for ( var i = 0; i < obj.length; i++ )
+                                       clone[ i ] = CKEDITOR.tools.clone( obj[ i ] );
+
+                               return clone;
+                       }
+
+                       // "Static" types.
+                       if ( obj === null || ( typeof obj != 'object' ) || ( obj instanceof String ) || ( obj instanceof Number ) || ( obj instanceof Boolean ) || ( obj instanceof Date ) || ( obj instanceof RegExp ) )
+                               return obj;
+
+                       // DOM objects and window.
+                       if ( obj.nodeType || obj.window === obj )
+                               return obj;
+
+                       // Objects.
+                       clone = new obj.constructor();
+
+                       for ( var propertyName in obj ) {
+                               var property = obj[ propertyName ];
+                               clone[ propertyName ] = CKEDITOR.tools.clone( property );
+                       }
+
+                       return clone;
+               },
+
+               /**
+                * Turns the first letter of a string to upper-case.
+                *
+                * @param {String} str
+                * @param {Boolean} [keepCase] Keep the case of 2nd to last letter.
+                * @returns {String}
+                */
+               capitalize: function( str, keepCase ) {
+                       return str.charAt( 0 ).toUpperCase() + ( keepCase ? str.slice( 1 ) : str.slice( 1 ).toLowerCase() );
+               },
+
+               /**
+                * Copies the properties from one object to another. By default, properties
+                * already present in the target object **are not** overwritten.
+                *
+                *              // Create the sample object.
+                *              var myObject = {
+                *                      prop1: true
+                *              };
+                *
+                *              // Extend the above object with two properties.
+                *              CKEDITOR.tools.extend( myObject, {
+                *                      prop2: true,
+                *                      prop3: true
+                *              } );
+                *
+                *              // Alert 'prop1', 'prop2' and 'prop3'.
+                *              for ( var p in myObject )
+                *                      alert( p );
+                *
+                * @param {Object} target The object to be extended.
+                * @param {Object...} source The object(s) from properties will be
+                * copied. Any number of objects can be passed to this function.
+                * @param {Boolean} [overwrite] If `true` is specified, it indicates that
+                * properties already present in the target object could be
+                * overwritten by subsequent objects.
+                * @param {Object} [properties] Only properties within the specified names
+                * list will be received from the source object.
+                * @returns {Object} The extended object (target).
+                */
+               extend: function( target ) {
+                       var argsLength = arguments.length,
+                               overwrite, propertiesList;
+
+                       if ( typeof ( overwrite = arguments[ argsLength - 1 ] ) == 'boolean' )
+                               argsLength--;
+                       else if ( typeof ( overwrite = arguments[ argsLength - 2 ] ) == 'boolean' ) {
+                               propertiesList = arguments[ argsLength - 1 ];
+                               argsLength -= 2;
+                       }
+                       for ( var i = 1; i < argsLength; i++ ) {
+                               var source = arguments[ i ];
+                               for ( var propertyName in source ) {
+                                       // Only copy existed fields if in overwrite mode.
+                                       if ( overwrite === true || target[ propertyName ] == null ) {
+                                               // Only copy  specified fields if list is provided.
+                                               if ( !propertiesList || ( propertyName in propertiesList ) )
+                                                       target[ propertyName ] = source[ propertyName ];
+
+                                       }
+                               }
+                       }
+
+                       return target;
+               },
+
+               /**
+                * Creates an object which is an instance of a class whose prototype is a
+                * predefined object. All properties defined in the source object are
+                * automatically inherited by the resulting object, including future
+                * changes to it.
+                *
+                * @param {Object} source The source object to be used as the prototype for
+                * the final object.
+                * @returns {Object} The resulting copy.
+                */
+               prototypedCopy: function( source ) {
+                       var copy = function() {};
+                       copy.prototype = source;
+                       return new copy();
+               },
+
+               /**
+                * Makes fast (shallow) copy of an object.
+                * This method is faster than {@link #clone} which does
+                * a deep copy of an object (including arrays).
+                *
+                * @since 4.1
+                * @param {Object} source The object to be copied.
+                * @returns {Object} Copy of `source`.
+                */
+               copy: function( source ) {
+                       var obj = {},
+                               name;
+
+                       for ( name in source )
+                               obj[ name ] = source[ name ];
+
+                       return obj;
+               },
+
+               /**
+                * Checks if an object is an Array.
+                *
+                *              alert( CKEDITOR.tools.isArray( [] ) );          // true
+                *              alert( CKEDITOR.tools.isArray( 'Test' ) );      // false
+                *
+                * @param {Object} object The object to be checked.
+                * @returns {Boolean} `true` if the object is an Array, otherwise `false`.
+                */
+               isArray: function( object ) {
+                       return Object.prototype.toString.call( object ) == '[object Array]';
+               },
+
+               /**
+                * Whether the object contains no properties of its own.
+                *
+                * @param object
+                * @returns {Boolean}
+                */
+               isEmpty: function( object ) {
+                       for ( var i in object ) {
+                               if ( object.hasOwnProperty( i ) )
+                                       return false;
+                       }
+                       return true;
+               },
+
+               /**
+                * Generates an object or a string containing vendor-specific and vendor-free CSS properties.
+                *
+                *              CKEDITOR.tools.cssVendorPrefix( 'border-radius', '0', true );
+                *              // On Firefox: '-moz-border-radius:0;border-radius:0'
+                *              // On Chrome: '-webkit-border-radius:0;border-radius:0'
+                *
+                * @param {String} property The CSS property name.
+                * @param {String} value The CSS value.
+                * @param {Boolean} [asString=false] If `true`, then the returned value will be a CSS string.
+                * @returns {Object/String} The object containing CSS properties or its stringified version.
+                */
+               cssVendorPrefix: function( property, value, asString ) {
+                       if ( asString )
+                               return cssVendorPrefix + property + ':' + value + ';' + property + ':' + value;
+
+                       var ret = {};
+                       ret[ property ] = value;
+                       ret[ cssVendorPrefix + property ] = value;
+
+                       return ret;
+               },
+
+               /**
+                * Transforms a CSS property name to its relative DOM style name.
+                *
+                *              alert( CKEDITOR.tools.cssStyleToDomStyle( 'background-color' ) );       // 'backgroundColor'
+                *              alert( CKEDITOR.tools.cssStyleToDomStyle( 'float' ) );                          // 'cssFloat'
+                *
+                * @method
+                * @param {String} cssName The CSS property name.
+                * @returns {String} The transformed name.
+                */
+               cssStyleToDomStyle: ( function() {
+                       var test = document.createElement( 'div' ).style;
+
+                       var cssFloat = ( typeof test.cssFloat != 'undefined' ) ? 'cssFloat' : ( typeof test.styleFloat != 'undefined' ) ? 'styleFloat' : 'float';
+
+                       return function( cssName ) {
+                               if ( cssName == 'float' )
+                                       return cssFloat;
+                               else {
+                                       return cssName.replace( /-./g, function( match ) {
+                                               return match.substr( 1 ).toUpperCase();
+                                       } );
+                               }
+                       };
+               } )(),
+
+               /**
+                * Builds a HTML snippet from a set of `<style>/<link>`.
+                *
+                * @param {String/Array} css Each of which are URLs (absolute) of a CSS file or
+                * a trunk of style text.
+                * @returns {String}
+                */
+               buildStyleHtml: function( css ) {
+                       css = [].concat( css );
+                       var item,
+                               retval = [];
+                       for ( var i = 0; i < css.length; i++ ) {
+                               if ( ( item = css[ i ] ) ) {
+                                       // Is CSS style text ?
+                                       if ( /@import|[{}]/.test( item ) )
+                                               retval.push( '<style>' + item + '</style>' );
+                                       else
+                                               retval.push( '<link type="text/css" rel=stylesheet href="' + item + '">' );
+                               }
+                       }
+                       return retval.join( '' );
+               },
+
+               /**
+                * Replaces special HTML characters in a string with their relative HTML
+                * entity values.
+                *
+                *              alert( CKEDITOR.tools.htmlEncode( 'A > B & C < D' ) ); // 'A &gt; B &amp; C &lt; D'
+                *
+                * @param {String} text The string to be encoded.
+                * @returns {String} The encoded string.
+                */
+               htmlEncode: function( text ) {
+                       // Backwards compatibility - accept also non-string values (casting is done below).
+                       // Since 4.4.8 we return empty string for null and undefined because these values make no sense.
+                       if ( text === undefined || text === null ) {
+                               return '';
+                       }
+
+                       return String( text ).replace( ampRegex, '&amp;' ).replace( gtRegex, '&gt;' ).replace( ltRegex, '&lt;' );
+               },
+
+               /**
+                * Decodes HTML entities that browsers tend to encode when used in text nodes.
+                *
+                *              alert( CKEDITOR.tools.htmlDecode( '&lt;a &amp; b &gt;' ) ); // '<a & b >'
+                *
+                * Read more about chosen entities in the [research](http://dev.ckeditor.com/ticket/13105#comment:8).
+                *
+                * @param {String} The string to be decoded.
+                * @returns {String} The decoded string.
+                */
+               htmlDecode: function( text ) {
+                       // See:
+                       // * http://dev.ckeditor.com/ticket/13105#comment:8 and comment:9,
+                       // * http://jsperf.com/wth-is-going-on-with-jsperf JSPerf has some serious problems, but you can observe
+                       // that combined regexp tends to be quicker (except on V8). It will also not be prone to fail on '&amp;lt;'
+                       // (see http://dev.ckeditor.com/ticket/13105#DXWTF:CKEDITOR.tools.htmlEnDecodeAttr).
+                       return text.replace( allEscRegex, allEscDecode );
+               },
+
+               /**
+                * Replaces special HTML characters in HTMLElement attribute with their relative HTML entity values.
+                *
+                *              alert( CKEDITOR.tools.htmlEncodeAttr( '<a " b >' ) ); // '&lt;a &quot; b &gt;'
+                *
+                * @param {String} The attribute value to be encoded.
+                * @returns {String} The encoded value.
+                */
+               htmlEncodeAttr: function( text ) {
+                       return CKEDITOR.tools.htmlEncode( text ).replace( quoteRegex, '&quot;' );
+               },
+
+               /**
+                * Decodes HTML entities that browsers tend to encode when used in attributes.
+                *
+                *              alert( CKEDITOR.tools.htmlDecodeAttr( '&lt;a &quot; b&gt;' ) ); // '<a " b>'
+                *
+                * Since CKEditor 4.5 this method simply executes {@link #htmlDecode} which covers
+                * all necessary entities.
+                *
+                * @param {String} text The text to be decoded.
+                * @returns {String} The decoded text.
+                */
+               htmlDecodeAttr: function( text ) {
+                       return CKEDITOR.tools.htmlDecode( text );
+               },
+
+               /**
+                * Transforms text to valid HTML: creates paragraphs, replaces tabs with non-breaking spaces etc.
+                *
+                * @since 4.5
+                * @param {String} text Text to transform.
+                * @param {Number} enterMode Editor {@link CKEDITOR.config#enterMode Enter mode}.
+                * @returns {String} HTML generated from the text.
+                */
+               transformPlainTextToHtml: function( text, enterMode ) {
+                       var isEnterBrMode = enterMode == CKEDITOR.ENTER_BR,
+                               // CRLF -> LF
+                               html = this.htmlEncode( text.replace( /\r\n/g, '\n' ) );
+
+                       // Tab -> &nbsp x 4;
+                       html = html.replace( /\t/g, '&nbsp;&nbsp; &nbsp;' );
+
+                       var paragraphTag = enterMode == CKEDITOR.ENTER_P ? 'p' : 'div';
+
+                       // Two line-breaks create one paragraphing block.
+                       if ( !isEnterBrMode ) {
+                               var duoLF = /\n{2}/g;
+                               if ( duoLF.test( html ) ) {
+                                       var openTag = '<' + paragraphTag + '>', endTag = '</' + paragraphTag + '>';
+                                       html = openTag + html.replace( duoLF, function() {
+                                               return endTag + openTag;
+                                       } ) + endTag;
+                               }
+                       }
+
+                       // One <br> per line-break.
+                       html = html.replace( /\n/g, '<br>' );
+
+                       // Compensate padding <br> at the end of block, avoid loosing them during insertion.
+                       if ( !isEnterBrMode ) {
+                               html = html.replace( new RegExp( '<br>(?=</' + paragraphTag + '>)' ), function( match ) {
+                                       return CKEDITOR.tools.repeat( match, 2 );
+                               } );
+                       }
+
+                       // Preserve spaces at the ends, so they won't be lost after insertion (merged with adjacent ones).
+                       html = html.replace( /^ | $/g, '&nbsp;' );
+
+                       // Finally, preserve whitespaces that are to be lost.
+                       html = html.replace( /(>|\s) /g, function( match, before ) {
+                               return before + '&nbsp;';
+                       } ).replace( / (?=<)/g, '&nbsp;' );
+
+                       return html;
+               },
+
+               /**
+                * Gets a unique number for this CKEDITOR execution session. It returns
+                * consecutive numbers starting from 1.
+                *
+                *              alert( CKEDITOR.tools.getNextNumber() ); // (e.g.) 1
+                *              alert( CKEDITOR.tools.getNextNumber() ); // 2
+                *
+                * @method
+                * @returns {Number} A unique number.
+                */
+               getNextNumber: ( function() {
+                       var last = 0;
+                       return function() {
+                               return ++last;
+                       };
+               } )(),
+
+               /**
+                * Gets a unique ID for CKEditor interface elements. It returns a
+                * string with the "cke_" prefix and a consecutive number.
+                *
+                *              alert( CKEDITOR.tools.getNextId() ); // (e.g.) 'cke_1'
+                *              alert( CKEDITOR.tools.getNextId() ); // 'cke_2'
+                *
+                * @returns {String} A unique ID.
+                */
+               getNextId: function() {
+                       return 'cke_' + this.getNextNumber();
+               },
+
+               /**
+                * Gets a universally unique ID. It returns a random string
+                * compliant with ISO/IEC 11578:1996, without dashes, with the "e" prefix to
+                * make sure that the ID does not start with a number.
+                *
+                * @returns {String} A global unique ID.
+                */
+               getUniqueId: function() {
+                       var uuid = 'e'; // Make sure that id does not start with number.
+                       for ( var i = 0; i < 8; i++ ) {
+                               uuid += Math.floor( ( 1 + Math.random() ) * 0x10000 ).toString( 16 ).substring( 1 );
+                       }
+                       return uuid;
+               },
+
+               /**
+                * Creates a function override.
+                *
+                *              var obj = {
+                *                      myFunction: function( name ) {
+                *                              alert( 'Name: ' + name );
+                *                      }
+                *              };
+                *
+                *              obj.myFunction = CKEDITOR.tools.override( obj.myFunction, function( myFunctionOriginal ) {
+                *                      return function( name ) {
+                *                              alert( 'Overriden name: ' + name );
+                *                              myFunctionOriginal.call( this, name );
+                *                      };
+                *              } );
+                *
+                * @param {Function} originalFunction The function to be overridden.
+                * @param {Function} functionBuilder A function that returns the new
+                * function. The original function reference will be passed to this function.
+                * @returns {Function} The new function.
+                */
+               override: function( originalFunction, functionBuilder ) {
+                       var newFn = functionBuilder( originalFunction );
+                       newFn.prototype = originalFunction.prototype;
+                       return newFn;
+               },
+
+               /**
+                * Executes a function after a specified delay.
+                *
+                *              CKEDITOR.tools.setTimeout( function() {
+                *                      alert( 'Executed after 2 seconds' );
+                *              }, 2000 );
+                *
+                * @param {Function} func The function to be executed.
+                * @param {Number} [milliseconds=0] The amount of time (in milliseconds) to wait
+                * to fire the function execution.
+                * @param {Object} [scope=window] The object to store the function execution scope
+                * (the `this` object).
+                * @param {Object/Array} [args] A single object, or an array of objects, to
+                * pass as argument to the function.
+                * @param {Object} [ownerWindow=window] The window that will be used to set the
+                * timeout.
+                * @returns {Object} A value that can be used to cancel the function execution.
+                */
+               setTimeout: function( func, milliseconds, scope, args, ownerWindow ) {
+                       if ( !ownerWindow )
+                               ownerWindow = window;
+
+                       if ( !scope )
+                               scope = ownerWindow;
+
+                       return ownerWindow.setTimeout( function() {
+                               if ( args )
+                                       func.apply( scope, [].concat( args ) );
+                               else
+                                       func.apply( scope );
+                       }, milliseconds || 0 );
+               },
+
+               /**
+                * Removes spaces from the start and the end of a string. The following
+                * characters are removed: space, tab, line break, line feed.
+                *
+                *              alert( CKEDITOR.tools.trim( '  example ' ); // 'example'
+                *
+                * @method
+                * @param {String} str The text from which the spaces will be removed.
+                * @returns {String} The modified string without the boundary spaces.
+                */
+               trim: ( function() {
+                       // We are not using \s because we don't want "non-breaking spaces" to be caught.
+                       var trimRegex = /(?:^[ \t\n\r]+)|(?:[ \t\n\r]+$)/g;
+                       return function( str ) {
+                               return str.replace( trimRegex, '' );
+                       };
+               } )(),
+
+               /**
+                * Removes spaces from the start (left) of a string. The following
+                * characters are removed: space, tab, line break, line feed.
+                *
+                *              alert( CKEDITOR.tools.ltrim( '  example ' ); // 'example '
+                *
+                * @method
+                * @param {String} str The text from which the spaces will be removed.
+                * @returns {String} The modified string excluding the removed spaces.
+                */
+               ltrim: ( function() {
+                       // We are not using \s because we don't want "non-breaking spaces" to be caught.
+                       var trimRegex = /^[ \t\n\r]+/g;
+                       return function( str ) {
+                               return str.replace( trimRegex, '' );
+                       };
+               } )(),
+
+               /**
+                * Removes spaces from the end (right) of a string. The following
+                * characters are removed: space, tab, line break, line feed.
+                *
+                *              alert( CKEDITOR.tools.ltrim( '  example ' ); // '  example'
+                *
+                * @method
+                * @param {String} str The text from which spaces will be removed.
+                * @returns {String} The modified string excluding the removed spaces.
+                */
+               rtrim: ( function() {
+                       // We are not using \s because we don't want "non-breaking spaces" to be caught.
+                       var trimRegex = /[ \t\n\r]+$/g;
+                       return function( str ) {
+                               return str.replace( trimRegex, '' );
+                       };
+               } )(),
+
+               /**
+                * Returns the index of an element in an array.
+                *
+                *              var letters = [ 'a', 'b', 0, 'c', false ];
+                *              alert( CKEDITOR.tools.indexOf( letters, '0' ) );                // -1 because 0 !== '0'
+                *              alert( CKEDITOR.tools.indexOf( letters, false ) );              // 4 because 0 !== false
+                *
+                * @param {Array} array The array to be searched.
+                * @param {Object/Function} value The element to be found. This can be an
+                * evaluation function which receives a single parameter call for
+                * each entry in the array, returning `true` if the entry matches.
+                * @returns {Number} The (zero-based) index of the first entry that matches
+                * the entry, or `-1` if not found.
+                */
+               indexOf: function( array, value ) {
+                       if ( typeof value == 'function' ) {
+                               for ( var i = 0, len = array.length; i < len; i++ ) {
+                                       if ( value( array[ i ] ) )
+                                               return i;
+                               }
+                       } else if ( array.indexOf )
+                               return array.indexOf( value );
+                       else {
+                               for ( i = 0, len = array.length; i < len; i++ ) {
+                                       if ( array[ i ] === value )
+                                               return i;
+                               }
+                       }
+                       return -1;
+               },
+
+               /**
+                * Returns the index of an element in an array.
+                *
+                *              var obj = { prop: true };
+                *              var letters = [ 'a', 'b', 0, obj, false ];
+                *
+                *              alert( CKEDITOR.tools.indexOf( letters, '0' ) ); // null
+                *              alert( CKEDITOR.tools.indexOf( letters, function( value ) {
+                *                      // Return true when passed value has property 'prop'.
+                *                      return value && 'prop' in value;
+                *              } ) );                                                                                  // obj
+                *
+                * @param {Array} array The array to be searched.
+                * @param {Object/Function} value The element to be found. Can be an
+                * evaluation function which receives a single parameter call for
+                * each entry in the array, returning `true` if the entry matches.
+                * @returns Object The value that was found in an array.
+                */
+               search: function( array, value ) {
+                       var index = CKEDITOR.tools.indexOf( array, value );
+                       return index >= 0 ? array[ index ] : null;
+               },
+
+               /**
+                * Creates a function that will always execute in the context of a
+                * specified object.
+                *
+                *              var obj = { text: 'My Object' };
+                *
+                *              function alertText() {
+                *                      alert( this.text );
+                *              }
+                *
+                *              var newFunc = CKEDITOR.tools.bind( alertText, obj );
+                *              newFunc(); // Alerts 'My Object'.
+                *
+                * @param {Function} func The function to be executed.
+                * @param {Object} obj The object to which the execution context will be bound.
+                * @returns {Function} The function that can be used to execute the
+                * `func` function in the context of `obj`.
+                */
+               bind: function( func, obj ) {
+                       return function() {
+                               return func.apply( obj, arguments );
+                       };
+               },
+
+               /**
+                * Class creation based on prototype inheritance which supports of the
+                * following features:
+                *
+                * * Static fields
+                * * Private fields
+                * * Public (prototype) fields
+                * * Chainable base class constructor
+                *
+                * @param {Object} definition The class definition object.
+                * @returns {Function} A class-like JavaScript function.
+                */
+               createClass: function( definition ) {
+                       var $ = definition.$,
+                               baseClass = definition.base,
+                               privates = definition.privates || definition._,
+                               proto = definition.proto,
+                               statics = definition.statics;
+
+                       // Create the constructor, if not present in the definition.
+                       !$ && ( $ = function() {
+                               baseClass && this.base.apply( this, arguments );
+                       } );
+
+                       if ( privates ) {
+                               var originalConstructor = $;
+                               $ = function() {
+                                       // Create (and get) the private namespace.
+                                       var _ = this._ || ( this._ = {} );
+
+                                       // Make some magic so "this" will refer to the main
+                                       // instance when coding private functions.
+                                       for ( var privateName in privates ) {
+                                               var priv = privates[ privateName ];
+
+                                               _[ privateName ] = ( typeof priv == 'function' ) ? CKEDITOR.tools.bind( priv, this ) : priv;
+                                       }
+
+                                       originalConstructor.apply( this, arguments );
+                               };
+                       }
+
+                       if ( baseClass ) {
+                               $.prototype = this.prototypedCopy( baseClass.prototype );
+                               $.prototype.constructor = $;
+                               // Super references.
+                               $.base = baseClass;
+                               $.baseProto = baseClass.prototype;
+                               // Super constructor.
+                               $.prototype.base = function() {
+                                       this.base = baseClass.prototype.base;
+                                       baseClass.apply( this, arguments );
+                                       this.base = arguments.callee;
+                               };
+                       }
+
+                       if ( proto )
+                               this.extend( $.prototype, proto, true );
+
+                       if ( statics )
+                               this.extend( $, statics, true );
+
+                       return $;
+               },
+
+               /**
+                * Creates a function reference that can be called later using
+                * {@link #callFunction}. This approach is especially useful to
+                * make DOM attribute function calls to JavaScript-defined functions.
+                *
+                *              var ref = CKEDITOR.tools.addFunction( function() {
+                *                      alert( 'Hello!');
+                *              } );
+                *              CKEDITOR.tools.callFunction( ref ); // 'Hello!'
+                *
+                * @param {Function} fn The function to be executed on call.
+                * @param {Object} [scope] The object to have the context on `fn` execution.
+                * @returns {Number} A unique reference to be used in conjuction with
+                * {@link #callFunction}.
+                */
+               addFunction: function( fn, scope ) {
+                       return functions.push( function() {
+                               return fn.apply( scope || this, arguments );
+                       } ) - 1;
+               },
+
+               /**
+                * Removes the function reference created with {@link #addFunction}.
+                *
+                * @param {Number} ref The function reference created with
+                * {@link #addFunction}.
+                */
+               removeFunction: function( ref ) {
+                       functions[ ref ] = null;
+               },
+
+               /**
+                * Executes a function based on the reference created with {@link #addFunction}.
+                *
+                *              var ref = CKEDITOR.tools.addFunction( function() {
+                *                      alert( 'Hello!');
+                *              } );
+                *              CKEDITOR.tools.callFunction( ref ); // 'Hello!'
+                *
+                * @param {Number} ref The function reference created with {@link #addFunction}.
+                * @param {Mixed} params Any number of parameters to be passed to the executed function.
+                * @returns {Mixed} The return value of the function.
+                */
+               callFunction: function( ref ) {
+                       var fn = functions[ ref ];
+                       return fn && fn.apply( window, Array.prototype.slice.call( arguments, 1 ) );
+               },
+
+               /**
+                * Appends the `px` length unit to the size value if it is missing.
+                *
+                *              var cssLength = CKEDITOR.tools.cssLength;
+                *              cssLength( 42 );                // '42px'
+                *              cssLength( '42' );              // '42px'
+                *              cssLength( '42px' );    // '42px'
+                *              cssLength( '42%' );             // '42%'
+                *              cssLength( 'bold' );    // 'bold'
+                *              cssLength( false );             // ''
+                *              cssLength( NaN );               // ''
+                *
+                * @method
+                * @param {Number/String/Boolean} length
+                */
+               cssLength: ( function() {
+                       var pixelRegex = /^-?\d+\.?\d*px$/,
+                               lengthTrimmed;
+
+                       return function( length ) {
+                               lengthTrimmed = CKEDITOR.tools.trim( length + '' ) + 'px';
+
+                               if ( pixelRegex.test( lengthTrimmed ) )
+                                       return lengthTrimmed;
+                               else
+                                       return length || '';
+                       };
+               } )(),
+
+               /**
+                * Converts the specified CSS length value to the calculated pixel length inside this page.
+                *
+                * **Note:** Percentage-based value is left intact.
+                *
+                * @method
+                * @param {String} cssLength CSS length value.
+                */
+               convertToPx: ( function() {
+                       var calculator;
+
+                       return function( cssLength ) {
+                               if ( !calculator ) {
+                                       calculator = CKEDITOR.dom.element.createFromHtml( '<div style="position:absolute;left:-9999px;' +
+                                               'top:-9999px;margin:0px;padding:0px;border:0px;"' +
+                                               '></div>', CKEDITOR.document );
+                                       CKEDITOR.document.getBody().append( calculator );
+                               }
+
+                               if ( !( /%$/ ).test( cssLength ) ) {
+                                       calculator.setStyle( 'width', cssLength );
+                                       return calculator.$.clientWidth;
+                               }
+
+                               return cssLength;
+                       };
+               } )(),
+
+               /**
+                * String specified by `str` repeats `times` times.
+                *
+                * @param {String} str
+                * @param {Number} times
+                * @returns {String}
+                */
+               repeat: function( str, times ) {
+                       return new Array( times + 1 ).join( str );
+               },
+
+               /**
+                * Returns the first successfully executed return value of a function that
+                * does not throw any exception.
+                *
+                * @param {Function...} fn
+                * @returns {Mixed}
+                */
+               tryThese: function() {
+                       var returnValue;
+                       for ( var i = 0, length = arguments.length; i < length; i++ ) {
+                               var lambda = arguments[ i ];
+                               try {
+                                       returnValue = lambda();
+                                       break;
+                               } catch ( e ) {}
+                       }
+                       return returnValue;
+               },
+
+               /**
+                * Generates a combined key from a series of params.
+                *
+                *              var key = CKEDITOR.tools.genKey( 'key1', 'key2', 'key3' );
+                *              alert( key ); // 'key1-key2-key3'.
+                *
+                * @param {String} subKey One or more strings used as subkeys.
+                * @returns {String}
+                */
+               genKey: function() {
+                       return Array.prototype.slice.call( arguments ).join( '-' );
+               },
+
+               /**
+                * Creates a "deferred" function which will not run immediately,
+                * but rather runs as soon as the interpreter’s call stack is empty.
+                * Behaves much like `window.setTimeout` with a delay.
+                *
+                * **Note:** The return value of the original function will be lost.
+                *
+                * @param {Function} fn The callee function.
+                * @returns {Function} The new deferred function.
+                */
+               defer: function( fn ) {
+                       return function() {
+                               var args = arguments,
+                                       self = this;
+                               window.setTimeout( function() {
+                                       fn.apply( self, args );
+                               }, 0 );
+                       };
+               },
+
+               /**
+                * Normalizes CSS data in order to avoid differences in the style attribute.
+                *
+                * @param {String} styleText The style data to be normalized.
+                * @param {Boolean} [nativeNormalize=false] Parse the data using the browser.
+                * @returns {String} The normalized value.
+                */
+               normalizeCssText: function( styleText, nativeNormalize ) {
+                       var props = [],
+                               name,
+                               parsedProps = CKEDITOR.tools.parseCssText( styleText, true, nativeNormalize );
+
+                       for ( name in parsedProps )
+                               props.push( name + ':' + parsedProps[ name ] );
+
+                       props.sort();
+
+                       return props.length ? ( props.join( ';' ) + ';' ) : '';
+               },
+
+               /**
+                * Finds and converts `rgb(x,x,x)` color definition to hexadecimal notation.
+                *
+                * @param {String} styleText The style data (or just a string containing RGB colors) to be converted.
+                * @returns {String} The style data with RGB colors converted to hexadecimal equivalents.
+                */
+               convertRgbToHex: function( styleText ) {
+                       return styleText.replace( /(?:rgb\(\s*(\d+)\s*,\s*(\d+)\s*,\s*(\d+)\s*\))/gi, function( match, red, green, blue ) {
+                               var color = [ red, green, blue ];
+                               // Add padding zeros if the hex value is less than 0x10.
+                               for ( var i = 0; i < 3; i++ )
+                                       color[ i ] = ( '0' + parseInt( color[ i ], 10 ).toString( 16 ) ).slice( -2 );
+                               return '#' + color.join( '' );
+                       } );
+               },
+
+               /**
+                * Normalizes hexadecimal notation so that the color string is always 6 characters long and lowercase.
+                *
+                * @param {String} styleText The style data (or just a string containing hex colors) to be converted.
+                * @returns {String} The style data with hex colors normalized.
+                */
+               normalizeHex: function( styleText ) {
+                       return styleText.replace( /#(([0-9a-f]{3}){1,2})($|;|\s+)/gi, function( match, hexColor, hexColorPart, separator ) {
+                               var normalizedHexColor = hexColor.toLowerCase();
+                               if ( normalizedHexColor.length == 3 ) {
+                                       var parts = normalizedHexColor.split( '' );
+                                       normalizedHexColor = [ parts[ 0 ], parts[ 0 ], parts[ 1 ], parts[ 1 ], parts[ 2 ], parts[ 2 ] ].join( '' );
+                               }
+                               return '#' + normalizedHexColor + separator;
+                       } );
+               },
+
+               /**
+                * Turns inline style text properties into one hash.
+                *
+                * @param {String} styleText The style data to be parsed.
+                * @param {Boolean} [normalize=false] Normalize properties and values
+                * (e.g. trim spaces, convert to lower case).
+                * @param {Boolean} [nativeNormalize=false] Parse the data using the browser.
+                * @returns {Object} The object containing parsed properties.
+                */
+               parseCssText: function( styleText, normalize, nativeNormalize ) {
+                       var retval = {};
+
+                       if ( nativeNormalize ) {
+                               // Injects the style in a temporary span object, so the browser parses it,
+                               // retrieving its final format.
+                               var temp = new CKEDITOR.dom.element( 'span' );
+                               styleText = temp.setAttribute( 'style', styleText ).getAttribute( 'style' ) || '';
+                       }
+
+                       // Normalize colors.
+                       if ( styleText ) {
+                               styleText = CKEDITOR.tools.normalizeHex( CKEDITOR.tools.convertRgbToHex( styleText ) );
+                       }
+
+                       // IE will leave a single semicolon when failed to parse the style text. (#3891)
+                       if ( !styleText || styleText == ';' )
+                               return retval;
+
+                       styleText.replace( /&quot;/g, '"' ).replace( /\s*([^:;\s]+)\s*:\s*([^;]+)\s*(?=;|$)/g, function( match, name, value ) {
+                               if ( normalize ) {
+                                       name = name.toLowerCase();
+                                       // Drop extra whitespacing from font-family.
+                                       if ( name == 'font-family' )
+                                               value = value.replace( /\s*,\s*/g, ',' );
+                                       value = CKEDITOR.tools.trim( value );
+                               }
+
+                               retval[ name ] = value;
+                       } );
+                       return retval;
+               },
+
+               /**
+                * Serializes the `style name => value` hash to a style text.
+                *
+                *              var styleObj = CKEDITOR.tools.parseCssText( 'color: red; border: none' );
+                *              console.log( styleObj.color ); // -> 'red'
+                *              CKEDITOR.tools.writeCssText( styleObj ); // -> 'color:red; border:none'
+                *              CKEDITOR.tools.writeCssText( styleObj, true ); // -> 'border:none; color:red'
+                *
+                * @since 4.1
+                * @param {Object} styles The object contaning style properties.
+                * @param {Boolean} [sort] Whether to sort CSS properties.
+                * @returns {String} The serialized style text.
+                */
+               writeCssText: function( styles, sort ) {
+                       var name,
+                               stylesArr = [];
+
+                       for ( name in styles )
+                               stylesArr.push( name + ':' + styles[ name ] );
+
+                       if ( sort )
+                               stylesArr.sort();
+
+                       return stylesArr.join( '; ' );
+               },
+
+               /**
+                * Compares two objects.
+                *
+                * **Note:** This method performs shallow, non-strict comparison.
+                *
+                * @since 4.1
+                * @param {Object} left
+                * @param {Object} right
+                * @param {Boolean} [onlyLeft] Check only the properties that are present in the `left` object.
+                * @returns {Boolean} Whether objects are identical.
+                */
+               objectCompare: function( left, right, onlyLeft ) {
+                       var name;
+
+                       if ( !left && !right )
+                               return true;
+                       if ( !left || !right )
+                               return false;
+
+                       for ( name in left ) {
+                               if ( left[ name ] != right[ name ] )
+                                       return false;
+
+                       }
+
+                       if ( !onlyLeft ) {
+                               for ( name in right ) {
+                                       if ( left[ name ] != right[ name ] )
+                                               return false;
+                               }
+                       }
+
+                       return true;
+               },
+
+               /**
+                * Returns an array of passed object's keys.
+                *
+                *              console.log( CKEDITOR.tools.objectKeys( { foo: 1, bar: false } );
+                *              // -> [ 'foo', 'bar' ]
+                *
+                * @since 4.1
+                * @param {Object} obj
+                * @returns {Array} Object's keys.
+                */
+               objectKeys: function( obj ) {
+                       var keys = [];
+                       for ( var i in obj )
+                               keys.push( i );
+
+                       return keys;
+               },
+
+               /**
+                * Converts an array to an object by rewriting array items
+                * to object properties.
+                *
+                *              var arr = [ 'foo', 'bar', 'foo' ];
+                *              console.log( CKEDITOR.tools.convertArrayToObject( arr ) );
+                *              // -> { foo: true, bar: true }
+                *              console.log( CKEDITOR.tools.convertArrayToObject( arr, 1 ) );
+                *              // -> { foo: 1, bar: 1 }
+                *
+                * @since 4.1
+                * @param {Array} arr The array to be converted to an object.
+                * @param [fillWith=true] Set each property of an object to `fillWith` value.
+                */
+               convertArrayToObject: function( arr, fillWith ) {
+                       var obj = {};
+
+                       if ( arguments.length == 1 )
+                               fillWith = true;
+
+                       for ( var i = 0, l = arr.length; i < l; ++i )
+                               obj[ arr[ i ] ] = fillWith;
+
+                       return obj;
+               },
+
+               /**
+                * Tries to fix the `document.domain` of the current document to match the
+                * parent window domain, avoiding "Same Origin" policy issues.
+                * This is an Internet Explorer only requirement.
+                *
+                * @since 4.1.2
+                * @returns {Boolean} `true` if the current domain is already good or if
+                * it has been fixed successfully.
+                */
+               fixDomain: function() {
+                       var domain;
+
+                       while ( 1 ) {
+                               try {
+                                       // Try to access the parent document. It throws
+                                       // "access denied" if restricted by the "Same Origin" policy.
+                                       domain = window.parent.document.domain;
+                                       break;
+                               } catch ( e ) {
+                                       // Calculate the value to set to document.domain.
+                                       domain = domain ?
+
+                                               // If it is not the first pass, strip one part of the
+                                               // name. E.g.  "test.example.com"  => "example.com"
+                                               domain.replace( /.+?(?:\.|$)/, '' ) :
+
+                                               // In the first pass, we'll handle the
+                                               // "document.domain = document.domain" case.
+                                               document.domain;
+
+                                       // Stop here if there is no more domain parts available.
+                                       if ( !domain )
+                                               break;
+
+                                       document.domain = domain;
+                               }
+                       }
+
+                       return !!domain;
+               },
+
+               /**
+                * Buffers `input` events (or any `input` calls)
+                * and triggers `output` not more often than once per `minInterval`.
+                *
+                *              var buffer = CKEDITOR.tools.eventsBuffer( 200, function() {
+                *                      console.log( 'foo!' );
+                *              } );
+                *
+                *              buffer.input();
+                *              // 'foo!' logged immediately.
+                *              buffer.input();
+                *              // Nothing logged.
+                *              buffer.input();
+                *              // Nothing logged.
+                *              // ... after 200ms a single 'foo!' will be logged.
+                *
+                * Can be easily used with events:
+                *
+                *              var buffer = CKEDITOR.tools.eventsBuffer( 200, function() {
+                *                      console.log( 'foo!' );
+                *              } );
+                *
+                *              editor.on( 'key', buffer.input );
+                *              // Note: There is no need to bind buffer as a context.
+                *
+                * @since 4.2.1
+                * @param {Number} minInterval Minimum interval between `output` calls in milliseconds.
+                * @param {Function} output Function that will be executed as `output`.
+                * @param {Object} [scopeObj] The object used to scope the listener call (the `this` object).
+                * @returns {Object}
+                * @returns {Function} return.input Buffer's input method.
+                * @returns {Function} return.reset Resets buffered events &mdash; `output` will not be executed
+                * until next `input` is triggered.
+                */
+               eventsBuffer: function( minInterval, output, scopeObj ) {
+                       var scheduled,
+                               lastOutput = 0;
+
+                       function triggerOutput() {
+                               lastOutput = ( new Date() ).getTime();
+                               scheduled = false;
+                               if ( scopeObj ) {
+                                       output.call( scopeObj );
+                               } else {
+                                       output();
+                               }
+                       }
+
+                       return {
+                               input: function() {
+                                       if ( scheduled )
+                                               return;
+
+                                       var diff = ( new Date() ).getTime() - lastOutput;
+
+                                       // If less than minInterval passed after last check,
+                                       // schedule next for minInterval after previous one.
+                                       if ( diff < minInterval )
+                                               scheduled = setTimeout( triggerOutput, minInterval - diff );
+                                       else
+                                               triggerOutput();
+                               },
+
+                               reset: function() {
+                                       if ( scheduled )
+                                               clearTimeout( scheduled );
+
+                                       scheduled = lastOutput = 0;
+                               }
+                       };
+               },
+
+               /**
+                * Enables HTML5 elements for older browsers (IE8) in the passed document.
+                *
+                * In IE8 this method can also be executed on a document fragment.
+                *
+                * **Note:** This method has to be used in the `<head>` section of the document.
+                *
+                * @since 4.3
+                * @param {Object} doc Native `Document` or `DocumentFragment` in which the elements will be enabled.
+                * @param {Boolean} [withAppend] Whether to append created elements to the `doc`.
+                */
+               enableHtml5Elements: function( doc, withAppend ) {
+                       var els = 'abbr,article,aside,audio,bdi,canvas,data,datalist,details,figcaption,figure,footer,header,hgroup,main,mark,meter,nav,output,progress,section,summary,time,video'.split( ',' ),
+                               i = els.length,
+                               el;
+
+                       while ( i-- ) {
+                               el = doc.createElement( els[ i ] );
+                               if ( withAppend )
+                                       doc.appendChild( el );
+                       }
+               },
+
+               /**
+                * Checks if any of the `arr` items match the provided regular expression.
+                *
+                * @param {Array} arr The array whose items will be checked.
+                * @param {RegExp} regexp The regular expression.
+                * @returns {Boolean} Returns `true` for the first occurrence of the search pattern.
+                * @since 4.4
+                */
+               checkIfAnyArrayItemMatches: function( arr, regexp ) {
+                       for ( var i = 0, l = arr.length; i < l; ++i ) {
+                               if ( arr[ i ].match( regexp ) )
+                                       return true;
+                       }
+                       return false;
+               },
+
+               /**
+                * Checks if any of the `obj` properties match the provided regular expression.
+                *
+                * @param obj The object whose properties will be checked.
+                * @param {RegExp} regexp The regular expression.
+                * @returns {Boolean} Returns `true` for the first occurrence of the search pattern.
+                * @since 4.4
+                */
+               checkIfAnyObjectPropertyMatches: function( obj, regexp ) {
+                       for ( var i in obj ) {
+                               if ( i.match( regexp ) )
+                                       return true;
+                       }
+                       return false;
+               },
+
+               /**
+                * Converts a keystroke to its string representation. Returns an object with two fields:
+                *
+                * * `display` &ndash; A string that should be used for visible labels.
+                * For Mac devices it uses `⌥` for `ALT`, `⇧` for `SHIFT` and `⌘` for `COMMAND`.
+                * * `aria` &ndash; A string that should be used for ARIA descriptions.
+                * It does not use special characters such as `⌥`, `⇧` or `⌘`.
+                *
+                *              var lang = editor.lang.common.keyboard;
+                *              var shortcut = CKEDITOR.tools.keystrokeToString( lang, CKEDITOR.CTRL + 88 );
+                *              console.log( shortcut.display ); // 'CTRL + X', on Mac '⌘ + X'.
+                *              console.log( shortcut.aria ); // 'CTRL + X', on Mac 'COMMAND + X'.
+                *
+                * @since 4.6.0
+                * @param {Object} lang A language object with the key name translation.
+                * @param {Number} keystroke The keystroke to convert.
+                * @returns {{display: String, aria: String}}
+                */
+               keystrokeToString: function( lang, keystroke ) {
+                       var special = keystroke & 0xFF0000,
+                               key = keystroke & 0x00FFFF,
+                               isMac = CKEDITOR.env.mac,
+                               CTRL = 17,
+                               CMD = 224,
+                               ALT = 18,
+                               SHIFT = 16,
+                               display = [],
+                               aria = [];
+
+
+                       if ( special & CKEDITOR.CTRL ) {
+                               display.push( isMac ? '⌘' : lang[ CTRL ] );
+                               aria.push( isMac ? lang[ CMD ] : lang[ CTRL ] );
+                       }
+
+                       if ( special & CKEDITOR.ALT ) {
+                               display.push( isMac ? '⌥' : lang[ ALT ] );
+                               aria.push( lang[ ALT ] );
+                       }
+
+                       if ( special & CKEDITOR.SHIFT ) {
+                               display.push( isMac ? '⇧' : lang[ SHIFT ] );
+                               aria.push( lang[ SHIFT ] );
+                       }
+
+                       if ( key ) {
+                               if ( lang[ key ] ) {
+                                       display.push( lang[ key ] );
+                                       aria.push( lang[ key ] );
+                               } else {
+                                       display.push( String.fromCharCode( key ) );
+                                       aria.push( String.fromCharCode( key ) );
+                               }
+                       }
+
+                       return {
+                               display: display.join( '+' ),
+                               aria: aria.join( '+' )
+                       };
+               },
+
+               /**
+                * The data URI of a transparent image. May be used e.g. in HTML as an image source or in CSS in `url()`.
+                *
+                * @since 4.4
+                * @readonly
+                */
+               transparentImageData: 'data:image/gif;base64,R0lGODlhAQABAPABAP///wAAACH5BAEKAAAALAAAAAABAAEAAAICRAEAOw==',
+
+
+               /**
+                * Returns the value of the cookie with a given name or `null` if the cookie is not found.
+                *
+                * @since 4.5.6
+                * @param {String} name
+                * @returns {String}
+                */
+               getCookie: function( name ) {
+                       name = name.toLowerCase();
+                       var parts = document.cookie.split( ';' );
+                       var pair, key;
+
+                       for ( var i = 0; i < parts.length; i++ ) {
+                               pair = parts[ i ].split( '=' );
+                               key = decodeURIComponent( CKEDITOR.tools.trim( pair[ 0 ] ).toLowerCase() );
+
+                               if ( key === name ) {
+                                       return decodeURIComponent( pair.length > 1 ? pair[ 1 ] : '' );
+                               }
+                       }
+
+                       return null;
+               },
+
+               /**
+                * Sets the value of the cookie with a given name.
+                *
+                * @since 4.5.6
+                * @param {String} name
+                * @param {String} value
+                */
+               setCookie: function( name, value ) {
+                       document.cookie = encodeURIComponent( name ) + '=' + encodeURIComponent( value ) + ';path=/';
+               },
+
+               /**
+                * Returns the CSRF token value. The value is a hash stored in `document.cookie`
+                * under the `ckCsrfToken` key. The CSRF token can be used to secure the communication
+                * between the web browser and the server, i.e. for the file upload feature in the editor.
+                *
+                * @since 4.5.6
+                * @returns {String}
+                */
+               getCsrfToken: function() {
+                       var token = CKEDITOR.tools.getCookie( TOKEN_COOKIE_NAME );
+
+                       if ( !token || token.length != TOKEN_LENGTH ) {
+                               token = generateToken( TOKEN_LENGTH );
+                               CKEDITOR.tools.setCookie( TOKEN_COOKIE_NAME, token );
+                       }
+
+                       return token;
+               },
+
+               /**
+                * Returns an escaped CSS selector. `CSS.escape()` is used if defined, leading digit is escaped otherwise.
+                *
+                * @since 4.5.10
+                * @param {String} selector A CSS selector to escape.
+                * @returns {String} An escaped selector.
+                */
+               escapeCss: function( selector ) {
+                       // Invalid input.
+                       if ( !selector ) {
+                               return '';
+                       }
+
+                       // CSS.escape() can be used.
+                       if ( window.CSS && CSS.escape ) {
+                               return CSS.escape( selector );
+                       }
+
+                       // Simple leading digit escape.
+                       if ( !isNaN( parseInt( selector.charAt( 0 ), 10 ) ) ) {
+                               return '\\3' + selector.charAt( 0 ) + ' ' + selector.substring( 1, selector.length );
+                       }
+
+                       return selector;
+               },
+
+               /**
+                * A set of functions for operations on styles.
+                *
+                * @property {CKEDITOR.tools.style}
+                */
+               style: {
+                       /**
+                        * Methods to parse miscellaneous CSS properties.
+                        *
+                        * @property {CKEDITOR.tools.style.parse}
+                        * @member CKEDITOR.tools.style
+                        */
+                       parse: {
+                               // Color list based on https://www.w3.org/TR/css-color-4/#named-colors.
+                               _colors: {
+                                       aliceblue: '#F0F8FF',
+                                       antiquewhite: '#FAEBD7',
+                                       aqua: '#00FFFF',
+                                       aquamarine: '#7FFFD4',
+                                       azure: '#F0FFFF',
+                                       beige: '#F5F5DC',
+                                       bisque: '#FFE4C4',
+                                       black: '#000000',
+                                       blanchedalmond: '#FFEBCD',
+                                       blue: '#0000FF',
+                                       blueviolet: '#8A2BE2',
+                                       brown: '#A52A2A',
+                                       burlywood: '#DEB887',
+                                       cadetblue: '#5F9EA0',
+                                       chartreuse: '#7FFF00',
+                                       chocolate: '#D2691E',
+                                       coral: '#FF7F50',
+                                       cornflowerblue: '#6495ED',
+                                       cornsilk: '#FFF8DC',
+                                       crimson: '#DC143C',
+                                       cyan: '#00FFFF',
+                                       darkblue: '#00008B',
+                                       darkcyan: '#008B8B',
+                                       darkgoldenrod: '#B8860B',
+                                       darkgray: '#A9A9A9',
+                                       darkgreen: '#006400',
+                                       darkgrey: '#A9A9A9',
+                                       darkkhaki: '#BDB76B',
+                                       darkmagenta: '#8B008B',
+                                       darkolivegreen: '#556B2F',
+                                       darkorange: '#FF8C00',
+                                       darkorchid: '#9932CC',
+                                       darkred: '#8B0000',
+                                       darksalmon: '#E9967A',
+                                       darkseagreen: '#8FBC8F',
+                                       darkslateblue: '#483D8B',
+                                       darkslategray: '#2F4F4F',
+                                       darkslategrey: '#2F4F4F',
+                                       darkturquoise: '#00CED1',
+                                       darkviolet: '#9400D3',
+                                       deeppink: '#FF1493',
+                                       deepskyblue: '#00BFFF',
+                                       dimgray: '#696969',
+                                       dimgrey: '#696969',
+                                       dodgerblue: '#1E90FF',
+                                       firebrick: '#B22222',
+                                       floralwhite: '#FFFAF0',
+                                       forestgreen: '#228B22',
+                                       fuchsia: '#FF00FF',
+                                       gainsboro: '#DCDCDC',
+                                       ghostwhite: '#F8F8FF',
+                                       gold: '#FFD700',
+                                       goldenrod: '#DAA520',
+                                       gray: '#808080',
+                                       green: '#008000',
+                                       greenyellow: '#ADFF2F',
+                                       grey: '#808080',
+                                       honeydew: '#F0FFF0',
+                                       hotpink: '#FF69B4',
+                                       indianred: '#CD5C5C',
+                                       indigo: '#4B0082',
+                                       ivory: '#FFFFF0',
+                                       khaki: '#F0E68C',
+                                       lavender: '#E6E6FA',
+                                       lavenderblush: '#FFF0F5',
+                                       lawngreen: '#7CFC00',
+                                       lemonchiffon: '#FFFACD',
+                                       lightblue: '#ADD8E6',
+                                       lightcoral: '#F08080',
+                                       lightcyan: '#E0FFFF',
+                                       lightgoldenrodyellow: '#FAFAD2',
+                                       lightgray: '#D3D3D3',
+                                       lightgreen: '#90EE90',
+                                       lightgrey: '#D3D3D3',
+                                       lightpink: '#FFB6C1',
+                                       lightsalmon: '#FFA07A',
+                                       lightseagreen: '#20B2AA',
+                                       lightskyblue: '#87CEFA',
+                                       lightslategray: '#778899',
+                                       lightslategrey: '#778899',
+                                       lightsteelblue: '#B0C4DE',
+                                       lightyellow: '#FFFFE0',
+                                       lime: '#00FF00',
+                                       limegreen: '#32CD32',
+                                       linen: '#FAF0E6',
+                                       magenta: '#FF00FF',
+                                       maroon: '#800000',
+                                       mediumaquamarine: '#66CDAA',
+                                       mediumblue: '#0000CD',
+                                       mediumorchid: '#BA55D3',
+                                       mediumpurple: '#9370DB',
+                                       mediumseagreen: '#3CB371',
+                                       mediumslateblue: '#7B68EE',
+                                       mediumspringgreen: '#00FA9A',
+                                       mediumturquoise: '#48D1CC',
+                                       mediumvioletred: '#C71585',
+                                       midnightblue: '#191970',
+                                       mintcream: '#F5FFFA',
+                                       mistyrose: '#FFE4E1',
+                                       moccasin: '#FFE4B5',
+                                       navajowhite: '#FFDEAD',
+                                       navy: '#000080',
+                                       oldlace: '#FDF5E6',
+                                       olive: '#808000',
+                                       olivedrab: '#6B8E23',
+                                       orange: '#FFA500',
+                                       orangered: '#FF4500',
+                                       orchid: '#DA70D6',
+                                       palegoldenrod: '#EEE8AA',
+                                       palegreen: '#98FB98',
+                                       paleturquoise: '#AFEEEE',
+                                       palevioletred: '#DB7093',
+                                       papayawhip: '#FFEFD5',
+                                       peachpuff: '#FFDAB9',
+                                       peru: '#CD853F',
+                                       pink: '#FFC0CB',
+                                       plum: '#DDA0DD',
+                                       powderblue: '#B0E0E6',
+                                       purple: '#800080',
+                                       rebeccapurple: '#663399',
+                                       red: '#FF0000',
+                                       rosybrown: '#BC8F8F',
+                                       royalblue: '#4169E1',
+                                       saddlebrown: '#8B4513',
+                                       salmon: '#FA8072',
+                                       sandybrown: '#F4A460',
+                                       seagreen: '#2E8B57',
+                                       seashell: '#FFF5EE',
+                                       sienna: '#A0522D',
+                                       silver: '#C0C0C0',
+                                       skyblue: '#87CEEB',
+                                       slateblue: '#6A5ACD',
+                                       slategray: '#708090',
+                                       slategrey: '#708090',
+                                       snow: '#FFFAFA',
+                                       springgreen: '#00FF7F',
+                                       steelblue: '#4682B4',
+                                       tan: '#D2B48C',
+                                       teal: '#008080',
+                                       thistle: '#D8BFD8',
+                                       tomato: '#FF6347',
+                                       turquoise: '#40E0D0',
+                                       violet: '#EE82EE',
+                                       wheat: '#F5DEB3',
+                                       white: '#FFFFFF',
+                                       whitesmoke: '#F5F5F5',
+                                       yellow: '#FFFF00',
+                                       yellowgreen: '#9ACD32'
+                               },
+
+                               _rgbaRegExp: /rgba?\(\s*\d+%?\s*,\s*\d+%?\s*,\s*\d+%?\s*(?:,\s*[0-9.]+\s*)?\)/gi,
+
+                               _hslaRegExp: /hsla?\(\s*[0-9.]+\s*,\s*\d+%\s*,\s*\d+%\s*(?:,\s*[0-9.]+\s*)?\)/gi,
+
+                               /**
+                                * Parses the `value` used as a `background` property shorthand and returns information as an object.
+                                *
+                                * **Note:** Currently only the `color` property is extracted. Any other parts will go into the `unprocessed` property.
+                                *
+                                *              var background = CKEDITOR.tools.style.parse.background( '#0C0 url(foo.png)' );
+                                *              console.log( background );
+                                *              // Logs: { color: '#0C0', unprocessed: 'url(foo.png)' }
+                                *
+                                * @param {String} value The value of the `background` property.
+                                * @returns {Object} An object with information extracted from the background.
+                                * @returns {String} return.color The **first** color value found. The color format remains the same as in input.
+                                * @returns {String} return.unprocessed The remaining part of the `value` that has not been processed.
+                                * @member CKEDITOR.tools.style.parse
+                                */
+                               background: function( value ) {
+                                       var ret = [],
+                                               colors = [];
+
+                                       colors = this._findColor( value );
+
+                                       if ( colors.length ) {
+                                               ret.color = colors[ 0 ];
+
+                                               CKEDITOR.tools.array.forEach( colors, function( colorToken ) {
+                                                       value = value.replace( colorToken, '' );
+                                               } );
+                                       }
+
+                                       value = CKEDITOR.tools.trim( value );
+
+                                       if ( value ) {
+                                               // If anything was left unprocessed include it as unprocessed part.
+                                               ret.unprocessed = value;
+                                       }
+
+                                       return ret;
+                               },
+
+                               /**
+                                * Parses the `margin` CSS property shorthand format.
+                                *
+                                *              console.log( CKEDITOR.tools.parse.margin( '3px 0 2' ) );
+                                *              // Logs: { top: "3px", right: "0", bottom: "2", left: "0" }
+                                *
+                                * @param {String} value The `margin` property value.
+                                * @returns {Object}
+                                * @returns {Number} return.top Top margin.
+                                * @returns {Number} return.right Right margin.
+                                * @returns {Number} return.bottom Bottom margin.
+                                * @returns {Number} return.left Left margin.
+                                * @member CKEDITOR.tools.style.parse
+                                */
+                               margin: function( value ) {
+                                       var ret = {};
+
+                                       var widths = value.match( /(?:\-?[\.\d]+(?:%|\w*)|auto|inherit|initial|unset)/g ) || [ '0px' ];
+
+                                       switch ( widths.length ) {
+                                               case 1:
+                                                       mapStyles( [ 0, 0, 0, 0 ] );
+                                                       break;
+                                               case 2:
+                                                       mapStyles( [ 0, 1, 0, 1 ] );
+                                                       break;
+                                               case 3:
+                                                       mapStyles( [ 0, 1, 2, 1 ] );
+                                                       break;
+                                               case 4:
+                                                       mapStyles( [ 0, 1, 2, 3 ] );
+                                                       break;
+                                       }
+
+                                       function mapStyles( map ) {
+                                               ret.top = widths[ map[ 0 ] ];
+                                               ret.right = widths[ map[ 1 ] ];
+                                               ret.bottom = widths[ map[ 2 ] ];
+                                               ret.left = widths[ map[ 3 ] ];
+                                       }
+
+                                       return ret;
+                               },
+
+                               /**
+                                * Searches the `value` for any CSS color occurrences and returns it.
+                                *
+                                * @private
+                                * @param {String} value
+                                * @returns {String[]} An array of matched results.
+                                * @member CKEDITOR.tools.style.parse
+                                */
+                               _findColor: function( value ) {
+                                       var ret = [],
+                                               arrayTools = CKEDITOR.tools.array;
+
+
+                                       // Check for rgb(a).
+                                       ret = ret.concat( value.match( this._rgbaRegExp ) || [] );
+
+                                       // Check for hsl(a).
+                                       ret = ret.concat( value.match( this._hslaRegExp ) || [] );
+
+                                       ret = ret.concat( arrayTools.filter( value.split( /\s+/ ), function( colorEntry ) {
+                                               // Check for hex format.
+                                               if ( colorEntry.match( /^\#[a-f0-9]{3}(?:[a-f0-9]{3})?$/gi ) ) {
+                                                       return true;
+                                               }
+
+                                               // Check for preset names.
+                                               return colorEntry.toLowerCase() in CKEDITOR.tools.style.parse._colors;
+                                       } ) );
+
+                                       return ret;
+                               }
+                       }
+               },
+
+               /**
+                * A set of array helpers.
+                *
+                * @property {CKEDITOR.tools.array}
+                * @member CKEDITOR.tools
+                */
+               array: {
+                       /**
+                        * Returns a copy of `array` filtered using the `fn` function. Any elements that the `fn` will return `false` for
+                        * will get removed from the returned array.
+                        *
+                        *              var filtered = this.array.filter( [ 0, 1, 2, 3 ], function( value ) {
+                        *                      // Leave only values equal or greater than 2.
+                        *                      return value >= 2;
+                        *              } );
+                        *              console.log( filtered );
+                        *              // Logs: [ 2, 3 ]
+                        *
+                        * @param {Array} array
+                        * @param {Function} fn A function that gets called with each `array` item. Any item that `fn`
+                        * returned a `false`-alike value for will be filtered out of the `array`.
+                        * @param {Mixed} fn.value The currently iterated array value.
+                        * @param {Number} fn.index The index of the currently iterated value in an array.
+                        * @param {Array} fn.array The original array passed as the `array` variable.
+                        * @param {Mixed} [thisArg=undefined] A context object for `fn`.
+                        * @returns {Array} The filtered array.
+                        * @member CKEDITOR.tools.array
+                        */
+                       filter: function( array, fn, thisArg ) {
+                               var ret = [];
+
+                               this.forEach( array, function( val, i ) {
+                                       if ( fn.call( thisArg, val, i, array ) ) {
+                                               ret.push( val );
+                                       }
+                               } );
+
+                               return ret;
+                       },
+
+                       /**
+                        * Iterates over every element in the `array`.
+                        *
+                        * @param {Array} array An array to be iterated over.
+                        * @param {Function} fn The function called for every `array` element.
+                        * @param {Mixed} fn.value The currently iterated array value.
+                        * @param {Number} fn.index The index of the currently iterated value in an array.
+                        * @param {Array} fn.array The original array passed as an `array` variable.
+                        * @param {Mixed} [thisArg=undefined] The context object for `fn`.
+                        * @member CKEDITOR.tools.array
+                        */
+                       forEach: function( array, fn, thisArg ) {
+                               var len = array.length,
+                                       i;
+
+                               for ( i = 0; i < len; i++ ) {
+                                       fn.call( thisArg, array[ i ], i, array );
+                               }
+                       },
+
+                       /**
+                        * Applies a function to each element of an array and returns the array of results in the same order.
+                        * Note the order of the parameters.
+                        *
+                        * @param {Array} array An array of elements that `fn` is applied on.
+                        * @param {Function} fn A function with the signature `a -> b`.
+                        * @param {Mixed} [thisArg=undefined] The context object for `fn`.
+                        * @returns {Array} An array of mapped elements.
+                        * @member CKEDITOR.tools.array
+                        * @since 4.6.2
+                        */
+                       map: function( array, fn, thisArg ) {
+                               var result = [];
+                               for ( var i = 0; i < array.length; i++ ) {
+                                       result.push( fn.call( thisArg, array[ i ], i, array ) );
+                               }
+                               return result;
+                       },
+
+                       /**
+                        * Applies a function against each value in an array storing the result in an accumulator passed to the next iteration.
+                        * Note the order of the parameters.
+                        *
+                        * @param {Array} array An array of elements that `fn` is applied on.
+                        * @param {Function} fn A function with the signature `(accumulator, a, index, array) -> b`.
+                        * @param {Mixed} initial Initial value of the accumulator.
+                        * @param {Mixed} [thisArg=undefined] The context object for `fn`.
+                        * @returns {Mixed} The final value of the accumulator.
+                        * @member CKEDITOR.tools.array
+                        * @since 4.6.2
+                       */
+                       reduce: function( array, fn, initial, thisArg ) {
+                               var acc = initial;
+                               for ( var i = 0; i < array.length; i++ ) {
+                                       acc = fn.call( thisArg, acc, array[ i ], i, array );
+                               }
+                               return acc;
+                       }
+               }
+       };
+
+       // Generates a CSRF token with a given length.
+       //
+       // @since 4.5.6
+       // @param {Number} length
+       // @returns {string}
+       function generateToken( length ) {
+               var randValues = [];
+               var result = '';
+
+               if ( window.crypto && window.crypto.getRandomValues ) {
+                       randValues = new Uint8Array( length );
+                       window.crypto.getRandomValues( randValues );
+               } else {
+                       for ( var i = 0; i < length; i++ ) {
+                               randValues.push( Math.floor( Math.random() * 256 ) );
+                       }
+               }
+
+               for ( var j = 0; j < randValues.length; j++ ) {
+                       var character = tokenCharset.charAt( randValues[ j ] % tokenCharset.length );
+                       result += Math.random() > 0.5 ? character.toUpperCase() : character;
+               }
+
+               return result;
+       }
+
+       /**
+        * @member CKEDITOR.tools.array
+        * @method indexOf
+        * @inheritdoc CKEDITOR.tools#indexOf
+        */
+       CKEDITOR.tools.array.indexOf = CKEDITOR.tools.indexOf;
+
+       /**
+        * @member CKEDITOR.tools.array
+        * @method isArray
+        * @inheritdoc CKEDITOR.tools#isArray
+        */
+       CKEDITOR.tools.array.isArray = CKEDITOR.tools.isArray;
+
+
+
+       /**
+        * The namespace containing functions to work on CSS properties.
+        *
+        * @since 4.6.1
+        * @class CKEDITOR.tools.style
+        */
+
+       /**
+        * The namespace with helper functions to parse some common CSS properties.
+        *
+        * @since 4.6.1
+        * @class CKEDITOR.tools.style.parse
+        */
+
+       /**
+        * The namespace with helper functions and polyfills for arrays.
+        *
+        * @since 4.6.1
+        * @class CKEDITOR.tools.array
+        */
+} )();
+
+// PACKAGER_RENAME( CKEDITOR.tools )
diff --git a/sources/core/ui.js b/sources/core/ui.js
new file mode 100644 (file)
index 0000000..ac5a285
--- /dev/null
@@ -0,0 +1,185 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * Contains UI features related to an editor instance.
+ *
+ * @class
+ * @mixins CKEDITOR.event
+ * @constructor Creates a `ui` class instance.
+ * @param {CKEDITOR.editor} editor The editor instance.
+ */
+CKEDITOR.ui = function( editor ) {
+       if ( editor.ui )
+               return editor.ui;
+
+       this.items = {};
+       this.instances = {};
+       this.editor = editor;
+
+       /**
+        * Object used to store private stuff.
+        *
+        * @private
+        */
+       this._ = {
+               handlers: {}
+       };
+
+       return this;
+};
+
+// PACKAGER_RENAME( CKEDITOR.ui )
+
+CKEDITOR.ui.prototype = {
+       /**
+        * Adds a UI item to the items collection. These items can be later used in
+        * the interface.
+        *
+        *              // Add a new button named 'MyBold'.
+        *              editorInstance.ui.add( 'MyBold', CKEDITOR.UI_BUTTON, {
+        *                      label: 'My Bold',
+        *                      command: 'bold'
+        *              } );
+        *
+        * @param {String} name The UI item name.
+        * @param {Object} type The item type.
+        * @param {Object} definition The item definition. The properties of this
+        * object depend on the item type.
+        */
+       add: function( name, type, definition ) {
+               // Compensate the unique name of this ui item to definition.
+               definition.name = name.toLowerCase();
+
+               var item = this.items[ name ] = {
+                       type: type,
+                       // The name of {@link CKEDITOR.command} which associate with this UI.
+                       command: definition.command || null,
+                       args: Array.prototype.slice.call( arguments, 2 )
+               };
+
+               CKEDITOR.tools.extend( item, definition );
+       },
+
+       /**
+        * Retrieves the created UI objects by name.
+        *
+        * @param {String} name The name of the UI definition.
+        */
+       get: function( name ) {
+               return this.instances[ name ];
+       },
+
+       /**
+        * Gets a UI object.
+        *
+        * @param {String} name The UI item name.
+        * @returns {Object} The UI element.
+        */
+       create: function( name ) {
+               var item = this.items[ name ],
+                       handler = item && this._.handlers[ item.type ],
+                       command = item && item.command && this.editor.getCommand( item.command );
+
+               var result = handler && handler.create.apply( this, item.args );
+
+               this.instances[ name ] = result;
+
+               // Add reference inside command object.
+               if ( command )
+                       command.uiItems.push( result );
+
+               if ( result && !result.type )
+                       result.type = item.type;
+
+               return result;
+       },
+
+       /**
+        * Adds a handler for a UI item type. The handler is responsible for
+        * transforming UI item definitions into UI objects.
+        *
+        * @param {Object} type The item type.
+        * @param {Object} handler The handler definition.
+        */
+       addHandler: function( type, handler ) {
+               this._.handlers[ type ] = handler;
+       },
+
+       /**
+        * Returns the unique DOM element that represents one editor's UI part, also known as "space".
+        * There are 3 main editor spaces available: `top`, `contents` and `bottom`
+        * and their availability depends on editor type.
+        *
+        *              // Hide the bottom space in the UI.
+        *              var bottom = editor.ui.space( 'bottom' );
+        *              bottom.setStyle( 'display', 'none' );
+        *
+        * @param {String} name The name of the space.
+        * @returns {CKEDITOR.dom.element} The element that represents the space.
+        */
+       space: function( name ) {
+               return CKEDITOR.document.getById( this.spaceId( name ) );
+       },
+
+       /**
+        * Returns the HTML ID for a specific UI space name.
+        *
+        * @param {String} name The name of the space.
+        * @returns {String} The ID of an element representing this space in the DOM.
+        */
+       spaceId: function( name ) {
+               return this.editor.id + '_' + name;
+       }
+};
+
+CKEDITOR.event.implementOn( CKEDITOR.ui );
+
+/**
+ * Internal event fired when a new UI element is ready.
+ *
+ * @event ready
+ * @param {Object} data The new UI element.
+ */
+
+/**
+ * Virtual class which just illustrates the features of handler objects to be
+ * passed to the {@link CKEDITOR.ui#addHandler} function.
+ * This class is not really a part of the API, so do not call its constructor.
+ *
+ * @class CKEDITOR.ui.handlerDefinition
+ */
+
+/**
+ * Transforms an item definition into a UI item object.
+ *
+ *             editorInstance.ui.addHandler( CKEDITOR.UI_BUTTON, {
+ *                     create: function( definition ) {
+ *                             return new CKEDITOR.ui.button( definition );
+ *                     }
+ *             } );
+ *
+ * @method create
+ * @param {Object} definition The item definition.
+ * @returns {Object} The UI element.
+ * @todo We lack the "UI element" abstract super class.
+ */
+
+/**
+ * The element in the {@link CKEDITOR#document host page's document} that contains the editor content.
+ * If the [fixed editor UI](#!/guide/dev_uitypes-section-fixed-user-interface) is used, then it will be set to
+ * `editor.ui.space( 'contents' )` &mdash; i.e. the `<div>` which contains the editor `<iframe>` (in case of classic editor)
+ * or {@link CKEDITOR.editable} (in case of inline editor). Otherwise it is set to the {@link CKEDITOR.editable} itself.
+ *
+ * Use the position of this element if you need to position elements placed in the host page's document relatively to the
+ * editor content.
+ *
+ *             var editor = CKEDITOR.instances.editor1;
+ *             console.log( editor.ui.contentsElement.getName() ); // 'div'
+ *
+ * @since 4.5
+ * @readonly
+ * @property {CKEDITOR.dom.element} contentsElement
+ */
diff --git a/sources/lang/_translationstatus.txt b/sources/lang/_translationstatus.txt
new file mode 100644 (file)
index 0000000..233ed53
--- /dev/null
@@ -0,0 +1,63 @@
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+
+af.js      Found: 62 Missing: 4
+ar.js      Found: 51 Missing: 15
+bg.js      Found: 58 Missing: 8
+bn.js      Found: 40 Missing: 26
+bs.js      Found: 29 Missing: 37
+ca.js      Found: 61 Missing: 5
+cs.js      Found: 66 Missing: 0
+cy.js      Found: 66 Missing: 0
+da.js      Found: 66 Missing: 0
+de.js      Found: 66 Missing: 0
+el.js      Found: 59 Missing: 7
+en-au.js   Found: 38 Missing: 28
+en-ca.js   Found: 37 Missing: 29
+en-gb.js   Found: 61 Missing: 5
+eo.js      Found: 66 Missing: 0
+es.js      Found: 66 Missing: 0
+et.js      Found: 66 Missing: 0
+eu.js      Found: 48 Missing: 18
+fa.js      Found: 66 Missing: 0
+fi.js      Found: 66 Missing: 0
+fo.js      Found: 66 Missing: 0
+fr-ca.js   Found: 42 Missing: 24
+fr.js      Found: 66 Missing: 0
+gl.js      Found: 40 Missing: 26
+gu.js      Found: 66 Missing: 0
+he.js      Found: 66 Missing: 0
+hi.js      Found: 43 Missing: 23
+hr.js      Found: 66 Missing: 0
+hu.js      Found: 63 Missing: 3
+is.js      Found: 41 Missing: 25
+it.js      Found: 66 Missing: 0
+ja.js      Found: 62 Missing: 4
+ka.js      Found: 62 Missing: 4
+km.js      Found: 40 Missing: 26
+ko.js      Found: 40 Missing: 26
+lt.js      Found: 66 Missing: 0
+lv.js      Found: 40 Missing: 26
+mk.js      Found: 0 Missing: 66
+mn.js      Found: 40 Missing: 26
+ms.js      Found: 39 Missing: 27
+nb.js      Found: 66 Missing: 0
+nl.js      Found: 65 Missing: 1
+no.js      Found: 66 Missing: 0
+pl.js      Found: 66 Missing: 0
+pt-br.js   Found: 66 Missing: 0
+pt.js      Found: 52 Missing: 14
+ro.js      Found: 61 Missing: 5
+ru.js      Found: 66 Missing: 0
+sk.js      Found: 49 Missing: 17
+sl.js      Found: 48 Missing: 18
+sr-latn.js Found: 40 Missing: 26
+sr.js      Found: 40 Missing: 26
+sv.js      Found: 62 Missing: 4
+th.js      Found: 40 Missing: 26
+tr.js      Found: 66 Missing: 0
+ug.js      Found: 66 Missing: 0
+uk.js      Found: 66 Missing: 0
+vi.js      Found: 66 Missing: 0
+zh-cn.js   Found: 66 Missing: 0
+zh.js      Found: 58 Missing: 8
diff --git a/sources/lang/af.js b/sources/lang/af.js
new file mode 100644 (file)
index 0000000..925dc4a
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Afrikaans language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'af' ] = {
+       // ARIA description.
+       editor: 'Woordverwerker',
+       editorPanel: 'Woordverwerkerpaneel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Druk op ALT 0 vir hulp',
+
+               browseServer: 'Blaai op bediener',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Oplaai',
+               uploadSubmit: 'Stuur aan die bediener',
+               image: 'Beeld',
+               flash: 'Flash',
+               form: 'Vorm',
+               checkbox: 'Merkhokkie',
+               radio: 'Radioknoppie',
+               textField: 'Teksveld',
+               textarea: 'Teksarea',
+               hiddenField: 'Versteekteveld',
+               button: 'Knop',
+               select: 'Keuseveld',
+               imageButton: 'Beeldknop',
+               notSet: '<geen instelling>',
+               id: 'Id',
+               name: 'Naam',
+               langDir: 'Skryfrigting',
+               langDirLtr: 'Links na regs (LTR)',
+               langDirRtl: 'Regs na links (RTL)',
+               langCode: 'Taalkode',
+               longDescr: 'Lang beskrywing URL',
+               cssClass: 'CSS klasse',
+               advisoryTitle: 'Aanbevole titel',
+               cssStyle: 'Styl',
+               ok: 'OK',
+               cancel: 'Kanselleer',
+               close: 'Sluit',
+               preview: 'Voorbeeld',
+               resize: 'Skalierung',
+               generalTab: 'Algemeen',
+               advancedTab: 'Gevorderd',
+               validateNumberFailed: 'Hierdie waarde is nie \'n nommer nie.',
+               confirmNewPage: 'Alle wysiginge sal verlore gaan. Is jy seker dat jy \'n nuwe bladsy wil laai?',
+               confirmCancel: 'Sommige opsies is gewysig. Is jy seker dat jy hierdie dialoogvenster wil sluit?',
+               options: 'Opsies',
+               target: 'Teiken',
+               targetNew: 'Nuwe venster (_blank)',
+               targetTop: 'Boonste venster (_top)',
+               targetSelf: 'Selfde venster (_self)',
+               targetParent: 'Oorspronklike venster (_parent)',
+               langDirLTR: 'Links na Regs (LTR)',
+               langDirRTL: 'Regs na Links (RTL)',
+               styles: 'Styl',
+               cssClasses: 'CSS klasse',
+               width: 'Breedte',
+               height: 'Hoogte',
+               align: 'Orienteerung',
+               alignLeft: 'Links',
+               alignRight: 'Regs',
+               alignCenter: 'Middel',
+               alignJustify: 'Eweredig',
+               alignTop: 'Bo',
+               alignMiddle: 'Middel',
+               alignBottom: 'Onder',
+               alignNone: 'Geen',
+               invalidValue: 'Ongeldige waarde',
+               invalidHeight: 'Hoogte moet \'n getal wees',
+               invalidWidth: 'Breedte moet \'n getal wees.',
+               invalidCssLength: 'Die waarde vir die "%1" veld moet \'n posetiewe getal wees met of sonder \'n geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).',
+               invalidHtmlLength: 'Die waarde vir die  "%1" veld moet \'n posetiewe getal wees met of sonder \'n geldige HTML eenheid (px of %).',
+               invalidInlineStyle: 'Ongeldige CSS. Formaat is een of meer sleutel-wert paare, "naam : wert" met kommapunte gesky.',
+               cssLengthTooltip: 'Voeg \'n getal wert in pixel in, of \'n waarde met geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nie beskikbaar nie</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Einde',
+                       36: 'Tuis',
+                       46: 'Verwyder',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ar.js b/sources/lang/ar.js
new file mode 100644 (file)
index 0000000..1412f22
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Arabic language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ar' ] = {
+       // ARIA description.
+       editor: 'محرر النص الغني',
+       editorPanel: 'لائحة محرر النص المنسق',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'إضغط على ALT + 0 للحصول على المساعدة.',
+
+               browseServer: 'تصفح',
+               url: 'الرابط',
+               protocol: 'البروتوكول',
+               upload: 'رفع',
+               uploadSubmit: 'أرسل',
+               image: 'صورة',
+               flash: 'فلاش',
+               form: 'نموذج',
+               checkbox: 'خانة إختيار',
+               radio: 'زر اختيار',
+               textField: 'مربع نص',
+               textarea: 'مساحة نصية',
+               hiddenField: 'إدراج حقل خفي',
+               button: 'زر ضغط',
+               select: 'اختار',
+               imageButton: 'زر صورة',
+               notSet: '<بدون تحديد>',
+               id: 'الرقم',
+               name: 'إسم',
+               langDir: 'إتجاه النص',
+               langDirLtr: 'اليسار لليمين (LTR)',
+               langDirRtl: 'اليمين لليسار (RTL)',
+               langCode: 'رمز اللغة',
+               longDescr: 'الوصف التفصيلى',
+               cssClass: 'فئات التنسيق',
+               advisoryTitle: 'عنوان التقرير',
+               cssStyle: 'نمط',
+               ok: 'موافق',
+               cancel: 'إلغاء الأمر',
+               close: 'أغلق',
+               preview: 'استعراض',
+               resize: 'تغيير الحجم',
+               generalTab: 'عام',
+               advancedTab: 'متقدم',
+               validateNumberFailed: 'لايوجد نتيجة',
+               confirmNewPage: 'ستفقد أي متغييرات اذا لم تقم بحفظها اولا. هل أنت متأكد أنك تريد صفحة جديدة؟',
+               confirmCancel: 'بعض الخيارات قد تغيرت. هل أنت متأكد من إغلاق مربع النص؟',
+               options: 'خيارات',
+               target: 'هدف الرابط',
+               targetNew: 'نافذة جديدة',
+               targetTop: 'النافذة الأعلى',
+               targetSelf: 'داخل النافذة',
+               targetParent: 'النافذة الأم',
+               langDirLTR: 'اليسار لليمين (LTR)',
+               langDirRTL: 'اليمين لليسار (RTL)',
+               styles: 'نمط',
+               cssClasses: 'فئات التنسيق',
+               width: 'العرض',
+               height: 'الإرتفاع',
+               align: 'محاذاة',
+               alignLeft: 'يسار',
+               alignRight: 'يمين',
+               alignCenter: 'وسط',
+               alignJustify: 'ضبط',
+               alignTop: 'أعلى',
+               alignMiddle: 'وسط',
+               alignBottom: 'أسفل',
+               alignNone: 'None', // MISSING
+               invalidValue: 'قيمة غير مفبولة.',
+               invalidHeight: 'الارتفاع يجب أن يكون عدداً.',
+               invalidWidth: 'العرض يجب أن يكون عدداً.',
+               invalidCssLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة CSS قياس مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'قيمة الخانة المخصصة لـ "%1" يجب أن تكون رقما موجبا، باستخدام أو من غير استخدام وحدة HTML قياس مقبولة (px or %).',
+               invalidInlineStyle: 'قيمة الخانة المخصصة لـ  Inline Style يجب أن تختوي على مجموع واحد أو أكثر بالشكل التالي: "name : value", مفصولة بفاصلة منقزطة.',
+               cssLengthTooltip: 'أدخل رقما للقيمة بالبكسل أو رقما بوحدة CSS مقبولة (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, غير متاح</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/az.js b/sources/lang/az.js
new file mode 100644 (file)
index 0000000..796fec7
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Azerbaijani language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'az' ] = {
+       // ARIA description.
+       editor: 'Mətn Redaktoru',
+       editorPanel: 'Mətn Redaktorun Paneli',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Yardım üçün ALT 0 düymələrini basın',
+
+               browseServer: 'Fayların siyahı',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Serverə yüklə',
+               uploadSubmit: 'Göndər',
+               image: 'Şəkil',
+               flash: 'Flash',
+               form: 'Forma',
+               checkbox: 'Çekboks',
+               radio: 'Radio düyməsi',
+               textField: 'Mətn xanası',
+               textarea: 'Mətn',
+               hiddenField: 'Gizli xana',
+               button: 'Düymə',
+               select: 'Opsiyaların seçilməsi',
+               imageButton: 'Şəkil tipli düymə',
+               notSet: '<seçilməmiş>',
+               id: 'Id',
+               name: 'Ad',
+               langDir: 'Yaziların istiqaməti',
+               langDirLtr: 'Soldan sağa (LTR)',
+               langDirRtl: 'Sağdan sola (RTL)',
+               langCode: 'Dilin kodu',
+               longDescr: 'URL-ın ətraflı izahı',
+               cssClass: 'CSS klassları',
+               advisoryTitle: 'Başlıq',
+               cssStyle: 'CSS',
+               ok: 'Tədbiq et',
+               cancel: 'İmtina et',
+               close: 'Bağla',
+               preview: 'Baxış',
+               resize: 'Eni dəyiş',
+               generalTab: 'Əsas',
+               advancedTab: 'Əlavə',
+               validateNumberFailed: 'Rəqəm deyil.',
+               confirmNewPage: 'Yadda saxlanılmamış dəyişikliklər itiriləcək. Davam etmək istədiyinizə əminsinizmi?',
+               confirmCancel: 'Dəyişikliklər edilib. Pəncərəni bağlamaq istəyirsizə əminsinizmi?',
+               options: 'Seçimlər',
+               target: 'Hədəf çərçivə',
+               targetNew: 'Yeni pəncərə (_blank)',
+               targetTop: 'Əsas pəncərə (_top)',
+               targetSelf: 'Carı pəncərə (_self)',
+               targetParent: 'Ana pəncərə (_parent)',
+               langDirLTR: 'Soldan sağa (LTR)',
+               langDirRTL: 'Sağdan sola (RTL)',
+               styles: 'Üslub',
+               cssClasses: 'Üslub klası',
+               width: 'En',
+               height: 'Uzunluq',
+               align: 'Yerləşmə',
+               alignLeft: 'Sol',
+               alignRight: 'Sağ',
+               alignCenter: 'Mərkəz',
+               alignJustify: 'Eninə görə',
+               alignTop: 'Yuxarı',
+               alignMiddle: 'Orta',
+               alignBottom: 'Aşağı',
+               alignNone: 'Yoxdur',
+               invalidValue: 'Yanlışdır.',
+               invalidHeight: 'Hündürlük rəqəm olmalıdır.',
+               invalidWidth: 'En rəqəm olmalıdır.',
+               invalidCssLength: '"%1" xanasında göstərilən məzmun tam və müsbət olmalıdır, CSS-də olan ölçü vahidlərin (px, %, in, cm, mm, em, ex, pt, or pc) istifadısinə icazə verilir.',
+               invalidHtmlLength: '"%1" xanasında göstərilən məzmun tam və müsbət olmalıdır HTML-də olan ölçü vahidlərin (px və ya %) istifadısinə icazə verilir.',
+               invalidInlineStyle: 'Teq içində olan üslub "ad :  məzmun" şəklidə, nöqtə-verqül işarəsi ilə bitməlidir',
+               cssLengthTooltip: 'Piksel sayı və ya digər CSS ölçü vahidləri (px, %, in, cm, mm, em, ex, pt, or pc) daxil edin.',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, mövcud deyil</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Boşluq',
+                       35: 'Son',
+                       36: 'Evə',
+                       46: 'Sil',
+                       224: 'Əmr'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Qısayol düymələri'
+       }
+};
diff --git a/sources/lang/bg.js b/sources/lang/bg.js
new file mode 100644 (file)
index 0000000..84a1d55
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Bulgarian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'bg' ] = {
+       // ARIA description.
+       editor: 'Текстов редактор за форматиран текст',
+       editorPanel: 'Панел на текстовия редактор',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'натиснете ALT 0 за помощ',
+
+               browseServer: 'Избор от сървъра',
+               url: 'URL',
+               protocol: 'Протокол',
+               upload: 'Качване',
+               uploadSubmit: 'Изпращане към сървъра',
+               image: 'Снимка',
+               flash: 'Флаш',
+               form: 'Форма',
+               checkbox: 'Поле за избор',
+               radio: 'Радио бутон',
+               textField: 'Текстово поле',
+               textarea: 'Текстова зона',
+               hiddenField: 'Скрито поле',
+               button: 'Бутон',
+               select: 'Поле за избор',
+               imageButton: 'Бутон за снимка',
+               notSet: '<не е избрано>',
+               id: 'ID',
+               name: 'Име',
+               langDir: 'Посока на езика',
+               langDirLtr: 'Ляво на дясно (ЛнД)',
+               langDirRtl: 'Дясно на ляво (ДнЛ)',
+               langCode: 'Код на езика',
+               longDescr: 'Уеб адрес за дълго описание',
+               cssClass: 'Класове за CSS',
+               advisoryTitle: 'Препоръчително заглавие',
+               cssStyle: 'Стил',
+               ok: 'ОК',
+               cancel: 'Отказ',
+               close: 'Затвори',
+               preview: 'Преглед',
+               resize: 'Влачете за да оразмерите',
+               generalTab: 'Общи',
+               advancedTab: 'Разширено',
+               validateNumberFailed: 'Тази стойност не е число',
+               confirmNewPage: 'Всички незапазени промени ще бъдат изгубени. Сигурни ли сте, че желаете да заредите нова страница?',
+               confirmCancel: 'Някои от опциите са променени. Сигурни ли сте, че желаете да затворите прозореца?',
+               options: 'Опции',
+               target: 'Цел',
+               targetNew: 'Нов прозорец (_blank)',
+               targetTop: 'Горна позиция (_top)',
+               targetSelf: 'Текущия прозорец (_self)',
+               targetParent: 'Основен прозорец (_parent)',
+               langDirLTR: 'Ляво на дясно (ЛнД)',
+               langDirRTL: 'Дясно на ляво (ДнЛ)',
+               styles: 'Стил',
+               cssClasses: 'Класове за CSS',
+               width: 'Ширина',
+               height: 'Височина',
+               align: 'Подравняване',
+               alignLeft: 'Ляво',
+               alignRight: 'Дясно',
+               alignCenter: 'Център',
+               alignJustify: 'Двустранно подравняване',
+               alignTop: 'Горе',
+               alignMiddle: 'По средата',
+               alignBottom: 'Долу',
+               alignNone: 'Без подравняване',
+               invalidValue: 'Невалидна стойност.',
+               invalidHeight: 'Височината трябва да е число.',
+               invalidWidth: 'Ширина требе да е число.',
+               invalidCssLength: 'Стойността на полето "%1" трябва да бъде положително число с или без валидна CSS измервателна единица (px, %, in, cm, mm, em, ex, pt, или pc).',
+               invalidHtmlLength: 'Стойността на полето "%1" трябва да бъде положително число с или без валидна HTML измервателна единица (px или %).',
+               invalidInlineStyle: 'Стойността на стилa трябва да съдържат една или повече двойки във формат "name : value", разделени с двоеточие.',
+               cssLengthTooltip: 'Въведете числена стойност в пиксели или друга валидна CSS единица (px, %, in, cm, mm, em, ex, pt, или pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, недостъпно</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/bn.js b/sources/lang/bn.js
new file mode 100644 (file)
index 0000000..9c6e69b
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Bengali/Bangla language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'bn' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'ব্রাউজ সার্ভার',
+               url: 'URL',
+               protocol: 'প্রোটোকল',
+               upload: 'আপলোড',
+               uploadSubmit: 'ইহাকে সার্ভারে প্রেরন কর',
+               image: 'ছবির লেবেল যুক্ত কর',
+               flash: 'ফ্লাশ লেবেল যুক্ত কর',
+               form: 'ফর্ম',
+               checkbox: 'চেক বাক্স',
+               radio: 'রেডিও বাটন',
+               textField: 'টেক্সট ফীল্ড',
+               textarea: 'টেক্সট এরিয়া',
+               hiddenField: 'গুপ্ত ফীল্ড',
+               button: 'বাটন',
+               select: 'বাছাই ফীল্ড',
+               imageButton: 'ছবির বাটন',
+               notSet: '<সেট নেই>',
+               id: 'আইডি',
+               name: 'নাম',
+               langDir: 'ভাষা লেখার দিক',
+               langDirLtr: 'বাম থেকে ডান (LTR)',
+               langDirRtl: 'ডান থেকে বাম (RTL)',
+               langCode: 'ভাষা কোড',
+               longDescr: 'URL এর লম্বা বর্ণনা',
+               cssClass: 'স্টাইল-শীট ক্লাস',
+               advisoryTitle: 'পরামর্শ শীর্ষক',
+               cssStyle: 'স্টাইল',
+               ok: 'ওকে',
+               cancel: 'বাতিল',
+               close: 'Close', // MISSING
+               preview: 'প্রিভিউ',
+               resize: 'Resize', // MISSING
+               generalTab: 'General', // MISSING
+               advancedTab: 'এডভান্সড',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Options', // MISSING
+               target: 'টার্গেট',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'বাম থেকে ডান (LTR)',
+               langDirRTL: 'ডান থেকে বাম (RTL)',
+               styles: 'স্টাইল',
+               cssClasses: 'স্টাইল-শীট ক্লাস',
+               width: 'প্রস্থ',
+               height: 'দৈর্ঘ্য',
+               align: 'এলাইন',
+               alignLeft: 'বামে',
+               alignRight: 'ডানে',
+               alignCenter: 'মাঝখানে',
+               alignJustify: 'ব্লক জাস্টিফাই',
+               alignTop: 'উপর',
+               alignMiddle: 'মধ্য',
+               alignBottom: 'নীচে',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/bs.js b/sources/lang/bs.js
new file mode 100644 (file)
index 0000000..f214df8
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Bosnian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'bs' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Browse Server', // MISSING
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Šalji',
+               uploadSubmit: 'Šalji na server',
+               image: 'Slika',
+               flash: 'Flash', // MISSING
+               form: 'Form', // MISSING
+               checkbox: 'Checkbox', // MISSING
+               radio: 'Radio Button', // MISSING
+               textField: 'Text Field', // MISSING
+               textarea: 'Textarea', // MISSING
+               hiddenField: 'Hidden Field', // MISSING
+               button: 'Button',
+               select: 'Selection Field', // MISSING
+               imageButton: 'Image Button', // MISSING
+               notSet: '<nije podešeno>',
+               id: 'Id',
+               name: 'Naziv',
+               langDir: 'Smjer pisanja',
+               langDirLtr: 'S lijeva na desno (LTR)',
+               langDirRtl: 'S desna na lijevo (RTL)',
+               langCode: 'Jezièni kôd',
+               longDescr: 'Dugaèki opis URL-a',
+               cssClass: 'Klase CSS stilova',
+               advisoryTitle: 'Advisory title',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Odustani',
+               close: 'Close', // MISSING
+               preview: 'Prikaži',
+               resize: 'Resize', // MISSING
+               generalTab: 'General', // MISSING
+               advancedTab: 'Naprednije',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Options', // MISSING
+               target: 'Prozor',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'S lijeva na desno (LTR)',
+               langDirRTL: 'S desna na lijevo (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Klase CSS stilova',
+               width: 'Širina',
+               height: 'Visina',
+               align: 'Poravnanje',
+               alignLeft: 'Lijevo',
+               alignRight: 'Desno',
+               alignCenter: 'Centar',
+               alignJustify: 'Puno poravnanje',
+               alignTop: 'Vrh',
+               alignMiddle: 'Sredina',
+               alignBottom: 'Dno',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ca.js b/sources/lang/ca.js
new file mode 100644 (file)
index 0000000..5ca9450
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Catalan language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ca' ] = {
+       // ARIA description.
+       editor: 'Editor de text enriquit',
+       editorPanel: 'Panell de l\'editor de text enriquit',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Premeu ALT 0 per ajuda',
+
+               browseServer: 'Veure servidor',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Puja',
+               uploadSubmit: 'Envia-la al servidor',
+               image: 'Imatge',
+               flash: 'Flash',
+               form: 'Formulari',
+               checkbox: 'Casella de verificació',
+               radio: 'Botó d\'opció',
+               textField: 'Camp de text',
+               textarea: 'Àrea de text',
+               hiddenField: 'Camp ocult',
+               button: 'Botó',
+               select: 'Camp de selecció',
+               imageButton: 'Botó d\'imatge',
+               notSet: '<no definit>',
+               id: 'Id',
+               name: 'Nom',
+               langDir: 'Direcció de l\'idioma',
+               langDirLtr: 'D\'esquerra a dreta (LTR)',
+               langDirRtl: 'De dreta a esquerra (RTL)',
+               langCode: 'Codi d\'idioma',
+               longDescr: 'Descripció llarga de la URL',
+               cssClass: 'Classes del full d\'estil',
+               advisoryTitle: 'Títol consultiu',
+               cssStyle: 'Estil',
+               ok: 'D\'acord',
+               cancel: 'Cancel·la',
+               close: 'Tanca',
+               preview: 'Previsualitza',
+               resize: 'Arrossegueu per redimensionar',
+               generalTab: 'General',
+               advancedTab: 'Avançat',
+               validateNumberFailed: 'Aquest valor no és un número.',
+               confirmNewPage: 'Els canvis en aquest contingut que no es desin es perdran. Esteu segur que voleu carregar una pàgina nova?',
+               confirmCancel: 'Algunes opcions s\'han canviat. Esteu segur que voleu tancar el quadre de diàleg?',
+               options: 'Opcions',
+               target: 'Destí',
+               targetNew: 'Nova finestra (_blank)',
+               targetTop: 'Finestra superior (_top)',
+               targetSelf: 'Mateixa finestra (_self)',
+               targetParent: 'Finestra pare (_parent)',
+               langDirLTR: 'D\'esquerra a dreta (LTR)',
+               langDirRTL: 'De dreta a esquerra (RTL)',
+               styles: 'Estil',
+               cssClasses: 'Classes del full d\'estil',
+               width: 'Amplada',
+               height: 'Alçada',
+               align: 'Alineació',
+               alignLeft: 'Ajusta a l\'esquerra',
+               alignRight: 'Ajusta a la dreta',
+               alignCenter: 'Centre',
+               alignJustify: 'Justificat',
+               alignTop: 'Superior',
+               alignMiddle: 'Centre',
+               alignBottom: 'Inferior',
+               alignNone: 'Cap',
+               invalidValue: 'Valor no vàlid.',
+               invalidHeight: 'L\'alçada ha de ser un número.',
+               invalidWidth: 'L\'amplada ha de ser un número.',
+               invalidCssLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
+               invalidHtmlLength: 'El valor especificat per als "%1" camps ha de ser un número positiu amb o sense unitat de mesura vàlida d\'HTML (px o %).',
+               invalidInlineStyle: 'El valor especificat per l\'estil en línia ha de constar d\'una o més tuples amb el format "name: value", separats per punt i coma.',
+               cssLengthTooltip: 'Introduïu un número per un valor en píxels o un número amb una unitat vàlida de CSS (px, %, in, cm, mm, em, ex, pt o pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, no disponible</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Retrocés',
+                       13: 'Intro',
+                       16: 'Majúscules',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Fi',
+                       36: 'Inici',
+                       46: 'Eliminar',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/cs.js b/sources/lang/cs.js
new file mode 100644 (file)
index 0000000..b76bee7
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Czech language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'cs' ] = {
+       // ARIA description.
+       editor: 'Textový editor',
+       editorPanel: 'Panel textového editoru',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Stiskněte ALT 0 pro nápovědu',
+
+               browseServer: 'Vybrat na serveru',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Odeslat',
+               uploadSubmit: 'Odeslat na server',
+               image: 'Obrázek',
+               flash: 'Flash',
+               form: 'Formulář',
+               checkbox: 'Zaškrtávací políčko',
+               radio: 'Přepínač',
+               textField: 'Textové pole',
+               textarea: 'Textová oblast',
+               hiddenField: 'Skryté pole',
+               button: 'Tlačítko',
+               select: 'Seznam',
+               imageButton: 'Obrázkové tlačítko',
+               notSet: '<nenastaveno>',
+               id: 'Id',
+               name: 'Jméno',
+               langDir: 'Směr jazyka',
+               langDirLtr: 'Zleva doprava (LTR)',
+               langDirRtl: 'Zprava doleva (RTL)',
+               langCode: 'Kód jazyka',
+               longDescr: 'Dlouhý popis URL',
+               cssClass: 'Třída stylu',
+               advisoryTitle: 'Pomocný titulek',
+               cssStyle: 'Styl',
+               ok: 'OK',
+               cancel: 'Zrušit',
+               close: 'Zavřít',
+               preview: 'Náhled',
+               resize: 'Uchopit pro změnu velikosti',
+               generalTab: 'Obecné',
+               advancedTab: 'Rozšířené',
+               validateNumberFailed: 'Zadaná hodnota není číselná.',
+               confirmNewPage: 'Jakékoliv neuložené změny obsahu budou ztraceny. Skutečně chcete otevřít novou stránku?',
+               confirmCancel: 'Některá z nastavení byla změněna. Skutečně chcete zavřít dialogové okno?',
+               options: 'Nastavení',
+               target: 'Cíl',
+               targetNew: 'Nové okno (_blank)',
+               targetTop: 'Okno nejvyšší úrovně (_top)',
+               targetSelf: 'Stejné okno (_self)',
+               targetParent: 'Rodičovské okno (_parent)',
+               langDirLTR: 'Zleva doprava (LTR)',
+               langDirRTL: 'Zprava doleva (RTL)',
+               styles: 'Styly',
+               cssClasses: 'Třídy stylů',
+               width: 'Šířka',
+               height: 'Výška',
+               align: 'Zarovnání',
+               alignLeft: 'Vlevo',
+               alignRight: 'Vpravo',
+               alignCenter: 'Na střed',
+               alignJustify: 'Zarovnat do bloku',
+               alignTop: 'Nahoru',
+               alignMiddle: 'Na střed',
+               alignBottom: 'Dolů',
+               alignNone: 'Žádné',
+               invalidValue: 'Neplatná hodnota.',
+               invalidHeight: 'Zadaná výška musí být číslo.',
+               invalidWidth: 'Šířka musí být číslo.',
+               invalidCssLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry CSS (px, %, in, cm, mm, em, ex, pt, nebo pc).',
+               invalidHtmlLength: 'Hodnota určená pro pole "%1" musí být kladné číslo bez nebo s platnou jednotkou míry HTML (px nebo %).',
+               invalidInlineStyle: 'Hodnota určená pro řádkový styl se musí skládat z jedné nebo více n-tic ve formátu "název : hodnota", oddělené středníky',
+               cssLengthTooltip: 'Zadejte číslo jako hodnotu v pixelech nebo číslo s platnou jednotkou CSS (px, %, v cm, mm, em, ex, pt, nebo pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nedostupné</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Konec',
+                       36: 'Domů',
+                       46: 'Smazat',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/cy.js b/sources/lang/cy.js
new file mode 100644 (file)
index 0000000..3f075aa
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Welsh language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'cy' ] = {
+       // ARIA description.
+       editor: 'Golygydd Testun Cyfoethog',
+       editorPanel: 'Panel Golygydd Testun Cyfoethog',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Gwasgwch ALT 0 am gymorth',
+
+               browseServer: 'Pori\'r Gweinydd',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Lanlwytho',
+               uploadSubmit: 'Anfon i\'r Gweinydd',
+               image: 'Delwedd',
+               flash: 'Flash',
+               form: 'Ffurflen',
+               checkbox: 'Blwch ticio',
+               radio: 'Botwm Radio',
+               textField: 'Maes Testun',
+               textarea: 'Ardal Testun',
+               hiddenField: 'Maes Cudd',
+               button: 'Botwm',
+               select: 'Maes Dewis',
+               imageButton: 'Botwm Delwedd',
+               notSet: '<heb osod>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Cyfeiriad Iaith',
+               langDirLtr: 'Chwith i\'r Dde (LTR)',
+               langDirRtl: 'Dde i\'r Chwith (RTL)',
+               langCode: 'Cod Iaith',
+               longDescr: 'URL Disgrifiad Hir',
+               cssClass: 'Dosbarthiadau Dalen Arddull',
+               advisoryTitle: 'Teitl Cynghorol',
+               cssStyle: 'Arddull',
+               ok: 'Iawn',
+               cancel: 'Diddymu',
+               close: 'Cau',
+               preview: 'Rhagolwg',
+               resize: 'Ailfeintio',
+               generalTab: 'Cyffredinol',
+               advancedTab: 'Uwch',
+               validateNumberFailed: '\'Dyw\'r gwerth hwn ddim yn rhif.',
+               confirmNewPage: 'Byddwch chi\'n colli unrhyw newidiadau i\'r cynnwys sydd heb eu cadw. Ydych am barhau i lwytho tudalen newydd?',
+               confirmCancel: 'Cafodd rhai o\'r opsiynau eu newid. Ydych chi wir am gau\'r deialog?',
+               options: 'Opsiynau',
+               target: 'Targed',
+               targetNew: 'Ffenest Newydd (_blank)',
+               targetTop: 'Ffenest ar y Brig (_top)',
+               targetSelf: 'Yr un Ffenest (_self)',
+               targetParent: 'Ffenest y Rhiant (_parent)',
+               langDirLTR: 'Chwith i\'r Dde (LTR)',
+               langDirRTL: 'Dde i\'r Chwith (RTL)',
+               styles: 'Arddull',
+               cssClasses: 'Dosbarthiadau Dalen Arddull',
+               width: 'Lled',
+               height: 'Uchder',
+               align: 'Alinio',
+               alignLeft: 'Chwith',
+               alignRight: 'Dde',
+               alignCenter: 'Canol',
+               alignJustify: 'Unioni',
+               alignTop: 'Brig',
+               alignMiddle: 'Canol',
+               alignBottom: 'Gwaelod',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Gwerth annilys.',
+               invalidHeight: 'Mae\'n rhaid i\'r uchder fod yn rhif.',
+               invalidWidth: 'Mae\'n rhaid i\'r lled fod yn rhif.',
+               invalidCssLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad CSS dilys (px, %, in, cm, mm, em, ex, pt, neu pc).',
+               invalidHtmlLength: 'Mae\'n rhaid i\'r gwerth ar gyfer maes "%1" fod yn rhif positif gyda neu heb uned fesuriad HTML dilys (px neu %).',
+               invalidInlineStyle: 'Mae\'n rhaid i\'r gwerth ar gyfer arddull mewn-llinell gynnwys un set neu fwy ar y fformat "enw : gwerth", wedi\'u gwahanu gyda hanner colon.',
+               cssLengthTooltip: 'Rhowch rif am werth mewn picsel neu rhif gydag uned CSS dilys (px, %, in, cm, mm, em, pt neu pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, ddim ar gael</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/da.js b/sources/lang/da.js
new file mode 100644 (file)
index 0000000..9b0a63d
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Danish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'da' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Tryk ALT 0 for hjælp',
+
+               browseServer: 'Gennemse...',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Upload',
+               uploadSubmit: 'Upload',
+               image: 'Indsæt billede',
+               flash: 'Indsæt Flash',
+               form: 'Indsæt formular',
+               checkbox: 'Indsæt afkrydsningsfelt',
+               radio: 'Indsæt alternativknap',
+               textField: 'Indsæt tekstfelt',
+               textarea: 'Indsæt tekstboks',
+               hiddenField: 'Indsæt skjult felt',
+               button: 'Indsæt knap',
+               select: 'Indsæt liste',
+               imageButton: 'Indsæt billedknap',
+               notSet: '<intet valgt>',
+               id: 'Id',
+               name: 'Navn',
+               langDir: 'Tekstretning',
+               langDirLtr: 'Fra venstre mod højre (LTR)',
+               langDirRtl: 'Fra højre mod venstre (RTL)',
+               langCode: 'Sprogkode',
+               longDescr: 'Udvidet beskrivelse',
+               cssClass: 'Typografiark (CSS)',
+               advisoryTitle: 'Titel',
+               cssStyle: 'Typografi (CSS)',
+               ok: 'OK',
+               cancel: 'Annullér',
+               close: 'Luk',
+               preview: 'Forhåndsvisning',
+               resize: 'Træk for at skalere',
+               generalTab: 'Generelt',
+               advancedTab: 'Avanceret',
+               validateNumberFailed: 'Værdien er ikke et tal.',
+               confirmNewPage: 'Alt indhold, der ikke er blevet gemt, vil gå tabt. Er du sikker på, at du vil indlæse en ny side?',
+               confirmCancel: 'Nogle af indstillingerne er blevet ændret. Er du sikker på, at du vil lukke vinduet?',
+               options: 'Vis muligheder',
+               target: 'Mål',
+               targetNew: 'Nyt vindue (_blank)',
+               targetTop: 'Øverste vindue (_top)',
+               targetSelf: 'Samme vindue (_self)',
+               targetParent: 'Samme vindue (_parent)',
+               langDirLTR: 'Venstre til højre (LTR)',
+               langDirRTL: 'Højre til venstre (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheetklasser',
+               width: 'Bredde',
+               height: 'Højde',
+               align: 'Justering',
+               alignLeft: 'Venstre',
+               alignRight: 'Højre',
+               alignCenter: 'Centreret',
+               alignJustify: 'Lige margener',
+               alignTop: 'Øverst',
+               alignMiddle: 'Centreret',
+               alignBottom: 'Nederst',
+               alignNone: 'Ingen',
+               invalidValue: 'Ugyldig værdi.',
+               invalidHeight: 'Højde skal være et tal.',
+               invalidWidth: 'Bredde skal være et tal.',
+               invalidCssLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px, %, in, cm, mm, em, ex, pt, eller pc).',
+               invalidHtmlLength: 'Værdien specificeret for "%1" feltet skal være et positivt nummer med eller uden en CSS måleenhed  (px eller %).',
+               invalidInlineStyle: 'Værdien specificeret for inline style skal indeholde en eller flere elementer med et format som "name:value", separeret af semikoloner',
+               cssLengthTooltip: 'Indsæt en numerisk værdi i pixel eller nummer med en gyldig CSS værdi (px, %, in, cm, mm, em, ex, pt, eller pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, ikke tilgængelig</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Retur',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Mellemrum',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Slet',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Tastatur genvej'
+       }
+};
diff --git a/sources/lang/de-ch.js b/sources/lang/de-ch.js
new file mode 100644 (file)
index 0000000..8f9c196
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+* @fileOverview
+*/
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'de-ch' ] = {
+       // ARIA description.
+       editor: 'WYSIWYG-Editor',
+       editorPanel: 'WYSIWYG-Editor-Leiste',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Drücken Sie ALT 0 für Hilfe',
+
+               browseServer: 'Server durchsuchen',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Hochladen',
+               uploadSubmit: 'Zum Server senden',
+               image: 'Bild',
+               flash: 'Flash',
+               form: 'Formular',
+               checkbox: 'Kontrollbox',
+               radio: 'Optionsfeld',
+               textField: 'Textfeld',
+               textarea: 'Textfeld',
+               hiddenField: 'Verstecktes Feld',
+               button: 'Schaltfläche',
+               select: 'Auswahlfeld',
+               imageButton: 'Bildschaltfläche',
+               notSet: '<nicht festgelegt>',
+               id: 'Kennung',
+               name: 'Name',
+               langDir: 'Schreibrichtung',
+               langDirLtr: 'Links nach Rechts (LTR)',
+               langDirRtl: 'Rechts nach Links (RTL)',
+               langCode: 'Sprachcode',
+               longDescr: 'Langbeschreibungs-URL',
+               cssClass: 'Formatvorlagenklassen',
+               advisoryTitle: 'Titel Beschreibung',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Abbrechen',
+               close: 'Schliessen',
+               preview: 'Vorschau',
+               resize: 'Grösse ändern',
+               generalTab: 'Allgemein',
+               advancedTab: 'Erweitert',
+               validateNumberFailed: 'Dieser Wert ist keine Nummer.',
+               confirmNewPage: 'Alle nicht gespeicherten Änderungen gehen verlohren. Sind Sie sicher die neue Seite zu laden?',
+               confirmCancel: 'Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schliessen?',
+               options: 'Optionen',
+               target: 'Zielseite',
+               targetNew: 'Neues Fenster (_blank)',
+               targetTop: 'Oberstes Fenster (_top)',
+               targetSelf: 'Gleiches Fenster (_self)',
+               targetParent: 'Oberes Fenster (_parent)',
+               langDirLTR: 'Links nach Rechts (LNR)',
+               langDirRTL: 'Rechts nach Links (RNL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Klasse',
+               width: 'Breite',
+               height: 'Höhe',
+               align: 'Ausrichtung',
+               alignLeft: 'Links',
+               alignRight: 'Rechts',
+               alignCenter: 'Zentriert',
+               alignJustify: 'Blocksatz',
+               alignTop: 'Oben',
+               alignMiddle: 'Mitte',
+               alignBottom: 'Unten',
+               alignNone: 'Keine',
+               invalidValue: 'Ungültiger Wert.',
+               invalidHeight: 'Höhe muss eine Zahl sein.',
+               invalidWidth: 'Breite muss eine Zahl sein.',
+               invalidCssLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
+               invalidHtmlLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte HTML Messeinheit (px oder %).',
+               invalidInlineStyle: 'Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Tupels mit dem Format "Name : Wert" getrennt mit Semikolons.',
+               cssLengthTooltip: 'Gebe eine Zahl ein für ein Wert in pixels oder eine Zahl mit einer korrekten CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nicht verfügbar</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Rücktaste',
+                       13: 'Eingabe',
+                       16: 'Umschalt',
+                       17: 'Strg',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Ende',
+                       36: 'Pos1',
+                       46: 'Entfernen',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/de.js b/sources/lang/de.js
new file mode 100644 (file)
index 0000000..cf1bc09
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * German language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'de' ] = {
+       // ARIA description.
+       editor: 'WYSIWYG-Editor',
+       editorPanel: 'WYSIWYG-Editor-Leiste',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Drücken Sie ALT 0 für Hilfe',
+
+               browseServer: 'Server durchsuchen',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Hochladen',
+               uploadSubmit: 'Zum Server senden',
+               image: 'Bild',
+               flash: 'Flash',
+               form: 'Formular',
+               checkbox: 'Kontrollbox',
+               radio: 'Optionsfeld',
+               textField: 'Textfeld',
+               textarea: 'Textfeld',
+               hiddenField: 'Verstecktes Feld',
+               button: 'Schaltfläche',
+               select: 'Auswahlfeld',
+               imageButton: 'Bildschaltfläche',
+               notSet: '<nicht festgelegt>',
+               id: 'Kennung',
+               name: 'Name',
+               langDir: 'Schreibrichtung',
+               langDirLtr: 'Links nach Rechts (LTR)',
+               langDirRtl: 'Rechts nach Links (RTL)',
+               langCode: 'Sprachcode',
+               longDescr: 'Langbeschreibungs-URL',
+               cssClass: 'Formatvorlagenklassen',
+               advisoryTitle: 'Titel Beschreibung',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Abbrechen',
+               close: 'Schließen',
+               preview: 'Vorschau',
+               resize: 'Größe ändern',
+               generalTab: 'Allgemein',
+               advancedTab: 'Erweitert',
+               validateNumberFailed: 'Dieser Wert ist keine Nummer.',
+               confirmNewPage: 'Alle nicht gespeicherten Änderungen gehen verlohren. Sind Sie sicher die neue Seite zu laden?',
+               confirmCancel: 'Einige Optionen wurden geändert. Wollen Sie den Dialog dennoch schließen?',
+               options: 'Optionen',
+               target: 'Zielseite',
+               targetNew: 'Neues Fenster (_blank)',
+               targetTop: 'Oberstes Fenster (_top)',
+               targetSelf: 'Gleiches Fenster (_self)',
+               targetParent: 'Oberes Fenster (_parent)',
+               langDirLTR: 'Links nach Rechts (LNR)',
+               langDirRTL: 'Rechts nach Links (RNL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Klasse',
+               width: 'Breite',
+               height: 'Höhe',
+               align: 'Ausrichtung',
+               alignLeft: 'Links',
+               alignRight: 'Rechts',
+               alignCenter: 'Zentriert',
+               alignJustify: 'Blocksatz',
+               alignTop: 'Oben',
+               alignMiddle: 'Mitte',
+               alignBottom: 'Unten',
+               alignNone: 'Keine',
+               invalidValue: 'Ungültiger Wert.',
+               invalidHeight: 'Höhe muss eine Zahl sein.',
+               invalidWidth: 'Breite muss eine Zahl sein.',
+               invalidCssLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
+               invalidHtmlLength: 'Wert spezifiziert für "%1" Feld muss ein positiver numerischer Wert sein mit oder ohne korrekte HTML Messeinheit (px oder %).',
+               invalidInlineStyle: 'Wert spezifiziert für inline Stilart muss enthalten ein oder mehr Tupels mit dem Format "Name : Wert" getrennt mit Semikolons.',
+               cssLengthTooltip: 'Gebe eine Zahl ein für ein Wert in pixels oder eine Zahl mit einer korrekten CSS Messeinheit (px, %, in, cm, mm, em, ex, pt oder pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nicht verfügbar</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Rücktaste',
+                       13: 'Eingabe',
+                       16: 'Umschalt',
+                       17: 'Strg',
+                       18: 'Alt',
+                       32: 'Leer',
+                       35: 'Ende',
+                       36: 'Pos1',
+                       46: 'Entfernen',
+                       224: 'Befehl'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Tastaturkürzel'
+       }
+};
diff --git a/sources/lang/el.js b/sources/lang/el.js
new file mode 100644 (file)
index 0000000..445c43d
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Greek language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'el' ] = {
+       // ARIA description.
+       editor: 'Επεξεργαστής Πλούσιου Κειμένου',
+       editorPanel: 'Πίνακας Επεξεργαστή Πλούσιου Κειμένου',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Πατήστε το ALT 0 για βοήθεια',
+
+               browseServer: 'Εξερεύνηση Διακομιστή',
+               url: 'URL',
+               protocol: 'Πρωτόκολλο',
+               upload: 'Αποστολή',
+               uploadSubmit: 'Αποστολή στον Διακομιστή',
+               image: 'Εικόνα',
+               flash: 'Flash',
+               form: 'Φόρμα',
+               checkbox: 'Κουτί Επιλογής',
+               radio: 'Κουμπί Επιλογής',
+               textField: 'Πεδίο Κειμένου',
+               textarea: 'Περιοχή Κειμένου',
+               hiddenField: 'Κρυφό Πεδίο',
+               button: 'Κουμπί',
+               select: 'Πεδίο Επιλογής',
+               imageButton: 'Κουμπί Εικόνας',
+               notSet: '<δεν έχει ρυθμιστεί>',
+               id: 'Id',
+               name: 'Όνομα',
+               langDir: 'Κατεύθυνση Κειμένου',
+               langDirLtr: 'Αριστερά προς Δεξιά (LTR)',
+               langDirRtl: 'Δεξιά προς Αριστερά (RTL)',
+               langCode: 'Κωδικός Γλώσσας',
+               longDescr: 'Αναλυτική Περιγραφή URL',
+               cssClass: 'Κλάσεις Φύλλων Στυλ',
+               advisoryTitle: 'Ενδεικτικός Τίτλος',
+               cssStyle: 'Μορφή Κειμένου',
+               ok: 'OK',
+               cancel: 'Ακύρωση',
+               close: 'Κλείσιμο',
+               preview: 'Προεπισκόπηση',
+               resize: 'Αλλαγή Μεγέθους',
+               generalTab: 'Γενικά',
+               advancedTab: 'Για Προχωρημένους',
+               validateNumberFailed: 'Αυτή η τιμή δεν είναι αριθμός.',
+               confirmNewPage: 'Οι όποιες αλλαγές στο περιεχόμενο θα χαθούν. Είσαστε σίγουροι ότι θέλετε να φορτώσετε μια νέα σελίδα;',
+               confirmCancel: 'Μερικές επιλογές έχουν αλλάξει. Είσαστε σίγουροι ότι θέλετε να κλείσετε το παράθυρο διαλόγου;',
+               options: 'Επιλογές',
+               target: 'Προορισμός',
+               targetNew: 'Νέο Παράθυρο (_blank)',
+               targetTop: 'Αρχική Περιοχή (_top)',
+               targetSelf: 'Ίδιο Παράθυρο (_self)',
+               targetParent: 'Γονεϊκό Παράθυρο (_parent)',
+               langDirLTR: 'Αριστερά προς Δεξιά (LTR)',
+               langDirRTL: 'Δεξιά προς Αριστερά (RTL)',
+               styles: 'Μορφή',
+               cssClasses: 'Κλάσεις Φύλλων Στυλ',
+               width: 'Πλάτος',
+               height: 'Ύψος',
+               align: 'Στοίχιση',
+               alignLeft: 'Αριστερά',
+               alignRight: 'Δεξιά',
+               alignCenter: 'Κέντρο',
+               alignJustify: 'Πλήρης Στοίχιση',
+               alignTop: 'Πάνω',
+               alignMiddle: 'Μέση',
+               alignBottom: 'Κάτω',
+               alignNone: 'Χωρίς',
+               invalidValue: 'Μη έγκυρη τιμή.',
+               invalidHeight: 'Το ύψος πρέπει να είναι ένας αριθμός.',
+               invalidWidth: 'Το πλάτος πρέπει να είναι ένας αριθμός.',
+               invalidCssLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
+               invalidHtmlLength: 'Η τιμή που ορίζεται για το πεδίο "%1" πρέπει να είναι ένας θετικός αριθμός με ή χωρίς μια έγκυρη μονάδα μέτρησης HTML (px ή %).',
+               invalidInlineStyle: 'Η τιμή για το εν σειρά στυλ πρέπει να περιέχει ένα ή περισσότερα ζεύγη με την μορφή "όνομα: τιμή" διαχωρισμένα με Ελληνικό ερωτηματικό.',
+               cssLengthTooltip: 'Εισάγεται μια τιμή σε pixel ή έναν αριθμό μαζί με μια έγκυρη μονάδα μέτρησης CSS (px, %, in, cm, mm, em, ex, pt, ή pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, δεν είναι διαθέσιμο</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/en-au.js b/sources/lang/en-au.js
new file mode 100644 (file)
index 0000000..4fc57f0
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * English (Australia) language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'en-au' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Browse Server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Upload',
+               uploadSubmit: 'Send it to the Server',
+               image: 'Image',
+               flash: 'Flash',
+               form: 'Form',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Hidden Field',
+               button: 'Button',
+               select: 'Selection Field',
+               imageButton: 'Image Button',
+               notSet: '<not set>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Language Direction',
+               langDirLtr: 'Left to Right (LTR)',
+               langDirRtl: 'Right to Left (RTL)',
+               langCode: 'Language Code',
+               longDescr: 'Long Description URL',
+               cssClass: 'Stylesheet Classes',
+               advisoryTitle: 'Advisory Title',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Cancel',
+               close: 'Close', // MISSING
+               preview: 'Preview',
+               resize: 'Resize', // MISSING
+               generalTab: 'General',
+               advancedTab: 'Advanced',
+               validateNumberFailed: 'This value is not a number.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
+               options: 'Options', // MISSING
+               target: 'Target',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'Left to Right (LTR)',
+               langDirRTL: 'Right to Left (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Width', // MISSING
+               height: 'Height', // MISSING
+               align: 'Align',
+               alignLeft: 'Left', // MISSING
+               alignRight: 'Right', // MISSING
+               alignCenter: 'Centre',
+               alignJustify: 'Justify',
+               alignTop: 'Top', // MISSING
+               alignMiddle: 'Middle', // MISSING
+               alignBottom: 'Bottom', // MISSING
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/en-ca.js b/sources/lang/en-ca.js
new file mode 100644 (file)
index 0000000..42d1aff
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * English (Canadian) language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'en-ca' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Browse Server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Upload',
+               uploadSubmit: 'Send it to the Server',
+               image: 'Image',
+               flash: 'Flash',
+               form: 'Form',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Hidden Field',
+               button: 'Button',
+               select: 'Selection Field',
+               imageButton: 'Image Button',
+               notSet: '<not set>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Language Direction',
+               langDirLtr: 'Left to Right (LTR)',
+               langDirRtl: 'Right to Left (RTL)',
+               langCode: 'Language Code',
+               longDescr: 'Long Description URL',
+               cssClass: 'Stylesheet Classes',
+               advisoryTitle: 'Advisory Title',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Cancel',
+               close: 'Close', // MISSING
+               preview: 'Preview',
+               resize: 'Resize', // MISSING
+               generalTab: 'General',
+               advancedTab: 'Advanced',
+               validateNumberFailed: 'This value is not a number.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
+               options: 'Options', // MISSING
+               target: 'Target',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'Left to Right (LTR)',
+               langDirRTL: 'Right to Left (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Width', // MISSING
+               height: 'Height', // MISSING
+               align: 'Align',
+               alignLeft: 'Left', // MISSING
+               alignRight: 'Right', // MISSING
+               alignCenter: 'Centre',
+               alignJustify: 'Justify',
+               alignTop: 'Top', // MISSING
+               alignMiddle: 'Middle', // MISSING
+               alignBottom: 'Bottom', // MISSING
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/en-gb.js b/sources/lang/en-gb.js
new file mode 100644 (file)
index 0000000..04cc61d
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * English (United Kingdom) language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'en-gb' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help',
+
+               browseServer: 'Browse Server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Upload',
+               uploadSubmit: 'Send it to the Server',
+               image: 'Image',
+               flash: 'Flash',
+               form: 'Form',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Hidden Field',
+               button: 'Button',
+               select: 'Selection Field',
+               imageButton: 'Image Button',
+               notSet: '<not set>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Language Direction',
+               langDirLtr: 'Left to Right (LTR)',
+               langDirRtl: 'Right to Left (RTL)',
+               langCode: 'Language Code',
+               longDescr: 'Long Description URL',
+               cssClass: 'Stylesheet Classes',
+               advisoryTitle: 'Advisory Title',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Cancel',
+               close: 'Close',
+               preview: 'Preview',
+               resize: 'Drag to resize',
+               generalTab: 'General',
+               advancedTab: 'Advanced',
+               validateNumberFailed: 'This value is not a number.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialogue window?',
+               options: 'Options',
+               target: 'Target',
+               targetNew: 'New Window (_blank)',
+               targetTop: 'Topmost Window (_top)',
+               targetSelf: 'Same Window (_self)',
+               targetParent: 'Parent Window (_parent)',
+               langDirLTR: 'Left to Right (LTR)',
+               langDirRTL: 'Right to Left (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Width',
+               height: 'Height',
+               align: 'Align',
+               alignLeft: 'Left',
+               alignRight: 'Right',
+               alignCenter: 'Centre',
+               alignJustify: 'Justify',
+               alignTop: 'Top',
+               alignMiddle: 'Middle',
+               alignBottom: 'Bottom',
+               alignNone: 'None',
+               invalidValue: 'Invalid value.',
+               invalidHeight: 'Height must be a number.',
+               invalidWidth: 'Width must be a number.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/en.js b/sources/lang/en.js
new file mode 100644 (file)
index 0000000..aa509fe
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the English
+ *             language. This is the base file for all translations.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'en' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help',
+
+               browseServer: 'Browse Server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Upload',
+               uploadSubmit: 'Send it to the Server',
+               image: 'Image',
+               flash: 'Flash',
+               form: 'Form',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Hidden Field',
+               button: 'Button',
+               select: 'Selection Field',
+               imageButton: 'Image Button',
+               notSet: '<not set>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Language Direction',
+               langDirLtr: 'Left to Right (LTR)',
+               langDirRtl: 'Right to Left (RTL)',
+               langCode: 'Language Code',
+               longDescr: 'Long Description URL',
+               cssClass: 'Stylesheet Classes',
+               advisoryTitle: 'Advisory Title',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Cancel',
+               close: 'Close',
+               preview: 'Preview',
+               resize: 'Resize',
+               generalTab: 'General',
+               advancedTab: 'Advanced',
+               validateNumberFailed: 'This value is not a number.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?',
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?',
+               options: 'Options',
+               target: 'Target',
+               targetNew: 'New Window (_blank)',
+               targetTop: 'Topmost Window (_top)',
+               targetSelf: 'Same Window (_self)',
+               targetParent: 'Parent Window (_parent)',
+               langDirLTR: 'Left to Right (LTR)',
+               langDirRTL: 'Right to Left (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Width',
+               height: 'Height',
+               align: 'Alignment',
+               alignLeft: 'Left',
+               alignRight: 'Right',
+               alignCenter: 'Center',
+               alignJustify: 'Justify',
+               alignTop: 'Top',
+               alignMiddle: 'Middle',
+               alignBottom: 'Bottom',
+               alignNone: 'None',
+               invalidValue: 'Invalid value.',
+               invalidHeight: 'Height must be a number.',
+               invalidWidth: 'Width must be a number.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).',
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.',
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut'
+       }
+};
diff --git a/sources/lang/eo.js b/sources/lang/eo.js
new file mode 100644 (file)
index 0000000..f270dfc
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Esperanto language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'eo' ] = {
+       // ARIA description.
+       editor: 'RiĉTeksta Redaktilo',
+       editorPanel: 'Panelo de la RiĉTeksta Redaktilo',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Premu ALT 0 por helpilo',
+
+               browseServer: 'Foliumi en la Servilo',
+               url: 'URL',
+               protocol: 'Protokolo',
+               upload: 'Alŝuti',
+               uploadSubmit: 'Sendu al Servilo',
+               image: 'Bildo',
+               flash: 'Flaŝo',
+               form: 'Formularo',
+               checkbox: 'Markobutono',
+               radio: 'Radiobutono',
+               textField: 'Teksta kampo',
+               textarea: 'Teksta Areo',
+               hiddenField: 'Kaŝita Kampo',
+               button: 'Butono',
+               select: 'Elekta Kampo',
+               imageButton: 'Bildbutono',
+               notSet: '<Defaŭlta>',
+               id: 'Id',
+               name: 'Nomo',
+               langDir: 'Skribdirekto',
+               langDirLtr: 'De maldekstro dekstren (LTR)',
+               langDirRtl: 'De dekstro maldekstren (RTL)',
+               langCode: 'Lingva Kodo',
+               longDescr: 'URL de Longa Priskribo',
+               cssClass: 'Klasoj de Stilfolioj',
+               advisoryTitle: 'Priskriba Titolo',
+               cssStyle: 'Stilo',
+               ok: 'Akcepti',
+               cancel: 'Rezigni',
+               close: 'Fermi',
+               preview: 'Vidigi Aspekton',
+               resize: 'Movigi por ŝanĝi la grandon',
+               generalTab: 'Ĝenerala',
+               advancedTab: 'Speciala',
+               validateNumberFailed: 'Tiu valoro ne estas nombro.',
+               confirmNewPage: 'La neregistritaj ŝanĝoj estas perdotaj. Ĉu vi certas, ke vi volas ŝargi novan paĝon?',
+               confirmCancel: 'Iuj opcioj esta ŝanĝitaj. Ĉu vi certas, ke vi volas fermi la dialogon?',
+               options: 'Opcioj',
+               target: 'Celo',
+               targetNew: 'Nova Fenestro (_blank)',
+               targetTop: 'Supra Fenestro (_top)',
+               targetSelf: 'Sama Fenestro (_self)',
+               targetParent: 'Patra Fenestro (_parent)',
+               langDirLTR: 'De maldekstro dekstren (LTR)',
+               langDirRTL: 'De dekstro maldekstren (RTL)',
+               styles: 'Stilo',
+               cssClasses: 'Stilfoliaj Klasoj',
+               width: 'Larĝo',
+               height: 'Alto',
+               align: 'Ĝisrandigo',
+               alignLeft: 'Maldekstre',
+               alignRight: 'Dekstre',
+               alignCenter: 'Centre',
+               alignJustify: 'Ĝisrandigi Ambaŭflanke',
+               alignTop: 'Supre',
+               alignMiddle: 'Centre',
+               alignBottom: 'Malsupre',
+               alignNone: 'Neniu',
+               invalidValue: 'Nevalida Valoro',
+               invalidHeight: 'Alto devas esti nombro.',
+               invalidWidth: 'Larĝo devas esti nombro.',
+               invalidCssLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida CSSmezurunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'La valoro indikita por la "%1" kampo devas esti pozitiva nombro kun aŭ sen valida HTMLmezurunuo (px or %).',
+               invalidInlineStyle: 'La valoro indikita por la enlinia stilo devas konsisti el unu aŭ pluraj elementoj kun la formato de "nomo : valoro", apartigitaj per punktokomoj.',
+               cssLengthTooltip: 'Entajpu nombron por rastrumera valoro aŭ nombron kun valida CSSunuo (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nehavebla</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Retropaŝo',
+                       13: 'Enigi',
+                       16: 'Registrumo',
+                       17: 'Stirklavo',
+                       18: 'Alt-klavo',
+                       32: 'Space', // MISSING
+                       35: 'Fino',
+                       36: 'Hejmo',
+                       46: 'Forigi',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/es.js b/sources/lang/es.js
new file mode 100644 (file)
index 0000000..40d9ae0
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Spanish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'es' ] = {
+       // ARIA description.
+       editor: 'Editor de texto enriquecido',
+       editorPanel: 'Panel del Editor de Texto Enriquecido',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Pulse ALT 0 para ayuda',
+
+               browseServer: 'Ver Servidor',
+               url: 'URL',
+               protocol: 'Protocolo',
+               upload: 'Cargar',
+               uploadSubmit: 'Enviar al Servidor',
+               image: 'Imagen',
+               flash: 'Flash',
+               form: 'Formulario',
+               checkbox: 'Casilla de Verificación',
+               radio: 'Botones de Radio',
+               textField: 'Campo de Texto',
+               textarea: 'Area de Texto',
+               hiddenField: 'Campo Oculto',
+               button: 'Botón',
+               select: 'Campo de Selección',
+               imageButton: 'Botón Imagen',
+               notSet: '<No definido>',
+               id: 'Id',
+               name: 'Nombre',
+               langDir: 'Orientación',
+               langDirLtr: 'Izquierda a Derecha (LTR)',
+               langDirRtl: 'Derecha a Izquierda (RTL)',
+               langCode: 'Cód. de idioma',
+               longDescr: 'Descripción larga URL',
+               cssClass: 'Clases de hojas de estilo',
+               advisoryTitle: 'Título',
+               cssStyle: 'Estilo',
+               ok: 'Aceptar',
+               cancel: 'Cancelar',
+               close: 'Cerrar',
+               preview: 'Previsualización',
+               resize: 'Arrastre para redimensionar',
+               generalTab: 'General',
+               advancedTab: 'Avanzado',
+               validateNumberFailed: 'El valor no es un número.',
+               confirmNewPage: 'Cualquier cambio que no se haya guardado se perderá.\r\n¿Está seguro de querer crear una nueva página?',
+               confirmCancel: 'Algunas de las opciones se han cambiado.\r\n¿Está seguro de querer cerrar el diálogo?',
+               options: 'Opciones',
+               target: 'Destino',
+               targetNew: 'Nueva ventana (_blank)',
+               targetTop: 'Ventana principal (_top)',
+               targetSelf: 'Misma ventana (_self)',
+               targetParent: 'Ventana padre (_parent)',
+               langDirLTR: 'Izquierda a derecha (LTR)',
+               langDirRTL: 'Derecha a izquierda (RTL)',
+               styles: 'Estilos',
+               cssClasses: 'Clase de la hoja de estilos',
+               width: 'Anchura',
+               height: 'Altura',
+               align: 'Alineación',
+               alignLeft: 'Izquierda',
+               alignRight: 'Derecha',
+               alignCenter: 'Centrado',
+               alignJustify: 'Justificado',
+               alignTop: 'Tope',
+               alignMiddle: 'Centro',
+               alignBottom: 'Pie',
+               alignNone: 'Ninguno',
+               invalidValue: 'Valor no válido',
+               invalidHeight: 'Altura debe ser un número.',
+               invalidWidth: 'Anchura debe ser un número.',
+               invalidCssLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
+               invalidHtmlLength: 'El valor especificado para el campo "%1" debe ser un número positivo, incluyendo optionalmente una unidad de medida HTML válida (px o %).',
+               invalidInlineStyle: 'El valor especificado para el estilo debe consistir en uno o más pares con el formato "nombre: valor", separados por punto y coma.',
+               cssLengthTooltip: 'Introduca un número para el valor en pixels o un número con una unidad de medida CSS válida (px, %, in, cm, mm, em, ex, pt, o pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, no disponible</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Retroceso',
+                       13: 'Ingresar',
+                       16: 'Mayús.',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Fin',
+                       36: 'Inicio',
+                       46: 'Suprimir',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/et.js b/sources/lang/et.js
new file mode 100644 (file)
index 0000000..c98ea81
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Estonian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'et' ] = {
+       // ARIA description.
+       editor: 'Rikkalik tekstiredaktor',
+       editorPanel: 'Rikkaliku tekstiredaktori paneel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Abi saamiseks vajuta ALT 0',
+
+               browseServer: 'Serveri sirvimine',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Laadi üles',
+               uploadSubmit: 'Saada serverisse',
+               image: 'Pilt',
+               flash: 'Flash',
+               form: 'Vorm',
+               checkbox: 'Märkeruut',
+               radio: 'Raadionupp',
+               textField: 'Tekstilahter',
+               textarea: 'Tekstiala',
+               hiddenField: 'Varjatud lahter',
+               button: 'Nupp',
+               select: 'Valiklahter',
+               imageButton: 'Piltnupp',
+               notSet: '<määramata>',
+               id: 'ID',
+               name: 'Nimi',
+               langDir: 'Keele suund',
+               langDirLtr: 'Vasakult paremale (LTR)',
+               langDirRtl: 'Paremalt vasakule (RTL)',
+               langCode: 'Keele kood',
+               longDescr: 'Pikk kirjeldus URL',
+               cssClass: 'Stiilistiku klassid',
+               advisoryTitle: 'Soovituslik pealkiri',
+               cssStyle: 'Laad',
+               ok: 'Olgu',
+               cancel: 'Loobu',
+               close: 'Sulge',
+               preview: 'Eelvaade',
+               resize: 'Suuruse muutmiseks lohista',
+               generalTab: 'Üldine',
+               advancedTab: 'Täpsemalt',
+               validateNumberFailed: 'See väärtus pole number.',
+               confirmNewPage: 'Kõik salvestamata muudatused lähevad kaotsi. Kas oled kindel, et tahad laadida uue lehe?',
+               confirmCancel: 'Mõned valikud on muudetud. Kas oled kindel, et tahad dialoogi sulgeda?',
+               options: 'Valikud',
+               target: 'Sihtkoht',
+               targetNew: 'Uus aken (_blank)',
+               targetTop: 'Kõige ülemine aken (_top)',
+               targetSelf: 'Sama aken (_self)',
+               targetParent: 'Vanemaken (_parent)',
+               langDirLTR: 'Vasakult paremale (LTR)',
+               langDirRTL: 'Paremalt vasakule (RTL)',
+               styles: 'Stiili',
+               cssClasses: 'Stiililehe klassid',
+               width: 'Laius',
+               height: 'Kõrgus',
+               align: 'Joondus',
+               alignLeft: 'Vasak',
+               alignRight: 'Paremale',
+               alignCenter: 'Kesk',
+               alignJustify: 'Rööpjoondus',
+               alignTop: 'Üles',
+               alignMiddle: 'Keskele',
+               alignBottom: 'Alla',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Vigane väärtus.',
+               invalidHeight: 'Kõrgus peab olema number.',
+               invalidWidth: 'Laius peab olema number.',
+               invalidCssLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv CSS ühikuga (px, %, in, cm, mm, em, ex, pt või pc) või ilma.',
+               invalidHtmlLength: '"%1" välja jaoks määratud väärtus peab olema positiivne täisarv HTML ühikuga (px või %) või ilma.',
+               invalidInlineStyle: 'Reasisese stiili määrangud peavad koosnema paarisväärtustest (tuples), mis on semikoolonitega eraldatult järgnevas vormingus: "nimi : väärtus".',
+               cssLengthTooltip: 'Sisesta väärtus pikslites või number koos sobiva CSS-i ühikuga (px, %, in, cm, mm, em, ex, pt või pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, pole saadaval</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/eu.js b/sources/lang/eu.js
new file mode 100644 (file)
index 0000000..98b92ef
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Basque language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'eu' ] = {
+       // ARIA description.
+       editor: 'Testu aberastuaren editorea',
+       editorPanel: 'Testu aberastuaren editorearen panela',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Sakatu ALT 0 laguntza jasotzeko',
+
+               browseServer: 'Arakatu zerbitzaria',
+               url: 'URLa',
+               protocol: 'Protokoloa',
+               upload: 'Kargatu',
+               uploadSubmit: 'Bidali zerbitzarira',
+               image: 'Irudia',
+               flash: 'Flash',
+               form: 'Formularioa',
+               checkbox: 'Kontrol-laukia',
+               radio: 'Aukera-botoia',
+               textField: 'Testu-eremua',
+               textarea: 'Testu-area',
+               hiddenField: 'Ezkutuko eremua',
+               button: 'Botoia',
+               select: 'Hautespen-eremua',
+               imageButton: 'Irudi-botoia',
+               notSet: '<ezarri gabe>',
+               id: 'Id',
+               name: 'Izena',
+               langDir: 'Hizkuntzaren norabidea',
+               langDirLtr: 'Ezkerretik eskuinera (LTR)',
+               langDirRtl: 'Eskuinetik ezkerrera (RTL)',
+               langCode: 'Hizkuntzaren kodea',
+               longDescr: 'URLaren deskribapen luzea',
+               cssClass: 'Estilo-orriko klaseak',
+               advisoryTitle: 'Aholkatutako izenburua',
+               cssStyle: 'Estiloa',
+               ok: 'Ados',
+               cancel: 'Utzi',
+               close: 'Itxi',
+               preview: 'Aurrebista',
+               resize: 'Aldatu tamainaz',
+               generalTab: 'Orokorra',
+               advancedTab: 'Aurreratua',
+               validateNumberFailed: 'Balio hau ez da zenbaki bat.',
+               confirmNewPage: 'Eduki honetan gorde gabe dauden aldaketak galduko dira. Ziur zaude orri berri bat kargatu nahi duzula?',
+               confirmCancel: 'Aukera batzuk aldatu dituzu. Ziur zaude elkarrizketa-koadroa itxi nahi duzula?',
+               options: 'Aukerak',
+               target: 'Helburua',
+               targetNew: 'Leiho berria (_blank)',
+               targetTop: 'Goieneko leihoan (_top)',
+               targetSelf: 'Leiho berean (_self)',
+               targetParent: 'Leiho gurasoan (_parent)',
+               langDirLTR: 'Ezkerretik eskuinera (LTR)',
+               langDirRTL: 'Eskuinetik ezkerrera (RTL)',
+               styles: 'Estiloa',
+               cssClasses: 'Estilo-orriko klaseak',
+               width: 'Zabalera',
+               height: 'Altuera',
+               align: 'Lerrokatzea',
+               alignLeft: 'Ezkerrean',
+               alignRight: 'Eskuinean',
+               alignCenter: 'Erdian',
+               alignJustify: 'Justifikatu',
+               alignTop: 'Goian',
+               alignMiddle: 'Erdian',
+               alignBottom: 'Behean',
+               alignNone: 'Bat ere ez',
+               invalidValue: 'Balio desegokia.',
+               invalidHeight: 'Altuera zenbaki bat izan behar da.',
+               invalidWidth: 'Zabalera zenbaki bat izan behar da.',
+               invalidCssLength: '"%1" eremurako zehaztutako balioak zenbaki positibo bat izan behar du, CSS neurri unitate batekin edo gabe (px, %, in, cm, mm, em, ex, pt edo pc).',
+               invalidHtmlLength: '"%1" eremurako zehaztutako balioak zenbaki positibo bat izan behar du, HTML neurri unitate batekin edo gabe (px edo %).',
+               invalidInlineStyle: 'Lineako estiloan zehaztutako balioak "izen : balio" formatuko tupla bat edo gehiago izan behar dira, komaz bereiztuak.',
+               cssLengthTooltip: 'Sartu zenbaki bat edo zenbaki bat baliozko CSS unitate batekin (px, %, in, cm, mm, em, ex, pt, edo pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, erabilezina</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Sartu',
+                       16: 'Maius',
+                       17: 'Ktrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Buka',
+                       36: 'Etxea',
+                       46: 'Ezabatu',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/fa.js b/sources/lang/fa.js
new file mode 100644 (file)
index 0000000..3540510
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Persian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'fa' ] = {
+       // ARIA description.
+       editor: 'ویرایش‌گر متن غنی',
+       editorPanel: 'پنل ویرایشگر متن غنی',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'کلید Alt+0 را برای راهنمایی بفشارید',
+
+               browseServer: 'فهرست​نمایی سرور',
+               url: 'URL',
+               protocol: 'قرارداد',
+               upload: 'بالاگذاری',
+               uploadSubmit: 'به سرور بفرست',
+               image: 'تصویر',
+               flash: 'فلش',
+               form: 'فرم',
+               checkbox: 'چک‌باکس',
+               radio: 'دکمه‌ی رادیویی',
+               textField: 'فیلد متنی',
+               textarea: 'ناحیهٴ متنی',
+               hiddenField: 'فیلد پنهان',
+               button: 'دکمه',
+               select: 'فیلد انتخاب چند گزینه​ای',
+               imageButton: 'دکمه‌ی تصویری',
+               notSet: '<تعیین‌نشده>',
+               id: 'شناسه',
+               name: 'نام',
+               langDir: 'جهت زبان',
+               langDirLtr: 'چپ به راست',
+               langDirRtl: 'راست به چپ',
+               langCode: 'کد زبان',
+               longDescr: 'URL توصیف طولانی',
+               cssClass: 'کلاس​های شیوه​نامه (Stylesheet)',
+               advisoryTitle: 'عنوان کمکی',
+               cssStyle: 'سبک',
+               ok: 'پذیرش',
+               cancel: 'انصراف',
+               close: 'بستن',
+               preview: 'پیش‌نمایش',
+               resize: 'تغییر اندازه',
+               generalTab: 'عمومی',
+               advancedTab: 'پیش‌رفته',
+               validateNumberFailed: 'این مقدار یک عدد نیست.',
+               confirmNewPage: 'هر تغییر ایجاد شده​ی ذخیره نشده از بین خواهد رفت. آیا اطمینان دارید که قصد بارگیری صفحه جدیدی را دارید؟',
+               confirmCancel: 'برخی از گزینه‌ها تغییر کرده‌اند. آیا واقعا قصد بستن این پنجره را دارید؟',
+               options: 'گزینه​ها',
+               target: 'مقصد',
+               targetNew: 'پنجره جدید',
+               targetTop: 'بالاترین پنجره',
+               targetSelf: 'همان پنجره',
+               targetParent: 'پنجره والد',
+               langDirLTR: 'چپ به راست',
+               langDirRTL: 'راست به چپ',
+               styles: 'سبک',
+               cssClasses: 'کلاس‌های سبک‌نامه',
+               width: 'عرض',
+               height: 'طول',
+               align: 'چینش',
+               alignLeft: 'چپ',
+               alignRight: 'راست',
+               alignCenter: 'وسط',
+               alignJustify: 'بلوک چین',
+               alignTop: 'بالا',
+               alignMiddle: 'میانه',
+               alignBottom: 'پائین',
+               alignNone: 'هیچ',
+               invalidValue: 'مقدار نامعتبر.',
+               invalidHeight: 'ارتفاع باید یک عدد باشد.',
+               invalidWidth: 'عرض باید یک عدد باشد.',
+               invalidCssLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری CSS معتبر باشد (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'عدد تعیین شده برای فیلد "%1" باید یک عدد مثبت با یا بدون یک واحد اندازه گیری HTML معتبر باشد (px or %).',
+               invalidInlineStyle: 'عدد تعیین شده برای سبک درون​خطی -Inline Style- باید دارای یک یا چند چندتایی با شکلی شبیه "name : value" که باید با یک ";" از هم جدا شوند.',
+               cssLengthTooltip: 'یک عدد برای یک مقدار بر حسب پیکسل و یا یک عدد با یک واحد CSS معتبر وارد کنید (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">، غیر قابل دسترس</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'عقبگرد',
+                       13: 'ورود',
+                       16: 'تعویض',
+                       17: 'کنترل',
+                       18: 'دگرساز',
+                       32: 'Space', // MISSING
+                       35: 'پایان',
+                       36: 'خانه',
+                       46: 'حذف',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/fi.js b/sources/lang/fi.js
new file mode 100644 (file)
index 0000000..d10adab
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Finnish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'fi' ] = {
+       // ARIA description.
+       editor: 'Rikastekstieditori',
+       editorPanel: 'Rikastekstieditoripaneeli',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Paina ALT 0 nähdäksesi ohjeen',
+
+               browseServer: 'Selaa palvelinta',
+               url: 'Osoite',
+               protocol: 'Protokolla',
+               upload: 'Lisää tiedosto',
+               uploadSubmit: 'Lähetä palvelimelle',
+               image: 'Kuva',
+               flash: 'Flash-animaatio',
+               form: 'Lomake',
+               checkbox: 'Valintaruutu',
+               radio: 'Radiopainike',
+               textField: 'Tekstikenttä',
+               textarea: 'Tekstilaatikko',
+               hiddenField: 'Piilokenttä',
+               button: 'Painike',
+               select: 'Valintakenttä',
+               imageButton: 'Kuvapainike',
+               notSet: '<ei asetettu>',
+               id: 'Tunniste',
+               name: 'Nimi',
+               langDir: 'Kielen suunta',
+               langDirLtr: 'Vasemmalta oikealle (LTR)',
+               langDirRtl: 'Oikealta vasemmalle (RTL)',
+               langCode: 'Kielikoodi',
+               longDescr: 'Pitkän kuvauksen URL',
+               cssClass: 'Tyyliluokat',
+               advisoryTitle: 'Avustava otsikko',
+               cssStyle: 'Tyyli',
+               ok: 'OK',
+               cancel: 'Peruuta',
+               close: 'Sulje',
+               preview: 'Esikatselu',
+               resize: 'Raahaa muuttaaksesi kokoa',
+               generalTab: 'Yleinen',
+               advancedTab: 'Lisäominaisuudet',
+               validateNumberFailed: 'Arvon pitää olla numero.',
+               confirmNewPage: 'Kaikki tallentamattomat muutokset tähän sisältöön menetetään. Oletko varma, että haluat ladata uuden sivun?',
+               confirmCancel: 'Jotkut asetuksista on muuttuneet. Oletko varma, että haluat sulkea valintaikkunan?',
+               options: 'Asetukset',
+               target: 'Kohde',
+               targetNew: 'Uusi ikkuna (_blank)',
+               targetTop: 'Päällimmäinen ikkuna (_top)',
+               targetSelf: 'Sama ikkuna (_self)',
+               targetParent: 'Ylemmän tason ikkuna (_parent)',
+               langDirLTR: 'Vasemmalta oikealle (LTR)',
+               langDirRTL: 'Oikealta vasemmalle (RTL)',
+               styles: 'Tyyli',
+               cssClasses: 'Tyylitiedoston luokat',
+               width: 'Leveys',
+               height: 'Korkeus',
+               align: 'Kohdistus',
+               alignLeft: 'Vasemmalle',
+               alignRight: 'Oikealle',
+               alignCenter: 'Keskelle',
+               alignJustify: 'Tasaa molemmat reunat',
+               alignTop: 'Ylös',
+               alignMiddle: 'Keskelle',
+               alignBottom: 'Alas',
+               alignNone: 'Ei asetettu',
+               invalidValue: 'Virheellinen arvo.',
+               invalidHeight: 'Korkeuden täytyy olla numero.',
+               invalidWidth: 'Leveyden täytyy olla numero.',
+               invalidCssLength: 'Kentän "%1" arvon täytyy olla positiivinen luku CSS mittayksikön (px, %, in, cm, mm, em, ex, pt tai pc) kanssa tai ilman.',
+               invalidHtmlLength: 'Kentän "%1" arvon täytyy olla positiivinen luku HTML mittayksikön (px tai %) kanssa tai ilman.',
+               invalidInlineStyle: 'Tyylille annetun arvon täytyy koostua yhdestä tai useammasta "nimi : arvo" parista, jotka ovat eroteltuna toisistaan puolipisteillä.',
+               cssLengthTooltip: 'Anna numeroarvo pikseleinä tai numeroarvo CSS mittayksikön kanssa (px, %, in, cm, mm, em, ex, pt, tai pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, ei saatavissa</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/fo.js b/sources/lang/fo.js
new file mode 100644 (file)
index 0000000..205b20f
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Faroese language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'fo' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Trýst ALT og 0 fyri vegleiðing',
+
+               browseServer: 'Ambætarakagi',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Send til ambætaran',
+               uploadSubmit: 'Send til ambætaran',
+               image: 'Myndir',
+               flash: 'Flash',
+               form: 'Formur',
+               checkbox: 'Flugubein',
+               radio: 'Radioknøttur',
+               textField: 'Tekstteigur',
+               textarea: 'Tekstumráði',
+               hiddenField: 'Fjaldur teigur',
+               button: 'Knøttur',
+               select: 'Valskrá',
+               imageButton: 'Myndaknøttur',
+               notSet: '<ikki sett>',
+               id: 'Id',
+               name: 'Navn',
+               langDir: 'Tekstkós',
+               langDirLtr: 'Frá vinstru til høgru (LTR)',
+               langDirRtl: 'Frá høgru til vinstru (RTL)',
+               langCode: 'Málkoda',
+               longDescr: 'Víðkað URL frágreiðing',
+               cssClass: 'Typografi klassar',
+               advisoryTitle: 'Vegleiðandi heiti',
+               cssStyle: 'Typografi',
+               ok: 'Góðkent',
+               cancel: 'Avlýs',
+               close: 'Lat aftur',
+               preview: 'Frumsýn',
+               resize: 'Drag fyri at broyta stødd',
+               generalTab: 'Generelt',
+               advancedTab: 'Fjølbroytt',
+               validateNumberFailed: 'Hetta er ikki eitt tal.',
+               confirmNewPage: 'Allar ikki goymdar broytingar í hesum innihaldið hvørva. Skal nýggj síða lesast kortini?',
+               confirmCancel: 'Nakrir valmøguleikar eru broyttir. Ert tú vísur í, at dialogurin skal latast aftur?',
+               options: 'Options',
+               target: 'Target',
+               targetNew: 'Nýtt vindeyga (_blank)',
+               targetTop: 'Vindeyga ovast (_top)',
+               targetSelf: 'Sama vindeyga (_self)',
+               targetParent: 'Upphavligt vindeyga (_parent)',
+               langDirLTR: 'Frá vinstru til høgru (LTR)',
+               langDirRTL: 'Frá høgru til vinstru (RTL)',
+               styles: 'Style',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Breidd',
+               height: 'Hædd',
+               align: 'Justering',
+               alignLeft: 'Vinstra',
+               alignRight: 'Høgra',
+               alignCenter: 'Miðsett',
+               alignJustify: 'Javnir tekstkantar',
+               alignTop: 'Ovast',
+               alignMiddle: 'Miðja',
+               alignBottom: 'Botnur',
+               alignNone: 'Eingin',
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Hædd má vera eitt tal.',
+               invalidWidth: 'Breidd má vera eitt tal.',
+               invalidCssLength: 'Virðið sett í "%1" feltið má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px, %, in, cm, mm, em, ex, pt, ella pc).',
+               invalidHtmlLength: 'Virðið sett í "%1" feltiðield má vera eitt positivt tal, við ella uttan gyldugum CSS mátieind (px ella %).',
+               invalidInlineStyle: 'Virði specifiserað fyri inline style má hava eitt ella fleiri pør (tuples) skrivað sum "name : value", hvørt parið sundurskilt við semi-colon.',
+               cssLengthTooltip: 'Skriva eitt tal fyri eitt virði í pixels ella eitt tal við gyldigum CSS eind (px, %, in, cm, mm, em, ex, pt, ella pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, ikki tøkt</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/fr-ca.js b/sources/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..2702f0c
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Canadian French language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'fr-ca' ] = {
+       // ARIA description.
+       editor: 'Éditeur de texte enrichi',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Appuyez sur 0 pour de l\'aide',
+
+               browseServer: 'Parcourir le serveur',
+               url: 'URL',
+               protocol: 'Protocole',
+               upload: 'Envoyer',
+               uploadSubmit: 'Envoyer au serveur',
+               image: 'Image',
+               flash: 'Animation Flash',
+               form: 'Formulaire',
+               checkbox: 'Case à cocher',
+               radio: 'Bouton radio',
+               textField: 'Champ texte',
+               textarea: 'Zone de texte',
+               hiddenField: 'Champ caché',
+               button: 'Bouton',
+               select: 'Liste déroulante',
+               imageButton: 'Bouton image',
+               notSet: '<Par défaut>',
+               id: 'Id',
+               name: 'Nom',
+               langDir: 'Sens d\'écriture',
+               langDirLtr: 'De gauche à droite (LTR)',
+               langDirRtl: 'De droite à gauche (RTL)',
+               langCode: 'Code langue',
+               longDescr: 'URL de description longue',
+               cssClass: 'Classes CSS',
+               advisoryTitle: 'Titre',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Annuler',
+               close: 'Fermer',
+               preview: 'Aperçu',
+               resize: 'Redimensionner',
+               generalTab: 'Général',
+               advancedTab: 'Avancé',
+               validateNumberFailed: 'Cette valeur n\'est pas un nombre.',
+               confirmNewPage: 'Les changements non sauvegardés seront perdus. Êtes-vous certain de vouloir charger une nouvelle page?',
+               confirmCancel: 'Certaines options ont été modifiées.  Êtes-vous certain de vouloir fermer?',
+               options: 'Options',
+               target: 'Cible',
+               targetNew: 'Nouvelle fenêtre (_blank)',
+               targetTop: 'Fenêtre supérieur (_top)',
+               targetSelf: 'Cette fenêtre (_self)',
+               targetParent: 'Fenêtre parent (_parent)',
+               langDirLTR: 'De gauche à droite (LTR)',
+               langDirRTL: 'De droite à gauche (RTL)',
+               styles: 'Style',
+               cssClasses: 'Classe CSS',
+               width: 'Largeur',
+               height: 'Hauteur',
+               align: 'Alignement',
+               alignLeft: 'Gauche',
+               alignRight: 'Droite',
+               alignCenter: 'Centré',
+               alignJustify: 'Justifié',
+               alignTop: 'Haut',
+               alignMiddle: 'Milieu',
+               alignBottom: 'Bas',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Valeur invalide.',
+               invalidHeight: 'La hauteur doit être un nombre.',
+               invalidWidth: 'La largeur doit être un nombre.',
+               invalidCssLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
+               invalidHtmlLength: 'La valeur spécifiée pour le champ "%1" doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).',
+               invalidInlineStyle: 'La valeur spécifiée pour le style intégré doit être composée d\'un ou plusieurs couples de valeur au format "nom : valeur", separés par des points-virgules.',
+               cssLengthTooltip: 'Entrer un nombre pour la valeur en pixel ou un nombre avec une unité CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, indisponible</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/fr.js b/sources/lang/fr.js
new file mode 100644 (file)
index 0000000..95b2d41
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * French language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'fr' ] = {
+       // ARIA description.
+       editor: 'Éditeur de texte enrichi',
+       editorPanel: 'Tableau de bord de l\'éditeur de texte enrichi',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Utilisez le raccourci Alt-0 pour obtenir de l\'aide',
+
+               browseServer: 'Parcourir le serveur',
+               url: 'URL',
+               protocol: 'Protocole',
+               upload: 'Téléverser',
+               uploadSubmit: 'Envoyer sur le serveur',
+               image: 'Image',
+               flash: 'Flash',
+               form: 'Formulaire',
+               checkbox: 'Case à cocher',
+               radio: 'Bouton radio',
+               textField: 'Champ texte',
+               textarea: 'Zone de texte',
+               hiddenField: 'Champ invisible',
+               button: 'Bouton',
+               select: 'Liste déroulante',
+               imageButton: 'Bouton avec image',
+               notSet: '<indéfini>',
+               id: 'ID',
+               name: 'Nom',
+               langDir: 'Sens d\'écriture',
+               langDirLtr: 'Gauche à droite (LTR)',
+               langDirRtl: 'Droite à gauche (RTL)',
+               langCode: 'Code de langue',
+               longDescr: 'URL de description longue',
+               cssClass: 'Classes de style',
+               advisoryTitle: 'Infobulle',
+               cssStyle: 'Style',
+               ok: 'OK',
+               cancel: 'Annuler',
+               close: 'Fermer',
+               preview: 'Aperçu',
+               resize: 'Redimensionner',
+               generalTab: 'Général',
+               advancedTab: 'Avancé',
+               validateNumberFailed: 'Cette valeur n\'est pas un nombre.',
+               confirmNewPage: 'Les changements non sauvegardés seront perdus. Êtes-vous sûr de vouloir charger une nouvelle page ?',
+               confirmCancel: 'Certaines options ont été modifiées. Êtes-vous sûr de vouloir fermer ?',
+               options: 'Options',
+               target: 'Cible',
+               targetNew: 'Nouvelle fenêtre (_blank)',
+               targetTop: 'Fenêtre supérieure (_top)',
+               targetSelf: 'Même fenêtre (_self)',
+               targetParent: 'Fenêtre parent (_parent)',
+               langDirLTR: 'Gauche à droite (LTR)',
+               langDirRTL: 'Droite à gauche (RTL)',
+               styles: 'Style',
+               cssClasses: 'Classes de style',
+               width: 'Largeur',
+               height: 'Hauteur',
+               align: 'Alignement',
+               alignLeft: 'Gauche',
+               alignRight: 'Droite',
+               alignCenter: 'Centrer',
+               alignJustify: 'Justifier',
+               alignTop: 'Haut',
+               alignMiddle: 'Milieu',
+               alignBottom: 'Bas',
+               alignNone: 'Aucun',
+               invalidValue: 'Valeur invalide.',
+               invalidHeight: 'La hauteur doit être un nombre.',
+               invalidWidth: 'La largeur doit être un nombre.',
+               invalidCssLength: 'La valeur spécifiée pour le champ « %1 » doit être un nombre positif avec ou sans unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
+               invalidHtmlLength: 'La valeur spécifiée pour le champ « %1 » doit être un nombre positif avec ou sans unité de mesure HTML valide (px ou %).',
+               invalidInlineStyle: 'La valeur spécifiée pour le style en ligne doit être composée d\'un ou plusieurs couples au format « nom : valeur », séparés par des points-virgules.',
+               cssLengthTooltip: 'Entrer un nombre pour une valeur en pixels ou un nombre avec une unité de mesure CSS valide (px, %, in, cm, mm, em, ex, pt, ou pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, indisponible</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Entrée',
+                       16: 'Majuscule',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Fin',
+                       36: 'Origine',
+                       46: 'Supprimer',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/gl.js b/sources/lang/gl.js
new file mode 100644 (file)
index 0000000..331a21b
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Galician language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'gl' ] = {
+       // ARIA description.
+       editor: 'Editor de texto mellorado',
+       editorPanel: 'Panel do editor de texto mellorado',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Prema ALT 0 para obter axuda',
+
+               browseServer: 'Examinar o servidor',
+               url: 'URL',
+               protocol: 'Protocolo',
+               upload: 'Enviar',
+               uploadSubmit: 'Enviar ao servidor',
+               image: 'Imaxe',
+               flash: 'Flash',
+               form: 'Formulario',
+               checkbox: 'Caixa de selección',
+               radio: 'Botón de opción',
+               textField: 'Campo de texto',
+               textarea: 'Área de texto',
+               hiddenField: 'Campo agochado',
+               button: 'Botón',
+               select: 'Campo de selección',
+               imageButton: 'Botón de imaxe',
+               notSet: '<sen estabelecer>',
+               id: 'ID',
+               name: 'Nome',
+               langDir: 'Dirección de escritura do idioma',
+               langDirLtr: 'Esquerda a dereita (LTR)',
+               langDirRtl: 'Dereita a esquerda (RTL)',
+               langCode: 'Código do idioma',
+               longDescr: 'Descrición completa do URL',
+               cssClass: 'Clases da folla de estilos',
+               advisoryTitle: 'Título',
+               cssStyle: 'Estilo',
+               ok: 'Aceptar',
+               cancel: 'Cancelar',
+               close: 'Pechar',
+               preview: 'Vista previa',
+               resize: 'Redimensionar',
+               generalTab: 'Xeral',
+               advancedTab: 'Avanzado',
+               validateNumberFailed: 'Este valor non é un número.',
+               confirmNewPage: 'Calquera cambio que non gardara neste contido perderase.\r\nConfirma que quere cargar unha páxina nova?',
+               confirmCancel: 'Algunhas das opcións foron cambiadas.\r\nConfirma que quere pechar o diálogo?',
+               options: 'Opcións',
+               target: 'Destino',
+               targetNew: 'Nova xanela (_blank)',
+               targetTop: 'Xanela principal (_top)',
+               targetSelf: 'Mesma xanela (_self)',
+               targetParent: 'Xanela superior (_parent)',
+               langDirLTR: 'Esquerda a dereita (LTR)',
+               langDirRTL: 'Dereita a esquerda (RTL)',
+               styles: 'Estilo',
+               cssClasses: 'Clases da folla de estilos',
+               width: 'Largo',
+               height: 'Alto',
+               align: 'Aliñamento',
+               alignLeft: 'Esquerda',
+               alignRight: 'Dereita',
+               alignCenter: 'Centro',
+               alignJustify: 'Xustificado',
+               alignTop: 'Arriba',
+               alignMiddle: 'Centro',
+               alignBottom: 'Abaixo',
+               alignNone: 'Ningún',
+               invalidValue: 'Valor incorrecto.',
+               invalidHeight: 'O alto debe ser un número.',
+               invalidWidth: 'O largo debe ser un número.',
+               invalidCssLength: 'O valor especificado para o campo «%1» debe ser un número positivo con ou sen unha unidade de medida CSS correcta (px, %, in, cm, mm, em, ex, pt, ou pc).',
+               invalidHtmlLength: 'O valor especificado para o campo «%1» debe ser un número positivo con ou sen unha unidade de medida HTML correcta (px ou %).',
+               invalidInlineStyle: 'O valor especificado no estilo en liña debe consistir nunha ou máis tuplas co formato «nome : valor», separadas por punto e coma.',
+               cssLengthTooltip: 'Escriba un número para o valor en píxeles ou un número cunha unidade CSS correcta (px, %, in, cm, mm, em, ex, pt, ou pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, non dispoñíbel</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Intro',
+                       16: 'Maiús',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Fin',
+                       36: 'Inicio',
+                       46: 'Supr',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/gu.js b/sources/lang/gu.js
new file mode 100644 (file)
index 0000000..17862d0
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Gujarati language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'gu' ] = {
+       // ARIA description.
+       editor: 'રીચ ટેક્ષ્ત્ એડીટર',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'પ્રેસ ALT 0 મદદ માટ',
+
+               browseServer: 'સર્વર બ્રાઉઝ કરો',
+               url: 'URL',
+               protocol: 'પ્રોટોકૉલ',
+               upload: 'અપલોડ',
+               uploadSubmit: 'આ સર્વરને મોકલવું',
+               image: 'ચિત્ર',
+               flash: 'ફ્લૅશ',
+               form: 'ફૉર્મ/પત્રક',
+               checkbox: 'ચેક બોક્સ',
+               radio: 'રેડિઓ બટન',
+               textField: 'ટેક્સ્ટ ફીલ્ડ, શબ્દ ક્ષેત્ર',
+               textarea: 'ટેક્સ્ટ એરિઆ, શબ્દ વિસ્તાર',
+               hiddenField: 'ગુપ્ત ક્ષેત્ર',
+               button: 'બટન',
+               select: 'પસંદગી ક્ષેત્ર',
+               imageButton: 'ચિત્ર બટન',
+               notSet: '<સેટ નથી>',
+               id: 'Id',
+               name: 'નામ',
+               langDir: 'ભાષા લેખવાની પદ્ધતિ',
+               langDirLtr: 'ડાબે થી જમણે (LTR)',
+               langDirRtl: 'જમણે થી ડાબે (RTL)',
+               langCode: 'ભાષા કોડ',
+               longDescr: 'વધારે માહિતી માટે URL',
+               cssClass: 'સ્ટાઇલ-શીટ ક્લાસ',
+               advisoryTitle: 'મુખ્ય મથાળું',
+               cssStyle: 'સ્ટાઇલ',
+               ok: 'ઠીક છે',
+               cancel: 'રદ કરવું',
+               close: 'બંધ કરવું',
+               preview: 'જોવું',
+               resize: 'ખેંચી ને યોગ્ય કરવું',
+               generalTab: 'જનરલ',
+               advancedTab: 'અડ્વાન્સડ',
+               validateNumberFailed: 'આ રકમ આકડો નથી.',
+               confirmNewPage: 'સવે કાર્ય વગરનું ફકરો ખોવાઈ જશે. તમને ખાતરી છે કે તમને નવું પાનું ખોલવું છે?',
+               confirmCancel: 'ઘણા વિકલ્પો બદલાયા છે. તમારે આ બોક્ષ્ બંધ કરવું છે?',
+               options: 'વિકલ્પો',
+               target: 'લક્ષ્ય',
+               targetNew: 'નવી વિન્ડો (_blank)',
+               targetTop: 'ઉપરની વિન્ડો (_top)',
+               targetSelf: 'એજ વિન્ડો (_self)',
+               targetParent: 'પેરનટ વિન્ડો (_parent)',
+               langDirLTR: 'ડાબે થી જમણે (LTR)',
+               langDirRTL: 'જમણે થી ડાબે (RTL)',
+               styles: 'શૈલી',
+               cssClasses: 'શૈલી કલાસીસ',
+               width: 'પહોળાઈ',
+               height: 'ઊંચાઈ',
+               align: 'લાઇનદોરીમાં ગોઠવવું',
+               alignLeft: 'ડાબી બાજુ ગોઠવવું',
+               alignRight: 'જમણી',
+               alignCenter: 'મધ્ય સેન્ટર',
+               alignJustify: 'બ્લૉક, અંતરાય જસ્ટિફાઇ',
+               alignTop: 'ઉપર',
+               alignMiddle: 'વચ્ચે',
+               alignBottom: 'નીચે',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'ઉંચાઈ એક આંકડો હોવો જોઈએ.',
+               invalidWidth: 'પોહળ ઈ એક આંકડો હોવો જોઈએ.',
+               invalidCssLength: '"%1" ની વેલ્યુ એક પોસીટીવ આંકડો હોવો જોઈએ અથવા CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc) વગર.',
+               invalidHtmlLength: '"%1" ની વેલ્યુ એક પોસીટીવ આંકડો હોવો જોઈએ અથવા HTML measurement unit (px or %) વગર.',
+               invalidInlineStyle: 'ઈનલાઈન  સ્ટાઈલ ની વેલ્યુ  "name : value" ના ફોર્મેટ માં હોવી જોઈએ, વચ્ચે સેમી-કોલોન જોઈએ.',
+               cssLengthTooltip: 'પિક્ષ્લ્ નો આંકડો CSS unit (px, %, in, cm, mm, em, ex, pt, or pc) માં નાખો.',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, નથી મળતું</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/he.js b/sources/lang/he.js
new file mode 100644 (file)
index 0000000..27b57bd
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Hebrew language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'he' ] = {
+       // ARIA description.
+       editor: 'עורך טקסט עשיר',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'לחץ אלט ALT + 0 לעזרה',
+
+               browseServer: 'סייר השרת',
+               url: 'כתובת (URL)',
+               protocol: 'פרוטוקול',
+               upload: 'העלאה',
+               uploadSubmit: 'שליחה לשרת',
+               image: 'תמונה',
+               flash: 'פלאש',
+               form: 'טופס',
+               checkbox: 'תיבת סימון',
+               radio: 'לחצן אפשרויות',
+               textField: 'שדה טקסט',
+               textarea: 'איזור טקסט',
+               hiddenField: 'שדה חבוי',
+               button: 'כפתור',
+               select: 'שדה בחירה',
+               imageButton: 'כפתור תמונה',
+               notSet: '<לא נקבע>',
+               id: 'זיהוי (ID)',
+               name: 'שם',
+               langDir: 'כיוון שפה',
+               langDirLtr: 'שמאל לימין (LTR)',
+               langDirRtl: 'ימין לשמאל (RTL)',
+               langCode: 'קוד שפה',
+               longDescr: 'קישור לתיאור מפורט',
+               cssClass: 'מחלקת עיצוב (CSS Class)',
+               advisoryTitle: 'כותרת מוצעת',
+               cssStyle: 'סגנון',
+               ok: 'אישור',
+               cancel: 'ביטול',
+               close: 'סגירה',
+               preview: 'תצוגה מקדימה',
+               resize: 'יש לגרור בכדי לשנות את הגודל',
+               generalTab: 'כללי',
+               advancedTab: 'אפשרויות מתקדמות',
+               validateNumberFailed: 'הערך חייב להיות מספרי.',
+               confirmNewPage: 'כל השינויים שלא נשמרו יאבדו. האם להעלות דף חדש?',
+               confirmCancel: 'חלק מהאפשרויות שונו, האם לסגור את הדיאלוג?',
+               options: 'אפשרויות',
+               target: 'מטרה',
+               targetNew: 'חלון חדש (_blank)',
+               targetTop: 'החלון העליון ביותר (_top)',
+               targetSelf: 'אותו חלון (_self)',
+               targetParent: 'חלון האב (_parent)',
+               langDirLTR: 'שמאל לימין (LTR)',
+               langDirRTL: 'ימין לשמאל (RTL)',
+               styles: 'סגנון',
+               cssClasses: 'מחלקות גליונות סגנון',
+               width: 'רוחב',
+               height: 'גובה',
+               align: 'יישור',
+               alignLeft: 'לשמאל',
+               alignRight: 'לימין',
+               alignCenter: 'מרכז',
+               alignJustify: 'יישור לשוליים',
+               alignTop: 'למעלה',
+               alignMiddle: 'לאמצע',
+               alignBottom: 'לתחתית',
+               alignNone: 'None', // MISSING
+               invalidValue: 'ערך לא חוקי.',
+               invalidHeight: 'הגובה חייב להיות מספר.',
+               invalidWidth: 'הרוחב חייב להיות מספר.',
+               invalidCssLength: 'הערך שצוין לשדה "%1" חייב להיות מספר חיובי עם או ללא יחידת מידה חוקית של CSS (px, %, in, cm, mm, em, ex, pt, או pc).',
+               invalidHtmlLength: 'הערך שצוין לשדה "%1" חייב להיות מספר חיובי עם או ללא יחידת מידה חוקית של HTML (px או %).',
+               invalidInlineStyle: 'הערך שצויין לשדה הסגנון חייב להכיל זוג ערכים אחד או יותר בפורמט "שם : ערך", מופרדים על ידי נקודה-פסיק.',
+               cssLengthTooltip: 'יש להכניס מספר המייצג פיקסלים או מספר עם יחידת גליונות סגנון תקינה (px, %, in, cm, mm, em, ex, pt, או pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, לא זמין</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'End',
+                       36: 'Home',
+                       46: 'מחק',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/hi.js b/sources/lang/hi.js
new file mode 100644 (file)
index 0000000..e0b29a3
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Hindi language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'hi' ] = {
+       // ARIA description.
+       editor: 'रिच टेक्स्ट एडिटर',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'मदद के लिये ALT 0 दबाए',
+
+               browseServer: 'सर्वर ब्राउज़ करें',
+               url: 'URL',
+               protocol: 'प्रोटोकॉल',
+               upload: 'अपलोड',
+               uploadSubmit: 'इसे सर्वर को भेजें',
+               image: 'तस्वीर',
+               flash: 'फ़्लैश',
+               form: 'फ़ॉर्म',
+               checkbox: 'चॅक बॉक्स',
+               radio: 'रेडिओ बटन',
+               textField: 'टेक्स्ट फ़ील्ड',
+               textarea: 'टेक्स्ट एरिया',
+               hiddenField: 'गुप्त फ़ील्ड',
+               button: 'बटन',
+               select: 'चुनाव फ़ील्ड',
+               imageButton: 'तस्वीर बटन',
+               notSet: '<सॅट नहीं>',
+               id: 'Id',
+               name: 'नाम',
+               langDir: 'भाषा लिखने की दिशा',
+               langDirLtr: 'बायें से दायें (LTR)',
+               langDirRtl: 'दायें से बायें (RTL)',
+               langCode: 'भाषा कोड',
+               longDescr: 'अधिक विवरण के लिए URL',
+               cssClass: 'स्टाइल-शीट क्लास',
+               advisoryTitle: 'परामर्श शीर्शक',
+               cssStyle: 'स्टाइल',
+               ok: 'ठीक है',
+               cancel: 'रद्द करें',
+               close: 'Close', // MISSING
+               preview: 'प्रीव्यू',
+               resize: 'Resize', // MISSING
+               generalTab: 'सामान्य',
+               advancedTab: 'ऍड्वान्स्ड',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Options', // MISSING
+               target: 'टार्गेट',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'बायें से दायें (LTR)',
+               langDirRTL: 'दायें से बायें (RTL)',
+               styles: 'स्टाइल',
+               cssClasses: 'स्टाइल-शीट क्लास',
+               width: 'चौड़ाई',
+               height: 'ऊँचाई',
+               align: 'ऍलाइन',
+               alignLeft: 'दायें',
+               alignRight: 'दायें',
+               alignCenter: 'बीच में',
+               alignJustify: 'ब्लॉक जस्टीफ़ाई',
+               alignTop: 'ऊपर',
+               alignMiddle: 'मध्य',
+               alignBottom: 'नीचे',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/hr.js b/sources/lang/hr.js
new file mode 100644 (file)
index 0000000..d12a338
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Croatian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'hr' ] = {
+       // ARIA description.
+       editor: 'Bogati uređivač teksta, %1',
+       editorPanel: 'Ploča Bogatog Uređivača Teksta',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Pritisni ALT 0 za pomoć',
+
+               browseServer: 'Pretraži server',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Pošalji',
+               uploadSubmit: 'Pošalji na server',
+               image: 'Slika',
+               flash: 'Flash',
+               form: 'Forma',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Hidden Field',
+               button: 'Button',
+               select: 'Selection Field',
+               imageButton: 'Image Button',
+               notSet: '<nije postavljeno>',
+               id: 'Id',
+               name: 'Naziv',
+               langDir: 'Smjer jezika',
+               langDirLtr: 'S lijeva na desno (LTR)',
+               langDirRtl: 'S desna na lijevo (RTL)',
+               langCode: 'Kôd jezika',
+               longDescr: 'Dugački opis URL',
+               cssClass: 'Klase stilova',
+               advisoryTitle: 'Advisory naslov',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Poništi',
+               close: 'Zatvori',
+               preview: 'Pregledaj',
+               resize: 'Povuci za promjenu veličine',
+               generalTab: 'Općenito',
+               advancedTab: 'Napredno',
+               validateNumberFailed: 'Ova vrijednost nije broj.',
+               confirmNewPage: 'Sve napravljene promjene će biti izgubljene ukoliko ih niste snimili. Sigurno želite učitati novu stranicu?',
+               confirmCancel: 'Neke od opcija su promjenjene. Sigurno želite zatvoriti ovaj prozor?',
+               options: 'Opcije',
+               target: 'Odredište',
+               targetNew: 'Novi prozor (_blank)',
+               targetTop: 'Vršni prozor (_top)',
+               targetSelf: 'Isti prozor (_self)',
+               targetParent: 'Roditeljski prozor (_parent)',
+               langDirLTR: 'S lijeva na desno (LTR)',
+               langDirRTL: 'S desna na lijevo (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Klase stilova',
+               width: 'Širina',
+               height: 'Visina',
+               align: 'Poravnanje',
+               alignLeft: 'Lijevo',
+               alignRight: 'Desno',
+               alignCenter: 'Središnje',
+               alignJustify: 'Blok poravnanje',
+               alignTop: 'Vrh',
+               alignMiddle: 'Sredina',
+               alignBottom: 'Dolje',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Neispravna vrijednost.',
+               invalidHeight: 'Visina mora biti broj.',
+               invalidWidth: 'Širina mora biti broj.',
+               invalidCssLength: 'Vrijednost određena za "%1" polje mora biti pozitivni broj sa ili bez važećih CSS mjernih jedinica (px, %, in, cm, mm, em, ex, pt ili pc).',
+               invalidHtmlLength: 'Vrijednost određena za "%1" polje mora biti pozitivni broj sa ili bez važećih HTML mjernih jedinica (px ili %).',
+               invalidInlineStyle: 'Vrijednost za linijski stil mora sadržavati jednu ili više definicija s formatom "naziv:vrijednost", odvojenih točka-zarezom.',
+               cssLengthTooltip: 'Unesite broj za vrijednost u pikselima ili broj s važećim CSS mjernim jedinicama (px, %, in, cm, mm, em, ex, pt ili pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nedostupno</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/hu.js b/sources/lang/hu.js
new file mode 100644 (file)
index 0000000..0cd0d96
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Hungarian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'hu' ] = {
+       // ARIA description.
+       editor: 'HTML szerkesztő',
+       editorPanel: 'Rich Text szerkesztő panel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Segítségért nyomjon ALT 0',
+
+               browseServer: 'Böngészés a szerveren',
+               url: 'Hivatkozás',
+               protocol: 'Protokoll',
+               upload: 'Feltöltés',
+               uploadSubmit: 'Küldés a szerverre',
+               image: 'Kép',
+               flash: 'Flash',
+               form: 'Űrlap',
+               checkbox: 'Jelölőnégyzet',
+               radio: 'Választógomb',
+               textField: 'Szövegmező',
+               textarea: 'Szövegterület',
+               hiddenField: 'Rejtettmező',
+               button: 'Gomb',
+               select: 'Legördülő lista',
+               imageButton: 'Képgomb',
+               notSet: '<nincs beállítva>',
+               id: 'Azonosító',
+               name: 'Név',
+               langDir: 'Írás iránya',
+               langDirLtr: 'Balról jobbra',
+               langDirRtl: 'Jobbról balra',
+               langCode: 'Nyelv kódja',
+               longDescr: 'Részletes leírás webcíme',
+               cssClass: 'Stíluskészlet',
+               advisoryTitle: 'Súgócimke',
+               cssStyle: 'Stílus',
+               ok: 'Rendben',
+               cancel: 'Mégsem',
+               close: 'Bezárás',
+               preview: 'Előnézet',
+               resize: 'Húzza az átméretezéshez',
+               generalTab: 'Általános',
+               advancedTab: 'További opciók',
+               validateNumberFailed: 'A mezőbe csak számokat írhat.',
+               confirmNewPage: 'Minden nem mentett változás el fog veszni! Biztosan be szeretné tölteni az oldalt?',
+               confirmCancel: 'Az űrlap tartalma megváltozott, ám a változásokat nem rögzítette. Biztosan be szeretné zárni az űrlapot?',
+               options: 'Beállítások',
+               target: 'Cél',
+               targetNew: 'Új ablak (_blank)',
+               targetTop: 'Legfelső ablak (_top)',
+               targetSelf: 'Aktuális ablakban (_self)',
+               targetParent: 'Szülő ablak (_parent)',
+               langDirLTR: 'Balról jobbra (LTR)',
+               langDirRTL: 'Jobbról balra (RTL)',
+               styles: 'Stílus',
+               cssClasses: 'Stíluslap osztály',
+               width: 'Szélesség',
+               height: 'Magasság',
+               align: 'Igazítás',
+               alignLeft: 'Bal',
+               alignRight: 'Jobbra',
+               alignCenter: 'Középre',
+               alignJustify: 'Sorkizárt',
+               alignTop: 'Tetejére',
+               alignMiddle: 'Középre',
+               alignBottom: 'Aljára',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Érvénytelen érték.',
+               invalidHeight: 'A magasság mezőbe csak számokat írhat.',
+               invalidWidth: 'A szélesség mezőbe csak számokat írhat.',
+               invalidCssLength: '"%1"-hez megadott érték csakis egy pozitív szám lehet, esetleg egy érvényes CSS egységgel megjelölve(px, %, in, cm, mm, em, ex, pt vagy pc).',
+               invalidHtmlLength: '"%1"-hez megadott érték csakis egy pozitív szám lehet, esetleg egy érvényes HTML egységgel megjelölve(px vagy %).',
+               invalidInlineStyle: 'Az inline stílusnak megadott értéknek tartalmaznia kell egy vagy több rekordot a "name : value" formátumban, pontosvesszővel elválasztva.',
+               cssLengthTooltip: 'Adjon meg egy számot értéknek pixelekben vagy egy számot érvényes CSS mértékegységben (px, %, in, cm, mm, em, ex, pt, vagy pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nem elérhető</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/id.js b/sources/lang/id.js
new file mode 100644 (file)
index 0000000..86e7076
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'id' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Panel Rich Text Editor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Tekan ALT 0 untuk bantuan.',
+
+               browseServer: 'Jelajah Server',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Unggah',
+               uploadSubmit: 'Kirim ke Server',
+               image: 'Gambar',
+               flash: 'Flash',
+               form: 'Formulir',
+               checkbox: 'Kotak Cek',
+               radio: 'Tombol Radio',
+               textField: 'Kolom Teks',
+               textarea: 'Area Teks',
+               hiddenField: 'Kolom Tersembunyi',
+               button: 'Tombol',
+               select: 'Kolom Seleksi',
+               imageButton: 'Tombol Gambar',
+               notSet: '<tidak diatur>',
+               id: 'Id',
+               name: 'Nama',
+               langDir: 'Arah Bahasa',
+               langDirLtr: 'Kiri ke Kanan (LTR)',
+               langDirRtl: 'Kanan ke Kiri',
+               langCode: 'Kode Bahasa',
+               longDescr: 'Deskripsi URL Panjang',
+               cssClass: 'Kelas Stylesheet',
+               advisoryTitle: 'Penasehat Judul',
+               cssStyle: 'Gaya',
+               ok: 'OK',
+               cancel: 'Batal',
+               close: 'Tutup',
+               preview: 'Pratinjau',
+               resize: 'Ubah ukuran',
+               generalTab: 'Umum',
+               advancedTab: 'Lebih Lanjut',
+               validateNumberFailed: 'Nilai ini tidak sebuah angka',
+               confirmNewPage: 'Semua perubahan yang tidak disimpan di konten ini akan hilang. Apakah anda yakin ingin memuat halaman baru?',
+               confirmCancel: 'Beberapa opsi telah berubah. Apakah anda yakin ingin menutup dialog?',
+               options: 'Opsi',
+               target: 'Sasaran',
+               targetNew: 'Jendela Baru (_blank)',
+               targetTop: 'Laman Atas (_top)',
+               targetSelf: 'Jendela yang Sama (_self)',
+               targetParent: 'Jendela Induk (_parent)',
+               langDirLTR: 'Kiri ke Kanan (LTR)',
+               langDirRTL: 'Kanan ke Kiri (RTL)',
+               styles: 'Gaya',
+               cssClasses: 'Kelas Stylesheet',
+               width: 'Lebar',
+               height: 'Tinggi',
+               align: 'Penjajaran',
+               alignLeft: 'Kiri',
+               alignRight: 'Kanan',
+               alignCenter: 'Tengah',
+               alignJustify: 'Rata kiri-kanan',
+               alignTop: 'Atas',
+               alignMiddle: 'Tengah',
+               alignBottom: 'Bawah',
+               alignNone: 'Tidak ada',
+               invalidValue: 'Nilai tidak sah.',
+               invalidHeight: 'Tinggi harus sebuah angka.',
+               invalidWidth: 'Lebar harus sebuah angka.',
+               invalidCssLength: 'Nilai untuk "%1" harus sebuah angkat positif dengan atau tanpa pengukuran unit CSS yang sah (px, %, in, cm, mm, em, ex, pt, or pc).',
+               invalidHtmlLength: 'Nilai yang dispesifikasian untuk kolom "%1" harus sebuah angka positif dengan atau tanpa sebuah unit pengukuran HTML (px atau %) yang valid.',
+               invalidInlineStyle: 'Nilai pada inline style merupakan pasangan nama dan nilai dengan format "nama : nilai", yang dipisahkan dengan titik dua.',
+               cssLengthTooltip: 'Masukkan sebuah angka untuk sebuah nilai dalam pixel atau sebuah angka dengan unit CSS yang sah (px, %, in, cm, mm, em, ex, pt, or pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, tidak tersedia</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Spasi',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Hapus',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Pintasan Keyboard'
+       }
+};
diff --git a/sources/lang/is.js b/sources/lang/is.js
new file mode 100644 (file)
index 0000000..256b667
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Icelandic language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'is' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Fletta í skjalasafni',
+               url: 'Vefslóð',
+               protocol: 'Samskiptastaðall',
+               upload: 'Senda upp',
+               uploadSubmit: 'Hlaða upp',
+               image: 'Setja inn mynd',
+               flash: 'Flash',
+               form: 'Setja inn innsláttarform',
+               checkbox: 'Setja inn hökunarreit',
+               radio: 'Setja inn valhnapp',
+               textField: 'Setja inn textareit',
+               textarea: 'Setja inn textasvæði',
+               hiddenField: 'Setja inn falið svæði',
+               button: 'Setja inn hnapp',
+               select: 'Setja inn lista',
+               imageButton: 'Setja inn myndahnapp',
+               notSet: '<ekkert valið>',
+               id: 'Auðkenni',
+               name: 'Nafn',
+               langDir: 'Lesstefna',
+               langDirLtr: 'Frá vinstri til hægri (LTR)',
+               langDirRtl: 'Frá hægri til vinstri (RTL)',
+               langCode: 'Tungumálakóði',
+               longDescr: 'Nánari lýsing',
+               cssClass: 'Stílsniðsflokkur',
+               advisoryTitle: 'Titill',
+               cssStyle: 'Stíll',
+               ok: 'Í lagi',
+               cancel: 'Hætta við',
+               close: 'Close', // MISSING
+               preview: 'Forskoða',
+               resize: 'Resize', // MISSING
+               generalTab: 'Almennt',
+               advancedTab: 'Tæknilegt',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Options', // MISSING
+               target: 'Mark',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'Frá vinstri til hægri (LTR)',
+               langDirRTL: 'Frá hægri til vinstri (RTL)',
+               styles: 'Stíll',
+               cssClasses: 'Stílsniðsflokkur',
+               width: 'Breidd',
+               height: 'Hæð',
+               align: 'Jöfnun',
+               alignLeft: 'Vinstri',
+               alignRight: 'Hægri',
+               alignCenter: 'Miðjað',
+               alignJustify: 'Jafna báðum megin',
+               alignTop: 'Efst',
+               alignMiddle: 'Miðjuð',
+               alignBottom: 'Neðst',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/it.js b/sources/lang/it.js
new file mode 100644 (file)
index 0000000..8229aad
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Italian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'it' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Pannello Rich Text Editor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Premi ALT 0 per aiuto',
+
+               browseServer: 'Cerca sul server',
+               url: 'URL',
+               protocol: 'Protocollo',
+               upload: 'Carica',
+               uploadSubmit: 'Invia al server',
+               image: 'Immagine',
+               flash: 'Oggetto Flash',
+               form: 'Modulo',
+               checkbox: 'Checkbox',
+               radio: 'Radio Button',
+               textField: 'Campo di testo',
+               textarea: 'Area di testo',
+               hiddenField: 'Campo nascosto',
+               button: 'Bottone',
+               select: 'Menu di selezione',
+               imageButton: 'Bottone immagine',
+               notSet: '<non impostato>',
+               id: 'Id',
+               name: 'Nome',
+               langDir: 'Direzione scrittura',
+               langDirLtr: 'Da Sinistra a Destra (LTR)',
+               langDirRtl: 'Da Destra a Sinistra (RTL)',
+               langCode: 'Codice Lingua',
+               longDescr: 'URL descrizione estesa',
+               cssClass: 'Nome classe CSS',
+               advisoryTitle: 'Titolo',
+               cssStyle: 'Stile',
+               ok: 'OK',
+               cancel: 'Annulla',
+               close: 'Chiudi',
+               preview: 'Anteprima',
+               resize: 'Trascina per ridimensionare',
+               generalTab: 'Generale',
+               advancedTab: 'Avanzate',
+               validateNumberFailed: 'Il valore inserito non è un numero.',
+               confirmNewPage: 'Ogni modifica non salvata sarà persa. Sei sicuro di voler caricare una nuova pagina?',
+               confirmCancel: 'Alcune delle opzioni sono state cambiate. Sei sicuro di voler chiudere la finestra di dialogo?',
+               options: 'Opzioni',
+               target: 'Destinazione',
+               targetNew: 'Nuova finestra (_blank)',
+               targetTop: 'Finestra in primo piano (_top)',
+               targetSelf: 'Stessa finestra (_self)',
+               targetParent: 'Finestra Padre (_parent)',
+               langDirLTR: 'Da sinistra a destra (LTR)',
+               langDirRTL: 'Da destra a sinistra (RTL)',
+               styles: 'Stile',
+               cssClasses: 'Classi di stile',
+               width: 'Larghezza',
+               height: 'Altezza',
+               align: 'Allineamento',
+               alignLeft: 'Sinistra',
+               alignRight: 'Destra',
+               alignCenter: 'Centrato',
+               alignJustify: 'Giustifica',
+               alignTop: 'In Alto',
+               alignMiddle: 'Centrato',
+               alignBottom: 'In Basso',
+               alignNone: 'Nessuno',
+               invalidValue: 'Valore non valido.',
+               invalidHeight: 'L\'altezza dev\'essere un numero',
+               invalidWidth: 'La Larghezza dev\'essere un numero',
+               invalidCssLength: 'Il valore indicato per il campo "%1" deve essere un numero positivo con o senza indicazione di una valida unità di misura per le classi CSS (px, %, in, cm, mm, em, ex, pt, o pc).',
+               invalidHtmlLength: 'Il valore indicato per il campo "%1" deve essere un numero positivo con o senza indicazione di una valida unità di misura per le pagine HTML (px o %).',
+               invalidInlineStyle: 'Il valore specificato per lo stile inline deve consistere in una o più tuple con il formato di "name : value", separati da semicolonne.',
+               cssLengthTooltip: 'Inserisci un numero per il valore in pixel oppure un numero con una valida unità CSS (px, %, in, cm, mm, ex, pt, o pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, non disponibile</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Invio',
+                       16: 'Maiusc',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Spazio',
+                       35: 'Fine',
+                       36: 'Inizio',
+                       46: 'Canc',
+                       224: 'Comando'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Scorciatoia da tastiera'
+       }
+};
diff --git a/sources/lang/ja.js b/sources/lang/ja.js
new file mode 100644 (file)
index 0000000..56b69f7
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Japanese language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ja' ] = {
+       // ARIA description.
+       editor: 'リッチテキストエディタ',
+       editorPanel: 'リッチテキストエディタパネル',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'ヘルプは ALT 0 を押してください',
+
+               browseServer: 'サーバブラウザ',
+               url: 'URL',
+               protocol: 'プロトコル',
+               upload: 'アップロード',
+               uploadSubmit: 'サーバーに送信',
+               image: 'イメージ',
+               flash: 'Flash',
+               form: 'フォーム',
+               checkbox: 'チェックボックス',
+               radio: 'ラジオボタン',
+               textField: '1行テキスト',
+               textarea: 'テキストエリア',
+               hiddenField: '不可視フィールド',
+               button: 'ボタン',
+               select: '選択フィールド',
+               imageButton: '画像ボタン',
+               notSet: '<なし>',
+               id: 'Id',
+               name: 'Name属性',
+               langDir: '文字表記の方向',
+               langDirLtr: '左から右 (LTR)',
+               langDirRtl: '右から左 (RTL)',
+               langCode: '言語コード',
+               longDescr: 'longdesc属性(長文説明)',
+               cssClass: 'スタイルシートクラス',
+               advisoryTitle: 'Title属性',
+               cssStyle: 'スタイルシート',
+               ok: 'OK',
+               cancel: 'キャンセル',
+               close: '閉じる',
+               preview: 'プレビュー',
+               resize: 'ドラッグしてリサイズ',
+               generalTab: '全般',
+               advancedTab: '高度な設定',
+               validateNumberFailed: '値が数ではありません',
+               confirmNewPage: '変更内容を保存せず、 新しいページを開いてもよろしいでしょうか?',
+               confirmCancel: 'オプション設定を変更しました。ダイアログを閉じてもよろしいでしょうか?',
+               options: 'オプション',
+               target: 'ターゲット',
+               targetNew: '新しいウインドウ (_blank)',
+               targetTop: '最上部ウィンドウ (_top)',
+               targetSelf: '同じウィンドウ (_self)',
+               targetParent: '親ウィンドウ (_parent)',
+               langDirLTR: '左から右 (LTR)',
+               langDirRTL: '右から左 (RTL)',
+               styles: 'スタイル',
+               cssClasses: 'スタイルシートクラス',
+               width: '幅',
+               height: '高さ',
+               align: '行揃え',
+               alignLeft: '左',
+               alignRight: '右',
+               alignCenter: '中央',
+               alignJustify: '両端揃え',
+               alignTop: '上',
+               alignMiddle: '中央',
+               alignBottom: '下',
+               alignNone: 'なし',
+               invalidValue: '不正な値です。',
+               invalidHeight: '高さは数値で入力してください。',
+               invalidWidth: '幅は数値で入力してください。',
+               invalidCssLength: '入力された "%1" 項目の値は、CSSの大きさ(px, %, in, cm, mm, em, ex, pt, または pc)が正しいものである/ないに関わらず、正の値である必要があります。',
+               invalidHtmlLength: '入力された "%1" 項目の値は、HTMLの大きさ(px または %)が正しいものである/ないに関わらず、正の値である必要があります。',
+               invalidInlineStyle: '入力されたインラインスタイルの値は、"名前 : 値" のフォーマットのセットで、複数の場合はセミコロンで区切られている形式である必要があります。',
+               cssLengthTooltip: 'ピクセル数もしくはCSSにセットできる数値を入力してください。(px,%,in,cm,mm,em,ex,pt,or pc)',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, 利用不可能</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'キーボードショートカット'
+       }
+};
diff --git a/sources/lang/ka.js b/sources/lang/ka.js
new file mode 100644 (file)
index 0000000..999132e
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the Georgian
+ *             language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ka' ] = {
+       // ARIA description.
+       editor: 'ტექსტის რედაქტორი',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'დააჭირეთ ALT 0-ს დახმარების მისაღებად',
+
+               browseServer: 'სერვერზე დათვალიერება',
+               url: 'URL',
+               protocol: 'პროტოკოლი',
+               upload: 'ატვირთვა',
+               uploadSubmit: 'სერვერზე გაგზავნა',
+               image: 'სურათი',
+               flash: 'Flash',
+               form: 'ფორმა',
+               checkbox: 'მონიშვნის ღილაკი',
+               radio: 'ამორჩევის ღილაკი',
+               textField: 'ტექსტური ველი',
+               textarea: 'ტექსტური არე',
+               hiddenField: 'მალული ველი',
+               button: 'ღილაკი',
+               select: 'არჩევის ველი',
+               imageButton: 'სურათიანი ღილაკი',
+               notSet: '<არაფერი>',
+               id: 'Id',
+               name: 'სახელი',
+               langDir: 'ენის მიმართულება',
+               langDirLtr: 'მარცხნიდან მარჯვნივ (LTR)',
+               langDirRtl: 'მარჯვნიდან მარცხნივ (RTL)',
+               langCode: 'ენის კოდი',
+               longDescr: 'დიდი აღწერის URL',
+               cssClass: 'CSS კლასი',
+               advisoryTitle: 'სათაური',
+               cssStyle: 'CSS სტილი',
+               ok: 'დიახ',
+               cancel: 'გაუქმება',
+               close: 'დახურვა',
+               preview: 'გადახედვა',
+               resize: 'გაწიე ზომის შესაცვლელად',
+               generalTab: 'ინფორმაცია',
+               advancedTab: 'გაფართოებული',
+               validateNumberFailed: 'ეს მნიშვნელობა არაა რიცხვი.',
+               confirmNewPage: 'ამ დოკუმენტში ყველა ჩაუწერელი ცვლილება დაიკარგება. დარწმუნებული ხართ რომ ახალი გვერდის ჩატვირთვა გინდათ?',
+               confirmCancel: 'ზოგიერთი პარამეტრი შეცვლილია, დარწმუნებულილ ხართ რომ ფანჯრის დახურვა გსურთ?',
+               options: 'პარამეტრები',
+               target: 'გახსნის ადგილი',
+               targetNew: 'ახალი ფანჯარა (_blank)',
+               targetTop: 'ზედა ფანჯარა (_top)',
+               targetSelf: 'იგივე ფანჯარა (_self)',
+               targetParent: 'მშობელი ფანჯარა (_parent)',
+               langDirLTR: 'მარცხნიდან მარჯვნივ (LTR)',
+               langDirRTL: 'მარჯვნიდან მარცხნივ (RTL)',
+               styles: 'სტილი',
+               cssClasses: 'CSS კლასი',
+               width: 'სიგანე',
+               height: 'სიმაღლე',
+               align: 'სწორება',
+               alignLeft: 'მარცხენა',
+               alignRight: 'მარჯვენა',
+               alignCenter: 'შუა',
+               alignJustify: '両端揃え',
+               alignTop: 'ზემოთა',
+               alignMiddle: 'შუა',
+               alignBottom: 'ქვემოთა',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'სიმაღლე რიცხვით უნდა იყოს წარმოდგენილი.',
+               invalidWidth: 'სიგანე რიცხვით უნდა იყოს წარმოდგენილი.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, მიუწვდომელია</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/km.js b/sources/lang/km.js
new file mode 100644 (file)
index 0000000..b9908d9
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Khmer language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'km' ] = {
+       // ARIA description.
+       editor: 'ឧបករណ៍​សរសេរ​អត្ថបទ​សម្បូរ​បែប',
+       editorPanel: 'ផ្ទាំង​ឧបករណ៍​សរសេរ​អត្ថបទ​សម្បូរ​បែប',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'ចុច ALT 0 សម្រាប់​ជំនួយ',
+
+               browseServer: 'រក​មើល​ក្នុង​ម៉ាស៊ីន​បម្រើ',
+               url: 'URL',
+               protocol: 'ពិធីការ',
+               upload: 'ផ្ទុក​ឡើង',
+               uploadSubmit: 'បញ្ជូនទៅកាន់ម៉ាស៊ីន​បម្រើ',
+               image: 'រូបភាព',
+               flash: 'Flash',
+               form: 'បែបបទ',
+               checkbox: 'ប្រអប់​ធីក',
+               radio: 'ប៊ូតុង​មូល',
+               textField: 'វាល​អត្ថបទ',
+               textarea: 'Textarea',
+               hiddenField: 'វាល​កំបាំង',
+               button: 'ប៊ូតុង',
+               select: 'វាល​ជម្រើស',
+               imageButton: 'ប៊ូតុង​រូបភាព',
+               notSet: '<មិនកំណត់>',
+               id: 'Id',
+               name: 'ឈ្មោះ',
+               langDir: 'ទិសដៅភាសា',
+               langDirLtr: 'ពីឆ្វេងទៅស្តាំ (LTR)',
+               langDirRtl: 'ពីស្តាំទៅឆ្វេង (RTL)',
+               langCode: 'លេខ​កូដ​ភាសា',
+               longDescr: 'URL អធិប្បាយ​វែង',
+               cssClass: 'Stylesheet Classes',
+               advisoryTitle: 'ចំណង​ជើង​ណែនាំ',
+               cssStyle: 'រចនាបថ',
+               ok: 'ព្រម',
+               cancel: 'បោះបង់',
+               close: 'បិទ',
+               preview: 'មើល​ជា​មុន',
+               resize: 'ប្ដូរ​ទំហំ',
+               generalTab: 'ទូទៅ',
+               advancedTab: 'កម្រិត​ខ្ពស់',
+               validateNumberFailed: 'តម្លៃ​នេះ​ពុំ​មែន​ជា​លេខ​ទេ។',
+               confirmNewPage: 'រាល់​បន្លាស់​ប្ដូរ​នានា​ដែល​មិន​ទាន់​រក្សា​ទុក​ក្នុង​មាតិកា​នេះ នឹង​ត្រូវ​បាត់​បង់។ តើ​អ្នក​ពិត​ជា​ចង់​ផ្ទុក​ទំព័រ​ថ្មី​មែនទេ?',
+               confirmCancel: 'ការ​កំណត់​មួយ​ចំនួន​ត្រូ​វ​បាន​ផ្លាស់​ប្ដូរ។ តើ​អ្នក​ពិត​ជា​ចង់​បិទ​ប្រអប់​នេះ​មែនទេ?',
+               options: 'ការ​កំណត់',
+               target: 'គោលដៅ',
+               targetNew: 'វីនដូ​ថ្មី (_blank)',
+               targetTop: 'វីនដូ​លើ​គេ (_top)',
+               targetSelf: 'វីនដូ​ដូច​គ្នា (_self)',
+               targetParent: 'វីនដូ​មេ (_parent)',
+               langDirLTR: 'ពីឆ្វេងទៅស្តាំ(LTR)',
+               langDirRTL: 'ពីស្តាំទៅឆ្វេង(RTL)',
+               styles: 'រចនាបថ',
+               cssClasses: 'Stylesheet Classes',
+               width: 'ទទឹង',
+               height: 'កំពស់',
+               align: 'កំណត់​ទីតាំង',
+               alignLeft: 'ខាងឆ្វង',
+               alignRight: 'ខាងស្តាំ',
+               alignCenter: 'កណ្តាល',
+               alignJustify: 'តំរឹមសងខាង',
+               alignTop: 'ខាងលើ',
+               alignMiddle: 'កណ្តាល',
+               alignBottom: 'ខាងក្រោម',
+               alignNone: 'គ្មាន',
+               invalidValue: 'តម្លៃ​មិន​ត្រឹម​ត្រូវ។',
+               invalidHeight: 'តម្លៃ​កំពស់​ត្រូវ​តែ​ជា​លេខ។',
+               invalidWidth: 'តម្លៃ​ទទឹង​ត្រូវ​តែ​ជា​លេខ។',
+               invalidCssLength: 'តម្លៃ​កំណត់​សម្រាប់​វាល "%1" ត្រូវ​តែ​ជា​លេខ​វិជ្ជមាន​ ដោយ​ភ្ជាប់ឬ​មិន​ភ្ជាប់​ជាមួយ​នឹង​ឯកតា​រង្វាស់​របស់ CSS (px, %, in, cm, mm, em, ex, pt ឬ pc) ។',
+               invalidHtmlLength: 'តម្លៃ​កំណត់​សម្រាប់​វាល "%1" ត្រូវ​តែ​ជា​លេខ​វិជ្ជមាន ដោយ​ភ្ជាប់​ឬ​មិន​ភ្ជាប់​ជាមួយ​នឹង​ឯកតា​រង្វាស់​របស់ HTML (px ឬ %) ។',
+               invalidInlineStyle: 'តម្លៃ​កំណត់​សម្រាប់​រចនាបថ​ក្នុង​តួ ត្រូវ​តែ​មាន​មួយ​ឬ​ធាតុ​ច្រើន​ដោយ​មាន​ទ្រង់ទ្រាយ​ជា "ឈ្មោះ : តម្លៃ" ហើយ​ញែក​ចេញ​ពី​គ្នា​ដោយ​ចុច​ក្បៀស។',
+               cssLengthTooltip: 'បញ្ចូល​លេខ​សម្រាប់​តម្លៃ​ជា​ភិចសែល ឬ​លេខ​ដែល​មាន​ឯកតា​ត្រឹមត្រូវ​របស់ CSS (px, %, in, cm, mm, em, ex, pt ឬ pc) ។',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, មិន​មាន</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'លុបថយក្រោយ',
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'ចុង',
+                       36: 'ផ្ទះ',
+                       46: 'លុប',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ko.js b/sources/lang/ko.js
new file mode 100644 (file)
index 0000000..d08261d
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Korean language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ko' ] = {
+       // ARIA description.
+       editor: '리치 텍스트 편집기',
+       editorPanel: '리치 텍스트 편집기 패널',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: '도움이 필요하면 ALT 0 을 누르세요',
+
+               browseServer: '서버 보기',
+               url: 'URL',
+               protocol: '프로토콜',
+               upload: '업로드',
+               uploadSubmit: '서버로 전송',
+               image: '이미지',
+               flash: '플래시',
+               form: '폼',
+               checkbox: '체크 박스',
+               radio: '라디오 버튼',
+               textField: '한 줄 입력 칸',
+               textarea: '여러 줄 입력 칸',
+               hiddenField: '숨은 입력 칸',
+               button: '버튼',
+               select: '선택 목록',
+               imageButton: '이미지 버튼',
+               notSet: '<설정 안 됨>',
+               id: 'ID',
+               name: '이름',
+               langDir: '언어 방향',
+               langDirLtr: '왼쪽에서 오른쪽 (LTR)',
+               langDirRtl: '오른쪽에서 왼쪽 (RTL)',
+               langCode: '언어 코드',
+               longDescr: '웹 주소 설명',
+               cssClass: '스타일 시트 클래스',
+               advisoryTitle: '보조 제목',
+               cssStyle: '스타일',
+               ok: '확인',
+               cancel: '취소',
+               close: '닫기',
+               preview: '미리보기',
+               resize: '크기 조절',
+               generalTab: '일반',
+               advancedTab: '자세히',
+               validateNumberFailed: '이 값은 숫자가 아닙니다.',
+               confirmNewPage: '저장하지 않은 모든 변경사항은 유실됩니다. 정말로 새로운 페이지를 부르겠습니까?',
+               confirmCancel: '일부 옵션이 변경 되었습니다. 정말로 창을 닫겠습니까?',
+               options: '옵션',
+               target: '타겟',
+               targetNew: '새 창 (_blank)',
+               targetTop: '최상위 창 (_top)',
+               targetSelf: '같은 창 (_self)',
+               targetParent: '부모 창 (_parent)',
+               langDirLTR: '왼쪽에서 오른쪽 (LTR)',
+               langDirRTL: '오른쪽에서 왼쪽 (RTL)',
+               styles: '스타일',
+               cssClasses: '스타일 시트 클래스',
+               width: '너비',
+               height: '높이',
+               align: '정렬',
+               alignLeft: '왼쪽',
+               alignRight: '오른쪽',
+               alignCenter: '가운데',
+               alignJustify: '양쪽 맞춤',
+               alignTop: '위',
+               alignMiddle: '중간',
+               alignBottom: '아래',
+               alignNone: '기본',
+               invalidValue: '잘못된 값.',
+               invalidHeight: '높이는 숫자여야 합니다.',
+               invalidWidth: '넓이는 숫자여야 합니다.',
+               invalidCssLength: '"%1" 값은 유효한 CSS 측정 단위(px, %, in, cm, mm, em, ex, pt, or pc)를 포함하거나 포함하지 않은 양수 여야 합니다.',
+               invalidHtmlLength: '"%1" 값은 유효한 HTML 측정 단위(px or %)를 포함하거나 포함하지 않은 양수여야 합니다.',
+               invalidInlineStyle: '인라인 스타일에 설정된 값은 "name : value" 형식을 가진 하나 이상의 투플(tuples)이 세미콜론(;)으로 구분되어 구성되어야 합니다.',
+               cssLengthTooltip: '픽셀 단위의 숫자만 입력하시거나 유효한 CSS 단위(px, %, in, cm, mm, em, ex, pt, or pc)와 함께 숫자를 입력해주세요.',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, 사용불가</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ku.js b/sources/lang/ku.js
new file mode 100644 (file)
index 0000000..ec53e49
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ku' ] = {
+       // ARIA description.
+       editor: 'سەرنووسەی دەقی تەواو',
+       editorPanel: 'بڕگەی سەرنووسەی دەقی تەواو',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'کلیکی ALT لەگەڵ 0 بکه‌ بۆ یارمەتی',
+
+               browseServer: 'هێنانی ڕاژە',
+               url: 'ناونیشانی بەستەر',
+               protocol: 'پڕۆتۆکۆڵ',
+               upload: 'بارکردن',
+               uploadSubmit: 'ناردنی بۆ ڕاژە',
+               image: 'وێنە',
+               flash: 'فلاش',
+               form: 'داڕشتە',
+               checkbox: 'خانەی نیشانکردن',
+               radio: 'جێگرەوەی دوگمە',
+               textField: 'خانەی دەق',
+               textarea: 'ڕووبەری دەق',
+               hiddenField: 'شاردنەوی خانە',
+               button: 'دوگمە',
+               select: 'هەڵبژاردەی خانە',
+               imageButton: 'دوگمەی وێنە',
+               notSet: '<هیچ دانەدراوە>',
+               id: 'ناسنامە',
+               name: 'ناو',
+               langDir: 'ئاراستەی زمان',
+               langDirLtr: 'چەپ بۆ ڕاست (LTR)',
+               langDirRtl: 'ڕاست بۆ چەپ (RTL)',
+               langCode: 'هێمای زمان',
+               longDescr: 'پێناسەی درێژی بەستەر',
+               cssClass: 'شێوازی چینی په‌ڕە',
+               advisoryTitle: 'ڕاوێژکاری سەردێڕ',
+               cssStyle: 'شێواز',
+               ok: 'باشە',
+               cancel: 'پاشگەزبوونەوە',
+               close: 'داخستن',
+               preview: 'پێشبینین',
+               resize: 'گۆڕینی ئەندازە',
+               generalTab: 'گشتی',
+               advancedTab: 'پەرەسەندوو',
+               validateNumberFailed: 'ئەم نرخە ژمارە نیە، تکایە نرخێکی ژمارە بنووسە.',
+               confirmNewPage: 'سەرجەم گۆڕانکاریەکان و پێکهاتەکانی ناووەوە لەدەست دەدەی گەر بێتوو پاشکەوتی نەکەی یەکەم جار، تۆ هەر دڵنیایی لەکردنەوەی پەنجەرەکی نوێ؟',
+               confirmCancel: 'هەندێك هەڵبژاردە گۆڕدراوە. تۆ دڵنیایی لە داخستنی ئەم دیالۆگە؟',
+               options: 'هەڵبژاردەکان',
+               target: 'ئامانج',
+               targetNew: 'پەنجەرەیەکی نوێ (_blank)',
+               targetTop: 'لووتکەی پەنجەرە (_top)',
+               targetSelf: 'لەهەمان پەنجەرە (_self)',
+               targetParent: 'پەنجەرەی باوان (_parent)',
+               langDirLTR: 'چەپ بۆ ڕاست (LTR)',
+               langDirRTL: 'ڕاست بۆ چەپ (RTL)',
+               styles: 'شێواز',
+               cssClasses: 'شێوازی چینی پەڕە',
+               width: 'پانی',
+               height: 'درێژی',
+               align: 'ڕێککەرەوە',
+               alignLeft: 'چەپ',
+               alignRight: 'ڕاست',
+               alignCenter: 'ناوەڕاست',
+               alignJustify: 'هاوستوونی',
+               alignTop: 'سەرەوە',
+               alignMiddle: 'ناوەند',
+               alignBottom: 'ژێرەوە',
+               alignNone: 'هیچ',
+               invalidValue: 'نرخێکی نادرووست.',
+               invalidHeight: 'درێژی دەبێت ژمارە بێت.',
+               invalidWidth: 'پانی دەبێت ژمارە بێت.',
+               invalidCssLength: 'ئەم نرخەی دراوە بۆ خانەی "%1" دەبێت ژمارەکی درووست بێت یان بێ ناونیشانی ئامرازی (px, %, in, cm, mm, em, ex, pt, یان pc).',
+               invalidHtmlLength: 'ئەم نرخەی دراوە بۆ خانەی "%1" دەبێت ژمارەکی درووست بێت یان بێ ناونیشانی ئامرازی HTML (px یان %).',
+               invalidInlineStyle: 'دانەی نرخی شێوازی ناوهێڵ دەبێت پێکهاتبێت لەیەك یان زیاتری داڕشتە "ناو : نرخ", جیاکردنەوەی بە فاریزە و خاڵ',
+               cssLengthTooltip: 'ژمارەیەك بنووسه‌ بۆ نرخی piksel یان ئامرازێکی درووستی CSS (px, %, in, cm, mm, em, ex, pt, یان pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, ئامادە نیە</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/lt.js b/sources/lang/lt.js
new file mode 100644 (file)
index 0000000..e6d9d7f
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Lithuanian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'lt' ] = {
+       // ARIA description.
+       editor: 'Pilnas redaktorius',
+       editorPanel: 'Pilno redagtoriaus skydelis',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Spauskite ALT 0 dėl pagalbos',
+
+               browseServer: 'Naršyti po serverį',
+               url: 'URL',
+               protocol: 'Protokolas',
+               upload: 'Siųsti',
+               uploadSubmit: 'Siųsti į serverį',
+               image: 'Vaizdas',
+               flash: 'Flash',
+               form: 'Forma',
+               checkbox: 'Žymimasis langelis',
+               radio: 'Žymimoji akutė',
+               textField: 'Teksto laukas',
+               textarea: 'Teksto sritis',
+               hiddenField: 'Nerodomas laukas',
+               button: 'Mygtukas',
+               select: 'Atrankos laukas',
+               imageButton: 'Vaizdinis mygtukas',
+               notSet: '<nėra nustatyta>',
+               id: 'Id',
+               name: 'Vardas',
+               langDir: 'Teksto kryptis',
+               langDirLtr: 'Iš kairės į dešinę (LTR)',
+               langDirRtl: 'Iš dešinės į kairę (RTL)',
+               langCode: 'Kalbos kodas',
+               longDescr: 'Ilgas aprašymas URL',
+               cssClass: 'Stilių lentelės klasės',
+               advisoryTitle: 'Konsultacinė antraštė',
+               cssStyle: 'Stilius',
+               ok: 'OK',
+               cancel: 'Nutraukti',
+               close: 'Uždaryti',
+               preview: 'Peržiūrėti',
+               resize: 'Pavilkite, kad pakeistumėte dydį',
+               generalTab: 'Bendros savybės',
+               advancedTab: 'Papildomas',
+               validateNumberFailed: 'Ši reikšmė nėra skaičius.',
+               confirmNewPage: 'Visas neišsaugotas turinys bus prarastas. Ar tikrai norite įkrauti naują puslapį?',
+               confirmCancel: 'Kai kurie parametrai pasikeitė. Ar tikrai norite užverti langą?',
+               options: 'Parametrai',
+               target: 'Tikslinė nuoroda',
+               targetNew: 'Naujas langas (_blank)',
+               targetTop: 'Viršutinis langas (_top)',
+               targetSelf: 'Esamas langas (_self)',
+               targetParent: 'Paskutinis langas (_parent)',
+               langDirLTR: 'Iš kairės į dešinę (LTR)',
+               langDirRTL: 'Iš dešinės į kairę (RTL)',
+               styles: 'Stilius',
+               cssClasses: 'Stilių klasės',
+               width: 'Plotis',
+               height: 'Aukštis',
+               align: 'Lygiuoti',
+               alignLeft: 'Kairę',
+               alignRight: 'Dešinę',
+               alignCenter: 'Centrą',
+               alignJustify: 'Lygiuoti abi puses',
+               alignTop: 'Viršūnę',
+               alignMiddle: 'Vidurį',
+               alignBottom: 'Apačią',
+               alignNone: 'Niekas',
+               invalidValue: 'Neteisinga reikšmė.',
+               invalidHeight: 'Aukštis turi būti nurodytas skaičiais.',
+               invalidWidth: 'Plotis turi būti nurodytas skaičiais.',
+               invalidCssLength: 'Reikšmė nurodyta "%1" laukui, turi būti teigiamas skaičius su arba be tinkamo CSS matavimo vieneto (px, %, in, cm, mm, em, ex, pt arba pc).',
+               invalidHtmlLength: 'Reikšmė nurodyta "%1" laukui, turi būti teigiamas skaičius su arba be tinkamo HTML matavimo vieneto (px arba %).',
+               invalidInlineStyle: 'Reikšmė nurodyta vidiniame stiliuje turi būti sudaryta iš vieno šių reikšmių "vardas : reikšmė", atskirta kabliataškiais.',
+               cssLengthTooltip: 'Įveskite reikšmę pikseliais arba skaičiais su tinkamu CSS vienetu (px, %, in, cm, mm, em, ex, pt arba pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, netinkamas</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/lv.js b/sources/lang/lv.js
new file mode 100644 (file)
index 0000000..1759e6c
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Latvian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'lv' ] = {
+       // ARIA description.
+       editor: 'Bagātinātā teksta redaktors',
+       editorPanel: 'Bagātinātā teksta redaktora panelis',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Palīdzībai, nospiediet ALT 0 ',
+
+               browseServer: 'Skatīt servera saturu',
+               url: 'URL',
+               protocol: 'Protokols',
+               upload: 'Augšupielādēt',
+               uploadSubmit: 'Nosūtīt serverim',
+               image: 'Attēls',
+               flash: 'Flash',
+               form: 'Forma',
+               checkbox: 'Atzīmēšanas kastīte',
+               radio: 'Izvēles poga',
+               textField: 'Teksta rinda',
+               textarea: 'Teksta laukums',
+               hiddenField: 'Paslēpta teksta rinda',
+               button: 'Poga',
+               select: 'Iezīmēšanas lauks',
+               imageButton: 'Attēlpoga',
+               notSet: '<nav iestatīts>',
+               id: 'Id',
+               name: 'Nosaukums',
+               langDir: 'Valodas lasīšanas virziens',
+               langDirLtr: 'No kreisās uz labo (LTR)',
+               langDirRtl: 'No labās uz kreiso (RTL)',
+               langCode: 'Valodas kods',
+               longDescr: 'Gara apraksta Hipersaite',
+               cssClass: 'Stilu saraksta klases',
+               advisoryTitle: 'Konsultatīvs virsraksts',
+               cssStyle: 'Stils',
+               ok: 'Darīts!',
+               cancel: 'Atcelt',
+               close: 'Aizvērt',
+               preview: 'Priekšskatījums',
+               resize: 'Mērogot',
+               generalTab: 'Vispārīgi',
+               advancedTab: 'Izvērstais',
+               validateNumberFailed: 'Šī vērtība nav skaitlis',
+               confirmNewPage: 'Jebkuras nesaglabātās izmaiņas tiks zaudētas. Vai tiešām vēlaties atvērt jaunu lapu?',
+               confirmCancel: 'Daži no uzstādījumiem ir mainīti. Vai tiešām vēlaties aizvērt šo dialogu?',
+               options: 'Uzstādījumi',
+               target: 'Mērķis',
+               targetNew: 'Jauns logs (_blank)',
+               targetTop: 'Virsējais logs (_top)',
+               targetSelf: 'Tas pats logs (_self)',
+               targetParent: 'Avota logs (_parent)',
+               langDirLTR: 'Kreisais uz Labo (LTR)',
+               langDirRTL: 'Labais uz Kreiso (RTL)',
+               styles: 'Stils',
+               cssClasses: 'Stilu klases',
+               width: 'Platums',
+               height: 'Augstums',
+               align: 'Nolīdzināt',
+               alignLeft: 'Pa kreisi',
+               alignRight: 'Pa labi',
+               alignCenter: 'Centrēti',
+               alignJustify: 'Izlīdzināt malas',
+               alignTop: 'Augšā',
+               alignMiddle: 'Vertikāli centrēts',
+               alignBottom: 'Apakšā',
+               alignNone: 'Nekas',
+               invalidValue: 'Nekorekta vērtība',
+               invalidHeight: 'Augstumam jābūt skaitlim.',
+               invalidWidth: 'Platumam jābūt skaitlim',
+               invalidCssLength: 'Laukam "%1" norādītajai vērtībai jābūt pozitīvam skaitlim ar vai bez korektām CSS mērvienībām (px, %, in, cm, mm, em, ex, pt, vai pc).',
+               invalidHtmlLength: 'Laukam "%1" norādītajai vērtībai jābūt pozitīvam skaitlim ar vai bez korektām HTML mērvienībām (px vai %).',
+               invalidInlineStyle: 'Iekļautajā stilā norādītajai vērtībai jāsastāv no viena vai vairākiem pāriem pēc forma\'ta "nosaukums: vērtība", atdalītiem ar semikolu.',
+               cssLengthTooltip: 'Ievadiet vērtību pikseļos vai skaitli ar derīgu CSS mērvienību (px, %, in, cm, mm, em, ex, pt, vai pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nav pieejams</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/mk.js b/sources/lang/mk.js
new file mode 100644 (file)
index 0000000..750da11
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'mk' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Притисни ALT 0 за помош',
+
+               browseServer: 'Пребарај низ серверот',
+               url: 'URL',
+               protocol: 'Протокол',
+               upload: 'Прикачи',
+               uploadSubmit: 'Прикачи на сервер',
+               image: 'Слика',
+               flash: 'Flash', // MISSING
+               form: 'Form', // MISSING
+               checkbox: 'Checkbox', // MISSING
+               radio: 'Radio Button', // MISSING
+               textField: 'Поле за текст',
+               textarea: 'Големо поле за текст',
+               hiddenField: 'Скриено поле',
+               button: 'Button',
+               select: 'Selection Field', // MISSING
+               imageButton: 'Копче-слика',
+               notSet: '<not set>',
+               id: 'Id',
+               name: 'Name',
+               langDir: 'Насока на јазик',
+               langDirLtr: 'Лево кон десно',
+               langDirRtl: 'Десно кон лево',
+               langCode: 'Код на јазик',
+               longDescr: 'Long Description URL', // MISSING
+               cssClass: 'Stylesheet Classes', // MISSING
+               advisoryTitle: 'Advisory Title', // MISSING
+               cssStyle: 'Стил',
+               ok: 'OK',
+               cancel: 'Cancel', // MISSING
+               close: 'Close', // MISSING
+               preview: 'Preview', // MISSING
+               resize: 'Resize', // MISSING
+               generalTab: 'Општо',
+               advancedTab: 'Advanced', // MISSING
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Опции',
+               target: 'Target', // MISSING
+               targetNew: 'Нов прозорец (_blank)',
+               targetTop: 'Најгорниот прозорец (_top)',
+               targetSelf: 'Истиот прозорец (_self)',
+               targetParent: 'Прозорец-родител (_parent)',
+               langDirLTR: 'Лево кон десно',
+               langDirRTL: 'Десно кон лево',
+               styles: 'Стил',
+               cssClasses: 'Stylesheet Classes', // MISSING
+               width: 'Широчина',
+               height: 'Височина',
+               align: 'Alignment', // MISSING
+               alignLeft: 'Лево',
+               alignRight: 'Десно',
+               alignCenter: 'Во средина',
+               alignJustify: 'Justify', // MISSING
+               alignTop: 'Горе',
+               alignMiddle: 'Средина',
+               alignBottom: 'Доле',
+               alignNone: 'Никое',
+               invalidValue: 'Невалидна вредност',
+               invalidHeight: 'Височината мора да биде број.',
+               invalidWidth: 'Широчината мора да биде број.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/mn.js b/sources/lang/mn.js
new file mode 100644 (file)
index 0000000..c5854a1
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Mongolian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'mn' ] = {
+       // ARIA description.
+       editor: 'Хэлбэрт бичвэр боловсруулагч',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Үйлчлэгч тооцоолуур (сервэр)-ийг үзэх',
+               url: 'цахим хуудасны хаяг (URL)',
+               protocol: 'Протокол',
+               upload: 'Илгээж ачаалах',
+               uploadSubmit: 'Үүнийг үйлчлэгч тооцоолуур (сервер) лүү илгээх',
+               image: 'Зураг',
+               flash: 'Флаш хөдөлгөөнтэй зураг',
+               form: 'Маягт',
+               checkbox: 'Тэмдэглээний нүд',
+               radio: 'Радио товчлуур',
+               textField: 'Бичвэрийн талбар',
+               textarea: 'Бичвэрийн зай',
+               hiddenField: 'Далд талбар',
+               button: 'Товчлуур',
+               select: 'Сонголтын талбар',
+               imageButton: 'Зургий товчуур',
+               notSet: '<тохируулаагүй>',
+               id: 'Id (техникийн нэр)',
+               name: 'Нэр',
+               langDir: 'Хэлний чиглэл',
+               langDirLtr: 'Зүүнээс баруун (LTR)',
+               langDirRtl: 'Баруунаас зүүн (RTL)',
+               langCode: 'Хэлний код',
+               longDescr: 'Урт тайлбарын вэб хаяг',
+               cssClass: 'Хэлбэрийн хуудасны ангиуд',
+               advisoryTitle: 'Зөвлөх гарчиг',
+               cssStyle: 'Загвар',
+               ok: 'За',
+               cancel: 'Болих',
+               close: 'Хаах',
+               preview: 'Урьдчилан харах',
+               resize: 'Resize', // MISSING
+               generalTab: 'Ерөнхий',
+               advancedTab: 'Гүнзгий',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Сонголт',
+               target: 'Бай',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'Зүүн талаас баруун тийшээ (LTR)',
+               langDirRTL: 'Баруун талаас зүүн тийшээ (RTL)',
+               styles: 'Загвар',
+               cssClasses: 'Хэлбэрийн хуудасны ангиуд',
+               width: 'Өргөн',
+               height: 'Өндөр',
+               align: 'Эгнээ',
+               alignLeft: 'Зүүн',
+               alignRight: 'Баруун',
+               alignCenter: 'Төвд',
+               alignJustify: 'Тэгшлэх',
+               alignTop: 'Дээд талд',
+               alignMiddle: 'Дунд',
+               alignBottom: 'Доод талд',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Өндөр нь тоо байх ёстой.',
+               invalidWidth: 'Өргөн нь тоо байх ёстой.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ms.js b/sources/lang/ms.js
new file mode 100644 (file)
index 0000000..764e92f
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Malay language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ms' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Browse Server',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Muat Naik',
+               uploadSubmit: 'Hantar ke Server',
+               image: 'Gambar',
+               flash: 'Flash', // MISSING
+               form: 'Borang',
+               checkbox: 'Checkbox',
+               radio: 'Butang Radio',
+               textField: 'Text Field',
+               textarea: 'Textarea',
+               hiddenField: 'Field Tersembunyi',
+               button: 'Butang',
+               select: 'Field Pilihan',
+               imageButton: 'Butang Bergambar',
+               notSet: '<tidak di set>',
+               id: 'Id',
+               name: 'Nama',
+               langDir: 'Arah Tulisan',
+               langDirLtr: 'Kiri ke Kanan (LTR)',
+               langDirRtl: 'Kanan ke Kiri (RTL)',
+               langCode: 'Kod Bahasa',
+               longDescr: 'Butiran Panjang URL',
+               cssClass: 'Kelas-kelas Stylesheet',
+               advisoryTitle: 'Tajuk Makluman',
+               cssStyle: 'Stail',
+               ok: 'OK',
+               cancel: 'Batal',
+               close: 'Tutup',
+               preview: 'Prebiu',
+               resize: 'Resize', // MISSING
+               generalTab: 'Umum',
+               advancedTab: 'Advanced',
+               validateNumberFailed: 'This value is not a number.', // MISSING
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Options', // MISSING
+               target: 'Sasaran',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'Kiri ke Kanan (LTR)',
+               langDirRTL: 'Kanan ke Kiri (RTL)',
+               styles: 'Stail',
+               cssClasses: 'Kelas-kelas Stylesheet',
+               width: 'Lebar',
+               height: 'Tinggi',
+               align: 'Jajaran',
+               alignLeft: 'Kiri',
+               alignRight: 'Kanan',
+               alignCenter: 'Tengah',
+               alignJustify: 'Jajaran Blok',
+               alignTop: 'Atas',
+               alignMiddle: 'Pertengahan',
+               alignBottom: 'Bawah',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Nilai tidak sah.',
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/nb.js b/sources/lang/nb.js
new file mode 100644 (file)
index 0000000..e27c582
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Norwegian Bokmål language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'nb' ] = {
+       // ARIA description.
+       editor: 'Rikteksteditor',
+       editorPanel: 'Panel for rikteksteditor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Trykk ALT 0 for hjelp',
+
+               browseServer: 'Bla gjennom tjener',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Last opp',
+               uploadSubmit: 'Send det til serveren',
+               image: 'Bilde',
+               flash: 'Flash',
+               form: 'Skjema',
+               checkbox: 'Avmerkingsboks',
+               radio: 'Alternativknapp',
+               textField: 'Tekstboks',
+               textarea: 'Tekstområde',
+               hiddenField: 'Skjult felt',
+               button: 'Knapp',
+               select: 'Rullegardinliste',
+               imageButton: 'Bildeknapp',
+               notSet: '<ikke satt>',
+               id: 'Id',
+               name: 'Navn',
+               langDir: 'Språkretning',
+               langDirLtr: 'Venstre til høyre (LTR)',
+               langDirRtl: 'Høyre til venstre (RTL)',
+               langCode: 'Språkkode',
+               longDescr: 'Utvidet beskrivelse',
+               cssClass: 'Stilarkklasser',
+               advisoryTitle: 'Tittel',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Avbryt',
+               close: 'Lukk',
+               preview: 'Forhåndsvis',
+               resize: 'Dra for å skalere',
+               generalTab: 'Generelt',
+               advancedTab: 'Avansert',
+               validateNumberFailed: 'Denne verdien er ikke et tall.',
+               confirmNewPage: 'Alle ulagrede endringer som er gjort i dette innholdet vil gå tapt. Er du sikker på at du vil laste en ny side?',
+               confirmCancel: 'Du har endret noen alternativer. Er du sikker på at du vil lukke dialogvinduet?',
+               options: 'Valg',
+               target: 'Mål',
+               targetNew: 'Nytt vindu (_blank)',
+               targetTop: 'Hele vinduet (_top)',
+               targetSelf: 'Samme vindu (_self)',
+               targetParent: 'Foreldrevindu (_parent)',
+               langDirLTR: 'Venstre til høyre (VTH)',
+               langDirRTL: 'Høyre til venstre (HTV)',
+               styles: 'Stil',
+               cssClasses: 'Stilarkklasser',
+               width: 'Bredde',
+               height: 'Høyde',
+               align: 'Juster',
+               alignLeft: 'Venstre',
+               alignRight: 'Høyre',
+               alignCenter: 'Midtjuster',
+               alignJustify: 'Blokkjuster',
+               alignTop: 'Topp',
+               alignMiddle: 'Midten',
+               alignBottom: 'Bunn',
+               alignNone: 'Ingen',
+               invalidValue: 'Ugyldig verdi.',
+               invalidHeight: 'Høyde må være et tall.',
+               invalidWidth: 'Bredde må være et tall.',
+               invalidCssLength: 'Den angitte verdien for feltet "%1" må være et positivt tall med eller uten en gyldig CSS-målingsenhet (px, %, in, cm, mm, em, ex, pt, eller pc).',
+               invalidHtmlLength: 'Den angitte verdien for feltet "%1" må være et positivt tall med eller uten en gyldig HTML-målingsenhet (px eller %).',
+               invalidInlineStyle: 'Verdi angitt for inline stil må bestå av en eller flere sett med formatet "navn : verdi", separert med semikolon',
+               cssLengthTooltip: 'Skriv inn et tall for en piksel-verdi eller et tall med en gyldig CSS-enhet (px, %, in, cm, mm, em, ex, pt, eller pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, utilgjenglig</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Mellomrom',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Tastatursnarvei'
+       }
+};
diff --git a/sources/lang/nl.js b/sources/lang/nl.js
new file mode 100644 (file)
index 0000000..5f1f251
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Dutch language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'nl' ] = {
+       // ARIA description.
+       editor: 'Tekstverwerker',
+       editorPanel: 'Tekstverwerker beheerpaneel',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Druk ALT 0 voor hulp',
+
+               browseServer: 'Bladeren op server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Upload',
+               uploadSubmit: 'Naar server verzenden',
+               image: 'Afbeelding',
+               flash: 'Flash',
+               form: 'Formulier',
+               checkbox: 'Selectievinkje',
+               radio: 'Keuzerondje',
+               textField: 'Tekstveld',
+               textarea: 'Tekstvak',
+               hiddenField: 'Verborgen veld',
+               button: 'Knop',
+               select: 'Selectieveld',
+               imageButton: 'Afbeeldingsknop',
+               notSet: '<niet ingevuld>',
+               id: 'Id',
+               name: 'Naam',
+               langDir: 'Schrijfrichting',
+               langDirLtr: 'Links naar rechts (LTR)',
+               langDirRtl: 'Rechts naar links (RTL)',
+               langCode: 'Taalcode',
+               longDescr: 'Lange URL-omschrijving',
+               cssClass: 'Stylesheet-klassen',
+               advisoryTitle: 'Adviserende titel',
+               cssStyle: 'Stijl',
+               ok: 'OK',
+               cancel: 'Annuleren',
+               close: 'Sluiten',
+               preview: 'Voorbeeld',
+               resize: 'Sleep om te herschalen',
+               generalTab: 'Algemeen',
+               advancedTab: 'Geavanceerd',
+               validateNumberFailed: 'Deze waarde is geen geldig getal.',
+               confirmNewPage: 'Alle aangebrachte wijzigingen gaan verloren. Weet u zeker dat u een nieuwe pagina wilt openen?',
+               confirmCancel: 'Enkele opties zijn gewijzigd. Weet u zeker dat u dit dialoogvenster wilt sluiten?',
+               options: 'Opties',
+               target: 'Doelvenster',
+               targetNew: 'Nieuw venster (_blank)',
+               targetTop: 'Hele venster (_top)',
+               targetSelf: 'Zelfde venster (_self)',
+               targetParent: 'Origineel venster (_parent)',
+               langDirLTR: 'Links naar rechts (LTR)',
+               langDirRTL: 'Rechts naar links (RTL)',
+               styles: 'Stijl',
+               cssClasses: 'Stylesheet-klassen',
+               width: 'Breedte',
+               height: 'Hoogte',
+               align: 'Uitlijning',
+               alignLeft: 'Links',
+               alignRight: 'Rechts',
+               alignCenter: 'Centreren',
+               alignJustify: 'Uitvullen',
+               alignTop: 'Boven',
+               alignMiddle: 'Midden',
+               alignBottom: 'Onder',
+               alignNone: 'Geen',
+               invalidValue: 'Ongeldige waarde.',
+               invalidHeight: 'De hoogte moet een getal zijn.',
+               invalidWidth: 'De breedte moet een getal zijn.',
+               invalidCssLength: 'Waarde in veld "%1" moet een positief nummer zijn, met of zonder een geldige CSS meeteenheid (px, %, in, cm, mm, em, ex, pt of pc).',
+               invalidHtmlLength: 'Waarde in veld "%1" moet een positief nummer zijn, met of zonder een geldige HTML meeteenheid (px of %).',
+               invalidInlineStyle: 'Waarde voor de online stijl moet bestaan uit een of meerdere tupels met het formaat "naam : waarde", gescheiden door puntkomma\'s.',
+               cssLengthTooltip: 'Geef een nummer in voor een waarde in pixels of geef een nummer in met een geldige CSS eenheid (px, %, in, cm, mm, em, ex, pt, of pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, niet beschikbaar</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Spatie',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Verwijderen',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Sneltoets'
+       }
+};
diff --git a/sources/lang/no.js b/sources/lang/no.js
new file mode 100644 (file)
index 0000000..87691f9
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Norwegian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'no' ] = {
+       // ARIA description.
+       editor: 'Rikteksteditor',
+       editorPanel: 'Panel for rikteksteditor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Trykk ALT 0 for hjelp',
+
+               browseServer: 'Bla igjennom server',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Last opp',
+               uploadSubmit: 'Send det til serveren',
+               image: 'Bilde',
+               flash: 'Flash',
+               form: 'Skjema',
+               checkbox: 'Avmerkingsboks',
+               radio: 'Alternativknapp',
+               textField: 'Tekstboks',
+               textarea: 'Tekstområde',
+               hiddenField: 'Skjult felt',
+               button: 'Knapp',
+               select: 'Rullegardinliste',
+               imageButton: 'Bildeknapp',
+               notSet: '<ikke satt>',
+               id: 'Id',
+               name: 'Navn',
+               langDir: 'Språkretning',
+               langDirLtr: 'Venstre til høyre (VTH)',
+               langDirRtl: 'Høyre til venstre (HTV)',
+               langCode: 'Språkkode',
+               longDescr: 'Utvidet beskrivelse',
+               cssClass: 'Stilarkklasser',
+               advisoryTitle: 'Tittel',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Avbryt',
+               close: 'Lukk',
+               preview: 'Forhåndsvis',
+               resize: 'Dra for å skalere',
+               generalTab: 'Generelt',
+               advancedTab: 'Avansert',
+               validateNumberFailed: 'Denne verdien er ikke et tall.',
+               confirmNewPage: 'Alle ulagrede endringer som er gjort i dette innholdet vil bli tapt. Er du sikker på at du vil laste en ny side?',
+               confirmCancel: 'Noen av valgene har blitt endret. Er du sikker på at du vil lukke dialogen?',
+               options: 'Valg',
+               target: 'Mål',
+               targetNew: 'Nytt vindu (_blank)',
+               targetTop: 'Hele vindu (_top)',
+               targetSelf: 'Samme vindu (_self)',
+               targetParent: 'Foreldrevindu (_parent)',
+               langDirLTR: 'Venstre til høyre (VTH)',
+               langDirRTL: 'Høyre til venstre (HTV)',
+               styles: 'Stil',
+               cssClasses: 'Stilarkklasser',
+               width: 'Bredde',
+               height: 'Høyde',
+               align: 'Juster',
+               alignLeft: 'Venstre',
+               alignRight: 'Høyre',
+               alignCenter: 'Midtjuster',
+               alignJustify: 'Blokkjuster',
+               alignTop: 'Topp',
+               alignMiddle: 'Midten',
+               alignBottom: 'Bunn',
+               alignNone: 'Ingen',
+               invalidValue: 'Ugyldig verdi.',
+               invalidHeight: 'Høyde må være et tall.',
+               invalidWidth: 'Bredde må være et tall.',
+               invalidCssLength: 'Den angitte verdien for feltet "%1" må være et positivt tall med eller uten en gyldig CSS-målingsenhet (px, %, in, cm, mm, em, ex, pt, eller pc).',
+               invalidHtmlLength: 'Den angitte verdien for feltet "%1" må være et positivt tall med eller uten en gyldig HTML-målingsenhet (px eller %).',
+               invalidInlineStyle: 'Verdi angitt for inline stil må bestå av en eller flere sett med formatet "navn : verdi", separert med semikolon',
+               cssLengthTooltip: 'Skriv inn et tall for en piksel-verdi eller et tall med en gyldig CSS-enhet (px, %, in, cm, mm, em, ex, pt, eller pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, utilgjenglig</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/oc.js b/sources/lang/oc.js
new file mode 100644 (file)
index 0000000..a78420f
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the Occitan
+ *             language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'oc' ] = {
+       // ARIA description.
+       editor: 'Editor de tèxte enriquit',
+       editorPanel: 'Tablèu de bòrd de l\'editor de tèxte enriquit',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Utilisatz l\'acorchi Alt-0 per obténer d\'ajuda',
+
+               browseServer: 'Percórrer lo servidor',
+               url: 'URL',
+               protocol: 'Protocòl',
+               upload: 'Mandar',
+               uploadSubmit: 'Mandar sul servidor',
+               image: 'Imatge',
+               flash: 'Flash',
+               form: 'Formulari',
+               checkbox: 'Casa de marcar',
+               radio: 'Boton ràdio',
+               textField: 'Camp  tèxte',
+               textarea: 'Zòna de tèxte',
+               hiddenField: 'Camp invisible',
+               button: 'Boton',
+               select: 'Lista desenrotlanta',
+               imageButton: 'Boton amb imatge',
+               notSet: '<indefinit>',
+               id: 'Id',
+               name: 'Nom',
+               langDir: 'Sens d\'escritura',
+               langDirLtr: 'Esquèrra a dreita (LTR)',
+               langDirRtl: 'Dreita a esquèrra (RTL)',
+               langCode: 'Còdi de lenga',
+               longDescr: 'URL de descripcion longa',
+               cssClass: 'Classas d\'estil',
+               advisoryTitle: 'Infobulla',
+               cssStyle: 'Estil',
+               ok: 'D\'acòrdi',
+               cancel: 'Anullar',
+               close: 'Tampar',
+               preview: 'Previsualizar',
+               resize: 'Redimensionar',
+               generalTab: 'General',
+               advancedTab: 'Avançat',
+               validateNumberFailed: 'Aquesta valor es pas un nombre.',
+               confirmNewPage: 'Los cambiaments pas salvats seràn perduts. Sètz segur que volètz cargar una novèla pagina ?',
+               confirmCancel: 'Certanas opcions son estadas modificadas. Sètz segur que volètz tampar ?',
+               options: 'Opcions',
+               target: 'Cibla',
+               targetNew: 'Novèla fenèstra (_blank)',
+               targetTop: 'Fenèstra superiora (_top)',
+               targetSelf: 'Meteissa fenèstra (_self)',
+               targetParent: 'Fenèstra parent (_parent)',
+               langDirLTR: 'Esquèrra a dreita (LTR)',
+               langDirRTL: 'Dreita a esquèrra (RTL)',
+               styles: 'Estil',
+               cssClasses: 'Classas d\'estil',
+               width: 'Largor',
+               height: 'Nautor',
+               align: 'Alinhament',
+               alignLeft: 'Esquèrra',
+               alignRight: 'Dreita',
+               alignCenter: 'Centrar',
+               alignJustify: 'Justificar',
+               alignTop: 'Naut',
+               alignMiddle: 'Mitan',
+               alignBottom: 'Bas',
+               alignNone: 'Pas cap',
+               invalidValue: 'Valor invalida.',
+               invalidHeight: 'La nautor deu èsser un nombre.',
+               invalidWidth: 'La largor deu èsser un nombre.',
+               invalidCssLength: 'La valor especificada pel camp « %1 » deu èsser un nombre positiu amb o sens unitat de mesura CSS valid (px, %, in, cm, mm, em, ex, pt, o pc).',
+               invalidHtmlLength: 'La valor especificada pel camp « %1 » deu èsser un nombre positiu amb o sens unitat de mesura HTML valid (px o %).',
+               invalidInlineStyle: 'La valor especificada per l\'estil en linha deu èsser compausada d\'un o mantun parelh al format « nom : valor », separats per de punts-virgulas.',
+               cssLengthTooltip: 'Entrar un nombre per una valor en pixèls o un nombre amb una unitat de mesura CSS valida (px, %, in, cm, mm, em, ex, pt, o pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, indisponible</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Retorn',
+                       13: 'Entrada',
+                       16: 'Majuscula',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Espaci',
+                       35: 'Fin',
+                       36: 'Origina',
+                       46: 'Suprimir',
+                       224: 'Comanda'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Acorchi de clavièr'
+       }
+};
diff --git a/sources/lang/pl.js b/sources/lang/pl.js
new file mode 100644 (file)
index 0000000..3290a6b
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Polish language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'pl' ] = {
+       // ARIA description.
+       editor: 'Edytor tekstu sformatowanego',
+       editorPanel: 'Panel edytora tekstu sformatowanego',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'W celu uzyskania pomocy naciśnij ALT 0',
+
+               browseServer: 'Przeglądaj',
+               url: 'Adres URL',
+               protocol: 'Protokół',
+               upload: 'Wyślij',
+               uploadSubmit: 'Wyślij',
+               image: 'Obrazek',
+               flash: 'Flash',
+               form: 'Formularz',
+               checkbox: 'Pole wyboru (checkbox)',
+               radio: 'Przycisk opcji (radio)',
+               textField: 'Pole tekstowe',
+               textarea: 'Obszar tekstowy',
+               hiddenField: 'Pole ukryte',
+               button: 'Przycisk',
+               select: 'Lista wyboru',
+               imageButton: 'Przycisk graficzny',
+               notSet: '<nie ustawiono>',
+               id: 'Id',
+               name: 'Nazwa',
+               langDir: 'Kierunek tekstu',
+               langDirLtr: 'Od lewej do prawej (LTR)',
+               langDirRtl: 'Od prawej do lewej (RTL)',
+               langCode: 'Kod języka',
+               longDescr: 'Adres URL długiego opisu',
+               cssClass: 'Nazwa klasy CSS',
+               advisoryTitle: 'Opis obiektu docelowego',
+               cssStyle: 'Styl',
+               ok: 'OK',
+               cancel: 'Anuluj',
+               close: 'Zamknij',
+               preview: 'Podgląd',
+               resize: 'Przeciągnij, aby zmienić rozmiar',
+               generalTab: 'Ogólne',
+               advancedTab: 'Zaawansowane',
+               validateNumberFailed: 'Ta wartość nie jest liczbą.',
+               confirmNewPage: 'Wszystkie niezapisane zmiany zostaną utracone. Czy na pewno wczytać nową stronę?',
+               confirmCancel: 'Pewne opcje zostały zmienione. Czy na pewno zamknąć okno dialogowe?',
+               options: 'Opcje',
+               target: 'Obiekt docelowy',
+               targetNew: 'Nowe okno (_blank)',
+               targetTop: 'Okno najwyżej w hierarchii (_top)',
+               targetSelf: 'To samo okno (_self)',
+               targetParent: 'Okno nadrzędne (_parent)',
+               langDirLTR: 'Od lewej do prawej (LTR)',
+               langDirRTL: 'Od prawej do lewej (RTL)',
+               styles: 'Style',
+               cssClasses: 'Klasy arkusza stylów',
+               width: 'Szerokość',
+               height: 'Wysokość',
+               align: 'Wyrównaj',
+               alignLeft: 'Do lewej',
+               alignRight: 'Do prawej',
+               alignCenter: 'Do środka',
+               alignJustify: 'Wyjustuj',
+               alignTop: 'Do góry',
+               alignMiddle: 'Do środka',
+               alignBottom: 'Do dołu',
+               alignNone: 'Brak',
+               invalidValue: 'Nieprawidłowa wartość.',
+               invalidHeight: 'Wysokość musi być liczbą.',
+               invalidWidth: 'Szerokość musi być liczbą.',
+               invalidCssLength: 'Wartość podana dla pola "%1" musi być liczbą dodatnią bez jednostki lub z poprawną jednostką długości zgodną z CSS (px, %, in, cm, mm, em, ex, pt lub pc).',
+               invalidHtmlLength: 'Wartość podana dla pola "%1" musi być liczbą dodatnią bez jednostki lub z poprawną jednostką długości zgodną z HTML (px lub %).',
+               invalidInlineStyle: 'Wartość podana dla stylu musi składać się z jednej lub większej liczby krotek w formacie "nazwa : wartość", rozdzielonych średnikami.',
+               cssLengthTooltip: 'Wpisz liczbę dla wartości w pikselach lub liczbę wraz z jednostką długości zgodną z CSS (px, %, in, cm, mm, em, ex, pt lub pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, niedostępne</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'spacja',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Skrót klawiszowy'
+       }
+};
diff --git a/sources/lang/pt-br.js b/sources/lang/pt-br.js
new file mode 100644 (file)
index 0000000..a6bc34f
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+* @fileOverview
+*/
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'pt-br' ] = {
+       // ARIA description.
+       editor: 'Editor de Rich Text',
+       editorPanel: 'Painel do editor de Rich Text',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Pressione ALT+0 para ajuda',
+
+               browseServer: 'Localizar no Servidor',
+               url: 'URL',
+               protocol: 'Protocolo',
+               upload: 'Enviar ao Servidor',
+               uploadSubmit: 'Enviar para o Servidor',
+               image: 'Imagem',
+               flash: 'Flash',
+               form: 'Formulário',
+               checkbox: 'Caixa de Seleção',
+               radio: 'Botão de Opção',
+               textField: 'Caixa de Texto',
+               textarea: 'Área de Texto',
+               hiddenField: 'Campo Oculto',
+               button: 'Botão',
+               select: 'Caixa de Listagem',
+               imageButton: 'Botão de Imagem',
+               notSet: '<não ajustado>',
+               id: 'Id',
+               name: 'Nome',
+               langDir: 'Direção do idioma',
+               langDirLtr: 'Esquerda para Direita (LTR)',
+               langDirRtl: 'Direita para Esquerda (RTL)',
+               langCode: 'Idioma',
+               longDescr: 'Descrição da URL',
+               cssClass: 'Classe de CSS',
+               advisoryTitle: 'Título',
+               cssStyle: 'Estilos',
+               ok: 'OK',
+               cancel: 'Cancelar',
+               close: 'Fechar',
+               preview: 'Visualizar',
+               resize: 'Arraste para redimensionar',
+               generalTab: 'Geral',
+               advancedTab: 'Avançado',
+               validateNumberFailed: 'Este valor não é um número.',
+               confirmNewPage: 'Todas as mudanças não salvas serão perdidas. Tem certeza de que quer abrir uma nova página?',
+               confirmCancel: 'Algumas opções foram alteradas. Tem certeza de que quer fechar a caixa de diálogo?',
+               options: 'Opções',
+               target: 'Destino',
+               targetNew: 'Nova Janela (_blank)',
+               targetTop: 'Janela de Cima (_top)',
+               targetSelf: 'Mesma Janela (_self)',
+               targetParent: 'Janela Pai (_parent)',
+               langDirLTR: 'Esquerda para Direita (LTR)',
+               langDirRTL: 'Direita para Esquerda (RTL)',
+               styles: 'Estilo',
+               cssClasses: 'Classes',
+               width: 'Largura',
+               height: 'Altura',
+               align: 'Alinhamento',
+               alignLeft: 'Esquerda',
+               alignRight: 'Direita',
+               alignCenter: 'Centralizado',
+               alignJustify: 'Justificar',
+               alignTop: 'Superior',
+               alignMiddle: 'Centralizado',
+               alignBottom: 'Inferior',
+               alignNone: 'Nenhum',
+               invalidValue: 'Valor inválido.',
+               invalidHeight: 'A altura tem que ser um número',
+               invalidWidth: 'A largura tem que ser um número.',
+               invalidCssLength: 'O valor do campo "%1" deve ser um número positivo opcionalmente seguido por uma válida unidade de medida de CSS (px, %, in, cm, mm, em, ex, pt ou pc).',
+               invalidHtmlLength: 'O valor do campo "%1" deve ser um número positivo opcionalmente seguido por uma válida unidade de medida de HTML (px ou %).',
+               invalidInlineStyle: 'O valor válido para estilo deve conter uma ou mais tuplas no formato "nome : valor", separados por ponto e vírgula.',
+               cssLengthTooltip: 'Insira um número para valor em pixels ou um número seguido de uma válida unidade de medida de CSS (px, %, in, cm, mm, em, ex, pt ou pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, indisponível</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Tecla Retroceder',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Tecla Espaço',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Comando'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Atalho do teclado'
+       }
+};
diff --git a/sources/lang/pt.js b/sources/lang/pt.js
new file mode 100644 (file)
index 0000000..d5ae35e
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Portuguese language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'pt' ] = {
+       // ARIA description.
+       editor: 'Editor de texto enriquecido',
+       editorPanel: 'Painel do editor de texto enriquecido',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Pressione ALT+0 para ajuda',
+
+               browseServer: 'Navegar no servidor',
+               url: 'URL',
+               protocol: 'Protocolo',
+               upload: 'Carregar',
+               uploadSubmit: 'Enviar para o servidor',
+               image: 'Imagem',
+               flash: 'Flash',
+               form: 'Formulário',
+               checkbox: 'Caixa de verificação',
+               radio: 'Botão',
+               textField: 'Campo de texto',
+               textarea: 'Área de texto',
+               hiddenField: 'Campo oculto',
+               button: 'Botão',
+               select: 'Campo de seleção',
+               imageButton: 'Botão da imagem',
+               notSet: '<Não definido>',
+               id: 'ID',
+               name: 'Nome',
+               langDir: 'Direção do idioma',
+               langDirLtr: 'Esquerda para a Direita (EPD)',
+               langDirRtl: 'Direita para a Esquerda (DPE)',
+               langCode: 'Código do idioma',
+               longDescr: 'Descrição completa do URL',
+               cssClass: 'Classes de estilo das folhas',
+               advisoryTitle: 'Título consultivo',
+               cssStyle: 'Estilo',
+               ok: 'CONFIRMAR',
+               cancel: 'Cancelar',
+               close: 'Fechar',
+               preview: 'Pré-visualização',
+               resize: 'Redimensionar',
+               generalTab: 'Geral',
+               advancedTab: 'Avançado',
+               validateNumberFailed: 'Este valor não é um numero.',
+               confirmNewPage: 'Irão ser perdidas quaisquer alterações não guardadas. Tem a certeza que deseja carregar a nova página?',
+               confirmCancel: 'Foram alteradas algumas das opções. Tem a certeza que deseja fechar a janela?',
+               options: 'Opções',
+               target: 'Destino',
+               targetNew: 'Nova janela (_blank)',
+               targetTop: 'Janela superior (_top)',
+               targetSelf: 'Mesma janela (_self)',
+               targetParent: 'Janela dependente (_parent)',
+               langDirLTR: 'Esquerda para a Direita (EPD)',
+               langDirRTL: 'Direita para a Esquerda (DPE)',
+               styles: 'Estilo',
+               cssClasses: 'Classes de folhas de estilo',
+               width: 'Largura',
+               height: 'Altura',
+               align: 'Alinhamento',
+               alignLeft: 'Esquerda',
+               alignRight: 'Direita',
+               alignCenter: 'Centrado',
+               alignJustify: 'Justificado',
+               alignTop: 'Topo',
+               alignMiddle: 'Centro',
+               alignBottom: 'Base',
+               alignNone: 'Nenhum',
+               invalidValue: 'Valor inválido.',
+               invalidHeight: 'A altura deve ser um número.',
+               invalidWidth: 'A largura deve ser um número. ',
+               invalidCssLength: 'O valor especificado para o campo "1%" deve ser um número positivo, com ou sem uma unidade de medida CSS válida (px, %, in, cm, mm, em, ex, pt, ou pc).',
+               invalidHtmlLength: 'O valor especificado para o campo "1%" deve ser um número positivo, com ou sem uma unidade de medida HTML válida (px ou %).',
+               invalidInlineStyle: 'O valor especificado para o estilo em linha deve constituir um ou mais conjuntos de valores com o formato de "nome : valor", separados por ponto e vírgula.',
+               cssLengthTooltip: 'Insira um número para um valor em pontos ou um número com uma unidade CSS válida (px, %, in, cm, mm, em, ex, pt, ou pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, indisponível</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'Fim',
+                       36: 'Entrada',
+                       46: 'Eliminar',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ro.js b/sources/lang/ro.js
new file mode 100644 (file)
index 0000000..d118aba
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Romanian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ro' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Apasă ALT 0 pentru ajutor',
+
+               browseServer: 'Răsfoieşte server',
+               url: 'URL',
+               protocol: 'Protocol',
+               upload: 'Încarcă',
+               uploadSubmit: 'Trimite la server',
+               image: 'Imagine',
+               flash: 'Flash',
+               form: 'Formular (Form)',
+               checkbox: 'Bifă (Checkbox)',
+               radio: 'Buton radio (RadioButton)',
+               textField: 'Câmp text (TextField)',
+               textarea: 'Suprafaţă text (Textarea)',
+               hiddenField: 'Câmp ascuns (HiddenField)',
+               button: 'Buton',
+               select: 'Câmp selecţie (SelectionField)',
+               imageButton: 'Buton imagine (ImageButton)',
+               notSet: '<nesetat>',
+               id: 'Id',
+               name: 'Nume',
+               langDir: 'Direcţia cuvintelor',
+               langDirLtr: 'stânga-dreapta (LTR)',
+               langDirRtl: 'dreapta-stânga (RTL)',
+               langCode: 'Codul limbii',
+               longDescr: 'Descrierea lungă URL',
+               cssClass: 'Clasele cu stilul paginii (CSS)',
+               advisoryTitle: 'Titlul consultativ',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Anulare',
+               close: 'Închide',
+               preview: 'Previzualizare',
+               resize: 'Trage pentru a redimensiona',
+               generalTab: 'General',
+               advancedTab: 'Avansat',
+               validateNumberFailed: 'Această valoare nu este un număr.',
+               confirmNewPage: 'Orice modificări nesalvate ale acestui conținut, vor fi pierdute. Sigur doriți încărcarea unei noi pagini?',
+               confirmCancel: 'Câteva opțiuni au fost schimbate. Sigur doriți să închideți dialogul?',
+               options: 'Opțiuni',
+               target: 'Țintă',
+               targetNew: 'Fereastră nouă (_blank)',
+               targetTop: 'Topmost Window (_top)',
+               targetSelf: 'În aceeași fereastră (_self)',
+               targetParent: 'Parent Window (_parent)',
+               langDirLTR: 'Stânga spre Dreapta (LTR)',
+               langDirRTL: 'Dreapta spre Stânga (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Stylesheet Classes',
+               width: 'Lăţime',
+               height: 'Înălţime',
+               align: 'Aliniere',
+               alignLeft: 'Mărește Bara',
+               alignRight: 'Dreapta',
+               alignCenter: 'Centru',
+               alignJustify: 'Aliniere în bloc (Block Justify)',
+               alignTop: 'Sus',
+               alignMiddle: 'Mijloc',
+               alignBottom: 'Jos',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Valoare invalidă',
+               invalidHeight: 'Înălțimea trebuie să fie un număr.',
+               invalidWidth: 'Lățimea trebuie să fie un număr.',
+               invalidCssLength: 'Valoarea specificată pentru câmpul "%1" trebuie să fie un număr pozitiv cu sau fără o unitate de măsură CSS (px, %, in, cm, mm, em, ex, pt, sau pc).',
+               invalidHtmlLength: 'Valoarea specificată pentru câmpul "%1" trebuie să fie un număr pozitiv cu sau fără o unitate de măsură HTML (px sau %).',
+               invalidInlineStyle: 'Valoarea specificată pentru stil trebuie să conțină una sau mai multe construcții de tipul "name : value", separate prin punct și virgulă.',
+               cssLengthTooltip: 'Introduceți un număr în pixeli sau un număr cu o unitate de măsură CSS (px, %, in, cm, mm, em, ex, pt, sau pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nu este disponibil</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ru.js b/sources/lang/ru.js
new file mode 100644 (file)
index 0000000..1ccc052
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object for the
+ * Russian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ru' ] = {
+       // ARIA description.
+       editor: 'Визуальный текстовый редактор',
+       editorPanel: 'Визуальный редактор текста',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Нажмите ALT-0 для открытия справки',
+
+               browseServer: 'Выбор на сервере',
+               url: 'Ссылка',
+               protocol: 'Протокол',
+               upload: 'Загрузка файла',
+               uploadSubmit: 'Загрузить на сервер',
+               image: 'Изображение',
+               flash: 'Flash',
+               form: 'Форма',
+               checkbox: 'Чекбокс',
+               radio: 'Радиокнопка',
+               textField: 'Текстовое поле',
+               textarea: 'Многострочное текстовое поле',
+               hiddenField: 'Скрытое поле',
+               button: 'Кнопка',
+               select: 'Выпадающий список',
+               imageButton: 'Кнопка-изображение',
+               notSet: '<не указано>',
+               id: 'Идентификатор',
+               name: 'Имя',
+               langDir: 'Направление текста',
+               langDirLtr: 'Слева направо (LTR)',
+               langDirRtl: 'Справа налево (RTL)',
+               langCode: 'Код языка',
+               longDescr: 'Длинное описание ссылки',
+               cssClass: 'Класс CSS',
+               advisoryTitle: 'Заголовок',
+               cssStyle: 'Стиль',
+               ok: 'ОК',
+               cancel: 'Отмена',
+               close: 'Закрыть',
+               preview: 'Предпросмотр',
+               resize: 'Перетащите для изменения размера',
+               generalTab: 'Основное',
+               advancedTab: 'Дополнительно',
+               validateNumberFailed: 'Это значение не является числом.',
+               confirmNewPage: 'Несохранённые изменения будут потеряны! Вы действительно желаете перейти на другую страницу?',
+               confirmCancel: 'Некоторые параметры были изменены. Вы уверены, что желаете закрыть без сохранения?',
+               options: 'Параметры',
+               target: 'Цель',
+               targetNew: 'Новое окно (_blank)',
+               targetTop: 'Главное окно (_top)',
+               targetSelf: 'Текущее окно (_self)',
+               targetParent: 'Родительское окно (_parent)',
+               langDirLTR: 'Слева направо (LTR)',
+               langDirRTL: 'Справа налево (RTL)',
+               styles: 'Стиль',
+               cssClasses: 'CSS классы',
+               width: 'Ширина',
+               height: 'Высота',
+               align: 'Выравнивание',
+               alignLeft: 'По левому краю',
+               alignRight: 'По правому краю',
+               alignCenter: 'По центру',
+               alignJustify: 'По ширине',
+               alignTop: 'Поверху',
+               alignMiddle: 'Посередине',
+               alignBottom: 'Понизу',
+               alignNone: 'Нет',
+               invalidValue: 'Недопустимое значение.',
+               invalidHeight: 'Высота задается числом.',
+               invalidWidth: 'Ширина задается числом.',
+               invalidCssLength: 'Значение, указанное в поле "%1", должно быть положительным целым числом. Допускается указание единиц меры CSS (px, %, in, cm, mm, em, ex, pt или pc).',
+               invalidHtmlLength: 'Значение, указанное в поле "%1", должно быть положительным целым числом. Допускается указание единиц меры HTML (px или %).',
+               invalidInlineStyle: 'Значение, указанное для стиля элемента, должно состоять из одной или нескольких пар данных в формате "параметр : значение", разделённых точкой с запятой.',
+               cssLengthTooltip: 'Введите значение в пикселях, либо число с корректной единицей меры CSS (px, %, in, cm, mm, em, ex, pt или pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, недоступно</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Пробел',
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Комбинация клавиш'
+       }
+};
diff --git a/sources/lang/si.js b/sources/lang/si.js
new file mode 100644 (file)
index 0000000..df0d734
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'si' ] = {
+       // ARIA description.
+       editor: 'පොහොසත් වචන සංස්කරණ',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'උදව් ලබා ගැනීමට  ALT බොත්තම ඔබන්න',
+
+               browseServer: 'සෙවුම් සේවාදායකය',
+               url: 'URL',
+               protocol: 'මුලාපත්‍රය',
+               upload: 'උඩුගතකිරීම',
+               uploadSubmit: 'සේවාදායකය වෙත යොමුකිරිම',
+               image: 'රුපය',
+               flash: 'දීප්තිය',
+               form: 'පෝරමය',
+               checkbox: 'ලකුණුකිරීමේ කොටුව',
+               radio: 'තේරීම් ',
+               textField: 'ලියන ප්‍රදේශය',
+               textarea: 'අකුරු ',
+               hiddenField: 'සැඟවුණු ප්‍රදේශය',
+               button: 'බොත්තම',
+               select: 'තෝරන්න ',
+               imageButton: 'රුප ',
+               notSet: '<යොදා >',
+               id: 'අංකය',
+               name: 'නම',
+               langDir: 'භාෂා දිශාව',
+               langDirLtr: 'වමේසිට දකුණුට',
+               langDirRtl: 'දකුණේ සිට වමට',
+               langCode: 'භාෂා කේතය',
+               longDescr: 'සම්පුර්න පැහැදිලි කිරීම',
+               cssClass: 'විලාශ පත්‍ර පන්තිය',
+               advisoryTitle: 'උපදෙස් ',
+               cssStyle: 'විලාසය',
+               ok: 'නිරදි',
+               cancel: 'අවලංගු කිරීම',
+               close: 'වැසීම',
+               preview: 'නැවත ',
+               resize: 'විශාලත්වය නැවත වෙනස් කිරීම',
+               generalTab: 'පොදු කරුණු.',
+               advancedTab: 'දීය',
+               validateNumberFailed: 'මෙම වටිනාකම අංකයක් නොවේ',
+               confirmNewPage: 'ආරක්ෂා නොකළ සියලුම දත්තයන් මැකියනුලැබේ. ඔබට නව පිටුවක් ලබා ගැනීමට අවශ්‍යද?',
+               confirmCancel: 'ඇතම් විකල්පයන් වෙනස් කර ඇත. ඔබට මින් නික්මීමට අවශ්‍යද?',
+               options: ' විකල්ප',
+               target: 'අරමුණ',
+               targetNew: 'නව කව්ළුව',
+               targetTop: 'වැදගත් කව්ළුව',
+               targetSelf: 'එම කව්ළුව(_තම\\\\)',
+               targetParent: 'මව් කව්ළුව(_)',
+               langDirLTR: 'වමේසිට දකුණුට',
+               langDirRTL: 'දකුණේ සිට වමට',
+               styles: 'විලාසය',
+               cssClasses: 'විලාසපත්‍ර පන්තිය',
+               width: 'පළල',
+               height: 'උස',
+               align: 'ගැලපුම',
+               alignLeft: 'වම',
+               alignRight: 'දකුණ',
+               alignCenter: 'මධ්‍ය',
+               alignJustify: 'Justify', // MISSING
+               alignTop: 'ඉ',
+               alignMiddle: 'මැද',
+               alignBottom: 'පහල',
+               alignNone: 'None', // MISSING
+               invalidValue: 'වැරදී වටිනාකමකි',
+               invalidHeight: 'උස අංකයක් විය යුතුය',
+               invalidWidth: 'පළල අංකයක් විය යුතුය',
+               invalidCssLength: 'වටිනාකමක් නිරූපණය කිරීම "%1" ප්‍රදේශය ධන සංක්‍යාත්මක වටිනාකමක් හෝ  නිවරදි නොවන  CSS මිනුම් එකක(px, %, in, cm, mm, em, ex, pt, pc)',
+               invalidHtmlLength: 'වටිනාකමක් නිරූපණය කිරීම "%1" ප්‍රදේශය ධන සංක්‍යාත්මක වටිනාකමක් හෝ  නිවරදි නොවන  HTML මිනුම් එකක (px හෝ %).',
+               invalidInlineStyle: 'වටිනාකමක් නිරූපණය කිරීම  පේළි විලාසයයට ආකෘතිය  අනතර්ග විය යුතය  "නම : වටිනාකම", තිත් කොමාවකින් වෙන් වෙන ලද.',
+               cssLengthTooltip: 'සංක්‍යා ඇතුලත් කිරීමේදී වටිනාකම තිත් ප්‍රමාණය නිවරදි CSS  ඒකක(තිත්, %, අඟල්,සෙමි, mm, em, ex, pt, pc)',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span පන්තිය="ළඟා වියහැකි ද බලන්න">, නොමැතිනම්</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/sk.js b/sources/lang/sk.js
new file mode 100644 (file)
index 0000000..e473cc6
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Slovak language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sk' ] = {
+       // ARIA description.
+       editor: 'Editor formátovaného textu',
+       editorPanel: 'Panel editora formátovaného textu',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Stlačením ALT 0 spustiť pomocníka',
+
+               browseServer: 'Prehliadať server',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Odoslať',
+               uploadSubmit: 'Odoslať na server',
+               image: 'Obrázok',
+               flash: 'Flash',
+               form: 'Formulár',
+               checkbox: 'Zaškrtávacie pole',
+               radio: 'Prepínač',
+               textField: 'Textové pole',
+               textarea: 'Textová oblasť',
+               hiddenField: 'Skryté pole',
+               button: 'Tlačidlo',
+               select: 'Rozbaľovací zoznam',
+               imageButton: 'Obrázkové tlačidlo',
+               notSet: '<nenastavené>',
+               id: 'Id',
+               name: 'Meno',
+               langDir: 'Orientácia jazyka',
+               langDirLtr: 'Zľava doprava (LTR)',
+               langDirRtl: 'Sprava doľava (RTL)',
+               langCode: 'Kód jazyka',
+               longDescr: 'Dlhý popis URL',
+               cssClass: 'Trieda štýlu',
+               advisoryTitle: 'Pomocný titulok',
+               cssStyle: 'Štýl',
+               ok: 'OK',
+               cancel: 'Zrušiť',
+               close: 'Zatvorit',
+               preview: 'Náhľad',
+               resize: 'Zmeniť veľkosť',
+               generalTab: 'Hlavné',
+               advancedTab: 'Rozšírené',
+               validateNumberFailed: 'Hodnota nie je číslo.',
+               confirmNewPage: 'Prajete si načítat novú stránku? Všetky neuložené zmeny budú stratené. ',
+               confirmCancel: 'Niektore možnosti boli zmenené. Naozaj chcete zavrieť okno?',
+               options: 'Možnosti',
+               target: 'Cieľ',
+               targetNew: 'Nové okno (_blank)',
+               targetTop: 'Najvrchnejšie okno (_top)',
+               targetSelf: 'To isté okno (_self)',
+               targetParent: 'Rodičovské okno (_parent)',
+               langDirLTR: 'Zľava doprava (LTR)',
+               langDirRTL: 'Sprava doľava (RTL)',
+               styles: 'Štýl',
+               cssClasses: 'Triedy štýlu',
+               width: 'Šírka',
+               height: 'Výška',
+               align: 'Zarovnanie',
+               alignLeft: 'Vľavo',
+               alignRight: 'Vpravo',
+               alignCenter: 'Na stred',
+               alignJustify: 'Zarovnať do bloku',
+               alignTop: 'Nahor',
+               alignMiddle: 'Na stred',
+               alignBottom: 'Dole',
+               alignNone: 'Žiadne',
+               invalidValue: 'Neplatná hodnota.',
+               invalidHeight: 'Výška musí byť číslo.',
+               invalidWidth: 'Šírka musí byť číslo.',
+               invalidCssLength: 'Špecifikovaná hodnota pre pole "%1" musí byť kladné číslo s alebo bez platnej CSS mernej jednotky (px, %, in, cm, mm, em, ex, pt alebo pc).',
+               invalidHtmlLength: 'Špecifikovaná hodnota pre pole "%1" musí byť kladné číslo s alebo bez platnej HTML mernej jednotky (px alebo %).',
+               invalidInlineStyle: 'Zadaná hodnota pre inline štýl musí pozostávať s jedného, alebo viac dvojíc formátu "názov: hodnota", oddelených bodkočiarkou.',
+               cssLengthTooltip: 'Vložte číslo pre hodnotu v pixeloch alebo číslo so správnou CSS jednotou (px, %, in, cm, mm, em, ex, pt alebo pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nedostupný</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Medzerník',
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Delete',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Klávesová skratka'
+       }
+};
diff --git a/sources/lang/sl.js b/sources/lang/sl.js
new file mode 100644 (file)
index 0000000..bbaa5ea
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Slovenian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sl' ] = {
+       // ARIA description.
+       editor: 'Urejevalnik obogatenega besedila',
+       editorPanel: 'Plošča urejevalnika obogatenega besedila',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Pritisnite ALT 0 za pomoč',
+
+               browseServer: 'Prebrskaj na strežniku',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Naloži',
+               uploadSubmit: 'Pošlji na strežnik',
+               image: 'Slika',
+               flash: 'Flash',
+               form: 'Obrazec',
+               checkbox: 'Potrditveno polje',
+               radio: 'Izbirno polje',
+               textField: 'Besedilno polje',
+               textarea: 'Besedilno območje',
+               hiddenField: 'Skrito polje',
+               button: 'Gumb',
+               select: 'Spustno polje',
+               imageButton: 'Slikovni gumb',
+               notSet: '<ni določen>',
+               id: 'Id',
+               name: 'Ime',
+               langDir: 'Smer jezika',
+               langDirLtr: 'Od leve proti desni (LTR)',
+               langDirRtl: 'Od desne proti levi (RTL)',
+               langCode: 'Koda jezika',
+               longDescr: 'Dolg opis URL-ja',
+               cssClass: 'Razredi slogovne predloge',
+               advisoryTitle: 'Predlagani naslov',
+               cssStyle: 'Slog',
+               ok: 'V redu',
+               cancel: 'Prekliči',
+               close: 'Zapri',
+               preview: 'Predogled',
+               resize: 'Potegni za spremembo velikosti',
+               generalTab: 'Splošno',
+               advancedTab: 'Napredno',
+               validateNumberFailed: 'Vrednost ni število.',
+               confirmNewPage: 'Vse neshranjene spremembe vsebine bodo izgubljene. Ali res želite naložiti novo stran?',
+               confirmCancel: 'Spremenili ste nekaj možnosti. Ali res želite zapreti okno?',
+               options: 'Možnosti',
+               target: 'Cilj',
+               targetNew: 'Novo okno (_blank)',
+               targetTop: 'Vrhovno okno (_top)',
+               targetSelf: 'Isto okno (_self)',
+               targetParent: 'Starševsko okno (_parent)',
+               langDirLTR: 'Od leve proti desni (LTR)',
+               langDirRTL: 'Od desne proti levi (RTL)',
+               styles: 'Slog',
+               cssClasses: 'Razredi slogovne predloge',
+               width: 'Širina',
+               height: 'Višina',
+               align: 'Poravnava',
+               alignLeft: 'Levo',
+               alignRight: 'Desno',
+               alignCenter: 'Sredinsko',
+               alignJustify: 'Obojestranska poravnava',
+               alignTop: 'Na vrh',
+               alignMiddle: 'V sredino',
+               alignBottom: 'Na dno',
+               alignNone: 'Brez poravnave',
+               invalidValue: 'Neveljavna vrednost.',
+               invalidHeight: 'Višina mora biti število.',
+               invalidWidth: 'Širina mora biti število.',
+               invalidCssLength: 'Vrednost, določena za polje »%1«, mora biti pozitivno število z ali brez veljavne CSS-enote za merjenje (px, %, in, cm, mm, em, ex, pt ali pc).',
+               invalidHtmlLength: 'Vrednost, določena za polje »%1«, mora biti pozitivno število z ali brez veljavne HTML-enote za merjenje (px ali %).',
+               invalidInlineStyle: 'Vrednost, določena za slog v vrstici, mora biti sestavljena iz ene ali več dvojic oblike »ime : vrednost«, ločenih s podpičji.',
+               cssLengthTooltip: 'Vnesite število za vrednost v slikovnih pikah ali število z veljavno CSS-enoto (px, %, in, cm, mm, em, ex, pt ali pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, nedosegljiv</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/sq.js b/sources/lang/sq.js
new file mode 100644 (file)
index 0000000..d5812ea
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sq' ] = {
+       // ARIA description.
+       editor: 'Redaktues i Pasur Teksti',
+       editorPanel: 'Paneli i redaktuesit të tekstit të plotë',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Shtyp ALT 0 për ndihmë',
+
+               browseServer: 'Shfleto në Server',
+               url: 'URL',
+               protocol: 'Protokolli',
+               upload: 'Ngarko',
+               uploadSubmit: 'Dërgo në server',
+               image: 'Imazh',
+               flash: 'Objekt flash',
+               form: 'Formular',
+               checkbox: 'Checkbox',
+               radio: 'Buton radio',
+               textField: 'Fushë tekst',
+               textarea: 'Hapësirë tekst',
+               hiddenField: 'Fushë e fshehur',
+               button: 'Buton',
+               select: 'Menu zgjedhjeje',
+               imageButton: 'Buton imazhi',
+               notSet: '<e pazgjedhur>',
+               id: 'Id',
+               name: 'Emër',
+               langDir: 'Kod gjuhe',
+               langDirLtr: 'Nga e majta në të djathtë (LTR)',
+               langDirRtl: 'Nga e djathta në të majtë (RTL)',
+               langCode: 'Kod gjuhe',
+               longDescr: 'Përshkrim i hollësishëm',
+               cssClass: 'Klasa stili CSS',
+               advisoryTitle: 'Titull',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Anulo',
+               close: 'Mbyll',
+               preview: 'Parashiko',
+               resize: 'Ripërmaso',
+               generalTab: 'Të përgjithshme',
+               advancedTab: 'Të përparuara',
+               validateNumberFailed: 'Vlera e futur nuk është një numër',
+               confirmNewPage: 'Çdo ndryshim që nuk është ruajtur do humbasë. Je i sigurtë që dëshiron të krijosh një faqe të re?',
+               confirmCancel: 'Disa opsione kanë ndryshuar. Je i sigurtë që dëshiron ta mbyllësh dritaren?',
+               options: 'Opsione',
+               target: 'Objektivi',
+               targetNew: 'Dritare e re (_blank)',
+               targetTop: 'Dritare në plan të parë (_top)',
+               targetSelf: 'E njëjta dritare (_self)',
+               targetParent: 'Dritarja prind (_parent)',
+               langDirLTR: 'Nga e majta në të djathë (LTR)',
+               langDirRTL: 'Nga e djathta në të majtë (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Klasa Stili CSS',
+               width: 'Gjerësi',
+               height: 'Lartësi',
+               align: 'Rreshtim',
+               alignLeft: 'Majtas',
+               alignRight: 'Djathtas',
+               alignCenter: 'Qendër',
+               alignJustify: 'Zgjero',
+               alignTop: 'Lart',
+               alignMiddle: 'Në mes',
+               alignBottom: 'Poshtë',
+               alignNone: 'Asnjë',
+               invalidValue: 'Vlerë e pavlefshme',
+               invalidHeight: 'Lartësia duhet të jetë një numër',
+               invalidWidth: 'Gjerësia duhet të jetë një numër',
+               invalidCssLength: 'Vlera e fushës "%1" duhet të jetë një numër pozitiv me apo pa njësi matëse të vlefshme CSS (px, %, in, cm, mm, em, ex, pt ose pc).',
+               invalidHtmlLength: 'Vlera e fushës "%1" duhet të jetë një numër pozitiv me apo pa njësi matëse të vlefshme HTML (px ose %)',
+               invalidInlineStyle: 'Stili inline duhet të jetë një apo disa vlera të formatit "emër: vlerë", ndarë nga pikëpresje.',
+               cssLengthTooltip: 'Fut një numër për vlerën në pixel apo një numër me një njësi të vlefshme CSS (px, %, in, cm, mm, ex, pt, ose pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, i padisponueshëm</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Prapa',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Grise',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/sr-latn.js b/sources/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..9994a0a
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Serbian (Latin) language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sr-latn' ] = {
+       // ARIA description.
+       editor: 'Bogati uređivač teksta',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Pretraži server',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Pošalji',
+               uploadSubmit: 'Pošalji na server',
+               image: 'Slika',
+               flash: 'Fleš',
+               form: 'Forma',
+               checkbox: 'Polje za potvrdu',
+               radio: 'Radio-dugme',
+               textField: 'Tekstualno polje',
+               textarea: 'Zona teksta',
+               hiddenField: 'Skriveno polje',
+               button: 'Dugme',
+               select: 'Izborno polje',
+               imageButton: 'Dugme sa slikom',
+               notSet: '<nije postavljeno>',
+               id: 'Id',
+               name: 'Naziv',
+               langDir: 'Smer jezika',
+               langDirLtr: 'S leva na desno (LTR)',
+               langDirRtl: 'S desna na levo (RTL)',
+               langCode: 'Kôd jezika',
+               longDescr: 'Pun opis URL',
+               cssClass: 'Stylesheet klase',
+               advisoryTitle: 'Advisory naslov',
+               cssStyle: 'Stil',
+               ok: 'OK',
+               cancel: 'Otkaži',
+               close: 'Zatvori',
+               preview: 'Izgled stranice',
+               resize: 'Resize', // MISSING
+               generalTab: 'Opšte',
+               advancedTab: 'Napredni tagovi',
+               validateNumberFailed: 'Ova vrednost nije broj.',
+               confirmNewPage: 'Nesačuvane promene ovog sadržaja će biti izgubljene. Jeste li sigurni da želita da učitate novu stranu?',
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Opcije',
+               target: 'Meta',
+               targetNew: 'Novi prozor (_blank)',
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Isti prozor (_self)',
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'S leva na desno (LTR)',
+               langDirRTL: 'S desna na levo (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Stylesheet klase',
+               width: 'Širina',
+               height: 'Visina',
+               align: 'Ravnanje',
+               alignLeft: 'Levo',
+               alignRight: 'Desno',
+               alignCenter: 'Sredina',
+               alignJustify: 'Obostrano ravnanje',
+               alignTop: 'Vrh',
+               alignMiddle: 'Sredina',
+               alignBottom: 'Dole',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Visina mora biti broj.',
+               invalidWidth: 'Širina mora biti broj.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/sr.js b/sources/lang/sr.js
new file mode 100644 (file)
index 0000000..341bf7a
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Serbian (Cyrillic) language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sr' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Press ALT 0 for help', // MISSING
+
+               browseServer: 'Претражи сервер',
+               url: 'УРЛ',
+               protocol: 'Протокол',
+               upload: 'Пошаљи',
+               uploadSubmit: 'Пошаљи на сервер',
+               image: 'Слика',
+               flash: 'Флеш елемент',
+               form: 'Форма',
+               checkbox: 'Поље за потврду',
+               radio: 'Радио-дугме',
+               textField: 'Текстуално поље',
+               textarea: 'Зона текста',
+               hiddenField: 'Скривено поље',
+               button: 'Дугме',
+               select: 'Изборно поље',
+               imageButton: 'Дугме са сликом',
+               notSet: '<није постављено>',
+               id: 'Ид',
+               name: 'Назив',
+               langDir: 'Смер језика',
+               langDirLtr: 'С лева на десно (LTR)',
+               langDirRtl: 'С десна на лево (RTL)',
+               langCode: 'Kôд језика',
+               longDescr: 'Пун опис УРЛ',
+               cssClass: 'Stylesheet класе',
+               advisoryTitle: 'Advisory наслов',
+               cssStyle: 'Стил',
+               ok: 'OK',
+               cancel: 'Oткажи',
+               close: 'Затвори',
+               preview: 'Изглед странице',
+               resize: 'Resize', // MISSING
+               generalTab: 'Опште',
+               advancedTab: 'Напредни тагови',
+               validateNumberFailed: 'Ова вредност није цигра.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Опције',
+               target: 'Meтa',
+               targetNew: 'New Window (_blank)', // MISSING
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'Same Window (_self)', // MISSING
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'С лева на десно (LTR)',
+               langDirRTL: 'С десна на лево (RTL)',
+               styles: 'Стил',
+               cssClasses: 'Stylesheet класе',
+               width: 'Ширина',
+               height: 'Висина',
+               align: 'Равнање',
+               alignLeft: 'Лево',
+               alignRight: 'Десно',
+               alignCenter: 'Средина',
+               alignJustify: 'Обострано равнање',
+               alignTop: 'Врх',
+               alignMiddle: 'Средина',
+               alignBottom: 'Доле',
+               alignNone: 'None', // MISSING
+               invalidValue: 'Invalid value.', // MISSING
+               invalidHeight: 'Height must be a number.', // MISSING
+               invalidWidth: 'Width must be a number.', // MISSING
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/sv.js b/sources/lang/sv.js
new file mode 100644 (file)
index 0000000..3074d46
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+* @fileOverview
+*/
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'sv' ] = {
+       // ARIA description.
+       editor: 'Rich Text-editor',
+       editorPanel: 'Panel till Rich Text-editor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Tryck ALT 0 för hjälp',
+
+               browseServer: 'Bläddra på server',
+               url: 'URL',
+               protocol: 'Protokoll',
+               upload: 'Ladda upp',
+               uploadSubmit: 'Skicka till server',
+               image: 'Bild',
+               flash: 'Flash',
+               form: 'Formulär',
+               checkbox: 'Kryssruta',
+               radio: 'Alternativknapp',
+               textField: 'Textfält',
+               textarea: 'Textruta',
+               hiddenField: 'Dolt fält',
+               button: 'Knapp',
+               select: 'Flervalslista',
+               imageButton: 'Bildknapp',
+               notSet: '<ej angivet>',
+               id: 'Id',
+               name: 'Namn',
+               langDir: 'Språkriktning',
+               langDirLtr: 'Vänster till Höger (VTH)',
+               langDirRtl: 'Höger till Vänster (HTV)',
+               langCode: 'Språkkod',
+               longDescr: 'URL-beskrivning',
+               cssClass: 'Stilmall',
+               advisoryTitle: 'Titel',
+               cssStyle: 'Stilmall',
+               ok: 'OK',
+               cancel: 'Avbryt',
+               close: 'Stäng',
+               preview: 'Förhandsgranska',
+               resize: 'Dra för att ändra storlek',
+               generalTab: 'Allmänt',
+               advancedTab: 'Avancerad',
+               validateNumberFailed: 'Värdet är inte ett nummer.',
+               confirmNewPage: 'Alla ändringar i innehållet kommer att förloras. Är du säker på att du vill ladda en ny sida?',
+               confirmCancel: 'Några av alternativen har ändrats. Är du säker på att du vill stänga dialogrutan?',
+               options: 'Alternativ',
+               target: 'Mål',
+               targetNew: 'Nytt fönster (_blank)',
+               targetTop: 'Översta fönstret (_top)',
+               targetSelf: 'Samma fönster (_self)',
+               targetParent: 'Föregående fönster (_parent)',
+               langDirLTR: 'Vänster till höger (LTR)',
+               langDirRTL: 'Höger till vänster (RTL)',
+               styles: 'Stil',
+               cssClasses: 'Stilmallar',
+               width: 'Bredd',
+               height: 'Höjd',
+               align: 'Justering',
+               alignLeft: 'Vänster',
+               alignRight: 'Höger',
+               alignCenter: 'Centrerad',
+               alignJustify: 'Justera till marginaler',
+               alignTop: 'Överkant',
+               alignMiddle: 'Mitten',
+               alignBottom: 'Nederkant',
+               alignNone: 'Ingen',
+               invalidValue: 'Felaktigt värde.',
+               invalidHeight: 'Höjd måste vara ett nummer.',
+               invalidWidth: 'Bredd måste vara ett nummer.',
+               invalidCssLength: 'Värdet för fältet "%1" måste vara ett positivt nummer med eller utan CSS-mätenheter (px, %, in, cm, mm, em, ex, pt, eller pc).',
+               invalidHtmlLength: 'Värdet för fältet "%1" måste vara ett positivt nummer med eller utan godkända HTML-mätenheter (px eller %).',
+               invalidInlineStyle: 'Det angivna värdet för style måste innehålla en eller flera tupler separerade med semikolon i följande format: "name : value"',
+               cssLengthTooltip: 'Ange ett nummer i pixlar eller ett nummer men godkänd CSS-mätenhet (px, %, in, cm, mm, em, ex, pt, eller pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, Ej tillgänglig</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backsteg',
+                       13: 'Retur',
+                       16: 'Skift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Mellanslag',
+                       35: 'Slut',
+                       36: 'Hem',
+                       46: 'Radera',
+                       224: 'Kommando'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Kortkommando'
+       }
+};
diff --git a/sources/lang/th.js b/sources/lang/th.js
new file mode 100644 (file)
index 0000000..6dc918e
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Thai language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'th' ] = {
+       // ARIA description.
+       editor: 'Rich Text Editor', // MISSING
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'กด ALT 0 หากต้องการความช่วยเหลือ',
+
+               browseServer: 'เปิดหน้าต่างจัดการไฟล์อัพโหลด',
+               url: 'ที่อยู่อ้างอิง URL',
+               protocol: 'โปรโตคอล',
+               upload: 'อัพโหลดไฟล์',
+               uploadSubmit: 'อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)',
+               image: 'รูปภาพ',
+               flash: 'ไฟล์ Flash',
+               form: 'แบบฟอร์ม',
+               checkbox: 'เช็คบ๊อก',
+               radio: 'เรดิโอบัตตอน',
+               textField: 'เท็กซ์ฟิลด์',
+               textarea: 'เท็กซ์แอเรีย',
+               hiddenField: 'ฮิดเดนฟิลด์',
+               button: 'ปุ่ม',
+               select: 'แถบตัวเลือก',
+               imageButton: 'ปุ่มแบบรูปภาพ',
+               notSet: '<ไม่ระบุ>',
+               id: 'ไอดี',
+               name: 'ชื่อ',
+               langDir: 'การเขียน-อ่านภาษา',
+               langDirLtr: 'จากซ้ายไปขวา (LTR)',
+               langDirRtl: 'จากขวามาซ้าย (RTL)',
+               langCode: 'รหัสภาษา',
+               longDescr: 'คำอธิบายประกอบ URL',
+               cssClass: 'คลาสของไฟล์กำหนดลักษณะการแสดงผล',
+               advisoryTitle: 'คำเกริ่นนำ',
+               cssStyle: 'ลักษณะการแสดงผล',
+               ok: 'ตกลง',
+               cancel: 'ยกเลิก',
+               close: 'ปิด',
+               preview: 'ดูหน้าเอกสารตัวอย่าง',
+               resize: 'ปรับขนาด',
+               generalTab: 'ทั่วไป',
+               advancedTab: 'ขั้นสูง',
+               validateNumberFailed: 'ค่านี้ไม่ใช่ตัวเลข',
+               confirmNewPage: 'การเปลี่ยนแปลงใดๆ ในเนื้อหานี้ ที่ไม่ได้ถูกบันทึกไว้ จะสูญหายทั้งหมด คุณแน่ใจว่าจะเรียกหน้าใหม่?',
+               confirmCancel: 'ตัวเลือกบางตัวมีการเปลี่ยนแปลง คุณแน่ใจว่าจะปิดกล่องโต้ตอบนี้?',
+               options: 'ตัวเลือก',
+               target: 'การเปิดหน้าลิงค์',
+               targetNew: 'หน้าต่างใหม่ (_blank)',
+               targetTop: 'Topmost Window (_top)', // MISSING
+               targetSelf: 'หน้าต่างเดียวกัน (_self)',
+               targetParent: 'Parent Window (_parent)', // MISSING
+               langDirLTR: 'จากซ้ายไปขวา (LTR)',
+               langDirRTL: 'จากขวามาซ้าย (RTL)',
+               styles: 'ลักษณะการแสดงผล',
+               cssClasses: 'คลาสของไฟล์กำหนดลักษณะการแสดงผล',
+               width: 'ความกว้าง',
+               height: 'ความสูง',
+               align: 'การจัดวาง',
+               alignLeft: 'ชิดซ้าย',
+               alignRight: 'ชิดขวา',
+               alignCenter: 'กึ่งกลาง',
+               alignJustify: 'நியாயப்படுத்தவும்',
+               alignTop: 'บนสุด',
+               alignMiddle: 'กึ่งกลางแนวตั้ง',
+               alignBottom: 'ชิดด้านล่าง',
+               alignNone: 'None', // MISSING
+               invalidValue: 'ค่าไม่ถูกต้อง',
+               invalidHeight: 'ความสูงต้องเป็นตัวเลข',
+               invalidWidth: 'ความกว้างต้องเป็นตัวเลข',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace', // MISSING
+                       13: 'Enter', // MISSING
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Delete', // MISSING
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/tr.js b/sources/lang/tr.js
new file mode 100644 (file)
index 0000000..0cbd57c
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+* @fileOverview
+*/
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'tr' ] = {
+       // ARIA description.
+       editor: 'Zengin Metin Editörü',
+       editorPanel: 'Zengin Metin Editör Paneli',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Yardım için ALT 0 tuşlarına basın',
+
+               browseServer: 'Sunucuya Gözat',
+               url: 'URL',
+               protocol: 'Protokol',
+               upload: 'Karşıya Yükle',
+               uploadSubmit: 'Sunucuya Gönder',
+               image: 'Resim',
+               flash: 'Flash',
+               form: 'Form',
+               checkbox: 'Onay Kutusu',
+               radio: 'Seçenek Düğmesi',
+               textField: 'Metin Kutusu',
+               textarea: 'Metin Alanı',
+               hiddenField: 'Gizli Alan',
+               button: 'Düğme',
+               select: 'Seçme Alanı',
+               imageButton: 'Resim Düğmesi',
+               notSet: '<tanımlanmamış>',
+               id: 'Kimlik',
+               name: 'İsim',
+               langDir: 'Dil Yönü',
+               langDirLtr: 'Soldan Sağa (LTR)',
+               langDirRtl: 'Sağdan Sola (RTL)',
+               langCode: 'Dil Kodlaması',
+               longDescr: 'Uzun Tanımlı URL',
+               cssClass: 'Biçem Sayfası Sınıfları',
+               advisoryTitle: 'Öneri Başlığı',
+               cssStyle: 'Biçem',
+               ok: 'Tamam',
+               cancel: 'İptal',
+               close: 'Kapat',
+               preview: 'Önizleme',
+               resize: 'Yeniden Boyutlandır',
+               generalTab: 'Genel',
+               advancedTab: 'Gelişmiş',
+               validateNumberFailed: 'Bu değer bir sayı değildir.',
+               confirmNewPage: 'Bu içerikle ilgili kaydedilmemiş tüm bilgiler kaybolacaktır. Yeni bir sayfa yüklemek istediğinizden emin misiniz?',
+               confirmCancel: 'Bazı seçenekleri değiştirdiniz. İletişim penceresini kapatmak istediğinizden emin misiniz?',
+               options: 'Seçenekler',
+               target: 'Hedef',
+               targetNew: 'Yeni Pencere (_blank)',
+               targetTop: 'En Üstteki Pencere (_top)',
+               targetSelf: 'Aynı Pencere (_self)',
+               targetParent: 'Üst Pencere (_parent)',
+               langDirLTR: 'Soldan Sağa (LTR)',
+               langDirRTL: 'Sağdan Sola (RTL)',
+               styles: 'Biçem',
+               cssClasses: 'Biçem Sayfası Sınıfları',
+               width: 'Genişlik',
+               height: 'Yükseklik',
+               align: 'Hizalama',
+               alignLeft: 'Sol',
+               alignRight: 'Sağ',
+               alignCenter: 'Ortala',
+               alignJustify: 'İki Kenara Yaslanmış',
+               alignTop: 'Üst',
+               alignMiddle: 'Orta',
+               alignBottom: 'Alt',
+               alignNone: 'Hiçbiri',
+               invalidValue: 'Geçersiz değer.',
+               invalidHeight: 'Yükseklik değeri bir sayı olmalıdır.',
+               invalidWidth: 'Genişlik değeri bir sayı olmalıdır.',
+               invalidCssLength: '"%1" alanı için verilen değer, geçerli bir CSS ölçü birimi (px, %, in, cm, mm, em, ex, pt, veya pc) içeren veya içermeyen pozitif bir sayı olmalıdır.',
+               invalidHtmlLength: 'Belirttiğiniz sayı "%1" alanı için pozitif bir sayı HTML birim değeri olmalıdır (px veya %).',
+               invalidInlineStyle: 'Satıriçi biçem için verilen değer, "isim : değer" biçiminde birbirinden noktalı virgüllerle ayrılan bir veya daha fazla değişkenler grubundan oluşmalıdır.',
+               cssLengthTooltip: 'Piksel türünde bir sayı veya geçerli bir CSS ölçü birimi (px, %, in, cm, mm, em, ex, pt veya pc) içeren bir sayı girin.',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, kullanılamaz</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Silme Tuşu',
+                       13: 'Giriş Tuşu',
+                       16: 'Üst Karater Tuşu',
+                       17: 'Kontrol Tuşu',
+                       18: 'Alt Tuşu',
+                       32: 'Boşluk Tuşu',
+                       35: 'En Sona Tuşu',
+                       36: 'En Başa Tuşu',
+                       46: 'Silme Tuşu',
+                       224: 'Komut Tuşu'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Klavye Kısayolu'
+       }
+};
diff --git a/sources/lang/tt.js b/sources/lang/tt.js
new file mode 100644 (file)
index 0000000..c63170b
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Tatar language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'tt' ] = {
+       // ARIA description.
+       editor: 'Форматлаулы текст өлкәсе',
+       editorPanel: 'Rich Text Editor panel', // MISSING
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Ярдәм өчен ALT 0 басыгыз',
+
+               browseServer: 'Сервер карап чыгу',
+               url: 'Сылталама',
+               protocol: 'Протокол',
+               upload: 'Йөкләү',
+               uploadSubmit: 'Серверга җибәрү',
+               image: 'Рәсем',
+               flash: 'Флеш',
+               form: 'Форма',
+               checkbox: 'Чекбокс',
+               radio: 'Радио төймә',
+               textField: 'Текст кыры',
+               textarea: 'Текст мәйданы',
+               hiddenField: 'Яшерен кыр',
+               button: 'Төймə',
+               select: 'Сайлау кыры',
+               imageButton: 'Рәсемле төймə',
+               notSet: '<билгеләнмәгән>',
+               id: 'Id',
+               name: 'Исем',
+               langDir: 'Язылыш юнəлеше',
+               langDirLtr: 'Сулдан уңга язылыш (LTR)',
+               langDirRtl: 'Уңнан сулга язылыш (RTL)',
+               langCode: 'Тел коды',
+               longDescr: 'Җентекле тасвирламага сылталама',
+               cssClass: 'Стильләр класслары',
+               advisoryTitle: 'Киңәш исем',
+               cssStyle: 'Стиль',
+               ok: 'Тәмам',
+               cancel: 'Баш тарту',
+               close: 'Чыгу',
+               preview: 'Карап алу',
+               resize: 'Зурлыкны үзгәртү',
+               generalTab: 'Төп',
+               advancedTab: 'Киңәйтелгән көйләүләр',
+               validateNumberFailed: 'Әлеге кыйммәт сан түгел.',
+               confirmNewPage: 'Any unsaved changes to this content will be lost. Are you sure you want to load new page?', // MISSING
+               confirmCancel: 'You have changed some options. Are you sure you want to close the dialog window?', // MISSING
+               options: 'Үзлекләр',
+               target: 'Максат',
+               targetNew: 'Яңа тәрәзә (_blank)',
+               targetTop: 'Өске тәрәзә (_top)',
+               targetSelf: 'Шул үк тәрәзә (_self)',
+               targetParent: 'Ана тәрәзә (_parent)',
+               langDirLTR: 'Сулдан уңга язылыш (LTR)',
+               langDirRTL: 'Уңнан сулга язылыш (RTL)',
+               styles: 'Стиль',
+               cssClasses: 'Стильләр класслары',
+               width: 'Киңлек',
+               height: 'Биеклек',
+               align: 'Тигезләү',
+               alignLeft: 'Сул якка',
+               alignRight: 'Уң якка',
+               alignCenter: 'Үзәккә',
+               alignJustify: 'Киңлеккә карап тигезләү',
+               alignTop: 'Өскә',
+               alignMiddle: 'Уртага',
+               alignBottom: 'Аска',
+               alignNone: 'Һичбер',
+               invalidValue: 'Дөрес булмаган кыйммәт.',
+               invalidHeight: 'Биеклек сан булырга тиеш.',
+               invalidWidth: 'Киңлек сан булырга тиеш.',
+               invalidCssLength: 'Value specified for the "%1" field must be a positive number with or without a valid CSS measurement unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+               invalidHtmlLength: 'Value specified for the "%1" field must be a positive number with or without a valid HTML measurement unit (px or %).', // MISSING
+               invalidInlineStyle: 'Value specified for the inline style must consist of one or more tuples with the format of "name : value", separated by semi-colons.', // MISSING
+               cssLengthTooltip: 'Enter a number for a value in pixels or a number with a valid CSS unit (px, %, in, cm, mm, em, ex, pt, or pc).', // MISSING
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, unavailable</span>', // MISSING
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Кайтару',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Бетерү',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/ug.js b/sources/lang/ug.js
new file mode 100644 (file)
index 0000000..13a256d
--- /dev/null
@@ -0,0 +1,116 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'ug' ] = {
+       // ARIA description.
+       editor: 'تەھرىرلىگۈچ',
+       editorPanel: 'مول تېكست تەھرىرلىگۈچ تاختىسى',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'ALT+0 نى بېسىپ ياردەمنى كۆرۈڭ',
+
+               browseServer: 'كۆرسىتىش مۇلازىمېتىر',
+               url: 'ئەسلى ھۆججەت',
+               protocol: 'كېلىشىم',
+               upload: 'يۈكلە',
+               uploadSubmit: 'مۇلازىمېتىرغا يۈكلە',
+               image: 'سۈرەت',
+               flash: 'Flash',
+               form: 'جەدۋەل',
+               checkbox: 'كۆپ تاللاش رامكىسى',
+               radio: 'يەككە تاللاش توپچىسى',
+               textField: 'يەككە قۇر تېكىست',
+               textarea: 'كۆپ قۇر تېكىست',
+               hiddenField: 'يوشۇرۇن دائىرە',
+               button: 'توپچا',
+               select: 'تىزىم/تىزىملىك',
+               imageButton: 'سۈرەت دائىرە',
+               notSet: '‹تەڭشەلمىگەن›',
+               id: 'ID',
+               name: 'ئات',
+               langDir: 'تىل يۆنىلىشى',
+               langDirLtr: 'سولدىن ئوڭغا (LTR)',
+               langDirRtl: 'ئوڭدىن سولغا (RTL)',
+               langCode: 'تىل كودى',
+               longDescr: 'تەپسىلىي چۈشەندۈرۈش ئادرېسى',
+               cssClass: 'ئۇسلۇب خىلىنىڭ ئاتى',
+               advisoryTitle: 'ماۋزۇ',
+               cssStyle: 'قۇر ئىچىدىكى ئۇسلۇبى',
+               ok: 'جەزملە',
+               cancel: 'ۋاز كەچ',
+               close: 'تاقا',
+               preview: 'ئالدىن كۆزەت',
+               resize: 'چوڭلۇقىنى ئۆزگەرت',
+               generalTab: 'ئادەتتىكى',
+               advancedTab: 'ئالىي',
+               validateNumberFailed: 'سان پىچىمىدا كىرگۈزۈش زۆرۈر',
+               confirmNewPage: 'نۆۋەتتىكى پۈتۈك مەزمۇنى ساقلانمىدى، يېڭى پۈتۈك قۇرامسىز؟',
+               confirmCancel: 'قىسمەن ئۆزگەرتىش ساقلانمىدى، بۇ سۆزلەشكۈنى تاقامسىز؟',
+               options: 'تاللانما',
+               target: 'نىشان كۆزنەك',
+               targetNew: 'يېڭى كۆزنەك (_blank)',
+               targetTop: 'پۈتۈن بەت (_top)',
+               targetSelf: 'مەزكۇر كۆزنەك (_self)',
+               targetParent: 'ئاتا كۆزنەك (_parent)',
+               langDirLTR: 'سولدىن ئوڭغا (LTR)',
+               langDirRTL: 'ئوڭدىن سولغا (RTL)',
+               styles: 'ئۇسلۇبلار',
+               cssClasses: 'ئۇسلۇب خىللىرى',
+               width: 'كەڭلىك',
+               height: 'ئېگىزلىك',
+               align: 'توغرىلىنىشى',
+               alignLeft: 'سول',
+               alignRight: 'ئوڭ',
+               alignCenter: 'ئوتتۇرا',
+               alignJustify: 'ئىككى تەرەپتىن توغرىلا',
+               alignTop: 'ئۈستى',
+               alignMiddle: 'ئوتتۇرا',
+               alignBottom: 'ئاستى',
+               alignNone: 'يوق',
+               invalidValue: 'ئىناۋەتسىز قىممەت.',
+               invalidHeight: 'ئېگىزلىك چوقۇم رەقەم پىچىمىدا بولۇشى زۆرۈر',
+               invalidWidth: 'كەڭلىك چوقۇم رەقەم پىچىمىدا بولۇشى زۆرۈر',
+               invalidCssLength: 'بۇ سۆز بۆلىكى چوقۇم مۇۋاپىق بولغان CSS ئۇزۇنلۇق قىممىتى بولۇشى زۆرۈر، بىرلىكى (px, %, in, cm, mm, em, ex, pt ياكى pc)',
+               invalidHtmlLength: 'بۇ سۆز بۆلىكى چوقۇم بىرىكمە HTML ئۇزۇنلۇق قىممىتى بولۇشى كېرەك. ئۆز ئىچىگە ئالىدىغان بىرلىك (px ياكى %)',
+               invalidInlineStyle: 'ئىچكى باغلانما ئۇسلۇبى چوقۇم چېكىتلىك پەش بىلەن ئايرىلغان بىر ياكى كۆپ «خاسلىق ئاتى:خاسلىق قىممىتى» پىچىمىدا بولۇشى لازىم',
+               cssLengthTooltip: 'بۇ سۆز بۆلىكى بىرىكمە CSS ئۇزۇنلۇق قىممىتى بولۇشى كېرەك. ئۆز ئىچىگە ئالىدىغان بىرلىك (px, %, in, cm, mm, em, ex, pt ياكى pc)',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class=\\\\"cke_accessibility\\\\">، ئىشلەتكىلى بولمايدۇ</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'End',
+                       36: 'Home',
+                       46: 'ئۆچۈر',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/uk.js b/sources/lang/uk.js
new file mode 100644 (file)
index 0000000..baa78e6
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Ukrainian language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'uk' ] = {
+       // ARIA description.
+       editor: 'Текстовий редактор',
+       editorPanel: 'Панель текстового редактора',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'натисніть ALT 0 для довідки',
+
+               browseServer: 'Огляд Сервера',
+               url: 'URL',
+               protocol: 'Протокол',
+               upload: 'Надіслати',
+               uploadSubmit: 'Надіслати на сервер',
+               image: 'Зображення',
+               flash: 'Flash',
+               form: 'Форма',
+               checkbox: 'Галочка',
+               radio: 'Кнопка вибору',
+               textField: 'Текстове поле',
+               textarea: 'Текстова область',
+               hiddenField: 'Приховане поле',
+               button: 'Кнопка',
+               select: 'Список',
+               imageButton: 'Кнопка із зображенням',
+               notSet: '<не визначено>',
+               id: 'Ідентифікатор',
+               name: 'Ім\'я',
+               langDir: 'Напрямок мови',
+               langDirLtr: 'Зліва направо (LTR)',
+               langDirRtl: 'Справа наліво (RTL)',
+               langCode: 'Код мови',
+               longDescr: 'Довгий опис URL',
+               cssClass: 'Клас CSS',
+               advisoryTitle: 'Заголовок',
+               cssStyle: 'Стиль CSS',
+               ok: 'ОК',
+               cancel: 'Скасувати',
+               close: 'Закрити',
+               preview: 'Попередній перегляд',
+               resize: 'Потягніть для зміни розмірів',
+               generalTab: 'Основне',
+               advancedTab: 'Додаткове',
+               validateNumberFailed: 'Значення не є цілим числом.',
+               confirmNewPage: 'Всі незбережені зміни будуть втрачені. Ви впевнені, що хочете завантажити нову сторінку?',
+               confirmCancel: 'Деякі опції змінено. Закрити вікно без збереження змін?',
+               options: 'Опції',
+               target: 'Ціль',
+               targetNew: 'Нове вікно (_blank)',
+               targetTop: 'Поточне вікно (_top)',
+               targetSelf: 'Поточний фрейм/вікно (_self)',
+               targetParent: 'Батьківський фрейм/вікно (_parent)',
+               langDirLTR: 'Зліва направо (LTR)',
+               langDirRTL: 'Справа наліво (RTL)',
+               styles: 'Стиль CSS',
+               cssClasses: 'Клас CSS',
+               width: 'Ширина',
+               height: 'Висота',
+               align: 'Вирівнювання',
+               alignLeft: 'По лівому краю',
+               alignRight: 'По правому краю',
+               alignCenter: 'По центру',
+               alignJustify: 'По ширині',
+               alignTop: 'По верхньому краю',
+               alignMiddle: 'По середині',
+               alignBottom: 'По нижньому краю',
+               alignNone: 'Нема',
+               invalidValue: 'Невірне значення.',
+               invalidHeight: 'Висота повинна бути цілим числом.',
+               invalidWidth: 'Ширина повинна бути цілим числом.',
+               invalidCssLength: 'Значення, вказане для "%1" в полі повинно бути позитивним числом або без дійсного виміру CSS блоку (px, %, in, cm, mm, em, ex, pt або pc).',
+               invalidHtmlLength: 'Значення, вказане для "%1" в полі повинно бути позитивним числом або без дійсного виміру HTML блоку (px або %).',
+               invalidInlineStyle: 'Значення, вказане для вбудованого стилю повинне складатися з одного чи кількох кортежів у форматі "ім\'я : значення", розділених крапкою з комою.',
+               cssLengthTooltip: 'Введіть номер значення в пікселях або число з дійсною одиниці CSS (px, %, in, cm, mm, em, ex, pt або pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, не доступне</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Backspace',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: 'Space', // MISSING
+                       35: 'End',
+                       36: 'Home',
+                       46: 'Видалити',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/vi.js b/sources/lang/vi.js
new file mode 100644 (file)
index 0000000..45d3d30
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Vietnamese language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'vi' ] = {
+       // ARIA description.
+       editor: 'Bộ soạn thảo văn bản có định dạng',
+       editorPanel: 'Bảng điều khiển Rich Text Editor',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: 'Nhấn ALT + 0 để được giúp đỡ',
+
+               browseServer: 'Duyệt máy chủ',
+               url: 'URL',
+               protocol: 'Giao thức',
+               upload: 'Tải lên',
+               uploadSubmit: 'Tải lên máy chủ',
+               image: 'Hình ảnh',
+               flash: 'Flash',
+               form: 'Biểu mẫu',
+               checkbox: 'Nút kiểm',
+               radio: 'Nút chọn',
+               textField: 'Trường văn bản',
+               textarea: 'Vùng văn bản',
+               hiddenField: 'Trường ẩn',
+               button: 'Nút',
+               select: 'Ô chọn',
+               imageButton: 'Nút hình ảnh',
+               notSet: '<không thiết lập>',
+               id: 'Định danh',
+               name: 'Tên',
+               langDir: 'Hướng ngôn ngữ',
+               langDirLtr: 'Trái sang phải (LTR)',
+               langDirRtl: 'Phải sang trái (RTL)',
+               langCode: 'Mã ngôn ngữ',
+               longDescr: 'Mô tả URL',
+               cssClass: 'Lớp Stylesheet',
+               advisoryTitle: 'Nhan đề hướng dẫn',
+               cssStyle: 'Kiểu ',
+               ok: 'Đồng ý',
+               cancel: 'Bỏ qua',
+               close: 'Đóng',
+               preview: 'Xem trước',
+               resize: 'Kéo rê để thay đổi kích cỡ',
+               generalTab: 'Tab chung',
+               advancedTab: 'Tab mở rộng',
+               validateNumberFailed: 'Giá trị này không phải là số.',
+               confirmNewPage: 'Mọi thay đổi không được lưu lại, nội dung này sẽ bị mất. Bạn có chắc chắn muốn tải một trang mới?',
+               confirmCancel: 'Một vài tùy chọn đã bị thay đổi. Bạn có chắc chắn muốn đóng hộp thoại?',
+               options: 'Tùy chọn',
+               target: 'Đích đến',
+               targetNew: 'Cửa sổ mới (_blank)',
+               targetTop: 'Cửa sổ trên cùng (_top)',
+               targetSelf: 'Tại trang (_self)',
+               targetParent: 'Cửa sổ cha (_parent)',
+               langDirLTR: 'Trái sang phải (LTR)',
+               langDirRTL: 'Phải sang trái (RTL)',
+               styles: 'Kiểu',
+               cssClasses: 'Lớp CSS',
+               width: 'Chiều rộng',
+               height: 'Chiều cao',
+               align: 'Vị trí',
+               alignLeft: 'Trái',
+               alignRight: 'Phải',
+               alignCenter: 'Giữa',
+               alignJustify: 'Sắp chữ',
+               alignTop: 'Trên',
+               alignMiddle: 'Giữa',
+               alignBottom: 'Dưới',
+               alignNone: 'Không',
+               invalidValue: 'Giá trị không hợp lệ.',
+               invalidHeight: 'Chiều cao phải là số nguyên.',
+               invalidWidth: 'Chiều rộng phải là số nguyên.',
+               invalidCssLength: 'Giá trị quy định cho trường "%1" phải là một số dương có hoặc không có một đơn vị đo CSS hợp lệ (px, %, in, cm, mm, em, ex, pt, hoặc pc).',
+               invalidHtmlLength: 'Giá trị quy định cho trường "%1" phải là một số dương có hoặc không có một đơn vị đo HTML hợp lệ (px hoặc %).',
+               invalidInlineStyle: 'Giá trị quy định cho kiểu nội tuyến phải bao gồm một hoặc nhiều dữ liệu với định dạng "tên:giá trị", cách nhau bằng dấu chấm phẩy.',
+               cssLengthTooltip: 'Nhập một giá trị theo pixel hoặc một số với một đơn vị CSS hợp lệ (px, %, in, cm, mm, em, ex, pt, hoặc pc).',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">, không có</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: 'Phím Backspace',
+                       13: 'Enter',
+                       16: 'Shift', // MISSING
+                       17: 'Ctrl', // MISSING
+                       18: 'Alt', // MISSING
+                       32: 'Space', // MISSING
+                       35: 'End', // MISSING
+                       36: 'Home', // MISSING
+                       46: 'Xóa',
+                       224: 'Command' // MISSING
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: 'Keyboard shortcut' // MISSING
+       }
+};
diff --git a/sources/lang/zh-cn.js b/sources/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..b89c0c9
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Chinese Simplified language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'zh-cn' ] = {
+       // ARIA description.
+       editor: '所见即所得编辑器',
+       editorPanel: '所见即所得编辑器面板',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: '按 ALT+0 获得帮助',
+
+               browseServer: '浏览服务器',
+               url: 'URL',
+               protocol: '协议',
+               upload: '上传',
+               uploadSubmit: '上传到服务器',
+               image: '图像',
+               flash: 'Flash',
+               form: '表单',
+               checkbox: '复选框',
+               radio: '单选按钮',
+               textField: '单行文本',
+               textarea: '多行文本',
+               hiddenField: '隐藏域',
+               button: '按钮',
+               select: '列表/菜单',
+               imageButton: '图像按钮',
+               notSet: '<没有设置>',
+               id: 'ID',
+               name: '名称',
+               langDir: '语言方向',
+               langDirLtr: '从左到右 (LTR)',
+               langDirRtl: '从右到左 (RTL)',
+               langCode: '语言代码',
+               longDescr: '详细说明 URL',
+               cssClass: '样式类名称',
+               advisoryTitle: '标题',
+               cssStyle: '行内样式',
+               ok: '确定',
+               cancel: '取消',
+               close: '关闭',
+               preview: '预览',
+               resize: '拖拽以改变大小',
+               generalTab: '常规',
+               advancedTab: '高级',
+               validateNumberFailed: '需要输入数字格式',
+               confirmNewPage: '当前文档内容未保存,是否确认新建文档?',
+               confirmCancel: '部分修改尚未保存,是否确认关闭对话框?',
+               options: '选项',
+               target: '目标窗口',
+               targetNew: '新窗口 (_blank)',
+               targetTop: '整页 (_top)',
+               targetSelf: '本窗口 (_self)',
+               targetParent: '父窗口 (_parent)',
+               langDirLTR: '从左到右 (LTR)',
+               langDirRTL: '从右到左 (RTL)',
+               styles: '样式',
+               cssClasses: '样式类',
+               width: '宽度',
+               height: '高度',
+               align: '对齐方式',
+               alignLeft: '左对齐',
+               alignRight: '右对齐',
+               alignCenter: '居中',
+               alignJustify: '两端对齐',
+               alignTop: '顶端',
+               alignMiddle: '居中',
+               alignBottom: '底部',
+               alignNone: '无',
+               invalidValue: '无效的值。',
+               invalidHeight: '高度必须为数字格式',
+               invalidWidth: '宽度必须为数字格式',
+               invalidCssLength: '此“%1”字段的值必须为正数,可以包含或不包含一个有效的 CSS 长度单位(px, %, in, cm, mm, em, ex, pt 或 pc)',
+               invalidHtmlLength: '此“%1”字段的值必须为正数,可以包含或不包含一个有效的 HTML 长度单位(px 或 %)',
+               invalidInlineStyle: '内联样式必须为格式是以分号分隔的一个或多个“属性名 : 属性值”。',
+               cssLengthTooltip: '输入一个表示像素值的数字,或加上一个有效的 CSS 长度单位(px, %, in, cm, mm, em, ex, pt 或 pc)。',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">,不可用</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: '退格键',
+                       13: '回车键',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: '空格键',
+                       35: '行尾键',
+                       36: '行首键',
+                       46: '删除键',
+                       224: 'Command'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: '快捷键'
+       }
+};
diff --git a/sources/lang/zh.js b/sources/lang/zh.js
new file mode 100644 (file)
index 0000000..c8a0548
--- /dev/null
@@ -0,0 +1,117 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/**
+ * @fileOverview Defines the {@link CKEDITOR.lang} object, for the
+ * Chinese Traditional language.
+ */
+
+/**#@+
+   @type String
+   @example
+*/
+
+/**
+ * Contains the dictionary of language entries.
+ * @namespace
+ */
+CKEDITOR.lang[ 'zh' ] = {
+       // ARIA description.
+       editor: 'RTF 編輯器',
+       editorPanel: 'RTF 編輯器面板',
+
+       // Common messages and labels.
+       common: {
+               // Screenreader titles. Please note that screenreaders are not always capable
+               // of reading non-English words. So be careful while translating it.
+               editorHelp: '按下 ALT 0 取得說明。',
+
+               browseServer: '瀏覽伺服器',
+               url: 'URL',
+               protocol: '通訊協定',
+               upload: '上傳',
+               uploadSubmit: '傳送至伺服器',
+               image: '圖像',
+               flash: 'Flash',
+               form: '表格',
+               checkbox: '核取方塊',
+               radio: '選項按鈕',
+               textField: '文字欄位',
+               textarea: '文字區域',
+               hiddenField: '隱藏欄位',
+               button: '按鈕',
+               select: '選取欄位',
+               imageButton: '影像按鈕',
+               notSet: '<未設定>',
+               id: 'ID',
+               name: '名稱',
+               langDir: '語言方向',
+               langDirLtr: '由左至右 (LTR)',
+               langDirRtl: '由右至左 (RTL)',
+               langCode: '語言代碼',
+               longDescr: '完整描述 URL',
+               cssClass: '樣式表類別',
+               advisoryTitle: '標題',
+               cssStyle: '樣式',
+               ok: '確定',
+               cancel: '取消',
+               close: '關閉',
+               preview: '預覽',
+               resize: '調整大小',
+               generalTab: '一般',
+               advancedTab: '進階',
+               validateNumberFailed: '此值不是數值。',
+               confirmNewPage: '現存的修改尚未儲存,要開新檔案?',
+               confirmCancel: '部份選項尚未儲存,要關閉對話框?',
+               options: '選項',
+               target: '目標',
+               targetNew: '開新視窗 (_blank)',
+               targetTop: '最上層視窗 (_top)',
+               targetSelf: '相同視窗 (_self)',
+               targetParent: '父視窗 (_parent)',
+               langDirLTR: '由左至右 (LTR)',
+               langDirRTL: '由右至左 (RTL)',
+               styles: '樣式',
+               cssClasses: '樣式表類別',
+               width: '寬度',
+               height: '高度',
+               align: '對齊方式',
+               alignLeft: '靠左對齊',
+               alignRight: '靠右對齊',
+               alignCenter: '置中對齊',
+               alignJustify: '左右對齊',
+               alignTop: '頂端',
+               alignMiddle: '中間對齊',
+               alignBottom: '底端',
+               alignNone: '無',
+               invalidValue: '無效值。',
+               invalidHeight: '高度必須為數字。',
+               invalidWidth: '寬度必須為數字。',
+               invalidCssLength: '「%1」的值應為正數,並可包含有效的 CSS 單位 (px, %, in, cm, mm, em, ex, pt, 或 pc)。',
+               invalidHtmlLength: '「%1」的值應為正數,並可包含有效的 HTML 單位 (px 或 %)。',
+               invalidInlineStyle: '行內樣式的值應包含一個以上的變數值組,其格式如「名稱:值」,並以分號區隔之。',
+               cssLengthTooltip: '請輸入數值,單位是像素或有效的 CSS 單位 (px, %, in, cm, mm, em, ex, pt, 或 pc)。',
+
+               // Put the voice-only part of the label in the span.
+               unavailable: '%1<span class="cke_accessibility">,無法使用</span>',
+
+               // Keyboard keys translations used for creating shortcuts descriptions in tooltips, context menus and ARIA labels.
+               keyboard: {
+                       8: '退格鍵',
+                       13: 'Enter',
+                       16: 'Shift',
+                       17: 'Ctrl',
+                       18: 'Alt',
+                       32: '空白鍵',
+                       35: 'End',
+                       36: 'Home',
+                       46: '刪除',
+                       224: 'Command 鍵'
+               },
+
+               // Prepended to ARIA labels with shortcuts.
+               keyboardShortcut: '鍵盤快捷鍵'
+       }
+};
diff --git a/sources/plugins/a11yhelp/dialogs/a11yhelp.js b/sources/plugins/a11yhelp/dialogs/a11yhelp.js
new file mode 100644 (file)
index 0000000..73b930c
--- /dev/null
@@ -0,0 +1,217 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.dialog.add( 'a11yHelp', function( editor ) {\r
+       var lang = editor.lang.a11yhelp,\r
+               coreLang = editor.lang.common.keyboard,\r
+               id = CKEDITOR.tools.getNextId();\r
+\r
+       // CharCode <-> KeyChar.\r
+       var keyMap = {\r
+               8: coreLang[ 8 ],\r
+               9: lang.tab,\r
+               13: coreLang[ 13 ],\r
+               16: coreLang[ 16 ],\r
+               17: coreLang[ 17 ],\r
+               18: coreLang[ 18 ],\r
+               19: lang.pause,\r
+               20: lang.capslock,\r
+               27: lang.escape,\r
+               33: lang.pageUp,\r
+               34: lang.pageDown,\r
+               35: coreLang[ 35 ],\r
+               36: coreLang[ 36 ],\r
+               37: lang.leftArrow,\r
+               38: lang.upArrow,\r
+               39: lang.rightArrow,\r
+               40: lang.downArrow,\r
+               45: lang.insert,\r
+               46: coreLang[ 46 ],\r
+               91: lang.leftWindowKey,\r
+               92: lang.rightWindowKey,\r
+               93: lang.selectKey,\r
+               96: lang.numpad0,\r
+               97: lang.numpad1,\r
+               98: lang.numpad2,\r
+               99: lang.numpad3,\r
+               100: lang.numpad4,\r
+               101: lang.numpad5,\r
+               102: lang.numpad6,\r
+               103: lang.numpad7,\r
+               104: lang.numpad8,\r
+               105: lang.numpad9,\r
+               106: lang.multiply,\r
+               107: lang.add,\r
+               109: lang.subtract,\r
+               110: lang.decimalPoint,\r
+               111: lang.divide,\r
+               112: lang.f1,\r
+               113: lang.f2,\r
+               114: lang.f3,\r
+               115: lang.f4,\r
+               116: lang.f5,\r
+               117: lang.f6,\r
+               118: lang.f7,\r
+               119: lang.f8,\r
+               120: lang.f9,\r
+               121: lang.f10,\r
+               122: lang.f11,\r
+               123: lang.f12,\r
+               144: lang.numLock,\r
+               145: lang.scrollLock,\r
+               186: lang.semiColon,\r
+               187: lang.equalSign,\r
+               188: lang.comma,\r
+               189: lang.dash,\r
+               190: lang.period,\r
+               191: lang.forwardSlash,\r
+               192: lang.graveAccent,\r
+               219: lang.openBracket,\r
+               220: lang.backSlash,\r
+               221: lang.closeBracket,\r
+               222: lang.singleQuote\r
+       };\r
+\r
+       // Modifier keys override.\r
+       keyMap[ CKEDITOR.ALT ] = coreLang[ 18 ];\r
+       keyMap[ CKEDITOR.SHIFT ] = coreLang[ 16 ];\r
+       keyMap[ CKEDITOR.CTRL ] = coreLang[ 17 ];\r
+\r
+       // Sort in desc.\r
+       var modifiers = [ CKEDITOR.ALT, CKEDITOR.SHIFT, CKEDITOR.CTRL ];\r
+\r
+       function representKeyStroke( keystroke ) {\r
+               var quotient, modifier,\r
+                       presentation = [];\r
+\r
+               for ( var i = 0; i < modifiers.length; i++ ) {\r
+                       modifier = modifiers[ i ];\r
+                       quotient = keystroke / modifiers[ i ];\r
+                       if ( quotient > 1 && quotient <= 2 ) {\r
+                               keystroke -= modifier;\r
+                               presentation.push( keyMap[ modifier ] );\r
+                       }\r
+               }\r
+\r
+               presentation.push( keyMap[ keystroke ] || String.fromCharCode( keystroke ) );\r
+\r
+               return presentation.join( '+' );\r
+       }\r
+\r
+       var variablesPattern = /\$\{(.*?)\}/g;\r
+\r
+       var replaceVariables = ( function() {\r
+               // Swaps keystrokes with their commands in object literal.\r
+               // This makes searching keystrokes by command much easier.\r
+               var keystrokesByCode = editor.keystrokeHandler.keystrokes,\r
+                       keystrokesByName = {};\r
+\r
+               for ( var i in keystrokesByCode )\r
+                       keystrokesByName[ keystrokesByCode[ i ] ] = i;\r
+\r
+               return function( match, name ) {\r
+                       // Return the keystroke representation or leave match untouched\r
+                       // if there's no keystroke for such command.\r
+                       return keystrokesByName[ name ] ? representKeyStroke( keystrokesByName[ name ] ) : match;\r
+               };\r
+       } )();\r
+\r
+       // Create the help list directly from lang file entries.\r
+       function buildHelpContents() {\r
+               var pageTpl = '<div class="cke_accessibility_legend" role="document" aria-labelledby="' + id + '_arialbl" tabIndex="-1">%1</div>' +\r
+                               '<span id="' + id + '_arialbl" class="cke_voice_label">' + lang.contents + ' </span>',\r
+                       sectionTpl = '<h1>%1</h1><dl>%2</dl>',\r
+                       itemTpl = '<dt>%1</dt><dd>%2</dd>';\r
+\r
+               var pageHtml = [],\r
+                       sections = lang.legend,\r
+                       sectionLength = sections.length;\r
+\r
+               for ( var i = 0; i < sectionLength; i++ ) {\r
+                       var section = sections[ i ],\r
+                               sectionHtml = [],\r
+                               items = section.items,\r
+                               itemsLength = items.length;\r
+\r
+                       for ( var j = 0; j < itemsLength; j++ ) {\r
+                               var item = items[ j ],\r
+                                       itemLegend = item.legend.replace( variablesPattern, replaceVariables );\r
+\r
+                               // (#9765) If some commands haven't been replaced in the legend,\r
+                               // most likely their keystrokes are unavailable and we shouldn't include\r
+                               // them in our help list.\r
+                               if ( itemLegend.match( variablesPattern ) )\r
+                                       continue;\r
+\r
+                               sectionHtml.push( itemTpl.replace( '%1', item.name ).replace( '%2', itemLegend ) );\r
+                       }\r
+\r
+                       pageHtml.push( sectionTpl.replace( '%1', section.name ).replace( '%2', sectionHtml.join( '' ) ) );\r
+               }\r
+\r
+               return pageTpl.replace( '%1', pageHtml.join( '' ) );\r
+       }\r
+\r
+       return {\r
+               title: lang.title,\r
+               minWidth: 600,\r
+               minHeight: 400,\r
+               contents: [ {\r
+                       id: 'info',\r
+                       label: editor.lang.common.generalTab,\r
+                       expand: true,\r
+                       elements: [\r
+                               {\r
+                                       type: 'html',\r
+                                       id: 'legends',\r
+                                       style: 'white-space:normal;',\r
+                                       focus: function() {\r
+                                               this.getElement().focus();\r
+                                       },\r
+                                       html: buildHelpContents() + '<style type="text/css">' +\r
+                                               '.cke_accessibility_legend' +\r
+                                               '{' +\r
+                                                       'width:600px;' +\r
+                                                       'height:400px;' +\r
+                                                       'padding-right:5px;' +\r
+                                                       'overflow-y:auto;' +\r
+                                                       'overflow-x:hidden;' +\r
+                                               '}' +\r
+                                               // Some adjustments are to be done for Quirks to work "properly" (#5757)\r
+                                               '.cke_browser_quirks .cke_accessibility_legend,' +\r
+                                               '{' +\r
+                                                       'height:390px' +\r
+                                               '}' +\r
+                                               // Override non-wrapping white-space rule in reset css.\r
+                                               '.cke_accessibility_legend *' +\r
+                                               '{' +\r
+                                                       'white-space:normal;' +\r
+                                               '}' +\r
+                                               '.cke_accessibility_legend h1' +\r
+                                               '{' +\r
+                                                       'font-size: 20px;' +\r
+                                                       'border-bottom: 1px solid #AAA;' +\r
+                                                       'margin: 5px 0px 15px;' +\r
+                                               '}' +\r
+                                               '.cke_accessibility_legend dl' +\r
+                                               '{' +\r
+                                                       'margin-left: 5px;' +\r
+                                               '}' +\r
+                                               '.cke_accessibility_legend dt' +\r
+                                               '{' +\r
+                                                       'font-size: 13px;' +\r
+                                                       'font-weight: bold;' +\r
+                                               '}' +\r
+                                               '.cke_accessibility_legend dd' +\r
+                                               '{' +\r
+                                                       'margin:10px' +\r
+                                               '}' +\r
+                                               '</style>'\r
+                               }\r
+                       ]\r
+               } ],\r
+               buttons: [ CKEDITOR.dialog.cancelButton ]\r
+       };\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/_translationstatus.txt b/sources/plugins/a11yhelp/dialogs/lang/_translationstatus.txt
new file mode 100644 (file)
index 0000000..28e8dae
--- /dev/null
@@ -0,0 +1,25 @@
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+\r
+cs.js      Found: 30 Missing: 0\r
+cy.js      Found: 30 Missing: 0\r
+da.js      Found: 12 Missing: 18\r
+de.js      Found: 30 Missing: 0\r
+el.js      Found: 25 Missing: 5\r
+eo.js      Found: 30 Missing: 0\r
+fa.js      Found: 30 Missing: 0\r
+fi.js      Found: 30 Missing: 0\r
+fr.js      Found: 30 Missing: 0\r
+gu.js      Found: 12 Missing: 18\r
+he.js      Found: 30 Missing: 0\r
+it.js      Found: 30 Missing: 0\r
+mk.js      Found: 5 Missing: 25\r
+nb.js      Found: 30 Missing: 0\r
+nl.js      Found: 30 Missing: 0\r
+no.js      Found: 30 Missing: 0\r
+pt-br.js   Found: 30 Missing: 0\r
+ro.js      Found: 6 Missing: 24\r
+tr.js      Found: 30 Missing: 0\r
+ug.js      Found: 27 Missing: 3\r
+vi.js      Found: 6 Missing: 24\r
+zh-cn.js   Found: 30 Missing: 0\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/af.js b/sources/plugins/a11yhelp/dialogs/lang/af.js
new file mode 100644 (file)
index 0000000..7469bc1
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'af', {\r
+       title: 'Toeganglikheid instruksies',\r
+       contents: 'Hulp inhoud. Druk ESC om toe te maak.',\r
+       legend: [\r
+               {\r
+               name: 'Algemeen',\r
+               items: [\r
+                       {\r
+                       name: 'Bewerker balk',\r
+                       legend: 'Druk ${toolbarFocus} om op die werkbalk te land. Beweeg na die volgende en voorige wekrbalkgroep met TAB and SHIFT+TAB. Beweeg na die volgende en voorige werkbalkknop met die regter of linker pyl. Druk SPASIE of ENTER om die knop te bevestig.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Bewerker dialoog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Bewerkerinhoudmenu',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pouse',\r
+       capslock: 'Hoofletterslot',\r
+       escape: 'Ontsnap',\r
+       pageUp: 'Blaaiop',\r
+       pageDown: 'Blaaiaf',\r
+       leftArrow: 'Linkspyl',\r
+       upArrow: 'Oppyl',\r
+       rightArrow: 'Regterpyl',\r
+       downArrow: 'Afpyl',\r
+       insert: 'Toevoeg',\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Nommerblok 0',\r
+       numpad1: 'Nommerblok 1',\r
+       numpad2: 'Nommerblok 2',\r
+       numpad3: 'Nommerblok 3',\r
+       numpad4: 'Nommerblok 4',\r
+       numpad5: 'Nommerblok 5',\r
+       numpad6: 'Nommerblok 6',\r
+       numpad7: 'Nommerblok 7',\r
+       numpad8: 'Nommerblok 8',\r
+       numpad9: 'Nommerblok 9',\r
+       multiply: 'Maal',\r
+       add: 'Plus',\r
+       subtract: 'Minus',\r
+       decimalPoint: 'Desimaalepunt',\r
+       divide: 'Gedeeldeur',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Nommervergrendel',\r
+       scrollLock: 'Rolvergrendel',\r
+       semiColon: 'Kommapunt',\r
+       equalSign: 'Isgelykaan',\r
+       comma: 'Komma',\r
+       dash: 'Koppelteken',\r
+       period: 'Punt',\r
+       forwardSlash: 'Skuinsstreep',\r
+       graveAccent: 'Aksentteken',\r
+       openBracket: 'Oopblokhakkie',\r
+       backSlash: 'Trustreep',\r
+       closeBracket: 'Toeblokhakkie',\r
+       singleQuote: 'Enkelaanhaalingsteken'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ar.js b/sources/plugins/a11yhelp/dialogs/lang/ar.js
new file mode 100644 (file)
index 0000000..5c316c7
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ar', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'عام',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'إضافة',\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'تقسيم',\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'فاصلة',\r
+       dash: 'Dash', // MISSING\r
+       period: 'نقطة',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/az.js b/sources/plugins/a11yhelp/dialogs/lang/az.js
new file mode 100644 (file)
index 0000000..9c04b65
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'az', {\r
+       title: 'Əlillərə dəstək üzrə təlimat',\r
+       contents: 'Kömək. Pəncərəni bağlamaq üçün ESC basın.',\r
+       legend: [\r
+               {\r
+               name: 'Əsas',\r
+               items: [\r
+                       {\r
+                       name: 'Düzəliş edənin alətlər çubuğu',\r
+                       legend: 'Panelə keçmək üçün ${toolbarFocus} basın. Növbəti panelə TAB, əvvəlki panelə isə SHIFT+TAB düyməsi vasitəsi ilə keçə bilərsiz. Paneldəki düymələr arasında sol və sağ ox düyməsi ilə keçid edə bilərsiz. Seçilmiş düyməsi SPACE və ya ENTER ilə işlədə bilərsiniz.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktorun pəncərəsi',\r
+                       legend:\r
+                               'Pəncərə içində növbəti element seçmək üçün TAB düyməni basın, əvvəlki isə - SHIFT+TAB. Təsdiq edilməsi üçün ENTER, imtina edilməsi isə ESC diymələri istifadə edin. Pəncərədə bir neçə vərəq olanda olnarın siyahı ALT+F10 ilə aça bilərsiz. Vərəqlərin siyahı fokus altında olanda ox düymələr vasitəsi ilə onların arasında keçid edə bilərsiz.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktorun seçimlərin menyusu',\r
+                       legend: 'Seçimləri redaktə etmək üçün ${contextMenu} ya da APPLICATION KEY basın. Növbəti seçimə keçmək üçün TAB ya AŞAĞI OX düyməsini basın, əvvəlki isə - SHIFT+TAB ya YUXARI OX. Seçimi arımaq SPACE ya ENTER düymələri istifadə edin. Alt menyunu açmaq üçün SPACE, ENTER ya SAĞA OX basın. ESC ya SOLA OX ilə geriyə qayıda bilərsiz. Bütün menyunu ESC ilə bağlıyın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Düzəliş edənin siyahı qutusu',\r
+                       legend: 'Siyahı qutusu içində növbəti bənd seçmək üçün TAB ya AŞAĞI OX, əvvəlki isə SHIFT+TAB ya YUXARI OX basın. Seçimi arımaq SPACE ya ENTER düymələri istifadə edin. Siyahı qutusu ESC ilə bağlıyın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktor elementin cığır paneli',\r
+                       legend: 'Elementin cığır paneli seçmək üçün ${elementsPathFocus} basın. Növbəti element seçmək üçün TAB ya SAĞA OX, əvvəlki isə SHIFT+TAB ya SOLA OX istifadə edin. Elementi arımaq SPACE ya ENTER düymələri mövcuddur.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Əmrlər',\r
+               items: [\r
+                       {\r
+                       name: 'Əmri geri qaytar',\r
+                       legend: '${undo} basın'\r
+               },\r
+                       {\r
+                       name: 'Geri əmri',\r
+                       legend: '${redo} basın'\r
+               },\r
+                       {\r
+                       name: 'Qalın əmri',\r
+                       legend: '${bold}  basın'\r
+               },\r
+                       {\r
+                       name: 'Kursiv əmri',\r
+                       legend: '${italic} basın'\r
+               },\r
+                       {\r
+                       name: 'Altdan xətt əmri',\r
+                       legend: '${underline} basın'\r
+               },\r
+                       {\r
+                       name: 'Link əmri',\r
+                       legend: '${link} basın'\r
+               },\r
+                       {\r
+                       name: 'Paneli gizlət əmri',\r
+                       legend: '${toolbarCollapse} basın'\r
+               },\r
+                       {\r
+                       name: 'Əvvəlki fokus sahəsi seç əmrı',\r
+                       legend: 'Kursordan əvvəl ən yaxın əlçatmaz yerə dəymək üçün ${accessPreviousSpace} basın, misal üçün: iki dal-badal HR teg. Uzaq yerlərə dəymək üçün bir neçə dəfə basın.'\r
+               },\r
+                       {\r
+                       name: 'Növbəti fokus sahəsi seç əmrı',\r
+                       legend: 'Kursordan sonra ən yaxın əlçatmaz yerə dəymək üçün ${accessNextSpace} basın, misal üçün: iki dal-badal HR teg. Uzaq yerlərə dəymək üçün bir neçə dəfə basın.'\r
+               },\r
+                       {\r
+                       name: 'Hərtərəfli Kömək',\r
+                       legend: '${a11yHelp} basın'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Sola ox işarəsi',\r
+       upArrow: 'Yuxarı ox işarəsi',\r
+       rightArrow: 'Sağa ox işarəsi',\r
+       downArrow: 'Aşağı ox işarəsi',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Soldaki Windows düyməsi',\r
+       rightWindowKey: 'Sağdaki Windows düyməsi',\r
+       selectKey: 'Düyməni seçin',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Vurma',\r
+       add: 'Əlavə et',\r
+       subtract: 'Çıxma',\r
+       decimalPoint: 'Onluq kəsri tam ədəddən ayıran nöqtə',\r
+       divide: 'Bölüşdürmə',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Nöqtəli verqül',\r
+       equalSign: 'Barəbərlik işarəsi',\r
+       comma: 'Vergül',\r
+       dash: 'Defis',\r
+       period: 'Nöqtə',\r
+       forwardSlash: 'Çəp xətt',\r
+       graveAccent: 'Vurğu işarəsi',\r
+       openBracket: 'Açılan mötərizə',\r
+       backSlash: 'Tərs çəpəki xətt',\r
+       closeBracket: 'Bağlanan mötərizə',\r
+       singleQuote: 'Tək dırnaq'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/bg.js b/sources/plugins/a11yhelp/dialogs/lang/bg.js
new file mode 100644 (file)
index 0000000..ce9cdd8
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'bg', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Общо',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ca.js b/sources/plugins/a11yhelp/dialogs/lang/ca.js
new file mode 100644 (file)
index 0000000..f415b90
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ca', {\r
+       title: 'Instruccions d\'Accessibilitat',\r
+       contents: 'Continguts de l\'Ajuda. Per tancar aquest quadre de diàleg premi ESC.',\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Editor de barra d\'eines',\r
+                       legend: 'Premi ${toolbarFocus} per desplaçar-se per la barra d\'eines. Vagi en el següent i anterior grup de barra d\'eines amb TAB i SHIFT+TAB. Vagi en el següent i anterior botó de la barra d\'eines amb RIGHT ARROW i LEFT ARROW. Premi SPACE o ENTER per activar el botó de la barra d\'eines.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de quadre de diàleg',\r
+                       legend:\r
+                               'Dins d\'un quadre de diàleg, premi la tecla TAB per desplaçar-se fins al següent element del quadre de diàleg, premi la tecla Shift + TAB per desplaçar-se a l\'anterior element del quadre de diàleg, premi la tecla ENTER per confirmar el quadre de diàleg, premi la tecla ESC per cancel·lar el quadre de diàleg. Quan un quadre de diàleg té diverses pestanyes, la llista de pestanyes pot ser assolit ja sigui amb ALT + F10 o TAB, com a part de l\'ordre de tabulació del quadre de diàleg. Amb la llista de pestanyes seleccionada, pot anar a la fitxa següent i anterior amb la tecla FLETXA DRETA i ESQUERRA, respectivament.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de menú contextual',\r
+                       legend: 'Premi ${contextMenu} o APPLICATION KEY per obrir el menú contextual. Després desplacis a la següent opció del menú amb TAB o DOWN ARROW. Desplacis a l\'anterior opció amb SHIFT+TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l\'opció del menú. Obri el submenú de l\'actual opció utilitzant SPACE o ENTER o RIGHT ARROW. Pot tornar a l\'opció del menú pare amb ESC o LEFT ARROW. Tanqui el menú contextual amb ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de caixa de llista',\r
+                       legend: 'Dins d\'un quadre de llista, desplacis al següent element de la llista amb TAB o DOWN ARROW. Desplacis a l\'anterior element de la llista amb SHIFT+TAB o UP ARROW. Premi SPACE o ENTER per seleccionar l\'opció de la llista. Premi ESC per tancar el quadre de llista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de barra de ruta de l\'element',\r
+                       legend: 'Premi ${elementsPathFocus} per anar als elements de la barra de ruta. Desplacis al botó de l\'element següent amb TAB o RIGHT ARROW. Desplacis a l\'anterior botó amb SHIFT+TAB o LEFT ARROW. Premi SPACE o ENTER per seleccionar l\'element a l\'editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Ordres',\r
+               items: [\r
+                       {\r
+                       name: 'Desfer ordre',\r
+                       legend: 'Premi ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Refer ordre',\r
+                       legend: 'Premi ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Ordre negreta',\r
+                       legend: 'Premi ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Ordre cursiva',\r
+                       legend: 'Premi ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Ordre subratllat',\r
+                       legend: 'Premi ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Ordre enllaç',\r
+                       legend: 'Premi ${link}'\r
+               },\r
+                       {\r
+                       name: 'Ordre amagar barra d\'eines',\r
+                       legend: 'Premi ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Ordre per accedir a l\'anterior espai enfocat',\r
+                       legend: 'Premi ${accessPreviousSpace} per accedir a l\'enfocament d\'espai més proper inabastable abans del símbol d\'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d\'espais distants.'\r
+               },\r
+                       {\r
+                       name: 'Ordre per accedir al següent espai enfocat',\r
+                       legend: 'Premi ${accessNextSpace} per accedir a l\'enfocament d\'espai més proper inabastable després del símbol d\'intercalació, per exemple: dos elements HR adjacents. Repetiu la combinació de tecles per arribar a enfocaments d\'espais distants.'\r
+               },\r
+                       {\r
+                       name: 'Ajuda d\'accessibilitat',\r
+                       legend: 'Premi ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulació',\r
+       pause: 'Pausa',\r
+       capslock: 'Bloqueig de majúscules',\r
+       escape: 'Escape',\r
+       pageUp: 'Pàgina Amunt',\r
+       pageDown: 'Pàgina Avall',\r
+       leftArrow: 'Fletxa Esquerra',\r
+       upArrow: 'Fletxa Amunt',\r
+       rightArrow: 'Fletxa Dreta',\r
+       downArrow: 'Fletxa Avall',\r
+       insert: 'Inserir',\r
+       leftWindowKey: 'Tecla Windows Esquerra',\r
+       rightWindowKey: 'Tecla Windows Dreta',\r
+       selectKey: 'Tecla Seleccionar',\r
+       numpad0: 'Teclat Numèric 0',\r
+       numpad1: 'Teclat Numèric 1',\r
+       numpad2: 'Teclat Numèric 2',\r
+       numpad3: 'Teclat Numèric 3',\r
+       numpad4: 'Teclat Numèric 4',\r
+       numpad5: 'Teclat Numèric 5',\r
+       numpad6: 'Teclat Numèric 6',\r
+       numpad7: 'Teclat Numèric 7',\r
+       numpad8: 'Teclat Numèric 8',\r
+       numpad9: 'Teclat Numèric 9',\r
+       multiply: 'Multiplicació',\r
+       add: 'Suma',\r
+       subtract: 'Resta',\r
+       decimalPoint: 'Punt Decimal',\r
+       divide: 'Divisió',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Bloqueig Teclat Numèric',\r
+       scrollLock: 'Bloqueig de Desplaçament',\r
+       semiColon: 'Punt i Coma',\r
+       equalSign: 'Símbol Igual',\r
+       comma: 'Coma',\r
+       dash: 'Guió',\r
+       period: 'Punt',\r
+       forwardSlash: 'Barra Diagonal',\r
+       graveAccent: 'Accent Obert',\r
+       openBracket: 'Claudàtor Obert',\r
+       backSlash: 'Barra Invertida',\r
+       closeBracket: 'Claudàtor Tancat',\r
+       singleQuote: 'Cometa Simple'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/cs.js b/sources/plugins/a11yhelp/dialogs/lang/cs.js
new file mode 100644 (file)
index 0000000..39e4d64
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'cs', {\r
+       title: 'Instrukce pro přístupnost',\r
+       contents: 'Obsah nápovědy. Pro uzavření tohoto dialogu stiskněte klávesu ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Obecné',\r
+               items: [\r
+                       {\r
+                       name: 'Panel nástrojů editoru',\r
+                       legend: 'Stiskněte${toolbarFocus} k procházení panelu nástrojů. Přejděte na další a předchozí skupiny pomocí TAB a SHIFT+TAB. Přechod na další a předchozí tlačítko panelu nástrojů je pomocí ŠIPKA VPRAVO nebo ŠIPKA VLEVO. Stisknutím mezerníku nebo klávesy ENTER tlačítko aktivujete.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialogové okno editoru',\r
+                       legend:\r
+                               'Uvnitř dialogového okna stiskněte TAB pro přesunutí na další prvek okna, stiskněte SHIFT+TAB pro přesun na předchozí prvek okna, stiskněte ENTER pro odeslání dialogu, stiskněte ESC pro jeho zrušení. Pro dialogová okna, která mají mnoho karet stiskněte ALT+F10 pro zaměření seznamu karet, nebo TAB, pro posun podle pořadí karet.Při zaměření seznamu karet se můžete jimi posouvat pomocí ŠIPKY VPRAVO a VLEVO.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Kontextové menu editoru',\r
+                       legend: 'Stiskněte ${contextMenu} nebo klávesu APPLICATION k otevření kontextového menu. Pak se přesuňte na další možnost menu pomocí TAB nebo ŠIPKY DOLŮ. Přesuňte se na předchozí možnost pomocí  SHIFT+TAB nebo ŠIPKY NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti menu. Podmenu současné možnosti otevřete pomocí MEZERNÍKU nebo ENTER či ŠIPKY DOLEVA. Kontextové menu uzavřete stiskem ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Rámeček seznamu editoru',\r
+                       legend: 'Uvnitř rámečku seznamu se přesunete na další položku menu pomocí TAB nebo ŠIPKA DOLŮ. Na předchozí položku se přesunete SHIFT+TAB nebo ŠIPKA NAHORU. Stiskněte MEZERNÍK nebo ENTER pro zvolení možnosti seznamu. Stiskněte ESC pro uzavření seznamu.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Lišta cesty prvku v editoru',\r
+                       legend: 'Stiskněte ${elementsPathFocus} pro procházení lišty cesty prvku. Na další tlačítko prvku se přesunete pomocí TAB nebo ŠIPKA VPRAVO. Na předchozí tlačítko se přesunete pomocí SHIFT+TAB nebo ŠIPKA VLEVO. Stiskněte MEZERNÍK nebo ENTER pro vybrání prvku v editoru.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Příkazy',\r
+               items: [\r
+                       {\r
+                       name: ' Příkaz Zpět',\r
+                       legend: 'Stiskněte ${undo}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Znovu',\r
+                       legend: 'Stiskněte ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Tučné',\r
+                       legend: 'Stiskněte ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Kurzíva',\r
+                       legend: 'Stiskněte ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Podtržení',\r
+                       legend: 'Stiskněte ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Odkaz',\r
+                       legend: 'Stiskněte ${link}'\r
+               },\r
+                       {\r
+                       name: ' Příkaz Skrýt panel nástrojů',\r
+                       legend: 'Stiskněte ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Příkaz pro přístup k předchozímu prostoru zaměření',\r
+                       legend: 'Stiskněte ${accessPreviousSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření před stříškou, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte.'\r
+               },\r
+                       {\r
+                       name: 'Příkaz pro přístup k dalšímu prostoru zaměření',\r
+                       legend: 'Stiskněte ${accessNextSpace} pro přístup k nejbližšímu nedosažitelnému prostoru zaměření po stříšce, například: dva přilehlé prvky HR. Pro dosažení vzdálených prostorů zaměření tuto kombinaci kláves opakujte.'\r
+               },\r
+                       {\r
+                       name: ' Nápověda přístupnosti',\r
+                       legend: 'Stiskněte ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulátor',\r
+       pause: 'Pauza',\r
+       capslock: 'Caps lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Stránka nahoru',\r
+       pageDown: 'Stránka dolů',\r
+       leftArrow: 'Šipka vlevo',\r
+       upArrow: 'Šipka nahoru',\r
+       rightArrow: 'Šipka vpravo',\r
+       downArrow: 'Šipka dolů',\r
+       insert: 'Vložit',\r
+       leftWindowKey: 'Levá klávesa Windows',\r
+       rightWindowKey: 'Pravá klávesa Windows',\r
+       selectKey: 'Vyberte klávesu',\r
+       numpad0: 'Numerická klávesa 0',\r
+       numpad1: 'Numerická klávesa 1',\r
+       numpad2: 'Numerická klávesa 2',\r
+       numpad3: 'Numerická klávesa 3',\r
+       numpad4: 'Numerická klávesa 4',\r
+       numpad5: 'Numerická klávesa 5',\r
+       numpad6: 'Numerická klávesa 6',\r
+       numpad7: 'Numerická klávesa 7',\r
+       numpad8: 'Numerická klávesa 8',\r
+       numpad9: 'Numerická klávesa 9',\r
+       multiply: 'Numerická klávesa násobení',\r
+       add: 'Přidat',\r
+       subtract: 'Numerická klávesa odečítání',\r
+       decimalPoint: 'Desetinná tečka',\r
+       divide: 'Numerická klávesa dělení',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num lock',\r
+       scrollLock: 'Scroll lock',\r
+       semiColon: 'Středník',\r
+       equalSign: 'Rovnítko',\r
+       comma: 'Čárka',\r
+       dash: 'Pomlčka',\r
+       period: 'Tečka',\r
+       forwardSlash: 'Lomítko',\r
+       graveAccent: 'Přízvuk',\r
+       openBracket: 'Otevřená hranatá závorka',\r
+       backSlash: 'Obrácené lomítko',\r
+       closeBracket: 'Uzavřená hranatá závorka',\r
+       singleQuote: 'Jednoduchá uvozovka'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/cy.js b/sources/plugins/a11yhelp/dialogs/lang/cy.js
new file mode 100644 (file)
index 0000000..3ac77cf
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'cy', {\r
+       title: 'Canllawiau Hygyrchedd',\r
+       contents: 'Cynnwys Cymorth. I gau y deialog hwn, pwyswch ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Cyffredinol',\r
+               items: [\r
+                       {\r
+                       name: 'Bar Offer y Golygydd',\r
+                       legend: 'Pwyswch $ {toolbarFocus} i fynd at y bar offer. Symudwch i\'r grŵp bar offer nesaf a blaenorol gyda TAB a SHIFT+TAB. Symudwch i\'r botwm bar offer nesaf a blaenorol gyda SAETH DDE neu SAETH CHWITH. Pwyswch SPACE neu ENTER i wneud botwm y bar offer yn weithredol.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Deialog y Golygydd',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Dewislen Cyd-destun y Golygydd',\r
+                       legend: 'Pwyswch $ {contextMenu} neu\'r ALLWEDD \'APPLICATION\' i agor y ddewislen cyd-destun. Yna symudwch i\'r opsiwn ddewislen nesaf gyda\'r TAB neu\'r SAETH I LAWR. Symudwch i\'r opsiwn blaenorol gyda SHIFT+TAB neu\'r SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn ddewislen. Agorwch is-dewislen yr opsiwn cyfredol gyda SPACE neu ENTER neu SAETH DDE. Ewch yn ôl i\'r eitem ar y ddewislen uwch gydag ESC neu SAETH CHWITH. Ceuwch y ddewislen cyd-destun gydag ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Blwch Rhestr y Golygydd',\r
+                       legend: 'Tu mewn y blwch rhestr, ewch i\'r eitem rhestr nesaf gyda TAB neu\'r SAETH I LAWR. Symudwch i restr eitem flaenorol gyda SHIFT+TAB neu SAETH I FYNY. Pwyswch SPACE neu ENTER i ddewis yr opsiwn o\'r rhestr. Pwyswch ESC i gau\'r rhestr.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Bar Llwybr Elfen y Golygydd',\r
+                       legend: 'Pwyswch ${elementsPathFocus} i fynd i\'r bar llwybr elfennau. Symudwch i fotwm yr elfen nesaf gyda TAB neu SAETH DDE. Symudwch i fotwm blaenorol gyda SHIFT+TAB neu SAETH CHWITH. Pwyswch SPACE neu ENTER i ddewis yr elfen yn y golygydd.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Gorchmynion',\r
+               items: [\r
+                       {\r
+                       name: 'Gorchymyn dadwneud',\r
+                       legend: 'Pwyswch ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn ailadrodd',\r
+                       legend: 'Pwyswch ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn Bras',\r
+                       legend: 'Pwyswch ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn italig',\r
+                       legend: 'Pwyswch ${italig}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn tanlinellu',\r
+                       legend: 'Pwyso ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn dolen',\r
+                       legend: 'Pwyswch ${link}'\r
+               },\r
+                       {\r
+                       name: 'Gorchymyn Cwympo\'r Dewislen',\r
+                       legend: 'Pwyswch ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Myned i orchymyn bwlch ffocws blaenorol',\r
+                       legend: 'Pwyswch ${accessPreviousSpace} i fyned i\'r "blwch ffocws sydd methu ei gyrraedd" cyn y caret, er enghraifft: dwy elfen HR drws nesaf i\'w gilydd. AIladroddwch y cyfuniad allwedd i gyrraedd bylchau ffocws pell.'\r
+               },\r
+                       {\r
+                       name: 'Ewch i\'r gorchymyn blwch ffocws nesaf',\r
+                       legend: 'Pwyswch ${accessNextSpace} i fyned i\'r blwch ffocws agosaf nad oes modd ei gyrraedd ar ôl y caret, er enghraifft: dwy elfen HR drws nesaf i\'w gilydd. Ailadroddwch y cyfuniad allwedd i gyrraedd blychau ffocws pell.'\r
+               },\r
+                       {\r
+                       name: 'Cymorth Hygyrchedd',\r
+                       legend: 'Pwyswch ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/da.js b/sources/plugins/a11yhelp/dialogs/lang/da.js
new file mode 100644 (file)
index 0000000..f507bf0
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'da', {\r
+       title: 'Tilgængelighedsinstrukser',\r
+       contents: 'Onlinehjælp. For at lukke dette vindue klik ESC',\r
+       legend: [\r
+               {\r
+               name: 'Generelt',\r
+               items: [\r
+                       {\r
+                       name: 'Editor værktøjslinje',\r
+                       legend: 'Tryk ${toolbarFocus} for at navigere til værktøjslinjen. Flyt til næste eller forrige værktøjsline gruppe ved hjælp af TAB eller SHIFT+TAB. Flyt til næste eller forrige værktøjslinje knap med venstre- eller højre piltast. Tryk på SPACE eller ENTER for at aktivere værktøjslinje knappen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor dialogboks',\r
+                       legend:\r
+                               'Inde i en dialogboks kan du, trykke på TAB for at navigere til næste element, trykke på SHIFT+TAB for at navigere til forrige element, trykke på ENTER for at afsende eller trykke på ESC for at lukke dialogboksen.\r\nNår en dialogboks har flere faner, fanelisten kan tilgås med ALT+F10 eller med TAB. Hvis fanelisten er i fokus kan du skifte til næste eller forrige tab, med højre- og venstre piltast.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktør kontekstmenu',\r
+                       legend: 'Tryk ${contextMenu} eller APPLICATION KEY for at åbne kontekstmenuen. Flyt derefter til næste menuvalg med TAB eller PIL NED. Flyt til forrige valg med SHIFT+TAB eller PIL OP. Tryk MELLEMRUM eller RETUR for at vælge menu-muligheder. Åben under-menu af aktuelle valg med MELLEMRUM eller RETUR eller HØJRE PIL. Gå tilbage til overliggende menu-emne med ESC eller VENSTRE PIL. Luk kontekstmenu med ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktør listeboks',\r
+                       legend: 'Flyt til næste emne med TAB eller PIL NED inde i en listeboks. Flyt til forrige listeemne med SHIFT+TAB eller PIL OP. Tryk MELLEMRUM eller RETUR for at vælge liste-muligheder. Tryk ESC for at lukke liste-boksen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktør elementsti-bar',\r
+                       legend: 'Tryk ${elementsPathFocus} for at navigere til elementernes sti-bar. Flyt til næste element-knap med TAB eller HØJRE PIL. Flyt til forrige knap med SHIFT+TAB eller VENSTRE PIL. Klik MELLEMRUM eller RETUR for at vælge element i editoren.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Kommandoer',\r
+               items: [\r
+                       {\r
+                       name: 'Fortryd kommando',\r
+                       legend: 'Klik på ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Gentag kommando',\r
+                       legend: 'Klik ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Fed kommando',\r
+                       legend: 'Klik ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursiv kommando',\r
+                       legend: 'Klik ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Understregnings kommando',\r
+                       legend: 'Klik ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link kommando',\r
+                       legend: 'Klik ${link}'\r
+               },\r
+                       {\r
+                       name: 'Klap værktøjslinje sammen kommando ',\r
+                       legend: 'Klik ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Adgang til forrige fokusområde kommando',\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: 'Tilgængelighedshjælp',\r
+                       legend: 'Kilk ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Venstre pil',\r
+       upArrow: 'Pil op',\r
+       rightArrow: 'Højre pil',\r
+       downArrow: 'Pil ned',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Venstre Windows tast',\r
+       rightWindowKey: 'Højre Windows tast',\r
+       selectKey: 'Select-knap',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Gange',\r
+       add: 'Plus',\r
+       subtract: 'Minus',\r
+       decimalPoint: 'Komma',\r
+       divide: 'Divider',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Lighedstegn',\r
+       comma: 'Komma',\r
+       dash: 'Bindestreg',\r
+       period: 'Punktum',\r
+       forwardSlash: 'Skråstreg',\r
+       graveAccent: 'Accent grave',\r
+       openBracket: 'Start klamme',\r
+       backSlash: 'Omvendt skråstreg',\r
+       closeBracket: 'Slut klamme',\r
+       singleQuote: 'Enkelt citationstegn'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/de-ch.js b/sources/plugins/a11yhelp/dialogs/lang/de-ch.js
new file mode 100644 (file)
index 0000000..8d26d73
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'de-ch', {\r
+       title: 'Barrierefreiheitinformationen',\r
+       contents: 'Hilfeinhalt. Um den Dialog zu schliessen die Taste ESC drücken.',\r
+       legend: [\r
+               {\r
+               name: 'Allgemein',\r
+               items: [\r
+                       {\r
+                       name: 'Editorwerkzeugleiste',\r
+                       legend: 'Drücken Sie ${toolbarFocus} auf der Symbolleiste. Gehen Sie zur nächsten oder vorherigen Symbolleistengruppe mit TAB und SHIFT+TAB. Gehen Sie zur nächsten oder vorherigen Symbolleiste auf die Schaltfläche mit dem RECHTS- oder LINKS-Pfeil. Drücken Sie die Leertaste oder Eingabetaste, um die Schaltfläche in der Symbolleiste aktivieren.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editordialog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Kontextmenü',\r
+                       legend: 'Dürcken Sie ${contextMenu} oder die Anwendungstaste um das Kontextmenü zu öffnen. Man kann die Pfeiltasten zum Wechsel benutzen. Mit der Leertaste oder der Enter-Taste kann man den Menüpunkt aufrufen. Schliessen Sie das Kontextmenü mit der ESC-Taste.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Listenbox',\r
+                       legend: 'Innerhalb einer Listenbox kann man mit der TAB-Taste oder den Pfeilrunter-Taste den nächsten Menüeintrag wählen. Mit der SHIFT+TAB Tastenkombination oder der Pfeilhoch-Taste gelangt man zum vorherigen Menüpunkt. Mit der Leertaste oder Enter kann man den Menüpunkt auswählen. Drücken Sie ESC zum Verlassen des Menüs.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Elementpfadleiste',\r
+                       legend: 'Drücken Sie ${elementsPathFocus} um sich durch die Pfadleiste zu bewegen. Um zum nächsten Element zu gelangen drücken Sie TAB oder die Pfeilrechts-Taste. Zum vorherigen Element gelangen Sie mit der SHIFT+TAB oder der Pfeillinks-Taste. Drücken Sie die Leertaste oder Enter um das Element auszuwählen.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Befehle',\r
+               items: [\r
+                       {\r
+                       name: 'Rückgängig-Befehl',\r
+                       legend: 'Drücken Sie ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Wiederherstellen-Befehl',\r
+                       legend: 'Drücken Sie ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Fettschrift-Befehl',\r
+                       legend: 'Drücken Sie ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursiv-Befehl',\r
+                       legend: 'Drücken Sie ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Unterstreichen-Befehl',\r
+                       legend: 'Drücken Sie ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link-Befehl',\r
+                       legend: 'Drücken Sie ${link}'\r
+               },\r
+                       {\r
+                       name: 'Werkzeugleiste einklappen-Befehl',\r
+                       legend: 'Drücken Sie ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Zugang bisheriger Fokussierung Raumbefehl ',\r
+                       legend: 'Drücken Sie ${accessPreviousSpace}  auf den am nächsten nicht erreichbar Fokus-Abstand vor die Einfügemarke zugreifen: zwei benachbarte HR-Elemente. Wiederholen Sie die Tastenkombination um entfernte Fokusräume zu erreichen. '\r
+               },\r
+                       {\r
+                       name: 'Zugang nächster Schwerpunkt Raumbefehl ',\r
+                       legend: 'Drücken Sie $ { accessNextSpace }, um den nächsten unerreichbar Fokus Leerzeichen nach dem Cursor zum Beispiel auf: zwei benachbarten HR Elemente. Wiederholen Sie die Tastenkombination zum fernen Fokus Bereiche zu erreichen. '\r
+               },\r
+                       {\r
+                       name: 'Eingabehilfen',\r
+                       legend: 'Drücken Sie ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Feststell',\r
+       escape: 'Escape',\r
+       pageUp: 'Bild auf',\r
+       pageDown: 'Bild ab',\r
+       leftArrow: 'Linke Pfeiltaste',\r
+       upArrow: 'Obere Pfeiltaste',\r
+       rightArrow: 'Rechte Pfeiltaste',\r
+       downArrow: 'Untere Pfeiltaste',\r
+       insert: 'Einfügen',\r
+       leftWindowKey: 'Linke Windowstaste',\r
+       rightWindowKey: 'Rechte Windowstaste',\r
+       selectKey: 'Taste auswählen',\r
+       numpad0: 'Ziffernblock 0',\r
+       numpad1: 'Ziffernblock 1',\r
+       numpad2: 'Ziffernblock 2',\r
+       numpad3: 'Ziffernblock 3',\r
+       numpad4: 'Ziffernblock 4',\r
+       numpad5: 'Ziffernblock 5',\r
+       numpad6: 'Ziffernblock 6',\r
+       numpad7: 'Ziffernblock 7',\r
+       numpad8: 'Ziffernblock 8',\r
+       numpad9: 'Ziffernblock 9',\r
+       multiply: 'Multiplizieren',\r
+       add: 'Addieren',\r
+       subtract: 'Subtrahieren',\r
+       decimalPoint: 'Punkt',\r
+       divide: 'Dividieren',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Ziffernblock feststellen',\r
+       scrollLock: 'Rollen',\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Gleichheitszeichen',\r
+       comma: 'Komma',\r
+       dash: 'Bindestrich',\r
+       period: 'Punkt',\r
+       forwardSlash: 'Schrägstrich',\r
+       graveAccent: 'Gravis',\r
+       openBracket: 'Öffnende eckige Klammer',\r
+       backSlash: 'Rückwärtsgewandter Schrägstrich',\r
+       closeBracket: 'Schliessende eckige Klammer',\r
+       singleQuote: 'Einfaches Anführungszeichen'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/de.js b/sources/plugins/a11yhelp/dialogs/lang/de.js
new file mode 100644 (file)
index 0000000..c74be37
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'de', {\r
+       title: 'Barrierefreiheitinformationen',\r
+       contents: 'Hilfeinhalt. Um den Dialog zu schliessen die Taste ESC drücken.',\r
+       legend: [\r
+               {\r
+               name: 'Allgemein',\r
+               items: [\r
+                       {\r
+                       name: 'Editorwerkzeugleiste',\r
+                       legend: 'Drücken Sie ${toolbarFocus} auf der Symbolleiste. Gehen Sie zur nächsten oder vorherigen Symbolleistengruppe mit TAB und SHIFT+TAB. Gehen Sie zur nächsten oder vorherigen Symbolleiste auf die Schaltfläche mit dem RECHTS- oder LINKS-Pfeil. Drücken Sie die Leertaste oder Eingabetaste, um die Schaltfläche in der Symbolleiste aktivieren.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editordialog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Kontextmenü',\r
+                       legend: 'Dürcken Sie ${contextMenu} oder die Anwendungstaste um das Kontextmenü zu öffnen. Man kann die Pfeiltasten zum Wechsel benutzen. Mit der Leertaste oder der Enter-Taste kann man den Menüpunkt aufrufen. Schliessen Sie das Kontextmenü mit der ESC-Taste.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Listenbox',\r
+                       legend: 'Innerhalb einer Listenbox kann man mit der TAB-Taste oder den Pfeilrunter-Taste den nächsten Menüeintrag wählen. Mit der SHIFT+TAB Tastenkombination oder der Pfeilhoch-Taste gelangt man zum vorherigen Menüpunkt. Mit der Leertaste oder Enter kann man den Menüpunkt auswählen. Drücken Sie ESC zum Verlassen des Menüs.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor-Elementpfadleiste',\r
+                       legend: 'Drücken Sie ${elementsPathFocus} um sich durch die Pfadleiste zu bewegen. Um zum nächsten Element zu gelangen drücken Sie TAB oder die Pfeilrechts-Taste. Zum vorherigen Element gelangen Sie mit der SHIFT+TAB oder der Pfeillinks-Taste. Drücken Sie die Leertaste oder Enter um das Element auszuwählen.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Befehle',\r
+               items: [\r
+                       {\r
+                       name: 'Rückgängig-Befehl',\r
+                       legend: 'Drücken Sie ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Wiederherstellen-Befehl',\r
+                       legend: 'Drücken Sie ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Fettschrift-Befehl',\r
+                       legend: 'Drücken Sie ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursiv-Befehl',\r
+                       legend: 'Drücken Sie ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Unterstreichen-Befehl',\r
+                       legend: 'Drücken Sie ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link-Befehl',\r
+                       legend: 'Drücken Sie ${link}'\r
+               },\r
+                       {\r
+                       name: 'Werkzeugleiste einklappen-Befehl',\r
+                       legend: 'Drücken Sie ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Zugang bisheriger Fokussierung Raumbefehl ',\r
+                       legend: 'Drücken Sie ${accessPreviousSpace}  auf den am nächsten nicht erreichbar Fokus-Abstand vor die Einfügemarke zugreifen: zwei benachbarte HR-Elemente. Wiederholen Sie die Tastenkombination um entfernte Fokusräume zu erreichen. '\r
+               },\r
+                       {\r
+                       name: 'Zugang nächster Schwerpunkt Raumbefehl ',\r
+                       legend: 'Drücken Sie $ { accessNextSpace }, um den nächsten unerreichbar Fokus Leerzeichen nach dem Cursor zum Beispiel auf: zwei benachbarten HR Elemente. Wiederholen Sie die Tastenkombination zum fernen Fokus Bereiche zu erreichen. '\r
+               },\r
+                       {\r
+                       name: 'Eingabehilfen',\r
+                       legend: 'Drücken Sie ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Feststell',\r
+       escape: 'Escape',\r
+       pageUp: 'Bild auf',\r
+       pageDown: 'Bild ab',\r
+       leftArrow: 'Linke Pfeiltaste',\r
+       upArrow: 'Obere Pfeiltaste',\r
+       rightArrow: 'Rechte Pfeiltaste',\r
+       downArrow: 'Untere Pfeiltaste',\r
+       insert: 'Einfügen',\r
+       leftWindowKey: 'Linke Windowstaste',\r
+       rightWindowKey: 'Rechte Windowstaste',\r
+       selectKey: 'Taste auswählen',\r
+       numpad0: 'Ziffernblock 0',\r
+       numpad1: 'Ziffernblock 1',\r
+       numpad2: 'Ziffernblock 2',\r
+       numpad3: 'Ziffernblock 3',\r
+       numpad4: 'Ziffernblock 4',\r
+       numpad5: 'Ziffernblock 5',\r
+       numpad6: 'Ziffernblock 6',\r
+       numpad7: 'Ziffernblock 7',\r
+       numpad8: 'Ziffernblock 8',\r
+       numpad9: 'Ziffernblock 9',\r
+       multiply: 'Multiplizieren',\r
+       add: 'Addieren',\r
+       subtract: 'Subtrahieren',\r
+       decimalPoint: 'Punkt',\r
+       divide: 'Dividieren',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Ziffernblock feststellen',\r
+       scrollLock: 'Rollen',\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Gleichheitszeichen',\r
+       comma: 'Komma',\r
+       dash: 'Bindestrich',\r
+       period: 'Punkt',\r
+       forwardSlash: 'Schrägstrich',\r
+       graveAccent: 'Gravis',\r
+       openBracket: 'Öffnende eckige Klammer',\r
+       backSlash: 'Rückwärtsgewandter Schrägstrich',\r
+       closeBracket: 'Schließende eckige Klammer',\r
+       singleQuote: 'Einfaches Anführungszeichen'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/el.js b/sources/plugins/a11yhelp/dialogs/lang/el.js
new file mode 100644 (file)
index 0000000..11febeb
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'el', {\r
+       title: 'Οδηγίες Προσβασιμότητας',\r
+       contents: 'Περιεχόμενα Βοήθειας. Πατήστε ESC για κλείσιμο.',\r
+       legend: [\r
+               {\r
+               name: 'Γενικά',\r
+               items: [\r
+                       {\r
+                       name: 'Εργαλειοθήκη Επεξεργαστή',\r
+                       legend: 'Πατήστε ${toolbarFocus} για να περιηγηθείτε στην γραμμή εργαλείων. Μετακινηθείτε ανάμεσα στις ομάδες της γραμμής εργαλείων με TAB και SHIFT+TAB. Μετακινηθείτε ανάμεσα στα κουμπιά εργαλείων με το ΔΕΞΙ ή ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να ενεργοποιήσετε το ενεργό κουμπί εργαλείου.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Παράθυρο Διαλόγου Επεξεργαστή',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Αναδυόμενο Μενού Επεξεργαστή',\r
+                       legend: 'Πατήστε ${contextMenu} ή APPLICATION KEY για να ανοίξετε το αναδυόμενο μενού. Μετά μετακινηθείτε στην επόμενη επιλογή του μενού με  TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στην προηγούμενη επιλογή με SHIFT+TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξτε το τρέχων στοιχείο. Ανοίξτε το αναδυόμενο μενού της τρέχουσας επιλογής με ΔΙΑΣΤΗΜΑ ή ENTER ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μεταβείτε πίσω στο αρχικό στοιχείο μενού με το ESC ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Κλείστε το αναδυόμενο μενού με ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Κουτί Λίστας Επεξεργαστών',\r
+                       legend: 'Μέσα σε ένα κουτί λίστας, μετακινηθείτε στο επόμενο στοιχείο με TAB ή ΚΑΤΩ ΒΕΛΑΚΙ. Μετακινηθείτε στο προηγούμενο στοιχείο με SHIFT+TAB ή το ΠΑΝΩ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε ένα στοιχείο. Πατήστε ESC για να κλείσετε το κουτί της λίστας.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Μπάρα Διαδρομών Στοιχείων Επεξεργαστή',\r
+                       legend: 'Πατήστε ${elementsPathFocus} για να περιηγηθείτε στην μπάρα διαδρομών στοιχείων του επεξεργαστή. Μετακινηθείτε στο κουμπί του επόμενου στοιχείου με το TAB ή το ΔΕΞΙ ΒΕΛΑΚΙ. Μετακινηθείτε στο κουμπί του προηγούμενου στοιχείου με το SHIFT+TAB ή το ΑΡΙΣΤΕΡΟ ΒΕΛΑΚΙ. Πατήστε ΔΙΑΣΤΗΜΑ ή ENTER για να επιλέξετε το στοιχείο στον επεξεργαστή.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Εντολές',\r
+               items: [\r
+                       {\r
+                       name: 'Εντολή αναίρεσης',\r
+                       legend: 'Πατήστε ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή επανάληψης',\r
+                       legend: 'Πατήστε ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή έντονης γραφής',\r
+                       legend: 'Πατήστε ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή πλάγιας γραφής',\r
+                       legend: 'Πατήστε ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή υπογράμμισης',\r
+                       legend: 'Πατήστε ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή συνδέσμου',\r
+                       legend: 'Πατήστε ${link}'\r
+               },\r
+                       {\r
+                       name: 'Εντολή Σύμπτηξης Εργαλειοθήκης',\r
+                       legend: 'Πατήστε ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Πρόσβαση στην προηγούμενη εντολή του χώρου εστίασης ',\r
+                       legend: 'Πατήστε ${accessPreviousSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης πριν το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για να φθάσετε στους χώρους μακρινής εστίασης. '\r
+               },\r
+                       {\r
+                       name: 'Πρόσβαση στην επόμενη εντολή του χώρου εστίασης',\r
+                       legend: 'Πατήστε ${accessNextSpace} για να έχετε πρόσβαση στον πιο κοντινό χώρο εστίασης μετά το δρομέα, για παράδειγμα: δύο παρακείμενα στοιχεία ΥΕ. Επαναλάβετε το συνδυασμό πλήκτρων για τους χώρους μακρινής εστίασης. '\r
+               },\r
+                       {\r
+                       name: 'Βοήθεια Προσβασιμότητας',\r
+                       legend: 'Πατήστε ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Αριστερό Βέλος',\r
+       upArrow: 'Πάνω Βέλος',\r
+       rightArrow: 'Δεξί Βέλος',\r
+       downArrow: 'Κάτω Βέλος',\r
+       insert: 'Insert ',\r
+       leftWindowKey: 'Αριστερό Πλήκτρο Windows',\r
+       rightWindowKey: 'Δεξί Πλήκτρο Windows',\r
+       selectKey: 'Πλήκτρο Select',\r
+       numpad0: 'Αριθμητικό πληκτρολόγιο 0',\r
+       numpad1: 'Αριθμητικό Πληκτρολόγιο 1',\r
+       numpad2: 'Αριθμητικό πληκτρολόγιο 2',\r
+       numpad3: 'Αριθμητικό πληκτρολόγιο 3',\r
+       numpad4: 'Αριθμητικό πληκτρολόγιο 4',\r
+       numpad5: 'Αριθμητικό πληκτρολόγιο 5',\r
+       numpad6: 'Αριθμητικό πληκτρολόγιο 6',\r
+       numpad7: 'Αριθμητικό πληκτρολόγιο 7',\r
+       numpad8: 'Αριθμητικό πληκτρολόγιο 8',\r
+       numpad9: 'Αριθμητικό πληκτρολόγιο 9',\r
+       multiply: 'Πολλαπλασιασμός',\r
+       add: 'Πρόσθεση',\r
+       subtract: 'Αφαίρεση',\r
+       decimalPoint: 'Υποδιαστολή',\r
+       divide: 'Διαίρεση',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: '6',\r
+       f7: '7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Ερωτηματικό',\r
+       equalSign: 'Σύμβολο Ισότητας',\r
+       comma: 'Κόμμα',\r
+       dash: 'Παύλα',\r
+       period: 'Τελεία',\r
+       forwardSlash: 'Κάθετος',\r
+       graveAccent: 'Βαρεία',\r
+       openBracket: 'Άνοιγμα Παρένθεσης',\r
+       backSlash: 'Ανάστροφη Κάθετος',\r
+       closeBracket: 'Κλείσιμο Παρένθεσης',\r
+       singleQuote: 'Απόστροφος'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/en-gb.js b/sources/plugins/a11yhelp/dialogs/lang/en-gb.js
new file mode 100644 (file)
index 0000000..98bf636
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'en-gb', {\r
+       title: 'Accessibility Instructions',\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box',\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar',\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands',\r
+               items: [\r
+                       {\r
+                       name: ' Undo command',\r
+                       legend: 'Press ${undo}'\r
+               },\r
+                       {\r
+                       name: ' Redo command',\r
+                       legend: 'Press ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Bold command',\r
+                       legend: 'Press ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Italic command',\r
+                       legend: 'Press ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Underline command',\r
+                       legend: 'Press ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Link command',\r
+                       legend: 'Press ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command',\r
+                       legend: 'Press ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help',\r
+                       legend: 'Press ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Left Arrow',\r
+       upArrow: 'Up Arrow',\r
+       rightArrow: 'Right Arrow',\r
+       downArrow: 'Down Arrow',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Left Windows key',\r
+       rightWindowKey: 'Right Windows key',\r
+       selectKey: 'Select key',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Multiply',\r
+       add: 'Add',\r
+       subtract: 'Subtract',\r
+       decimalPoint: 'Decimal Point',\r
+       divide: 'Divide',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semicolon',\r
+       equalSign: 'Equal Sign',\r
+       comma: 'Comma',\r
+       dash: 'Dash',\r
+       period: 'Period',\r
+       forwardSlash: 'Forward Slash',\r
+       graveAccent: 'Grave Accent',\r
+       openBracket: 'Open Bracket',\r
+       backSlash: 'Backslash',\r
+       closeBracket: 'Close Bracket',\r
+       singleQuote: 'Single Quote'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/en.js b/sources/plugins/a11yhelp/dialogs/lang/en.js
new file mode 100644 (file)
index 0000000..fee0b4e
--- /dev/null
@@ -0,0 +1,159 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'en', {\r
+       title: 'Accessibility Instructions',\r
+       contents: 'Help Contents. To close this dialog press ESC.',\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. ' +\r
+                               'Move to the next and previous toolbar group with TAB and SHIFT+TAB. ' +\r
+                               'Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. ' +\r
+                               'Press SPACE or ENTER to activate the toolbar button.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. ' +\r
+                               'When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. ' +\r
+                               'With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. ' +\r
+                               'Then move to next menu option with TAB or DOWN ARROW. ' +\r
+                               'Move to previous option with SHIFT+TAB or UP ARROW. ' +\r
+                               'Press SPACE or ENTER to select the menu option. ' +\r
+                               'Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. ' +\r
+                               'Go back to parent menu item with ESC or LEFT ARROW. ' +\r
+                               'Close context menu with ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box',\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. ' +\r
+                               'Move to previous list item with SHIFT+TAB or UP ARROW. ' +\r
+                               'Press SPACE or ENTER to select the list option. ' +\r
+                               'Press ESC to close the list-box.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar',\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. ' +\r
+                               'Move to next element button with TAB or RIGHT ARROW. ' +\r
+                               'Move to previous button with SHIFT+TAB or LEFT ARROW. ' +\r
+                               'Press SPACE or ENTER to select the element in editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands',\r
+               items: [\r
+                       {\r
+                       name: ' Undo command',\r
+                       legend: 'Press ${undo}'\r
+               },\r
+                       {\r
+                       name: ' Redo command',\r
+                       legend: 'Press ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Bold command',\r
+                       legend: 'Press ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Italic command',\r
+                       legend: 'Press ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Underline command',\r
+                       legend: 'Press ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Link command',\r
+                       legend: 'Press ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command',\r
+                       legend: 'Press ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command',\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, ' +\r
+                               'for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.'\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command',\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, ' +\r
+                               'for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.'\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help',\r
+                       legend: 'Press ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Left Arrow',\r
+       upArrow: 'Up Arrow',\r
+       rightArrow: 'Right Arrow',\r
+       downArrow: 'Down Arrow',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Left Windows key',\r
+       rightWindowKey: 'Right Windows key',\r
+       selectKey: 'Select key',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Multiply',\r
+       add: 'Add',\r
+       subtract: 'Subtract',\r
+       decimalPoint: 'Decimal Point',\r
+       divide: 'Divide',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semicolon',\r
+       equalSign: 'Equal Sign',\r
+       comma: 'Comma',\r
+       dash: 'Dash',\r
+       period: 'Period',\r
+       forwardSlash: 'Forward Slash',\r
+       graveAccent: 'Grave Accent',\r
+       openBracket: 'Open Bracket',\r
+       backSlash: 'Backslash',\r
+       closeBracket: 'Close Bracket',\r
+       singleQuote: 'Single Quote'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/eo.js b/sources/plugins/a11yhelp/dialogs/lang/eo.js
new file mode 100644 (file)
index 0000000..c2bc106
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'eo', {\r
+       title: 'Uzindikoj pri atingeblo',\r
+       contents: 'Helpilenhavo. Por fermi tiun dialogon, premu la ESKAPAN klavon.',\r
+       legend: [\r
+               {\r
+               name: 'Ĝeneralaĵoj',\r
+               items: [\r
+                       {\r
+                       name: 'Ilbreto de la redaktilo',\r
+                       legend: 'Premu ${toolbarFocus} por atingi la ilbreton. Moviĝu al la sekva aŭ antaŭa grupoj de la ilbreto per la klavoj TABA kaj MAJUSKLIGA+TABA. Moviĝu al la sekva aŭ antaŭa butonoj de la ilbreto per la klavoj SAGO DEKSTREN kaj SAGO MALDEKSTREN. Premu la SPACETklavon aŭ la ENENklavon por aktivigi la ilbretbutonon.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktildialogo',\r
+                       legend:\r
+                               'En dialogo, premu la TABAN klavon por navigi al la sekva dialogelemento, premu la MAJUSKLIGAN+TABAN klavon por iri al la antaŭa dialogelemento, premu la ENEN klavon por sendi la dialogon, premu la ESKAPAN klavon por nuligi la dialogon. Kiam dialogo havas multajn langetojn, eblas atingi la langetliston aŭ per ALT+F10 aŭ per la TABA klavo kiel parton de la dialoga taba ordo. En langetlisto, moviĝu al la sekva kaj antaŭa langeto per la klavoj SAGO DEKSTREN KAJ MALDEKSTREN respektive.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Kunteksta menuo de la redaktilo',\r
+                       legend: 'Premu ${contextMenu} aŭ entajpu la KLAVKOMBINAĴON por malfermi la kuntekstan menuon. Poste moviĝu al la sekva opcio de la menuo per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa opcio per la klavoj MAJUSKLGA + TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la menuopcion. Malfermu la submenuon de la kuranta opcio per la SPACETklavo aŭ la ENENklavo aŭ la SAGO DEKSTREN. Revenu al la elemento de la patra menuo per la klavoj ESKAPA aŭ SAGO MALDEKSTREN. Fermu la kuntekstan menuon per la ESKAPA klavo.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Fallisto de la redaktilo',\r
+                       legend: 'En fallisto, moviĝu al la sekva listelemento per la klavoj TABA aŭ SAGO SUBEN. Moviĝu al la antaŭa listelemento per la klavoj MAJUSKLIGA+TABA aŭ SAGO SUPREN. Premu la SPACETklavon aŭ ENENklavon por selekti la opcion en la listo. Premu la ESKAPAN klavon por fermi la falmenuon.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Breto indikanta la vojon al la redaktilelementoj',\r
+                       legend: 'Premu ${elementsPathFocus} por navigi al la breto indikanta la vojon al la redaktilelementoj. Moviĝu al la butono de la sekva elemento per la klavoj TABA aŭ SAGO DEKSTREN. Moviĝu al la butono de la antaŭa elemento per la klavoj MAJUSKLIGA+TABA aŭ SAGO MALDEKSTREN. Premu la SPACETklavon aŭ ENENklavon por selekti la elementon en la redaktilo.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komandoj',\r
+               items: [\r
+                       {\r
+                       name: 'Komando malfari',\r
+                       legend: 'Premu ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Komando refari',\r
+                       legend: 'Premu ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Komando grasa',\r
+                       legend: 'Premu ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Komando kursiva',\r
+                       legend: 'Premu ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Komando substreki',\r
+                       legend: 'Premu ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Komando ligilo',\r
+                       legend: 'Premu ${link}'\r
+               },\r
+                       {\r
+                       name: 'Komando faldi la ilbreton',\r
+                       legend: 'Premu ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Komando por atingi la antaŭan fokusan spacon',\r
+                       legend: 'Press ${accessPreviousSpace} por atingi la plej proksiman neatingeblan fokusan spacon antaŭ la kursoro, ekzemple : du kuntuŝiĝajn HR elementojn. Ripetu la klavkombinaĵon por atingi malproksimajn fokusajn spacojn.'\r
+               },\r
+                       {\r
+                       name: 'Komando por atingi la sekvan fokusan spacon',\r
+                       legend: 'Press ${accessNextSpace} por atingi la plej proksiman neatingeblan fokusan spacon post la kursoro, ekzemple : du kuntuŝiĝajn HR elementojn. Ripetu la klavkombinajôn por atingi malproksimajn fokusajn spacojn'\r
+               },\r
+                       {\r
+                       name: 'Helpilo pri atingeblo',\r
+                       legend: 'Premu ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabo',\r
+       pause: 'Paŭzo',\r
+       capslock: 'Majuskla baskulo',\r
+       escape: 'Eskapa klavo',\r
+       pageUp: 'Antaŭa Paĝo',\r
+       pageDown: 'Sekva Paĝo',\r
+       leftArrow: 'Sago Maldekstren',\r
+       upArrow: 'Sago Supren',\r
+       rightArrow: 'Sago Dekstren',\r
+       downArrow: 'Sago Suben',\r
+       insert: 'Enmeti',\r
+       leftWindowKey: 'Maldekstra Windows-klavo',\r
+       rightWindowKey: 'Dekstra Windows-klavo',\r
+       selectKey: 'Selektklavo',\r
+       numpad0: 'Nombra Klavaro 0',\r
+       numpad1: 'Nombra Klavaro 1',\r
+       numpad2: 'Nombra Klavaro 2',\r
+       numpad3: 'Nombra Klavaro 3',\r
+       numpad4: 'Nombra Klavaro 4',\r
+       numpad5: 'Nombra Klavaro 5',\r
+       numpad6: 'Nombra Klavaro 6',\r
+       numpad7: 'Nombra Klavaro 7',\r
+       numpad8: 'Nombra Klavaro 8',\r
+       numpad9: 'Nombra Klavaro 9',\r
+       multiply: 'Obligi',\r
+       add: 'Almeti',\r
+       subtract: 'Subtrahi',\r
+       decimalPoint: 'Dekuma Punkto',\r
+       divide: 'Dividi',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Nombra Baskulo',\r
+       scrollLock: 'Ruluma Baskulo',\r
+       semiColon: 'Punktokomo',\r
+       equalSign: 'Egalsigno',\r
+       comma: 'Komo',\r
+       dash: 'Haltostreko',\r
+       period: 'Punkto',\r
+       forwardSlash: 'Oblikvo',\r
+       graveAccent: 'Malakuto',\r
+       openBracket: 'Malferma Krampo',\r
+       backSlash: 'Retroklino',\r
+       closeBracket: 'Ferma Krampo',\r
+       singleQuote: 'Citilo'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/es.js b/sources/plugins/a11yhelp/dialogs/lang/es.js
new file mode 100644 (file)
index 0000000..b1eaa20
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'es', {\r
+       title: 'Instrucciones de accesibilidad',\r
+       contents: 'Ayuda. Para cerrar presione ESC.',\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Barra de herramientas del editor',\r
+                       legend: 'Presiona ${toolbarFocus} para navegar por la barra de herramientas. Para moverse por los distintos grupos de herramientas usa las teclas TAB y MAY+TAB. Para moverse por las distintas herramientas usa FLECHA DERECHA o FECHA IZQUIERDA. Presiona "espacio" o "intro" para activar la herramienta.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de diálogo',\r
+                       legend:\r
+                               'Dentro del diálogo, presione TAB para navegar a los siguientes elementos de diálogo, presione SHIFT+TAB para moverse a los anteriores elementos de diálogo, presione ENTER para enviar el diálogo, presiona ESC para cancelar el diálogo. Cuando el diálogo tiene multiples pestañas, la lista de pestañas puede ser abarcada con ALT + F10 or con TAB como parte del orden de pestañas del diálogo. ECon la pestaña enfocada, puede moverse a la siguiente o anterior pestaña con las FLECHAS IZQUIRDA y DERECHA respectivamente.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor del menú contextual',\r
+                       legend: 'Presiona ${contextMenu} o TECLA MENÚ para abrir el menú contextual. Entonces muévete a la siguiente opción del menú con TAB o FLECHA ABAJO. Muévete a la opción previa con SHIFT + TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para seleccionar la opción del menú. Abre el submenú de la opción actual con ESPACIO o ENTER o FLECHA DERECHA. Regresa al elemento padre del menú con ESC o FLECHA IZQUIERDA. Cierra el menú contextual con ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Lista del Editor',\r
+                       legend: 'Dentro de una lista, te mueves al siguiente elemento de la lista con TAB o FLECHA ABAJO. Te mueves al elemento previo de la lista con SHIFT+TAB o FLECHA ARRIBA. Presiona ESPACIO o ENTER para elegir la opción de la lista. Presiona ESC para cerrar la lista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barra de Ruta del Elemento en el Editor',\r
+                       legend: 'Presiona ${elementsPathFocus} para navegar a los elementos de la barra de ruta. Te mueves al siguiente elemento botón con TAB o FLECHA DERECHA. Te mueves al botón previo con SHIFT+TAB o FLECHA IZQUIERDA. Presiona ESPACIO o ENTER para seleccionar el elemento en el editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comandos',\r
+               items: [\r
+                       {\r
+                       name: 'Comando deshacer',\r
+                       legend: 'Presiona ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Comando rehacer',\r
+                       legend: 'Presiona ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Comando negrita',\r
+                       legend: 'Presiona ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Comando itálica',\r
+                       legend: 'Presiona ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Comando subrayar',\r
+                       legend: 'Presiona ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Comando liga',\r
+                       legend: 'Presiona ${liga}'\r
+               },\r
+                       {\r
+                       name: 'Comando colapsar barra de herramientas',\r
+                       legend: 'Presiona ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Comando accesar el anterior espacio de foco',\r
+                       legend: 'Presiona ${accessPreviousSpace} para accesar el espacio de foco no disponible más cercano anterior al cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes.'\r
+               },\r
+                       {\r
+                       name: 'Comando accesar el siguiente spacio de foco',\r
+                       legend: 'Presiona ${accessNextSpace} para accesar el espacio de foco no disponible más cercano después del cursor, por ejemplo: dos elementos HR adyacentes. Repite la combinación de teclas para alcanzar espacios de foco distantes.'\r
+               },\r
+                       {\r
+                       name: 'Ayuda de Accesibilidad',\r
+                       legend: 'Presiona ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulador',\r
+       pause: 'Pausa',\r
+       capslock: 'Bloq. Mayús.',\r
+       escape: 'Escape',\r
+       pageUp: 'Regresar Página',\r
+       pageDown: 'Avanzar Página',\r
+       leftArrow: 'Flecha Izquierda',\r
+       upArrow: 'Flecha Arriba',\r
+       rightArrow: 'Flecha Derecha',\r
+       downArrow: 'Flecha Abajo',\r
+       insert: 'Insertar',\r
+       leftWindowKey: 'Tecla Windows Izquierda',\r
+       rightWindowKey: 'Tecla Windows Derecha',\r
+       selectKey: 'Tecla de Selección',\r
+       numpad0: 'Tecla 0 del teclado numérico',\r
+       numpad1: 'Tecla 1 del teclado numérico',\r
+       numpad2: 'Tecla 2 del teclado numérico',\r
+       numpad3: 'Tecla 3 del teclado numérico',\r
+       numpad4: 'Tecla 4 del teclado numérico',\r
+       numpad5: 'Tecla 5 del teclado numérico',\r
+       numpad6: 'Tecla 6 del teclado numérico',\r
+       numpad7: 'Tecla 7 del teclado numérico',\r
+       numpad8: 'Tecla 8 del teclado numérico',\r
+       numpad9: 'Tecla 9 del teclado numérico',\r
+       multiply: 'Multiplicar',\r
+       add: 'Sumar',\r
+       subtract: 'Restar',\r
+       decimalPoint: 'Punto Decimal',\r
+       divide: 'Dividir',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Punto y coma',\r
+       equalSign: 'Signo de Igual',\r
+       comma: 'Coma',\r
+       dash: 'Guión',\r
+       period: 'Punto',\r
+       forwardSlash: 'Diagonal',\r
+       graveAccent: 'Acento Grave',\r
+       openBracket: 'Abrir llave',\r
+       backSlash: 'Diagonal Invertida',\r
+       closeBracket: 'Cerrar llave',\r
+       singleQuote: 'Comillas simples'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/et.js b/sources/plugins/a11yhelp/dialogs/lang/et.js
new file mode 100644 (file)
index 0000000..0146089
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'et', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Abi sisu. Selle dialoogi sulgemiseks vajuta ESC klahvi.',\r
+       legend: [\r
+               {\r
+               name: 'Üldine',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/eu.js b/sources/plugins/a11yhelp/dialogs/lang/eu.js
new file mode 100644 (file)
index 0000000..b53748f
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'eu', {\r
+       title: 'Erabilerraztasunaren argibideak',\r
+       contents: 'Laguntzaren edukiak. Elkarrizketa-koadro hau ixteko sakatu ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Orokorra',\r
+               items: [\r
+                       {\r
+                       name: 'Editorearen tresna-barra',\r
+                       legend: 'Sakatu ${toolbarFocus} tresna-barrara nabigatzeko. Tresna-barrako aurreko eta hurrengo taldera joateko erabili TAB eta MAIUS+TAB. Tresna-barrako aurreko eta hurrengo botoira joateko erabili ESKUIN-GEZIA eta EZKER-GEZIA. Sakatu ZURIUNEA edo SARTU tresna-barrako botoia aktibatzeko.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorearen elkarrizketa-koadroa',\r
+                       legend:\r
+                               'Elkarrizketa-koadro baten barruan sakatu TAB hurrengo elementura nabigatzeko, sakatu MAIUS+TAB aurreko elementura joateko, sakatu SARTU elkarrizketa-koadroa bidaltzeko eta sakatu ESC uzteko. Elkarrizketa-koadro batek hainbat fitxa dituenean, ALT+F10 erabiliz irits daiteke fitxen zerrendara, edo TAB erabiliz. Fokoa fitxen zerrendak duenean, aurreko eta hurrengo fitxetara joateko erabili EZKER-GEZIA eta ESKUIN-GEZIA.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorearen testuinguru-menua',\r
+                       legend: 'Sakatu ${contextMenu} edo APLIKAZIO TEKLA testuinguru-menua irekitzeko. Menuko hurrengo aukerara joateko erabili TAB edo BEHERA GEZIA. Aurreko aukerara nabigatzeko erabili MAIUS+TAB edo GORA GEZIA. Sakatu ZURIUNEA edo SARTU menuko aukera hautatzeko. Ireki uneko aukeraren azpi-menua ZURIUNEA edo SARTU edo ESKUIN-GEZIA erabiliz. Menuko aukera gurasora itzultzeko erabili ESC edo EZKER-GEZIA. Testuinguru-menua ixteko sakatu ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorearen zerrenda-koadroa',\r
+                       legend: 'Zerrenda-koadro baten barruan, zerrendako hurrengo elementura joateko erabili TAB edo BEHERA GEZIA. Zerrendako aurreko elementura nabigatzeko MAIUS+TAB edo GORA GEZIA. Sakatu ZURIUNEA edo SARTU zerrendako aukera hautatzeko. Sakatu ESC zerrenda-koadroa ixteko.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorearen elementuaren bide-barra',\r
+                       legend: 'Sakatu ${elementsPathFocus} elementuaren bide-barrara nabigatzeko. Hurrengo elementuaren botoira joateko erabili TAB edo ESKUIN-GEZIA. Aurreko botoira joateko aldiz erabili MAIUS+TAB edo EZKER-GEZIA. Elementua editorean hautatzeko sakatu ZURIUNEA edo SARTU.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komandoak',\r
+               items: [\r
+                       {\r
+                       name: 'Desegin komandoa',\r
+                       legend: 'Sakatu ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Berregin komandoa',\r
+                       legend: 'Sakatu ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Lodia komandoa',\r
+                       legend: 'Sakatu ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Etzana komandoa',\r
+                       legend: 'Sakatu ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Azpimarratu komandoa',\r
+                       legend: 'Sakatu ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Esteka komandoa',\r
+                       legend: 'Sakatu ${link}'\r
+               },\r
+                       {\r
+                       name: 'Tolestu tresna-barra komandoa',\r
+                       legend: 'Sakatu ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: 'Erabilerraztasunaren laguntza',\r
+                       legend: 'Sakatu ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabuladorea',\r
+       pause: 'Pausatu',\r
+       capslock: 'Blok Maius',\r
+       escape: 'Ihes',\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Ezker-gezia',\r
+       upArrow: 'Gora gezia',\r
+       rightArrow: 'Eskuin-gezia',\r
+       downArrow: 'Behera gezia',\r
+       insert: 'Txertatu',\r
+       leftWindowKey: 'Ezkerreko Windows tekla',\r
+       rightWindowKey: 'Eskuineko Windows tekla',\r
+       selectKey: 'Hautatu tekla',\r
+       numpad0: 'Zenbakizko teklatua 0',\r
+       numpad1: 'Zenbakizko teklatua 1',\r
+       numpad2: 'Zenbakizko teklatua 2',\r
+       numpad3: 'Zenbakizko teklatua 3',\r
+       numpad4: 'Zenbakizko teklatua 4',\r
+       numpad5: 'Zenbakizko teklatua 5',\r
+       numpad6: 'Zenbakizko teklatua 6',\r
+       numpad7: 'Zenbakizko teklatua 7',\r
+       numpad8: 'Zenbakizko teklatua 8',\r
+       numpad9: 'Zenbakizko teklatua 9',\r
+       multiply: 'Biderkatu',\r
+       add: 'Gehitu',\r
+       subtract: 'Kendu',\r
+       decimalPoint: 'Koma hamartarra',\r
+       divide: 'Zatitu',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Blok Zenb',\r
+       scrollLock: 'Blok Korr',\r
+       semiColon: 'Puntu eta koma',\r
+       equalSign: 'Berdin zeinua',\r
+       comma: 'Koma',\r
+       dash: 'Marratxoa',\r
+       period: 'Puntua',\r
+       forwardSlash: 'Barra',\r
+       graveAccent: 'Azentu kamutsa',\r
+       openBracket: 'Parentesia ireki',\r
+       backSlash: 'Alderantzizko barra',\r
+       closeBracket: 'Itxi parentesia',\r
+       singleQuote: 'Komatxo bakuna'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/fa.js b/sources/plugins/a11yhelp/dialogs/lang/fa.js
new file mode 100644 (file)
index 0000000..88072f0
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'fa', {\r
+       title: 'دستورالعمل‌های دسترسی',\r
+       contents: 'راهنمای فهرست مطالب. برای بستن این کادر محاوره‌ای ESC را فشار دهید.',\r
+       legend: [\r
+               {\r
+               name: 'عمومی',\r
+               items: [\r
+                       {\r
+                       name: 'نوار ابزار ویرایشگر',\r
+                       legend: '${toolbarFocus} را برای باز کردن نوار ابزار بفشارید. با کلید Tab و Shift+Tab در مجموعه نوار ابزار بعدی و قبلی حرکت کنید. برای حرکت در کلید نوار ابزار قبلی و بعدی با کلید جهت‌نمای راست و چپ جابجا شوید. کلید Space یا Enter را برای فعال کردن کلید نوار ابزار بفشارید.'\r
+               },\r
+\r
+                       {\r
+                       name: 'پنجره محاورهای ویرایشگر',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'منوی متنی ویرایشگر',\r
+                       legend: '${contextMenu} یا کلید برنامههای کاربردی را برای باز کردن منوی متن را بفشارید. سپس میتوانید برای حرکت به گزینه بعدی منو با کلید Tab و یا کلید جهتنمای پایین جابجا شوید. حرکت به گزینه قبلی با Shift+Tab یا کلید جهتنمای بالا. فشردن Space یا Enter برای انتخاب یک گزینه از منو. باز کردن زیر شاخه گزینه منو جاری با کلید Space یا Enter و یا کلید جهتنمای راست و چپ. بازگشت به منوی والد با کلید Esc یا کلید جهتنمای چپ. بستن منوی متن با Esc.'\r
+               },\r
+\r
+                       {\r
+                       name: 'جعبه فهرست ویرایشگر',\r
+                       legend: 'در داخل جعبه لیست، قلم دوم از اقلام لیست بعدی را با TAB و یا Arrow Down حرکت دهید. انتقال به قلم دوم از اقلام لیست قبلی را با SHIFT + TAB یا UP ARROW. کلید Space یا ENTER را برای انتخاب گزینه لیست بفشارید. کلید ESC را برای بستن جعبه لیست بفشارید.'\r
+               },\r
+\r
+                       {\r
+                       name: 'ویرایشگر عنصر نوار راه',\r
+                       legend: 'برای رفتن به مسیر عناصر ${elementsPathFocus} را بفشارید. حرکت به کلید عنصر بعدی با کلید Tab یا کلید جهت‌نمای راست. برگشت به کلید قبلی با Shift+Tab یا کلید جهت‌نمای چپ. فشردن Space یا Enter برای انتخاب یک عنصر در ویرایشگر.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'فرمان‌ها',\r
+               items: [\r
+                       {\r
+                       name: 'بازگشت به آخرین فرمان',\r
+                       legend: 'فشردن ${undo}'\r
+               },\r
+                       {\r
+                       name: 'انجام مجدد فرمان',\r
+                       legend: 'فشردن ${redo}'\r
+               },\r
+                       {\r
+                       name: 'فرمان درشت کردن متن',\r
+                       legend: 'فشردن ${bold}'\r
+               },\r
+                       {\r
+                       name: 'فرمان کج کردن متن',\r
+                       legend: 'فشردن ${italic}'\r
+               },\r
+                       {\r
+                       name: 'فرمان زیرخطدار کردن متن',\r
+                       legend: 'فشردن ${underline}'\r
+               },\r
+                       {\r
+                       name: 'فرمان پیوند دادن',\r
+                       legend: 'فشردن ${link}'\r
+               },\r
+                       {\r
+                       name: 'بستن نوار ابزار فرمان',\r
+                       legend: 'فشردن ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'دسترسی به فرمان محل تمرکز قبلی',\r
+                       legend: 'فشردن ${accessPreviousSpace} برای دسترسی به نزدیک‌ترین فضای قابل دسترسی تمرکز قبل از هشتک، برای مثال: دو عنصر مجاور HR -خط افقی-. تکرار کلید ترکیبی برای رسیدن به فضاهای تمرکز از راه دور.'\r
+               },\r
+                       {\r
+                       name: 'دسترسی به فضای دستور بعدی',\r
+                       legend: 'برای دسترسی به نزدیک‌ترین فضای تمرکز غیر قابل دسترس، ${accessNextSpace} را پس از علامت هشتک بفشارید، برای مثال:  دو عنصر مجاور HR -خط افقی-. کلید ترکیبی را برای رسیدن به فضای تمرکز تکرار کنید.'\r
+               },\r
+                       {\r
+                       name: 'راهنمای دسترسی',\r
+                       legend: 'فشردن ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'برگه',\r
+       pause: 'توقف',\r
+       capslock: 'Caps Lock',\r
+       escape: 'گریز',\r
+       pageUp: 'صفحه به بالا',\r
+       pageDown: 'صفحه به پایین',\r
+       leftArrow: 'پیکان چپ',\r
+       upArrow: 'پیکان بالا',\r
+       rightArrow: 'پیکان راست',\r
+       downArrow: 'پیکان پایین',\r
+       insert: 'ورود',\r
+       leftWindowKey: 'کلید چپ ویندوز',\r
+       rightWindowKey: 'کلید راست ویندوز',\r
+       selectKey: 'انتخاب کلید',\r
+       numpad0: 'کلید شماره 0',\r
+       numpad1: 'کلید شماره 1',\r
+       numpad2: 'کلید شماره 2',\r
+       numpad3: 'کلید شماره 3',\r
+       numpad4: 'کلید شماره 4',\r
+       numpad5: 'کلید شماره 5',\r
+       numpad6: 'کلید شماره 6',\r
+       numpad7: 'کلید شماره 7',\r
+       numpad8: 'کلید شماره 8',\r
+       numpad9: 'کلید شماره 9',\r
+       multiply: 'ضرب',\r
+       add: 'افزودن',\r
+       subtract: 'تفریق',\r
+       decimalPoint: 'نقطه‌ی اعشار',\r
+       divide: 'جدا کردن',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semicolon',\r
+       equalSign: 'علامت تساوی',\r
+       comma: 'کاما',\r
+       dash: 'خط تیره',\r
+       period: 'دوره',\r
+       forwardSlash: 'Forward Slash',\r
+       graveAccent: 'Grave Accent',\r
+       openBracket: 'Open Bracket',\r
+       backSlash: 'Backslash',\r
+       closeBracket: 'Close Bracket',\r
+       singleQuote: 'Single Quote'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/fi.js b/sources/plugins/a11yhelp/dialogs/lang/fi.js
new file mode 100644 (file)
index 0000000..093d409
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'fi', {\r
+       title: 'Saavutettavuus ohjeet',\r
+       contents: 'Ohjeen sisällöt. Sulkeaksesi tämän dialogin paina ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Yleinen',\r
+               items: [\r
+                       {\r
+                       name: 'Editorin työkalupalkki',\r
+                       legend: 'Paina ${toolbarFocus} siirtyäksesi työkalupalkkiin. Siirry seuraavaan ja edelliseen työkalupalkin ryhmään TAB ja SHIFT+TAB näppäimillä. Siirry seuraavaan ja edelliseen työkalupainikkeeseen käyttämällä NUOLI OIKEALLE tai NUOLI VASEMMALLE näppäimillä. Paina VÄLILYÖNTI tai ENTER näppäintä aktivoidaksesi työkalupainikkeen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorin dialogi',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorin oheisvalikko',\r
+                       legend: 'Paina ${contextMenu} tai SOVELLUSPAINIKETTA avataksesi oheisvalikon. Liiku seuraavaan valikon vaihtoehtoon TAB tai NUOLI ALAS näppäimillä. Siirry edelliseen vaihtoehtoon SHIFT+TAB tai NUOLI YLÖS näppäimillä. Paina VÄLILYÖNTI tai ENTER valitaksesi valikon kohdan. Avataksesi nykyisen kohdan alivalikon paina VÄLILYÖNTI tai ENTER tai NUOLI OIKEALLE painiketta. Siirtyäksesi takaisin valikon ylemmälle tasolle paina ESC tai NUOLI vasemmalle. Oheisvalikko suljetaan ESC painikkeella.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorin listalaatikko',\r
+                       legend: 'Listalaatikon sisällä siirry seuraavaan listan kohtaan TAB tai NUOLI ALAS painikkeilla. Siirry edelliseen listan kohtaan SHIFT+TAB tai NUOLI YLÖS painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi listan vaihtoehdon. Paina ESC sulkeaksesi listalaatikon.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorin elementtipolun palkki',\r
+                       legend: 'Paina ${elementsPathFocus} siirtyäksesi elementtipolun palkkiin. Siirry seuraavaan elementtipainikkeeseen TAB tai NUOLI OIKEALLE painikkeilla. Siirry aiempaan painikkeeseen SHIFT+TAB tai NUOLI VASEMMALLE painikkeilla. Paina VÄLILYÖNTI tai ENTER valitaksesi elementin editorissa.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komennot',\r
+               items: [\r
+                       {\r
+                       name: 'Peruuta komento',\r
+                       legend: 'Paina ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Tee uudelleen komento',\r
+                       legend: 'Paina ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Lihavoi komento',\r
+                       legend: 'Paina ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursivoi komento',\r
+                       legend: 'Paina ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Alleviivaa komento',\r
+                       legend: 'Paina ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Linkki komento',\r
+                       legend: 'Paina ${link}'\r
+               },\r
+                       {\r
+                       name: 'Pienennä työkalupalkki komento',\r
+                       legend: 'Paina ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Siirry aiempaan fokustilaan komento',\r
+                       legend: 'Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin edellä olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin.'\r
+               },\r
+                       {\r
+                       name: 'Siirry seuraavaan fokustilaan komento',\r
+                       legend: 'Paina ${accessPreviousSpace} siiryäksesi lähimpään kursorin jälkeen olevaan saavuttamattomaan fokustilaan, esimerkiksi: kaksi vierekkäistä HR elementtiä. Toista näppäinyhdistelmää päästäksesi kauempana oleviin fokustiloihin.'\r
+               },\r
+                       {\r
+                       name: 'Saavutettavuus ohjeet',\r
+                       legend: 'Paina ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numeronäppäimistö 0',\r
+       numpad1: 'Numeronäppäimistö 1',\r
+       numpad2: 'Numeronäppäimistö 2',\r
+       numpad3: 'Numeronäppäimistö 3',\r
+       numpad4: 'Numeronäppäimistö 4',\r
+       numpad5: 'Numeronäppäimistö 5',\r
+       numpad6: 'Numeronäppäimistö 6',\r
+       numpad7: 'Numeronäppäimistö 7',\r
+       numpad8: 'Numeronäppäimistö 8',\r
+       numpad9: 'Numeronäppäimistö 9',\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Puolipiste',\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Pilkku',\r
+       dash: 'Dash', // MISSING\r
+       period: 'Piste',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/fo.js b/sources/plugins/a11yhelp/dialogs/lang/fo.js
new file mode 100644 (file)
index 0000000..efce724
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'fo', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'General', // MISSING\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Falda',\r
+       add: 'Pluss',\r
+       subtract: 'Frádráttar',\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Býta',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Javnatekn',\r
+       comma: 'Komma',\r
+       dash: 'Dash', // MISSING\r
+       period: 'Punktum',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/fr-ca.js b/sources/plugins/a11yhelp/dialogs/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..c87c586
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'fr-ca', {\r
+       title: 'Instructions d\'accessibilité',\r
+       contents: 'Contenu de l\'aide.  Pour fermer cette fenêtre, appuyez sur ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Général',\r
+               items: [\r
+                       {\r
+                       name: 'Barre d\'outil de l\'éditeur',\r
+                       legend: 'Appuyer sur ${toolbarFocus} pour accéder à la barre d\'outils. Se déplacer vers les groupes suivant ou précédent de la barre d\'outil avec les touches TAB et SHIFT+TAB. Se déplacer vers les boutons suivant ou précédent de la barre d\'outils avec les touches FLECHE DROITE et FLECHE GAUCHE. Appuyer sur la barre d\'espace ou la touche ENTRER pour activer le bouton de barre d\'outils.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialogue de l\'éditeur',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu contextuel de l\'éditeur',\r
+                       legend: 'Appuyer sur ${contextMenu} ou entrer le RACCOURCI CLAVIER pour ouvrir le menu contextuel. Puis se déplacer vers l\'option suivante du menu avec les touches TAB ou FLECHE BAS. Se déplacer vers l\'option précédente avec les touches SHIFT+TAB ou FLECHE HAUT. appuyer sur la BARRE D\'ESPACE ou la touche ENTREE pour sélectionner l\'option du menu. Oovrir le sous-menu de l\'option courante avec la BARRE D\'ESPACE ou les touches ENTREE ou FLECHE DROITE. Revenir à l\'élément de menu parent avec les touches ESC ou FLECHE GAUCHE. Fermer le menu contextuel avec ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu déroulant de l\'éditeur',\r
+                       legend: 'A l\'intérieur d\'une liste en menu déroulant, se déplacer vers l\'élément suivant de la liste avec les touches TAB ou FLECHE BAS. Se déplacer vers l\'élément précédent de la liste avec les touches SHIFT+TAB ou FLECHE HAUT. Appuyer sur la BARRE D\'ESPACE ou sur ENTREE pour sélectionner l\'option dans la liste. Appuyer sur ESC pour fermer le menu déroulant.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barre d\'emplacement des éléments de l\'éditeur',\r
+                       legend: 'Appuyer sur ${elementsPathFocus} pour naviguer vers la barre d\'emplacement des éléments de léditeur. Se déplacer vers le bouton d\'élément suivant avec les touches TAB ou FLECHE DROITE. Se déplacer vers le bouton d\'élément précédent avec les touches SHIFT+TAB ou FLECHE GAUCHE. Appuyer sur la BARRE D\'ESPACE ou sur ENTREE pour sélectionner l\'élément dans l\'éditeur.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commandes',\r
+               items: [\r
+                       {\r
+                       name: 'Annuler',\r
+                       legend: 'Appuyer sur ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Refaire',\r
+                       legend: 'Appuyer sur ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Gras',\r
+                       legend: 'Appuyer sur ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Italique',\r
+                       legend: 'Appuyer sur ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Souligné',\r
+                       legend: 'Appuyer sur ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Lien',\r
+                       legend: 'Appuyer sur ${link}'\r
+               },\r
+                       {\r
+                       name: 'Enrouler la barre d\'outils',\r
+                       legend: 'Appuyer sur ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Accéder à l\'objet de focus précédent',\r
+                       legend: 'Appuyer ${accessPreviousSpace} pour accéder au prochain espace disponible avant le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d\'espaces distantes.'\r
+               },\r
+                       {\r
+                       name: 'Accéder au prochain objet de focus',\r
+                       legend: 'Appuyer ${accessNextSpace} pour accéder au prochain espace disponible après le curseur, par exemple: deux éléments HR adjacents.  Répéter la combinaison pour joindre les éléments d\'espaces distantes.'\r
+               },\r
+                       {\r
+                       name: 'Aide d\'accessibilité',\r
+                       legend: 'Appuyer sur ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/fr.js b/sources/plugins/a11yhelp/dialogs/lang/fr.js
new file mode 100644 (file)
index 0000000..9727639
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'fr', {\r
+       title: 'Instructions d\'accessibilité',\r
+       contents: 'Contenu de l\'aide. Pour fermer cette fenêtre, appuyez sur la touche Échap.',\r
+       legend: [\r
+               {\r
+               name: 'Général',\r
+               items: [\r
+                       {\r
+                       name: 'Barre d\'outils de l\'éditeur',\r
+                       legend: 'Appuyer sur ${toolbarFocus} pour accéder à la barre d\'outils. Se déplacer vers le groupe suivant ou précédent de la barre d\'outils avec les touches Tab et Maj+Tab. Se déplacer vers le bouton suivant ou précédent de la barre d\'outils avec les touches Flèche droite et Flèche gauche. Appuyer sur la barre d\'espace ou la touche Entrée pour activer le bouton de barre d\'outils.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Fenêtre de l\'éditeur',\r
+                       legend:\r
+                               'Dans une boîte de dialogue, appuyer sur Tab pour passer à l\'élément suivant, appuyer sur Maj+Tab pour passer à l\'élément précédent, appuyer sur Entrée pour valider, appuyer sur Échap pour annuler. Quand une boîte de dialogue possède des onglets, la liste peut être atteinte avec Alt+F10 ou avec Tab. Dans la liste des onglets, se déplacer vers le suivant et le précédent avec les touches Flèche droite et Flèche gauche respectivement.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu contextuel de l\'éditeur',\r
+                       legend: 'Appuyer sur ${contextMenu} ou sur la touche Menu pour ouvrir le menu contextuel. Se déplacer ensuite vers l\'option suivante du menu avec les touches Tab ou Flèche bas. Se déplacer vers l\'option précédente avec les touches Maj+Tab ou Flèche haut. Appuyer sur la barre d\'espace ou la touche Entrée pour sélectionner l\'option du menu. Appuyer sur la barre d\'espace, la touche Entrée ou Flèche droite pour ouvrir le sous-menu de l\'option sélectionnée. Revenir à l\'élément de menu parent avec la touche Échap ou Flèche gauche. Fermer le menu contextuel avec Échap.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Zone de liste de l\'éditeur',\r
+                       legend: 'Dans une liste en menu déroulant, se déplacer vers l\'élément suivant de la liste avec les touches Tab ou Flèche bas. Se déplacer vers l\'élément précédent de la liste avec les touches Maj+Tab ou Flèche haut. Appuyer sur la barre d\'espace ou sur Entrée pour sélectionner l\'option dans la liste. Appuyer sur Échap pour fermer le menu déroulant.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barre du chemin d\'éléments de l\'éditeur',\r
+                       legend: 'Appuyer sur ${elementsPathFocus} pour naviguer vers la barre du fil d\'Ariane des éléments. Se déplacer vers le bouton de l\'élément suivant avec les touches Tab ou Flèche droite. Se déplacer vers le bouton précédent avec les touches Maj+Tab ou Flèche gauche. Appuyer sur la barre d\'espace ou sur Entrée pour sélectionner l\'élément dans l\'éditeur.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commandes',\r
+               items: [\r
+                       {\r
+                       name: ' Annuler la commande',\r
+                       legend: 'Appuyer sur ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Commande restaurer',\r
+                       legend: 'Appuyer sur ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Commande gras',\r
+                       legend: 'Appuyer sur ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Commande italique',\r
+                       legend: 'Appuyer sur ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Commande souligné',\r
+                       legend: 'Appuyer sur ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Commande lien',\r
+                       legend: 'Appuyer sur ${link}'\r
+               },\r
+                       {\r
+                       name: ' Commande enrouler la barre d\'outils',\r
+                       legend: 'Appuyer sur ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Commande d\'accès à l\'élément sélectionnable précédent',\r
+                       legend: 'Appuyer sur ${accessNextSpace} pour accéder à l\'élément sélectionnable inatteignable le plus proche avant le curseur, par exemple : deux lignes horizontales adjacentes. Répéter la combinaison de touches pour atteindre les éléments sélectionnables précédents.'\r
+               },\r
+                       {\r
+                       name: 'Commande d\'accès à l\'élément sélectionnable suivant',\r
+                       legend: 'Appuyer sur ${accessNextSpace} pour accéder à l\'élément sélectionnable inatteignable le plus proche après le curseur, par exemple : deux lignes horizontales adjacentes. Répéter la combinaison de touches pour atteindre les éléments sélectionnables suivants.'\r
+               },\r
+                       {\r
+                       name: ' Aide sur l\'accessibilité',\r
+                       legend: 'Appuyer sur ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulation',\r
+       pause: 'Pause',\r
+       capslock: 'Verr. Maj.',\r
+       escape: 'Échap',\r
+       pageUp: 'Page supérieure',\r
+       pageDown: 'Page suivante',\r
+       leftArrow: 'Flèche gauche',\r
+       upArrow: 'Flèche haut',\r
+       rightArrow: 'Flèche droite',\r
+       downArrow: 'Flèche basse',\r
+       insert: 'Inser',\r
+       leftWindowKey: 'Touche Windows gauche',\r
+       rightWindowKey: 'Touche Windows droite',\r
+       selectKey: 'Touche Sélectionner',\r
+       numpad0: '0 du pavé numérique',\r
+       numpad1: '1 du pavé numérique',\r
+       numpad2: '2 du pavé numérique',\r
+       numpad3: '3 du pavé numérique',\r
+       numpad4: '4 du pavé numérique',\r
+       numpad5: '5 du pavé numérique',\r
+       numpad6: '6 du pavé numérique',\r
+       numpad7: '7 du pavé numérique',\r
+       numpad8: 'Pavé numérique 8',\r
+       numpad9: '9 du pavé numérique',\r
+       multiply: 'Multiplier',\r
+       add: 'Plus',\r
+       subtract: 'Moins',\r
+       decimalPoint: 'Point décimal',\r
+       divide: 'Diviser',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Verr. Num.',\r
+       scrollLock: 'Arrêt défil.',\r
+       semiColon: 'Point-virgule',\r
+       equalSign: 'Signe égal',\r
+       comma: 'Virgule',\r
+       dash: 'Tiret',\r
+       period: 'Point',\r
+       forwardSlash: 'Barre oblique',\r
+       graveAccent: 'Accent grave',\r
+       openBracket: 'Parenthèse ouvrante',\r
+       backSlash: 'Barre oblique inverse',\r
+       closeBracket: 'Parenthèse fermante',\r
+       singleQuote: 'Apostrophe'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/gl.js b/sources/plugins/a11yhelp/dialogs/lang/gl.js
new file mode 100644 (file)
index 0000000..4978330
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'gl', {\r
+       title: 'Instrucións de accesibilidade',\r
+       contents: 'Axuda. Para pechar este diálogo prema ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Xeral',\r
+               items: [\r
+                       {\r
+                       name: 'Barra de ferramentas do editor',\r
+                       legend: 'Prema ${toolbarFocus} para navegar pola barra de ferramentas. Para moverse polos distintos grupos de ferramentas use as teclas TAB e MAIÚS+TAB. Para moverse polas distintas ferramentas use FRECHA DEREITA ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para activar o botón da barra de ferramentas.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de diálogo',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor do menú contextual',\r
+                       legend: 'Prema ${contextMenu} ou a TECLA MENÚ para abrir o menú contextual. A seguir móvase á seguinte opción do menú con TAB ou FRECHA ABAIXO. Móvase á opción anterior con MAIÚS + TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para seleccionar a opción do menú. Abra o submenú da opción actual con ESPAZO ou INTRO ou FRECHA DEREITA. Regrese ao elemento principal do menú con ESC ou FRECHA ESQUERDA. Peche o menú contextual con ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Lista do editor',\r
+                       legend: 'Dentro dunha lista, móvase ao seguinte elemento da lista con TAB ou FRECHA ABAIXO. Móvase ao elemento anterior da lista con MAIÚS+TAB ou FRECHA ARRIBA. Prema ESPAZO ou INTRO para escoller a opción da lista. Prema ESC para pechar a lista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barra da ruta ao elemento no editor',\r
+                       legend: 'Prema ${elementsPathFocus} para navegar ata os elementos da barra de ruta. Móvase ao seguinte elemento botón con TAB ou FRECHA DEREITA. Móvase ao botón anterior con MAIÚS+TAB ou FRECHA ESQUERDA. Prema ESPAZO ou INTRO para seleccionar o elemento no editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Ordes',\r
+               items: [\r
+                       {\r
+                       name: 'Orde «desfacer»',\r
+                       legend: 'Prema ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Orde «refacer»',\r
+                       legend: 'Prema ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Orde «negra»',\r
+                       legend: 'Prema ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Orde «cursiva»',\r
+                       legend: 'Prema ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Orde «subliñar»',\r
+                       legend: 'Prema ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Orde «ligazón»',\r
+                       legend: 'Prema ${link}'\r
+               },\r
+                       {\r
+                       name: 'Orde «contraer a barra de ferramentas»',\r
+                       legend: 'Prema ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Orde «acceder ao anterior espazo en foco»',\r
+                       legend: 'Prema ${accessPreviousSpace} para acceder ao espazo máis próximo de foco inalcanzábel anterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes.'\r
+               },\r
+                       {\r
+                       name: 'Orde «acceder ao seguinte espazo en foco»',\r
+                       legend: 'Prema ${accessNextSpace} para acceder ao espazo máis próximo de foco inalcanzábel posterior ao cursor, por exemplo: dous elementos HR adxacentes. Repita a combinación de teclas para chegar a espazos de foco distantes.'\r
+               },\r
+                       {\r
+                       name: 'Axuda da accesibilidade',\r
+                       legend: 'Prema ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulador',\r
+       pause: 'Pausa',\r
+       capslock: 'Bloq. Maiús',\r
+       escape: 'Escape',\r
+       pageUp: 'Páxina arriba',\r
+       pageDown: 'Páxina abaixo',\r
+       leftArrow: 'Frecha esquerda',\r
+       upArrow: 'Frecha arriba',\r
+       rightArrow: 'Frecha dereita',\r
+       downArrow: 'Frecha abaixo',\r
+       insert: 'Inserir',\r
+       leftWindowKey: 'Tecla Windows esquerda',\r
+       rightWindowKey: 'Tecla Windows dereita',\r
+       selectKey: 'Escolla a tecla',\r
+       numpad0: 'Tec. numérico 0',\r
+       numpad1: 'Tec. numérico 1',\r
+       numpad2: 'Tec. numérico 2',\r
+       numpad3: 'Tec. numérico 3',\r
+       numpad4: 'Tec. numérico 4',\r
+       numpad5: 'Tec. numérico 5',\r
+       numpad6: 'Tec. numérico 6',\r
+       numpad7: 'Tec. numérico 7',\r
+       numpad8: 'Tec. numérico 8',\r
+       numpad9: 'Tec. numérico 9',\r
+       multiply: 'Multiplicar',\r
+       add: 'Sumar',\r
+       subtract: 'Restar',\r
+       decimalPoint: 'Punto decimal',\r
+       divide: 'Dividir',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Bloq. num.',\r
+       scrollLock: 'Bloq. despraz.',\r
+       semiColon: 'Punto e coma',\r
+       equalSign: 'Signo igual',\r
+       comma: 'Coma',\r
+       dash: 'Guión',\r
+       period: 'Punto',\r
+       forwardSlash: 'Barra inclinada',\r
+       graveAccent: 'Acento grave',\r
+       openBracket: 'Abrir corchete',\r
+       backSlash: 'Barra invertida',\r
+       closeBracket: 'Pechar corchete',\r
+       singleQuote: 'Comiña simple'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/gu.js b/sources/plugins/a11yhelp/dialogs/lang/gu.js
new file mode 100644 (file)
index 0000000..30eb2cd
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'gu', {\r
+       title: 'એક્ક્ષેબિલિટી ની વિગતો',\r
+       contents: 'હેલ્પ. આ બંધ કરવા ESC દબાવો.',\r
+       legend: [\r
+               {\r
+               name: 'જનરલ',\r
+               items: [\r
+                       {\r
+                       name: 'એડિટર ટૂલબાર',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'એડિટર ડાયલોગ',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'કમાંડસ',\r
+               items: [\r
+                       {\r
+                       name: 'અન્ડું કમાંડ',\r
+                       legend: '$ દબાવો {undo}'\r
+               },\r
+                       {\r
+                       name: 'ફરી કરો કમાંડ',\r
+                       legend: '$ દબાવો {redo}'\r
+               },\r
+                       {\r
+                       name: 'બોલ્દનો કમાંડ',\r
+                       legend: '$ દબાવો {bold}'\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/he.js b/sources/plugins/a11yhelp/dialogs/lang/he.js
new file mode 100644 (file)
index 0000000..24b8572
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'he', {\r
+       title: 'הוראות נגישות',\r
+       contents: 'הוראות נגישות. לסגירה לחץ אסקייפ (ESC).',\r
+       legend: [\r
+               {\r
+               name: 'כללי',\r
+               items: [\r
+                       {\r
+                       name: 'סרגל הכלים',\r
+                       legend: 'לחץ על ${toolbarFocus} כדי לנווט לסרגל הכלים. עבור לכפתור הבא עם מקש הטאב (TAB) או חץ שמאלי. עבור לכפתור הקודם עם מקש השיפט (SHIFT) + טאב (TAB) או חץ ימני. לחץ רווח או אנטר (ENTER) כדי להפעיל את הכפתור הנבחר.'\r
+               },\r
+\r
+                       {\r
+                       name: 'דיאלוגים (חלונות תשאול)',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'תפריט ההקשר (Context Menu)',\r
+                       legend: 'לחץ ${contextMenu} או APPLICATION KEYכדי לפתוח את תפריט ההקשר. עבור לאפשרות הבאה עם טאב (TAB) או חץ למטה. עבור לאפשרות הקודמת עם שיפט (SHIFT) + טאב (TAB) או חץ למעלה. לחץ רווח או אנטר (ENTER) כדי לבחור את האפשרות. פתח את תת התפריט (Sub-menu) של האפשרות הנוכחית עם רווח או אנטר (ENTER) או חץ שמאלי. חזור לתפריט האב עם אסקייפ (ESC) או חץ שמאלי. סגור את תפריט ההקשר עם אסקייפ (ESC).'\r
+               },\r
+\r
+                       {\r
+                       name: 'תפריטים צפים (List boxes)',\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'עץ אלמנטים (Elements Path)',\r
+                       legend: 'לחץ ${elementsPathFocus} כדי לנווט לעץ האלמנטים. עבור לפריט הבא עם טאב (TAB) או חץ ימני. עבור לפריט הקודם עם שיפט (SHIFT) + טאב (TAB) או חץ שמאלי. לחץ רווח או אנטר (ENTER) כדי לבחור את האלמנט בעורך.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'פקודות',\r
+               items: [\r
+                       {\r
+                       name: ' ביטול צעד אחרון',\r
+                       legend: 'לחץ ${undo}'\r
+               },\r
+                       {\r
+                       name: ' חזרה על צעד אחרון',\r
+                       legend: 'לחץ ${redo}'\r
+               },\r
+                       {\r
+                       name: ' הדגשה',\r
+                       legend: 'לחץ ${bold}'\r
+               },\r
+                       {\r
+                       name: ' הטייה',\r
+                       legend: 'לחץ ${italic}'\r
+               },\r
+                       {\r
+                       name: ' הוספת קו תחתון',\r
+                       legend: 'לחץ ${underline}'\r
+               },\r
+                       {\r
+                       name: ' הוספת לינק',\r
+                       legend: 'לחץ ${link}'\r
+               },\r
+                       {\r
+                       name: ' כיווץ סרגל הכלים',\r
+                       legend: 'לחץ ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'גישה למיקום המיקוד הקודם',\r
+                       legend: 'לחץ ${accessPreviousSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב לפני הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר.'\r
+               },\r
+                       {\r
+                       name: 'גישה למיקום המיקוד הבא',\r
+                       legend: 'לחץ ${accessNextSpace} כדי לגשת למיקום המיקוד הלא-נגיש הקרוב אחרי הסמן, למשל בין שני אלמנטים סמוכים מסוג HR. חזור על צירוף מקשים זה כדי להגיע למקומות מיקוד רחוקים יותר.'\r
+               },\r
+                       {\r
+                       name: ' הוראות נגישות',\r
+                       legend: 'לחץ ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'חץ שמאלה',\r
+       upArrow: 'חץ למעלה',\r
+       rightArrow: 'חץ ימינה',\r
+       downArrow: 'חץ למטה',\r
+       insert: 'הכנס',\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'בחר מקש',\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'הוסף',\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'סלאש',\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'סלאש הפוך',\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'ציטוט יחיד'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/hi.js b/sources/plugins/a11yhelp/dialogs/lang/hi.js
new file mode 100644 (file)
index 0000000..308c5ef
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'hi', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'सामान्य',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/hr.js b/sources/plugins/a11yhelp/dialogs/lang/hr.js
new file mode 100644 (file)
index 0000000..b05273e
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'hr', {\r
+       title: 'Upute dostupnosti',\r
+       contents: 'Sadržaj pomoći. Za zatvaranje pritisnite ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Općenito',\r
+               items: [\r
+                       {\r
+                       name: 'Alatna traka',\r
+                       legend: 'Pritisni ${toolbarFocus} za navigaciju do alatne trake. Pomicanje do prethodne ili sljedeće alatne grupe vrši se pomoću SHIFT+TAB i TAB. Pomicanje do prethodnog ili sljedećeg gumba u alatnoj traci vrši se pomoću lijeve i desne strelice kursora. Pritisnite SPACE ili ENTER za aktivaciju alatne trake.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dijalog',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Kontekstni izbornik',\r
+                       legend: 'Pritisnite ${contextMenu} ili APPLICATION tipku za otvaranje kontekstnog izbornika. Pomicanje se vrši TAB ili strelicom kursora prema dolje ili SHIFT+TAB ili strelica kursora prema gore. SPACE ili ENTER odabiru opciju izbornika. Otvorite podizbornik trenutne opcije sa  SPACE, ENTER ili desna strelica kursora. Povratak na prethodni izbornik vrši se sa ESC ili lijevom strelicom kursora. Zatvaranje se vrši pritiskom na tipku ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Lista',\r
+                       legend: 'Unutar list-boxa, pomicanje na sljedeću stavku vrši se sa TAB ili strelica kursora prema dolje. Na prethodnu sa SHIFT+TAB ili strelica prema gore. Pritiskom na SPACE ili ENTER odabire se stavka ili ESC za zatvaranje.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Traka putanje elemenata',\r
+                       legend: 'Pritisnite ${elementsPathFocus} za navigaciju po putanji elemenata. Pritisnite TAB ili desnu strelicu kursora za pomicanje na sljedeći element ili SHIFT+TAB ili lijeva strelica kursora za pomicanje na prethodni element. Pritiskom na SPACE ili ENTER vrši se odabir elementa.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Naredbe',\r
+               items: [\r
+                       {\r
+                       name: 'Vrati naredbu',\r
+                       legend: 'Pritisni ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Ponovi naredbu',\r
+                       legend: 'Pritisni ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Bold naredba',\r
+                       legend: 'Pritisni ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Italic naredba',\r
+                       legend: 'Pritisni ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Underline naredba',\r
+                       legend: 'Pritisni ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link naredba',\r
+                       legend: 'Pritisni ${link}'\r
+               },\r
+                       {\r
+                       name: 'Smanji alatnu traku naredba',\r
+                       legend: 'Pritisni ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Access previous focus space naredba',\r
+                       legend: 'Pritisni ${accessPreviousSpace} za pristup najbližem nedostupnom razmaku prije kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak.'\r
+               },\r
+                       {\r
+                       name: 'Access next focus space naredba',\r
+                       legend: 'Pritisni ${accessNextSpace} za pristup najbližem nedostupnom razmaku nakon kursora, npr.: dva spojena HR elementa. Ponovnim pritiskom dohvatiti će se sljedeći nedostupni razmak.'\r
+               },\r
+                       {\r
+                       name: 'Pomoć za dostupnost',\r
+                       legend: 'Pritisni ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/hu.js b/sources/plugins/a11yhelp/dialogs/lang/hu.js
new file mode 100644 (file)
index 0000000..f14f17d
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'hu', {\r
+       title: 'Kisegítő utasítások',\r
+       contents: 'Súgó tartalmak. A párbeszédablak bezárásához nyomjon ESC-et.',\r
+       legend: [\r
+               {\r
+               name: 'Általános',\r
+               items: [\r
+                       {\r
+                       name: 'Szerkesztő Eszköztár',\r
+                       legend: 'Nyomjon ${toolbarFocus} hogy kijelölje az eszköztárat. A következő és előző eszköztár csoporthoz a TAB és SHIFT+TAB-al juthat el. A következő és előző eszköztár gombhoz a BAL NYÍL vagy JOBB NYÍL gombbal juthat el. Nyomjon SPACE-t vagy ENTER-t hogy aktiválja az eszköztár gombot.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Szerkesző párbeszéd ablak',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Szerkesztő helyi menü',\r
+                       legend: 'Nyomjon ${contextMenu}-t vagy ALKALMAZÁS BILLENTYŰT a helyi menü megnyitásához. Ezután a következő menüpontra léphet a TAB vagy LEFELÉ NYÍLLAL. Az előző opciót a SHIFT+TAB vagy FELFELÉ NYÍLLAL érheti el. Nyomjon SPACE-t vagy ENTER-t a menüpont kiválasztásához. A jelenlegi menüpont almenüjének megnyitásához nyomjon SPACE-t vagy ENTER-t, vagy JOBB NYILAT. A főmenühöz való visszatéréshez nyomjon ESC-et vagy BAL NYILAT. A helyi menü bezárása az ESC billentyűvel lehetséges.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Szerkesztő lista',\r
+                       legend: 'A listán belül a következő elemre a TAB vagy LEFELÉ NYÍLLAL mozoghat. Az előző elem kiválasztásához nyomjon SHIFT+TAB-ot vagy FELFELÉ NYILAT. Nyomjon SPACE-t vagy ENTER-t az elem kiválasztásához. Az ESC billentyű megnyomásával bezárhatja a listát.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Szerkesztő elem utak sáv',\r
+                       legend: 'Nyomj ${elementsPathFocus} hogy kijelöld a elemek út sávját. A következő elem gombhoz a TAB-al vagy a JOBB NYÍLLAL juthatsz el. Az előző gombhoz a SHIFT+TAB vagy BAL NYÍLLAL mehetsz. A SPACE vagy ENTER billentyűvel kiválaszthatod az elemet a szerkesztőben.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Parancsok',\r
+               items: [\r
+                       {\r
+                       name: 'Parancs visszavonása',\r
+                       legend: 'Nyomj ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Parancs megismétlése',\r
+                       legend: 'Nyomjon ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Félkövér parancs',\r
+                       legend: 'Nyomjon ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Dőlt parancs',\r
+                       legend: 'Nyomjon ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Aláhúzott parancs',\r
+                       legend: 'Nyomjon ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link parancs',\r
+                       legend: 'Nyomjon ${link}'\r
+               },\r
+                       {\r
+                       name: 'Szerkesztősáv összecsukása parancs',\r
+                       legend: 'Nyomjon ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Hozzáférés az előző fókusz helyhez parancs',\r
+                       legend: 'Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel előtt, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket.'\r
+               },\r
+                       {\r
+                       name: 'Hozzáférés a következő fókusz helyhez parancs',\r
+                       legend: 'Nyomj ${accessNextSpace} hogy hozzáférj a legközelebbi elérhetetlen fókusz helyhez a hiányjel után, például: két szomszédos HR elemhez. Ismételd meg a billentyűkombinációt hogy megtaláld a távolabbi fókusz helyeket.'\r
+               },\r
+                       {\r
+                       name: 'Kisegítő súgó',\r
+                       legend: 'Nyomjon ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'balra nyíl',\r
+       upArrow: 'felfelé nyíl',\r
+       rightArrow: 'jobbra nyíl',\r
+       downArrow: 'lefelé nyíl',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'bal Windows-billentyű',\r
+       rightWindowKey: 'jobb Windows-billentyű',\r
+       selectKey: 'Billentyű választása',\r
+       numpad0: 'Számbillentyűk 0',\r
+       numpad1: 'Számbillentyűk 1',\r
+       numpad2: 'Számbillentyűk 2',\r
+       numpad3: 'Számbillentyűk 3',\r
+       numpad4: 'Számbillentyűk 4',\r
+       numpad5: 'Számbillentyűk 5',\r
+       numpad6: 'Számbillentyűk 6',\r
+       numpad7: 'Számbillentyűk 7',\r
+       numpad8: 'Számbillentyűk 8',\r
+       numpad9: 'Számbillentyűk 9',\r
+       multiply: 'Szorzás',\r
+       add: 'Hozzáadás',\r
+       subtract: 'Kivonás',\r
+       decimalPoint: 'Tizedespont',\r
+       divide: 'Osztás',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Pontosvessző',\r
+       equalSign: 'Egyenlőségjel',\r
+       comma: 'Vessző',\r
+       dash: 'Kötőjel',\r
+       period: 'Pont',\r
+       forwardSlash: 'Perjel',\r
+       graveAccent: 'Visszafelé dőlő ékezet',\r
+       openBracket: 'Nyitó szögletes zárójel',\r
+       backSlash: 'fordított perjel',\r
+       closeBracket: 'Záró szögletes zárójel',\r
+       singleQuote: 'szimpla idézőjel'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/id.js b/sources/plugins/a11yhelp/dialogs/lang/id.js
new file mode 100644 (file)
index 0000000..7799b38
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'id', {\r
+       title: 'Instruksi Accessibility',\r
+       contents: 'Bantuan. Tekan ESC untuk menutup dialog ini.',\r
+       legend: [\r
+               {\r
+               name: 'Umum',\r
+               items: [\r
+                       {\r
+                       name: 'Toolbar Editor',\r
+                       legend: 'Tekan ${toolbarFocus} untuk berpindah ke toolbar. Untuk berpindah ke group toolbar selanjutnya dan sebelumnya gunakan TAB dan SHIFT+TAB. Untuk berpindah ke tombol toolbar selanjutnya dan sebelumnya gunakan RIGHT ARROW atau LEFT ARROW. Tekan SPASI atau ENTER untuk mengaktifkan tombol toolbar.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialog Editor',\r
+                       legend:\r
+                               'Pada jendela dialog, tekan TAB untuk berpindah pada elemen dialog selanjutnya, tekan SHIFT+TAB untuk berpindah pada elemen dialog sebelumnya, tekan ENTER untuk submit dialog, tekan ESC untuk membatalkan dialog. Pada dialog dengan multi tab, daftar tab dapat diakses dengan ALT+F10 ataupun dengan tombol TAB sesuai urutan tab pada dialog. Jika daftar tab aktif terpilih, untuk berpindah tab dapat menggunakan RIGHT dan LEFT ARROW.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Context Menu Editor',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'List Box Editor',\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/it.js b/sources/plugins/a11yhelp/dialogs/lang/it.js
new file mode 100644 (file)
index 0000000..55ecadc
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'it', {\r
+       title: 'Istruzioni di Accessibilità',\r
+       contents: 'Contenuti di Aiuto. Per chiudere questa finestra premi ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Generale',\r
+               items: [\r
+                       {\r
+                       name: 'Barra degli strumenti Editor',\r
+                       legend: 'Premere ${toolbarFocus} per passare alla barra degli strumenti. Usare TAB per spostarsi al gruppo successivo, MAIUSC+TAB per spostarsi a quello precedente. Usare FRECCIA DESTRA per spostarsi al pulsante successivo, FRECCIA SINISTRA per spostarsi a quello precedente. Premere SPAZIO o INVIO per attivare il pulsante della barra degli strumenti.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Finestra Editor',\r
+                       legend:\r
+                               'All\'interno di una finestra di dialogo è possibile premere TAB per passare all\'elemento successivo della finestra, MAIUSC+TAB per passare a quello precedente; premere INVIO per inviare i dati della finestra, oppure ESC per annullare l\'operazione. Quando una finestra di dialogo ha più schede, è possibile passare all\'elenco delle schede sia con ALT+F10 che con TAB, in base all\'ordine delle tabulazioni della finestra. Quando l\'elenco delle schede è attivo, premere la FRECCIA DESTRA o la FRECCIA SINISTRA per passare rispettivamente alla scheda successiva o a quella precedente.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menù contestuale Editor',\r
+                       legend: 'Premi ${contextMenu} o TASTO APPLICAZIONE per aprire il menu contestuale. Dunque muoviti all\'opzione successiva del menu con il tasto TAB o con la Freccia Sotto. Muoviti all\'opzione precedente con  MAIUSC+TAB o con Freccia Sopra. Premi SPAZIO o INVIO per scegliere l\'opzione di menu. Apri il sottomenu dell\'opzione corrente con SPAZIO o INVIO oppure con la Freccia Destra. Torna indietro al menu superiore con ESC oppure Freccia Sinistra. Chiudi il menu contestuale con ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Box Lista Editor',\r
+                       legend: 'All\'interno di un elenco di opzioni, per spostarsi all\'elemento successivo premere TAB oppure FRECCIA GIÙ. Per spostarsi all\'elemento precedente usare SHIFT+TAB oppure FRECCIA SU. Premere SPAZIO o INVIO per selezionare l\'elemento della lista. Premere ESC per chiudere l\'elenco di opzioni.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barra percorso elementi editor',\r
+                       legend: 'Premere ${elementsPathFocus} per passare agli elementi della barra del percorso. Usare TAB o FRECCIA DESTRA per passare al pulsante successivo. Per passare al pulsante precedente premere MAIUSC+TAB o FRECCIA SINISTRA. Premere SPAZIO o INVIO per selezionare l\'elemento nell\'editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comandi',\r
+               items: [\r
+                       {\r
+                       name: ' Annulla comando',\r
+                       legend: 'Premi ${undo}'\r
+               },\r
+                       {\r
+                       name: ' Ripeti comando',\r
+                       legend: 'Premi ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Comando Grassetto',\r
+                       legend: 'Premi ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Comando Corsivo',\r
+                       legend: 'Premi ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Comando Sottolineato',\r
+                       legend: 'Premi ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Comando Link',\r
+                       legend: 'Premi ${link}'\r
+               },\r
+                       {\r
+                       name: ' Comando riduci barra degli strumenti',\r
+                       legend: 'Premi ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Comando di accesso al precedente spazio di focus',\r
+                       legend: 'Premi ${accessPreviousSpace} per accedere il più vicino spazio di focus non raggiungibile prima del simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti.'\r
+               },\r
+                       {\r
+                       name: 'Comando di accesso al prossimo spazio di focus',\r
+                       legend: 'Premi ${accessNextSpace} per accedere il più vicino spazio di focus non raggiungibile dopo il simbolo caret, per esempio due elementi HR adiacenti. Ripeti la combinazione di tasti per raggiungere spazi di focus distanti.'\r
+               },\r
+                       {\r
+                       name: ' Aiuto Accessibilità',\r
+                       legend: 'Premi ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pausa',\r
+       capslock: 'Bloc Maiusc',\r
+       escape: 'Esc',\r
+       pageUp: 'Pagina sù',\r
+       pageDown: 'Pagina giù',\r
+       leftArrow: 'Freccia sinistra',\r
+       upArrow: 'Freccia su',\r
+       rightArrow: 'Freccia destra',\r
+       downArrow: 'Freccia giù',\r
+       insert: 'Ins',\r
+       leftWindowKey: 'Tasto di Windows sinistro',\r
+       rightWindowKey: 'Tasto di Windows destro',\r
+       selectKey: 'Tasto di selezione',\r
+       numpad0: '0 sul tastierino numerico',\r
+       numpad1: '1 sul tastierino numerico',\r
+       numpad2: '2 sul tastierino numerico',\r
+       numpad3: '3 sul tastierino numerico',\r
+       numpad4: '4 sul tastierino numerico',\r
+       numpad5: '5 sul tastierino numerico',\r
+       numpad6: '6 sul tastierino numerico',\r
+       numpad7: '7 sul tastierino numerico',\r
+       numpad8: '8 sul tastierino numerico',\r
+       numpad9: '9 sul tastierino numerico',\r
+       multiply: 'Moltiplicazione',\r
+       add: 'Più',\r
+       subtract: 'Sottrazione',\r
+       decimalPoint: 'Punto decimale',\r
+       divide: 'Divisione',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Bloc Num',\r
+       scrollLock: 'Bloc Scorr',\r
+       semiColon: 'Punto-e-virgola',\r
+       equalSign: 'Segno di uguale',\r
+       comma: 'Virgola',\r
+       dash: 'Trattino',\r
+       period: 'Punto',\r
+       forwardSlash: 'Barra',\r
+       graveAccent: 'Accento grave',\r
+       openBracket: 'Parentesi quadra aperta',\r
+       backSlash: 'Barra rovesciata',\r
+       closeBracket: 'Parentesi quadra chiusa',\r
+       singleQuote: 'Apostrofo'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ja.js b/sources/plugins/a11yhelp/dialogs/lang/ja.js
new file mode 100644 (file)
index 0000000..9053e37
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ja', {\r
+       title: 'ユーザー補助の説明',\r
+       contents: 'ヘルプ このダイアログを閉じるには ESCを押してください。',\r
+       legend: [\r
+               {\r
+               name: '全般',\r
+               items: [\r
+                       {\r
+                       name: 'エディターツールバー',\r
+                       legend: '${toolbarFocus} を押すとツールバーのオン/オフ操作ができます。カーソルをツールバーのグループで移動させるにはTabかSHIFT+Tabを押します。グループ内でカーソルを移動させるには、右カーソルか左カーソルを押します。スペースキーやエンターを押すとボタンを有効/無効にすることができます。'\r
+               },\r
+\r
+                       {\r
+                       name: '編集ダイアログ',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'エディターのメニュー',\r
+                       legend: '${contextMenu} キーかAPPLICATION KEYを押すとコンテキストメニューが開きます。Tabか下カーソルでメニューのオプション選択が下に移動します。戻るには、SHIFT+Tabか上カーソルです。スペースもしくはENTERキーでメニューオプションを決定できます。現在選んでいるオプションのサブメニューを開くには、スペース、もしくは右カーソルを押します。サブメニューから親メニューに戻るには、ESCか左カーソルを押してください。ESCでコンテキストメニュー自体をキャンセルできます。'\r
+               },\r
+\r
+                       {\r
+                       name: 'エディターリストボックス',\r
+                       legend: 'リストボックス内で移動するには、Tabか下カーソルで次のアイテムへ移動します。SHIFT+Tabで前のアイテムに戻ります。リストのオプションを選択するには、スペースもしくは、ENTERを押してください。リストボックスを閉じるには、ESCを押してください。'\r
+               },\r
+\r
+                       {\r
+                       name: 'エディター要素パスバー',\r
+                       legend: '${elementsPathFocus} を押すとエレメントパスバーを操作出来ます。Tabか右カーソルで次のエレメントを選択できます。前のエレメントを選択するには、SHIFT+Tabか左カーソルです。スペースもしくは、ENTERでエディタ内の対象エレメントを選択出来ます。'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'コマンド',\r
+               items: [\r
+                       {\r
+                       name: '元に戻す',\r
+                       legend: '${undo} をクリック'\r
+               },\r
+                       {\r
+                       name: 'やり直し',\r
+                       legend: '${redo} をクリック'\r
+               },\r
+                       {\r
+                       name: '太字',\r
+                       legend: '${bold} をクリック'\r
+               },\r
+                       {\r
+                       name: '斜体 ',\r
+                       legend: '${italic} をクリック'\r
+               },\r
+                       {\r
+                       name: '下線',\r
+                       legend: '${underline} をクリック'\r
+               },\r
+                       {\r
+                       name: 'リンク',\r
+                       legend: '${link} をクリック'\r
+               },\r
+                       {\r
+                       name: 'ツールバーを縮める',\r
+                       legend: '${toolbarCollapse} をクリック'\r
+               },\r
+                       {\r
+                       name: '前のカーソル移動のできないポイントへ',\r
+                       legend: '${accessPreviousSpace} を押すとカーソルより前にあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。'\r
+               },\r
+                       {\r
+                       name: '次のカーソル移動のできないポイントへ',\r
+                       legend: '${accessNextSpace} を押すとカーソルより後ろにあるカーソルキーで入り込めないスペースへ移動できます。例えば、HRエレメントが2つ接している場合などです。離れた場所へは、複数回キーを押します。'\r
+               },\r
+                       {\r
+                       name: 'ユーザー補助ヘルプ',\r
+                       legend: '${a11yHelp} をクリック'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: '左矢印',\r
+       upArrow: '上矢印',\r
+       rightArrow: '右矢印',\r
+       downArrow: '下矢印',\r
+       insert: 'Insert',\r
+       leftWindowKey: '左Windowキー',\r
+       rightWindowKey: '右のWindowキー',\r
+       selectKey: 'Select',\r
+       numpad0: 'Num 0',\r
+       numpad1: 'Num 1',\r
+       numpad2: 'Num 2',\r
+       numpad3: 'Num 3',\r
+       numpad4: 'Num 4',\r
+       numpad5: 'Num 5',\r
+       numpad6: 'Num 6',\r
+       numpad7: 'Num 7',\r
+       numpad8: 'Num 8',\r
+       numpad9: 'Num 9',\r
+       multiply: '掛ける',\r
+       add: '足す',\r
+       subtract: '引く',\r
+       decimalPoint: '小数点',\r
+       divide: '割る',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'セミコロン',\r
+       equalSign: 'イコール記号',\r
+       comma: 'カンマ',\r
+       dash: 'ダッシュ',\r
+       period: 'ピリオド',\r
+       forwardSlash: 'フォワードスラッシュ',\r
+       graveAccent: 'グレイヴアクセント',\r
+       openBracket: '開きカッコ',\r
+       backSlash: 'バックスラッシュ',\r
+       closeBracket: '閉じカッコ',\r
+       singleQuote: 'シングルクォート'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/km.js b/sources/plugins/a11yhelp/dialogs/lang/km.js
new file mode 100644 (file)
index 0000000..4cdd048
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'km', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'មាតិកា​ជំនួយ។ ដើម្បី​បិទ​ផ្ទាំង​នេះ សូម​ចុច ESC ។',\r
+       legend: [\r
+               {\r
+               name: 'ទូទៅ',\r
+               items: [\r
+                       {\r
+                       name: 'របារ​ឧបករណ៍​កម្មវិធី​និពន្ធ',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'ផ្ទាំង​កម្មវិធីនិពន្ធ',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'ម៉ីនុយបរិបទអ្នកកែសម្រួល',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'ប្រអប់បញ្ជីអ្នកកែសម្រួល',\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'ពាក្យបញ្ជា',\r
+               items: [\r
+                       {\r
+                       name: 'ការ​បញ្ជា​មិនធ្វើវិញ',\r
+                       legend: 'ចុច ${undo}'\r
+               },\r
+                       {\r
+                       name: 'ការបញ្ជា​ធ្វើវិញ',\r
+                       legend: 'ចុច ${redo}'\r
+               },\r
+                       {\r
+                       name: 'ការបញ្ជា​អក្សរ​ដិត',\r
+                       legend: 'ចុច ${bold}'\r
+               },\r
+                       {\r
+                       name: 'ការបញ្ជា​អក្សរ​ទ្រេត',\r
+                       legend: 'ចុច ${italic}'\r
+               },\r
+                       {\r
+                       name: 'ពាក្យបញ្ជា​បន្ទាត់​ពីក្រោម',\r
+                       legend: 'ចុច ${underline}'\r
+               },\r
+                       {\r
+                       name: 'ពាក្យបញ្ជា​តំណ',\r
+                       legend: 'ចុច ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: 'ជំនួយ​ពី​ភាព​ងាយស្រួល',\r
+                       legend: 'ជួយ ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'ផ្អាក',\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'ចាកចេញ',\r
+       pageUp: 'ទំព័រ​លើ',\r
+       pageDown: 'ទំព័រ​ក្រោម',\r
+       leftArrow: 'ព្រួញ​ឆ្វេង',\r
+       upArrow: 'ព្រួញ​លើ',\r
+       rightArrow: 'ព្រួញ​ស្ដាំ',\r
+       downArrow: 'ព្រួញ​ក្រោម',\r
+       insert: 'បញ្ចូល',\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'ជ្រើស​គ្រាប់​ចុច',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'គុណ',\r
+       add: 'បន្ថែម',\r
+       subtract: 'ដក',\r
+       decimalPoint: 'ចំណុចទសភាគ',\r
+       divide: 'ចែក',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'បិទ​រំកិល',\r
+       semiColon: 'ចុច​ក្បៀស',\r
+       equalSign: 'សញ្ញា​អឺរ៉ូ',\r
+       comma: 'ក្បៀស',\r
+       dash: 'Dash', // MISSING\r
+       period: 'ចុច',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'តង្កៀប​បើក',\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'តង្កៀប​បិទ',\r
+       singleQuote: 'បន្តក់​មួយ'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ko.js b/sources/plugins/a11yhelp/dialogs/lang/ko.js
new file mode 100644 (file)
index 0000000..e5ed192
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ko', {\r
+       title: '접근성 설명',\r
+       contents: '도움말. 이 창을 닫으시려면 ESC 를 누르세요.',\r
+       legend: [\r
+               {\r
+               name: '일반',\r
+               items: [\r
+                       {\r
+                       name: '편집기 툴바',\r
+                       legend: '툴바를 탐색하시려면 ${toolbarFocus} 를 투르세요. 이전/다음 툴바 그룹으로 이동하시려면 TAB 키 또는 SHIFT+TAB 키를 누르세요. 이전/다음 툴바 버튼으로 이동하시려면 오른쪽 화살표 키 또는 왼쪽 화살표 키를 누르세요. 툴바 버튼을 활성화 하려면 SPACE 키 또는 ENTER 키를 누르세요.'\r
+               },\r
+\r
+                       {\r
+                       name: '편집기 다이얼로그',\r
+                       legend:\r
+                               'TAB 키를 누르면 다음 대화상자로 이동하고, SHIFT+TAB 키를 누르면 이전 대화상자로 이동합니다. 대화상자를 제출하려면 ENTER 키를 누르고, ESC 키를 누르면 대화상자를 취소합니다. 대화상자에 탭이 여러개 있을 때, ALT+F10 키 또는 TAB 키를 누르면 순서에 따라 탭 목록에 도달할 수 있습니다. 탭 목록에 초점이 맞을 때, 오른쪽과 왼쪽 화살표 키를 이용하면 각각 다음과 이전 탭으로 이동할 수 있습니다.'\r
+               },\r
+\r
+                       {\r
+                       name: '편집기 환경 메뉴',\r
+                       legend: '${contextMenu} 또는 어플리케이션 키를 누르면 환경-메뉴를 열 수 있습니다. 환경-메뉴에서 TAB 키 또는 아래 화살표 키를 누르면 다음 메뉴 옵션으로 이동할 수 있습니다. 이전 옵션으로 이동은 SHIFT+TAB 키 또는 위 화살표 키를 눌러서 할 수 있습니다. 스페이스 키 또는 ENTER 키를 눌러서 메뉴 옵션을 선택할 수 있습니다. 스페이스 키 또는 ENTER 키 또는 오른쪽 화살표 키를 눌러서 하위 메뉴를 열 수 있습니다. 부모 메뉴 항목으로 돌아가려면 ESC 키 또는 왼쪽 화살표 키를 누릅니다. ESC 키를 눌러서 환경-메뉴를 닫습니다.'\r
+               },\r
+\r
+                       {\r
+                       name: '편집기 목록 박스',\r
+                       legend: '리스트-박스 내에서, 목록의 다음 항목으로 이동하려면 TAB 키 또는 아래쪽 화살표 키를 누릅니다. 목록의 이전 항목으로 이동하려면 SHIFT+TAB 키 또는 위쪽 화살표 키를 누릅니다. 스페이스 키 또는 ENTER 키를 누르면 목록의 해당 옵션을 선택합니다. ESC 키를 눌러서 리스트-박스를 닫을 수 있습니다.'\r
+               },\r
+\r
+                       {\r
+                       name: '편집기 요소 경로 막대',\r
+                       legend: '${elementsPathFocus}를 눌러서 요소 경로 막대를 탐색할 수 있습니다. 다음 요소로 이동하려면 TAB 키 또는 오른쪽 화살표 키를 누릅니다. SHIFT+TAB 키 또는 왼쪽 화살표 키를 누르면 이전 버튼으로 이동할 수 있습니다. 스페이스 키나 ENTER 키를 누르면 편집기의 해당 항목을 선택합니다.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: '명령',\r
+               items: [\r
+                       {\r
+                       name: ' 명령 실행 취소',\r
+                       legend: '${undo} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 명령 다시 실행',\r
+                       legend: '${redo} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 굵게 명령',\r
+                       legend: '${bold} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 기울임 꼴 명령',\r
+                       legend: '${italic} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 밑줄 명령',\r
+                       legend: '${underline} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 링크 명령',\r
+                       legend: '${link} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 툴바 줄이기 명령',\r
+                       legend: '${toolbarCollapse} 누르시오'\r
+               },\r
+                       {\r
+                       name: ' 이전 포커스 공간 접근 명령',\r
+                       legend: '탈자 기호(^) 이전에 ${accessPreviousSpace} 를 누르면, 접근 불가능하면서 가장 가까운 포커스 영역에 접근합니다. 예를 들면, 두 인접한 HR 요소가 있습니다. 키 조합을 반복해서 멀리있는 포커스 영역들에 도달할 수 있습니다.'\r
+               },\r
+                       {\r
+                       name: '다음 포커스 공간 접근 명령',\r
+                       legend: '탈자 기호(^) 다음에 ${accessNextSpace} 를 누르면, 접근 불가능하면서 가장 가까운 포커스 영역에 접근합니다. 예를 들면, 두 인접한 HR 요소가 있습니다. 키 조합을 반복해서 멀리있는 포커스 영역들에 도달할 수 있습니다. '\r
+               },\r
+                       {\r
+                       name: ' 접근성 도움말',\r
+                       legend: '${a11yHelp} 누르시오'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: '탭 키',\r
+       pause: '일시정지 키',\r
+       capslock: '캡스 록 키',\r
+       escape: '이스케이프 키',\r
+       pageUp: '페이지 업 키',\r
+       pageDown: '페이지 다운 키',\r
+       leftArrow: '왼쪽 화살표 키',\r
+       upArrow: '위쪽 화살표 키',\r
+       rightArrow: '오른쪽 화살표 키',\r
+       downArrow: '아래쪽 화살표 키',\r
+       insert: '인서트 키',\r
+       leftWindowKey: '왼쪽 윈도우 키',\r
+       rightWindowKey: '오른쪽 윈도우 키',\r
+       selectKey: '셀렉트 키',\r
+       numpad0: '숫자 패드 0 키',\r
+       numpad1: '숫자 패드 1 키',\r
+       numpad2: '숫자 패드 2 키',\r
+       numpad3: '숫자 패드 3 키',\r
+       numpad4: '숫자 패드 4 키',\r
+       numpad5: '숫자 패드 5 키',\r
+       numpad6: '숫자 패드 6 키',\r
+       numpad7: '숫자 패드 7 키',\r
+       numpad8: '숫자 패드 8 키',\r
+       numpad9: '숫자 패드 9 키',\r
+       multiply: '곱셈(*) 키',\r
+       add: '덧셈(+) 키',\r
+       subtract: '뺄셈(-) 키',\r
+       decimalPoint: '온점(.) 키',\r
+       divide: '나눗셈(/) 키',\r
+       f1: 'F1 키',\r
+       f2: 'F2 키',\r
+       f3: 'F3 키',\r
+       f4: 'F4 키',\r
+       f5: 'F5 키',\r
+       f6: 'F6 키',\r
+       f7: 'F7 키',\r
+       f8: 'F8 키',\r
+       f9: 'F9 키',\r
+       f10: 'F10 키',\r
+       f11: 'F11 키',\r
+       f12: 'F12 키',\r
+       numLock: 'Num Lock 키',\r
+       scrollLock: 'Scroll Lock 키',\r
+       semiColon: '세미콜론(;) 키',\r
+       equalSign: '등호(=) 키',\r
+       comma: '쉼표(,) 키',\r
+       dash: '대시(-) 키',\r
+       period: '온점(.) 키',\r
+       forwardSlash: '슬래시(/) 키',\r
+       graveAccent: '억음 악센트(`) 키',\r
+       openBracket: '브라켓 열기([) 키',\r
+       backSlash: '역슬래시(\\\\) 키',\r
+       closeBracket: '브라켓 닫기(]) 키',\r
+       singleQuote: '외 따옴표(\') 키'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ku.js b/sources/plugins/a11yhelp/dialogs/lang/ku.js
new file mode 100644 (file)
index 0000000..3f044a2
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ku', {\r
+       title: 'ڕێنمای لەبەردەستدابوون',\r
+       contents: 'پێکهاتەی یارمەتی. کلیك ESC بۆ داخستنی ئەم دیالۆگه.',\r
+       legend: [\r
+               {\r
+               name: 'گشتی',\r
+               items: [\r
+                       {\r
+                       name: 'تووڵامرازی دەستكاریكەر',\r
+                       legend: 'کلیك ${toolbarFocus} بۆ ڕابەری تووڵامراز. بۆ گواستنەوەی پێشوو داهاتووی گرووپی تووڵامرازی داگرتنی کلیلی TAB لەگەڵ‌ SHIFT+TAB. بۆ گواستنەوەی پێشوو داهاتووی دووگمەی تووڵامرازی لەڕێی کلیلی تیری دەستی ڕاست یان کلیلی تیری دەستی چەپ. کلیکی کلیلی SPACE یان ENTER بۆ چالاککردنی دووگمەی تووڵامراز.'\r
+               },\r
+\r
+                       {\r
+                       name: 'دیالۆگی دەستكاریكەر',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'\r
+               },\r
+\r
+                       {\r
+                       name: 'پێڕستی سەرنووسەر',\r
+                       legend: 'کلیك ${contextMenu} یان دوگمەی لیسته‌(Menu) بۆ کردنەوەی لیستەی دەق. بۆ چوونە هەڵبژاردەیەکی تر له‌ لیسته‌ کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوارەوه‌ بۆ چوون بۆ هەڵبژاردەی پێشوو کلیکی کلیلی SHIFT+TAB یان کلیلی تیری ڕوو له‌ سەرەوە. داگرتنی کلیلی SPACE یان ENTER بۆ هەڵبژاردنی هەڵبژاردەی لیسته‌. بۆ کردنەوەی لقی ژێر لیسته‌ لەهەڵبژاردەی لیستە کلیکی کلیلی SPACE یان ENTER یان کلیلی تیری دەستی ڕاست. بۆ گەڕانەوه بۆ سەرەوەی لیسته‌ کلیکی کلیلی ESC یان کلیلی تیری دەستی چەپ. بۆ داخستنی لیستە کلیكی کلیلی ESC بکە.'\r
+               },\r
+\r
+                       {\r
+                       name: 'لیستی سنووقی سەرنووسەر',\r
+                       legend: 'لەناو سنوقی لیست, چۆن بۆ هەڵنبژاردەی لیستێکی تر کلیکی کلیلی TAB یان کلیلی تیری ڕوو لەخوار. چوون بۆ هەڵبژاردەی لیستی پێشوو کلیکی کلیلی SHIFT+TAB یان کلیلی تیری ڕوو لەسەرەوه‌. کلیکی کلیلی SPACE یان ENTER بۆ دیاریکردنی ‌هەڵبژاردەی لیست. کلیکی کلیلی ESC بۆ داخستنی سنوقی لیست.'\r
+               },\r
+\r
+                       {\r
+                       name: 'تووڵامرازی توخم',\r
+                       legend: 'کلیك ${elementsPathFocus} بۆ ڕابەری تووڵامرازی توخمەکان. چوون بۆ دوگمەی توخمێکی تر کلیکی کلیلی TAB یان کلیلی تیری دەستی ڕاست. چوون بۆ دوگمەی توخمی پێشوو کلیلی SHIFT+TAB یان کلیکی کلیلی تیری دەستی چەپ. داگرتنی کلیلی SPACE یان ENTER بۆ دیاریکردنی توخمەکه‌ لەسەرنووسه.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'فەرمانەکان',\r
+               items: [\r
+                       {\r
+                       name: 'پووچکردنەوەی فەرمان',\r
+                       legend: 'کلیك ${undo}'\r
+               },\r
+                       {\r
+                       name: 'هەڵگەڕانەوەی فەرمان',\r
+                       legend: 'کلیك ${redo}'\r
+               },\r
+                       {\r
+                       name: 'فەرمانی دەقی قەڵەو',\r
+                       legend: 'کلیك ${bold}'\r
+               },\r
+                       {\r
+                       name: 'فەرمانی دەقی لار',\r
+                       legend: 'کلیك ${italic}'\r
+               },\r
+                       {\r
+                       name: 'فەرمانی ژێرهێڵ',\r
+                       legend: 'کلیك ${underline}'\r
+               },\r
+                       {\r
+                       name: 'فەرمانی به‌ستەر',\r
+                       legend: 'کلیك ${link}'\r
+               },\r
+                       {\r
+                       name: 'شاردەنەوەی تووڵامراز',\r
+                       legend: 'کلیك ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'چوونەناو سەرنجدانی پێشوی فەرمانی بۆشایی',\r
+                       legend: 'کلیک ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.'\r
+               },\r
+                       {\r
+                       name: 'چوونەناو سەرنجدانی داهاتووی فەرمانی بۆشایی',\r
+                       legend: 'کلیک ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.'\r
+               },\r
+                       {\r
+                       name: 'دەستپێگەیشتنی یارمەتی',\r
+                       legend: 'کلیك ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Left Arrow',\r
+       upArrow: 'Up Arrow',\r
+       rightArrow: 'Right Arrow',\r
+       downArrow: 'Down Arrow',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'پەنجەرەی چەپ',\r
+       rightWindowKey: 'پەنجەرەی ڕاست',\r
+       selectKey: 'Select',\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: '1',\r
+       numpad2: '2',\r
+       numpad3: '3',\r
+       numpad4: '4',\r
+       numpad5: '5',\r
+       numpad6: '6',\r
+       numpad7: '7',\r
+       numpad8: '8',\r
+       numpad9: '9',\r
+       multiply: '*',\r
+       add: '+',\r
+       subtract: '-',\r
+       decimalPoint: '.',\r
+       divide: '/',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: ';',\r
+       equalSign: '=',\r
+       comma: ',',\r
+       dash: '-',\r
+       period: '.',\r
+       forwardSlash: '/',\r
+       graveAccent: '`',\r
+       openBracket: '[',\r
+       backSlash: '\\\\',\r
+       closeBracket: '}',\r
+       singleQuote: '\''\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/lt.js b/sources/plugins/a11yhelp/dialogs/lang/lt.js
new file mode 100644 (file)
index 0000000..c27e3ba
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'lt', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Bendros savybės',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/lv.js b/sources/plugins/a11yhelp/dialogs/lang/lv.js
new file mode 100644 (file)
index 0000000..aac4129
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'lv', {\r
+       title: 'Pieejamības instrukcija',\r
+       contents: 'Palīdzības saturs. Lai aizvērtu ciet šo dialogu nospiediet ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Galvenais',\r
+               items: [\r
+                       {\r
+                       name: 'Redaktora rīkjosla',\r
+                       legend: 'Nospiediet ${toolbarFocus} lai pārvietotos uz rīkjoslu. Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas grupu izmantojiet pogu TAB un SHIFT+TAB. Lai pārvietotos uz nākošo vai iepriekšējo rīkjoslas pogu izmantojiet Kreiso vai Labo bultiņu. Nospiediet Atstarpi vai ENTER lai aktivizētu rīkjosla pogu.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktora dialoga  logs',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktora satura izvēle',\r
+                       legend: 'Nospiediet ${contextMenu} vai APPLICATION KEY lai atvērtu satura izvēlni. Lai pārvietotos uz nākošo izvēlnes opciju izmantojiet pogu TAB vai pogu Bultiņu uz leju. Lai pārvietotos uz iepriekšējo opciju izmantojiet  SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvelētos izvēlnes opciju. Atveriet tekošajā opcija apakšizvēlni ar SAPCE vai ENTER ka ari to var izdarīt ar Labo bultiņu. Lai atgrieztos atpakaļ uz sakuma izvēlni nospiediet ESC vai Kreiso bultiņu. Lai aizvērtu ciet izvēlnes saturu nospiediet ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktora saraksta lauks',\r
+                       legend: 'Saraksta laukā, lai pārvietotos uz nākošo saraksta elementu nospiediet TAB vai pogu Bultiņa uz leju. Lai pārvietotos uz iepriekšējo saraksta elementu nospiediet SHIFT+TAB vai pogu Bultiņa uz augšu. Nospiediet SPACE vai ENTER lai izvēlētos saraksta opcijas. Nospiediet ESC lai aizvērtu saraksta lauku.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Redaktora elementa ceļa josla',\r
+                       legend: 'Nospiediet ${elementsPathFocus} lai pārvietotos uz elementa ceļa joslu. Lai pārvietotos uz nākošo elementa pogu izmantojiet TAB vai Labo bultiņu. Lai pārvietotos uz iepriekšējo elementa pogu izmantojiet SHIFT+TAB vai Kreiso bultiņu. Nospiediet SPACE vai ENTER lai izvēlētos elementu redaktorā.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komandas',\r
+               items: [\r
+                       {\r
+                       name: 'Komanda atcelt darbību',\r
+                       legend: 'Nospiediet ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Komanda atkārtot darbību',\r
+                       legend: 'Nospiediet ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Treknraksta komanda',\r
+                       legend: 'Nospiediet ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursīva komanda',\r
+                       legend: 'Nospiediet ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Apakšsvītras komanda ',\r
+                       legend: 'Nospiediet ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Hipersaites komanda',\r
+                       legend: 'Nospiediet ${link}'\r
+               },\r
+                       {\r
+                       name: 'Rīkjoslas aizvēršanas komanda',\r
+                       legend: 'Nospiediet ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Piekļūt iepriekšējai fokusa vietas komandai',\r
+                       legend: 'Nospiediet ${accessPreviousSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pirms kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām.'\r
+               },\r
+                       {\r
+                       name: 'Piekļūt nākošā fokusa apgabala komandai',\r
+                       legend: 'Nospiediet ${accessNextSpace} lai piekļūtu tuvākajai nepieejamajai fokusa vietai pēc kursora. Piemēram: diviem blakus esošiem līnijas HR elementiem. Atkārtojiet taustiņu kombināciju lai piekļūtu pie tālākām vietām.'\r
+               },\r
+                       {\r
+                       name: 'Pieejamības palīdzība',\r
+                       legend: 'Nospiediet ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/mk.js b/sources/plugins/a11yhelp/dialogs/lang/mk.js
new file mode 100644 (file)
index 0000000..8316358
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'mk', {\r
+       title: 'Инструкции за пристапност',\r
+       contents: 'Содржина на делот за помош. За да го затворите овој дијалог притиснете ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Општо',\r
+               items: [\r
+                       {\r
+                       name: 'Мени за уредувачот',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Дијалот за едиторот',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Контекст-мени на уредувачот',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Наредби',\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Пауза',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Up',\r
+       leftArrow: 'Стрелка лево',\r
+       upArrow: 'Стрелка горе',\r
+       rightArrow: 'Стрелка десно',\r
+       downArrow: 'Стрелка доле',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Лево Windows копче',\r
+       rightWindowKey: 'Десно Windows копче',\r
+       selectKey: 'Select копче',\r
+       numpad0: 'Нум. таст. 0',\r
+       numpad1: 'Нум. таст. 1',\r
+       numpad2: 'Нум. таст. 2',\r
+       numpad3: 'Нум. таст. 3',\r
+       numpad4: 'Нум. таст. 4',\r
+       numpad5: 'Нум. таст. 5',\r
+       numpad6: 'Нум. таст. 6',\r
+       numpad7: 'Нум. таст. 7',\r
+       numpad8: 'Нум. таст. 8',\r
+       numpad9: 'Нум. таст. 9',\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/mn.js b/sources/plugins/a11yhelp/dialogs/lang/mn.js
new file mode 100644 (file)
index 0000000..eb11634
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'mn', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Ерөнхий',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/nb.js b/sources/plugins/a11yhelp/dialogs/lang/nb.js
new file mode 100644 (file)
index 0000000..ccfeb66
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'nb', {\r
+       title: 'Instruksjoner for tilgjengelighet',\r
+       contents: 'Innhold for hjelp. Trykk ESC for å lukke denne dialogen.',\r
+       legend: [\r
+               {\r
+               name: 'Generelt',\r
+               items: [\r
+                       {\r
+                       name: 'Verktøylinje for editor',\r
+                       legend: 'Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT+TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialog for editor',\r
+                       legend:\r
+                               'Mens du er i en dialog, trykk TAB for å navigere til neste dialogelement, trykk SHIFT+TAB for å flytte til forrige dialogelement, trykk ENTER for å akseptere dialogen, trykk ESC for å avbryte dialogen. Når en dialog har flere faner, kan fanelisten nås med enten ALT+F10 eller med TAB. Når fanelisten er fokusert, går man til neste og forrige fane med henholdsvis HØYRE og VENSTRE PILTAST.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Kontekstmeny for editor',\r
+                       legend: 'Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Listeboks for editor',\r
+                       legend: 'I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Verktøylinje for elementsti',\r
+                       legend: 'Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Hurtigtaster',\r
+               items: [\r
+                       {\r
+                       name: 'Angre',\r
+                       legend: 'Trykk ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Gjør om',\r
+                       legend: 'Trykk ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Fet tekst',\r
+                       legend: 'Trykk ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursiv tekst',\r
+                       legend: 'Trykk ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Understreking',\r
+                       legend: 'Trykk ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Lenke',\r
+                       legend: 'Trykk ${link}'\r
+               },\r
+                       {\r
+                       name: 'Skjul verktøylinje',\r
+                       legend: 'Trykk ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Gå til forrige fokusområde',\r
+                       legend: 'Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.'\r
+               },\r
+                       {\r
+                       name: 'Gå til neste fokusområde',\r
+                       legend: 'Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.'\r
+               },\r
+                       {\r
+                       name: 'Hjelp for tilgjengelighet',\r
+                       legend: 'Trykk ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulator',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Venstre piltast',\r
+       upArrow: 'Opp-piltast',\r
+       rightArrow: 'Høyre piltast',\r
+       downArrow: 'Ned-piltast',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Venstre Windows-tast',\r
+       rightWindowKey: 'Høyre Windows-tast',\r
+       selectKey: 'Velg nøkkel',\r
+       numpad0: 'Numerisk tastatur 0',\r
+       numpad1: 'Numerisk tastatur 1',\r
+       numpad2: 'Numerisk tastatur 2',\r
+       numpad3: 'Numerisk tastatur 3',\r
+       numpad4: 'Numerisk tastatur 4',\r
+       numpad5: 'Numerisk tastatur 5',\r
+       numpad6: 'Numerisk tastatur 6',\r
+       numpad7: 'Numerisk tastatur 7',\r
+       numpad8: 'Numerisk tastatur 8',\r
+       numpad9: 'Numerisk tastatur 9',\r
+       multiply: 'Multipliser',\r
+       add: 'Legg til',\r
+       subtract: 'Trekk fra',\r
+       decimalPoint: 'Desimaltegn',\r
+       divide: 'Divider',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Likhetstegn',\r
+       comma: 'Komma',\r
+       dash: 'Bindestrek',\r
+       period: 'Punktum',\r
+       forwardSlash: 'Forover skråstrek',\r
+       graveAccent: 'Grav aksent',\r
+       openBracket: 'Åpne parentes',\r
+       backSlash: 'Bakover skråstrek',\r
+       closeBracket: 'Lukk parentes',\r
+       singleQuote: 'Enkelt sitattegn'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/nl.js b/sources/plugins/a11yhelp/dialogs/lang/nl.js
new file mode 100644 (file)
index 0000000..00d53ea
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'nl', {\r
+       title: 'Toegankelijkheidsinstructies',\r
+       contents: 'Help-inhoud. Druk op ESC om dit dialoog te sluiten.',\r
+       legend: [\r
+               {\r
+               name: 'Algemeen',\r
+               items: [\r
+                       {\r
+                       name: 'Werkbalk tekstverwerker',\r
+                       legend: 'Druk op ${toolbarFocus} om naar de werkbalk te navigeren. Om te schakelen naar de volgende en vorige werkbalkgroep, gebruik TAB en SHIFT+TAB. Om te schakelen naar de volgende en vorige werkbalkknop, gebruik de PIJL RECHTS en PIJL LINKS. Druk op SPATIE of ENTER om een werkbalkknop te activeren.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialoog tekstverwerker',\r
+                       legend:\r
+                               'In een dialoogvenster, druk op TAB om te navigeren naar het volgende veld. Druk op SHIFT+TAB om naar het vorige veld te navigeren. Druk op ENTER om het dialoogvenster te verzenden. Druk op ESC om het dialoogvenster te sluiten. Bij dialoogvensters met meerdere tabbladen kan de tabset bereikt worden met ALT+F10 of met TAB als onderdeel van de tabvolgorde in het dialoogvenster. Als de tabset focus heeft, kun je schakalen naar het volgende en vorige tabblad met respectievelijk PIJL RECHTS en PIJL LINKS.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Contextmenu tekstverwerker',\r
+                       legend: 'Druk op ${contextMenu} of APPLICATION KEY om het contextmenu te openen. Schakel naar de volgende menuoptie met TAB of PIJL OMLAAG. Schakel naar de vorige menuoptie met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om een menuoptie te selecteren. Op een submenu van de huidige optie met SPATIE, ENTER of PIJL RECHTS. Ga terug naar de bovenliggende menuoptie met ESC of PIJL LINKS. Sluit het contextmenu met ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Keuzelijst tekstverwerker',\r
+                       legend: 'In een keuzelijst, schakel naar het volgende item met TAB of PIJL OMLAAG. Schakel naar het vorige item met SHIFT+TAB of PIJL OMHOOG. Druk op SPATIE of ENTER om het item te selecteren. Druk op ESC om de keuzelijst te sluiten.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Elementenpad werkbalk tekstverwerker',\r
+                       legend: 'Druk op ${elementsPathFocus} om naar het elementenpad te navigeren. Om te schakelen naar het volgende element, gebruik TAB of PIJL RECHTS. Om te schakelen naar het vorige element, gebruik SHIFT+TAB or PIJL LINKS. Druk op SPATIE of ENTER om een element te selecteren in de tekstverwerker.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Opdrachten',\r
+               items: [\r
+                       {\r
+                       name: 'Ongedaan maken opdracht',\r
+                       legend: 'Druk op ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Opnieuw uitvoeren opdracht',\r
+                       legend: 'Druk op ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Vetgedrukt opdracht',\r
+                       legend: 'Druk op ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Cursief opdracht',\r
+                       legend: 'Druk op ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Onderstrepen opdracht',\r
+                       legend: 'Druk op ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link opdracht',\r
+                       legend: 'Druk op ${link}'\r
+               },\r
+                       {\r
+                       name: 'Werkbalk inklappen opdracht',\r
+                       legend: 'Druk op ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Ga naar vorige focus spatie commando',\r
+                       legend: 'Druk ${accessPreviousSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie voor de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken.'\r
+               },\r
+                       {\r
+                       name: 'Ga naar volgende focus spatie commando',\r
+                       legend: 'Druk ${accessNextSpace} om toegang te verkrijgen tot de dichtstbijzijnde onbereikbare focus spatie na de caret, bijvoorbeeld: twee aangrenzende HR elementen. Herhaal de toetscombinatie om de verste focus spatie te bereiken.'\r
+               },\r
+                       {\r
+                       name: 'Toegankelijkheidshulp',\r
+                       legend: 'Druk op ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Pijl naar links',\r
+       upArrow: 'Pijl omhoog',\r
+       rightArrow: 'Pijl naar rechts',\r
+       downArrow: 'Pijl naar beneden',\r
+       insert: 'Invoegen',\r
+       leftWindowKey: 'Linker Windows-toets',\r
+       rightWindowKey: 'Rechter Windows-toets',\r
+       selectKey: 'Selecteer toets',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Vermenigvuldigen',\r
+       add: 'Toevoegen',\r
+       subtract: 'Aftrekken',\r
+       decimalPoint: 'Decimaalteken',\r
+       divide: 'Delen',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Puntkomma',\r
+       equalSign: 'Is gelijk-teken',\r
+       comma: 'Komma',\r
+       dash: 'Koppelteken',\r
+       period: 'Punt',\r
+       forwardSlash: 'Slash',\r
+       graveAccent: 'Accent grave',\r
+       openBracket: 'Vierkant haakje openen',\r
+       backSlash: 'Backslash',\r
+       closeBracket: 'Vierkant haakje sluiten',\r
+       singleQuote: 'Apostrof'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/no.js b/sources/plugins/a11yhelp/dialogs/lang/no.js
new file mode 100644 (file)
index 0000000..4402ddf
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'no', {\r
+       title: 'Instruksjoner for tilgjengelighet',\r
+       contents: 'Innhold for hjelp. Trykk ESC for å lukke denne dialogen.',\r
+       legend: [\r
+               {\r
+               name: 'Generelt',\r
+               items: [\r
+                       {\r
+                       name: 'Verktøylinje for editor',\r
+                       legend: 'Trykk ${toolbarFocus} for å navigere til verktøylinjen. Flytt til neste og forrige verktøylinjegruppe med TAB og SHIFT+TAB. Flytt til neste og forrige verktøylinjeknapp med HØYRE PILTAST og VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å aktivere verktøylinjeknappen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialog for editor',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Kontekstmeny for editor',\r
+                       legend: 'Trykk ${contextMenu} eller MENYKNAPP for å åpne kontekstmeny. Gå til neste alternativ i menyen med TAB eller PILTAST NED. Gå til forrige alternativ med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge menyalternativet. Åpne undermenyen på valgt alternativ med MELLOMROM eller ENTER eller HØYRE PILTAST. Gå tilbake til overordnet menyelement med ESC eller VENSTRE PILTAST. Lukk kontekstmenyen med ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Listeboks for editor',\r
+                       legend: 'I en listeboks, gå til neste alternativ i listen med TAB eller PILTAST NED. Gå til forrige alternativ i listen med SHIFT+TAB eller PILTAST OPP. Trykk MELLOMROM eller ENTER for å velge alternativet i listen. Trykk ESC for å lukke listeboksen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Verktøylinje for elementsti',\r
+                       legend: 'Trykk ${elementsPathFocus} for å navigere til verktøylinjen som viser elementsti. Gå til neste elementknapp med TAB eller HØYRE PILTAST. Gå til forrige elementknapp med SHIFT+TAB eller VENSTRE PILTAST. Trykk MELLOMROM eller ENTER for å velge elementet i editoren.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Kommandoer',\r
+               items: [\r
+                       {\r
+                       name: 'Angre',\r
+                       legend: 'Trykk ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Gjør om',\r
+                       legend: 'Trykk ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Fet tekst',\r
+                       legend: 'Trykk ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kursiv tekst',\r
+                       legend: 'Trykk ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Understreking',\r
+                       legend: 'Trykk ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Link',\r
+                       legend: 'Trykk ${link}'\r
+               },\r
+                       {\r
+                       name: 'Skjul verktøylinje',\r
+                       legend: 'Trykk ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Gå til forrige fokusområde',\r
+                       legend: 'Trykk ${accessPreviousSpace} for å komme til nærmeste fokusområde før skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.'\r
+               },\r
+                       {\r
+                       name: 'Gå til neste fokusområde',\r
+                       legend: 'Trykk ${accessNextSpace} for å komme til nærmeste fokusområde etter skrivemarkøren som ikke kan nås på vanlig måte, for eksempel to tilstøtende HR-elementer. Gjenta tastekombinasjonen for å komme til fokusområder lenger unna i dokumentet.'\r
+               },\r
+                       {\r
+                       name: 'Hjelp for tilgjengelighet',\r
+                       legend: 'Trykk ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/oc.js b/sources/plugins/a11yhelp/dialogs/lang/oc.js
new file mode 100644 (file)
index 0000000..8df209d
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'oc', {\r
+       title: 'Instruccions d\'accessibilitat',\r
+       contents: 'Contengut de l\'ajuda. Per tampar aquesta fenèstra, quichatz sus la tòca Escap.',\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Barra d\'aisinas de l\'editor',\r
+                       legend: 'Quichar sus ${toolbarFocus} per accedir a la barra d\'aisinas. Se desplaçar cap al groupe seguent o precedent de la barra d\'aisinas amb las tòcas Tab e Maj+Tab. Se desplaçar cap al boton seguent o precedent de la barra d\'aisinas amb las tòcas Sageta dreita e Sageta esquèrra. Quichar sus la barra d\'espaci o la tòca Entrada per activer lo boton de barra d\'aisinas.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Fenèstra de l\'editor',\r
+                       legend:\r
+                               'Dins una bóstia de dialòg, quichar sus Tab per passar a l\'element seguent, quichar sus Maj+Tab per passar a l\'element precedent, quichar sus Entrada per validar, quichar sus Escap per anullar. Quand una bóstia de dialòg possedís des onglets, la lista pòt èsser atenta amb Alt+F10 o amb Tab. Dins la lista dels onglets, se desplaçar cap al seguent e lo precedent amb las tòcas Sageta dreita e Sageta esquèrra respectivament.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menú contextual de l\'editor',\r
+                       legend: 'Quichar sus ${contextMenu} o sus la tòca Menú per dobrir lo menú contextual. Se desplaçar ensuite cap a l\'opcion seguenta del menú amb las tòcas Tab o Sageta bas. Se desplaçar cap a l\'opcion precedenta amb las tòcas Maj+Tab o Sageta naut. Quichar sus la barra d\'espaci o la tòca Entrada per seleccionar l\'opcion del menu. Quichar sus la barra d\'espaci, la tòca Entrada o Sageta dreita per dobrir lo sosmenú de l\'opcion seleccionada. Tornar a l\'element de menú parent amb la tòca Escap o Sageta esquèrra. Tampar lo menú contextual amb Escap.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Zòna de lista de l\'editor',\r
+                       legend: 'Dins una lista en menú desenrotlant, se desplaçar cap a l\'element seguent de la lista amb las tòcas Tab o Sageta bas. Se desplaçar cap a l\'element precedent de la lista amb las tòcas Maj+Tab o Sageta naut. Quichar sus la barra d\'espaci o sus Entrada per seleccionar l\'opcion dins la lista. Quichar sus Escap per tampar lo menú desenrotlant.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barra del camin d\'elements de l\'editor',\r
+                       legend: 'Quichar sus ${elementsPathFocus} per naviguer cap a la barra del fial d\'Ariana dels elements. Se desplaçar cap al boton de l\'element seguent amb las tòcas Tab o Sageta dreita. Se desplaçar cap al boton precedent amb las tòcas Maj+Tab o Sageta esquèrra. Quichar sus la barra d\'espaci o sus Entrada per seleccionar l\'element dins l\'editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comandas',\r
+               items: [\r
+                       {\r
+                       name: 'Anullar la comanda',\r
+                       legend: 'Quichar sus ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Comanda restablir',\r
+                       legend: 'Quichar sus ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Comanda gras',\r
+                       legend: 'Quichar sus ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Comanda italica',\r
+                       legend: 'Quichar sus ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Comanda solinhat',\r
+                       legend: 'Quichar sus ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Comanda ligam',\r
+                       legend: 'Quichar sus ${link}'\r
+               },\r
+                       {\r
+                       name: 'Comanda enrotlar la barra d\'aisinas',\r
+                       legend: 'Quichar sus ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Comanda d\'accès a l\'element seleccionable precedent',\r
+                       legend: 'Quichar sus ${accessNextSpace} per accedir a l\'element seleccionable inategnible lo mai pròche abans lo cursor, per exemple : doas linhas orizontalas adjacentas. Repetir la combinason de tòcas per aténher los elements seleccionables precedents.'\r
+               },\r
+                       {\r
+                       name: 'Comanda d\'accès a l\'element seleccionable seguent',\r
+                       legend: 'Quichar sus ${accessNextSpace} per accedir a l\'element seleccionable inatenhible lo mai pròche aprèp lo cursor, per exemple : doas linhas orizontalas adjacentas. Repetir la combinason de tòcas per aténher los elements seleccionables seguents.'\r
+               },\r
+                       {\r
+                       name: ' Ajuda sus l\'accessibilitat',\r
+                       legend: 'Quichar sus ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tabulacion',\r
+       pause: 'Pausa',\r
+       capslock: 'Verr. Maj.',\r
+       escape: 'Escap',\r
+       pageUp: 'Pagina superiora',\r
+       pageDown: 'Pagina seguenta',\r
+       leftArrow: 'Sageta esquèrra',\r
+       upArrow: 'Sageta naut',\r
+       rightArrow: 'Sageta dreita',\r
+       downArrow: 'Sageta bassa',\r
+       insert: 'Inser',\r
+       leftWindowKey: 'Tòca Windows esquèrra',\r
+       rightWindowKey: 'Tòca Windows dreita',\r
+       selectKey: 'Tòca Seleccionar',\r
+       numpad0: '0 del pavat numeric',\r
+       numpad1: '1 del pavat numeric',\r
+       numpad2: '2 del pavat numeric',\r
+       numpad3: '3 del pavat numeric',\r
+       numpad4: '4 del pavat numeric',\r
+       numpad5: '5 del pavat numeric',\r
+       numpad6: '6 del pavat numeric',\r
+       numpad7: '7 del pavat numeric',\r
+       numpad8: 'Pavat numeric 8',\r
+       numpad9: '9 del pavat numeric',\r
+       multiply: 'Multiplicar',\r
+       add: 'Plus',\r
+       subtract: 'Mens',\r
+       decimalPoint: 'Punt decimal',\r
+       divide: 'Devesir',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Verr. Num.',\r
+       scrollLock: 'Arrèst desfil.',\r
+       semiColon: 'Punt-virgula',\r
+       equalSign: 'Signe egal',\r
+       comma: 'Virgula',\r
+       dash: 'Jonhent',\r
+       period: 'Punt',\r
+       forwardSlash: 'Barra oblica',\r
+       graveAccent: 'Accent grèu',\r
+       openBracket: 'Parentèsi dobèrta',\r
+       backSlash: 'Barra oblica invèrsa',\r
+       closeBracket: 'Parentèsi tampanta',\r
+       singleQuote: 'Apostròfa'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/pl.js b/sources/plugins/a11yhelp/dialogs/lang/pl.js
new file mode 100644 (file)
index 0000000..825ea08
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'pl', {\r
+       title: 'Instrukcje dotyczące dostępności',\r
+       contents: 'Zawartość pomocy. Wciśnij ESC, aby zamknąć to okno.',\r
+       legend: [\r
+               {\r
+               name: 'Informacje ogólne',\r
+               items: [\r
+                       {\r
+                       name: 'Pasek narzędzi edytora',\r
+                       legend: 'Naciśnij ${toolbarFocus}, by przejść do paska narzędzi. Przejdź do następnej i poprzedniej grupy narzędzi używając TAB oraz SHIFT+TAB. Przejdź do następnego i poprzedniego przycisku paska narzędzi za pomocą STRZAŁKI W PRAWO lub STRZAŁKI W LEWO. Naciśnij SPACJĘ lub ENTER by aktywować przycisk paska narzędzi.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Okno dialogowe edytora',\r
+                       legend:\r
+                               'Wewnątrz okna dialogowego naciśnij TAB, by przejść do kolejnego elementu tego okna lub SHIFT+TAB, by przejść do poprzedniego elementu okna. Naciśnij ENTER w celu zatwierdzenia opcji okna dialogowego lub ESC w celu anulowania zmian. Jeśli okno dialogowe ma kilka zakładek, do listy zakładek można przejść za pomocą ALT+F10 lub TAB. Gdy lista zakładek jest aktywna, możesz przejść do kolejnej i poprzedniej zakładki za pomocą STRZAŁKI W PRAWO i STRZAŁKI W LEWO.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu kontekstowe edytora',\r
+                       legend: 'Wciśnij ${contextMenu} lub PRZYCISK APLIKACJI aby otworzyć menu kontekstowe. Przejdź do następnej pozycji menu wciskając TAB lub STRZAŁKĘ W DÓŁ. Przejdź do poprzedniej pozycji menu wciskając SHIFT + TAB lub STRZAŁKĘ W GÓRĘ. Wciśnij SPACJĘ lub ENTER aby wygrać pozycję menu. Otwórz pod-menu obecnej pozycji wciskając SPACJĘ lub ENTER lub STRZAŁKĘ W PRAWO. Wróć do pozycji nadrzędnego menu wciskając ESC lub STRZAŁKĘ W LEWO. Zamknij menu wciskając ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Lista w edytorze',\r
+                       legend: 'Wewnątrz listy przejdź do kolejnego elementu listy za pomocą przycisku TAB lub STRZAŁKI W DÓŁ. Przejdź do poprzedniego elementu listy za pomocą SHIFT+TAB lub STRZAŁKI W GÓRĘ. Naciśnij SPACJĘ lub ENTER w celu wybrania opcji z listy. Naciśnij ESC, by zamknąć listę.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Pasek ścieżki elementów edytora',\r
+                       legend: 'Naciśnij ${elementsPathFocus} w celu przejścia do paska ścieżki elementów edytora. W celu przejścia do kolejnego elementu naciśnij klawisz TAB lub STRZAŁKI W PRAWO. W celu przejścia do poprzedniego elementu naciśnij klawisze SHIFT+TAB lub STRZAŁKI W LEWO. By wybrać element w edytorze, użyj klawisza SPACJI lub ENTER.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Polecenia',\r
+               items: [\r
+                       {\r
+                       name: 'Polecenie Cofnij',\r
+                       legend: 'Naciśnij ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie Ponów',\r
+                       legend: 'Naciśnij ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie Pogrubienie',\r
+                       legend: 'Naciśnij ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie Kursywa',\r
+                       legend: 'Naciśnij ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie Podkreślenie',\r
+                       legend: 'Naciśnij ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie Wstaw/ edytuj odnośnik',\r
+                       legend: 'Naciśnij ${link}'\r
+               },\r
+                       {\r
+                       name: 'Polecenie schowaj pasek narzędzi',\r
+                       legend: 'Naciśnij ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: 'Pomoc dotycząca dostępności',\r
+                       legend: 'Naciśnij ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Strzałka w lewo',\r
+       upArrow: 'Strzałka w górę',\r
+       rightArrow: 'Strzałka w prawo',\r
+       downArrow: 'Strzałka w dół',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Lewy klawisz Windows',\r
+       rightWindowKey: 'Prawy klawisz Windows',\r
+       selectKey: 'Klawisz wyboru',\r
+       numpad0: 'Klawisz 0 na klawiaturze numerycznej',\r
+       numpad1: 'Klawisz 1 na klawiaturze numerycznej',\r
+       numpad2: 'Klawisz 2 na klawiaturze numerycznej',\r
+       numpad3: 'Klawisz 3 na klawiaturze numerycznej',\r
+       numpad4: 'Klawisz 4 na klawiaturze numerycznej',\r
+       numpad5: 'Klawisz 5 na klawiaturze numerycznej',\r
+       numpad6: 'Klawisz 6 na klawiaturze numerycznej',\r
+       numpad7: 'Klawisz 7 na klawiaturze numerycznej',\r
+       numpad8: 'Klawisz 8 na klawiaturze numerycznej',\r
+       numpad9: 'Klawisz 9 na klawiaturze numerycznej',\r
+       multiply: 'Przemnóż',\r
+       add: 'Plus',\r
+       subtract: 'Minus',\r
+       decimalPoint: 'Separator dziesiętny',\r
+       divide: 'Podziel',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Średnik',\r
+       equalSign: 'Znak równości',\r
+       comma: 'Przecinek',\r
+       dash: 'Pauza',\r
+       period: 'Kropka',\r
+       forwardSlash: 'Ukośnik prawy',\r
+       graveAccent: 'Akcent słaby',\r
+       openBracket: 'Nawias kwadratowy otwierający',\r
+       backSlash: 'Ukośnik lewy',\r
+       closeBracket: 'Nawias kwadratowy zamykający',\r
+       singleQuote: 'Apostrof'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/pt-br.js b/sources/plugins/a11yhelp/dialogs/lang/pt-br.js
new file mode 100644 (file)
index 0000000..030df98
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'pt-br', {\r
+       title: 'Instruções de Acessibilidade',\r
+       contents: 'Conteúdo da Ajuda. Para fechar este diálogo pressione ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Geral',\r
+               items: [\r
+                       {\r
+                       name: 'Barra de Ferramentas do Editor',\r
+                       legend: 'Pressione ${toolbarFocus} para navegar para a barra de ferramentas. Mova para o anterior ou próximo grupo de ferramentas com TAB e SHIFT+TAB. Mova para o anterior ou próximo botão com SETA PARA DIREITA or SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para ativar o botão da barra de ferramentas.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Diálogo do Editor',\r
+                       legend:\r
+                               'Dentro de um diálogo, pressione TAB para navegar para o próximo elemento. Pressione SHIFT+TAB para mover para o elemento anterior. Pressione ENTER ara enviar o diálogo. pressione ESC para cancelar o diálogo. Quando um diálogo tem múltiplas abas, a lista de abas pode ser acessada com ALT+F10 ou TAB, como parte da ordem de tabulação do diálogo. Com a lista de abas em foco, mova para a próxima aba e para a aba anterior com a SETA DIREITA ou SETA ESQUERDA, respectivamente.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu de Contexto do Editor',\r
+                       legend: 'Pressione ${contextMenu} ou TECLA DE MENU para abrir o menu de contexto, então mova para a próxima opção com TAB ou SETA PARA BAIXO. Mova para a anterior com SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu. Abra o submenu da opção atual com ESPAÇO ou ENTER ou SETA PARA DIREITA. Volte para o menu pai com ESC ou SETA PARA ESQUERDA. Feche o menu de contexto com ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Caixa de Lista do Editor',\r
+                       legend: 'Dentro de uma caixa de lista, mova para o próximo item com TAB ou SETA PARA BAIXO. Mova para o item anterior com SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar uma opção na lista. Pressione ESC para fechar a caixa de lista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Barra de Caminho do Elementos do Editor',\r
+                       legend: 'Pressione ${elementsPathFocus} para a barra de caminho dos elementos. Mova para o próximo botão de elemento com TAB ou SETA PARA DIREITA. Mova para o botão anterior com SHIFT+TAB ou SETA PARA ESQUERDA. Pressione ESPAÇO ou ENTER para selecionar o elemento no editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comandos',\r
+               items: [\r
+                       {\r
+                       name: ' Comando Desfazer',\r
+                       legend: 'Pressione ${undo}'\r
+               },\r
+                       {\r
+                       name: ' Comando Refazer',\r
+                       legend: 'Pressione ${redo}'\r
+               },\r
+                       {\r
+                       name: ' Comando Negrito',\r
+                       legend: 'Pressione ${bold}'\r
+               },\r
+                       {\r
+                       name: ' Comando Itálico',\r
+                       legend: 'Pressione ${italic}'\r
+               },\r
+                       {\r
+                       name: ' Comando Sublinhado',\r
+                       legend: 'Pressione ${underline}'\r
+               },\r
+                       {\r
+                       name: ' Comando Link',\r
+                       legend: 'Pressione ${link}'\r
+               },\r
+                       {\r
+                       name: ' Comando Fechar Barra de Ferramentas',\r
+                       legend: 'Pressione ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Acessar o comando anterior de spaço de foco',\r
+                       legend: 'Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo antes do cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes.'\r
+               },\r
+                       {\r
+                       name: 'Acessar próximo fomando de spaço de foco',\r
+                       legend: 'Pressione ${accessNextSpace} para acessar o espaço de foco não alcançável mais próximo após o cursor, por exemplo: dois elementos HR adjacentes. Repita a combinação de teclas para alcançar espaços de foco distantes.'\r
+               },\r
+                       {\r
+                       name: ' Ajuda de Acessibilidade',\r
+                       legend: 'Pressione ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tecla Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Seta à Esquerda',\r
+       upArrow: 'Seta à Cima',\r
+       rightArrow: 'Seta à Direita',\r
+       downArrow: 'Seta à Baixo',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Tecla do Windows Esquerda',\r
+       rightWindowKey: 'Tecla do Windows Direita',\r
+       selectKey: 'Tecla Selecionar',\r
+       numpad0: '0 do Teclado Numérico',\r
+       numpad1: '1 do Teclado Numérico',\r
+       numpad2: '2 do Teclado Numérico',\r
+       numpad3: '3 do Teclado Numérico',\r
+       numpad4: '4 do Teclado Numérico',\r
+       numpad5: '5 do Teclado Numérico',\r
+       numpad6: '6 do Teclado Numérico',\r
+       numpad7: '7 do Teclado Numérico',\r
+       numpad8: '8 do Teclado Numérico',\r
+       numpad9: '9 do Teclado Numérico',\r
+       multiply: 'Multiplicar',\r
+       add: 'Mais',\r
+       subtract: 'Subtrair',\r
+       decimalPoint: 'Ponto',\r
+       divide: 'Dividir',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Ponto-e-vírgula',\r
+       equalSign: 'Igual',\r
+       comma: 'Vírgula',\r
+       dash: 'Hífen',\r
+       period: 'Ponto',\r
+       forwardSlash: 'Barra',\r
+       graveAccent: 'Acento Grave',\r
+       openBracket: 'Abrir Conchetes',\r
+       backSlash: 'Contra-barra',\r
+       closeBracket: 'Fechar Colchetes',\r
+       singleQuote: 'Aspas Simples'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/pt.js b/sources/plugins/a11yhelp/dialogs/lang/pt.js
new file mode 100644 (file)
index 0000000..986a377
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'pt', {\r
+       title: 'Instruções de acessibilidade',\r
+       contents: 'Conteúdo de ajuda. Use a tecla ESC para fechar esta janela.',\r
+       legend: [\r
+               {\r
+               name: 'Geral',\r
+               items: [\r
+                       {\r
+                       name: 'Barra de ferramentas do editor',\r
+                       legend: 'Clique em ${toolbarFocus} para navegar na barra de ferramentas. Para navegar entre o grupo da barra de ferramentas anterior e seguinte use TAB e SHIFT+TAB. Para navegar entre o botão da barra de ferramentas seguinte e anterior use a SETA DIREITA ou SETA ESQUERDA. Carregue em ESPAÇO ou ENTER para ativar o botão da barra de ferramentas.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Janela do editor',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Menu de contexto do editor',\r
+                       legend: 'Clique em ${contextMenu} ou TECLA APLICAÇÃO para abrir o menu de contexto. Depois vá para a opção do menu seguinte com TAB ou SETA PARA BAIXO. Vá para a opção anterior com  SHIFT+TAB ou SETA PARA CIMA. Pressione ESPAÇO ou ENTER para selecionar a opção do menu.  Abra o submenu da opção atual com ESPAÇO, ENTER ou SETA DIREITA. GVá para o item do menu parente  com ESC ou SETA ESQUERDA. Feche o menu de contexto com ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor de caixa em lista',\r
+                       legend: 'Dentro de uma lista, para navegar para o item seguinte da lista use TAB ou SETA PARA BAIXO. Para o item anterior da lista use SHIFT+TAB ou SETA PARA BAIXO. Carregue em ESPAÇO ou ENTER para selecionar a opção lista. Carregue em ESC para fechar a caixa da lista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor da barra de caminho dos elementos',\r
+                       legend: 'Clique em ${elementsPathFocus} para navegar na barra de caminho dos elementos. Para o botão do elemento seguinte use TAB ou SETA DIREITA. para o botão anterior use SHIFT+TAB ou SETA ESQUERDA. Carregue em ESPAÇO ou ENTER para selecionar o elemento no editor.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comandos',\r
+               items: [\r
+                       {\r
+                       name: 'Comando de anular',\r
+                       legend: 'Carregar ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Comando de refazer',\r
+                       legend: 'Clique ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Comando de negrito',\r
+                       legend: 'Pressione ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Comando de itálico',\r
+                       legend: 'Pressione ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Comando de sublinhado',\r
+                       legend: 'Pressione ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Comando de hiperligação',\r
+                       legend: 'Pressione ${link}'\r
+               },\r
+                       {\r
+                       name: 'Comando de ocultar barra de ferramentas',\r
+                       legend: 'Pressione ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Aceder ao comando espaço de foco anterior',\r
+                       legend: 'Clique em ${accessPreviousSpace} para aceder ao espaço do focos inalcançável mais perto antes do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes.'\r
+               },\r
+                       {\r
+                       name: 'Acesso comando do espaço focus seguinte',\r
+                       legend: 'Pressione ${accessNextSpace} para aceder ao espaço do focos inalcançável mais perto depois do sinal de omissão, por exemplo: dois elementos HR adjacentes. Repetir a combinação da chave para alcançar os espaços dos focos distantes.'\r
+               },\r
+                       {\r
+                       name: 'Ajuda a acessibilidade',\r
+                       legend: 'Pressione ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pausa',\r
+       capslock: 'Maiúsculas',\r
+       escape: 'Esc',\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Seta esquerda',\r
+       upArrow: 'Seta para cima',\r
+       rightArrow: 'Seta direita',\r
+       downArrow: 'Seta para baixo',\r
+       insert: 'Inserir',\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiplicar',\r
+       add: 'Adicionar',\r
+       subtract: 'Subtrair',\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Separar',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Vírgula',\r
+       dash: 'Cardinal',\r
+       period: 'Ponto',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Acento grave',\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Plica'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ro.js b/sources/plugins/a11yhelp/dialogs/lang/ro.js
new file mode 100644 (file)
index 0000000..a182bbd
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ro', {\r
+       title: 'Instrucțiuni de accesibilitate',\r
+       contents: 'Cuprins. Pentru a închide acest dialog, apăsați tasta ESC.',\r
+       legend: [\r
+               {\r
+               name: 'General',\r
+               items: [\r
+                       {\r
+                       name: 'Editează bara instrumente.',\r
+                       legend: 'Apasă ${toolbarFocus} pentru a naviga prin bara de instrumente. Pentru a te mișca prin grupurile de instrumente folosește tastele TAB și SHIFT+TAB. Pentru a te mișca intre diverse instrumente folosește tastele SĂGEATĂ DREAPTA sau SĂGEATĂ STÂNGA. Apasă butonul SPAȚIU sau ENTER pentru activarea instrumentului.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialog editor',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor meniu contextual',\r
+                       legend: 'Apasă ${contextMenu} sau TASTA MENIU pentru a deschide meniul contextual. Treci la următoarea opțiune din meniu cu TAB sau SĂGEATĂ JOS. Treci la opțiunea anterioară cu  SHIFT+TAB sau SĂGEATĂ SUS. Apasă SPAȚIU sau ENTER pentru a selecta opțiunea din meniu. Deschide sub-meniul opțiunii curente cu SPAȚIU sau ENTER sau SĂGEATĂ DREAPTA. Revino la elementul din meniul părinte cu ESC sau SĂGEATĂ STÂNGA. Închide meniul de context cu ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Casetă Listă',\r
+                       legend: 'În interiorul unei liste, treci la următorull element cu TAB sau SĂGEATĂ JOS. Treci la elementul anterior din listă cu SHIFT+TAB sau SĂGEATĂ SUS. Apasă SPAȚIU sau ENTER pentru a selecta opțiunea din listă. Apasă ESC pentru a închide lista.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Comenzi',\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Apasă ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Comanda precedentă',\r
+                       legend: 'Apasă ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Comanda Îngroșat',\r
+                       legend: 'Apasă ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Comanda Inclinat',\r
+                       legend: 'Apasă ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Comanda Subliniere',\r
+                       legend: 'Apasă ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Comanda Legatură',\r
+                       legend: 'Apasă ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ru.js b/sources/plugins/a11yhelp/dialogs/lang/ru.js
new file mode 100644 (file)
index 0000000..19d502a
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ru', {\r
+       title: 'Горячие клавиши',\r
+       contents: 'Помощь. Для закрытия этого окна нажмите ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Основное',\r
+               items: [\r
+                       {\r
+                       name: 'Панель инструментов',\r
+                       legend: 'Нажмите ${toolbarFocus} для перехода к панели инструментов. Для перемещения между группами панели инструментов используйте TAB и SHIFT+TAB. Для перемещения между кнопками панели иструментов используйте кнопки ВПРАВО или ВЛЕВО. Нажмите ПРОБЕЛ или ENTER для запуска кнопки панели инструментов.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Диалоги',\r
+                       legend:\r
+                               'Внутри диалога, нажмите TAB чтобы перейти к следующему элементу диалога, нажмите SHIFT+TAB чтобы перейти к предыдущему элементу диалога, нажмите ENTER чтобы отправить диалог, нажмите ESC чтобы отменить диалог. Когда диалоговое окно имеет несколько вкладок, получить доступ к панели вкладок как части диалога можно нажатием или сочетания ALT+F10 или TAB, при этом активные элементы диалога будут перебираться с учетом порядка табуляции. При активной панели вкладок, переход к следующей или предыдущей вкладке осуществляется нажатием стрелки "ВПРАВО" или стрелки "ВЛЕВО" соответственно.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Контекстное меню',\r
+                       legend: 'Нажмите ${contextMenu} или клавишу APPLICATION, чтобы открыть контекстное меню. Затем перейдите к следующему пункту меню с помощью TAB или стрелкой "ВНИЗ". Переход к предыдущей опции - SHIFT+TAB или стрелкой "ВВЕРХ". Нажмите SPACE, или ENTER, чтобы задействовать опцию меню. Открыть подменю текущей опции - SPACE или ENTER или стрелкой "ВПРАВО". Возврат к родительскому пункту меню - ESC или стрелкой "ВЛЕВО". Закрытие контекстного меню - ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Редактор списка',\r
+                       legend: 'Внутри окна списка, переход к следующему пункту списка - TAB или стрелкой "ВНИЗ". Переход к предыдущему пункту списка - SHIFT+TAB или стрелкой "ВВЕРХ". Нажмите SPACE, или ENTER, чтобы задействовать опцию списка. Нажмите ESC, чтобы закрыть окно списка.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Путь к элементу',\r
+                       legend: 'Нажмите ${elementsPathFocus}, чтобы перейти к панели пути элементов. Переход к следующей кнопке элемента - TAB или стрелкой "ВПРАВО". Переход к предыдущей кнопку - SHIFT+TAB или стрелкой "ВЛЕВО". Нажмите SPACE, или ENTER, чтобы выбрать элемент в редакторе.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Команды',\r
+               items: [\r
+                       {\r
+                       name: 'Отменить',\r
+                       legend: 'Нажмите ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Повторить',\r
+                       legend: 'Нажмите ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Полужирный',\r
+                       legend: 'Нажмите ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Курсив',\r
+                       legend: 'Нажмите ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Подчеркнутый',\r
+                       legend: 'Нажмите ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Гиперссылка',\r
+                       legend: 'Нажмите ${link}'\r
+               },\r
+                       {\r
+                       name: 'Свернуть панель инструментов',\r
+                       legend: 'Нажмите ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Команды доступа к предыдущему фокусному пространству',\r
+                       legend: 'Нажмите ${accessPreviousSpace}, чтобы обратиться к ближайшему недостижимому фокусному пространству перед символом "^", например: два смежных HR элемента. Повторите комбинацию клавиш, чтобы достичь отдаленных фокусных пространств.'\r
+               },\r
+                       {\r
+                       name: 'Команды доступа к следующему фокусному пространству',\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.'\r
+               },\r
+                       {\r
+                       name: 'Справка по горячим клавишам',\r
+                       legend: 'Нажмите ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Esc',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Стрелка влево',\r
+       upArrow: 'Стрелка вверх',\r
+       rightArrow: 'Стрелка вправо',\r
+       downArrow: 'Стрелка вниз',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Левая клавиша Windows',\r
+       rightWindowKey: 'Правая клавиша Windows',\r
+       selectKey: 'Выбрать',\r
+       numpad0: 'Цифра 0',\r
+       numpad1: 'Цифра 1',\r
+       numpad2: 'Цифра 2',\r
+       numpad3: 'Цифра 3',\r
+       numpad4: 'Цифра 4',\r
+       numpad5: 'Цифра 5',\r
+       numpad6: 'Цифра 6',\r
+       numpad7: 'Цифра 7',\r
+       numpad8: 'Цифра 8',\r
+       numpad9: 'Цифра 9',\r
+       multiply: 'Умножить',\r
+       add: 'Плюс',\r
+       subtract: 'Вычесть',\r
+       decimalPoint: 'Десятичная точка',\r
+       divide: 'Делить',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Точка с запятой',\r
+       equalSign: 'Равно',\r
+       comma: 'Запятая',\r
+       dash: 'Тире',\r
+       period: 'Точка',\r
+       forwardSlash: 'Наклонная черта',\r
+       graveAccent: 'Апостроф',\r
+       openBracket: 'Открыть скобку',\r
+       backSlash: 'Обратная наклонная черта',\r
+       closeBracket: 'Закрыть скобку',\r
+       singleQuote: 'Одинарная кавычка'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/si.js b/sources/plugins/a11yhelp/dialogs/lang/si.js
new file mode 100644 (file)
index 0000000..14d94ad
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'si', {\r
+       title: 'ළඟා වියහැකි ',\r
+       contents: 'උදව් සඳහා අන්තර්ගතය.නික්මයෙමට ESC බොත්තම ඔබන්න',\r
+       legend: [\r
+               {\r
+               name: 'පොදු කරුණු',\r
+               items: [\r
+                       {\r
+                       name: 'සංස්කරණ මෙවලම් ',\r
+                       legend: 'ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT+TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට SPACE හෝ ENTER බොත්තම ඔබන්න.'\r
+               },\r
+\r
+                       {\r
+                       name: 'සංස්කරණ ',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'සංස්කරණ අඩංගුවට ',\r
+                       legend: 'ඔබන්න ${අන්තර්ගත මෙනුව} හෝ  APPLICATION KEY  අන්තර්ගත-මෙනුව විවුරතකිරීමට. ඊළඟ මෙනුව-ව්කල්පයන්ට යෑමට TAB හෝ DOWN ARROW බොත්තම ද, පෙර විකල්පයන්ටයෑමට SHIFT+TAB හෝ  UP ARROW බොත්තම ද, මෙනුව-ව්කල්පයන් තේරීමට SPACE හෝ ENTER බොත්තම ද,  දැනට විවුර්තව ඇති උප-මෙනුවක වීකල්ප තේරීමට SPACE හෝ ENTER හෝ RIGHT ARROW ද, නැවත පෙර ප්‍රධාන මෙනුවට යෑමට  ESC හෝ LEFT ARROW බොත්තම ද.  අන්තර්ගත-මෙනුව වැසීමට  ESC බොත්තම ද ඔබන්න.'\r
+               },\r
+\r
+                       {\r
+                       name: 'සංස්කරණ තේරුම් ',\r
+                       legend: 'තේරුම් කොටුව තුළ , ඊළඟ අයිතමයට යෑමට TAB හෝ DOWN ARROW , පෙර අයිතමයට යෑමට SHIFT+TAB හෝ UP ARROW . අයිතම විකල්පයන් තේරීමට SPACE හෝ ENTER ,තේරුම් කොටුව වැසීමට ESC බොත්තම් ද ඔබන්න.'\r
+               },\r
+\r
+                       {\r
+                       name: 'සංස්කරණ අංග සහිත ',\r
+                       legend: 'ඔබන්න ${මෙවලම් තීරු අවධානය} මෙවලම් තීරුවේ එහා මෙහා යෑමට.ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරුකාණ්ඩය හා TAB හා SHIFT+TAB .ඉදිරියට යෑමට හා ආපසු යෑමට මෙවලම් තීරු බොත්තම සමග RIGHT ARROW හෝ LEFT ARROW.මෙවලම් තීරු බොත්තම සක්‍රිය කර ගැනීමට SPACE හෝ ENTER බොත්තම ඔබන්න.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'විධාන',\r
+               items: [\r
+                       {\r
+                       name: 'විධානය වෙනස් ',\r
+                       legend: 'ඔබන්න ${වෙනස් කිරීම}'\r
+               },\r
+                       {\r
+                       name: 'විධාන නැවත් පෙර පරිදිම වෙනස්කර ගැනීම.',\r
+                       legend: 'ඔබන්න ${නැවත් පෙර පරිදිම වෙනස්කර ගැනීම}'\r
+               },\r
+                       {\r
+                       name: 'තද අකුරින් විධාන',\r
+                       legend: 'ඔබන්න ${තද }'\r
+               },\r
+                       {\r
+                       name: 'බැධී අකුරු විධාන',\r
+                       legend: 'ඔබන්න ${බැධී අකුරු }'\r
+               },\r
+                       {\r
+                       name: 'යටින් ඉරි ඇද ඇති විධාන.',\r
+                       legend: 'ඔබන්න ${යටින් ඉරි ඇද ඇති}'\r
+               },\r
+                       {\r
+                       name: 'සම්බන්ධිත විධාන',\r
+                       legend: 'ඔබන්න ${සම්බන්ධ }'\r
+               },\r
+                       {\r
+                       name: 'මෙවලම් තීරු හැකුලුම් විධාන',\r
+                       legend: 'ඔබන්න ${මෙවලම් තීරු හැකුලුම් }'\r
+               },\r
+                       {\r
+                       name: 'යොමුවීමට පෙර  වැදගත්  විධාන',\r
+                       legend: 'ඔබන්න ${යොමුවීමට ඊළඟ }'\r
+               },\r
+                       {\r
+                       name: 'යොමුවීමට ඊළග වැදගත්  විධාන',\r
+                       legend: 'ඔබන්න ${යොමුවීමට ඊළඟ }'\r
+               },\r
+                       {\r
+                       name: 'ප්‍රවේශ ',\r
+                       legend: 'ඔබන්න  ${a11y }'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sk.js b/sources/plugins/a11yhelp/dialogs/lang/sk.js
new file mode 100644 (file)
index 0000000..2d74c3b
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sk', {\r
+       title: 'Inštrukcie prístupnosti',\r
+       contents: 'Pomocný obsah. Pre zatvorenie tohto okna, stlačte ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Všeobecne',\r
+               items: [\r
+                       {\r
+                       name: 'Lišta nástrojov editora',\r
+                       legend: 'Stlačte ${toolbarFocus} pre navigáciu na lištu nástrojov. Medzi ďalšou a predchádzajúcou lištou nástrojov sa pohybujete s TAB a SHIFT+TAB. Medzi ďalším a predchádzajúcim tlačidlom na lište nástrojov sa pohybujete s pravou šípkou a ľavou šípkou. Stlačte medzerník alebo ENTER pre aktiváciu tlačidla lišty nástrojov.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorový dialóg',\r
+                       legend:\r
+                               'V dialógovom okne stlačte TAB pre presun na ďalší prvok, SHIFT+TAB pre presun na predchádzajúci prvok, ENTER pre odoslanie, ESC pre zrušenie. Keď má dialógové okno viacero kariet, zoznam kariet dosiahnete buď stlačením ALT+F10 alebo s TAB v príslušnom poradí kariet. So zameraným zoznamom kariet sa pohybujte k ďalšej alebo predchádzajúcej karte cez PRAVÚ a ĽAVÚ ŠÍPKU.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorové kontextové menu',\r
+                       legend: 'Stlačte ${contextMenu} alebo APPLICATION KEY pre otvorenie kontextového menu. Potom sa presúvajte na ďalšie možnosti menu s TAB alebo dolnou šípkou. Presunte sa k predchádzajúcej možnosti s SHIFT+TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti menu. Otvorte pod-menu danej možnosti s medzerníkom, alebo ENTER, alebo pravou šípkou. Vráťte sa späť do položky rodičovského menu s ESC alebo ľavou šípkou. Zatvorte kontextové menu s ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorov box zoznamu',\r
+                       legend: 'V boxe zoznamu, presuňte sa na ďalšiu položku v zozname s TAB alebo dolnou šípkou. Presuňte sa k predchádzajúcej položke v zozname so SHIFT+TAB alebo hornou šípkou. Stlačte medzerník alebo ENTER pre výber možnosti zoznamu. Stlačte ESC pre zatvorenie boxu zoznamu.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editorove pásmo cesty prvku',\r
+                       legend: 'Stlačte ${elementsPathFocus} pre navigovanie na pásmo cesty elementu. Presuňte sa na tlačidlo ďalšieho prvku s TAB alebo pravou šípkou. Presuňte sa k predchádzajúcemu tlačidlu s SHIFT+TAB alebo ľavou šípkou. Stlačte medzerník alebo ENTER pre výber prvku v editore.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Príkazy',\r
+               items: [\r
+                       {\r
+                       name: 'Vrátiť príkazy',\r
+                       legend: 'Stlačte ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Nanovo vrátiť príkaz',\r
+                       legend: 'Stlačte ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Príkaz na stučnenie',\r
+                       legend: 'Stlačte ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Príkaz na kurzívu',\r
+                       legend: 'Stlačte ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Príkaz na podčiarknutie',\r
+                       legend: 'Stlačte ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Príkaz na odkaz',\r
+                       legend: 'Stlačte ${link}'\r
+               },\r
+                       {\r
+                       name: 'Príkaz na zbalenie lišty nástrojov',\r
+                       legend: 'Stlačte ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Prejsť na predchádzajúcu zamerateľnú medzeru príkazu',\r
+                       legend: 'Stlačte ${accessPreviousSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery pred vsuvkuo. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier.'\r
+               },\r
+                       {\r
+                       name: 'Prejsť na ďalší ',\r
+                       legend: 'Stlačte ${accessNextSpace} pre prístup na najbližšie nedosiahnuteľné zamerateľné medzery po vsuvke. Napríklad: dve za sebou idúce horizontálne čiary. Opakujte kombináciu klávesov pre dosiahnutie vzdialených zamerateľných medzier.'\r
+               },\r
+                       {\r
+                       name: 'Pomoc prístupnosti',\r
+                       legend: 'Stlačte ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Stránka hore',\r
+       pageDown: 'Stránka dole',\r
+       leftArrow: 'Šípka naľavo',\r
+       upArrow: 'Šípka hore',\r
+       rightArrow: 'Šípka napravo',\r
+       downArrow: 'Šípka dole',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Ľavé Windows tlačidlo',\r
+       rightWindowKey: 'Pravé Windows tlačidlo',\r
+       selectKey: 'Tlačidlo Select',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Násobenie',\r
+       add: 'Sčítanie',\r
+       subtract: 'Odčítanie',\r
+       decimalPoint: 'Desatinná čiarka',\r
+       divide: 'Delenie',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Bodkočiarka',\r
+       equalSign: 'Rovná sa',\r
+       comma: 'Čiarka',\r
+       dash: 'Pomĺčka',\r
+       period: 'Bodka',\r
+       forwardSlash: 'Lomítko',\r
+       graveAccent: 'Zdôrazňovanie prízvuku',\r
+       openBracket: 'Hranatá zátvorka otváracia',\r
+       backSlash: 'Backslash',\r
+       closeBracket: 'Hranatá zátvorka zatváracia',\r
+       singleQuote: 'Jednoduché úvodzovky'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sl.js b/sources/plugins/a11yhelp/dialogs/lang/sl.js
new file mode 100644 (file)
index 0000000..bb38713
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sl', {\r
+       title: 'Navodila za dostopnost',\r
+       contents: 'Vsebina pomoči. Če želite zapreti pogovorno okno, pritisnite ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Splošno',\r
+               items: [\r
+                       {\r
+                       name: 'Orodna vrstica urejevalnika',\r
+                       legend: 'Pritisnite ${toolbarFocus} za pomik v orodno vrstico. Z TAB in SHIFT+TAB se pomikate na naslednjo in prejšnjo skupino orodne vrstice. Z DESNO PUŠČICO ali LEVO PUŠČICO se pomikate na naslednji in prejšnji gumb orodne vrstice. Pritisnite SPACE ali ENTER, da aktivirate gumb orodne vrstice.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Urejevalno Pogovorno Okno',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Kontekstni meni urejevalnika',\r
+                       legend: 'Pritisnite ${contextMenu} ali APPLICATION KEY, da odprete kontekstni meni. Nato se premaknite na naslednjo možnost menija s tipko TAB ali PUŠČICA DOL. Premakniti se na prejšnjo možnost z SHIFT + TAB ali PUŠČICA GOR. Pritisnite SPACE ali ENTER za izbiro možnosti menija. Odprite podmeni trenutne možnosti menija s tipko SPACE ali ENTER ali DESNA PUŠČICA. Vrnite se na matični element menija s tipko ESC ali LEVA PUŠČICA. Zaprite kontekstni meni z ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Urejevalno Seznamsko Polje',\r
+                       legend: 'Znotraj seznama, se premaknete na naslednji element seznama s tipko TAB ali PUŠČICO DOL. Z SHIFT+TAB ali PUŠČICO GOR se premaknete na prejšnji element seznama. Pritisnite tipko SPACE ali ENTER za izbiro elementa. Pritisnite tipko ESC, da zaprete seznam.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Urejevalna vrstica poti elementa',\r
+                       legend: 'Pritisnite ${elementsPathFocus} za pomikanje po vrstici elementnih poti. S TAB ali DESNA PUŠČICA se premaknete na naslednji gumb elementa. Z SHIFT+TAB ali LEVO PUŠČICO se premaknete na prejšnji gumb elementa. Pritisnite SPACE ali ENTER za izbiro elementa v urejevalniku.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Ukazi',\r
+               items: [\r
+                       {\r
+                       name: 'Razveljavi ukaz',\r
+                       legend: 'Pritisnite ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Ponovi ukaz',\r
+                       legend: 'Pritisnite ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Krepki ukaz',\r
+                       legend: 'Pritisnite ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Ležeči ukaz',\r
+                       legend: 'Pritisnite ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Poudarni ukaz',\r
+                       legend: 'Pritisnite ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Ukaz povezave',\r
+                       legend: 'Pritisnite ${link}'\r
+               },\r
+                       {\r
+                       name: 'Skrči Orodno Vrstico Ukaz',\r
+                       legend: 'Pritisnite ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Dostop do prejšnjega ukaza ostrenja',\r
+                       legend: 'Pritisnite ${accessPreviousSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora pred strešico, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore.'\r
+               },\r
+                       {\r
+                       name: 'Dostop do naslednjega ukaza ostrenja',\r
+                       legend: 'Pritisnite ${accessNextSpace} za dostop do najbližjega nedosegljivega osredotočenega prostora po strešici, npr.: dva sosednja HR elementa. Ponovite kombinacijo tipk, da dosežete oddaljene osredotočene prostore.'\r
+               },\r
+                       {\r
+                       name: 'Pomoč dostopnosti',\r
+                       legend: 'Pritisnite ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Puščica levo',\r
+       upArrow: 'Puščica gor',\r
+       rightArrow: 'Puščica desno',\r
+       downArrow: 'Puščica dol',\r
+       insert: 'Insert',\r
+       leftWindowKey: 'Leva tipka Windows',\r
+       rightWindowKey: 'Desna tipka Windows',\r
+       selectKey: 'Select tipka',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Zmnoži',\r
+       add: 'Dodaj',\r
+       subtract: 'Odštej',\r
+       decimalPoint: 'Decimalna vejica',\r
+       divide: 'Deli',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Podpičje',\r
+       equalSign: 'Enačaj',\r
+       comma: 'Vejica',\r
+       dash: 'Vezaj',\r
+       period: 'Pika',\r
+       forwardSlash: 'Desna poševnica',\r
+       graveAccent: 'Krativec',\r
+       openBracket: 'Oklepaj',\r
+       backSlash: 'Leva poševnica',\r
+       closeBracket: 'Zaklepaj',\r
+       singleQuote: 'Opuščaj'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sq.js b/sources/plugins/a11yhelp/dialogs/lang/sq.js
new file mode 100644 (file)
index 0000000..c5947cc
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sq', {\r
+       title: 'Udhëzimet e Qasjes',\r
+       contents: 'Përmbajtja ndihmëse. Për ta mbyllur dialogun shtyp ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Të përgjithshme',\r
+               items: [\r
+                       {\r
+                       name: 'Shiriti i Redaktuesit',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialogu i Redaktuesit',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komandat',\r
+               items: [\r
+                       {\r
+                       name: 'Rikthe komandën',\r
+                       legend: 'Shtyp ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Ribëj komandën',\r
+                       legend: 'Shtyp ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Komanda e trashjes së tekstit',\r
+                       legend: 'Shtyp ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Komanda kursive',\r
+                       legend: 'Shtyp ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Komanda e nënvijëzimit',\r
+                       legend: 'Shtyp ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Komanda e Nyjes',\r
+                       legend: 'Shtyp ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Shtyp ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: 'Ndihmë Qasjeje',\r
+                       legend: 'Shtyp ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Fletë',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Shenja majtas',\r
+       upArrow: 'Shenja sipër',\r
+       rightArrow: 'Shenja djathtas',\r
+       downArrow: 'Shenja poshtë',\r
+       insert: 'Shto',\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Shto',\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semicolon',\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Presje',\r
+       dash: 'vizë',\r
+       period: 'Pikë',\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Hape kllapën',\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Mbylle kllapën',\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sr-latn.js b/sources/plugins/a11yhelp/dialogs/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..5b743ac
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sr-latn', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Opšte',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sr.js b/sources/plugins/a11yhelp/dialogs/lang/sr.js
new file mode 100644 (file)
index 0000000..0e3e979
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sr', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Опште',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Commands', // MISSING\r
+               items: [\r
+                       {\r
+                       name: ' Undo command', // MISSING\r
+                       legend: 'Press ${undo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Redo command', // MISSING\r
+                       legend: 'Press ${redo}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Bold command', // MISSING\r
+                       legend: 'Press ${bold}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Italic command', // MISSING\r
+                       legend: 'Press ${italic}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Underline command', // MISSING\r
+                       legend: 'Press ${underline}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Link command', // MISSING\r
+                       legend: 'Press ${link}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/sv.js b/sources/plugins/a11yhelp/dialogs/lang/sv.js
new file mode 100644 (file)
index 0000000..4962b95
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'sv', {\r
+       title: 'Hjälpmedelsinstruktioner',\r
+       contents: 'Hjälpinnehåll. För att stänga denna dialogruta trycker du på ESC.',\r
+       legend: [\r
+               {\r
+               name: 'Allmänt',\r
+               items: [\r
+                       {\r
+                       name: 'Editor verktygsfält',\r
+                       legend: 'Tryck på ${toolbarFocus} för att navigera till verktygsfältet. Flytta till nästa och föregående verktygsfältsgrupp med TAB och SHIFT+TAB. Flytta till nästa och föregående knapp i verktygsfältet med HÖGERPIL eller VÄNSTERPIL. Tryck SPACE eller ENTER för att aktivera knappen i verktygsfältet.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Dialogeditor',\r
+                       legend:\r
+                               'Inuti en dialogruta, tryck TAB för att navigera till nästa fält i dialogrutan, tryck SKIFT+TAB för att flytta till föregående fält, tryck ENTER för att skicka. Du avbryter och stänger dialogen med ESC. För dialogrutor som har flera flikar, tryck ALT+F10 eller TAB för att navigera till fliklistan. med fliklistan vald flytta till nästa och föregående flik med HÖGER- eller VÄNSTERPIL.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor för innehållsmeny',\r
+                       legend: 'Tryck på $ {contextMenu} eller PROGRAMTANGENTEN för att öppna snabbmenyn. Flytta sedan till nästa menyalternativ med TAB eller NEDPIL. Flytta till föregående alternativ med SHIFT + TABB eller UPPIL. Tryck Space eller ENTER för att välja menyalternativ. Öppna undermeny av nuvarande alternativ med SPACE eller ENTER eller HÖGERPIL. Gå tillbaka till överordnade menyalternativ med ESC eller VÄNSTERPIL. Stäng snabbmenyn med ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor för list-box',\r
+                       legend: 'Inuti en list-box, gå till nästa listobjekt med TAB eller NEDPIL. Flytta till föregående listobjekt med SHIFT+TAB eller UPPIL. Tryck SPACE eller ENTER för att välja listan alternativet. Tryck ESC för att stänga list-boxen.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor för elementens sökväg',\r
+                       legend: 'Tryck på ${elementsPathFocus} för att navigera till verktygsfältet för elementens sökvägar. Flytta till nästa elementknapp med TAB eller HÖGERPIL. Flytta till föregående knapp med SKIFT+TAB eller VÄNSTERPIL. Tryck SPACE eller ENTER för att välja element i redigeraren.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Kommandon',\r
+               items: [\r
+                       {\r
+                       name: 'Ångra kommando',\r
+                       legend: 'Tryck på ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Gör om kommando',\r
+                       legend: 'Tryck på ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Kommandot fet stil',\r
+                       legend: 'Tryck på ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Kommandot kursiv',\r
+                       legend: 'Tryck på ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Kommandot understruken',\r
+                       legend: 'Tryck på ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Kommandot länk',\r
+                       legend: 'Tryck på ${link}'\r
+               },\r
+                       {\r
+                       name: 'Verktygsfält Dölj kommandot',\r
+                       legend: 'Tryck på ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Gå till föregående fokus plats',\r
+                       legend: 'Tryck på ${accessPreviousSpace} för att gå till närmast onåbara utrymme före markören, exempel: två intilliggande HR element. Repetera tangentkombinationen för att gå till nästa.'\r
+               },\r
+                       {\r
+                       name: 'Tillgå nästa fokuskommandots utrymme',\r
+                       legend: 'Tryck ${accessNextSpace} på för att komma åt den närmaste onåbar fokus utrymme efter cirkumflex, till exempel: två intilliggande HR element. Upprepa tangentkombinationen för att nå avlägsna fokus utrymmen.'\r
+               },\r
+                       {\r
+                       name: 'Hjälp om tillgänglighet',\r
+                       legend: 'Tryck ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Paus',\r
+       capslock: 'Caps lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Sida Up',\r
+       pageDown: 'Sida Ned',\r
+       leftArrow: 'Vänsterpil',\r
+       upArrow: 'Uppil',\r
+       rightArrow: 'Högerpil',\r
+       downArrow: 'Nedåtpil',\r
+       insert: 'Infoga',\r
+       leftWindowKey: 'Vänster Windowstangent',\r
+       rightWindowKey: 'Höger Windowstangent',\r
+       selectKey: 'Välj tangent',\r
+       numpad0: 'Nummer 0',\r
+       numpad1: 'Nummer 1',\r
+       numpad2: 'Nummer 2',\r
+       numpad3: 'Nummer 3',\r
+       numpad4: 'Nummer 4',\r
+       numpad5: 'Nummer 5',\r
+       numpad6: 'Nummer 6',\r
+       numpad7: 'Nummer 7',\r
+       numpad8: 'Nummer 8',\r
+       numpad9: 'Nummer 9',\r
+       multiply: 'Multiplicera',\r
+       add: 'Addera',\r
+       subtract: 'Minus',\r
+       decimalPoint: 'Decimalpunkt',\r
+       divide: 'Dividera',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Semikolon',\r
+       equalSign: 'Lika med tecken',\r
+       comma: 'Komma',\r
+       dash: 'Minus',\r
+       period: 'Punkt',\r
+       forwardSlash: 'Snedstreck framåt',\r
+       graveAccent: 'Accent',\r
+       openBracket: 'Öppningsparentes',\r
+       backSlash: 'Snedstreck bakåt',\r
+       closeBracket: 'Slutparentes',\r
+       singleQuote: 'Enkelt Citattecken'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/th.js b/sources/plugins/a11yhelp/dialogs/lang/th.js
new file mode 100644 (file)
index 0000000..1382894
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'th', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'ทั่วไป',\r
+               items: [\r
+                       {\r
+                       name: 'แถบเครื่องมือสำหรับเครื่องมือช่วยพิมพ์',\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'คำสั่ง',\r
+               items: [\r
+                       {\r
+                       name: 'เลิกทำคำสั่ง',\r
+                       legend: 'วาง ${undo}'\r
+               },\r
+                       {\r
+                       name: 'คำสั่งสำหรับทำซ้ำ',\r
+                       legend: 'วาง ${redo}'\r
+               },\r
+                       {\r
+                       name: 'คำสั่งสำหรับตัวหนา',\r
+                       legend: 'วาง ${bold}'\r
+               },\r
+                       {\r
+                       name: 'คำสั่งสำหรับตัวเอียง',\r
+                       legend: 'วาง ${italic}'\r
+               },\r
+                       {\r
+                       name: 'คำสั่งสำหรับขีดเส้นใต้',\r
+                       legend: 'วาง ${underline}'\r
+               },\r
+                       {\r
+                       name: 'คำสั่งสำหรับลิงก์',\r
+                       legend: 'วาง ${link}'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: 'Press ${toolbarCollapse}' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: 'Press ${a11yHelp}' // MISSING\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab', // MISSING\r
+       pause: 'Pause', // MISSING\r
+       capslock: 'Caps Lock', // MISSING\r
+       escape: 'Escape', // MISSING\r
+       pageUp: 'Page Up', // MISSING\r
+       pageDown: 'Page Down', // MISSING\r
+       leftArrow: 'Left Arrow', // MISSING\r
+       upArrow: 'Up Arrow', // MISSING\r
+       rightArrow: 'Right Arrow', // MISSING\r
+       downArrow: 'Down Arrow', // MISSING\r
+       insert: 'Insert', // MISSING\r
+       leftWindowKey: 'Left Windows key', // MISSING\r
+       rightWindowKey: 'Right Windows key', // MISSING\r
+       selectKey: 'Select key', // MISSING\r
+       numpad0: 'Numpad 0', // MISSING\r
+       numpad1: 'Numpad 1', // MISSING\r
+       numpad2: 'Numpad 2', // MISSING\r
+       numpad3: 'Numpad 3', // MISSING\r
+       numpad4: 'Numpad 4', // MISSING\r
+       numpad5: 'Numpad 5', // MISSING\r
+       numpad6: 'Numpad 6', // MISSING\r
+       numpad7: 'Numpad 7', // MISSING\r
+       numpad8: 'Numpad 8', // MISSING\r
+       numpad9: 'Numpad 9', // MISSING\r
+       multiply: 'Multiply', // MISSING\r
+       add: 'Add', // MISSING\r
+       subtract: 'Subtract', // MISSING\r
+       decimalPoint: 'Decimal Point', // MISSING\r
+       divide: 'Divide', // MISSING\r
+       f1: 'F1', // MISSING\r
+       f2: 'F2', // MISSING\r
+       f3: 'F3', // MISSING\r
+       f4: 'F4', // MISSING\r
+       f5: 'F5', // MISSING\r
+       f6: 'F6', // MISSING\r
+       f7: 'F7', // MISSING\r
+       f8: 'F8', // MISSING\r
+       f9: 'F9', // MISSING\r
+       f10: 'F10', // MISSING\r
+       f11: 'F11', // MISSING\r
+       f12: 'F12', // MISSING\r
+       numLock: 'Num Lock', // MISSING\r
+       scrollLock: 'Scroll Lock', // MISSING\r
+       semiColon: 'Semicolon', // MISSING\r
+       equalSign: 'Equal Sign', // MISSING\r
+       comma: 'Comma', // MISSING\r
+       dash: 'Dash', // MISSING\r
+       period: 'Period', // MISSING\r
+       forwardSlash: 'Forward Slash', // MISSING\r
+       graveAccent: 'Grave Accent', // MISSING\r
+       openBracket: 'Open Bracket', // MISSING\r
+       backSlash: 'Backslash', // MISSING\r
+       closeBracket: 'Close Bracket', // MISSING\r
+       singleQuote: 'Single Quote' // MISSING\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/tr.js b/sources/plugins/a11yhelp/dialogs/lang/tr.js
new file mode 100644 (file)
index 0000000..15306a5
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'tr', {\r
+       title: 'Erişilebilirlik Talimatları',\r
+       contents: 'Yardım içeriği. Bu pencereyi kapatmak için ESC tuşuna basın.',\r
+       legend: [\r
+               {\r
+               name: 'Genel',\r
+               items: [\r
+                       {\r
+                       name: 'Düzenleyici Araç Çubuğu',\r
+                       legend: 'Araç çubuğunda gezinmek için ${toolbarFocus} basın. TAB ve SHIFT+TAB ile önceki ve sonraki araç çubuğu grubuna taşıyın. SAĞ OK veya SOL OK ile önceki ve sonraki bir araç çubuğu düğmesini hareket ettirin. SPACE tuşuna basın veya araç çubuğu düğmesini etkinleştirmek için ENTER tuşna basın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Diyalog Düzenleyici',\r
+                       legend:\r
+                               'Dialog penceresi içinde, sonraki iletişim alanına gitmek için SEKME tuşuna basın, önceki alana geçmek için SHIFT + TAB tuşuna basın, pencereyi göndermek için ENTER tuşuna basın, dialog penceresini iptal etmek için ESC tuşuna basın. Birden çok sekme sayfaları olan diyalogların, sekme listesine gitmek için ALT + F10 tuşlarına basın. Sonra TAB veya SAĞ OK sonraki sekmeye taşıyın. SHIFT + TAB veya SOL OK ile önceki sekmeye geçin. Sekme sayfayı seçmek için SPACE veya ENTER tuşuna basın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'İçerik Menü Editörü',\r
+                       legend: 'İçerik menüsünü açmak için ${contextMenu} veya UYGULAMA TUŞU\'na basın. Daha sonra SEKME veya AŞAĞI OK ile bir sonraki menü seçeneği taşıyın. SHIFT + TAB veya YUKARI OK ile önceki seçeneğe gider. Menü seçeneğini seçmek için SPACE veya ENTER tuşuna basın. Seçili seçeneğin alt menüsünü SPACE ya da ENTER veya SAĞ OK açın. Üst menü öğesini geçmek için ESC veya SOL OK ile geri dönün. ESC ile bağlam menüsünü kapatın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Liste Kutusu Editörü',\r
+                       legend: 'Liste kutusu içinde, bir sonraki liste öğesine SEKME VEYA AŞAĞI OK ile taşıyın. SHIFT+TAB veya YUKARI önceki liste öğesi taşıyın. Liste seçeneği seçmek için SPACE veya ENTER tuşuna basın. Liste kutusunu kapatmak için ESC tuşuna basın.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Element Yol Çubuğu Editörü',\r
+                       legend: 'Elementlerin yol çubuğunda gezinmek için ${ElementsPathFocus} basın. SEKME veya SAĞ OK ile sonraki element düğmesine taşıyın. SHIFT+TAB veya SOL OK önceki düğmeye hareket ettirin. Editör içindeki elementi seçmek için ENTER veya SPACE tuşuna basın.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Komutlar',\r
+               items: [\r
+                       {\r
+                       name: 'Komutu geri al',\r
+                       legend: '$(undo)\'ya basın'\r
+               },\r
+                       {\r
+                       name: 'Komutu geri al',\r
+                       legend: '${redo} basın'\r
+               },\r
+                       {\r
+                       name: ' Kalın komut',\r
+                       legend: '${bold} basın'\r
+               },\r
+                       {\r
+                       name: ' İtalik komutu',\r
+                       legend: '${italic} basın'\r
+               },\r
+                       {\r
+                       name: ' Alttan çizgi komutu',\r
+                       legend: '${underline} basın'\r
+               },\r
+                       {\r
+                       name: ' Bağlantı komutu',\r
+                       legend: '${link} basın'\r
+               },\r
+                       {\r
+                       name: ' Araç çubuğu Toplama komutu',\r
+                       legend: '${toolbarCollapse} basın'\r
+               },\r
+                       {\r
+                       name: 'Önceki komut alanına odaklan',\r
+                       legend: 'Düzeltme imleçinden önce, en yakın uzaktaki alana erişmek için ${accessPreviousSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın.'\r
+               },\r
+                       {\r
+                       name: 'Sonraki komut alanına odaklan',\r
+                       legend: 'Düzeltme imleçinden sonra, en yakın uzaktaki alana erişmek için ${accessNextSpace} basın, örneğin: iki birleşik HR elementleri. Aynı tuş kombinasyonu tekrarıyla diğer alanlarada ulaşın.'\r
+               },\r
+                       {\r
+                       name: 'Erişilebilirlik Yardımı',\r
+                       legend: '${a11yHelp}\'e basın'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Sekme tuşu',\r
+       pause: 'Durdurma tuşu',\r
+       capslock: 'Büyük harf tuşu',\r
+       escape: 'Vazgeç tuşu',\r
+       pageUp: 'Sayfa Yukarı',\r
+       pageDown: 'Sayfa Aşağı',\r
+       leftArrow: 'Sol ok',\r
+       upArrow: 'Yukarı ok',\r
+       rightArrow: 'Sağ ok',\r
+       downArrow: 'Aşağı ok',\r
+       insert: 'Araya gir',\r
+       leftWindowKey: 'Sol windows tuşu',\r
+       rightWindowKey: 'Sağ windows tuşu',\r
+       selectKey: 'Seçme tuşu',\r
+       numpad0: 'Nümerik 0',\r
+       numpad1: 'Nümerik 1',\r
+       numpad2: 'Nümerik 2',\r
+       numpad3: 'Nümerik 3',\r
+       numpad4: 'Nümerik 4',\r
+       numpad5: 'Nümerik 5',\r
+       numpad6: 'Nümerik 6',\r
+       numpad7: 'Nümerik 7',\r
+       numpad8: 'Nümerik 8',\r
+       numpad9: 'Nümerik 9',\r
+       multiply: 'Çarpma',\r
+       add: 'Toplama',\r
+       subtract: 'Çıkarma',\r
+       decimalPoint: 'Ondalık işareti',\r
+       divide: 'Bölme',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lk',\r
+       scrollLock: 'Scr Lk',\r
+       semiColon: 'Noktalı virgül',\r
+       equalSign: 'Eşittir',\r
+       comma: 'Virgül',\r
+       dash: 'Eksi',\r
+       period: 'Nokta',\r
+       forwardSlash: 'İleri eğik çizgi',\r
+       graveAccent: 'Üst tırnak',\r
+       openBracket: 'Parantez aç',\r
+       backSlash: 'Ters eğik çizgi',\r
+       closeBracket: 'Parantez kapa',\r
+       singleQuote: 'Tek tırnak'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/tt.js b/sources/plugins/a11yhelp/dialogs/lang/tt.js
new file mode 100644 (file)
index 0000000..bdd9847
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'tt', {\r
+       title: 'Accessibility Instructions', // MISSING\r
+       contents: 'Help Contents. To close this dialog press ESC.', // MISSING\r
+       legend: [\r
+               {\r
+               name: 'Гомуми',\r
+               items: [\r
+                       {\r
+                       name: 'Editor Toolbar', // MISSING\r
+                       legend: 'Press ${toolbarFocus} to navigate to the toolbar. Move to the next and previous toolbar group with TAB and SHIFT+TAB. Move to the next and previous toolbar button with RIGHT ARROW or LEFT ARROW. Press SPACE or ENTER to activate the toolbar button.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Dialog', // MISSING\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Context Menu', // MISSING\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Then move to next menu option with TAB or DOWN ARROW. Move to previous option with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the menu option. Open sub-menu of current option with SPACE or ENTER or RIGHT ARROW. Go back to parent menu item with ESC or LEFT ARROW. Close context menu with ESC.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor List Box', // MISSING\r
+                       legend: 'Inside a list-box, move to next list item with TAB OR DOWN ARROW. Move to previous list item with SHIFT+TAB or UP ARROW. Press SPACE or ENTER to select the list option. Press ESC to close the list-box.' // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Editor Element Path Bar', // MISSING\r
+                       legend: 'Press ${elementsPathFocus} to navigate to the elements path bar. Move to next element button with TAB or RIGHT ARROW. Move to previous button with SHIFT+TAB or LEFT ARROW. Press SPACE or ENTER to select the element in editor.' // MISSING\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Командалар',\r
+               items: [\r
+                       {\r
+                       name: 'Кайтару',\r
+                       legend: '${undo} басыгыз'\r
+               },\r
+                       {\r
+                       name: 'Кабатлау',\r
+                       legend: '${redo} басыгыз'\r
+               },\r
+                       {\r
+                       name: 'Калын',\r
+                       legend: '${bold} басыгыз'\r
+               },\r
+                       {\r
+                       name: 'Курсив',\r
+                       legend: '${italic} басыгыз'\r
+               },\r
+                       {\r
+                       name: 'Астына сызылган',\r
+                       legend: '${underline} басыгыз'\r
+               },\r
+                       {\r
+                       name: 'Сылталама',\r
+                       legend: '${link} басыгыз'\r
+               },\r
+                       {\r
+                       name: ' Toolbar Collapse command', // MISSING\r
+                       legend: '${toolbarCollapse} басыгыз'\r
+               },\r
+                       {\r
+                       name: ' Access previous focus space command', // MISSING\r
+                       legend: 'Press ${accessPreviousSpace} to access the closest unreachable focus space before the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Access next focus space command', // MISSING\r
+                       legend: 'Press ${accessNextSpace} to access the closest unreachable focus space after the caret, for example: two adjacent HR elements. Repeat the key combination to reach distant focus spaces.' // MISSING\r
+               },\r
+                       {\r
+                       name: ' Accessibility Help', // MISSING\r
+                       legend: '${a11yHelp} басыгыз'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Тыныш',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Сул якка ук',\r
+       upArrow: 'Өскә таба ук',\r
+       rightArrow: 'Уң якка ук',\r
+       downArrow: 'Аска таба ук',\r
+       insert: 'Өстәү',\r
+       leftWindowKey: 'Сул Windows төймəсе',\r
+       rightWindowKey: 'Уң Windows төймəсе',\r
+       selectKey: 'Select төймəсе',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Тапкырлау',\r
+       add: 'Кушу',\r
+       subtract: 'Алу',\r
+       decimalPoint: 'Унарлы нокта',\r
+       divide: 'Бүлү',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Нокталы өтер',\r
+       equalSign: 'Тигезлек билгесе',\r
+       comma: 'Өтер',\r
+       dash: 'Сызык',\r
+       period: 'Дәрәҗә',\r
+       forwardSlash: 'Кыек сызык',\r
+       graveAccent: 'Гравис',\r
+       openBracket: 'Җәя ачу',\r
+       backSlash: 'Кире кыек сызык',\r
+       closeBracket: 'Җәя ябу',\r
+       singleQuote: 'Бер иңле куштырнаклар'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/ug.js b/sources/plugins/a11yhelp/dialogs/lang/ug.js
new file mode 100644 (file)
index 0000000..1771562
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'ug', {\r
+       title: 'قوشۇمچە چۈشەندۈرۈش',\r
+       contents: 'ياردەم مەزمۇنى. بۇ سۆزلەشكۈنى ياپماقچى بولسىڭىز ESC نى بېسىڭ.',\r
+       legend: [\r
+               {\r
+               name: 'ئادەتتىكى',\r
+               items: [\r
+                       {\r
+                       name: 'قورال بالداق تەھرىر',\r
+                       legend: '${toolbarFocus} بېسىلسا قورال بالداققا يېتەكلەيدۇ، TAB ياكى SHIFT+TAB ئارقىلىق قورال بالداق گۇرۇپپىسى تاللىنىدۇ، ئوڭ سول يا ئوقتا توپچا تاللىنىدۇ، بوشلۇق ياكى Enter كۇنۇپكىسىدا تاللانغان توپچىنى قوللىنىدۇ.'\r
+               },\r
+\r
+                       {\r
+                       name: 'تەھرىرلىگۈچ سۆزلەشكۈسى',\r
+                       legend:\r
+                               'سۆزلەشكۈدە TAB كۇنۇپكىسىدا كېيىنكى سۆز بۆلىكىگە يۆتكىلىدۇ، SHIFT+TAB بىرىكمە كۇنۇپكىسىدا ئالدىنقى سۆز بۆلىكىگە يۆتكىلىدۇ، ENTER كۇنۇپكىسىدا سۆزلەشكۈنى تاپشۇرىدۇ، ESC كۇنۇپكىسى سۆزلەشكۈدىن ۋاز كېچىدۇ. كۆپ بەتكۈچلۈك سۆزلەشكۈگە نىسبەتەن، ALT+F10 دا بەتكۈچ تىزىمىغا يۆتكەيدۇ. ئاندىن TAB كۇنۇپكىسى ياكى ئوڭ يا ئوق كۇنۇپكىسى كېيىنكى بەتكۈچكە يۆتكەيدۇ؛SHIFT+ TAB كۇنۇپكىسى ياكى سول يا ئوق كۇنۇپكىسى ئالدىنقى بەتكۈچكە يۆتكەيدۇ. بوشلۇق كۇنۇپكىسى ياكى ENTER كۇنۇپكىسى بەتكۈچنى تاللايدۇ.'\r
+               },\r
+\r
+                       {\r
+                       name: 'تەھرىرلىگۈچ تىل مۇھىت تىزىملىكى',\r
+                       legend: '${contextMenu} ياكى ئەپ كۇنۇپكىسىدا تىل مۇھىت تىزىملىكىنى ئاچىدۇ. ئاندىن TAB ياكى ئاستى يا ئوق كۇنۇپكىسىدا كېيىنكى تىزىملىك تۈرىگە يۆتكەيدۇ؛ SHIFT+TAB ياكى ئۈستى يا ئوق كۇنۇپكىسىدا ئالدىنقى تىزىملىك تۈرىگە يۆتكەيدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىملىك تۈرىنى تاللايدۇ. بوشلۇق، ENTER ياكى ئوڭ يا ئوق كۇنۇپكىسىدا تارماق تىزىملىكنى ئاچىدۇ. قايتىش تىزىملىكىگە ESC ياكى سول يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ESC كۇنۇپكىسىدا تىل مۇھىت تىزىملىكى تاقىلىدۇ.'\r
+               },\r
+\r
+                       {\r
+                       name: 'تەھرىرلىگۈچ تىزىمى',\r
+                       legend: 'تىزىم قۇتىسىدا، كېيىنكى تىزىم تۈرىگە يۆتكەشتە TAB ياكى ئاستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. ئالدىنقى تىزىم تۈرىگە يۆتكەشتە SHIFT+TAB ياكى ئۈستى يا ئوق كۇنۇپكىسى ئىشلىتىلىدۇ. بوشلۇق ياكى ENTER كۇنۇپكىسىدا تىزىم تۈرىنى تاللايدۇ.ESC كۇنۇپكىسىدا تىزىم قۇتىسىنى يىغىدۇ.'\r
+               },\r
+\r
+                       {\r
+                       name: 'تەھرىرلىگۈچ ئېلېمېنت يول بالداق',\r
+                       legend: '${elementsPathFocus} بېسىلسا ئېلېمېنت يول بالداققا يېتەكلەيدۇ، TAB ياكى ئوڭ يا ئوقتا كېيىنكى ئېلېمېنت تاللىنىدۇ، SHIFT+TAB ياكى سول يا ئوقتا ئالدىنقى ئېلېمېنت تاللىنىدۇ، بوشلۇق ياكى Enter كۇنۇپكىسىدا تەھرىرلىگۈچتىكى ئېلېمېنت تاللىنىدۇ.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'بۇيرۇق',\r
+               items: [\r
+                       {\r
+                       name: 'بۇيرۇقتىن يېنىۋال',\r
+                       legend: '${undo} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'قايتىلاش بۇيرۇقى',\r
+                       legend: '${redo} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'توملىتىش بۇيرۇقى',\r
+                       legend: '${bold} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'يانتۇ بۇيرۇقى',\r
+                       legend: '${italic} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'ئاستى سىزىق بۇيرۇقى',\r
+                       legend: '${underline} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'ئۇلانما بۇيرۇقى',\r
+                       legend: '${link} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'قورال بالداق قاتلاش بۇيرۇقى',\r
+                       legend: '${toolbarCollapse} نى بېسىڭ'\r
+               },\r
+                       {\r
+                       name: 'ئالدىنقى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق',\r
+                       legend: '${accessPreviousSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ ئالدىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ.'\r
+               },\r
+                       {\r
+                       name: 'كېيىنكى فوكۇس نۇقتىسىنى زىيارەت قىلىدىغان بۇيرۇق',\r
+                       legend: '${accessNextSpace} بېسىپ ^ بەلگىسىگە ئەڭ يېقىن زىيارەت قىلغىلى بولمايدىغان فوكۇس نۇقتا رايونىنىڭ كەينىنى زىيارەت قىلىدۇ، مەسىلەن: ئۆز ئارا قوشنا ئىككى HR ئېلېمېنت. بۇ بىرىكمە كۇنۇپكا تەكرارلانسا يىراقتىكى فوكۇس نۇقتا رايونىغا يەتكىلى بولىدۇ.'\r
+               },\r
+                       {\r
+                       name: 'توسالغۇسىز لايىھە چۈشەندۈرۈشى',\r
+                       legend: '${a11yHelp} نى بېسىڭ'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Escape',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'سول يا ئوق',\r
+       upArrow: 'ئۈستى يا ئوق',\r
+       rightArrow: 'ئوڭ يا ئوق',\r
+       downArrow: 'ئاستى يا ئوق',\r
+       insert: 'قىستۇر',\r
+       leftWindowKey: 'سول Windows كۇنۇپكىسى',\r
+       rightWindowKey: 'ئوڭ Windows كۇنۇپكىسى',\r
+       selectKey: 'تاللاش كۇنۇپكىسى',\r
+       numpad0: 'سان تاختا 0',\r
+       numpad1: 'سان تاختا 1',\r
+       numpad2: 'سان تاختا 2',\r
+       numpad3: 'سان تاختا 3',\r
+       numpad4: 'سان تاختا 4',\r
+       numpad5: 'سان تاختا 5',\r
+       numpad6: 'سان تاختا 6',\r
+       numpad7: 'سان تاختا 7',\r
+       numpad8: 'سان تاختا 8',\r
+       numpad9: 'سان تاختا 9',\r
+       multiply: 'يۇلتۇز كۇنۇپكىسى',\r
+       add: 'قوشۇش',\r
+       subtract: 'ئېلىش',\r
+       decimalPoint: 'كەسىر چېكىت',\r
+       divide: 'بۆلۈش',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'سان قۇلۇپ كۇنۇپكىسى',\r
+       scrollLock: 'سۈرگۈچ قۇلۇپ كۇنۇپكىسى',\r
+       semiColon: 'چېكىتلىك پەش',\r
+       equalSign: 'تەڭلىك بەلگىسى',\r
+       comma: 'پەش',\r
+       dash: 'سىزىقچە',\r
+       period: 'چېكىت',\r
+       forwardSlash: 'سولغا يانتۇ سىزىق',\r
+       graveAccent: 'ئۇرغۇ بەلگىسى',\r
+       openBracket: 'ئېچىلغان تىرناق',\r
+       backSlash: 'ئوڭغا يانتۇ سىزىق',\r
+       closeBracket: 'يېپىلغان تىرناق',\r
+       singleQuote: 'يالاڭ پەش'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/uk.js b/sources/plugins/a11yhelp/dialogs/lang/uk.js
new file mode 100644 (file)
index 0000000..d1e8589
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'uk', {\r
+       title: 'Спеціальні Інструкції',\r
+       contents: 'Довідка. Натисніть ESC і вона зникне.',\r
+       legend: [\r
+               {\r
+               name: 'Основне',\r
+               items: [\r
+                       {\r
+                       name: 'Панель Редактора',\r
+                       legend: 'Натисніть ${toolbarFocus} для переходу до панелі інструментів. Для переміщення між групами панелі інструментів використовуйте TAB і SHIFT+TAB. Для переміщення між кнопками панелі іструментів використовуйте кнопки СТРІЛКА ВПРАВО або ВЛІВО. Натисніть ПРОПУСК або ENTER для запуску кнопки панелі інструментів.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Діалог Редактора',\r
+                       legend:\r
+                               'Усередині діалогу, натисніть TAB щоб перейти до наступного елементу діалогу, натисніть SHIFT+TAB щоб перейти до попереднього елемента діалогу, натисніть ENTER щоб відправити діалог, натисніть ESC щоб скасувати діалог. Коли діалогове вікно має декілька вкладок, отримати доступ до панелі вкладок як частині діалогу можна натисканням або поєднання ALT+F10 або TAB, при цьому активні елементи діалогу будуть перебиратися з урахуванням порядку табуляції. При активній панелі вкладок, перехід до наступної або попередньої вкладці здійснюється натисканням стрілки "ВПРАВО" або стрілки "ВЛЕВО" відповідно.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Контекстне Меню Редактора',\r
+                       legend: 'Press ${contextMenu} or APPLICATION KEY to open context-menu. Потім перейдіть до наступного пункту меню за допомогою TAB або СТРІЛКИ ВНИЗ. Натисніть ПРОПУСК або ENTER для вибору параметру меню. Відкрийте підменю поточного параметру, натиснувши ПРОПУСК або ENTER або СТРІЛКУ ВПРАВО. Перейдіть до батьківського елемента меню, натиснувши ESC або СТРІЛКУ ВЛІВО. Закрийте контекстне меню, натиснувши ESC.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Скринька Списків Редактора',\r
+                       legend: 'Усередині списку, перехід до наступного пункту списку виконується клавішею TAB або СТРІЛКА ВНИЗ. Перехід до попереднього елемента списку клавішею SHIFT+TAB або СТРІЛКА ВГОРУ. Натисніть ПРОПУСК або ENTER, щоб вибрати параметр списку. Натисніть клавішу ESC, щоб закрити список.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Шлях до елемента редактора',\r
+                       legend: 'Натисніть ${elementsPathFocus} для навігації між елементами панелі. Перейдіть до наступного елемента кнопкою TAB або СТРІЛКА ВПРАВО. Перейдіть до попереднього елемента кнопкою SHIFT+TAB або СТРІЛКА ВЛІВО. Натисніть ПРОПУСК або ENTER для вибору елемента в редакторі.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Команди',\r
+               items: [\r
+                       {\r
+                       name: 'Відмінити команду',\r
+                       legend: 'Натисніть ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Повторити',\r
+                       legend: 'Натисніть ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Жирний',\r
+                       legend: 'Натисніть ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Курсив',\r
+                       legend: 'Натисніть ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Підкреслений',\r
+                       legend: 'Натисніть ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Посилання',\r
+                       legend: 'Натисніть ${link}'\r
+               },\r
+                       {\r
+                       name: 'Згорнути панель інструментів',\r
+                       legend: 'Натисніть ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Доступ до попереднього місця фокусування',\r
+                       legend: 'Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування перед кареткою, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування.'\r
+               },\r
+                       {\r
+                       name: 'Доступ до наступного місця фокусування',\r
+                       legend: 'Натисніть ${accessNextSpace} для доступу до найближчої недосяжної області фокусування після каретки, наприклад: два сусідні елементи HR. Повторіть комбінацію клавіш для досягнення віддалених областей фокусування.'\r
+               },\r
+                       {\r
+                       name: 'Допомога з доступності',\r
+                       legend: 'Натисніть ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Esc',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: 'Ліва стрілка',\r
+       upArrow: 'Стрілка вгору',\r
+       rightArrow: 'Права стрілка',\r
+       downArrow: 'Стрілка вниз',\r
+       insert: 'Вставити',\r
+       leftWindowKey: 'Ліва клавіша Windows',\r
+       rightWindowKey: 'Права клавіша Windows',\r
+       selectKey: 'Виберіть клавішу',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: 'Множення',\r
+       add: 'Додати',\r
+       subtract: 'Віднімання',\r
+       decimalPoint: 'Десяткова кома',\r
+       divide: 'Ділення',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Крапка з комою',\r
+       equalSign: 'Знак рівності',\r
+       comma: 'Кома',\r
+       dash: 'Тире',\r
+       period: 'Період',\r
+       forwardSlash: 'Коса риска',\r
+       graveAccent: 'Гравіс',\r
+       openBracket: 'Відкрити дужку',\r
+       backSlash: 'Зворотна коса риска',\r
+       closeBracket: 'Закрити дужку',\r
+       singleQuote: 'Одинарні лапки'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/vi.js b/sources/plugins/a11yhelp/dialogs/lang/vi.js
new file mode 100644 (file)
index 0000000..497deb2
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'vi', {\r
+       title: 'Hướng dẫn trợ năng',\r
+       contents: 'Nội dung Hỗ trợ. Nhấn ESC để đóng hộp thoại.',\r
+       legend: [\r
+               {\r
+               name: 'Chung',\r
+               items: [\r
+                       {\r
+                       name: 'Thanh công cụ soạn thảo',\r
+                       legend: 'Nhấn ${toolbarFocus} để điều hướng đến thanh công cụ. Nhấn TAB và SHIFT+TAB để chuyển đến nhóm thanh công cụ khác. Nhấn MŨI TÊN PHẢI hoặc MŨI TÊN TRÁI để chuyển sang nút khác trên thanh công cụ. Nhấn PHÍM CÁCH hoặc ENTER để kích hoạt nút trên thanh công cụ.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Hộp thoại Biên t',\r
+                       legend:\r
+                               'Inside a dialog, press TAB to navigate to the next dialog element, press SHIFT+TAB to move to the previous dialog element, press ENTER to submit the dialog, press ESC to cancel the dialog. When a dialog has multiple tabs, the tab list can be reached either with ALT+F10 or with TAB as part of the dialog tabbing order. With tab list focused, move to the next and previous tab with RIGHT and LEFT ARROW, respectively.'  // MISSING\r
+               },\r
+\r
+                       {\r
+                       name: 'Trình đơn Ngữ cảnh cBộ soạn thảo',\r
+                       legend: 'Nhấn ${contextMenu} hoặc PHÍM ỨNG DỤNG để mở thực đơn ngữ cảnh. Sau đó nhấn TAB hoặc MŨI TÊN XUỐNG để di chuyển đến tuỳ chọn tiếp theo của thực đơn. Nhấn SHIFT+TAB hoặc MŨI TÊN LÊN để quay lại tuỳ chọn trước. Nhấn DẤU CÁCH hoặc ENTER để chọn tuỳ chọn của thực đơn. Nhấn DẤU CÁCH hoặc ENTER hoặc MŨI TÊN SANG PHẢI để mở thực đơn con của tuỳ chọn hiện tại. Nhấn ESC hoặc MŨI TÊN SANG TRÁI để quay trở lại thực đơn gốc. Nhấn ESC để đóng thực đơn ngữ cảnh.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Hộp danh sách trình biên tập',\r
+                       legend: 'Trong một danh sách chọn, di chuyển đối tượng tiếp theo với phím TAB hoặc phím mũi tên hướng xuống. Di chuyển đến đối tượng trước đó bằng cách nhấn tổ hợp phím SHIFT+TAB hoặc mũi tên hướng lên. Phím khoảng cách hoặc phím ENTER để chọn các tùy chọn trong danh sách. Nhấn phím ESC để đóng lại danh sách chọn.'\r
+               },\r
+\r
+                       {\r
+                       name: 'Thanh đường dẫn các đối tượng',\r
+                       legend: 'Nhấn ${elementsPathFocus} để điều hướng các đối tượng trong thanh đường dẫn. Di chuyển đến đối tượng tiếp theo bằng phím TAB hoặc phím mũi tên bên phải. Di chuyển đến đối tượng trước đó bằng tổ hợp phím SHIFT+TAB hoặc phím mũi tên bên trái. Nhấn phím khoảng cách hoặc ENTER để chọn đối tượng trong trình soạn thảo.'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: 'Lệnh',\r
+               items: [\r
+                       {\r
+                       name: 'Làm lại lện',\r
+                       legend: 'Ấn ${undo}'\r
+               },\r
+                       {\r
+                       name: 'Làm lại lệnh',\r
+                       legend: 'Ấn ${redo}'\r
+               },\r
+                       {\r
+                       name: 'Lệnh in đậm',\r
+                       legend: 'Ấn ${bold}'\r
+               },\r
+                       {\r
+                       name: 'Lệnh in nghiêng',\r
+                       legend: 'Ấn ${italic}'\r
+               },\r
+                       {\r
+                       name: 'Lệnh gạch dưới',\r
+                       legend: 'Ấn ${underline}'\r
+               },\r
+                       {\r
+                       name: 'Lệnh liên kết',\r
+                       legend: 'Nhấn ${link}'\r
+               },\r
+                       {\r
+                       name: 'Lệnh hiển thị thanh công cụ',\r
+                       legend: 'Nhấn${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: 'Truy cập đến lệnh tập trung vào khoảng cách trước đó',\r
+                       legend: 'Ấn ${accessPreviousSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách.'\r
+               },\r
+                       {\r
+                       name: 'Truy cập phần đối tượng lệnh khoảng trống',\r
+                       legend: 'Ấn ${accessNextSpace} để truy cập đến phần tập trung khoảng cách sau phần còn sót lại của khoảng cách gần nhất vốn không tác động đến được , thí dụ: hai yếu tố điều chỉnh HR. Lặp lại các phím kết họep này để vươn đến phần khoảng cách.'\r
+               },\r
+                       {\r
+                       name: 'Trợ giúp liên quan',\r
+                       legend: 'Nhấn ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Phím Tab',\r
+       pause: 'Phím Pause',\r
+       capslock: 'Phím Caps Lock',\r
+       escape: 'Phím Escape',\r
+       pageUp: 'Phím Page Up',\r
+       pageDown: 'Phím Page Down',\r
+       leftArrow: 'Phím Left Arrow',\r
+       upArrow: 'Phím Up Arrow',\r
+       rightArrow: 'Phím Right Arrow',\r
+       downArrow: 'Phím Down Arrow',\r
+       insert: 'Chèn',\r
+       leftWindowKey: 'Phím Left Windows',\r
+       rightWindowKey: 'Phím Right Windows ',\r
+       selectKey: 'Chọn phím',\r
+       numpad0: 'Phím 0',\r
+       numpad1: 'Phím 1',\r
+       numpad2: 'Phím 2',\r
+       numpad3: 'Phím 3',\r
+       numpad4: 'Phím 4',\r
+       numpad5: 'Phím 5',\r
+       numpad6: 'Phím 6',\r
+       numpad7: 'Phím 7',\r
+       numpad8: 'Phím 8',\r
+       numpad9: 'Phím 9',\r
+       multiply: 'Nhân',\r
+       add: 'Thêm',\r
+       subtract: 'Trừ',\r
+       decimalPoint: 'Điểm số thập phân',\r
+       divide: 'Chia',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: 'Dấu chấm phẩy',\r
+       equalSign: 'Đăng nhập bằng',\r
+       comma: 'Dấu phẩy',\r
+       dash: 'Dấu gạch ngang',\r
+       period: 'Phím .',\r
+       forwardSlash: 'Phím /',\r
+       graveAccent: 'Phím `',\r
+       openBracket: 'Open Bracket',\r
+       backSlash: 'Dấu gạch chéo ngược',\r
+       closeBracket: 'Gần giá đỡ',\r
+       singleQuote: 'Trích dẫn'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/zh-cn.js b/sources/plugins/a11yhelp/dialogs/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..d2d0f2b
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'zh-cn', {\r
+       title: '辅助功能说明',\r
+       contents: '帮助内容。要关闭此对话框请按 ESC 键。',\r
+       legend: [\r
+               {\r
+               name: '常规',\r
+               items: [\r
+                       {\r
+                       name: '编辑器工具栏',\r
+                       legend: '按 ${toolbarFocus} 切换到工具栏,使用 TAB 键和 SHIFT+TAB 组合键移动到上一个和下一个工具栏组。使用左右箭头键移动到上一个或下一个工具栏按钮。按空格键或回车键以选中工具栏按钮。'\r
+               },\r
+\r
+                       {\r
+                       name: '编辑器对话框',\r
+                       legend:\r
+                               '在对话框内,按 TAB 键移动到下一个字段,按 SHIFT + TAB 组合键移动到上一个字段,按 ENTER 键提交对话框,按 ESC 键取消对话框。对于有多选项卡的对话框,可以按 ALT + F10 直接切换到或者按 TAB 键逐步移到选项卡列表,当焦点移到选项卡列表时可以用左右箭头键来移动到前后的选项卡。'\r
+               },\r
+\r
+                       {\r
+                       name: '编辑器上下文菜单',\r
+                       legend: '用 ${contextMenu} 或者“应用程序键”打开上下文菜单。然后用 TAB 键或者下箭头键来移动到下一个菜单项;SHIFT + TAB 组合键或者上箭头键移动到上一个菜单项。用 SPACE 键或者 ENTER 键选择菜单项。用 SPACE 键,ENTER 键或者右箭头键打开子菜单。返回菜单用 ESC 键或者左箭头键。用 ESC 键关闭上下文菜单。'\r
+               },\r
+\r
+                       {\r
+                       name: '编辑器列表框',\r
+                       legend: '在列表框中,移到下一列表项用 TAB 键或者下箭头键。移到上一列表项用SHIFT+TAB 组合键或者上箭头键,用 SPACE 键或者 ENTER 键选择列表项。用 ESC 键收起列表框。'\r
+               },\r
+\r
+                       {\r
+                       name: '编辑器元素路径栏',\r
+                       legend: '按 ${elementsPathFocus} 以导航到元素路径栏,使用 TAB 键或右箭头键选择下一个元素,使用 SHIFT+TAB 组合键或左箭头键选择上一个元素,按空格键或回车键以选定编辑器里的元素。'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: '命令',\r
+               items: [\r
+                       {\r
+                       name: ' 撤消命令',\r
+                       legend: '按 ${undo}'\r
+               },\r
+                       {\r
+                       name: ' 重做命令',\r
+                       legend: '按 ${redo}'\r
+               },\r
+                       {\r
+                       name: ' 加粗命令',\r
+                       legend: '按 ${bold}'\r
+               },\r
+                       {\r
+                       name: ' 倾斜命令',\r
+                       legend: '按 ${italic}'\r
+               },\r
+                       {\r
+                       name: ' 下划线命令',\r
+                       legend: '按 ${underline}'\r
+               },\r
+                       {\r
+                       name: ' 链接命令',\r
+                       legend: '按 ${link}'\r
+               },\r
+                       {\r
+                       name: ' 工具栏折叠命令',\r
+                       legend: '按 ${toolbarCollapse}'\r
+               },\r
+                       {\r
+                       name: '访问前一个焦点区域的命令',\r
+                       legend: '按 ${accessPreviousSpace} 访问^符号前最近的不可访问的焦点区域,例如:两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。'\r
+               },\r
+                       {\r
+                       name: '访问下一个焦点区域命令',\r
+                       legend: '按 ${accessNextSpace} 以访问^符号后最近的不可访问的焦点区域。例如:两个相邻的 HR 元素。重复此组合按键可以到达远处的焦点区域。'\r
+               },\r
+                       {\r
+                       name: '辅助功能帮助',\r
+                       legend: '按 ${a11yHelp}'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab 键',\r
+       pause: '暂停键',\r
+       capslock: '大写锁定键',\r
+       escape: 'Esc 键',\r
+       pageUp: '上翻页键',\r
+       pageDown: '下翻页键',\r
+       leftArrow: '向左箭头键',\r
+       upArrow: '向上箭头键',\r
+       rightArrow: '向右箭头键',\r
+       downArrow: '向下箭头键',\r
+       insert: '插入键',\r
+       leftWindowKey: '左 WIN 键',\r
+       rightWindowKey: '右 WIN 键',\r
+       selectKey: '选择键',\r
+       numpad0: '小键盘 0 键',\r
+       numpad1: '小键盘 1 键',\r
+       numpad2: '小键盘 2 键',\r
+       numpad3: '小键盘 3 键',\r
+       numpad4: '小键盘 4 键',\r
+       numpad5: '小键盘 5 键',\r
+       numpad6: '小键盘 6 键',\r
+       numpad7: '小键盘 7 键',\r
+       numpad8: '小键盘 8 键',\r
+       numpad9: '小键盘 9 键',\r
+       multiply: '星号键',\r
+       add: '加号键',\r
+       subtract: '减号键',\r
+       decimalPoint: '小数点键',\r
+       divide: '除号键',\r
+       f1: 'F1 键',\r
+       f2: 'F2 键',\r
+       f3: 'F3 键',\r
+       f4: 'F4 键',\r
+       f5: 'F5 键',\r
+       f6: 'F6 键',\r
+       f7: 'F7 键',\r
+       f8: 'F8 键',\r
+       f9: 'F9 键',\r
+       f10: 'F10 键',\r
+       f11: 'F11 键',\r
+       f12: 'F12 键',\r
+       numLock: '数字锁定键',\r
+       scrollLock: '滚动锁定键',\r
+       semiColon: '分号键',\r
+       equalSign: '等号键',\r
+       comma: '逗号键',\r
+       dash: '短划线键',\r
+       period: '句号键',\r
+       forwardSlash: '斜杠键',\r
+       graveAccent: '重音符键',\r
+       openBracket: '左中括号键',\r
+       backSlash: '反斜杠键',\r
+       closeBracket: '右中括号键',\r
+       singleQuote: '单引号键'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/dialogs/lang/zh.js b/sources/plugins/a11yhelp/dialogs/lang/zh.js
new file mode 100644 (file)
index 0000000..0fe1310
--- /dev/null
@@ -0,0 +1,140 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'a11yhelp', 'zh', {\r
+       title: '輔助工具指南',\r
+       contents: '說明內容。若要關閉此對話框請按「ESC」。',\r
+       legend: [\r
+               {\r
+               name: '一般',\r
+               items: [\r
+                       {\r
+                       name: '編輯器工具列',\r
+                       legend: '請按 ${toolbarFocus} 以導覽到工具列。利用 TAB 或 SHIFT+TAB 以便移動到下一個及前一個工具列群組。利用右方向鍵或左方向鍵以便移動到下一個及上一個工具列按鈕。按下空白鍵或 ENTER 鍵啟用工具列按鈕。'\r
+               },\r
+\r
+                       {\r
+                       name: '編輯器對話方塊',\r
+                       legend:\r
+                               '在對話框中,按下 TAB 鍵以導覽到下一個對話框元素,按下 SHIFT+TAB 以移動到上一個對話框元素,按下 ENTER 以遞交對話框,按下 ESC 以取消對話框。當對話框有多個分頁時,可以使用 ALT+F10 或是在對話框分頁順序中的一部份按下 TAB 以使用分頁列表。焦點在分頁列表上時,分別使用右方向鍵及左方向鍵移動到下一個及上一個分頁。'\r
+               },\r
+\r
+                       {\r
+                       name: '編輯器內容功能表',\r
+                       legend: '請按下「${contextMenu}」或是「應用程式鍵」以開啟內容選單。以「TAB」或是「↓」鍵移動到下一個選單選項。以「SHIFT + TAB」或是「↑」鍵移動到上一個選單選項。按下「空白鍵」或是「ENTER」鍵以選取選單選項。以「空白鍵」或「ENTER」或「→」開啟目前選項之子選單。以「ESC」或「←」回到父選單。以「ESC」鍵關閉內容選單」。'\r
+               },\r
+\r
+                       {\r
+                       name: '編輯器清單方塊',\r
+                       legend: '在清單方塊中,使用 TAB 或下方向鍵移動到下一個列表項目。使用 SHIFT+TAB 或上方向鍵移動到上一個列表項目。按下空白鍵或 ENTER 以選取列表選項。按下 ESC 以關閉清單方塊。'\r
+               },\r
+\r
+                       {\r
+                       name: '編輯器元件路徑工具列',\r
+                       legend: '請按 ${elementsPathFocus} 以瀏覽元素路徑列。利用 TAB 或右方向鍵以便移動到下一個元素按鈕。利用 SHIFT 或左方向鍵以便移動到上一個按鈕。按下空白鍵或 ENTER 鍵來選取在編輯器中的元素。'\r
+               }\r
+               ]\r
+       },\r
+               {\r
+               name: '命令',\r
+               items: [\r
+                       {\r
+                       name: '復原命令',\r
+                       legend: '請按下「${undo}」'\r
+               },\r
+                       {\r
+                       name: '重複命令',\r
+                       legend: '請按下「 ${redo}」'\r
+               },\r
+                       {\r
+                       name: '粗體命令',\r
+                       legend: '請按下「${bold}」'\r
+               },\r
+                       {\r
+                       name: '斜體',\r
+                       legend: '請按下「${italic}」'\r
+               },\r
+                       {\r
+                       name: '底線命令',\r
+                       legend: '請按下「${underline}」'\r
+               },\r
+                       {\r
+                       name: '連結',\r
+                       legend: '請按下「${link}」'\r
+               },\r
+                       {\r
+                       name: '隱藏工具列',\r
+                       legend: '請按下「${toolbarCollapse}」'\r
+               },\r
+                       {\r
+                       name: '存取前一個焦點空間命令',\r
+                       legend: '請按下 ${accessPreviousSpace} 以存取最近但無法靠近之插字符號前的焦點空間。舉例:二個相鄰的 HR 元素。\r\n重複按鍵以存取較遠的焦點空間。'\r
+               },\r
+                       {\r
+                       name: '存取下一個焦點空間命令',\r
+                       legend: '請按下 ${accessNextSpace} 以存取最近但無法靠近之插字符號後的焦點空間。舉例:二個相鄰的 HR 元素。\r\n重複按鍵以存取較遠的焦點空間。'\r
+               },\r
+                       {\r
+                       name: '協助工具說明',\r
+                       legend: '請按下「${a11yHelp}」'\r
+               }\r
+               ]\r
+       }\r
+       ],\r
+       tab: 'Tab',\r
+       pause: 'Pause',\r
+       capslock: 'Caps Lock',\r
+       escape: 'Esc',\r
+       pageUp: 'Page Up',\r
+       pageDown: 'Page Down',\r
+       leftArrow: '向左箭號',\r
+       upArrow: '向上鍵號',\r
+       rightArrow: '向右鍵號',\r
+       downArrow: '向下鍵號',\r
+       insert: '插入',\r
+       leftWindowKey: '左方 Windows 鍵',\r
+       rightWindowKey: '右方 Windows 鍵',\r
+       selectKey: '選擇鍵',\r
+       numpad0: 'Numpad 0',\r
+       numpad1: 'Numpad 1',\r
+       numpad2: 'Numpad 2',\r
+       numpad3: 'Numpad 3',\r
+       numpad4: 'Numpad 4',\r
+       numpad5: 'Numpad 5',\r
+       numpad6: 'Numpad 6',\r
+       numpad7: 'Numpad 7',\r
+       numpad8: 'Numpad 8',\r
+       numpad9: 'Numpad 9',\r
+       multiply: '乘號',\r
+       add: '新增',\r
+       subtract: '減號',\r
+       decimalPoint: '小數點',\r
+       divide: '除號',\r
+       f1: 'F1',\r
+       f2: 'F2',\r
+       f3: 'F3',\r
+       f4: 'F4',\r
+       f5: 'F5',\r
+       f6: 'F6',\r
+       f7: 'F7',\r
+       f8: 'F8',\r
+       f9: 'F9',\r
+       f10: 'F10',\r
+       f11: 'F11',\r
+       f12: 'F12',\r
+       numLock: 'Num Lock',\r
+       scrollLock: 'Scroll Lock',\r
+       semiColon: '分號',\r
+       equalSign: '等號',\r
+       comma: '逗號',\r
+       dash: '虛線',\r
+       period: '句點',\r
+       forwardSlash: '斜線',\r
+       graveAccent: '抑音符號',\r
+       openBracket: '左方括號',\r
+       backSlash: '反斜線',\r
+       closeBracket: '右方括號',\r
+       singleQuote: '單引號'\r
+} );\r
diff --git a/sources/plugins/a11yhelp/plugin.js b/sources/plugins/a11yhelp/plugin.js
new file mode 100644 (file)
index 0000000..9e2925a
--- /dev/null
@@ -0,0 +1,51 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Plugin definition for the a11yhelp, which provides a dialog\r
+ * with accessibility related help.\r
+ */\r
+\r
+( function() {\r
+       var pluginName = 'a11yhelp',\r
+               commandName = 'a11yHelp';\r
+\r
+       CKEDITOR.plugins.add( pluginName, {\r
+               requires: 'dialog',\r
+\r
+               // List of available localizations.\r
+               // jscs:disable\r
+               availableLangs: { af:1,ar:1,az:1,bg:1,ca:1,cs:1,cy:1,da:1,de:1,'de-ch':1,el:1,en:1,'en-gb':1,eo:1,es:1,et:1,eu:1,fa:1,fi:1,fo:1,fr:1,'fr-ca':1,gl:1,gu:1,he:1,hi:1,hr:1,hu:1,id:1,it:1,ja:1,km:1,ko:1,ku:1,lt:1,lv:1,mk:1,mn:1,nb:1,nl:1,no:1,oc:1,pl:1,pt:1,'pt-br':1,ro:1,ru:1,si:1,sk:1,sl:1,sq:1,sr:1,'sr-latn':1,sv:1,th:1,tr:1,tt:1,ug:1,uk:1,vi:1,zh:1,'zh-cn':1 },\r
+               // jscs:enable\r
+\r
+               init: function( editor ) {\r
+                       var plugin = this;\r
+                       editor.addCommand( commandName, {\r
+                               exec: function() {\r
+                                       var langCode = editor.langCode;\r
+                                       langCode =\r
+                                               plugin.availableLangs[ langCode ] ? langCode :\r
+                                               plugin.availableLangs[ langCode.replace( /-.*/, '' ) ] ? langCode.replace( /-.*/, '' ) :\r
+                                               'en';\r
+\r
+                                       CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( plugin.path + 'dialogs/lang/' + langCode + '.js' ), function() {\r
+                                               editor.lang.a11yhelp = plugin.langEntries[ langCode ];\r
+                                               editor.openDialog( commandName );\r
+                                       } );\r
+                               },\r
+                               modes: { wysiwyg: 1, source: 1 },\r
+                               readOnly: 1,\r
+                               canUndo: false\r
+                       } );\r
+\r
+                       editor.setKeystroke( CKEDITOR.ALT + 48 /*0*/, 'a11yHelp' );\r
+                       CKEDITOR.dialog.add( commandName, this.path + 'dialogs/a11yhelp.js' );\r
+\r
+                       editor.on( 'ariaEditorHelpLabel', function( evt ) {\r
+                               evt.data.label = editor.lang.common.editorHelp;\r
+                       } );\r
+               }\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/basicstyles/icons/bold.png b/sources/plugins/basicstyles/icons/bold.png
new file mode 100644 (file)
index 0000000..d714916
Binary files /dev/null and b/sources/plugins/basicstyles/icons/bold.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/bold.png b/sources/plugins/basicstyles/icons/hidpi/bold.png
new file mode 100644 (file)
index 0000000..2de207d
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/bold.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/italic.png b/sources/plugins/basicstyles/icons/hidpi/italic.png
new file mode 100644 (file)
index 0000000..2c2dae4
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/italic.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/strike.png b/sources/plugins/basicstyles/icons/hidpi/strike.png
new file mode 100644 (file)
index 0000000..19c5e22
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/strike.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/subscript.png b/sources/plugins/basicstyles/icons/hidpi/subscript.png
new file mode 100644 (file)
index 0000000..585d59b
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/subscript.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/superscript.png b/sources/plugins/basicstyles/icons/hidpi/superscript.png
new file mode 100644 (file)
index 0000000..9daa12a
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/superscript.png differ
diff --git a/sources/plugins/basicstyles/icons/hidpi/underline.png b/sources/plugins/basicstyles/icons/hidpi/underline.png
new file mode 100644 (file)
index 0000000..6653814
Binary files /dev/null and b/sources/plugins/basicstyles/icons/hidpi/underline.png differ
diff --git a/sources/plugins/basicstyles/icons/italic.png b/sources/plugins/basicstyles/icons/italic.png
new file mode 100644 (file)
index 0000000..5f8aaae
Binary files /dev/null and b/sources/plugins/basicstyles/icons/italic.png differ
diff --git a/sources/plugins/basicstyles/icons/strike.png b/sources/plugins/basicstyles/icons/strike.png
new file mode 100644 (file)
index 0000000..5842b7a
Binary files /dev/null and b/sources/plugins/basicstyles/icons/strike.png differ
diff --git a/sources/plugins/basicstyles/icons/subscript.png b/sources/plugins/basicstyles/icons/subscript.png
new file mode 100644 (file)
index 0000000..db11f78
Binary files /dev/null and b/sources/plugins/basicstyles/icons/subscript.png differ
diff --git a/sources/plugins/basicstyles/icons/superscript.png b/sources/plugins/basicstyles/icons/superscript.png
new file mode 100644 (file)
index 0000000..3df28d2
Binary files /dev/null and b/sources/plugins/basicstyles/icons/superscript.png differ
diff --git a/sources/plugins/basicstyles/icons/underline.png b/sources/plugins/basicstyles/icons/underline.png
new file mode 100644 (file)
index 0000000..160be92
Binary files /dev/null and b/sources/plugins/basicstyles/icons/underline.png differ
diff --git a/sources/plugins/basicstyles/lang/af.js b/sources/plugins/basicstyles/lang/af.js
new file mode 100644 (file)
index 0000000..bcceb14
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'af', {\r
+       bold: 'Vet',\r
+       italic: 'Skuins',\r
+       strike: 'Deurgestreep',\r
+       subscript: 'Onderskrif',\r
+       superscript: 'Bo-skrif',\r
+       underline: 'Onderstreep'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ar.js b/sources/plugins/basicstyles/lang/ar.js
new file mode 100644 (file)
index 0000000..fb4adc6
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ar', {\r
+       bold: 'عريض',\r
+       italic: 'مائل',\r
+       strike: 'يتوسطه خط',\r
+       subscript: 'منخفض',\r
+       superscript: 'مرتفع',\r
+       underline: 'تسطير'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/az.js b/sources/plugins/basicstyles/lang/az.js
new file mode 100644 (file)
index 0000000..097a1ec
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'az', {\r
+       bold: 'Qalın',\r
+       italic: 'Kursiv',\r
+       strike: 'Üstüxətli',\r
+       subscript: 'Aşağı indeks',\r
+       superscript: 'Yuxarı indeks',\r
+       underline: 'Altdan xətt'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/bg.js b/sources/plugins/basicstyles/lang/bg.js
new file mode 100644 (file)
index 0000000..56f6f7d
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'bg', {\r
+       bold: 'Удебелен',\r
+       italic: 'Наклонен',\r
+       strike: 'Зачертан текст',\r
+       subscript: 'Индексиран текст',\r
+       superscript: 'Суперскрипт',\r
+       underline: 'Подчертан'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/bn.js b/sources/plugins/basicstyles/lang/bn.js
new file mode 100644 (file)
index 0000000..fd790a4
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'bn', {\r
+       bold: 'বোল্ড',\r
+       italic: 'বাঁকা',\r
+       strike: 'স্ট্রাইক থ্রু',\r
+       subscript: 'অধোলেখ',\r
+       superscript: 'অভিলেখ',\r
+       underline: 'আন্ডারলাইন'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/bs.js b/sources/plugins/basicstyles/lang/bs.js
new file mode 100644 (file)
index 0000000..9188f98
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'bs', {\r
+       bold: 'Boldiraj',\r
+       italic: 'Ukosi',\r
+       strike: 'Precrtaj',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Podvuci'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ca.js b/sources/plugins/basicstyles/lang/ca.js
new file mode 100644 (file)
index 0000000..2924d1e
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ca', {\r
+       bold: 'Negreta',\r
+       italic: 'Cursiva',\r
+       strike: 'Ratllat',\r
+       subscript: 'Subíndex',\r
+       superscript: 'Superíndex',\r
+       underline: 'Subratllat'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/cs.js b/sources/plugins/basicstyles/lang/cs.js
new file mode 100644 (file)
index 0000000..737c648
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'cs', {\r
+       bold: 'Tučné',\r
+       italic: 'Kurzíva',\r
+       strike: 'Přeškrtnuté',\r
+       subscript: 'Dolní index',\r
+       superscript: 'Horní index',\r
+       underline: 'Podtržené'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/cy.js b/sources/plugins/basicstyles/lang/cy.js
new file mode 100644 (file)
index 0000000..3acb736
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'cy', {\r
+       bold: 'Bras',\r
+       italic: 'Italig',\r
+       strike: 'Llinell Trwyddo',\r
+       subscript: 'Is-sgript',\r
+       superscript: 'Uwchsgript',\r
+       underline: 'Tanlinellu'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/da.js b/sources/plugins/basicstyles/lang/da.js
new file mode 100644 (file)
index 0000000..0b1f3e8
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'da', {\r
+       bold: 'Fed',\r
+       italic: 'Kursiv',\r
+       strike: 'Gennemstreget',\r
+       subscript: 'Sænket skrift',\r
+       superscript: 'Hævet skrift',\r
+       underline: 'Understreget'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/de-ch.js b/sources/plugins/basicstyles/lang/de-ch.js
new file mode 100644 (file)
index 0000000..2370c04
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'de-ch', {\r
+       bold: 'Fett',\r
+       italic: 'Kursiv',\r
+       strike: 'Durchgestrichen',\r
+       subscript: 'Tiefgestellt',\r
+       superscript: 'Hochgestellt',\r
+       underline: 'Unterstrichen'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/de.js b/sources/plugins/basicstyles/lang/de.js
new file mode 100644 (file)
index 0000000..fbc92e4
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'de', {\r
+       bold: 'Fett',\r
+       italic: 'Kursiv',\r
+       strike: 'Durchgestrichen',\r
+       subscript: 'Tiefgestellt',\r
+       superscript: 'Hochgestellt',\r
+       underline: 'Unterstrichen'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/el.js b/sources/plugins/basicstyles/lang/el.js
new file mode 100644 (file)
index 0000000..2c72cda
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'el', {\r
+       bold: 'Έντονη',\r
+       italic: 'Πλάγια',\r
+       strike: 'Διακριτή Διαγραφή',\r
+       subscript: 'Δείκτης',\r
+       superscript: 'Εκθέτης',\r
+       underline: 'Υπογράμμιση'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/en-au.js b/sources/plugins/basicstyles/lang/en-au.js
new file mode 100644 (file)
index 0000000..6b9dc7e
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-au', {\r
+       bold: 'Bold',\r
+       italic: 'Italic',\r
+       strike: 'Strike Through',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Underline'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/en-ca.js b/sources/plugins/basicstyles/lang/en-ca.js
new file mode 100644 (file)
index 0000000..612b2b8
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-ca', {\r
+       bold: 'Bold',\r
+       italic: 'Italic',\r
+       strike: 'Strike Through',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Underline'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/en-gb.js b/sources/plugins/basicstyles/lang/en-gb.js
new file mode 100644 (file)
index 0000000..418058e
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'en-gb', {\r
+       bold: 'Bold',\r
+       italic: 'Italic',\r
+       strike: 'Strike Through',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Underline'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/en.js b/sources/plugins/basicstyles/lang/en.js
new file mode 100644 (file)
index 0000000..3c9bc32
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'en', {\r
+       bold: 'Bold',\r
+       italic: 'Italic',\r
+       strike: 'Strikethrough',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Underline'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/eo.js b/sources/plugins/basicstyles/lang/eo.js
new file mode 100644 (file)
index 0000000..995f0c3
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'eo', {\r
+       bold: 'Grasa',\r
+       italic: 'Kursiva',\r
+       strike: 'Trastreko',\r
+       subscript: 'Suba indico',\r
+       superscript: 'Supra indico',\r
+       underline: 'Substreko'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/es.js b/sources/plugins/basicstyles/lang/es.js
new file mode 100644 (file)
index 0000000..baaf99f
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'es', {\r
+       bold: 'Negrita',\r
+       italic: 'Cursiva',\r
+       strike: 'Tachado',\r
+       subscript: 'Subíndice',\r
+       superscript: 'Superíndice',\r
+       underline: 'Subrayado'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/et.js b/sources/plugins/basicstyles/lang/et.js
new file mode 100644 (file)
index 0000000..8dee05e
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'et', {\r
+       bold: 'Paks',\r
+       italic: 'Kursiiv',\r
+       strike: 'Läbijoonitud',\r
+       subscript: 'Allindeks',\r
+       superscript: 'Ülaindeks',\r
+       underline: 'Allajoonitud'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/eu.js b/sources/plugins/basicstyles/lang/eu.js
new file mode 100644 (file)
index 0000000..7017540
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'eu', {\r
+       bold: 'Lodia',\r
+       italic: 'Etzana',\r
+       strike: 'Marratua',\r
+       subscript: 'Azpi-indizea',\r
+       superscript: 'Goi-indizea',\r
+       underline: 'Azpimarratu'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/fa.js b/sources/plugins/basicstyles/lang/fa.js
new file mode 100644 (file)
index 0000000..49343fb
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'fa', {\r
+       bold: 'درشت',\r
+       italic: 'خمیده',\r
+       strike: 'خط‌خورده',\r
+       subscript: 'زیرنویس',\r
+       superscript: 'بالانویس',\r
+       underline: 'زیرخط‌دار'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/fi.js b/sources/plugins/basicstyles/lang/fi.js
new file mode 100644 (file)
index 0000000..5e1fbce
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'fi', {\r
+       bold: 'Lihavoitu',\r
+       italic: 'Kursivoitu',\r
+       strike: 'Yliviivattu',\r
+       subscript: 'Alaindeksi',\r
+       superscript: 'Yläindeksi',\r
+       underline: 'Alleviivattu'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/fo.js b/sources/plugins/basicstyles/lang/fo.js
new file mode 100644 (file)
index 0000000..f48b73a
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'fo', {\r
+       bold: 'Feit skrift',\r
+       italic: 'Skráskrift',\r
+       strike: 'Yvirstrikað',\r
+       subscript: 'Lækkað skrift',\r
+       superscript: 'Hækkað skrift',\r
+       underline: 'Undirstrikað'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/fr-ca.js b/sources/plugins/basicstyles/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..6b8ffbf
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'fr-ca', {\r
+       bold: 'Gras',\r
+       italic: 'Italique',\r
+       strike: 'Barré',\r
+       subscript: 'Indice',\r
+       superscript: 'Exposant',\r
+       underline: 'Souligné'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/fr.js b/sources/plugins/basicstyles/lang/fr.js
new file mode 100644 (file)
index 0000000..022e438
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'fr', {\r
+       bold: 'Gras',\r
+       italic: 'Italique',\r
+       strike: 'Barré',\r
+       subscript: 'Indice',\r
+       superscript: 'Exposant',\r
+       underline: 'Souligné'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/gl.js b/sources/plugins/basicstyles/lang/gl.js
new file mode 100644 (file)
index 0000000..ebd5aa4
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'gl', {\r
+       bold: 'Negra',\r
+       italic: 'Cursiva',\r
+       strike: 'Riscado',\r
+       subscript: 'Subíndice',\r
+       superscript: 'Superíndice',\r
+       underline: 'Subliñado'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/gu.js b/sources/plugins/basicstyles/lang/gu.js
new file mode 100644 (file)
index 0000000..fc043b4
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'gu', {\r
+       bold: 'બોલ્ડ/સ્પષ્ટ',\r
+       italic: 'ઇટેલિક, ત્રાંસા',\r
+       strike: 'છેકી નાખવું',\r
+       subscript: 'એક ચિહ્નની નીચે કરેલું બીજું ચિહ્ન',\r
+       superscript: 'એક ચિહ્ન ઉપર કરેલું બીજું ચિહ્ન.',\r
+       underline: 'અન્ડર્લાઇન, નીચે લીટી'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/he.js b/sources/plugins/basicstyles/lang/he.js
new file mode 100644 (file)
index 0000000..16b16a4
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'he', {\r
+       bold: 'מודגש',\r
+       italic: 'נטוי',\r
+       strike: 'כתיב מחוק',\r
+       subscript: 'כתיב תחתון',\r
+       superscript: 'כתיב עליון',\r
+       underline: 'קו תחתון'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/hi.js b/sources/plugins/basicstyles/lang/hi.js
new file mode 100644 (file)
index 0000000..2b2fcb5
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'hi', {\r
+       bold: 'बोल्ड',\r
+       italic: 'इटैलिक',\r
+       strike: 'स्ट्राइक थ्रू',\r
+       subscript: 'अधोलेख',\r
+       superscript: 'अभिलेख',\r
+       underline: 'रेखांकण'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/hr.js b/sources/plugins/basicstyles/lang/hr.js
new file mode 100644 (file)
index 0000000..6ddfb31
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'hr', {\r
+       bold: 'Podebljaj',\r
+       italic: 'Ukosi',\r
+       strike: 'Precrtano',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Potcrtano'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/hu.js b/sources/plugins/basicstyles/lang/hu.js
new file mode 100644 (file)
index 0000000..41d3a32
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'hu', {\r
+       bold: 'Félkövér',\r
+       italic: 'Dőlt',\r
+       strike: 'Áthúzott',\r
+       subscript: 'Alsó index',\r
+       superscript: 'Felső index',\r
+       underline: 'Aláhúzott'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/id.js b/sources/plugins/basicstyles/lang/id.js
new file mode 100644 (file)
index 0000000..39e916d
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'id', {\r
+       bold: 'Huruf Tebal',\r
+       italic: 'Huruf Miring',\r
+       strike: 'Strikethrough', // MISSING\r
+       subscript: 'Subscript', // MISSING\r
+       superscript: 'Superscript', // MISSING\r
+       underline: 'Garis Bawah'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/is.js b/sources/plugins/basicstyles/lang/is.js
new file mode 100644 (file)
index 0000000..d22f80a
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'is', {\r
+       bold: 'Feitletrað',\r
+       italic: 'Skáletrað',\r
+       strike: 'Yfirstrikað',\r
+       subscript: 'Niðurskrifað',\r
+       superscript: 'Uppskrifað',\r
+       underline: 'Undirstrikað'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/it.js b/sources/plugins/basicstyles/lang/it.js
new file mode 100644 (file)
index 0000000..12d5594
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'it', {\r
+       bold: 'Grassetto',\r
+       italic: 'Corsivo',\r
+       strike: 'Barrato',\r
+       subscript: 'Pedice',\r
+       superscript: 'Apice',\r
+       underline: 'Sottolineato'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ja.js b/sources/plugins/basicstyles/lang/ja.js
new file mode 100644 (file)
index 0000000..1d7ba09
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ja', {\r
+       bold: '太字',\r
+       italic: '斜体',\r
+       strike: '打ち消し線',\r
+       subscript: '下付き',\r
+       superscript: '上付き',\r
+       underline: '下線'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ka.js b/sources/plugins/basicstyles/lang/ka.js
new file mode 100644 (file)
index 0000000..e1ea391
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ka', {\r
+       bold: 'მსხვილი',\r
+       italic: 'დახრილი',\r
+       strike: 'გადახაზული',\r
+       subscript: 'ინდექსი',\r
+       superscript: 'ხარისხი',\r
+       underline: 'გახაზული'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/km.js b/sources/plugins/basicstyles/lang/km.js
new file mode 100644 (file)
index 0000000..a55d004
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'km', {\r
+       bold: 'ដិត',\r
+       italic: 'ទ្រេត',\r
+       strike: 'គូស​បន្ទាត់​ចំ​កណ្ដាល',\r
+       subscript: 'អក្សរតូចក្រោម',\r
+       superscript: 'អក្សរតូចលើ',\r
+       underline: 'គូស​បន្ទាត់​ក្រោម'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ko.js b/sources/plugins/basicstyles/lang/ko.js
new file mode 100644 (file)
index 0000000..7a61f11
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ko', {\r
+       bold: '굵게',\r
+       italic: '기울임꼴',\r
+       strike: '취소선',\r
+       subscript: '아래 첨자',\r
+       superscript: '위 첨자',\r
+       underline: '밑줄'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ku.js b/sources/plugins/basicstyles/lang/ku.js
new file mode 100644 (file)
index 0000000..fa3c16d
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ku', {\r
+       bold: 'قەڵەو',\r
+       italic: 'لار',\r
+       strike: 'لێدان',\r
+       subscript: 'ژێرنووس',\r
+       superscript: 'سەرنووس',\r
+       underline: 'ژێرهێڵ'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/lt.js b/sources/plugins/basicstyles/lang/lt.js
new file mode 100644 (file)
index 0000000..edb6949
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'lt', {\r
+       bold: 'Pusjuodis',\r
+       italic: 'Kursyvas',\r
+       strike: 'Perbrauktas',\r
+       subscript: 'Apatinis indeksas',\r
+       superscript: 'Viršutinis indeksas',\r
+       underline: 'Pabrauktas'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/lv.js b/sources/plugins/basicstyles/lang/lv.js
new file mode 100644 (file)
index 0000000..4efd61f
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'lv', {\r
+       bold: 'Treknināts',\r
+       italic: 'Kursīvs',\r
+       strike: 'Pārsvītrots',\r
+       subscript: 'Apakšrakstā',\r
+       superscript: 'Augšrakstā',\r
+       underline: 'Pasvītrots'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/mk.js b/sources/plugins/basicstyles/lang/mk.js
new file mode 100644 (file)
index 0000000..7d56475
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'mk', {\r
+       bold: 'Здебелено',\r
+       italic: 'Накривено',\r
+       strike: 'Прецртано',\r
+       subscript: 'Долен индекс',\r
+       superscript: 'Горен индекс',\r
+       underline: 'Подвлечено'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/mn.js b/sources/plugins/basicstyles/lang/mn.js
new file mode 100644 (file)
index 0000000..71fa4da
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'mn', {\r
+       bold: 'Тод бүдүүн',\r
+       italic: 'Налуу',\r
+       strike: 'Дундуур нь зураастай болгох',\r
+       subscript: 'Суурь болгох',\r
+       superscript: 'Зэрэг болгох',\r
+       underline: 'Доогуур нь зураастай болгох'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ms.js b/sources/plugins/basicstyles/lang/ms.js
new file mode 100644 (file)
index 0000000..0fd97ee
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ms', {\r
+       bold: 'Bold',\r
+       italic: 'Italic',\r
+       strike: 'Strike Through',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Underline'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/nb.js b/sources/plugins/basicstyles/lang/nb.js
new file mode 100644 (file)
index 0000000..6ab2325
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'nb', {\r
+       bold: 'Fet',\r
+       italic: 'Kursiv',\r
+       strike: 'Gjennomstreking',\r
+       subscript: 'Senket skrift',\r
+       superscript: 'Hevet skrift',\r
+       underline: 'Understreking'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/nl.js b/sources/plugins/basicstyles/lang/nl.js
new file mode 100644 (file)
index 0000000..b2ddb86
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'nl', {\r
+       bold: 'Vet',\r
+       italic: 'Cursief',\r
+       strike: 'Doorhalen',\r
+       subscript: 'Subscript',\r
+       superscript: 'Superscript',\r
+       underline: 'Onderstrepen'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/no.js b/sources/plugins/basicstyles/lang/no.js
new file mode 100644 (file)
index 0000000..9fdcf1b
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'no', {\r
+       bold: 'Fet',\r
+       italic: 'Kursiv',\r
+       strike: 'Gjennomstreking',\r
+       subscript: 'Senket skrift',\r
+       superscript: 'Hevet skrift',\r
+       underline: 'Understreking'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/oc.js b/sources/plugins/basicstyles/lang/oc.js
new file mode 100644 (file)
index 0000000..56d7df0
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'oc', {\r
+       bold: 'Gras',\r
+       italic: 'Italica',\r
+       strike: 'Raiat',\r
+       subscript: 'Indici',\r
+       superscript: 'Exponent',\r
+       underline: 'Solinhat'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/pl.js b/sources/plugins/basicstyles/lang/pl.js
new file mode 100644 (file)
index 0000000..5739141
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'pl', {\r
+       bold: 'Pogrubienie',\r
+       italic: 'Kursywa',\r
+       strike: 'Przekreślenie',\r
+       subscript: 'Indeks dolny',\r
+       superscript: 'Indeks górny',\r
+       underline: 'Podkreślenie'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/pt-br.js b/sources/plugins/basicstyles/lang/pt-br.js
new file mode 100644 (file)
index 0000000..b1bbd20
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'pt-br', {\r
+       bold: 'Negrito',\r
+       italic: 'Itálico',\r
+       strike: 'Tachado',\r
+       subscript: 'Subscrito',\r
+       superscript: 'Sobrescrito',\r
+       underline: 'Sublinhado'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/pt.js b/sources/plugins/basicstyles/lang/pt.js
new file mode 100644 (file)
index 0000000..7421106
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'pt', {\r
+       bold: 'Negrito',\r
+       italic: 'Itálico',\r
+       strike: 'Rasurado',\r
+       subscript: 'Superior à linha',\r
+       superscript: 'Superior à linha',\r
+       underline: 'Sublinhado'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ro.js b/sources/plugins/basicstyles/lang/ro.js
new file mode 100644 (file)
index 0000000..e760a45
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ro', {\r
+       bold: 'Îngroşat (bold)',\r
+       italic: 'Înclinat (italic)',\r
+       strike: 'Tăiat (strike through)',\r
+       subscript: 'Indice (subscript)',\r
+       superscript: 'Putere (superscript)',\r
+       underline: 'Subliniat (underline)'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ru.js b/sources/plugins/basicstyles/lang/ru.js
new file mode 100644 (file)
index 0000000..0a38898
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ru', {\r
+       bold: 'Полужирный',\r
+       italic: 'Курсив',\r
+       strike: 'Зачеркнутый',\r
+       subscript: 'Подстрочный индекс',\r
+       superscript: 'Надстрочный индекс',\r
+       underline: 'Подчеркнутый'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/si.js b/sources/plugins/basicstyles/lang/si.js
new file mode 100644 (file)
index 0000000..58b5a45
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'si', {\r
+       bold: 'තද අකුරින් ලියනලද',\r
+       italic: 'බැධීඅකුරින් ලියන ලද',\r
+       strike: 'Strikethrough', // MISSING\r
+       subscript: 'Subscript', // MISSING\r
+       superscript: 'Superscript', // MISSING\r
+       underline: 'යටින් ඉරි අදින ලද'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sk.js b/sources/plugins/basicstyles/lang/sk.js
new file mode 100644 (file)
index 0000000..42e351d
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sk', {\r
+       bold: 'Tučné',\r
+       italic: 'Kurzíva',\r
+       strike: 'Prečiarknuté',\r
+       subscript: 'Dolný index',\r
+       superscript: 'Horný index',\r
+       underline: 'Podčiarknuté'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sl.js b/sources/plugins/basicstyles/lang/sl.js
new file mode 100644 (file)
index 0000000..3ccb5ba
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sl', {\r
+       bold: 'Krepko',\r
+       italic: 'Ležeče',\r
+       strike: 'Prečrtano',\r
+       subscript: 'Podpisano',\r
+       superscript: 'Nadpisano',\r
+       underline: 'Podčrtano'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sq.js b/sources/plugins/basicstyles/lang/sq.js
new file mode 100644 (file)
index 0000000..5c6d704
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sq', {\r
+       bold: 'Trash',\r
+       italic: 'Pjerrët',\r
+       strike: 'Nëpërmes',\r
+       subscript: 'Nën-skriptë',\r
+       superscript: 'Super-skriptë',\r
+       underline: 'Nënvijëzuar'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sr-latn.js b/sources/plugins/basicstyles/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..535dd50
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sr-latn', {\r
+       bold: 'Podebljano',\r
+       italic: 'Kurziv',\r
+       strike: 'Precrtano',\r
+       subscript: 'Indeks',\r
+       superscript: 'Stepen',\r
+       underline: 'Podvučeno'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sr.js b/sources/plugins/basicstyles/lang/sr.js
new file mode 100644 (file)
index 0000000..2e7564e
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sr', {\r
+       bold: 'Подебљано',\r
+       italic: 'Курзив',\r
+       strike: 'Прецртано',\r
+       subscript: 'Индекс',\r
+       superscript: 'Степен',\r
+       underline: 'Подвучено'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/sv.js b/sources/plugins/basicstyles/lang/sv.js
new file mode 100644 (file)
index 0000000..efa20a8
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'sv', {\r
+       bold: 'Fet',\r
+       italic: 'Kursiv',\r
+       strike: 'Genomstruken',\r
+       subscript: 'Nedsänkta tecken',\r
+       superscript: 'Upphöjda tecken',\r
+       underline: 'Understruken'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/th.js b/sources/plugins/basicstyles/lang/th.js
new file mode 100644 (file)
index 0000000..82cab00
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'th', {\r
+       bold: 'ตัวหนา',\r
+       italic: 'ตัวเอียง',\r
+       strike: 'ตัวขีดเส้นทับ',\r
+       subscript: 'ตัวห้อย',\r
+       superscript: 'ตัวยก',\r
+       underline: 'ตัวขีดเส้นใต้'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/tr.js b/sources/plugins/basicstyles/lang/tr.js
new file mode 100644 (file)
index 0000000..0e36c82
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'tr', {\r
+       bold: 'Kalın',\r
+       italic: 'İtalik',\r
+       strike: 'Üstü Çizgili',\r
+       subscript: 'Alt Simge',\r
+       superscript: 'Üst Simge',\r
+       underline: 'Altı Çizgili'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/tt.js b/sources/plugins/basicstyles/lang/tt.js
new file mode 100644 (file)
index 0000000..c8da547
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'tt', {\r
+       bold: 'Калын',\r
+       italic: 'Курсив',\r
+       strike: 'Сызылган',\r
+       subscript: 'Аскы индекс',\r
+       superscript: 'Өске индекс',\r
+       underline: 'Астына сызылган'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/ug.js b/sources/plugins/basicstyles/lang/ug.js
new file mode 100644 (file)
index 0000000..aa28429
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'ug', {\r
+       bold: 'توم',\r
+       italic: 'يانتۇ',\r
+       strike: 'ئۆچۈرۈش سىزىقى',\r
+       subscript: 'تۆۋەن ئىندېكس',\r
+       superscript: 'يۇقىرى ئىندېكس',\r
+       underline: 'ئاستى سىزىق'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/uk.js b/sources/plugins/basicstyles/lang/uk.js
new file mode 100644 (file)
index 0000000..3ec1acc
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'uk', {\r
+       bold: 'Жирний',\r
+       italic: 'Курсив',\r
+       strike: 'Закреслений',\r
+       subscript: 'Нижній індекс',\r
+       superscript: 'Верхній індекс',\r
+       underline: 'Підкреслений'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/vi.js b/sources/plugins/basicstyles/lang/vi.js
new file mode 100644 (file)
index 0000000..c0aaa69
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'vi', {\r
+       bold: 'Đậm',\r
+       italic: 'Nghiêng',\r
+       strike: 'Gạch xuyên ngang',\r
+       subscript: 'Chỉ số dưới',\r
+       superscript: 'Chỉ số trên',\r
+       underline: 'Gạch chân'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/zh-cn.js b/sources/plugins/basicstyles/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..f43d23d
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'zh-cn', {\r
+       bold: '加粗',\r
+       italic: '倾斜',\r
+       strike: '删除线',\r
+       subscript: '下标',\r
+       superscript: '上标',\r
+       underline: '下划线'\r
+} );\r
diff --git a/sources/plugins/basicstyles/lang/zh.js b/sources/plugins/basicstyles/lang/zh.js
new file mode 100644 (file)
index 0000000..d74943c
--- /dev/null
@@ -0,0 +1,12 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'basicstyles', 'zh', {\r
+       bold: '粗體',\r
+       italic: '斜體',\r
+       strike: '刪除線',\r
+       subscript: '下標',\r
+       superscript: '上標',\r
+       underline: '底線'\r
+} );\r
diff --git a/sources/plugins/basicstyles/plugin.js b/sources/plugins/basicstyles/plugin.js
new file mode 100644 (file)
index 0000000..4a6325a
--- /dev/null
@@ -0,0 +1,209 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'basicstyles', {\r
+       // jscs:disable maximumLineLength\r
+       lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+       // jscs:enable maximumLineLength\r
+       icons: 'bold,italic,underline,strike,subscript,superscript', // %REMOVE_LINE_CORE%\r
+       hidpi: true, // %REMOVE_LINE_CORE%\r
+       init: function( editor ) {\r
+               var order = 0;\r
+               // All buttons use the same code to register. So, to avoid\r
+               // duplications, let's use this tool function.\r
+               var addButtonCommand = function( buttonName, buttonLabel, commandName, styleDefiniton ) {\r
+                               // Disable the command if no definition is configured.\r
+                               if ( !styleDefiniton )\r
+                                       return;\r
+\r
+                               var style = new CKEDITOR.style( styleDefiniton ),\r
+                                       forms = contentForms[ commandName ];\r
+\r
+                               // Put the style as the most important form.\r
+                               forms.unshift( style );\r
+\r
+                               // Listen to contextual style activation.\r
+                               editor.attachStyleStateChange( style, function( state ) {\r
+                                       !editor.readOnly && editor.getCommand( commandName ).setState( state );\r
+                               } );\r
+\r
+                               // Create the command that can be used to apply the style.\r
+                               editor.addCommand( commandName, new CKEDITOR.styleCommand( style, {\r
+                                       contentForms: forms\r
+                               } ) );\r
+\r
+                               // Register the button, if the button plugin is loaded.\r
+                               if ( editor.ui.addButton ) {\r
+                                       editor.ui.addButton( buttonName, {\r
+                                               label: buttonLabel,\r
+                                               command: commandName,\r
+                                               toolbar: 'basicstyles,' + ( order += 10 )\r
+                                       } );\r
+                               }\r
+                       };\r
+\r
+               var contentForms = {\r
+                               bold: [\r
+                                       'strong',\r
+                                       'b',\r
+                                       [ 'span', function( el ) {\r
+                                               var fw = el.styles[ 'font-weight' ];\r
+                                               return fw == 'bold' || +fw >= 700;\r
+                                       } ]\r
+                               ],\r
+\r
+                               italic: [\r
+                                       'em',\r
+                                       'i',\r
+                                       [ 'span', function( el ) {\r
+                                               return el.styles[ 'font-style' ] == 'italic';\r
+                                       } ]\r
+                               ],\r
+\r
+                               underline: [\r
+                                       'u',\r
+                                       [ 'span', function( el ) {\r
+                                               return el.styles[ 'text-decoration' ] == 'underline';\r
+                                       } ]\r
+                               ],\r
+\r
+                               strike: [\r
+                                       's',\r
+                                       'strike',\r
+                                       [ 'span', function( el ) {\r
+                                               return el.styles[ 'text-decoration' ] == 'line-through';\r
+                                       } ]\r
+                               ],\r
+\r
+                               subscript: [\r
+                                       'sub'\r
+                               ],\r
+\r
+                               superscript: [\r
+                                       'sup'\r
+                               ]\r
+                       },\r
+                       config = editor.config,\r
+                       lang = editor.lang.basicstyles;\r
+\r
+               addButtonCommand( 'Bold', lang.bold, 'bold', config.coreStyles_bold );\r
+               addButtonCommand( 'Italic', lang.italic, 'italic', config.coreStyles_italic );\r
+               addButtonCommand( 'Underline', lang.underline, 'underline', config.coreStyles_underline );\r
+               addButtonCommand( 'Strike', lang.strike, 'strike', config.coreStyles_strike );\r
+               addButtonCommand( 'Subscript', lang.subscript, 'subscript', config.coreStyles_subscript );\r
+               addButtonCommand( 'Superscript', lang.superscript, 'superscript', config.coreStyles_superscript );\r
+\r
+               editor.setKeystroke( [\r
+                       [ CKEDITOR.CTRL + 66 /*B*/, 'bold' ],\r
+                       [ CKEDITOR.CTRL + 73 /*I*/, 'italic' ],\r
+                       [ CKEDITOR.CTRL + 85 /*U*/, 'underline' ]\r
+               ] );\r
+       }\r
+} );\r
+\r
+// Basic Inline Styles.\r
+\r
+/**\r
+ * The style definition that applies the **bold** style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             config.coreStyles_bold = { element: 'b', overrides: 'strong' };\r
+ *\r
+ *             config.coreStyles_bold = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Bold' }\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_bold = { element: 'strong', overrides: 'b' };\r
+\r
+/**\r
+ * The style definition that applies the *italics* style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             config.coreStyles_italic = { element: 'i', overrides: 'em' };\r
+ *\r
+ *             CKEDITOR.config.coreStyles_italic = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Italic' }\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_italic = { element: 'em', overrides: 'i' };\r
+\r
+/**\r
+ * The style definition that applies the <u>underline</u> style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             CKEDITOR.config.coreStyles_underline = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Underline' }\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_underline = { element: 'u' };\r
+\r
+/**\r
+ * The style definition that applies the <strike>strikethrough</strike> style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             CKEDITOR.config.coreStyles_strike = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Strikethrough' },\r
+ *                     overrides: 'strike'\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_strike = { element: 's', overrides: 'strike' };\r
+\r
+/**\r
+ * The style definition that applies the subscript style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             CKEDITOR.config.coreStyles_subscript = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Subscript' },\r
+ *                     overrides: 'sub'\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_subscript = { element: 'sub' };\r
+\r
+/**\r
+ * The style definition that applies the superscript style to the text.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_basicstyles)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/basicstyles.html).\r
+ *\r
+ *             CKEDITOR.config.coreStyles_superscript = {\r
+ *                     element: 'span',\r
+ *                     attributes: { 'class': 'Superscript' },\r
+ *                     overrides: 'sup'\r
+ *             };\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.coreStyles_superscript = { element: 'sup' };\r
diff --git a/sources/plugins/button/lang/af.js b/sources/plugins/button/lang/af.js
new file mode 100644 (file)
index 0000000..6ccebfa
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'af', {\r
+       selectedLabel: '%1 uitgekies'\r
+} );\r
diff --git a/sources/plugins/button/lang/ar.js b/sources/plugins/button/lang/ar.js
new file mode 100644 (file)
index 0000000..025068d
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ar', {\r
+       selectedLabel: '%1 (محدد)'\r
+} );\r
diff --git a/sources/plugins/button/lang/az.js b/sources/plugins/button/lang/az.js
new file mode 100644 (file)
index 0000000..30ac85e
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'az', {\r
+       selectedLabel: '%1 (seçilib)'\r
+} );\r
diff --git a/sources/plugins/button/lang/bg.js b/sources/plugins/button/lang/bg.js
new file mode 100644 (file)
index 0000000..0b146bb
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'bg', {\r
+       selectedLabel: '%1 (Избрано)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ca.js b/sources/plugins/button/lang/ca.js
new file mode 100644 (file)
index 0000000..0891d49
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ca', {\r
+       selectedLabel: '%1 (Seleccionat)'\r
+} );\r
diff --git a/sources/plugins/button/lang/cs.js b/sources/plugins/button/lang/cs.js
new file mode 100644 (file)
index 0000000..552a05c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'cs', {\r
+       selectedLabel: '%1 (Vybráno)'\r
+} );\r
diff --git a/sources/plugins/button/lang/da.js b/sources/plugins/button/lang/da.js
new file mode 100644 (file)
index 0000000..255dcc5
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'da', {\r
+       selectedLabel: '%1 (Valgt)'\r
+} );\r
diff --git a/sources/plugins/button/lang/de-ch.js b/sources/plugins/button/lang/de-ch.js
new file mode 100644 (file)
index 0000000..63430d7
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'de-ch', {\r
+       selectedLabel: '%1 (Ausgewählt)'\r
+} );\r
diff --git a/sources/plugins/button/lang/de.js b/sources/plugins/button/lang/de.js
new file mode 100644 (file)
index 0000000..dca3daa
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'de', {\r
+       selectedLabel: '%1 (Ausgewählt)'\r
+} );\r
diff --git a/sources/plugins/button/lang/el.js b/sources/plugins/button/lang/el.js
new file mode 100644 (file)
index 0000000..1718816
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'el', {\r
+       selectedLabel: '%1 (Επιλεγμένο)'\r
+} );\r
diff --git a/sources/plugins/button/lang/en-gb.js b/sources/plugins/button/lang/en-gb.js
new file mode 100644 (file)
index 0000000..d7daefc
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'en-gb', {\r
+       selectedLabel: '%1 (Selected)'\r
+} );\r
diff --git a/sources/plugins/button/lang/en.js b/sources/plugins/button/lang/en.js
new file mode 100644 (file)
index 0000000..d5c4088
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'en', {\r
+       selectedLabel: '%1 (Selected)'\r
+} );\r
diff --git a/sources/plugins/button/lang/eo.js b/sources/plugins/button/lang/eo.js
new file mode 100644 (file)
index 0000000..acf0c13
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'eo', {\r
+       selectedLabel: '%1 (Selektita)'\r
+} );\r
diff --git a/sources/plugins/button/lang/es.js b/sources/plugins/button/lang/es.js
new file mode 100644 (file)
index 0000000..cb46c6f
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'es', {\r
+       selectedLabel: '%1 (Seleccionado)'\r
+} );\r
diff --git a/sources/plugins/button/lang/eu.js b/sources/plugins/button/lang/eu.js
new file mode 100644 (file)
index 0000000..c49d92a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'eu', {\r
+       selectedLabel: '%1 (hautatuta)'\r
+} );\r
diff --git a/sources/plugins/button/lang/fa.js b/sources/plugins/button/lang/fa.js
new file mode 100644 (file)
index 0000000..358c88a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'fa', {\r
+       selectedLabel: '%1 (انتخاب شده)'\r
+} );\r
diff --git a/sources/plugins/button/lang/fi.js b/sources/plugins/button/lang/fi.js
new file mode 100644 (file)
index 0000000..4822e74
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'fi', {\r
+       selectedLabel: '%1 (Valittu)'\r
+} );\r
diff --git a/sources/plugins/button/lang/fr.js b/sources/plugins/button/lang/fr.js
new file mode 100644 (file)
index 0000000..1b1c6d3
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'fr', {\r
+       selectedLabel: '%1 (Sélectionné)'\r
+} );\r
diff --git a/sources/plugins/button/lang/gl.js b/sources/plugins/button/lang/gl.js
new file mode 100644 (file)
index 0000000..3e4e0b7
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'gl', {\r
+       selectedLabel: '%1 (seleccionado)'\r
+} );\r
diff --git a/sources/plugins/button/lang/he.js b/sources/plugins/button/lang/he.js
new file mode 100644 (file)
index 0000000..c67afb6
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'he', {\r
+       selectedLabel: '1% (סומן)'\r
+} );\r
diff --git a/sources/plugins/button/lang/hu.js b/sources/plugins/button/lang/hu.js
new file mode 100644 (file)
index 0000000..0dffac1
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'hu', {\r
+       selectedLabel: '%1 (Kiválasztva)'\r
+} );\r
diff --git a/sources/plugins/button/lang/id.js b/sources/plugins/button/lang/id.js
new file mode 100644 (file)
index 0000000..f973ffc
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'id', {\r
+       selectedLabel: '%1(Dipilih)'\r
+} );\r
diff --git a/sources/plugins/button/lang/it.js b/sources/plugins/button/lang/it.js
new file mode 100644 (file)
index 0000000..359dc9a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'it', {\r
+       selectedLabel: '%1 (selezionato)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ja.js b/sources/plugins/button/lang/ja.js
new file mode 100644 (file)
index 0000000..e2b064f
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ja', {\r
+       selectedLabel: '%1 (選択中)'\r
+} );\r
diff --git a/sources/plugins/button/lang/km.js b/sources/plugins/button/lang/km.js
new file mode 100644 (file)
index 0000000..9437a2f
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'km', {\r
+       selectedLabel: '%1 (បាន​ជ្រើស​រើស)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ko.js b/sources/plugins/button/lang/ko.js
new file mode 100644 (file)
index 0000000..64ad966
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ko', {\r
+       selectedLabel: '%1 (선택됨)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ku.js b/sources/plugins/button/lang/ku.js
new file mode 100644 (file)
index 0000000..d342dd0
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ku', {\r
+       selectedLabel: '%1 (هەڵبژێردراو)'\r
+} );\r
diff --git a/sources/plugins/button/lang/lt.js b/sources/plugins/button/lang/lt.js
new file mode 100644 (file)
index 0000000..b492bd5
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'lt', {\r
+       selectedLabel: '%1 (Pasirinkta)'\r
+} );\r
diff --git a/sources/plugins/button/lang/nb.js b/sources/plugins/button/lang/nb.js
new file mode 100644 (file)
index 0000000..8d38121
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'nb', {\r
+       selectedLabel: '%1 (Valgt)'\r
+} );\r
diff --git a/sources/plugins/button/lang/nl.js b/sources/plugins/button/lang/nl.js
new file mode 100644 (file)
index 0000000..3e00f80
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'nl', {\r
+       selectedLabel: '%1 (Geselecteerd)'\r
+} );\r
diff --git a/sources/plugins/button/lang/no.js b/sources/plugins/button/lang/no.js
new file mode 100644 (file)
index 0000000..e6252b1
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'no', {\r
+       selectedLabel: '%1 (Valgt)'\r
+} );\r
diff --git a/sources/plugins/button/lang/oc.js b/sources/plugins/button/lang/oc.js
new file mode 100644 (file)
index 0000000..cb91761
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'oc', {\r
+       selectedLabel: '%1 (Seleccionat)'\r
+} );\r
diff --git a/sources/plugins/button/lang/pl.js b/sources/plugins/button/lang/pl.js
new file mode 100644 (file)
index 0000000..304d07a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'pl', {\r
+       selectedLabel: '%1 (Wybrany)'\r
+} );\r
diff --git a/sources/plugins/button/lang/pt-br.js b/sources/plugins/button/lang/pt-br.js
new file mode 100644 (file)
index 0000000..e3fdf84
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'pt-br', {\r
+       selectedLabel: '%1 (Selecionado)'\r
+} );\r
diff --git a/sources/plugins/button/lang/pt.js b/sources/plugins/button/lang/pt.js
new file mode 100644 (file)
index 0000000..e02c45a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'pt', {\r
+       selectedLabel: '%1 (Selecionado)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ro.js b/sources/plugins/button/lang/ro.js
new file mode 100644 (file)
index 0000000..0669dd5
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ro', {\r
+       selectedLabel: '%1 (Selectat)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ru.js b/sources/plugins/button/lang/ru.js
new file mode 100644 (file)
index 0000000..085f6ee
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ru', {\r
+       selectedLabel: '%1 (Выбрано)'\r
+} );\r
diff --git a/sources/plugins/button/lang/sk.js b/sources/plugins/button/lang/sk.js
new file mode 100644 (file)
index 0000000..12bec80
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'sk', {\r
+       selectedLabel: '%1 (Vybrané)'\r
+} );\r
diff --git a/sources/plugins/button/lang/sl.js b/sources/plugins/button/lang/sl.js
new file mode 100644 (file)
index 0000000..c6633ae
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'sl', {\r
+       selectedLabel: '%1 (Izbrano)'\r
+} );\r
diff --git a/sources/plugins/button/lang/sq.js b/sources/plugins/button/lang/sq.js
new file mode 100644 (file)
index 0000000..2e53e4c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'sq', {\r
+       selectedLabel: '%1 (Përzgjedhur)'\r
+} );\r
diff --git a/sources/plugins/button/lang/sv.js b/sources/plugins/button/lang/sv.js
new file mode 100644 (file)
index 0000000..b89e475
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'sv', {\r
+       selectedLabel: '%1 (Vald)'\r
+} );\r
diff --git a/sources/plugins/button/lang/tr.js b/sources/plugins/button/lang/tr.js
new file mode 100644 (file)
index 0000000..30d3670
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'tr', {\r
+       selectedLabel: '%1 (Seçilmiş)'\r
+} );\r
diff --git a/sources/plugins/button/lang/tt.js b/sources/plugins/button/lang/tt.js
new file mode 100644 (file)
index 0000000..6324922
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'tt', {\r
+       selectedLabel: '%1 (Сайланган)'\r
+} );\r
diff --git a/sources/plugins/button/lang/ug.js b/sources/plugins/button/lang/ug.js
new file mode 100644 (file)
index 0000000..fa3a90c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'ug', {\r
+       selectedLabel: '%1 (تاللاندى)'\r
+} );\r
diff --git a/sources/plugins/button/lang/uk.js b/sources/plugins/button/lang/uk.js
new file mode 100644 (file)
index 0000000..7b49fe2
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'uk', {\r
+       selectedLabel: '%1 (Вибрано)'\r
+} );\r
diff --git a/sources/plugins/button/lang/vi.js b/sources/plugins/button/lang/vi.js
new file mode 100644 (file)
index 0000000..b6a5911
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'vi', {\r
+       selectedLabel: '%1 (Đã chọn)'\r
+} );\r
diff --git a/sources/plugins/button/lang/zh-cn.js b/sources/plugins/button/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..fade7d7
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'zh-cn', {\r
+       selectedLabel: '已选中 %1 项'\r
+} );\r
diff --git a/sources/plugins/button/lang/zh.js b/sources/plugins/button/lang/zh.js
new file mode 100644 (file)
index 0000000..7479462
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'button', 'zh', {\r
+       selectedLabel: '%1 (已選取)'\r
+} );\r
diff --git a/sources/plugins/button/plugin.js b/sources/plugins/button/plugin.js
new file mode 100644 (file)
index 0000000..6d2db33
--- /dev/null
@@ -0,0 +1,389 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       var template = '<a id="{id}"' +\r
+               ' class="cke_button cke_button__{name} cke_button_{state} {cls}"' +\r
+               ( CKEDITOR.env.gecko && !CKEDITOR.env.hc ? '' : ' href="javascript:void(\'{titleJs}\')"' ) +\r
+               ' title="{title}"' +\r
+               ' tabindex="-1"' +\r
+               ' hidefocus="true"' +\r
+               ' role="button"' +\r
+               ' aria-labelledby="{id}_label"' +\r
+               ' aria-describedby="{id}_description"' +\r
+               ' aria-haspopup="{hasArrow}"' +\r
+               ' aria-disabled="{ariaDisabled}"';\r
+\r
+       // Some browsers don't cancel key events in the keydown but in the\r
+       // keypress.\r
+       // TODO: Check if really needed.\r
+       if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )\r
+               template += ' onkeypress="return false;"';\r
+\r
+       // With Firefox, we need to force the button to redraw, otherwise it\r
+       // will remain in the focus state.\r
+       if ( CKEDITOR.env.gecko )\r
+               template += ' onblur="this.style.cssText = this.style.cssText;"';\r
+\r
+       template += ' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event);"' +\r
+               ' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' +\r
+               ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // #188\r
+                       '="CKEDITOR.tools.callFunction({clickFn},this);return false;">' +\r
+               '<span class="cke_button_icon cke_button__{iconName}_icon" style="{style}"';\r
+\r
+\r
+       template += '>&nbsp;</span>' +\r
+               '<span id="{id}_label" class="cke_button_label cke_button__{name}_label" aria-hidden="false">{label}</span>' +\r
+               '<span id="{id}_description" class="cke_button_label" aria-hidden="false">{ariaShortcut}</span>' +\r
+               '{arrowHtml}' +\r
+               '</a>';\r
+\r
+       var templateArrow = '<span class="cke_button_arrow">' +\r
+               // BLACK DOWN-POINTING TRIANGLE\r
+       ( CKEDITOR.env.hc ? '&#9660;' : '' ) +\r
+               '</span>';\r
+\r
+       var btnArrowTpl = CKEDITOR.addTemplate( 'buttonArrow', templateArrow ),\r
+               btnTpl = CKEDITOR.addTemplate( 'button', template );\r
+\r
+       CKEDITOR.plugins.add( 'button', {\r
+               lang: 'af,ar,az,bg,ca,cs,da,de,de-ch,el,en,en-gb,eo,es,eu,fa,fi,fr,gl,he,hu,id,it,ja,km,ko,ku,lt,nb,nl,no,oc,pl,pt,pt-br,ro,ru,sk,sl,sq,sv,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               beforeInit: function( editor ) {\r
+                       editor.ui.addHandler( CKEDITOR.UI_BUTTON, CKEDITOR.ui.button.handler );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * Button UI element.\r
+        *\r
+        * @readonly\r
+        * @property {String} [='button']\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.UI_BUTTON = 'button';\r
+\r
+       /**\r
+        * Represents a button UI element. This class should not be called directly. To\r
+        * create new buttons use {@link CKEDITOR.ui#addButton} instead.\r
+        *\r
+        * @class\r
+        * @constructor Creates a button class instance.\r
+        * @param {Object} definition The button definition.\r
+        */\r
+       CKEDITOR.ui.button = function( definition ) {\r
+               CKEDITOR.tools.extend( this, definition,\r
+               // Set defaults.\r
+               {\r
+                       title: definition.label,\r
+                       click: definition.click ||\r
+                       function( editor ) {\r
+                               editor.execCommand( definition.command );\r
+                       }\r
+               } );\r
+\r
+               this._ = {};\r
+       };\r
+\r
+       /**\r
+        * Represents the button handler object.\r
+        *\r
+        * @class\r
+        * @singleton\r
+        * @extends CKEDITOR.ui.handlerDefinition\r
+        */\r
+       CKEDITOR.ui.button.handler = {\r
+               /**\r
+                * Transforms a button definition in a {@link CKEDITOR.ui.button} instance.\r
+                *\r
+                * @member CKEDITOR.ui.button.handler\r
+                * @param {Object} definition\r
+                * @returns {CKEDITOR.ui.button}\r
+                */\r
+               create: function( definition ) {\r
+                       return new CKEDITOR.ui.button( definition );\r
+               }\r
+       };\r
+\r
+       /** @class CKEDITOR.ui.button */\r
+       CKEDITOR.ui.button.prototype = {\r
+               /**\r
+                * Renders the button.\r
+                *\r
+                * @param {CKEDITOR.editor} editor The editor instance which this button is\r
+                * to be used by.\r
+                * @param {Array} output The output array to which the HTML code related to\r
+                * this button should be appended.\r
+                */\r
+               render: function( editor, output ) {\r
+                       function updateState() {\r
+                               // "this" is a CKEDITOR.ui.button instance.\r
+                               var mode = editor.mode;\r
+\r
+                               if ( mode ) {\r
+                                       // Restore saved button state.\r
+                                       var state = this.modes[ mode ] ? modeStates[ mode ] !== undefined ? modeStates[ mode ] : CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;\r
+\r
+                                       state = editor.readOnly && !this.readOnly ? CKEDITOR.TRISTATE_DISABLED : state;\r
+\r
+                                       this.setState( state );\r
+\r
+                                       // Let plugin to disable button.\r
+                                       if ( this.refresh )\r
+                                               this.refresh();\r
+                               }\r
+                       }\r
+\r
+                       var env = CKEDITOR.env,\r
+                               id = this._.id = CKEDITOR.tools.getNextId(),\r
+                               stateName = '',\r
+                               command = this.command,\r
+                               // Get the command name.\r
+                               clickFn,\r
+                               keystroke,\r
+                               shortcut;\r
+\r
+                       this._.editor = editor;\r
+\r
+                       var instance = {\r
+                               id: id,\r
+                               button: this,\r
+                               editor: editor,\r
+                               focus: function() {\r
+                                       var element = CKEDITOR.document.getById( id );\r
+                                       element.focus();\r
+                               },\r
+                               execute: function() {\r
+                                       this.button.click( editor );\r
+                               },\r
+                               attach: function( editor ) {\r
+                                       this.button.attach( editor );\r
+                               }\r
+                       };\r
+\r
+                       var keydownFn = CKEDITOR.tools.addFunction( function( ev ) {\r
+                               if ( instance.onkey ) {\r
+                                       ev = new CKEDITOR.dom.event( ev );\r
+                                       return ( instance.onkey( instance, ev.getKeystroke() ) !== false );\r
+                               }\r
+                       } );\r
+\r
+                       var focusFn = CKEDITOR.tools.addFunction( function( ev ) {\r
+                               var retVal;\r
+\r
+                               if ( instance.onfocus )\r
+                                       retVal = ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false );\r
+\r
+                               return retVal;\r
+                       } );\r
+\r
+                       var selLocked = 0;\r
+\r
+                       instance.clickFn = clickFn = CKEDITOR.tools.addFunction( function() {\r
+\r
+                               // Restore locked selection in Opera.\r
+                               if ( selLocked ) {\r
+                                       editor.unlockSelection( 1 );\r
+                                       selLocked = 0;\r
+                               }\r
+                               instance.execute();\r
+\r
+                               // Fixed iOS focus issue when your press disabled button (#12381).\r
+                               if ( env.iOS ) {\r
+                                       editor.focus();\r
+                               }\r
+                       } );\r
+\r
+\r
+                       // Indicate a mode sensitive button.\r
+                       if ( this.modes ) {\r
+                               var modeStates = {};\r
+\r
+                               editor.on( 'beforeModeUnload', function() {\r
+                                       if ( editor.mode && this._.state != CKEDITOR.TRISTATE_DISABLED )\r
+                                               modeStates[ editor.mode ] = this._.state;\r
+                               }, this );\r
+\r
+                               // Update status when activeFilter, mode or readOnly changes.\r
+                               editor.on( 'activeFilterChange', updateState, this );\r
+                               editor.on( 'mode', updateState, this );\r
+                               // If this button is sensitive to readOnly state, update it accordingly.\r
+                               !this.readOnly && editor.on( 'readOnly', updateState, this );\r
+\r
+                       } else if ( command ) {\r
+                               // Get the command instance.\r
+                               command = editor.getCommand( command );\r
+\r
+                               if ( command ) {\r
+                                       command.on( 'state', function() {\r
+                                               this.setState( command.state );\r
+                                       }, this );\r
+\r
+                                       stateName += ( command.state == CKEDITOR.TRISTATE_ON ? 'on' : command.state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off' );\r
+                               }\r
+                       }\r
+\r
+                       // For button that has text-direction awareness on selection path.\r
+                       if ( this.directional ) {\r
+                               editor.on( 'contentDirChanged', function( evt ) {\r
+                                       var el = CKEDITOR.document.getById( this._.id ),\r
+                                               icon = el.getFirst();\r
+\r
+                                       var pathDir = evt.data;\r
+\r
+                                       // Make a minor direction change to become style-able for the skin icon.\r
+                                       if ( pathDir !=  editor.lang.dir )\r
+                                               el.addClass( 'cke_' + pathDir );\r
+                                       else\r
+                                               el.removeClass( 'cke_ltr' ).removeClass( 'cke_rtl' );\r
+\r
+                                       // Inline style update for the plugin icon.\r
+                                       icon.setAttribute( 'style', CKEDITOR.skin.getIconStyle( iconName, pathDir == 'rtl', this.icon, this.iconOffset ) );\r
+                               }, this );\r
+                       }\r
+\r
+                       if ( !command ) {\r
+                               stateName += 'off';\r
+                       } else {\r
+                               keystroke = editor.getCommandKeystroke( command );\r
+\r
+                               if ( keystroke ) {\r
+                                       shortcut = CKEDITOR.tools.keystrokeToString( editor.lang.common.keyboard, keystroke );\r
+                               }\r
+                       }\r
+\r
+                       var name = this.name || this.command,\r
+                               iconName = name;\r
+\r
+                       // Check if we're pointing to an icon defined by another command. (#9555)\r
+                       if ( this.icon && !( /\./ ).test( this.icon ) ) {\r
+                               iconName = this.icon;\r
+                               this.icon = null;\r
+                       }\r
+\r
+                       var params = {\r
+                               id: id,\r
+                               name: name,\r
+                               iconName: iconName,\r
+                               label: this.label,\r
+                               cls: this.className || '',\r
+                               state: stateName,\r
+                               ariaDisabled: stateName == 'disabled' ? 'true' : 'false',\r
+                               title: this.title + ( shortcut ? ' (' + shortcut.display + ')' : '' ),\r
+                               ariaShortcut: shortcut ? editor.lang.common.keyboardShortcut + ' ' + shortcut.aria : '',\r
+                               titleJs: env.gecko && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ),\r
+                               hasArrow: this.hasArrow ? 'true' : 'false',\r
+                               keydownFn: keydownFn,\r
+                               focusFn: focusFn,\r
+                               clickFn: clickFn,\r
+                               style: CKEDITOR.skin.getIconStyle( iconName, ( editor.lang.dir == 'rtl' ), this.icon, this.iconOffset ),\r
+                               arrowHtml: this.hasArrow ? btnArrowTpl.output() : ''\r
+                       };\r
+\r
+                       btnTpl.output( params, output );\r
+\r
+                       if ( this.onRender )\r
+                               this.onRender();\r
+\r
+                       return instance;\r
+               },\r
+\r
+               /**\r
+                * Sets the button state.\r
+                *\r
+                * @param {Number} state Indicates the button state. One of {@link CKEDITOR#TRISTATE_ON},\r
+                * {@link CKEDITOR#TRISTATE_OFF}, or {@link CKEDITOR#TRISTATE_DISABLED}.\r
+                */\r
+               setState: function( state ) {\r
+                       if ( this._.state == state )\r
+                               return false;\r
+\r
+                       this._.state = state;\r
+\r
+                       var element = CKEDITOR.document.getById( this._.id );\r
+\r
+                       if ( element ) {\r
+                               element.setState( state, 'cke_button' );\r
+\r
+                               state == CKEDITOR.TRISTATE_DISABLED ?\r
+                                       element.setAttribute( 'aria-disabled', true ) :\r
+                                       element.removeAttribute( 'aria-disabled' );\r
+\r
+                               if ( !this.hasArrow ) {\r
+                                       // Note: aria-pressed attribute should not be added to menuButton instances. (#11331)\r
+                                       state == CKEDITOR.TRISTATE_ON ?\r
+                                               element.setAttribute( 'aria-pressed', true ) :\r
+                                               element.removeAttribute( 'aria-pressed' );\r
+                               } else {\r
+                                       var newLabel = state == CKEDITOR.TRISTATE_ON ?\r
+                                               this._.editor.lang.button.selectedLabel.replace( /%1/g, this.label ) : this.label;\r
+                                       CKEDITOR.document.getById( this._.id + '_label' ).setText( newLabel );\r
+                               }\r
+\r
+                               return true;\r
+                       } else {\r
+                               return false;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Gets the button state.\r
+                *\r
+                * @returns {Number} The button state. One of {@link CKEDITOR#TRISTATE_ON},\r
+                * {@link CKEDITOR#TRISTATE_OFF}, or {@link CKEDITOR#TRISTATE_DISABLED}.\r
+                */\r
+               getState: function() {\r
+                       return this._.state;\r
+               },\r
+\r
+               /**\r
+                * Returns this button's {@link CKEDITOR.feature} instance.\r
+                *\r
+                * It may be this button instance if it has at least one of\r
+                * `allowedContent` and `requiredContent` properties. Otherwise,\r
+                * if a command is bound to this button by the `command` property, then\r
+                * that command will be returned.\r
+                *\r
+                * This method implements the {@link CKEDITOR.feature#toFeature} interface method.\r
+                *\r
+                * @since 4.1\r
+                * @param {CKEDITOR.editor} Editor instance.\r
+                * @returns {CKEDITOR.feature} The feature.\r
+                */\r
+               toFeature: function( editor ) {\r
+                       if ( this._.feature )\r
+                               return this._.feature;\r
+\r
+                       var feature = this;\r
+\r
+                       // If button isn't a feature, return command if is bound.\r
+                       if ( !this.allowedContent && !this.requiredContent && this.command )\r
+                               feature = editor.getCommand( this.command ) || feature;\r
+\r
+                       return this._.feature = feature;\r
+               }\r
+       };\r
+\r
+       /**\r
+        * Adds a button definition to the UI elements list.\r
+        *\r
+        *              editorInstance.ui.addButton( 'MyBold', {\r
+        *                      label: 'My Bold',\r
+        *                      command: 'bold',\r
+        *                      toolbar: 'basicstyles,1'\r
+        *              } );\r
+        *\r
+        * @member CKEDITOR.ui\r
+        * @param {String} name The button name.\r
+        * @param {Object} definition The button definition.\r
+        * @param {String} definition.label The textual part of the button (if visible) and its tooltip.\r
+        * @param {String} definition.command The command to be executed once the button is activated.\r
+        * @param {String} definition.toolbar The {@link CKEDITOR.config#toolbarGroups toolbar group} into which\r
+        * the button will be added. An optional index value (separated by a comma) determines the button position within the group.\r
+        */\r
+       CKEDITOR.ui.prototype.addButton = function( name, definition ) {\r
+               this.add( name, CKEDITOR.UI_BUTTON, definition );\r
+       };\r
+\r
+} )();\r
diff --git a/sources/plugins/clipboard/dev/clipboard.html b/sources/plugins/clipboard/dev/clipboard.html
new file mode 100644 (file)
index 0000000..735d00e
--- /dev/null
@@ -0,0 +1,190 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Clipboard playground &ndash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <style>\r
+body {\r
+       margin: 0;\r
+}\r
+\r
+#editables, #console\r
+{\r
+       width: 48%;\r
+}\r
+#editable {\r
+       padding: 5px 10px;\r
+}\r
+\r
+#console {\r
+       position: fixed;\r
+       top: 10px;\r
+       right: 30px;\r
+       height: 500px;\r
+       border: solid 3px #555;\r
+       overflow: auto;\r
+}\r
+#console > p {\r
+       border-bottom: solid 1px #555;\r
+       margin: 0;\r
+       padding: 0 5px;\r
+       background: rgba(0, 0, 0, 0.25);\r
+       transition: background-color 1s;\r
+}\r
+#console > p.old {\r
+       background: rgba(0, 0, 0, 0);\r
+}\r
+#console time, #console .prompt {\r
+       padding: 0 5px;\r
+       display: inline-block;\r
+}\r
+#console time {\r
+       background: #999;\r
+       background: rgba(0, 0, 0, 0.5 );\r
+       color: #FFF;\r
+       margin-left: -5px;\r
+}\r
+#console .prompt {\r
+       background: #DDD;\r
+       background: rgba(0, 0, 0, 0.1 );\r
+       min-width: 200px;\r
+}\r
+.someClass {\r
+       color: blue;\r
+}\r
+.specChar {\r
+       color: #777;\r
+       background-color: #EEE;\r
+       background-color: rgba(0, 0, 0, 0.1);\r
+       font-size: 0.8em;\r
+       border-radius: 2px;\r
+       padding: 1px;\r
+}\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               CKEditor Sample &mdash; clipboard plugin playground\r
+       </h1>\r
+       <div id="editables">\r
+               <p>\r
+                       <label for="editor1">\r
+                               Editor 1:</label>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               </p>\r
+               <p>\r
+                       <label for="editor2">\r
+                               Editor 2:</label>\r
+                       <textarea cols="80" id="editor2" name="editor2" rows="10">&lt;p&gt;This is more &lt;strong class="MsoNormal"&gt;sample text&lt;/strong&gt;.&lt;/p&gt;</textarea>\r
+               </p>\r
+               <p>\r
+                       <label for="editor3">\r
+                               Editor 3:</label>\r
+                       <textarea cols="80" id="editor3" name="editor3" rows="10">&lt;p&gt;This editor &lt;strong&gt;forces pasting in text mode&lt;/strong&gt; by listening for "beforePaste" event.&lt;/p&gt;</textarea>\r
+               </p>\r
+               <p>\r
+                       <label for="editor4">\r
+                               Editor 4:</label>\r
+                       <textarea cols="80" id="editor4" name="editor4" rows="10">&lt;p&gt;This editor &lt;strong&gt;forces pasting in text mode&lt;/strong&gt; by "forcePasteAsPlainText" config option.&lt;/p&gt;</textarea>\r
+               </p>\r
+               <p>\r
+                       <label for="editor5">\r
+                               Editor 5:</label>\r
+                       <textarea cols="80" id="editor5" name="editor5" rows="10">Editor with autoParagraphing set to off.</textarea>\r
+               </p>\r
+               <div id="editor6" contenteditable="true" style="font-family: Georgia; font-size: 14px">\r
+                       <h1>Editor 6</h1>\r
+                       <p>Content content content.</p>\r
+                       <p class="someClass">Styled by <code>.someClass</code>.</p>\r
+               </div>\r
+       </div>\r
+       <div id="console">\r
+       </div>\r
+       <script>\r
+( function()\r
+{\r
+       'use strict';\r
+\r
+       var log = window.__log = function( title, msg ) {\r
+               var msgEl = new CKEDITOR.dom.element( 'p' ),\r
+                       consoleEl = CKEDITOR.document.getById( 'console' ),\r
+                       time = new Date().toString().match( /\d\d:\d\d:\d\d/ )[ 0 ],\r
+                       format = function( tpl ) {\r
+                               return tpl.replace( /{time}/g, time ).replace( '{title}', title ).replace( '{msg}', msg || '' );\r
+                       };\r
+\r
+               window.console && console.log && console.log( format( '[{time}] {title}: {msg}' ) );\r
+\r
+               msg = ( msg || '' ).replace( /\r/g, '{\\r}' ).replace( /\n/g, '{\\n}' ).replace( /\t/g, '{\\t}' );\r
+               msg = CKEDITOR.tools.htmlEncode( msg );\r
+               msg = msg.replace( /\{(\\\w)\}/g, '<code class="specChar">$1</code>' );\r
+\r
+               msgEl.setHtml( format( '<time datetime="{time}">{time}</time><span class="prompt">{title}</span> {msg}' ) );\r
+               consoleEl.append( msgEl );\r
+               consoleEl.$.scrollTop = consoleEl.$.scrollHeight;\r
+               setTimeout( function() { msgEl.addClass( 'old' ); }, 250 );\r
+       };\r
+\r
+       var observe = function( editor, num ) {\r
+               var p = 'EDITOR ' + num + ' > ';\r
+\r
+               editor.on( 'paste', function( event ) {\r
+                       log( p + 'paste(prior:-1)', event.data.type + ' - "' + event.data.dataValue + '"' );\r
+               }, null, null, -1 );\r
+               editor.on( 'paste', function( event ) {\r
+                       log( p + 'paste(prior:10)', event.data.type + ' - "' + event.data.dataValue + '"' );\r
+               } );\r
+               editor.on( 'paste', function( event ) {\r
+                       log( p + 'paste(prior:999)', event.data.type + ' - "' + event.data.dataValue + '"' );\r
+               }, null, null, 999 );\r
+               editor.on( 'beforePaste', function( event ) {\r
+                       log( p + 'beforePaste', event.data.type );\r
+               } );\r
+               editor.on( 'beforePaste', function( event ) {\r
+                       log( p + 'beforePaste(prior:999)', event.data.type );\r
+               }, null, null, 999 );\r
+               editor.on( 'afterPaste', function( event ) {\r
+                       log( p + 'afterPaste' );\r
+               } );\r
+               editor.on( 'copy', function( event ) {\r
+                       log( p + 'copy' );\r
+               } );\r
+               editor.on( 'cut', function( event ) {\r
+                       log( p + 'cut' );\r
+               } );\r
+       };\r
+\r
+       CKEDITOR.disableAutoInline = true;\r
+       var config = {\r
+                       height: 120,\r
+                       toolbar: [ [ 'Source' ] ],\r
+                       allowedContent: true\r
+               },\r
+               editor1 = CKEDITOR.replace( 'editor1', config ),\r
+               editor2 = CKEDITOR.replace( 'editor2', config ),\r
+               editor3 = CKEDITOR.replace( 'editor3', config ),\r
+               editor4 = CKEDITOR.replace( 'editor4', CKEDITOR.tools.extend( { forcePasteAsPlainText: true }, config ) ),\r
+               editor5 = CKEDITOR.replace( 'editor5', CKEDITOR.tools.extend( { autoParagraph: false }, config ) ),\r
+               editor6 = CKEDITOR.inline( document.getElementById( 'editor6' ), config );\r
+\r
+       editor3.on( 'beforePaste', function( evt ) {\r
+               evt.data.type = 'text';\r
+       } );\r
+\r
+       observe( editor1, 1 );\r
+       observe( editor2, 2 );\r
+       observe( editor3, 3 );\r
+       observe( editor4, 4 );\r
+       observe( editor5, 5 );\r
+       observe( editor6, 6 );\r
+\r
+})();\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/clipboard/dev/console.js b/sources/plugins/clipboard/dev/console.js
new file mode 100644 (file)
index 0000000..96ccd81
--- /dev/null
@@ -0,0 +1,49 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/* global CKCONSOLE */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       var pasteType, pasteValue;\r
+\r
+       CKCONSOLE.add( 'paste', {\r
+               panels: [\r
+                       {\r
+                               type: 'box',\r
+                               content:\r
+                               '<ul class="ckconsole_list">' +\r
+                                       '<li>type: <span class="ckconsole_value" data-value="type"></span></li>' +\r
+                                       '<li>value: <span class="ckconsole_value" data-value="value"></span></li>' +\r
+                               '</ul>',\r
+\r
+                               refresh: function() {\r
+                                       return {\r
+                                               header: 'Paste',\r
+                                               type: pasteType,\r
+                                               value: pasteValue\r
+                                       };\r
+                               },\r
+\r
+                               refreshOn: function( editor, refresh ) {\r
+                                       editor.on( 'paste', function( evt ) {\r
+                                               pasteType = evt.data.type;\r
+                                               pasteValue = CKEDITOR.tools.htmlEncode( evt.data.dataValue );\r
+                                               refresh();\r
+                                       } );\r
+                               }\r
+                       },\r
+                       {\r
+                               type: 'log',\r
+                               on: function( editor, log, logFn ) {\r
+                                       editor.on( 'paste', function( evt ) {\r
+                                               logFn( 'paste; type:' + evt.data.type )();\r
+                                       } );\r
+                               }\r
+                       }\r
+               ]\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/clipboard/dev/dnd.html b/sources/plugins/clipboard/dev/dnd.html
new file mode 100644 (file)
index 0000000..2dfb2be
--- /dev/null
@@ -0,0 +1,185 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Manual test for #11460</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../dev/console/console.js"></script>\r
+       <script src="../../../plugins/clipboard/dev/console.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <style type="text/css">\r
+       h2 {\r
+               margin: 10px 0px 4px 0px;\r
+               padding: 0;\r
+               font-size: 14px;\r
+       }\r
+       h3 {\r
+               margin: 5px 0px 2px 0px;\r
+               padding: 0;\r
+               font-size: 12px;\r
+       }\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               Manual test for #11460\r
+       </h1>\r
+       <h2>Description (<a href="javascript:hideshow('description');">hide/show</a>)</h2>\r
+       <div id="description" class="description">\r
+               <p>Test internal D&amp;D in the editor, dropping content from an external source (helpers, MS Word) and D&amp;D between editors. Keep in mind that internal D&amp;D is the most complex operation because editor have to handle two ranges at the same time.</p>\r
+               <h3>Expected behavior:</h3>\r
+               <ul>\r
+                       <li>proper drop position,</li>\r
+                       <li>in the internal and cross editor D&amp;D: dragged content should be removed,</li>\r
+                       <li>dropped content should be (more less) the same as dragged content,</li>\r
+                       <li>paste event should be fired,</li>\r
+                       <li>undo should work properly (one undo operation for one D&amp;D),</li>\r
+                       <li>no crashes, nor errors,</li>\r
+               </ul>\r
+               <h3>Drag scenarios:</h3>\r
+               <ul>\r
+                       <li>drag simple text,</li>\r
+                       <li>drag table cell/cells,</li>\r
+                       <li>drag link,</li>\r
+                       <li>drag helpers textarea content,</li>\r
+                       <li>drag helpers html content,</li>\r
+                       <li>drag content from MS Word.</li>\r
+               </ul>\r
+               <h3>Drop scenarios:</h3>\r
+               <ul>\r
+                       <li>drop in the different paragraph (before and after),</li>\r
+                       <li>drop in the same paragraph (before and after),</li>\r
+                       <li>drop in the same text node (before and after),</li>\r
+                       <li>drop between text lines,</li>\r
+                       <li>drop on the whitespace next to the header,</li>\r
+                       <li>drop on the whitespace on the left side from the quote,</li>\r
+                       <li>drop into a cell.</li>\r
+               </ul>\r
+               <h3>Known issues (not part of this ticket):</h3>\r
+               <ul>\r
+                       <li>because of <a href="http://dev.ckeditor.com/ticket/11636">#11636</a> dragged content is not correct in some cases (e.g. when you drag part of the link),</li>\r
+                       <li>drag position needs clean up after D&amp;D (e.g. remove empty paragraphs, fix table),</li>\r
+                       <li>drop position needs clean up after D&amp;D (e.g. add spaces before/after dropped content, apply parents styles, break paragraph when one paragraph is dropped at the end to the other paragraph),</li>\r
+                       <li>in the external D&amp;D: Chrome add plenty of addition tags.</li>\r
+               </ul>\r
+       </div>\r
+       <div>\r
+               <h2>Helpers (<a href="javascript:hideshow('helpers');">hide/show</a>)</h2>\r
+               <div id="helpers">\r
+                       <textarea style="width:49%; height:50px; float: left;">Lorem ipsum dolor sit amet, consectetur adipiscing elit. In commodo vulputate tempor. Sed <b>at</b> elit.</textarea>\r
+                       <div style="width:49%; height:50px; float: right;">\r
+                               Lorem ipsum <b>dolor</b> sit <i>amet</i>, consectetur adipiscing elit. In commodo vulputate tempor. Sed &lt;b&gt;at elit&lt;/b&gt; vel ligula mollis aliquet a ac odio.\r
+                               <pre>\r
+Aenean cursus egestas ipsum.\r
+                               </pre>\r
+                       </div>\r
+                       <div style="clear:both;"></div>\r
+               </div>\r
+       </div>\r
+       <div>\r
+               <h2>Classic editor (<a href="javascript:hideshow('classic-editor');">hide/show</a>)</h2>\r
+               <div id="classic-editor">\r
+                       <textarea cols="80" id="classic" name="classic" rows="10">\r
+                               &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;../../../samples/assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+                       </textarea>\r
+               </div>\r
+       </div>\r
+       <div>\r
+               <h2>Inline editor (<a href="javascript:hideshow('inline');">hide/show</a>)</h2>\r
+               <div id="inline" contenteditable="true">\r
+                       <h1><img alt="Saturn V carrying Apollo 11" class="right" src="../../../samples/assets/sample.jpg" /> Apollo 11</h1>\r
+\r
+                       <p><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>\r
+\r
+                       <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>\r
+\r
+                       <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>\r
+\r
+                       <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+\r
+                       <blockquote>\r
+                               <p>One small step for [a] man, one giant leap for mankind.</p>\r
+                       </blockquote>\r
+\r
+                       <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>\r
+\r
+                       <blockquote>\r
+                               <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>\r
+                       </blockquote>\r
+\r
+                       <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>\r
+\r
+                       <table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;">\r
+                               <caption><strong>Mission crew</strong></caption>\r
+                               <thead>\r
+                               <tr>\r
+                                       <th scope="col">Position</th>\r
+                                       <th scope="col">Astronaut</th>\r
+                               </tr>\r
+                               </thead>\r
+                               <tbody>\r
+                               <tr>\r
+                                       <td>Commander</td>\r
+                                       <td>Neil A. Armstrong</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Command Module Pilot</td>\r
+                                       <td>Michael Collins</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Lunar Module Pilot</td>\r
+                                       <td>Edwin &quot;Buzz&quot; E. Aldrin, Jr.</td>\r
+                               </tr>\r
+                               </tbody>\r
+                       </table>\r
+\r
+                       <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>\r
+\r
+                       <ol>\r
+                               <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>\r
+                               <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>\r
+                               <li><strong>Lunar Module</strong> for landing on the Moon.</li>\r
+                       </ol>\r
+\r
+                       <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>\r
+\r
+                       <hr />\r
+                       <p style="text-align: right;"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p>\r
+               </div>\r
+       </div>\r
+               <script type="text/javascript">\r
+               CKEDITOR.disableAutoInline = true;\r
+\r
+               function hideshow( id ) {\r
+                       var element = CKEDITOR.document.getById( id );\r
+\r
+                       if( element.getStyle( 'display' ) == 'none' )\r
+                               element.show();\r
+                       else\r
+                               element.hide();\r
+               }\r
+\r
+               CKEDITOR.replace( 'classic' );\r
+               CKEDITOR.inline( 'inline' );\r
+\r
+               CKCONSOLE.addEventPanel( 'dragstart', [ '$', 'target', 'dataTransfer' ] );\r
+               CKCONSOLE.addEventPanel( 'dragend', [ '$', 'target', 'dataTransfer' ]   );\r
+               CKCONSOLE.addEventPanel( 'drop',\r
+                       [ '$', 'target', 'dataTransfer', 'dragRange', 'dropRange' ] );\r
+\r
+               CKCONSOLE.create( 'dragstart', { editor: 'classic' } );\r
+               CKCONSOLE.create( 'drop', { editor: 'classic' } );\r
+               CKCONSOLE.create( 'paste', { editor: 'classic' } );\r
+               CKCONSOLE.create( 'dragend', { editor: 'classic' } );\r
+\r
+               CKCONSOLE.create( 'dragstart', { editor: 'inline' } );\r
+               CKCONSOLE.create( 'drop', { editor: 'inline' } );\r
+               CKCONSOLE.create( 'paste', { editor: 'inline' } );\r
+               CKCONSOLE.create( 'dragend', { editor: 'inline' } );\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/clipboard/dialogs/paste.js b/sources/plugins/clipboard/dialogs/paste.js
new file mode 100644 (file)
index 0000000..80ce29f
--- /dev/null
@@ -0,0 +1,254 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.dialog.add( 'paste', function( editor ) {\r
+       var lang = editor.lang.clipboard,\r
+               clipboard = CKEDITOR.plugins.clipboard,\r
+               lastDataTransfer;\r
+\r
+       function onPasteFrameLoad( win ) {\r
+               var doc = new CKEDITOR.dom.document( win.document ),\r
+                       body = doc.getBody(),\r
+                       script = doc.getById( 'cke_actscrpt' );\r
+\r
+               script && script.remove();\r
+\r
+               body.setAttribute( 'contenteditable', true );\r
+\r
+               // Forward dataTransfer (#13883).\r
+               body.on( clipboard.mainPasteEvent, function( evt ) {\r
+                       var dataTransfer = clipboard.initPasteDataTransfer( evt );\r
+\r
+                       if ( !lastDataTransfer ) {\r
+                               lastDataTransfer = dataTransfer;\r
+                       } else\r
+                       // For two paste with the same dataTransfer we can use that dataTransfer (two internal pastes are\r
+                       // considered as an internal paste).\r
+                       if ( dataTransfer != lastDataTransfer ) {\r
+                               // If there were two paste with different DataTransfer objects create a new, empty, data transfer\r
+                               // and use it (one internal and one external paste are considered as external paste).\r
+                               lastDataTransfer = clipboard.initPasteDataTransfer();\r
+                       }\r
+               } );\r
+\r
+               // IE before version 8 will leave cursor blinking inside the document after\r
+               // editor blurred unless we clean up the selection. (#4716)\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 8 ) {\r
+                       doc.getWindow().on( 'blur', function() {\r
+                               doc.$.selection.empty();\r
+                       } );\r
+               }\r
+\r
+               doc.on( 'keydown', function( e ) {\r
+                       var domEvent = e.data,\r
+                               key = domEvent.getKeystroke(),\r
+                               processed;\r
+\r
+                       switch ( key ) {\r
+                               case 27:\r
+                                       this.hide();\r
+                                       processed = 1;\r
+                                       break;\r
+\r
+                               case 9:\r
+                               case CKEDITOR.SHIFT + 9:\r
+                                       this.changeFocus( 1 );\r
+                                       processed = 1;\r
+                       }\r
+\r
+                       processed && domEvent.preventDefault();\r
+               }, this );\r
+\r
+               editor.fire( 'ariaWidget', new CKEDITOR.dom.element( win.frameElement ) );\r
+\r
+               // Handle pending focus.\r
+               if ( doc.getWindow().getFrame().removeCustomData( 'pendingFocus' ) )\r
+                       body.focus();\r
+       }\r
+\r
+       // If pasteDialogCommit wasn't canceled by e.g. editor.getClipboardData\r
+       // then fire paste event.\r
+       // Do not use editor#paste, because it would start from beforePaste event.\r
+       editor.on( 'pasteDialogCommit', function( evt ) {\r
+               if ( evt.data )\r
+                       editor.fire( 'paste', {\r
+                               type: 'auto',\r
+                               dataValue: evt.data.dataValue,\r
+                               method: 'paste',\r
+                               dataTransfer: evt.data.dataTransfer || clipboard.initPasteDataTransfer()\r
+                       } );\r
+       }, null, null, 1000 );\r
+\r
+       return {\r
+               title: lang.title,\r
+\r
+               minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 370 : 350,\r
+               minHeight: CKEDITOR.env.quirks ? 250 : 245,\r
+               onShow: function() {\r
+                       // FIREFOX BUG: Force the browser to render the dialog to make the to-be-\r
+                       // inserted iframe editable. (#3366)\r
+                       this.parts.dialog.$.offsetHeight;\r
+\r
+                       this.setupContent();\r
+\r
+                       // Set dialog title to the custom value (set e.g. in editor.openDialog callback) and reset this value.\r
+                       // If custom title not set, use default one.\r
+                       this.parts.title.setHtml( this.customTitle || lang.title );\r
+                       this.customTitle = null;\r
+               },\r
+\r
+               onLoad: function() {\r
+                       if ( ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) && editor.lang.dir == 'rtl' )\r
+                               this.parts.contents.setStyle( 'overflow', 'hidden' );\r
+               },\r
+\r
+               onOk: function() {\r
+                       this.commitContent();\r
+               },\r
+\r
+               contents: [ {\r
+                       id: 'general',\r
+                       label: editor.lang.common.generalTab,\r
+                       elements: [\r
+                               {\r
+                                       type: 'html',\r
+                                       id: 'securityMsg',\r
+                                       html: '<div style="white-space:normal;width:340px">' + lang.securityMsg + '</div>'\r
+                               },\r
+                               {\r
+                                       type: 'html',\r
+                                       id: 'pasteMsg',\r
+                                       html: '<div style="white-space:normal;width:340px">' + lang.pasteMsg + '</div>'\r
+                               },\r
+                               {\r
+                                       type: 'html',\r
+                                       id: 'editing_area',\r
+                                       style: 'width:100%;height:100%',\r
+                                       html: '',\r
+                                       focus: function() {\r
+                                               var iframe = this.getInputElement(),\r
+                                                       doc = iframe.getFrameDocument(),\r
+                                                       body = doc.getBody();\r
+\r
+                                               // Frame content may not loaded at the moment.\r
+                                               if ( !body || body.isReadOnly() )\r
+                                                       iframe.setCustomData( 'pendingFocus', 1 );\r
+                                               else\r
+                                                       body.focus();\r
+                                       },\r
+                                       setup: function() {\r
+                                               var dialog = this.getDialog();\r
+                                               var htmlToLoad = '<html dir="' + editor.config.contentsLangDirection + '"' +\r
+                                                       ' lang="' + ( editor.config.contentsLanguage || editor.langCode ) + '">' +\r
+                                                       '<head><style>body{margin:3px;height:95%;word-break:break-all;}</style></head><body>' +\r
+                                                       '<script id="cke_actscrpt" type="text/javascript">' +\r
+                                                       'window.parent.CKEDITOR.tools.callFunction(' + CKEDITOR.tools.addFunction( onPasteFrameLoad, dialog ) + ',this);' +\r
+                                                       '</script></body>' +\r
+                                                       '</html>';\r
+\r
+                                               var src =\r
+                                                       CKEDITOR.env.air ?\r
+                                                               'javascript:void(0)' : // jshint ignore:line\r
+                                                       ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ?\r
+                                                               'javascript:void((function(){' + encodeURIComponent( // jshint ignore:line\r
+                                                                       'document.open();' +\r
+                                                                       '(' + CKEDITOR.tools.fixDomain + ')();' +\r
+                                                                       'document.close();'\r
+                                                               ) + '})())"'\r
+                                                       : '';\r
+\r
+                                               var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +\r
+                                                       ' class="cke_pasteframe"' +\r
+                                                       ' frameborder="0" ' +\r
+                                                       ' allowTransparency="true"' +\r
+                                                       ' src="' + src + '"' +\r
+                                                       ' aria-label="' + lang.pasteArea + '"' +\r
+                                                       ' aria-describedby="' + dialog.getContentElement( 'general', 'pasteMsg' ).domId + '"' +\r
+                                                       '></iframe>' );\r
+\r
+                                               // Reset last data transfer.\r
+                                               lastDataTransfer = null;\r
+\r
+                                               iframe.on( 'load', function( e ) {\r
+                                                       e.removeListener();\r
+\r
+                                                       var doc = iframe.getFrameDocument();\r
+                                                       doc.write( htmlToLoad );\r
+\r
+                                                       editor.focusManager.add( doc.getBody() );\r
+\r
+                                                       if ( CKEDITOR.env.air )\r
+                                                               onPasteFrameLoad.call( this, doc.getWindow().$ );\r
+                                               }, dialog );\r
+\r
+                                               iframe.setCustomData( 'dialog', dialog );\r
+\r
+                                               var container = this.getElement();\r
+                                               container.setHtml( '' );\r
+                                               container.append( iframe );\r
+\r
+                                               // IE need a redirect on focus to make\r
+                                               // the cursor blinking inside iframe. (#5461)\r
+                                               if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {\r
+                                                       var focusGrabber = CKEDITOR.dom.element.createFromHtml( '<span tabindex="-1" style="position:absolute" role="presentation"></span>' );\r
+                                                       focusGrabber.on( 'focus', function() {\r
+                                                               // Since fixDomain is called in src attribute,\r
+                                                               // IE needs some slight delay to correctly move focus.\r
+                                                               setTimeout( function() {\r
+                                                                       iframe.$.contentWindow.focus();\r
+                                                               } );\r
+                                                       } );\r
+                                                       container.append( focusGrabber );\r
+\r
+                                                       // Override focus handler on field.\r
+                                                       this.focus = function() {\r
+                                                               focusGrabber.focus();\r
+                                                               this.fire( 'focus' );\r
+                                                       };\r
+                                               }\r
+\r
+                                               this.getInputElement = function() {\r
+                                                       return iframe;\r
+                                               };\r
+\r
+                                               // Force container to scale in IE.\r
+                                               if ( CKEDITOR.env.ie ) {\r
+                                                       container.setStyle( 'display', 'block' );\r
+                                                       container.setStyle( 'height', ( iframe.$.offsetHeight + 2 ) + 'px' );\r
+                                               }\r
+                                       },\r
+                                       commit: function() {\r
+                                               var editor = this.getDialog().getParentEditor(),\r
+                                                       body = this.getInputElement().getFrameDocument().getBody(),\r
+                                                       bogus = body.getBogus(),\r
+                                                       html;\r
+                                               bogus && bogus.remove();\r
+\r
+                                               // Saving the contents so changes until paste is complete will not take place (#7500)\r
+                                               html = body.getHtml();\r
+\r
+                                               // Opera needs some time to think about what has happened and what it should do now.\r
+                                               setTimeout( function() {\r
+                                                       editor.fire( 'pasteDialogCommit', {\r
+                                                               dataValue: html,\r
+                                                               // Avoid error if there was no paste so lastDataTransfer is null.\r
+                                                               dataTransfer: lastDataTransfer || clipboard.initPasteDataTransfer()\r
+                                                       } );\r
+                                               }, 0 );\r
+                                       }\r
+                               }\r
+                       ]\r
+               } ]\r
+       };\r
+} );\r
+\r
+/**\r
+ * Internal event to pass paste dialog's data to the listeners.\r
+ *\r
+ * @private\r
+ * @event pasteDialogCommit\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ */\r
diff --git a/sources/plugins/clipboard/icons/copy-rtl.png b/sources/plugins/clipboard/icons/copy-rtl.png
new file mode 100644 (file)
index 0000000..ce94fc0
Binary files /dev/null and b/sources/plugins/clipboard/icons/copy-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/copy.png b/sources/plugins/clipboard/icons/copy.png
new file mode 100644 (file)
index 0000000..ce94fc0
Binary files /dev/null and b/sources/plugins/clipboard/icons/copy.png differ
diff --git a/sources/plugins/clipboard/icons/cut-rtl.png b/sources/plugins/clipboard/icons/cut-rtl.png
new file mode 100644 (file)
index 0000000..8ae48d9
Binary files /dev/null and b/sources/plugins/clipboard/icons/cut-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/cut.png b/sources/plugins/clipboard/icons/cut.png
new file mode 100644 (file)
index 0000000..8ae48d9
Binary files /dev/null and b/sources/plugins/clipboard/icons/cut.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/copy-rtl.png b/sources/plugins/clipboard/icons/hidpi/copy-rtl.png
new file mode 100644 (file)
index 0000000..74c6765
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/copy-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/copy.png b/sources/plugins/clipboard/icons/hidpi/copy.png
new file mode 100644 (file)
index 0000000..74c6765
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/copy.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/cut-rtl.png b/sources/plugins/clipboard/icons/hidpi/cut-rtl.png
new file mode 100644 (file)
index 0000000..f5a9b0d
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/cut-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/cut.png b/sources/plugins/clipboard/icons/hidpi/cut.png
new file mode 100644 (file)
index 0000000..f5a9b0d
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/cut.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/paste-rtl.png b/sources/plugins/clipboard/icons/hidpi/paste-rtl.png
new file mode 100644 (file)
index 0000000..12cac92
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/paste-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/hidpi/paste.png b/sources/plugins/clipboard/icons/hidpi/paste.png
new file mode 100644 (file)
index 0000000..12cac92
Binary files /dev/null and b/sources/plugins/clipboard/icons/hidpi/paste.png differ
diff --git a/sources/plugins/clipboard/icons/paste-rtl.png b/sources/plugins/clipboard/icons/paste-rtl.png
new file mode 100644 (file)
index 0000000..7039251
Binary files /dev/null and b/sources/plugins/clipboard/icons/paste-rtl.png differ
diff --git a/sources/plugins/clipboard/icons/paste.png b/sources/plugins/clipboard/icons/paste.png
new file mode 100644 (file)
index 0000000..7039251
Binary files /dev/null and b/sources/plugins/clipboard/icons/paste.png differ
diff --git a/sources/plugins/clipboard/lang/af.js b/sources/plugins/clipboard/lang/af.js
new file mode 100644 (file)
index 0000000..f87522f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'af', {\r
+       copy: 'Kopiëer',\r
+       copyError: 'U blaaier se sekuriteitsinstelling belet die kopiëringsaksie. Gebruik die sleutelbordkombinasie (Ctrl/Cmd+C).',\r
+       cut: 'Knip',\r
+       cutError: 'U blaaier se sekuriteitsinstelling belet die outomatiese knip-aksie. Gebruik die sleutelbordkombinasie (Ctrl/Cmd+X).',\r
+       paste: 'Plak',\r
+       pasteArea: 'Plak-area',\r
+       pasteMsg: 'Plak die teks in die volgende teks-area met die sleutelbordkombinasie (<STRONG>Ctrl/Cmd+V</STRONG>) en druk <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Weens u blaaier se sekuriteitsinstelling is data op die knipbord nie toeganklik nie. U kan dit eers weer in hierdie venster plak.',\r
+       title: 'Byvoeg'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ar.js b/sources/plugins/clipboard/lang/ar.js
new file mode 100644 (file)
index 0000000..aa96596
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ar', {\r
+       copy: 'نسخ',\r
+       copyError: 'الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع عمليات النسخ التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl/Cmd+C).',\r
+       cut: 'قص',\r
+       cutError: 'الإعدادات الأمنية للمتصفح الذي تستخدمه تمنع القص التلقائي. فضلاً إستخدم لوحة المفاتيح لفعل ذلك (Ctrl/Cmd+X).',\r
+       paste: 'لصق',\r
+       pasteArea: 'منطقة اللصق',\r
+       pasteMsg: 'الصق داخل الصندوق بإستخدام زرائر (<STRONG>Ctrl/Cmd+V</STRONG>) في لوحة المفاتيح، ثم اضغط زر  <STRONG>موافق</STRONG>.',\r
+       securityMsg: 'نظراً لإعدادات الأمان الخاصة بمتصفحك، لن يتمكن هذا المحرر من الوصول لمحتوى حافظتك، لذلك يجب عليك لصق المحتوى مرة أخرى في هذه النافذة.',\r
+       title: 'لصق'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/az.js b/sources/plugins/clipboard/lang/az.js
new file mode 100644 (file)
index 0000000..1fc1a99
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'az', {\r
+       copy: 'Köçür',\r
+       copyError: 'Avtomatik köçürülməsi mümkün deyil. Ctrl+C basın.',\r
+       cut: 'Kəs',\r
+       cutError: 'Avtomatik kəsmə mümkün deyil. Ctrl+X basın.',\r
+       paste: 'Əlavə et',\r
+       pasteArea: 'Əlavəetmə sahəsi',\r
+       pasteMsg: 'Bu sahəyə əlavə edin (<strong>Ctrl+V</strong>)',\r
+       securityMsg: 'Mübadilə buferi açmaq mümkün deyil. Bu pəncərədə yenidən əlavə edin.',\r
+       title: 'Əlavə et'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/bg.js b/sources/plugins/clipboard/lang/bg.js
new file mode 100644 (file)
index 0000000..93a5a9c
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'bg', {\r
+       copy: 'Копирай',\r
+       copyError: 'Настройките за сигурност на вашия бразуър не разрешават на редактора да изпълни запаметяването. За целта използвайте клавиатурата (Ctrl/Cmd+C).',\r
+       cut: 'Отрежи',\r
+       cutError: 'Настройките за сигурност на Вашия браузър не позволяват на редактора автоматично да изъплни действията за отрязване. Моля ползвайте клавиатурните команди за целта (ctrl+x).',\r
+       paste: 'Вмъкни',\r
+       pasteArea: 'Зона за вмъкване',\r
+       pasteMsg: 'Вмъкнете тук съдъжанието с клавиатуарата (<STRONG>Ctrl/Cmd+V</STRONG>) и натиснете <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Заради настройките за сигурност на Вашия браузър, редакторът не може да прочете данните от клипборда коректно.',\r
+       title: 'Вмъкни'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/bn.js b/sources/plugins/clipboard/lang/bn.js
new file mode 100644 (file)
index 0000000..f821fa0
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'bn', {\r
+       copy: 'কপি',\r
+       copyError: 'আপনার ব্রাউজারের নিরাপত্তা সেটিংসমূহ এডিটরকে স্বয়ংক্রিয়ভাবে কপি করার প্রক্রিয়া চালনা করার অনুমতি দেয় না। অনুগ্রহপূর্বক এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl/Cmd+C)।',\r
+       cut: 'কাট',\r
+       cutError: 'আপনার ব্রাউজারের সুরক্ষা সেটিংস এডিটরকে অটোমেটিক কাট করার অনুমতি দেয়নি। দয়া করে এই কাজের জন্য কিবোর্ড ব্যবহার করুন (Ctrl/Cmd+X)।',\r
+       paste: 'পেস্ট',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'অনুগ্রহ করে নীচের বাক্সে কিবোর্ড ব্যবহার করে (<STRONG>Ctrl/Cmd+V</STRONG>) পেস্ট করুন এবং <STRONG>OK</STRONG> চাপ দিন',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'পেস্ট'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/bs.js b/sources/plugins/clipboard/lang/bs.js
new file mode 100644 (file)
index 0000000..1c23a61
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'bs', {\r
+       copy: 'Kopiraj',\r
+       copyError: 'Sigurnosne postavke Vašeg pretraživaèa ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tastaturi (Ctrl/Cmd+C).',\r
+       cut: 'Izreži',\r
+       cutError: 'Sigurnosne postavke vašeg pretraživaèa ne dozvoljavaju operacije automatskog rezanja. Molimo koristite kraticu na tastaturi (Ctrl/Cmd+X).',\r
+       paste: 'Zalijepi',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', // MISSING\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'Zalijepi'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ca.js b/sources/plugins/clipboard/lang/ca.js
new file mode 100644 (file)
index 0000000..52179c1
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ca', {\r
+       copy: 'Copiar',\r
+       copyError: 'La configuració de seguretat del vostre navegador no permet executar automàticament les operacions de copiar. Si us plau, utilitzeu el teclat (Ctrl/Cmd+C).',\r
+       cut: 'Retallar',\r
+       cutError: 'La configuració de seguretat del vostre navegador no permet executar automàticament les operacions de retallar. Si us plau, utilitzeu el teclat (Ctrl/Cmd+X).',\r
+       paste: 'Enganxar',\r
+       pasteArea: 'Àrea d\'enganxat',\r
+       pasteMsg: 'Si us plau, enganxi dins del següent camp utilitzant el teclat (<strong>Ctrl/Cmd+V</strong>) i premi OK.',\r
+       securityMsg: 'A causa de la configuració de seguretat del vostre navegador, l\'editor no pot accedir a les dades del porta-retalls directament. Enganxeu-ho un altre cop en aquesta finestra.',\r
+       title: 'Enganxar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/cs.js b/sources/plugins/clipboard/lang/cs.js
new file mode 100644 (file)
index 0000000..7cf573e
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'cs', {\r
+       copy: 'Kopírovat',\r
+       copyError: 'Bezpečnostní nastavení vašeho prohlížeče nedovolují editoru spustit funkci pro kopírování zvoleného textu do schránky. Prosím zkopírujte zvolený text do schránky pomocí klávesnice (Ctrl/Cmd+C).',\r
+       cut: 'Vyjmout',\r
+       cutError: 'Bezpečnostní nastavení vašeho prohlížeče nedovolují editoru spustit funkci pro vyjmutí zvoleného textu do schránky. Prosím vyjměte zvolený text do schránky pomocí klávesnice (Ctrl/Cmd+X).',\r
+       paste: 'Vložit',\r
+       pasteArea: 'Oblast vkládání',\r
+       pasteMsg: 'Do následujícího pole vložte požadovaný obsah pomocí klávesnice (<STRONG>Ctrl/Cmd+V</STRONG>) a stiskněte <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Z důvodů nastavení bezpečnosti vašeho prohlížeče nemůže editor přistupovat přímo do schránky. Obsah schránky prosím vložte znovu do tohoto okna.',\r
+       title: 'Vložit'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/cy.js b/sources/plugins/clipboard/lang/cy.js
new file mode 100644 (file)
index 0000000..00c5eeb
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'cy', {\r
+       copy: 'Copïo',\r
+       copyError: '\'Dyw gosodiadau diogelwch eich porwr ddim yn caniatàu\'r golygydd i gynnal \'gweithredoedd copïo\' yn awtomatig. Defnyddiwch y bysellfwrdd (Ctrl/Cmd+C).',\r
+       cut: 'Torri',\r
+       cutError: 'Nid yw gosodiadau diogelwch eich porwr yn caniatàu\'r golygydd i gynnal \'gweithredoedd torri\' yn awtomatig. Defnyddiwch y bysellfwrdd (Ctrl/Cmd+X).',\r
+       paste: 'Gludo',\r
+       pasteArea: 'Ardal Gludo',\r
+       pasteMsg: 'Gludwch i mewn i\'r blwch canlynol gan ddefnyddio\'r bysellfwrdd (<strong>Ctrl/Cmd+V</strong>) a phwyso <strong>Iawn</strong>.',\r
+       securityMsg: 'Oherwydd gosodiadau diogelwch eich porwr, \'dyw\'r porwr ddim yn gallu ennill mynediad i\'r data ar y clipfwrdd yn uniongyrchol. Mae angen i chi ei ludo eto i\'r ffenestr hon.',\r
+       title: 'Gludo'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/da.js b/sources/plugins/clipboard/lang/da.js
new file mode 100644 (file)
index 0000000..c029016
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'da', {\r
+       copy: 'Kopiér',\r
+       copyError: 'Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Brug i stedet tastaturet til at kopiere teksten (Ctrl/Cmd+C).',\r
+       cut: 'Klip',\r
+       cutError: 'Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Brug i stedet tastaturet til at klippe teksten (Ctrl/Cmd+X).',\r
+       paste: 'Indsæt',\r
+       pasteArea: 'Indsæt område',\r
+       pasteMsg: 'Indsæt i feltet herunder (<STRONG>Ctrl/Cmd+V</STRONG>) og klik på <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Din browsers sikkerhedsindstillinger tillader ikke editoren at få automatisk adgang til udklipsholderen.<br><br>Du skal indsætte udklipsholderens indhold i dette vindue igen.',\r
+       title: 'Indsæt'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/de-ch.js b/sources/plugins/clipboard/lang/de-ch.js
new file mode 100644 (file)
index 0000000..325b100
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'de-ch', {\r
+       copy: 'Kopieren',\r
+       copyError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).',\r
+       cut: 'Ausschneiden',\r
+       cutError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).',\r
+       paste: 'Einfügen',\r
+       pasteArea: 'Einfügebereich',\r
+       pasteMsg: 'Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit <STRONG>Strg+V</STRONG>) ein und bestätigen Sie mit <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Aufgrund von Sicherheitsbeschränkungen Ihres Browsers kann der Editor nicht direkt auf die Zwischenablage zugreifen. Bitte fügen Sie den Inhalt erneut in diesem Fenster ein.',\r
+       title: 'Einfügen'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/de.js b/sources/plugins/clipboard/lang/de.js
new file mode 100644 (file)
index 0000000..2d6b30b
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'de', {\r
+       copy: 'Kopieren',\r
+       copyError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch kopieren. Bitte benutzen Sie die System-Zwischenablage über STRG-C (kopieren).',\r
+       cut: 'Ausschneiden',\r
+       cutError: 'Die Sicherheitseinstellungen Ihres Browsers lassen es nicht zu, den Text automatisch auszuschneiden. Bitte benutzen Sie die System-Zwischenablage über STRG-X (ausschneiden) und STRG-V (einfügen).',\r
+       paste: 'Einfügen',\r
+       pasteArea: 'Einfügebereich',\r
+       pasteMsg: 'Bitte fügen Sie den Text in der folgenden Box über die Tastatur (mit <STRONG>Strg+V</STRONG>) ein und bestätigen Sie mit <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Aufgrund von Sicherheitsbeschränkungen Ihres Browsers kann der Editor nicht direkt auf die Zwischenablage zugreifen. Bitte fügen Sie den Inhalt erneut in diesem Fenster ein.',\r
+       title: 'Einfügen'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/el.js b/sources/plugins/clipboard/lang/el.js
new file mode 100644 (file)
index 0000000..0528840
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'el', {\r
+       copy: 'Αντιγραφή',\r
+       copyError: 'Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αντιγραφής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+C).',\r
+       cut: 'Αποκοπή',\r
+       cutError: 'Οι ρυθμίσεις ασφαλείας του περιηγητή σας δεν επιτρέπουν την επιλεγμένη εργασία αποκοπής. Παρακαλώ χρησιμοποιείστε το πληκτρολόγιο (Ctrl/Cmd+X).',\r
+       paste: 'Επικόλληση',\r
+       pasteArea: 'Περιοχή Επικόλλησης',\r
+       pasteMsg: 'Παρακαλώ επικολλήστε στο ακόλουθο κουτί χρησιμοποιώντας το πληκτρολόγιο (<strong>Ctrl/Cmd+V</strong>) και πατήστε OK.',\r
+       securityMsg: 'Λόγων των ρυθμίσεων ασφάλειας του περιηγητή σας, ο επεξεργαστής δεν μπορεί να έχει πρόσβαση στην μνήμη επικόλλησης. Χρειάζεται να επικολλήσετε ξανά σε αυτό το παράθυρο.',\r
+       title: 'Επικόλληση'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/en-au.js b/sources/plugins/clipboard/lang/en-au.js
new file mode 100644 (file)
index 0000000..5c497fb
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'en-au', {\r
+       copy: 'Copy',\r
+       copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',\r
+       cut: 'Cut',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',\r
+       paste: 'Paste',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',\r
+       title: 'Paste'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/en-ca.js b/sources/plugins/clipboard/lang/en-ca.js
new file mode 100644 (file)
index 0000000..036ebab
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'en-ca', {\r
+       copy: 'Copy',\r
+       copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',\r
+       cut: 'Cut',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',\r
+       paste: 'Paste',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',\r
+       title: 'Paste'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/en-gb.js b/sources/plugins/clipboard/lang/en-gb.js
new file mode 100644 (file)
index 0000000..bb511ce
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'en-gb', {\r
+       copy: 'Copy',\r
+       copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',\r
+       cut: 'Cut',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',\r
+       paste: 'Paste',\r
+       pasteArea: 'Paste Area',\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',\r
+       title: 'Paste'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/en.js b/sources/plugins/clipboard/lang/en.js
new file mode 100644 (file)
index 0000000..4db6960
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'en', {\r
+       copy: 'Copy',\r
+       copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).',\r
+       cut: 'Cut',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).',\r
+       paste: 'Paste',\r
+       pasteArea: 'Paste Area',\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.',\r
+       title: 'Paste'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/eo.js b/sources/plugins/clipboard/lang/eo.js
new file mode 100644 (file)
index 0000000..2df4150
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'eo', {\r
+       copy: 'Kopii',\r
+       copyError: 'La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras kopiajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-C).',\r
+       cut: 'Eltondi',\r
+       cutError: 'La sekurecagordo de via TTT-legilo ne permesas, ke la redaktilo faras eltondajn operaciojn. Bonvolu uzi la klavaron por tio (Ctrl/Cmd-X).',\r
+       paste: 'Interglui',\r
+       pasteArea: 'Intergluoareo',\r
+       pasteMsg: 'Bonvolu glui la tekston en la jenan areon per uzado de la klavaro (<strong>Ctrl/Cmd+V</strong>) kaj premu OK',\r
+       securityMsg: 'Pro la sekurecagordo de via TTT-legilo, la redaktilo ne povas rekte atingi viajn datenojn en la poŝo. Bonvolu denove interglui la datenojn en tiun fenestron.',\r
+       title: 'Interglui'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/es.js b/sources/plugins/clipboard/lang/es.js
new file mode 100644 (file)
index 0000000..c455992
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'es', {\r
+       copy: 'Copiar',\r
+       copyError: 'La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de copiado.\r\nPor favor use el teclado (Ctrl/Cmd+C).',\r
+       cut: 'Cortar',\r
+       cutError: 'La configuración de seguridad de este navegador no permite la ejecución automática de operaciones de cortado.\r\nPor favor use el teclado (Ctrl/Cmd+X).',\r
+       paste: 'Pegar',\r
+       pasteArea: 'Zona de pegado',\r
+       pasteMsg: 'Por favor pegue dentro del cuadro utilizando el teclado (<STRONG>Ctrl/Cmd+V</STRONG>);\r\nluego presione <STRONG>Aceptar</STRONG>.',\r
+       securityMsg: 'Debido a la configuración de seguridad de su navegador, el editor no tiene acceso al portapapeles.\r\nEs necesario que lo pegue de nuevo en esta ventana.',\r
+       title: 'Pegar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/et.js b/sources/plugins/clipboard/lang/et.js
new file mode 100644 (file)
index 0000000..7d86b30
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'et', {\r
+       copy: 'Kopeeri',\r
+       copyError: 'Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt kopeerida. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+C).',\r
+       cut: 'Lõika',\r
+       cutError: 'Sinu veebisirvija turvaseaded ei luba redaktoril automaatselt lõigata. Palun kasutage selleks klaviatuuri klahvikombinatsiooni (Ctrl/Cmd+X).',\r
+       paste: 'Aseta',\r
+       pasteArea: 'Asetamise ala',\r
+       pasteMsg: 'Palun aseta tekst järgnevasse kasti kasutades klaviatuuri klahvikombinatsiooni (<STRONG>Ctrl/Cmd+V</STRONG>) ja vajuta seejärel <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Sinu veebisirvija turvaseadete tõttu ei oma redaktor otsest ligipääsu lõikelaua andmetele. Sa pead asetama need uuesti siia aknasse.',\r
+       title: 'Asetamine'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/eu.js b/sources/plugins/clipboard/lang/eu.js
new file mode 100644 (file)
index 0000000..93240b5
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'eu', {\r
+       copy: 'Kopiatu',\r
+       copyError: 'Zure web nabigatzailearen segurtasun ezarpenek ez dute baimentzen testuak automatikoki kopiatzea. Mesedez teklatua erabil ezazu (Ctrl/Cmd+C).',\r
+       cut: 'Ebaki',\r
+       cutError: 'Zure web nabigatzailearen segurtasun ezarpenek ez dute baimentzen testuak automatikoki moztea. Mesedez teklatua erabil ezazu (Ctrl/Cmd+X).',\r
+       paste: 'Itsatsi',\r
+       pasteArea: 'Itsasteko area',\r
+       pasteMsg: 'Mesedez teklatua erabiliz (<strong>Ctrl/Cmd+V</strong>) ondorengo eremuan testua itsatsi eta sakatu <strong>Ados</strong>.',\r
+       securityMsg: 'Nabigatzailearen segurtasun ezarpenak direla eta, editoreak ezin du arbela zuzenean erabili. Leiho honetan berriro itsatsi behar duzu.',\r
+       title: 'Itsatsi'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/fa.js b/sources/plugins/clipboard/lang/fa.js
new file mode 100644 (file)
index 0000000..8abee21
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'fa', {\r
+       copy: 'رونوشت',\r
+       copyError: 'تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای کپی کردن را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+C).',\r
+       cut: 'برش',\r
+       cutError: 'تنظیمات امنیتی مرورگر شما اجازه نمیدهد که ویرایشگر به طور خودکار عملکردهای برش را انجام دهد. لطفا با دکمههای صفحه کلید این کار را انجام دهید (Ctrl/Cmd+X).',\r
+       paste: 'چسباندن',\r
+       pasteArea: 'محل چسباندن',\r
+       pasteMsg: 'لطفا متن را با کلیدهای (<STRONG>Ctrl/Cmd+V</STRONG>) در این جعبهٴ متنی بچسبانید و <STRONG>پذیرش</STRONG> را بزنید.',\r
+       securityMsg: 'به خاطر تنظیمات امنیتی مرورگر شما، ویرایشگر نمیتواند دسترسی مستقیم به دادههای clipboard داشته باشد. شما باید دوباره آنرا در این پنجره بچسبانید.',\r
+       title: 'چسباندن'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/fi.js b/sources/plugins/clipboard/lang/fi.js
new file mode 100644 (file)
index 0000000..d165fb3
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'fi', {\r
+       copy: 'Kopioi',\r
+       copyError: 'Selaimesi turva-asetukset eivät salli editorin toteuttaa kopioimista. Käytä näppäimistöä kopioimiseen (Ctrl+C).',\r
+       cut: 'Leikkaa',\r
+       cutError: 'Selaimesi turva-asetukset eivät salli editorin toteuttaa leikkaamista. Käytä näppäimistöä leikkaamiseen (Ctrl+X).',\r
+       paste: 'Liitä',\r
+       pasteArea: 'Leikealue',\r
+       pasteMsg: 'Liitä painamalla (<STRONG>Ctrl+V</STRONG>) ja painamalla <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Selaimesi turva-asetukset eivät salli editorin käyttää leikepöytää suoraan. Sinun pitää suorittaa liittäminen tässä ikkunassa.',\r
+       title: 'Liitä'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/fo.js b/sources/plugins/clipboard/lang/fo.js
new file mode 100644 (file)
index 0000000..5c1ec8a
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'fo', {\r
+       copy: 'Avrita',\r
+       copyError: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í at avrita tekstin. Vinarliga nýt knappaborðið til at avrita tekstin (Ctrl/Cmd+C).',\r
+       cut: 'Kvett',\r
+       cutError: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í at kvetta tekstin. Vinarliga nýt knappaborðið til at kvetta tekstin (Ctrl/Cmd+X).',\r
+       paste: 'Innrita',\r
+       pasteArea: 'Avritingarumráði',\r
+       pasteMsg: 'Vinarliga koyr tekstin í hendan rútin við knappaborðinum (<strong>Ctrl/Cmd+V</strong>) og klikk á <strong>Góðtak</strong>.',\r
+       securityMsg: 'Trygdaruppseting alnótskagans forðar tekstviðgeranum í beinleiðis atgongd til avritingarminnið. Tygum mugu royna aftur í hesum rútinum.',\r
+       title: 'Innrita'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/fr-ca.js b/sources/plugins/clipboard/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..3425f56
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'fr-ca', {\r
+       copy: 'Copier',\r
+       copyError: 'Les paramètres de sécurité de votre navigateur empêchent l\'éditeur de copier automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+C).',\r
+       cut: 'Couper',\r
+       cutError: 'Les paramètres de sécurité de votre navigateur empêchent l\'éditeur de couper automatiquement vos données. Veuillez utiliser les équivalents claviers (Ctrl/Cmd+X).',\r
+       paste: 'Coller',\r
+       pasteArea: 'Coller la zone',\r
+       pasteMsg: 'Veuillez coller dans la zone ci-dessous en utilisant le clavier (<STRONG>Ctrl/Cmd+V</STRONG>) et appuyer sur <STRONG>OK</STRONG>.',\r
+       securityMsg: 'A cause des paramètres de sécurité de votre navigateur, l\'éditeur ne peut accéder au presse-papier directement. Vous devez coller à nouveau le contenu dans cette fenêtre.',\r
+       title: 'Coller'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/fr.js b/sources/plugins/clipboard/lang/fr.js
new file mode 100644 (file)
index 0000000..bb8349f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'fr', {\r
+       copy: 'Copier',\r
+       copyError: 'Les paramètres de sécurité de votre navigateur n\'autorisent pas l\'éditeur à exécuter automatiquement l\'opération « Copier ». Veuillez utiliser le raccourci clavier à cet effet (Ctrl/Cmd+C).',\r
+       cut: 'Couper',\r
+       cutError: 'Les paramètres de sécurité de votre navigateur n\'autorisent pas l\'éditeur à exécuter automatiquement l\'opération « Couper ». Veuillez utiliser le raccourci clavier à cet effet (Ctrl/Cmd+X).',\r
+       paste: 'Coller',\r
+       pasteArea: 'Coller la zone',\r
+       pasteMsg: 'Veuillez coller le texte dans la zone suivante en utilisant le raccourci clavier (<strong>Ctrl/Cmd+V</strong>) et cliquez sur OK.',\r
+       securityMsg: 'Les paramètres de sécurité de votre navigateur empêchent l\'éditeur d\'accéder directement aux données du presse-papier. Vous devez les coller à nouveau dans cette fenêtre.',\r
+       title: 'Coller'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/gl.js b/sources/plugins/clipboard/lang/gl.js
new file mode 100644 (file)
index 0000000..3c89dd0
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'gl', {\r
+       copy: 'Copiar',\r
+       copyError: 'Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de copia. Use o teclado para iso (Ctrl/Cmd+C).',\r
+       cut: 'Cortar',\r
+       cutError: 'Os axustes de seguranza do seu navegador non permiten que o editor realice automaticamente as tarefas de corte. Use o teclado para iso (Ctrl/Cmd+X).',\r
+       paste: 'Pegar',\r
+       pasteArea: 'Zona de pegado',\r
+       pasteMsg: 'Pegue dentro do seguinte cadro usando o teclado (<STRONG>Ctrl/Cmd+V</STRONG>) e prema en Aceptar',\r
+       securityMsg: 'Por mor da configuración de seguranza do seu navegador, o editor non ten acceso ao portapapeis. É necesario pegalo novamente nesta xanela.',\r
+       title: 'Pegar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/gu.js b/sources/plugins/clipboard/lang/gu.js
new file mode 100644 (file)
index 0000000..fcf039a
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'gu', {\r
+       copy: 'નકલ',\r
+       copyError: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કોપી કરવાની પરવાનગી નથી આપતી.  (Ctrl/Cmd+C) का प्रयोग करें।',\r
+       cut: 'કાપવું',\r
+       cutError: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસ કટ કરવાની પરવાનગી નથી આપતી. (Ctrl/Cmd+X) નો ઉપયોગ કરો.',\r
+       paste: 'પેસ્ટ',\r
+       pasteArea: 'પેસ્ટ કરવાની જગ્યા',\r
+       pasteMsg: 'Ctrl/Cmd+V નો પ્રયોગ કરી પેસ્ટ કરો',\r
+       securityMsg: 'તમારા બ્રાઉઝર ની સુરક્ષિત સેટિંગસના કારણે,એડિટર તમારા કિલ્પબોર્ડ ડેટા ને કોપી નથી કરી શકતો. તમારે આ વિન્ડોમાં ફરીથી પેસ્ટ કરવું પડશે.',\r
+       title: 'પેસ્ટ'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/he.js b/sources/plugins/clipboard/lang/he.js
new file mode 100644 (file)
index 0000000..a3726c3
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'he', {\r
+       copy: 'העתקה',\r
+       copyError: 'הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות העתקה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+C).',\r
+       cut: 'גזירה',\r
+       cutError: 'הגדרות האבטחה בדפדפן שלך לא מאפשרות לעורך לבצע פעולות גזירה אוטומטיות. יש להשתמש במקלדת לשם כך (Ctrl/Cmd+X).',\r
+       paste: 'הדבקה',\r
+       pasteArea: 'איזור הדבקה',\r
+       pasteMsg: 'נא להדביק בתוך הקופסה באמצעות (<b>Ctrl/Cmd+V</b>) וללחוץ על <b>אישור</b>.',\r
+       securityMsg: 'עקב הגדרות אבטחה בדפדפן, לא ניתן לגשת אל לוח הגזירים (Clipboard) בצורה ישירה. נא להדביק שוב בחלון זה.',\r
+       title: 'הדבקה'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/hi.js b/sources/plugins/clipboard/lang/hi.js
new file mode 100644 (file)
index 0000000..738b0b9
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'hi', {\r
+       copy: 'कॉपी',\r
+       copyError: 'आपके ब्राआउज़र की सुरक्षा सॅटिन्ग्स ने कॉपी करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+C) का प्रयोग करें।',\r
+       cut: 'कट',\r
+       cutError: 'आपके ब्राउज़र की सुरक्षा सॅटिन्ग्स ने कट करने की अनुमति नहीं प्रदान की है। (Ctrl/Cmd+X) का प्रयोग करें।',\r
+       paste: 'पेस्ट',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Ctrl/Cmd+V का प्रयोग करके पेस्ट करें और ठीक है करें.',\r
+       securityMsg: 'आपके ब्राउज़र की सुरक्षा आपके ब्राउज़र की सुरKश सैटिंग के कारण, एडिटर आपके क्लिपबोर्ड डेटा को नहीं पा सकता है. आपको उसे इस विन्डो में दोबारा पेस्ट करना होगा.',\r
+       title: 'पेस्ट'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/hr.js b/sources/plugins/clipboard/lang/hr.js
new file mode 100644 (file)
index 0000000..7366069
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'hr', {\r
+       copy: 'Kopiraj',\r
+       copyError: 'Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+C).',\r
+       cut: 'Izreži',\r
+       cutError: 'Sigurnosne postavke Vašeg pretraživača ne dozvoljavaju operacije automatskog izrezivanja. Molimo koristite kraticu na tipkovnici (Ctrl/Cmd+X).',\r
+       paste: 'Zalijepi',\r
+       pasteArea: 'Prostor za ljepljenje',\r
+       pasteMsg: 'Molimo zaljepite unutar doljnjeg okvira koristeći tipkovnicu (<STRONG>Ctrl/Cmd+V</STRONG>) i kliknite <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Zbog sigurnosnih postavki Vašeg pretraživača, editor nema direktan pristup Vašem međuspremniku. Potrebno je ponovno zalijepiti tekst u ovaj prozor.',\r
+       title: 'Zalijepi'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/hu.js b/sources/plugins/clipboard/lang/hu.js
new file mode 100644 (file)
index 0000000..b124e35
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'hu', {\r
+       copy: 'Másolás',\r
+       copyError: 'A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a másolás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).',\r
+       cut: 'Kivágás',\r
+       cutError: 'A böngésző biztonsági beállításai nem engedélyezik a szerkesztőnek, hogy végrehajtsa a kivágás műveletet. Használja az alábbi billentyűkombinációt (Ctrl/Cmd+X).',\r
+       paste: 'Beillesztés',\r
+       pasteArea: 'Beszúrás mező',\r
+       pasteMsg: 'Másolja be az alábbi mezőbe a <STRONG>Ctrl/Cmd+V</STRONG> billentyűk lenyomásával, majd nyomjon <STRONG>Rendben</STRONG>-t.',\r
+       securityMsg: 'A böngésző biztonsági beállításai miatt a szerkesztő nem képes hozzáférni a vágólap adataihoz. Illeszd be újra ebben az ablakban.',\r
+       title: 'Beillesztés'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/id.js b/sources/plugins/clipboard/lang/id.js
new file mode 100644 (file)
index 0000000..e7b40ad
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'id', {\r
+       copy: 'Salin',\r
+       copyError: 'Pengaturan keamanan peramban anda tidak mengizinkan editor untuk mengeksekusi operasi menyalin secara otomatis. Mohon gunakan papan tuts (Ctrl/Cmd+C)',\r
+       cut: 'Potong',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', // MISSING\r
+       paste: 'Tempel',\r
+       pasteArea: 'Area Tempel',\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', // MISSING\r
+       securityMsg: 'Karena pengaturan keamanan peramban anda, editor tida dapat mengakses data clipboard anda secara langsung. Anda harus mem-paste kembali pada halaman ini',\r
+       title: 'Tempel'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/is.js b/sources/plugins/clipboard/lang/is.js
new file mode 100644 (file)
index 0000000..6b36cef
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'is', {\r
+       copy: 'Afrita',\r
+       copyError: 'Öryggisstillingar vafrans þíns leyfa ekki afritun texta með músaraðgerð. Notaðu lyklaborðið í afrita (Ctrl/Cmd+C).',\r
+       cut: 'Klippa',\r
+       cutError: 'Öryggisstillingar vafrans þíns leyfa ekki klippingu texta með músaraðgerð. Notaðu lyklaborðið í klippa (Ctrl/Cmd+X).',\r
+       paste: 'Líma',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Límdu í svæðið hér að neðan og (<STRONG>Ctrl/Cmd+V</STRONG>) og smelltu á <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Vegna öryggisstillinga í vafranum þínum fær ritillinn ekki beinan aðgang að klippuborðinu. Þú verður að líma innihaldið aftur inn í þennan glugga.',\r
+       title: 'Líma'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/it.js b/sources/plugins/clipboard/lang/it.js
new file mode 100644 (file)
index 0000000..21f8815
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'it', {\r
+       copy: 'Copia',\r
+       copyError: 'Le impostazioni di sicurezza del browser non permettono di copiare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+C).',\r
+       cut: 'Taglia',\r
+       cutError: 'Le impostazioni di sicurezza del browser non permettono di tagliare automaticamente il testo. Usa la tastiera (Ctrl/Cmd+X).',\r
+       paste: 'Incolla',\r
+       pasteArea: 'Incolla',\r
+       pasteMsg: 'Incolla il testo all\'interno dell\'area sottostante usando la scorciatoia di tastiere (<STRONG>Ctrl/Cmd+V</STRONG>) e premi <STRONG>OK</STRONG>.',\r
+       securityMsg: 'A causa delle impostazioni di sicurezza del browser,l\'editor non è in grado di accedere direttamente agli appunti. E\' pertanto necessario incollarli di nuovo in questa finestra.',\r
+       title: 'Incolla'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ja.js b/sources/plugins/clipboard/lang/ja.js
new file mode 100644 (file)
index 0000000..f099380
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ja', {\r
+       copy: 'コピー',\r
+       copyError: 'ブラウザーのセキュリティ設定によりエディタのコピー操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+C)を使用してください。',\r
+       cut: '切り取り',\r
+       cutError: 'ブラウザーのセキュリティ設定によりエディタの切り取り操作を自動で実行することができません。実行するには手動でキーボードの(Ctrl/Cmd+X)を使用してください。',\r
+       paste: '貼り付け',\r
+       pasteArea: '貼り付け場所',\r
+       pasteMsg: 'キーボード(<STRONG>Ctrl/Cmd+V</STRONG>)を使用して、次の入力エリア内で貼り付けて、<STRONG>OK</STRONG>を押してください。',\r
+       securityMsg: 'ブラウザのセキュリティ設定により、エディタはクリップボードデータに直接アクセスすることができません。このウィンドウは貼り付け操作を行う度に表示されます。',\r
+       title: '貼り付け'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ka.js b/sources/plugins/clipboard/lang/ka.js
new file mode 100644 (file)
index 0000000..e1af8cb
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ka', {\r
+       copy: 'ასლი',\r
+       copyError: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ასლის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+C).',\r
+       cut: 'ამოჭრა',\r
+       cutError: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა ამოჭრის ოპერაციის ავტომატურად განხორციელების საშუალებას. გამოიყენეთ კლავიატურა ამისთვის (Ctrl/Cmd+X).',\r
+       paste: 'ჩასმა',\r
+       pasteArea: 'ჩასმის არე',\r
+       pasteMsg: 'ჩასვით ამ არის შიგნით კლავიატურის გამოყენებით (<strong>Ctrl/Cmd+V</strong>) და დააჭირეთ OK-ს',\r
+       securityMsg: 'თქვენი ბროუზერის უსაფრთხოების პარამეტრები არ იძლევა clipboard-ის მონაცემების წვდომის უფლებას. კიდევ უნდა ჩასვათ ტექსტი ამ ფანჯარაში.',\r
+       title: 'ჩასმა'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/km.js b/sources/plugins/clipboard/lang/km.js
new file mode 100644 (file)
index 0000000..32c30cb
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'km', {\r
+       copy: 'ចម្លង',\r
+       copyError: 'ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ ចំលងអត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ (Ctrl/Cmd+C)។',\r
+       cut: 'កាត់យក',\r
+       cutError: 'ការកំណត់សុវត្ថភាពរបស់កម្មវិធីរុករករបស់លោកអ្នក នេះ​មិនអាចធ្វើកម្មវិធីតាក់តែងអត្ថបទ កាត់អត្ថបទយកដោយស្វ័យប្រវត្តបានឡើយ ។ សូមប្រើប្រាស់បន្សំ ឃីដូចនេះ  (Ctrl/Cmd+X) ។',\r
+       paste: 'បិទ​ភ្ជាប់',\r
+       pasteArea: 'តំបន់​បិទ​ភ្ជាប់',\r
+       pasteMsg: 'សូមចំលងអត្ថបទទៅដាក់ក្នុងប្រអប់ដូចខាងក្រោមដោយប្រើប្រាស់ ឃី ​(<STRONG>Ctrl/Cmd+V</STRONG>) ហើយចុច <STRONG>OK</STRONG> ។',\r
+       securityMsg: 'ព្រោះតែ​ការកំណត់​សុវត្ថិភាព ប្រអប់សរសេរ​មិន​អាចចាប់​យកទិន្នន័យពីក្តារតម្បៀតខ្ទាស់​អ្នក​​ដោយផ្ទាល់​បានទេ។ អ្នក​ត្រូវចំលង​ដាក់វាម្តង​ទៀត ក្នុងផ្ទាំងនេះ។',\r
+       title: 'បិទ​ភ្ជាប់'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ko.js b/sources/plugins/clipboard/lang/ko.js
new file mode 100644 (file)
index 0000000..0a0d1e9
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ko', {\r
+       copy: '복사',\r
+       copyError: '브라우저의 보안설정 때문에 복사할 수 없습니다. 키보드(Ctrl/Cmd+C)를 이용해서 복사하십시오.',\r
+       cut: '잘라내기',\r
+       cutError: '브라우저의 보안설정 때문에 잘라내기 기능을 실행할 수 없습니다. 키보드(Ctrl/Cmd+X)를 이용해서 잘라내기 하십시오',\r
+       paste: '붙여넣기',\r
+       pasteArea: '붙여넣기 범위',\r
+       pasteMsg: '키보드(<strong>Ctrl/Cmd+V</strong>)를 이용해서 상자안에 붙여넣고 <strong>확인</strong> 를 누르세요.',\r
+       securityMsg: '브라우저 보안 설정으로 인해, 클립보드에 직접 접근할 수 없습니다. 이 창에 다시 붙여넣기 하십시오.',\r
+       title: '붙여넣기'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ku.js b/sources/plugins/clipboard/lang/ku.js
new file mode 100644 (file)
index 0000000..86e1778
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ku', {\r
+       copy: 'لەبەرگرتنەوە',\r
+       copyError: 'پارێزی وێبگەڕەکەت ڕێگەنادات بەسەرنووسەکە لە لکاندنی دەقی خۆکارارنە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+C).',\r
+       cut: 'بڕین',\r
+       cutError: 'پارێزی وێبگەڕەکەت ڕێگەنادات بە سەرنووسەکە لەبڕینی خۆکارانە. تکایە لەبری ئەمە ئەم فەرمانە بەکاربهێنە بەداگرتنی کلیلی (Ctrl/Cmd+X).',\r
+       paste: 'لکاندن',\r
+       pasteArea: 'ناوچەی لکاندن',\r
+       pasteMsg: 'تکایە بیلکێنە لەناوەوەی ئەم سنوقە لەڕێی تەختەکلیلەکەت بە بەکارهێنانی کلیلی (<STRONG>Ctrl/Cmd+V</STRONG>) دووای کلیکی باشە بکە.',\r
+       securityMsg: 'بەهۆی شێوەپێدانی پارێزی وێبگەڕەکەت، سەرنووسەکه ناتوانێت دەستبگەیەنێت بەهەڵگیراوەکە ڕاستەوخۆ. بۆیه پێویسته دووباره بیلکێنیت لەم پەنجەرەیه.',\r
+       title: 'لکاندن'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/lt.js b/sources/plugins/clipboard/lang/lt.js
new file mode 100644 (file)
index 0000000..86ecbbb
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'lt', {\r
+       copy: 'Kopijuoti',\r
+       copyError: 'Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti kopijavimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+C).',\r
+       cut: 'Iškirpti',\r
+       cutError: 'Jūsų naršyklės saugumo nustatymai neleidžia redaktoriui automatiškai įvykdyti iškirpimo operacijų. Tam prašome naudoti klaviatūrą (Ctrl/Cmd+X).',\r
+       paste: 'Įdėti',\r
+       pasteArea: 'Įkelti dalį',\r
+       pasteMsg: 'Žemiau esančiame įvedimo lauke įdėkite tekstą, naudodami klaviatūrą (<STRONG>Ctrl/Cmd+V</STRONG>) ir paspauskite mygtuką <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Dėl jūsų naršyklės saugumo nustatymų, redaktorius negali tiesiogiai pasiekti laikinosios atminties. Jums reikia nukopijuoti dar kartą į šį langą.',\r
+       title: 'Įdėti'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/lv.js b/sources/plugins/clipboard/lang/lv.js
new file mode 100644 (file)
index 0000000..c762fc6
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'lv', {\r
+       copy: 'Kopēt',\r
+       copyError: 'Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt kopēšanas darbību.  Lūdzu, izmantojiet (Ctrl/Cmd+C), lai veiktu šo darbību.',\r
+       cut: 'Izgriezt',\r
+       cutError: 'Jūsu pārlūkprogrammas drošības iestatījumi nepieļauj redaktoram automātiski veikt izgriezšanas darbību.  Lūdzu, izmantojiet (Ctrl/Cmd+X), lai veiktu šo darbību.',\r
+       paste: 'Ielīmēt',\r
+       pasteArea: 'Ielīmēšanas zona',\r
+       pasteMsg: 'Lūdzu, ievietojiet tekstu šajā laukumā, izmantojot klaviatūru (<STRONG>Ctrl/Cmd+V</STRONG>) un apstipriniet ar <STRONG>Darīts!</STRONG>.',\r
+       securityMsg: 'Jūsu pārlūka drošības uzstādījumu dēļ, nav iespējams tieši piekļūt jūsu starpliktuvei. Jums jāielīmē atkārtoti šajā logā.',\r
+       title: 'Ievietot'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/mk.js b/sources/plugins/clipboard/lang/mk.js
new file mode 100644 (file)
index 0000000..eb16066
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'mk', {\r
+       copy: 'Копирај (Copy)',\r
+       copyError: 'Опциите за безбедност на вашиот прелистувач не дозволуваат уредувачот автоматски да изврши копирање. Ве молиме употребете ја тастатурата. (Ctrl/Cmd+C)',\r
+       cut: 'Исечи (Cut)',\r
+       cutError: 'Опциите за безбедност на вашиот прелистувач не дозволуваат уредувачот автоматски да изврши сечење. Ве молиме употребете ја тастатурата. (Ctrl/Cmd+C)',\r
+       paste: 'Залепи (Paste)',\r
+       pasteArea: 'Простор за залепување',\r
+       pasteMsg: 'Ве молиме да залепите во следниот квадрат користејќи ја тастатурата (<string>Ctrl/Cmd+V</string>) и да притиснете OK',\r
+       securityMsg: 'Опциите за безбедност на вашиот прелистувач не дозволуваат уредувачот директно да пристапи до копираните податоци. Потребно е повторно да се обидете во овој прозорец.',\r
+       title: 'Залепи (Paste)'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/mn.js b/sources/plugins/clipboard/lang/mn.js
new file mode 100644 (file)
index 0000000..5351941
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'mn', {\r
+       copy: 'Хуулах',\r
+       copyError: 'Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хуулах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+C) товчны хослолыг ашиглана уу.',\r
+       cut: 'Хайчлах',\r
+       cutError: 'Таны browser-ын хамгаалалтын тохиргоо editor-д автоматаар хайчлах үйлдэлийг зөвшөөрөхгүй байна. (Ctrl/Cmd+X) товчны хослолыг ашиглана уу.',\r
+       paste: 'Буулгах',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: '(<strong>Ctrl/Cmd+V</strong>) товчийг ашиглан paste хийнэ үү. Мөн <strong>OK</strong> дар.',\r
+       securityMsg: 'Таны үзүүлэгч/browser/-н хамгаалалтын тохиргооноос болоод editor clipboard өгөгдөлрүү шууд хандах боломжгүй. Энэ цонход дахин paste хийхийг оролд.',\r
+       title: 'Буулгах'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ms.js b/sources/plugins/clipboard/lang/ms.js
new file mode 100644 (file)
index 0000000..3a01be4
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ms', {\r
+       copy: 'Salin',\r
+       copyError: 'Keselamatan perisian browser anda tidak membenarkan operasi salinan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+C).',\r
+       cut: 'Potong',\r
+       cutError: 'Keselamatan perisian browser anda tidak membenarkan operasi suntingan text/imej. Sila gunakan papan kekunci (Ctrl/Cmd+X).',\r
+       paste: 'Tampal',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', // MISSING\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'Tampal'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/nb.js b/sources/plugins/clipboard/lang/nb.js
new file mode 100644 (file)
index 0000000..5355b8a
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'nb', {\r
+       copy: 'Kopier',\r
+       copyError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+C).',\r
+       cut: 'Klipp ut',\r
+       cutError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk tastatursnarveien (Ctrl/Cmd+X).',\r
+       paste: 'Lim inn',\r
+       pasteArea: 'Innlimingsområde',\r
+       pasteMsg: 'Vennligst lim inn i følgende boks med tastaturet (<strong>Ctrl/Cmd+V</strong>) og trykk <strong>OK</strong>.',\r
+       securityMsg: 'Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.',\r
+       title: 'Lim inn'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/nl.js b/sources/plugins/clipboard/lang/nl.js
new file mode 100644 (file)
index 0000000..bae806f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'nl', {\r
+       copy: 'Kopiëren',\r
+       copyError: 'De beveiligingsinstelling van de browser verhinderen het automatisch kopiëren. Gebruik de sneltoets Ctrl/Cmd+C van het toetsenbord.',\r
+       cut: 'Knippen',\r
+       cutError: 'De beveiligingsinstelling van de browser verhinderen het automatisch knippen. Gebruik de sneltoets Ctrl/Cmd+X van het toetsenbord.',\r
+       paste: 'Plakken',\r
+       pasteArea: 'Plakgebied',\r
+       pasteMsg: 'Plak de tekst in het volgende vak gebruikmakend van uw toetsenbord (<strong>Ctrl/Cmd+V</strong>) en klik op OK.',\r
+       securityMsg: 'Door de beveiligingsinstellingen van uw browser is het niet mogelijk om direct vanuit het klembord in de editor te plakken. Middels opnieuw plakken in dit venster kunt u de tekst alsnog plakken in de editor.',\r
+       title: 'Plakken'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/no.js b/sources/plugins/clipboard/lang/no.js
new file mode 100644 (file)
index 0000000..e8c48da
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'no', {\r
+       copy: 'Kopier',\r
+       copyError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk kopiering av tekst. Vennligst bruk snarveien (Ctrl/Cmd+C).',\r
+       cut: 'Klipp ut',\r
+       cutError: 'Din nettlesers sikkerhetsinstillinger tillater ikke automatisk utklipping av tekst. Vennligst bruk snarveien (Ctrl/Cmd+X).',\r
+       paste: 'Lim inn',\r
+       pasteArea: 'Innlimingsområde',\r
+       pasteMsg: 'Vennligst lim inn i følgende boks med tastaturet (<STRONG>Ctrl/Cmd+V</STRONG>) og trykk <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Din nettlesers sikkerhetsinstillinger gir ikke redigeringsverktøyet direkte tilgang til utklippstavlen. Du må derfor lime det inn på nytt i dette vinduet.',\r
+       title: 'Lim inn'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/oc.js b/sources/plugins/clipboard/lang/oc.js
new file mode 100644 (file)
index 0000000..e9e78cd
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'oc', {\r
+       copy: 'Copiar',\r
+       copyError: 'Los paramètres de seguretat de vòstre navigador autorizan pas l\'editor a executar automaticament l\'operacion « Copiar ». Utilizatz l\'acorchi de clavièr a aqueste efièit (Ctrl/Cmd+C).',\r
+       cut: 'Talhar',\r
+       cutError: 'Los paramètres de seguretat de vòstre navigador autorizan pas l\'editor a executar automaticament l\'operacion « Talhar ». Utilizatz l\'acorchi de clavièr a aqueste efièit (Ctrl/Cmd+X).',\r
+       paste: 'Pegar',\r
+       pasteArea: 'Pegar la zòna',\r
+       pasteMsg: 'Pegatz lo tèxte dins la zòna seguenta en utilizant l\'acorchi de clavièr (<strong>Ctrl/Cmd+V</strong>) e clicatz sus D\'acòrdi.',\r
+       securityMsg: 'Los paramètres de seguretat de vòstre navigador empach l\'editor d\'accedir dirèctament a las donadas del quichapapièr. Las vos cal pegar tornamai dins aquesta fenèstra.',\r
+       title: 'Pegar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/pl.js b/sources/plugins/clipboard/lang/pl.js
new file mode 100644 (file)
index 0000000..e2ccd16
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'pl', {\r
+       copy: 'Kopiuj',\r
+       copyError: 'Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne kopiowanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+C.',\r
+       cut: 'Wytnij',\r
+       cutError: 'Ustawienia bezpieczeństwa Twojej przeglądarki nie pozwalają na automatyczne wycinanie tekstu. Użyj skrótu klawiszowego Ctrl/Cmd+X.',\r
+       paste: 'Wklej',\r
+       pasteArea: 'Obszar wklejania',\r
+       pasteMsg: 'Wklej tekst w poniższym polu, używając skrótu klawiaturowego (<STRONG>Ctrl/Cmd+V</STRONG>), i kliknij <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Zabezpieczenia przeglądarki uniemożliwiają wklejenie danych bezpośrednio do edytora. Proszę ponownie wkleić dane w tym oknie.',\r
+       title: 'Wklej'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/pt-br.js b/sources/plugins/clipboard/lang/pt-br.js
new file mode 100644 (file)
index 0000000..74608ba
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'pt-br', {\r
+       copy: 'Copiar',\r
+       copyError: 'As configurações de segurança do seu navegador não permitem que o editor execute operações de copiar automaticamente. Por favor, utilize o teclado para copiar (Ctrl/Cmd+C).',\r
+       cut: 'Recortar',\r
+       cutError: 'As configurações de segurança do seu navegador não permitem que o editor execute operações de recortar automaticamente. Por favor, utilize o teclado para recortar (Ctrl/Cmd+X).',\r
+       paste: 'Colar',\r
+       pasteArea: 'Área para Colar',\r
+       pasteMsg: 'Transfira o link usado na caixa usando o teclado com (<STRONG>Ctrl/Cmd+V</STRONG>) e <STRONG>OK</STRONG>.',\r
+       securityMsg: 'As configurações de segurança do seu navegador não permitem que o editor acesse os dados da área de transferência diretamente. Por favor cole o conteúdo manualmente nesta janela.',\r
+       title: 'Colar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/pt.js b/sources/plugins/clipboard/lang/pt.js
new file mode 100644 (file)
index 0000000..623ce06
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'pt', {\r
+       copy: 'Copiar',\r
+       copyError: 'A configuração de segurança do navegador não permite a execução automática de operações de copiar. Por favor use o teclado (Ctrl/Cmd+C).',\r
+       cut: 'Cortar',\r
+       cutError: 'A configuração de segurança do navegador não permite a execução automática de operações de cortar. Por favor use o teclado (Ctrl/Cmd+X).',\r
+       paste: 'Colar',\r
+       pasteArea: 'Colar área',\r
+       pasteMsg: 'Por favor, cole dentro da seguinte caixa usando o teclado (<STRONG>Ctrl/Cmd+V</STRONG>) e carregue em <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Devido ás definições de segurança do teu browser, o editor não pode aceder ao clipboard diretamente. É necessário que voltes a colar as informações nesta janela.',\r
+       title: 'Colar'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ro.js b/sources/plugins/clipboard/lang/ro.js
new file mode 100644 (file)
index 0000000..1e57798
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ro', {\r
+       copy: 'Copiază',\r
+       copyError: 'Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de copiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+C).',\r
+       cut: 'Taie',\r
+       cutError: 'Setările de securitate ale navigatorului (browser) pe care îl folosiţi nu permit editorului să execute automat operaţiunea de tăiere. Vă rugăm folosiţi tastatura (Ctrl/Cmd+X).',\r
+       paste: 'Adaugă',\r
+       pasteArea: 'Suprafața de adăugare',\r
+       pasteMsg: 'Vă rugăm adăugaţi în căsuţa următoare folosind tastatura (<strong>Ctrl/Cmd+V</strong>) şi apăsaţi OK',\r
+       securityMsg: 'Din cauza setărilor de securitate ale programului dvs. cu care navigaţi pe internet (browser), editorul nu poate accesa direct datele din clipboard. Va trebui să adăugaţi din nou datele în această fereastră.',\r
+       title: 'Adaugă'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ru.js b/sources/plugins/clipboard/lang/ru.js
new file mode 100644 (file)
index 0000000..d9b4d58
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ru', {\r
+       copy: 'Копировать',\r
+       copyError: 'Настройки безопасности вашего браузера не разрешают редактору выполнять операции по копированию текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+C).',\r
+       cut: 'Вырезать',\r
+       cutError: 'Настройки безопасности вашего браузера не разрешают редактору выполнять операции по вырезке текста. Пожалуйста, используйте для этого клавиатуру (Ctrl/Cmd+X).',\r
+       paste: 'Вставить',\r
+       pasteArea: 'Зона для вставки',\r
+       pasteMsg: 'Пожалуйста, вставьте текст в зону ниже, используя клавиатуру (<strong>Ctrl/Cmd+V</strong>) и нажмите кнопку "OK".',\r
+       securityMsg: 'Настройки безопасности вашего браузера не разрешают редактору напрямую обращаться к буферу обмена. Вы должны вставить текст снова в это окно.',\r
+       title: 'Вставить'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/si.js b/sources/plugins/clipboard/lang/si.js
new file mode 100644 (file)
index 0000000..8430d01
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'si', {\r
+       copy: 'පිටපත් කරන්න',\r
+       copyError: 'Your browser security settings don\'t permit the editor to automatically execute copying operations. Please use the keyboard for that (Ctrl/Cmd+C).', // MISSING\r
+       cut: 'කපාගන්න',\r
+       cutError: 'Your browser security settings don\'t permit the editor to automatically execute cutting operations. Please use the keyboard for that (Ctrl/Cmd+X).', // MISSING\r
+       paste: 'අලවන්න',\r
+       pasteArea: 'අලවන ප්‍රදේශ',\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', // MISSING\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'අලවන්න'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sk.js b/sources/plugins/clipboard/lang/sk.js
new file mode 100644 (file)
index 0000000..6b2b4f4
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sk', {\r
+       copy: 'Kopírovať',\r
+       copyError: 'Bezpečnostné nastavenia vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu kopírovania. Použite na to klávesnicu (Ctrl/Cmd+C).',\r
+       cut: 'Vystrihnúť',\r
+       cutError: 'Bezpečnostné nastavenia vášho prehliadača nedovoľujú editoru automaticky spustiť operáciu vystrihnutia. Použite na to klávesnicu (Ctrl/Cmd+X).',\r
+       paste: 'Vložiť',\r
+       pasteArea: 'Miesto na vloženie',\r
+       pasteMsg: 'Použitím klávesnice (<STRONG>Ctrl/Cmd+V</STRONG>) vložte text do rámčeka a stlačte OK.',\r
+       securityMsg: 'Kvôli bezpečnostným nastaveniam vášho prehliadača editor nemôže pristupovať k schránke na kopírovanie priamo. Vložte to preto do tohto okna.',\r
+       title: 'Vložiť'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sl.js b/sources/plugins/clipboard/lang/sl.js
new file mode 100644 (file)
index 0000000..3ddc89e
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sl', {\r
+       copy: 'Kopiraj',\r
+       copyError: 'Varnostne nastavitve brskalnika ne dopuščajo samodejnega kopiranja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+C).',\r
+       cut: 'Izreži',\r
+       cutError: 'Varnostne nastavitve brskalnika ne dopuščajo samodejnega izrezovanja. Uporabite kombinacijo tipk na tipkovnici (Ctrl/Cmd+X).',\r
+       paste: 'Prilepi',\r
+       pasteArea: 'Prilepi območje',\r
+       pasteMsg: 'Prosimo, prilepite v sleči okvir s pomočjo tipkovnice (<strong>Ctrl/Cmd+V</strong>) in pritisnite V redu.',\r
+       securityMsg: 'Zaradi varnostnih nastavitev vašega brskalnika urejevalnik ne more neposredno dostopati do odložišča. Vsebino odložišča ponovno prilepite v to okno.',\r
+       title: 'Prilepi'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sq.js b/sources/plugins/clipboard/lang/sq.js
new file mode 100644 (file)
index 0000000..eda22e7
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sq', {\r
+       copy: 'Kopjo',\r
+       copyError: 'Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e kopjimit. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+C).',\r
+       cut: 'Preje',\r
+       cutError: 'Të dhënat e sigurisë së shfletuesit tuaj nuk lejojnë që redaktuesi automatikisht të kryej veprimin e prerjes. Ju lutemi shfrytëzoni tastierën për këtë veprim (Ctrl/Cmd+X).',\r
+       paste: 'Hidhe',\r
+       pasteArea: 'Hapësira Hedhëse',\r
+       pasteMsg: 'Ju lutemi hidhni brenda kutizës në vijim duke shfrytëzuar tastierën (<strong>Ctrl/Cmd+V</strong>) dhe shtypni Mirë.',\r
+       securityMsg: 'Për shkak të dhënave të sigurisë së shfletuesit tuaj, redaktuesi nuk është në gjendje të i qaset drejtpërdrejtë të dhanve të tabelës suaj të punës. Ju duhet të hidhni atë përsëri në këtë dritare.',\r
+       title: 'Hidhe'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sr-latn.js b/sources/plugins/clipboard/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..52102f6
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sr-latn', {\r
+       copy: 'Kopiraj',\r
+       copyError: 'Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog kopiranja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+C).',\r
+       cut: 'Iseci',\r
+       cutError: 'Sigurnosna podešavanja Vašeg pretraživača ne dozvoljavaju operacije automatskog isecanja teksta. Molimo Vas da koristite prečicu sa tastature (Ctrl/Cmd+X).',\r
+       paste: 'Zalepi',\r
+       pasteArea: 'Prostor za lepljenje',\r
+       pasteMsg: 'Molimo Vas da zalepite unutar donje povrine koristeći tastaturnu prečicu (<STRONG>Ctrl/Cmd+V</STRONG>) i da pritisnete <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Zbog sigurnosnih postavki vašeg pregledača, editor nije u mogućnosti da direktno pristupi podacima u klipbordu. Potrebno je da zalepite još jednom u ovom prozoru.',\r
+       title: 'Zalepi'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sr.js b/sources/plugins/clipboard/lang/sr.js
new file mode 100644 (file)
index 0000000..c59ff1f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sr', {\r
+       copy: 'Копирај',\r
+       copyError: 'Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског копирања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+C).',\r
+       cut: 'Исеци',\r
+       cutError: 'Сигурносна подешавања Вашег претраживача не дозвољавају операције аутоматског исецања текста. Молимо Вас да користите пречицу са тастатуре (Ctrl/Cmd+X).',\r
+       paste: 'Залепи',\r
+       pasteArea: 'Залепи зону',\r
+       pasteMsg: 'Молимо Вас да залепите унутар доње површине користећи тастатурну пречицу (<STRONG>Ctrl/Cmd+V</STRONG>) и да притиснете <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Због сигурносних подешавања претраживача, едитор не може да приступи оставу. Требате да га поново залепите у овом прозору.',\r
+       title: 'Залепи'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/sv.js b/sources/plugins/clipboard/lang/sv.js
new file mode 100644 (file)
index 0000000..9663daa
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'sv', {\r
+       copy: 'Kopiera',\r
+       copyError: 'Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden kopiera. Använd (Ctrl/Cmd+C) istället.',\r
+       cut: 'Klipp ut',\r
+       cutError: 'Säkerhetsinställningar i Er webbläsare tillåter inte åtgärden klipp ut. Använd (Ctrl/Cmd+X) istället.',\r
+       paste: 'Klistra in',\r
+       pasteArea: 'Paste Area',\r
+       pasteMsg: 'Var god och klistra in Er text i rutan nedan genom att använda (<strong>Ctrl/Cmd+V</strong>) klicka sen på OK.',\r
+       securityMsg: 'På grund av din webbläsares säkerhetsinställningar kan verktyget inte få åtkomst till urklippsdatan. Var god och använd detta fönster istället.',\r
+       title: 'Klistra in'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/th.js b/sources/plugins/clipboard/lang/th.js
new file mode 100644 (file)
index 0000000..29664a6
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'th', {\r
+       copy: 'สำเนา',\r
+       copyError: 'ไม่สามารถสำเนาข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว C พร้อมกัน).',\r
+       cut: 'ตัด',\r
+       cutError: 'ไม่สามารถตัดข้อความที่เลือกไว้ได้เนื่องจากการกำหนดค่าระดับความปลอดภัย. กรุณาใช้ปุ่มลัดเพื่อวางข้อความแทน (กดปุ่ม Ctrl/Cmd และตัว X พร้อมกัน).',\r
+       paste: 'วาง',\r
+       pasteArea: 'Paste Area', // MISSING\r
+       pasteMsg: 'กรุณาใช้คีย์บอร์ดเท่านั้น โดยกดปุ๋ม (<strong>Ctrl/Cmd และ V</strong>)พร้อมๆกัน และกด <strong>OK</strong>.',\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'วาง'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/tr.js b/sources/plugins/clipboard/lang/tr.js
new file mode 100644 (file)
index 0000000..a60ddc7
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'tr', {\r
+       copy: 'Kopyala',\r
+       copyError: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kopyalama işlemine izin vermiyor. İşlem için (Ctrl/Cmd+C) tuşlarını kullanın.',\r
+       cut: 'Kes',\r
+       cutError: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin otomatik kesme işlemine izin vermiyor. İşlem için (Ctrl/Cmd+X) tuşlarını kullanın.',\r
+       paste: 'Yapıştır',\r
+       pasteArea: 'Yapıştırma Alanı',\r
+       pasteMsg: 'Lütfen aşağıdaki kutunun içine yapıştırın. (<STRONG>Ctrl/Cmd+V</STRONG>) ve <STRONG>Tamam</STRONG> butonunu tıklayın.',\r
+       securityMsg: 'Gezgin yazılımınızın güvenlik ayarları düzenleyicinin direkt olarak panoya erişimine izin vermiyor. Bu pencere içine tekrar yapıştırmalısınız..',\r
+       title: 'Yapıştır'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/tt.js b/sources/plugins/clipboard/lang/tt.js
new file mode 100644 (file)
index 0000000..e4b0537
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'tt', {\r
+       copy: 'Күчермәләү',\r
+       copyError: 'Браузерыгызның иминлек үзлекләре автоматик рәвештә күчермәләү үтәүне тыя. Тиз төймәләрне (Ctrl/Cmd+C) кулланыгыз.',\r
+       cut: 'Кисеп алу',\r
+       cutError: 'Браузерыгызның иминлек үзлекләре автоматик рәвештә күчермәләү үтәүне тыя. Тиз төймәләрне (Ctrl/Cmd+C) кулланыгыз.',\r
+       paste: 'Өстәү',\r
+       pasteArea: 'Өстәү мәйданы',\r
+       pasteMsg: 'Please paste inside the following box using the keyboard (<strong>Ctrl/Cmd+V</strong>) and hit OK', // MISSING\r
+       securityMsg: 'Because of your browser security settings, the editor is not able to access your clipboard data directly. You are required to paste it again in this window.', // MISSING\r
+       title: 'Өстәү'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/ug.js b/sources/plugins/clipboard/lang/ug.js
new file mode 100644 (file)
index 0000000..dcdf29c
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'ug', {\r
+       copy: 'كۆچۈر',\r
+       copyError: 'تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كۆچۈر مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+C) ئارقىلىق تاماملاڭ',\r
+       cut: 'كەس',\r
+       cutError: 'تور كۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى تەھرىرلىگۈچنىڭ كەس مەشغۇلاتىنى ئۆزلۈكىدىن ئىجرا قىلىشىغا يول قويمايدۇ، ھەرپتاختا تېز كۇنۇپكا (Ctrl/Cmd+X) ئارقىلىق تاماملاڭ',\r
+       paste: 'چاپلا',\r
+       pasteArea: 'چاپلاش دائىرىسى',\r
+       pasteMsg: 'ھەرپتاختا تېز كۇنۇپكا (<STRONG>Ctrl/Cmd+V</STRONG>) نى ئىشلىتىپ مەزمۇننى تۆۋەندىكى رامكىغا كۆچۈرۈڭ، ئاندىن <STRONG>جەزملە</STRONG>نى بېسىڭ',\r
+       securityMsg: 'توركۆرگۈڭىزنىڭ بىخەتەرلىك تەڭشىكى سەۋەبىدىن بۇ تەھرىرلىگۈچ چاپلاش تاختىسىدىكى مەزمۇننى بىۋاستە زىيارەت قىلالمايدۇ، بۇ كۆزنەكتە قايتا بىر قېتىم چاپلىشىڭىز كېرەك.',\r
+       title: 'چاپلا'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/uk.js b/sources/plugins/clipboard/lang/uk.js
new file mode 100644 (file)
index 0000000..242688f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'uk', {\r
+       copy: 'Копіювати',\r
+       copyError: 'Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції копіювання. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+C).',\r
+       cut: 'Вирізати',\r
+       cutError: 'Налаштування безпеки Вашого браузера не дозволяють редактору автоматично виконувати операції вирізування. Будь ласка, використовуйте клавіатуру для цього (Ctrl/Cmd+X)',\r
+       paste: 'Вставити',\r
+       pasteArea: 'Область вставки',\r
+       pasteMsg: 'Будь ласка, вставте інформацію з буфера обміну в цю область, користуючись комбінацією клавіш (<STRONG>Ctrl/Cmd+V</STRONG>), та натисніть <STRONG>OK</STRONG>.',\r
+       securityMsg: 'Редактор не може отримати прямий доступ до буферу обміну у зв\'язку з налаштуваннями Вашого браузера. Вам потрібно вставити інформацію в це вікно.',\r
+       title: 'Вставити'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/vi.js b/sources/plugins/clipboard/lang/vi.js
new file mode 100644 (file)
index 0000000..fd36e1f
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'vi', {\r
+       copy: 'Sao chép',\r
+       copyError: 'Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh sao chép. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+C).',\r
+       cut: 'Cắt',\r
+       cutError: 'Các thiết lập bảo mật của trình duyệt không cho phép trình biên tập tự động thực thi lệnh cắt. Hãy sử dụng bàn phím cho lệnh này (Ctrl/Cmd+X).',\r
+       paste: 'Dán',\r
+       pasteArea: 'Khu vực dán',\r
+       pasteMsg: 'Hãy dán nội dung vào trong khung bên dưới, sử dụng tổ hợp phím (<STRONG>Ctrl/Cmd+V</STRONG>) và nhấn vào nút <STRONG>Đồng ý</STRONG>.',\r
+       securityMsg: 'Do thiết lập bảo mật của trình duyệt nên trình biên tập không thể truy cập trực tiếp vào nội dung đã sao chép. Bạn cần phải dán lại nội dung vào cửa sổ này.',\r
+       title: 'Dán'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/zh-cn.js b/sources/plugins/clipboard/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..930f24e
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'zh-cn', {\r
+       copy: '复制',\r
+       copyError: '您的浏览器安全设置不允许编辑器自动执行复制操作,请使用键盘快捷键(Ctrl/Cmd+C)来完成。',\r
+       cut: '剪切',\r
+       cutError: '您的浏览器安全设置不允许编辑器自动执行剪切操作,请使用键盘快捷键(Ctrl/Cmd+X)来完成。',\r
+       paste: '粘贴',\r
+       pasteArea: '粘贴区域',\r
+       pasteMsg: '请使用键盘快捷键(<STRONG>Ctrl/Cmd+V</STRONG>)把内容粘贴到下面的方框里,再按 <STRONG>确定</STRONG>',\r
+       securityMsg: '因为您的浏览器的安全设置原因,本编辑器不能直接访问您的剪贴板内容,你需要在本窗口重新粘贴一次。',\r
+       title: '粘贴'\r
+} );\r
diff --git a/sources/plugins/clipboard/lang/zh.js b/sources/plugins/clipboard/lang/zh.js
new file mode 100644 (file)
index 0000000..33a4ef0
--- /dev/null
@@ -0,0 +1,15 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'clipboard', 'zh', {\r
+       copy: '複製',\r
+       copyError: '瀏覽器的安全性設定不允許編輯器自動執行複製動作。請使用鍵盤快捷鍵 (Ctrl/Cmd+C) 複製。',\r
+       cut: '剪下',\r
+       cutError: '瀏覽器的安全性設定不允許編輯器自動執行剪下動作。請使用鏐盤快捷鍵 (Ctrl/Cmd+X) 剪下。',\r
+       paste: '貼上',\r
+       pasteArea: '貼上區',\r
+       pasteMsg: '請使用鍵盤快捷鍵 (<strong>Ctrl/Cmd+V</strong>) 貼到下方區域中並按下「確定」。',\r
+       securityMsg: '因為瀏覽器的安全性設定,本編輯器無法直接存取您的剪貼簿資料,請您自行在本視窗進行貼上動作。',\r
+       title: '貼上'\r
+} );\r
diff --git a/sources/plugins/clipboard/plugin.js b/sources/plugins/clipboard/plugin.js
new file mode 100644 (file)
index 0000000..5c387b3
--- /dev/null
@@ -0,0 +1,2772 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @ignore\r
+ * File overview: Clipboard support.\r
+ */\r
+\r
+//\r
+// COPY & PASTE EXECUTION FLOWS:\r
+// -- CTRL+C\r
+//             * if ( isCustomCopyCutSupported )\r
+//                     * dataTransfer.setData( 'text/html', getSelectedHtml )\r
+//             * else\r
+//                     * browser's default behavior\r
+// -- CTRL+X\r
+//             * listen onKey (onkeydown)\r
+//             * fire 'saveSnapshot' on editor\r
+//             * if ( isCustomCopyCutSupported )\r
+//                     * dataTransfer.setData( 'text/html', getSelectedHtml )\r
+//                     * extractSelectedHtml // remove selected contents\r
+//             * else\r
+//                     * browser's default behavior\r
+//             * deferred second 'saveSnapshot' event\r
+// -- CTRL+V\r
+//             * listen onKey (onkeydown)\r
+//             * simulate 'beforepaste' for non-IEs on editable\r
+//             * listen 'onpaste' on editable ('onbeforepaste' for IE)\r
+//             * fire 'beforePaste' on editor\r
+//             * if ( !canceled && ( htmlInDataTransfer || !external paste) && dataTransfer is not empty ) getClipboardDataByPastebin\r
+//             * fire 'paste' on editor\r
+//             * !canceled && fire 'afterPaste' on editor\r
+// -- Copy command\r
+//             * tryToCutCopy\r
+//                     * execCommand\r
+//             * !success && notification\r
+// -- Cut command\r
+//             * fixCut\r
+//             * tryToCutCopy\r
+//                     * execCommand\r
+//             * !success && notification\r
+// -- Paste command\r
+//             * fire 'paste' on editable ('beforepaste' for IE)\r
+//             * !canceled && execCommand 'paste'\r
+//             * !success && fire 'pasteDialog' on editor\r
+// -- Paste from native context menu & menubar\r
+//             (Fx & Webkits are handled in 'paste' default listener.\r
+//             Opera cannot be handled at all because it doesn't fire any events\r
+//             Special treatment is needed for IE, for which is this part of doc)\r
+//             * listen 'onpaste'\r
+//             * cancel native event\r
+//             * fire 'beforePaste' on editor\r
+//             * if ( !canceled && ( htmlInDataTransfer || !external paste) && dataTransfer is not empty ) getClipboardDataByPastebin\r
+//             * execIECommand( 'paste' ) -> this fires another 'paste' event, so cancel it\r
+//             * fire 'paste' on editor\r
+//             * !canceled && fire 'afterPaste' on editor\r
+//\r
+//\r
+// PASTE EVENT - PREPROCESSING:\r
+// -- Possible dataValue types: auto, text, html.\r
+// -- Possible dataValue contents:\r
+//             * text (possible \n\r)\r
+//             * htmlified text (text + br,div,p - no presentational markup & attrs - depends on browser)\r
+//             * html\r
+// -- Possible flags:\r
+//             * htmlified - if true then content is a HTML even if no markup inside. This flag is set\r
+//                     for content from editable pastebins, because they 'htmlify' pasted content.\r
+//\r
+// -- Type: auto:\r
+//             * content: htmlified text ->    filter, unify text markup (brs, ps, divs), set type: text\r
+//             * content: html ->                              filter, set type: html\r
+// -- Type: text:\r
+//             * content: htmlified text ->    filter, unify text markup\r
+//             * content: html ->                              filter, strip presentational markup, unify text markup\r
+// -- Type: html:\r
+//             * content: htmlified text ->    filter, unify text markup\r
+//             * content: html ->                              filter\r
+//\r
+// -- Phases:\r
+//             * if dataValue is empty copy data from dataTransfer to dataValue (priority 1)\r
+//             * filtering (priorities 3-5) - e.g. pastefromword filters\r
+//             * content type sniffing (priority 6)\r
+//             * markup transformations for text (priority 6)\r
+//\r
+// DRAG & DROP EXECUTION FLOWS:\r
+// -- Drag\r
+//             * save to the global object:\r
+//                     * drag timestamp (with 'cke-' prefix),\r
+//                     * selected html,\r
+//                     * drag range,\r
+//                     * editor instance.\r
+//             * put drag timestamp into event.dataTransfer.text\r
+// -- Drop\r
+//             * if events text == saved timestamp && editor == saved editor\r
+//                     internal drag & drop occurred\r
+//                     * getRangeAtDropPosition\r
+//                     * create bookmarks for drag and drop ranges starting from the end of the document\r
+//                     * dragRange.deleteContents()\r
+//                     * fire 'paste' with saved html and drop range\r
+//             * if events text == saved timestamp && editor != saved editor\r
+//                     cross editor drag & drop occurred\r
+//                     * getRangeAtDropPosition\r
+//                     * fire 'paste' with saved html\r
+//                     * dragRange.deleteContents()\r
+//                     * FF: refreshCursor on afterPaste\r
+//             * if events text != saved timestamp\r
+//                     drop form external source occurred\r
+//                     * getRangeAtDropPosition\r
+//                     * if event contains html data then fire 'paste' with html\r
+//                     * else if event contains text data then fire 'paste' with encoded text\r
+//                     * FF: refreshCursor on afterPaste\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       // Register the plugin.\r
+       CKEDITOR.plugins.add( 'clipboard', {\r
+               requires: 'dialog',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'copy,copy-rtl,cut,cut-rtl,paste,paste-rtl', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       var filterType,\r
+                               filtersFactory = filtersFactoryFactory();\r
+\r
+                       if ( editor.config.forcePasteAsPlainText ) {\r
+                               filterType = 'plain-text';\r
+                       } else if ( editor.config.pasteFilter ) {\r
+                               filterType = editor.config.pasteFilter;\r
+                       }\r
+                       // On Webkit the pasteFilter defaults 'semantic-content' because pasted data is so terrible\r
+                       // that it must be always filtered.\r
+                       else if ( CKEDITOR.env.webkit && !( 'pasteFilter' in editor.config ) ) {\r
+                               filterType = 'semantic-content';\r
+                       }\r
+\r
+                       editor.pasteFilter = filtersFactory.get( filterType );\r
+\r
+                       initPasteClipboard( editor );\r
+                       initDragDrop( editor );\r
+\r
+                       CKEDITOR.dialog.add( 'paste', CKEDITOR.getUrl( this.path + 'dialogs/paste.js' ) );\r
+\r
+                       // Convert image file (if present) to base64 string for Firefox. Do it as the first\r
+                       // step as the conversion is asynchronous and should hold all further paste processing.\r
+                       if ( CKEDITOR.env.gecko ) {\r
+                               var supportedImageTypes = [ 'image/png', 'image/jpeg', 'image/gif' ],\r
+                                       latestId;\r
+\r
+                               editor.on( 'paste', function( evt ) {\r
+                                       var dataObj = evt.data,\r
+                                               data = dataObj.dataValue,\r
+                                               dataTransfer = dataObj.dataTransfer;\r
+\r
+                                       // If data empty check for image content inside data transfer. #16705\r
+                                       if ( !data && dataObj.method == 'paste' && dataTransfer && dataTransfer.getFilesCount() == 1 && latestId != dataTransfer.id ) {\r
+                                               var file = dataTransfer.getFile( 0 );\r
+\r
+                                               if ( CKEDITOR.tools.indexOf( supportedImageTypes, file.type ) != -1 ) {\r
+                                                       var fileReader = new FileReader();\r
+\r
+                                                       // Convert image file to img tag with base64 image.\r
+                                                       fileReader.addEventListener( 'load', function() {\r
+                                                               evt.data.dataValue = '<img src="' + fileReader.result + '" />';\r
+                                                               editor.fire( 'paste', evt.data );\r
+                                                       }, false );\r
+\r
+                                                       // Proceed with normal flow if reading file was aborted.\r
+                                                       fileReader.addEventListener( 'abort', function() {\r
+                                                               editor.fire( 'paste', evt.data );\r
+                                                       }, false );\r
+\r
+                                                       // Proceed with normal flow if reading file failed.\r
+                                                       fileReader.addEventListener( 'error', function() {\r
+                                                               editor.fire( 'paste', evt.data );\r
+                                                       }, false );\r
+\r
+                                                       fileReader.readAsDataURL( file );\r
+\r
+                                                       latestId = dataObj.dataTransfer.id;\r
+\r
+                                                       evt.stop();\r
+                                               }\r
+                                       }\r
+                               }, null, null, 1 );\r
+                       }\r
+\r
+                       editor.on( 'paste', function( evt ) {\r
+                               // Init `dataTransfer` if `paste` event was fired without it, so it will be always available.\r
+                               if ( !evt.data.dataTransfer ) {\r
+                                       evt.data.dataTransfer = new CKEDITOR.plugins.clipboard.dataTransfer();\r
+                               }\r
+\r
+                               // If dataValue is already set (manually or by paste bin), so do not override it.\r
+                               if ( evt.data.dataValue ) {\r
+                                       return;\r
+                               }\r
+\r
+                               var dataTransfer = evt.data.dataTransfer,\r
+                                       // IE support only text data and throws exception if we try to get html data.\r
+                                       // This html data object may also be empty if we drag content of the textarea.\r
+                                       value = dataTransfer.getData( 'text/html' );\r
+\r
+                               if ( value ) {\r
+                                       evt.data.dataValue = value;\r
+                                       evt.data.type = 'html';\r
+                               } else {\r
+                                       // Try to get text data otherwise.\r
+                                       value = dataTransfer.getData( 'text/plain' );\r
+\r
+                                       if ( value ) {\r
+                                               evt.data.dataValue = editor.editable().transformPlainTextToHtml( value );\r
+                                               evt.data.type = 'text';\r
+                                       }\r
+                               }\r
+                       }, null, null, 1 );\r
+\r
+                       editor.on( 'paste', function( evt ) {\r
+                               var data = evt.data.dataValue,\r
+                                       blockElements = CKEDITOR.dtd.$block;\r
+\r
+                               // Filter webkit garbage.\r
+                               if ( data.indexOf( 'Apple-' ) > -1 ) {\r
+                                       // Replace special webkit's &nbsp; with simple space, because webkit\r
+                                       // produces them even for normal spaces.\r
+                                       data = data.replace( /<span class="Apple-converted-space">&nbsp;<\/span>/gi, ' ' );\r
+\r
+                                       // Strip <span> around white-spaces when not in forced 'html' content type.\r
+                                       // This spans are created only when pasting plain text into Webkit,\r
+                                       // but for safety reasons remove them always.\r
+                                       if ( evt.data.type != 'html' ) {\r
+                                               data = data.replace( /<span class="Apple-tab-span"[^>]*>([^<]*)<\/span>/gi, function( all, spaces ) {\r
+                                                       // Replace tabs with 4 spaces like Fx does.\r
+                                                       return spaces.replace( /\t/g, '&nbsp;&nbsp; &nbsp;' );\r
+                                               } );\r
+                                       }\r
+\r
+                                       // This br is produced only when copying & pasting HTML content.\r
+                                       if ( data.indexOf( '<br class="Apple-interchange-newline">' ) > -1 ) {\r
+                                               evt.data.startsWithEOL = 1;\r
+                                               evt.data.preSniffing = 'html'; // Mark as not text.\r
+                                               data = data.replace( /<br class="Apple-interchange-newline">/, '' );\r
+                                       }\r
+\r
+                                       // Remove all other classes.\r
+                                       data = data.replace( /(<[^>]+) class="Apple-[^"]*"/gi, '$1' );\r
+                               }\r
+\r
+                               // Strip editable that was copied from inside. (#9534)\r
+                               if ( data.match( /^<[^<]+cke_(editable|contents)/i ) ) {\r
+                                       var tmp,\r
+                                               editable_wrapper,\r
+                                               wrapper = new CKEDITOR.dom.element( 'div' );\r
+\r
+                                       wrapper.setHtml( data );\r
+                                       // Verify for sure and check for nested editor UI parts. (#9675)\r
+                                       while ( wrapper.getChildCount() == 1 &&\r
+                                                       ( tmp = wrapper.getFirst() ) &&\r
+                                                       tmp.type == CKEDITOR.NODE_ELEMENT &&    // Make sure first-child is element.\r
+                                                       ( tmp.hasClass( 'cke_editable' ) || tmp.hasClass( 'cke_contents' ) ) ) {\r
+                                               wrapper = editable_wrapper = tmp;\r
+                                       }\r
+\r
+                                       // If editable wrapper was found strip it and bogus <br> (added on FF).\r
+                                       if ( editable_wrapper )\r
+                                               data = editable_wrapper.getHtml().replace( /<br>$/i, '' );\r
+                               }\r
+\r
+                               if ( CKEDITOR.env.ie ) {\r
+                                       // &nbsp; <p> -> <p> (br.cke-pasted-remove will be removed later)\r
+                                       data = data.replace( /^&nbsp;(?: |\r\n)?<(\w+)/g, function( match, elementName ) {\r
+                                               if ( elementName.toLowerCase() in blockElements ) {\r
+                                                       evt.data.preSniffing = 'html'; // Mark as not a text.\r
+                                                       return '<' + elementName;\r
+                                               }\r
+                                               return match;\r
+                                       } );\r
+                               } else if ( CKEDITOR.env.webkit ) {\r
+                                       // </p><div><br></div> -> </p><br>\r
+                                       // We don't mark br, because this situation can happen for htmlified text too.\r
+                                       data = data.replace( /<\/(\w+)><div><br><\/div>$/, function( match, elementName ) {\r
+                                               if ( elementName in blockElements ) {\r
+                                                       evt.data.endsWithEOL = 1;\r
+                                                       return '</' + elementName + '>';\r
+                                               }\r
+                                               return match;\r
+                                       } );\r
+                               } else if ( CKEDITOR.env.gecko ) {\r
+                                       // Firefox adds bogus <br> when user pasted text followed by space(s).\r
+                                       data = data.replace( /(\s)<br>$/, '$1' );\r
+                               }\r
+\r
+                               evt.data.dataValue = data;\r
+                       }, null, null, 3 );\r
+\r
+                       editor.on( 'paste', function( evt ) {\r
+                               var dataObj = evt.data,\r
+                                       type = dataObj.type,\r
+                                       data = dataObj.dataValue,\r
+                                       trueType,\r
+                                       // Default is 'html'.\r
+                                       defaultType = editor.config.clipboard_defaultContentType || 'html',\r
+                                       transferType = dataObj.dataTransfer.getTransferType( editor );\r
+\r
+                               // If forced type is 'html' we don't need to know true data type.\r
+                               if ( type == 'html' || dataObj.preSniffing == 'html' ) {\r
+                                       trueType = 'html';\r
+                               } else {\r
+                                       trueType = recogniseContentType( data );\r
+                               }\r
+\r
+                               // Unify text markup.\r
+                               if ( trueType == 'htmlifiedtext' ) {\r
+                                       data = htmlifiedTextHtmlification( editor.config, data );\r
+                               }\r
+\r
+                               // Strip presentational markup & unify text markup.\r
+                               // Forced plain text (dialog or forcePAPT).\r
+                               // Note: we do not check dontFilter option in this case, because forcePAPT was implemented\r
+                               // before pasteFilter and pasteFilter is automatically used on Webkit&Blink since 4.5, so\r
+                               // forcePAPT should have priority as it had before 4.5.\r
+                               if ( type == 'text' && trueType == 'html' ) {\r
+                                       data = filterContent( editor, data, filtersFactory.get( 'plain-text' ) );\r
+                               }\r
+                               // External paste and pasteFilter exists and filtering isn't disabled.\r
+                               else if ( transferType == CKEDITOR.DATA_TRANSFER_EXTERNAL && editor.pasteFilter && !dataObj.dontFilter ) {\r
+                                       data = filterContent( editor, data, editor.pasteFilter );\r
+                               }\r
+\r
+                               if ( dataObj.startsWithEOL ) {\r
+                                       data = '<br data-cke-eol="1">' + data;\r
+                               }\r
+                               if ( dataObj.endsWithEOL ) {\r
+                                       data += '<br data-cke-eol="1">';\r
+                               }\r
+\r
+                               if ( type == 'auto' ) {\r
+                                       type = ( trueType == 'html' || defaultType == 'html' ) ? 'html' : 'text';\r
+                               }\r
+\r
+                               dataObj.type = type;\r
+                               dataObj.dataValue = data;\r
+                               delete dataObj.preSniffing;\r
+                               delete dataObj.startsWithEOL;\r
+                               delete dataObj.endsWithEOL;\r
+                       }, null, null, 6 );\r
+\r
+                       // Inserts processed data into the editor at the end of the\r
+                       // events chain.\r
+                       editor.on( 'paste', function( evt ) {\r
+                               var data = evt.data;\r
+\r
+                               if ( data.dataValue ) {\r
+                                       editor.insertHtml( data.dataValue, data.type, data.range );\r
+\r
+                                       // Defer 'afterPaste' so all other listeners for 'paste' will be fired first.\r
+                                       // Fire afterPaste only if paste inserted some HTML.\r
+                                       setTimeout( function() {\r
+                                               editor.fire( 'afterPaste' );\r
+                                       }, 0 );\r
+                               }\r
+                       }, null, null, 1000 );\r
+\r
+                       editor.on( 'pasteDialog', function( evt ) {\r
+                               // TODO it's possible that this setTimeout is not needed any more,\r
+                               // because of changes introduced in the same commit as this comment.\r
+                               // Editor.getClipboardData adds listener to the dialog's events which are\r
+                               // fired after a while (not like 'showDialog').\r
+                               setTimeout( function() {\r
+                                       // Open default paste dialog.\r
+                                       editor.openDialog( 'paste', evt.data );\r
+                               }, 0 );\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       function firePasteEvents( editor, data, withBeforePaste ) {\r
+               if ( !data.type ) {\r
+                       data.type = 'auto';\r
+               }\r
+\r
+               if ( withBeforePaste ) {\r
+                       // Fire 'beforePaste' event so clipboard flavor get customized\r
+                       // by other plugins.\r
+                       if ( editor.fire( 'beforePaste', data ) === false )\r
+                               return false; // Event canceled\r
+               }\r
+\r
+               // Do not fire paste if there is no data (dataValue and dataTranfser are empty).\r
+               // This check should be done after firing 'beforePaste' because for native paste\r
+               // 'beforePaste' is by default fired even for empty clipboard.\r
+               if ( !data.dataValue && data.dataTransfer.isEmpty() ) {\r
+                       return false;\r
+               }\r
+\r
+               if ( !data.dataValue ) {\r
+                       data.dataValue = '';\r
+               }\r
+\r
+               // Because of FF bug we need to use this hack, otherwise cursor is hidden\r
+               // or it is not possible to move it (#12420).\r
+               // Also, check that editor.toolbox exists, because the toolbar plugin might not be loaded (#13305).\r
+               if ( CKEDITOR.env.gecko && data.method == 'drop' && editor.toolbox ) {\r
+                       editor.once( 'afterPaste', function() {\r
+                               editor.toolbox.focus();\r
+                       } );\r
+               }\r
+\r
+               return editor.fire( 'paste', data );\r
+       }\r
+\r
+       function initPasteClipboard( editor ) {\r
+               var clipboard = CKEDITOR.plugins.clipboard,\r
+                       preventBeforePasteEvent = 0,\r
+                       preventPasteEvent = 0,\r
+                       inReadOnly = 0;\r
+\r
+               addListeners();\r
+               addButtonsCommands();\r
+\r
+               /**\r
+                * Gets clipboard data by directly accessing the clipboard (IE only) or opening the paste dialog window.\r
+                *\r
+                *              editor.getClipboardData( { title: 'Get my data' }, function( data ) {\r
+                *                      if ( data )\r
+                *                              alert( data.type + ' ' + data.dataValue );\r
+                *              } );\r
+                *\r
+                * @member CKEDITOR.editor\r
+                * @param {Object} options\r
+                * @param {String} [options.title] The title of the paste dialog window.\r
+                * @param {Function} callback A function that will be executed with `data.type` and `data.dataValue`\r
+                * or `null` if none of the capturing methods succeeded.\r
+                */\r
+               editor.getClipboardData = function( options, callback ) {\r
+                       var beforePasteNotCanceled = false,\r
+                               dataType = 'auto',\r
+                               dialogCommited = false;\r
+\r
+                       // Options are optional - args shift.\r
+                       if ( !callback ) {\r
+                               callback = options;\r
+                               options = null;\r
+                       }\r
+\r
+                       // Listen with maximum priority to handle content before everyone else.\r
+                       // This callback will handle paste event that will be fired if direct\r
+                       // access to the clipboard succeed in IE.\r
+                       editor.on( 'paste', onPaste, null, null, 0 );\r
+\r
+                       // Listen at the end of listeners chain to see if event wasn't canceled\r
+                       // and to retrieve modified data.type.\r
+                       editor.on( 'beforePaste', onBeforePaste, null, null, 1000 );\r
+\r
+                       // getClipboardDataDirectly() will fire 'beforePaste' synchronously, so we can\r
+                       // check if it was canceled and if any listener modified data.type.\r
+\r
+                       // If command didn't succeed (only IE allows to access clipboard and only if\r
+                       // user agrees) open and handle paste dialog.\r
+                       if ( getClipboardDataDirectly() === false ) {\r
+                               // Direct access to the clipboard wasn't successful so remove listener.\r
+                               editor.removeListener( 'paste', onPaste );\r
+\r
+                               // If beforePaste was canceled do not open dialog.\r
+                               // Add listeners only if dialog really opened. 'pasteDialog' can be canceled.\r
+                               if ( beforePasteNotCanceled && editor.fire( 'pasteDialog', onDialogOpen ) ) {\r
+                                       editor.on( 'pasteDialogCommit', onDialogCommit );\r
+\r
+                                       // 'dialogHide' will be fired after 'pasteDialogCommit'.\r
+                                       editor.on( 'dialogHide', function( evt ) {\r
+                                               evt.removeListener();\r
+                                               evt.data.removeListener( 'pasteDialogCommit', onDialogCommit );\r
+\r
+                                               // Because Opera has to wait a while in pasteDialog we have to wait here.\r
+                                               setTimeout( function() {\r
+                                                       // Notify even if user canceled dialog (clicked 'cancel', ESC, etc).\r
+                                                       if ( !dialogCommited )\r
+                                                               callback( null );\r
+                                               }, 10 );\r
+                                       } );\r
+                               } else {\r
+                                       callback( null );\r
+                               }\r
+                       }\r
+\r
+                       function onPaste( evt ) {\r
+                               evt.removeListener();\r
+                               evt.cancel();\r
+                               callback( evt.data );\r
+                       }\r
+\r
+                       function onBeforePaste( evt ) {\r
+                               evt.removeListener();\r
+                               beforePasteNotCanceled = true;\r
+                               dataType = evt.data.type;\r
+                       }\r
+\r
+                       function onDialogCommit( evt ) {\r
+                               evt.removeListener();\r
+                               // Cancel pasteDialogCommit so paste dialog won't automatically fire\r
+                               // 'paste' evt by itself.\r
+                               evt.cancel();\r
+                               dialogCommited = true;\r
+                               callback( {\r
+                                       type: dataType,\r
+                                       dataValue: evt.data.dataValue,\r
+                                       dataTransfer: evt.data.dataTransfer,\r
+                                       method: 'paste'\r
+                               } );\r
+                       }\r
+\r
+                       function onDialogOpen() {\r
+                               this.customTitle = ( options && options.title );\r
+                       }\r
+               };\r
+\r
+               function addButtonsCommands() {\r
+                       addButtonCommand( 'Cut', 'cut', createCutCopyCmd( 'cut' ), 10, 1 );\r
+                       addButtonCommand( 'Copy', 'copy', createCutCopyCmd( 'copy' ), 20, 4 );\r
+                       addButtonCommand( 'Paste', 'paste', createPasteCmd(), 30, 8 );\r
+\r
+                       function addButtonCommand( buttonName, commandName, command, toolbarOrder, ctxMenuOrder ) {\r
+                               var lang = editor.lang.clipboard[ commandName ];\r
+\r
+                               editor.addCommand( commandName, command );\r
+                               editor.ui.addButton && editor.ui.addButton( buttonName, {\r
+                                       label: lang,\r
+                                       command: commandName,\r
+                                       toolbar: 'clipboard,' + toolbarOrder\r
+                               } );\r
+\r
+                               // If the "menu" plugin is loaded, register the menu item.\r
+                               if ( editor.addMenuItems ) {\r
+                                       editor.addMenuItem( commandName, {\r
+                                               label: lang,\r
+                                               command: commandName,\r
+                                               group: 'clipboard',\r
+                                               order: ctxMenuOrder\r
+                                       } );\r
+                               }\r
+                       }\r
+               }\r
+\r
+               function addListeners() {\r
+                       editor.on( 'key', onKey );\r
+                       editor.on( 'contentDom', addPasteListenersToEditable );\r
+\r
+                       // For improved performance, we're checking the readOnly state on selectionChange instead of hooking a key event for that.\r
+                       editor.on( 'selectionChange', function( evt ) {\r
+                               inReadOnly = evt.data.selection.getRanges()[ 0 ].checkReadOnly();\r
+                               setToolbarStates();\r
+                       } );\r
+\r
+                       // If the "contextmenu" plugin is loaded, register the listeners.\r
+                       if ( editor.contextMenu ) {\r
+                               editor.contextMenu.addListener( function( element, selection ) {\r
+                                       inReadOnly = selection.getRanges()[ 0 ].checkReadOnly();\r
+                                       return {\r
+                                               cut: stateFromNamedCommand( 'cut' ),\r
+                                               copy: stateFromNamedCommand( 'copy' ),\r
+                                               paste: stateFromNamedCommand( 'paste' )\r
+                                       };\r
+                               } );\r
+                       }\r
+               }\r
+\r
+               // Add events listeners to editable.\r
+               function addPasteListenersToEditable() {\r
+                       var editable = editor.editable();\r
+\r
+                       if ( CKEDITOR.plugins.clipboard.isCustomCopyCutSupported ) {\r
+                               var initOnCopyCut = function( evt ) {\r
+                                       // If user tries to cut in read-only editor, we must prevent default action. (#13872)\r
+                                       if ( !editor.readOnly || evt.name != 'cut' ) {\r
+                                               clipboard.initPasteDataTransfer( evt, editor );\r
+                                       }\r
+                                       evt.data.preventDefault();\r
+                               };\r
+\r
+                               editable.on( 'copy', initOnCopyCut );\r
+                               editable.on( 'cut', initOnCopyCut );\r
+\r
+                               // Delete content with the low priority so one can overwrite cut data.\r
+                               editable.on( 'cut', function() {\r
+                                       // If user tries to cut in read-only editor, we must prevent default action. (#13872)\r
+                                       if ( !editor.readOnly ) {\r
+                                               editor.extractSelectedHtml();\r
+                                       }\r
+                               }, null, null, 999 );\r
+                       }\r
+\r
+                       // We'll be catching all pasted content in one line, regardless of whether\r
+                       // it's introduced by a document command execution (e.g. toolbar buttons) or\r
+                       // user paste behaviors (e.g. CTRL+V).\r
+                       editable.on( clipboard.mainPasteEvent, function( evt ) {\r
+                               if ( clipboard.mainPasteEvent == 'beforepaste' && preventBeforePasteEvent ) {\r
+                                       return;\r
+                               }\r
+\r
+                               // If you've just asked yourself why preventPasteEventNow() is not here, but\r
+                               // in listener for CTRL+V and exec method of 'paste' command\r
+                               // you've asked the same question we did.\r
+                               //\r
+                               // THE ANSWER:\r
+                               //\r
+                               // First thing to notice - this answer makes sense only for IE,\r
+                               // because other browsers don't listen for 'paste' event.\r
+                               //\r
+                               // What would happen if we move preventPasteEventNow() here?\r
+                               // For:\r
+                               // * CTRL+V - IE fires 'beforepaste', so we prevent 'paste' and pasteDataFromClipboard(). OK.\r
+                               // * editor.execCommand( 'paste' ) - we fire 'beforepaste', so we prevent\r
+                               //              'paste' and pasteDataFromClipboard() and doc.execCommand( 'Paste' ). OK.\r
+                               // * native context menu - IE fires 'beforepaste', so we prevent 'paste', but unfortunately\r
+                               //              on IE we fail with pasteDataFromClipboard() here, because of... we don't know why, but\r
+                               //              we just fail, so... we paste nothing. FAIL.\r
+                               // * native menu bar - the same as for native context menu.\r
+                               //\r
+                               // But don't you know any way to distinguish first two cases from last two?\r
+                               // Only one - special flag set in CTRL+V handler and exec method of 'paste'\r
+                               // command. And that's what we did using preventPasteEventNow().\r
+\r
+                               pasteDataFromClipboard( evt );\r
+                       } );\r
+\r
+                       // It's not possible to clearly handle all four paste methods (ctrl+v, native menu bar\r
+                       // native context menu, editor's command) in one 'paste/beforepaste' event in IE.\r
+                       //\r
+                       // For ctrl+v & editor's command it's easy to handle pasting in 'beforepaste' listener,\r
+                       // so we do this. For another two methods it's better to use 'paste' event.\r
+                       //\r
+                       // 'paste' is always being fired after 'beforepaste' (except of weird one on opening native\r
+                       // context menu), so for two methods handled in 'beforepaste' we're canceling 'paste'\r
+                       // using preventPasteEvent state.\r
+                       //\r
+                       // 'paste' event in IE is being fired before getClipboardDataByPastebin executes its callback.\r
+                       //\r
+                       // QUESTION: Why didn't you handle all 4 paste methods in handler for 'paste'?\r
+                       //              Wouldn't this just be simpler?\r
+                       // ANSWER: Then we would have to evt.data.preventDefault() only for native\r
+                       //              context menu and menu bar pastes. The same with execIECommand().\r
+                       //              That would force us to mark CTRL+V and editor's paste command with\r
+                       //              special flag, other than preventPasteEvent. But we still would have to\r
+                       //              have preventPasteEvent for the second event fired by execIECommand.\r
+                       //              Code would be longer and not cleaner.\r
+                       if ( clipboard.mainPasteEvent == 'beforepaste' ) {\r
+                               editable.on( 'paste', function( evt ) {\r
+                                       if ( preventPasteEvent ) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       // Cancel next 'paste' event fired by execIECommand( 'paste' )\r
+                                       // at the end of this callback.\r
+                                       preventPasteEventNow();\r
+\r
+                                       // Prevent native paste.\r
+                                       evt.data.preventDefault();\r
+\r
+                                       pasteDataFromClipboard( evt );\r
+\r
+                                       // Force IE to paste content into pastebin so pasteDataFromClipboard will work.\r
+                                       if ( !execIECommand( 'paste' ) ) {\r
+                                               editor.openDialog( 'paste' );\r
+                                       }\r
+                               } );\r
+\r
+                               // If mainPasteEvent is 'beforePaste' (IE before Edge),\r
+                               // dismiss the (wrong) 'beforepaste' event fired on context/toolbar menu open. (#7953)\r
+                               editable.on( 'contextmenu', preventBeforePasteEventNow, null, null, 0 );\r
+\r
+                               editable.on( 'beforepaste', function( evt ) {\r
+                                       // Do not prevent event on CTRL+V and SHIFT+INS because it blocks paste (#11970).\r
+                                       if ( evt.data && !evt.data.$.ctrlKey && !evt.data.$.shiftKey )\r
+                                               preventBeforePasteEventNow();\r
+                               }, null, null, 0 );\r
+                       }\r
+\r
+                       editable.on( 'beforecut', function() {\r
+                               !preventBeforePasteEvent && fixCut( editor );\r
+                       } );\r
+\r
+                       var mouseupTimeout;\r
+\r
+                       // Use editor.document instead of editable in non-IEs for observing mouseup\r
+                       // since editable won't fire the event if selection process started within\r
+                       // iframe and ended out of the editor (#9851).\r
+                       editable.attachListener( CKEDITOR.env.ie ? editable : editor.document.getDocumentElement(), 'mouseup', function() {\r
+                               mouseupTimeout = setTimeout( function() {\r
+                                       setToolbarStates();\r
+                               }, 0 );\r
+                       } );\r
+\r
+                       // Make sure that deferred mouseup callback isn't executed after editor instance\r
+                       // had been destroyed. This may happen when editor.destroy() is called in parallel\r
+                       // with mouseup event (i.e. a button with onclick callback) (#10219).\r
+                       editor.on( 'destroy', function() {\r
+                               clearTimeout( mouseupTimeout );\r
+                       } );\r
+\r
+                       editable.on( 'keyup', setToolbarStates );\r
+               }\r
+\r
+               // Create object representing Cut or Copy commands.\r
+               function createCutCopyCmd( type ) {\r
+                       return {\r
+                               type: type,\r
+                               canUndo: type == 'cut', // We can't undo copy to clipboard.\r
+                               startDisabled: true,\r
+                               fakeKeystroke: type == 'cut' ? CKEDITOR.CTRL + 88 /*X*/ :  CKEDITOR.CTRL + 67 /*C*/,\r
+                               exec: function() {\r
+                                       // Attempts to execute the Cut and Copy operations.\r
+                                       function tryToCutCopy( type ) {\r
+                                               if ( CKEDITOR.env.ie )\r
+                                                       return execIECommand( type );\r
+\r
+                                               // non-IEs part\r
+                                               try {\r
+                                                       // Other browsers throw an error if the command is disabled.\r
+                                                       return editor.document.$.execCommand( type, false, null );\r
+                                               } catch ( e ) {\r
+                                                       return false;\r
+                                               }\r
+                                       }\r
+\r
+                                       this.type == 'cut' && fixCut();\r
+\r
+                                       var success = tryToCutCopy( this.type );\r
+\r
+                                       if ( !success ) {\r
+                                               // Show cutError or copyError.\r
+                                               editor.showNotification( editor.lang.clipboard[ this.type + 'Error' ] ); // jshint ignore:line\r
+                                       }\r
+\r
+                                       return success;\r
+                               }\r
+                       };\r
+               }\r
+\r
+               function createPasteCmd() {\r
+                       return {\r
+                               // Snapshots are done manually by editable.insertXXX methods.\r
+                               canUndo: false,\r
+                               async: true,\r
+                               fakeKeystroke: CKEDITOR.CTRL + 86 /*V*/,\r
+                               exec: function( editor, data ) {\r
+                                       var cmd = this,\r
+                                               fire = function( data, withBeforePaste ) {\r
+                                                       data && firePasteEvents( editor, data, !!withBeforePaste );\r
+\r
+                                                       editor.fire( 'afterCommandExec', {\r
+                                                               name: 'paste',\r
+                                                               command: cmd,\r
+                                                               returnValue: !!data\r
+                                                       } );\r
+                                               };\r
+\r
+                                       // Check data precisely - don't open dialog on empty string.\r
+                                       if ( typeof data == 'string' )\r
+                                               fire( {\r
+                                                               dataValue: data,\r
+                                                               method: 'paste',\r
+                                                               dataTransfer: clipboard.initPasteDataTransfer()\r
+                                                       }, 1 );\r
+                                       else\r
+                                               editor.getClipboardData( fire );\r
+                               }\r
+                       };\r
+               }\r
+\r
+               function preventPasteEventNow() {\r
+                       preventPasteEvent = 1;\r
+                       // For safety reason we should wait longer than 0/1ms.\r
+                       // We don't know how long execution of quite complex getClipboardData will take\r
+                       // and in for example 'paste' listener execCommand() (which fires 'paste') is called\r
+                       // after getClipboardData finishes.\r
+                       // Luckily, it's impossible to immediately fire another 'paste' event we want to handle,\r
+                       // because we only handle there native context menu and menu bar.\r
+                       setTimeout( function() {\r
+                               preventPasteEvent = 0;\r
+                       }, 100 );\r
+               }\r
+\r
+               function preventBeforePasteEventNow() {\r
+                       preventBeforePasteEvent = 1;\r
+                       setTimeout( function() {\r
+                               preventBeforePasteEvent = 0;\r
+                       }, 10 );\r
+               }\r
+\r
+               // Tries to execute any of the paste, cut or copy commands in IE. Returns a\r
+               // boolean indicating that the operation succeeded.\r
+               // @param {String} command *LOWER CASED* name of command ('paste', 'cut', 'copy').\r
+               function execIECommand( command ) {\r
+                       var doc = editor.document,\r
+                               body = doc.getBody(),\r
+                               enabled = false,\r
+                               onExec = function() {\r
+                                       enabled = true;\r
+                               };\r
+\r
+                       // The following seems to be the only reliable way to detect that\r
+                       // clipboard commands are enabled in IE. It will fire the\r
+                       // onpaste/oncut/oncopy events only if the security settings allowed\r
+                       // the command to execute.\r
+                       body.on( command, onExec );\r
+\r
+                       // IE7: document.execCommand has problem to paste into positioned element.\r
+                       if ( CKEDITOR.env.version > 7 ) {\r
+                               doc.$.execCommand( command );\r
+                       } else {\r
+                               doc.$.selection.createRange().execCommand( command );\r
+                       }\r
+\r
+                       body.removeListener( command, onExec );\r
+\r
+                       return enabled;\r
+               }\r
+\r
+               // Cutting off control type element in IE standards breaks the selection entirely. (#4881)\r
+               function fixCut() {\r
+                       if ( !CKEDITOR.env.ie || CKEDITOR.env.quirks )\r
+                               return;\r
+\r
+                       var sel = editor.getSelection(),\r
+                               control, range, dummy;\r
+\r
+                       if ( ( sel.getType() == CKEDITOR.SELECTION_ELEMENT ) && ( control = sel.getSelectedElement() ) ) {\r
+                               range = sel.getRanges()[ 0 ];\r
+                               dummy = editor.document.createText( '' );\r
+                               dummy.insertBefore( control );\r
+                               range.setStartBefore( dummy );\r
+                               range.setEndAfter( control );\r
+                               sel.selectRanges( [ range ] );\r
+\r
+                               // Clear up the fix if the paste wasn't succeeded.\r
+                               setTimeout( function() {\r
+                                       // Element still online?\r
+                                       if ( control.getParent() ) {\r
+                                               dummy.remove();\r
+                                               sel.selectElement( control );\r
+                                       }\r
+                               }, 0 );\r
+                       }\r
+               }\r
+\r
+               // Allow to peek clipboard content by redirecting the\r
+               // pasting content into a temporary bin and grab the content of it.\r
+               function getClipboardDataByPastebin( evt, callback ) {\r
+                       var doc = editor.document,\r
+                               editable = editor.editable(),\r
+                               cancel = function( evt ) {\r
+                                       evt.cancel();\r
+                               },\r
+                               blurListener;\r
+\r
+                       // Avoid recursions on 'paste' event or consequent paste too fast. (#5730)\r
+                       if ( doc.getById( 'cke_pastebin' ) )\r
+                               return;\r
+\r
+                       var sel = editor.getSelection();\r
+                       var bms = sel.createBookmarks();\r
+\r
+                       // #11384. On IE9+ we use native selectionchange (i.e. editor#selectionCheck) to cache the most\r
+                       // recent selection which we then lock on editable blur. See selection.js for more info.\r
+                       // selectionchange fired before getClipboardDataByPastebin() cached selection\r
+                       // before creating bookmark (cached selection will be invalid, because bookmarks modified the DOM),\r
+                       // so we need to fire selectionchange one more time, to store current seleciton.\r
+                       // Selection will be locked when we focus pastebin.\r
+                       if ( CKEDITOR.env.ie )\r
+                               sel.root.fire( 'selectionchange' );\r
+\r
+                       // Create container to paste into.\r
+                       // For rich content we prefer to use "body" since it holds\r
+                       // the least possibility to be splitted by pasted content, while this may\r
+                       // breaks the text selection on a frame-less editable, "div" would be\r
+                       // the best one in that case.\r
+                       // In another case on old IEs moving the selection into a "body" paste bin causes error panic.\r
+                       // Body can't be also used for Opera which fills it with <br>\r
+                       // what is indistinguishable from pasted <br> (copying <br> in Opera isn't possible,\r
+                       // but it can be copied from other browser).\r
+                       var pastebin = new CKEDITOR.dom.element(\r
+                               ( CKEDITOR.env.webkit || editable.is( 'body' ) ) && !CKEDITOR.env.ie ? 'body' : 'div', doc );\r
+\r
+                       pastebin.setAttributes( {\r
+                               id: 'cke_pastebin',\r
+                               'data-cke-temp': '1'\r
+                       } );\r
+\r
+                       var containerOffset = 0,\r
+                               offsetParent,\r
+                               win = doc.getWindow();\r
+\r
+                       if ( CKEDITOR.env.webkit ) {\r
+                               // It's better to paste close to the real paste destination, so inherited styles\r
+                               // (which Webkits will try to compensate by styling span) differs less from the destination's one.\r
+                               editable.append( pastebin );\r
+                               // Style pastebin like .cke_editable, to minimize differences between origin and destination. (#9754)\r
+                               pastebin.addClass( 'cke_editable' );\r
+\r
+                               // Compensate position of offsetParent.\r
+                               if ( !editable.is( 'body' ) ) {\r
+                                       // We're not able to get offsetParent from pastebin (body element), so check whether\r
+                                       // its parent (editable) is positioned.\r
+                                       if ( editable.getComputedStyle( 'position' ) != 'static' )\r
+                                               offsetParent = editable;\r
+                                       // And if not - safely get offsetParent from editable.\r
+                                       else\r
+                                               offsetParent = CKEDITOR.dom.element.get( editable.$.offsetParent );\r
+\r
+                                       containerOffset = offsetParent.getDocumentPosition().y;\r
+                               }\r
+                       } else {\r
+                               // Opera and IE doesn't allow to append to html element.\r
+                               editable.getAscendant( CKEDITOR.env.ie ? 'body' : 'html', 1 ).append( pastebin );\r
+                       }\r
+\r
+                       pastebin.setStyles( {\r
+                               position: 'absolute',\r
+                               // Position the bin at the top (+10 for safety) of viewport to avoid any subsequent document scroll.\r
+                               top: ( win.getScrollPosition().y - containerOffset + 10 ) + 'px',\r
+                               width: '1px',\r
+                               // Caret has to fit in that height, otherwise browsers like Chrome & Opera will scroll window to show it.\r
+                               // Set height equal to viewport's height - 20px (safety gaps), minimum 1px.\r
+                               height: Math.max( 1, win.getViewPaneSize().height - 20 ) + 'px',\r
+                               overflow: 'hidden',\r
+                               // Reset styles that can mess up pastebin position.\r
+                               margin: 0,\r
+                               padding: 0\r
+                       } );\r
+\r
+                       // Paste fails in Safari when the body tag has 'user-select: none'. (#12506)\r
+                       if ( CKEDITOR.env.safari )\r
+                               pastebin.setStyles( CKEDITOR.tools.cssVendorPrefix( 'user-select', 'text' ) );\r
+\r
+                       // Check if the paste bin now establishes new editing host.\r
+                       var isEditingHost = pastebin.getParent().isReadOnly();\r
+\r
+                       if ( isEditingHost ) {\r
+                               // Hide the paste bin.\r
+                               pastebin.setOpacity( 0 );\r
+                               // And make it editable.\r
+                               pastebin.setAttribute( 'contenteditable', true );\r
+                       }\r
+                       // Transparency is not enough since positioned non-editing host always shows\r
+                       // resize handler, pull it off the screen instead.\r
+                       else {\r
+                               pastebin.setStyle( editor.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-10000px' );\r
+                       }\r
+\r
+                       editor.on( 'selectionChange', cancel, null, null, 0 );\r
+\r
+                       // Webkit fill fire blur on editable when moving selection to\r
+                       // pastebin (if body is used). Cancel it because it causes incorrect\r
+                       // selection lock in case of inline editor (#10644).\r
+                       // The same seems to apply to Firefox (#10787).\r
+                       if ( CKEDITOR.env.webkit || CKEDITOR.env.gecko )\r
+                               blurListener = editable.once( 'blur', cancel, null, null, -100 );\r
+\r
+                       // Temporarily move selection to the pastebin.\r
+                       isEditingHost && pastebin.focus();\r
+                       var range = new CKEDITOR.dom.range( pastebin );\r
+                       range.selectNodeContents( pastebin );\r
+                       var selPastebin = range.select();\r
+\r
+                       // If non-native paste is executed, IE will open security alert and blur editable.\r
+                       // Editable will then lock selection inside itself and after accepting security alert\r
+                       // this selection will be restored. We overwrite stored selection, so it's restored\r
+                       // in pastebin. (#9552)\r
+                       if ( CKEDITOR.env.ie ) {\r
+                               blurListener = editable.once( 'blur', function() {\r
+                                       editor.lockSelection( selPastebin );\r
+                               } );\r
+                       }\r
+\r
+                       var scrollTop = CKEDITOR.document.getWindow().getScrollPosition().y;\r
+\r
+                       // Wait a while and grab the pasted contents.\r
+                       setTimeout( function() {\r
+                               // Restore main window's scroll position which could have been changed\r
+                               // by browser in cases described in #9771.\r
+                               if ( CKEDITOR.env.webkit )\r
+                                       CKEDITOR.document.getBody().$.scrollTop = scrollTop;\r
+\r
+                               // Blur will be fired only on non-native paste. In other case manually remove listener.\r
+                               blurListener && blurListener.removeListener();\r
+\r
+                               // Restore properly the document focus. (#8849)\r
+                               if ( CKEDITOR.env.ie )\r
+                                       editable.focus();\r
+\r
+                               // IE7: selection must go before removing pastebin. (#8691)\r
+                               sel.selectBookmarks( bms );\r
+                               pastebin.remove();\r
+\r
+                               // Grab the HTML contents.\r
+                               // We need to look for a apple style wrapper on webkit it also adds\r
+                               // a div wrapper if you copy/paste the body of the editor.\r
+                               // Remove hidden div and restore selection.\r
+                               var bogusSpan;\r
+                               if ( CKEDITOR.env.webkit && ( bogusSpan = pastebin.getFirst() ) && ( bogusSpan.is && bogusSpan.hasClass( 'Apple-style-span' ) ) )\r
+                                       pastebin = bogusSpan;\r
+\r
+                               editor.removeListener( 'selectionChange', cancel );\r
+                               callback( pastebin.getHtml() );\r
+                       }, 0 );\r
+               }\r
+\r
+               // Try to get content directly on IE from clipboard, without native event\r
+               // being fired before. In other words - synthetically get clipboard data, if it's possible.\r
+               // mainPasteEvent will be fired, so if forced native paste:\r
+               // * worked, getClipboardDataByPastebin will grab it,\r
+               // * didn't work, dataValue and dataTransfer will be empty and editor#paste won't be fired.\r
+               // Clipboard data can be accessed directly only on IEs older than Edge.\r
+               // On other browsers we should fire beforePaste event and return false.\r
+               function getClipboardDataDirectly() {\r
+                       if ( clipboard.mainPasteEvent == 'paste' ) {\r
+                               // beforePaste should be fired when dialog open so it can be canceled.\r
+                               editor.fire( 'beforePaste', { type: 'auto', method: 'paste' } );\r
+                               return false;\r
+                       }\r
+\r
+                       // Prevent IE from pasting at the begining of the document.\r
+                       editor.focus();\r
+\r
+                       // Command will be handled by 'beforepaste', but as\r
+                       // execIECommand( 'paste' ) will fire also 'paste' event\r
+                       // we're canceling it.\r
+                       preventPasteEventNow();\r
+\r
+                       // #9247: Lock focus to prevent IE from hiding toolbar for inline editor.\r
+                       var focusManager = editor.focusManager;\r
+                       focusManager.lock();\r
+\r
+                       if ( editor.editable().fire( clipboard.mainPasteEvent ) && !execIECommand( 'paste' ) ) {\r
+                               focusManager.unlock();\r
+                               return false;\r
+                       }\r
+                       focusManager.unlock();\r
+\r
+                       return true;\r
+               }\r
+\r
+               // Listens for some clipboard related keystrokes, so they get customized.\r
+               // Needs to be bind to keydown event.\r
+               function onKey( event ) {\r
+                       if ( editor.mode != 'wysiwyg' )\r
+                               return;\r
+\r
+                       switch ( event.data.keyCode ) {\r
+                               // Paste\r
+                               case CKEDITOR.CTRL + 86: // CTRL+V\r
+                               case CKEDITOR.SHIFT + 45: // SHIFT+INS\r
+                                       var editable = editor.editable();\r
+\r
+                                       // Cancel 'paste' event because ctrl+v is for IE handled\r
+                                       // by 'beforepaste'.\r
+                                       preventPasteEventNow();\r
+\r
+                                       // Simulate 'beforepaste' event for all browsers using 'paste' as main event.\r
+                                       if ( clipboard.mainPasteEvent == 'paste' ) {\r
+                                               editable.fire( 'beforepaste' );\r
+                                       }\r
+\r
+                                       return;\r
+\r
+                                       // Cut\r
+                               case CKEDITOR.CTRL + 88: // CTRL+X\r
+                               case CKEDITOR.SHIFT + 46: // SHIFT+DEL\r
+                                       // Save Undo snapshot.\r
+                                       editor.fire( 'saveSnapshot' ); // Save before cut\r
+                                       setTimeout( function() {\r
+                                               editor.fire( 'saveSnapshot' ); // Save after cut\r
+                                       }, 50 ); // OSX is slow (#11416).\r
+                       }\r
+               }\r
+\r
+               function pasteDataFromClipboard( evt ) {\r
+                       // Default type is 'auto', but can be changed by beforePaste listeners.\r
+                       var eventData = {\r
+                                       type: 'auto',\r
+                                       method: 'paste',\r
+                                       dataTransfer: clipboard.initPasteDataTransfer( evt )\r
+                               };\r
+\r
+                       eventData.dataTransfer.cacheData();\r
+\r
+                       // Fire 'beforePaste' event so clipboard flavor get customized by other plugins.\r
+                       // If 'beforePaste' is canceled continue executing getClipboardDataByPastebin and then do nothing\r
+                       // (do not fire 'paste', 'afterPaste' events). This way we can grab all - synthetically\r
+                       // and natively pasted content and prevent its insertion into editor\r
+                       // after canceling 'beforePaste' event.\r
+                       var beforePasteNotCanceled = editor.fire( 'beforePaste', eventData ) !== false;\r
+\r
+                       // Do not use paste bin if the browser let us get HTML or files from dataTranfer.\r
+                       if ( beforePasteNotCanceled && clipboard.canClipboardApiBeTrusted( eventData.dataTransfer, editor ) ) {\r
+                               evt.data.preventDefault();\r
+                               setTimeout( function() {\r
+                                       firePasteEvents( editor, eventData );\r
+                               }, 0 );\r
+                       } else {\r
+                               getClipboardDataByPastebin( evt, function( data ) {\r
+                                       // Clean up.\r
+                                       eventData.dataValue = data.replace( /<span[^>]+data-cke-bookmark[^<]*?<\/span>/ig, '' );\r
+\r
+                                       // Fire remaining events (without beforePaste)\r
+                                       beforePasteNotCanceled && firePasteEvents( editor, eventData );\r
+                               } );\r
+                       }\r
+               }\r
+\r
+               function setToolbarStates() {\r
+                       if ( editor.mode != 'wysiwyg' )\r
+                               return;\r
+\r
+                       var pasteState = stateFromNamedCommand( 'paste' );\r
+\r
+                       editor.getCommand( 'cut' ).setState( stateFromNamedCommand( 'cut' ) );\r
+                       editor.getCommand( 'copy' ).setState( stateFromNamedCommand( 'copy' ) );\r
+                       editor.getCommand( 'paste' ).setState( pasteState );\r
+                       editor.fire( 'pasteState', pasteState );\r
+               }\r
+\r
+               function stateFromNamedCommand( command ) {\r
+                       if ( inReadOnly && command in { paste: 1, cut: 1 } )\r
+                               return CKEDITOR.TRISTATE_DISABLED;\r
+\r
+                       if ( command == 'paste' )\r
+                               return CKEDITOR.TRISTATE_OFF;\r
+\r
+                       // Cut, copy - check if the selection is not empty.\r
+                       var sel = editor.getSelection(),\r
+                               ranges = sel.getRanges(),\r
+                               selectionIsEmpty = sel.getType() == CKEDITOR.SELECTION_NONE || ( ranges.length == 1 && ranges[ 0 ].collapsed );\r
+\r
+                       return selectionIsEmpty ? CKEDITOR.TRISTATE_DISABLED : CKEDITOR.TRISTATE_OFF;\r
+               }\r
+       }\r
+\r
+       // Returns:\r
+       // * 'htmlifiedtext' if content looks like transformed by browser from plain text.\r
+       //              See clipboard/paste.html TCs for more info.\r
+       // * 'html' if it is not 'htmlifiedtext'.\r
+       function recogniseContentType( data ) {\r
+               if ( CKEDITOR.env.webkit ) {\r
+                       // Plain text or ( <div><br></div> and text inside <div> ).\r
+                       if ( !data.match( /^[^<]*$/g ) && !data.match( /^(<div><br( ?\/)?><\/div>|<div>[^<]*<\/div>)*$/gi ) )\r
+                               return 'html';\r
+               } else if ( CKEDITOR.env.ie ) {\r
+                       // Text and <br> or ( text and <br> in <p> - paragraphs can be separated by new \r\n ).\r
+                       if ( !data.match( /^([^<]|<br( ?\/)?>)*$/gi ) && !data.match( /^(<p>([^<]|<br( ?\/)?>)*<\/p>|(\r\n))*$/gi ) )\r
+                               return 'html';\r
+               } else if ( CKEDITOR.env.gecko ) {\r
+                       // Text or <br>.\r
+                       if ( !data.match( /^([^<]|<br( ?\/)?>)*$/gi ) )\r
+                               return 'html';\r
+               } else {\r
+                       return 'html';\r
+               }\r
+\r
+               return 'htmlifiedtext';\r
+       }\r
+\r
+       // This function transforms what browsers produce when\r
+       // pasting plain text into editable element (see clipboard/paste.html TCs\r
+       // for more info) into correct HTML (similar to that produced by text2Html).\r
+       function htmlifiedTextHtmlification( config, data ) {\r
+               function repeatParagraphs( repeats ) {\r
+                       // Repeat blocks floor((n+1)/2) times.\r
+                       // Even number of repeats - add <br> at the beginning of last <p>.\r
+                       return CKEDITOR.tools.repeat( '</p><p>', ~~( repeats / 2 ) ) + ( repeats % 2 == 1 ? '<br>' : '' );\r
+               }\r
+\r
+                       // Replace adjacent white-spaces (EOLs too - Fx sometimes keeps them) with one space.\r
+               data = data.replace( /\s+/g, ' ' )\r
+                       // Remove spaces from between tags.\r
+                       .replace( /> +</g, '><' )\r
+                       // Normalize XHTML syntax and upper cased <br> tags.\r
+                       .replace( /<br ?\/>/gi, '<br>' );\r
+\r
+               // IE - lower cased tags.\r
+               data = data.replace( /<\/?[A-Z]+>/g, function( match ) {\r
+                       return match.toLowerCase();\r
+               } );\r
+\r
+               // Don't touch single lines (no <br|p|div>) - nothing to do here.\r
+               if ( data.match( /^[^<]$/ ) )\r
+                       return data;\r
+\r
+               // Webkit.\r
+               if ( CKEDITOR.env.webkit && data.indexOf( '<div>' ) > -1 ) {\r
+                               // One line break at the beginning - insert <br>\r
+                       data = data.replace( /^(<div>(<br>|)<\/div>)(?!$|(<div>(<br>|)<\/div>))/g, '<br>' )\r
+                               // Two or more - reduce number of new lines by one.\r
+                               .replace( /^(<div>(<br>|)<\/div>){2}(?!$)/g, '<div></div>' );\r
+\r
+                       // Two line breaks create one paragraph in Webkit.\r
+                       if ( data.match( /<div>(<br>|)<\/div>/ ) ) {\r
+                               data = '<p>' + data.replace( /(<div>(<br>|)<\/div>)+/g, function( match ) {\r
+                                       return repeatParagraphs( match.split( '</div><div>' ).length + 1 );\r
+                               } ) + '</p>';\r
+                       }\r
+\r
+                       // One line break create br.\r
+                       data = data.replace( /<\/div><div>/g, '<br>' );\r
+\r
+                       // Remove remaining divs.\r
+                       data = data.replace( /<\/?div>/g, '' );\r
+               }\r
+\r
+               // Opera and Firefox and enterMode != BR.\r
+               if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR ) {\r
+                       // Remove bogus <br> - Fx generates two <brs> for one line break.\r
+                       // For two line breaks it still produces two <brs>, but it's better to ignore this case than the first one.\r
+                       if ( CKEDITOR.env.gecko )\r
+                               data = data.replace( /^<br><br>$/, '<br>' );\r
+\r
+                       // This line satisfy edge case when for Opera we have two line breaks\r
+                       //data = data.replace( /)\r
+\r
+                       if ( data.indexOf( '<br><br>' ) > -1 ) {\r
+                               // Two line breaks create one paragraph, three - 2, four - 3, etc.\r
+                               data = '<p>' + data.replace( /(<br>){2,}/g, function( match ) {\r
+                                       return repeatParagraphs( match.length / 4 );\r
+                               } ) + '</p>';\r
+                       }\r
+               }\r
+\r
+               return switchEnterMode( config, data );\r
+       }\r
+\r
+       function filtersFactoryFactory() {\r
+               var filters = {};\r
+\r
+               function setUpTags() {\r
+                       var tags = {};\r
+\r
+                       for ( var tag in CKEDITOR.dtd ) {\r
+                               if ( tag.charAt( 0 ) != '$' && tag != 'div' && tag != 'span' ) {\r
+                                       tags[ tag ] = 1;\r
+                               }\r
+                       }\r
+\r
+                       return tags;\r
+               }\r
+\r
+               function createSemanticContentFilter() {\r
+                       var filter = new CKEDITOR.filter();\r
+\r
+                       filter.allow( {\r
+                               $1: {\r
+                                       elements: setUpTags(),\r
+                                       attributes: true,\r
+                                       styles: false,\r
+                                       classes: false\r
+                               }\r
+                       } );\r
+\r
+                       return filter;\r
+               }\r
+\r
+               return {\r
+                       get: function( type ) {\r
+                               if ( type == 'plain-text' ) {\r
+                                       // Does this look confusing to you? Did we forget about enter mode?\r
+                                       // It is a trick that let's us creating one filter for edidtor, regardless of its\r
+                                       // activeEnterMode (which as the name indicates can change during runtime).\r
+                                       //\r
+                                       // How does it work?\r
+                                       // The active enter mode is passed to the filter.applyTo method.\r
+                                       // The filter first marks all elements except <br> as disallowed and then tries to remove\r
+                                       // them. However, it cannot remove e.g. a <p> element completely, because it's a basic structural element,\r
+                                       // so it tries to replace it with an element created based on the active enter mode, eventually doing nothing.\r
+                                       //\r
+                                       // Now you can sleep well.\r
+                                       return filters.plainText || ( filters.plainText = new CKEDITOR.filter( 'br' ) );\r
+                               } else if ( type == 'semantic-content' ) {\r
+                                       return filters.semanticContent || ( filters.semanticContent = createSemanticContentFilter() );\r
+                               } else if ( type ) {\r
+                                       // Create filter based on rules (string or object).\r
+                                       return new CKEDITOR.filter( type );\r
+                               }\r
+\r
+                               return null;\r
+                       }\r
+               };\r
+       }\r
+\r
+       function filterContent( editor, data, filter ) {\r
+               var fragment = CKEDITOR.htmlParser.fragment.fromHtml( data ),\r
+                       writer = new CKEDITOR.htmlParser.basicWriter();\r
+\r
+               filter.applyTo( fragment, true, false, editor.activeEnterMode );\r
+               fragment.writeHtml( writer );\r
+\r
+               return writer.getHtml();\r
+       }\r
+\r
+       function switchEnterMode( config, data ) {\r
+               if ( config.enterMode == CKEDITOR.ENTER_BR ) {\r
+                       data = data.replace( /(<\/p><p>)+/g, function( match ) {\r
+                               return CKEDITOR.tools.repeat( '<br>', match.length / 7 * 2 );\r
+                       } ).replace( /<\/?p>/g, '' );\r
+               } else if ( config.enterMode == CKEDITOR.ENTER_DIV ) {\r
+                       data = data.replace( /<(\/)?p>/g, '<$1div>' );\r
+               }\r
+\r
+               return data;\r
+       }\r
+\r
+       function preventDefaultSetDropEffectToNone( evt ) {\r
+               evt.data.preventDefault();\r
+               evt.data.$.dataTransfer.dropEffect = 'none';\r
+       }\r
+\r
+       function initDragDrop( editor ) {\r
+               var clipboard = CKEDITOR.plugins.clipboard;\r
+\r
+               editor.on( 'contentDom', function() {\r
+                       var editable = editor.editable(),\r
+                               dropTarget = CKEDITOR.plugins.clipboard.getDropTarget( editor ),\r
+                               top = editor.ui.space( 'top' ),\r
+                               bottom = editor.ui.space( 'bottom' );\r
+\r
+                       // -------------- DRAGOVER TOP & BOTTOM --------------\r
+\r
+                       // Not allowing dragging on toolbar and bottom (#12613).\r
+                       clipboard.preventDefaultDropOnElement( top );\r
+                       clipboard.preventDefaultDropOnElement( bottom );\r
+\r
+                       // -------------- DRAGSTART --------------\r
+                       // Listed on dragstart to mark internal and cross-editor drag & drop\r
+                       // and save range and selected HTML.\r
+\r
+                       editable.attachListener( dropTarget, 'dragstart', fireDragEvent );\r
+\r
+                       // Make sure to reset data transfer (in case dragend was not called or was canceled).\r
+                       editable.attachListener( editor, 'dragstart', clipboard.resetDragDataTransfer, clipboard, null, 1 );\r
+\r
+                       // Create a dataTransfer object and save it globally.\r
+                       editable.attachListener( editor, 'dragstart', function( evt ) {\r
+                               clipboard.initDragDataTransfer( evt, editor );\r
+                       }, null, null, 2 );\r
+\r
+                       editable.attachListener( editor, 'dragstart', function() {\r
+                               // Save drag range globally for cross editor D&D.\r
+                               var dragRange = clipboard.dragRange = editor.getSelection().getRanges()[ 0 ];\r
+\r
+                               // Store number of children, so we can later tell if any text node was split on drop. (#13011, #13447)\r
+                               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {\r
+                                       clipboard.dragStartContainerChildCount = dragRange ? getContainerChildCount( dragRange.startContainer ) : null;\r
+                                       clipboard.dragEndContainerChildCount = dragRange ? getContainerChildCount( dragRange.endContainer ) : null;\r
+                               }\r
+                       }, null, null, 100 );\r
+\r
+                       // -------------- DRAGEND --------------\r
+                       // Clean up on dragend.\r
+\r
+                       editable.attachListener( dropTarget, 'dragend', fireDragEvent );\r
+\r
+                       // Init data transfer if someone wants to use it in dragend.\r
+                       editable.attachListener( editor, 'dragend', clipboard.initDragDataTransfer, clipboard, null, 1 );\r
+\r
+                       // When drag & drop is done we need to reset dataTransfer so the future\r
+                       // external drop will be not recognize as internal.\r
+                       editable.attachListener( editor, 'dragend', clipboard.resetDragDataTransfer, clipboard, null, 100 );\r
+\r
+                       // -------------- DRAGOVER --------------\r
+                       // We need to call preventDefault on dragover because otherwise if\r
+                       // we drop image it will overwrite document.\r
+\r
+                       editable.attachListener( dropTarget, 'dragover', function( evt ) {\r
+                               var target = evt.data.getTarget();\r
+\r
+                               // Prevent reloading page when dragging image on empty document (#12619).\r
+                               if ( target && target.is && target.is( 'html' ) ) {\r
+                                       evt.data.preventDefault();\r
+                                       return;\r
+                               }\r
+\r
+                               // If we do not prevent default dragover on IE the file path\r
+                               // will be loaded and we will lose content. On the other hand\r
+                               // if we prevent it the cursor will not we shown, so we prevent\r
+                               // dragover only on IE, on versions which support file API and only\r
+                               // if the event contains files.\r
+                               if ( CKEDITOR.env.ie &&\r
+                                       CKEDITOR.plugins.clipboard.isFileApiSupported &&\r
+                                       evt.data.$.dataTransfer.types.contains( 'Files' ) ) {\r
+                                       evt.data.preventDefault();\r
+                               }\r
+                       } );\r
+\r
+                       // -------------- DROP --------------\r
+\r
+                       editable.attachListener( dropTarget, 'drop', function( evt ) {\r
+                               // Do nothing if event was already prevented. (#13879)\r
+                               if ( evt.data.$.defaultPrevented ) {\r
+                                       return;\r
+                               }\r
+\r
+                               // Cancel native drop.\r
+                               evt.data.preventDefault();\r
+\r
+                               var target = evt.data.getTarget(),\r
+                                       readOnly = target.isReadOnly();\r
+\r
+                               // Do nothing if drop on non editable element (#13015).\r
+                               // The <html> tag isn't editable (body is), but we want to allow drop on it\r
+                               // (so it is possible to drop below editor contents).\r
+                               if ( readOnly && !( target.type == CKEDITOR.NODE_ELEMENT && target.is( 'html' ) ) ) {\r
+                                       return;\r
+                               }\r
+\r
+                               // Getting drop position is one of the most complex parts.\r
+                               var dropRange = clipboard.getRangeAtDropPosition( evt, editor ),\r
+                                       dragRange = clipboard.dragRange;\r
+\r
+                               // Do nothing if it was not possible to get drop range.\r
+                               if ( !dropRange ) {\r
+                                       return;\r
+                               }\r
+\r
+                               // Fire drop.\r
+                               fireDragEvent( evt, dragRange, dropRange  );\r
+                       }, null, null, 9999 );\r
+\r
+                       // Create dataTransfer or get it, if it was created before.\r
+                       editable.attachListener( editor, 'drop', clipboard.initDragDataTransfer, clipboard, null, 1 );\r
+\r
+                       // Execute drop action, fire paste.\r
+                       editable.attachListener( editor, 'drop', function( evt ) {\r
+                               var data = evt.data;\r
+\r
+                               if ( !data ) {\r
+                                       return;\r
+                               }\r
+\r
+                               // Let user modify drag and drop range.\r
+                               var dropRange = data.dropRange,\r
+                                       dragRange = data.dragRange,\r
+                                       dataTransfer = data.dataTransfer;\r
+\r
+                               if ( dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_INTERNAL ) {\r
+                                       // Execute drop with a timeout because otherwise selection, after drop,\r
+                                       // on IE is in the drag position, instead of drop position.\r
+                                       setTimeout( function() {\r
+                                               clipboard.internalDrop( dragRange, dropRange, dataTransfer, editor );\r
+                                       }, 0 );\r
+                               } else if ( dataTransfer.getTransferType( editor ) == CKEDITOR.DATA_TRANSFER_CROSS_EDITORS ) {\r
+                                       crossEditorDrop( dragRange, dropRange, dataTransfer );\r
+                               } else {\r
+                                       externalDrop( dropRange, dataTransfer );\r
+                               }\r
+                       }, null, null, 9999 );\r
+\r
+                       // Cross editor drag and drop (drag in one Editor and drop in the other).\r
+                       function crossEditorDrop( dragRange, dropRange, dataTransfer ) {\r
+                               // Paste event should be fired before delete contents because otherwise\r
+                               // Chrome have a problem with drop range (Chrome split the drop\r
+                               // range container so the offset is bigger then container length).\r
+                               dropRange.select();\r
+                               firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop' }, 1 );\r
+\r
+                               // Remove dragged content and make a snapshot.\r
+                               dataTransfer.sourceEditor.fire( 'saveSnapshot' );\r
+\r
+                               dataTransfer.sourceEditor.editable().extractHtmlFromRange( dragRange );\r
+\r
+                               // Make some selection before saving snapshot, otherwise error will be thrown, because\r
+                               // there will be no valid selection after content is removed.\r
+                               dataTransfer.sourceEditor.getSelection().selectRanges( [ dragRange ] );\r
+                               dataTransfer.sourceEditor.fire( 'saveSnapshot' );\r
+                       }\r
+\r
+                       // Drop from external source.\r
+                       function externalDrop( dropRange, dataTransfer ) {\r
+                               // Paste content into the drop position.\r
+                               dropRange.select();\r
+\r
+                               firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop' }, 1 );\r
+\r
+                               // Usually we reset DataTranfer on dragend,\r
+                               // but dragend is called on the same element as dragstart\r
+                               // so it will not be called on on external drop.\r
+                               clipboard.resetDragDataTransfer();\r
+                       }\r
+\r
+                       // Fire drag/drop events (dragstart, dragend, drop).\r
+                       function fireDragEvent( evt, dragRange, dropRange ) {\r
+                               var eventData = {\r
+                                               $: evt.data.$,\r
+                                               target: evt.data.getTarget()\r
+                                       };\r
+\r
+                               if ( dragRange ) {\r
+                                       eventData.dragRange = dragRange;\r
+                               }\r
+                               if ( dropRange ) {\r
+                                       eventData.dropRange = dropRange;\r
+                               }\r
+\r
+                               if ( editor.fire( evt.name, eventData ) === false ) {\r
+                                       evt.data.preventDefault();\r
+                               }\r
+                       }\r
+\r
+                       function getContainerChildCount( container ) {\r
+                               if ( container.type != CKEDITOR.NODE_ELEMENT ) {\r
+                                       container = container.getParent();\r
+                               }\r
+\r
+                               return container.getChildCount();\r
+                       }\r
+               } );\r
+       }\r
+\r
+       /**\r
+        * @singleton\r
+        * @class CKEDITOR.plugins.clipboard\r
+        */\r
+       CKEDITOR.plugins.clipboard = {\r
+               /**\r
+                * True if the environment allows to set data on copy or cut manually. This value is false in IE, because this browser\r
+                * shows the security dialog window when the script tries to set clipboard data and on iOS, because custom data is\r
+                * not saved to clipboard there.\r
+                *\r
+                * @since 4.5\r
+                * @readonly\r
+                * @property {Boolean}\r
+                */\r
+               isCustomCopyCutSupported: !CKEDITOR.env.ie && !CKEDITOR.env.iOS,\r
+\r
+               /**\r
+                * True if the environment supports MIME types and custom data types in dataTransfer/cliboardData getData/setData methods.\r
+                *\r
+                * @since 4.5\r
+                * @readonly\r
+                * @property {Boolean}\r
+                */\r
+               isCustomDataTypesSupported: !CKEDITOR.env.ie,\r
+\r
+               /**\r
+                * True if the environment supports File API.\r
+                *\r
+                * @since 4.5\r
+                * @readonly\r
+                * @property {Boolean}\r
+                */\r
+               isFileApiSupported: !CKEDITOR.env.ie || CKEDITOR.env.version > 9,\r
+\r
+               /**\r
+                * Main native paste event editable should listen to.\r
+                *\r
+                * **Note:** Safari does not like the {@link CKEDITOR.editor#beforePaste} event &mdash; it sometimes does not\r
+                * handle <kbd>Ctrl+C</kbd> properly. This is probably caused by some race condition between events.\r
+                * Chrome, Firefox and Edge work well with both events, so it is better to use {@link CKEDITOR.editor#paste}\r
+                * which will handle pasting from e.g. browsers' menu bars.\r
+                * IE7/8 does not like the {@link CKEDITOR.editor#paste} event for which it is throwing random errors.\r
+                *\r
+                * @since 4.5\r
+                * @readonly\r
+                * @property {String}\r
+                */\r
+               mainPasteEvent: ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) ? 'beforepaste' : 'paste',\r
+\r
+               /**\r
+                * Returns `true` if it is expected that a browser provides HTML data through the Clipboard API.\r
+                * If not, this method returns `false` and as a result CKEditor will use the paste bin. Read more in\r
+                * the [Clipboard Integration](http://docs.ckeditor.com/#!/guide/dev_clipboard-section-clipboard-api) guide.\r
+                *\r
+                * @since 4.5.2\r
+                * @returns {Boolean}\r
+                */\r
+               canClipboardApiBeTrusted: function( dataTransfer, editor ) {\r
+                       // If it's an internal or cross-editor data transfer, then it means that custom cut/copy/paste support works\r
+                       // and that the data were put manually on the data transfer so we can be sure that it's available.\r
+                       if ( dataTransfer.getTransferType( editor ) != CKEDITOR.DATA_TRANSFER_EXTERNAL ) {\r
+                               return true;\r
+                       }\r
+\r
+                       // In Chrome we can trust Clipboard API, with the exception of Chrome on Android (in both - mobile and desktop modes), where\r
+                       // clipboard API is not available so we need to check it (#13187).\r
+                       if ( CKEDITOR.env.chrome && !dataTransfer.isEmpty() ) {\r
+                               return true;\r
+                       }\r
+\r
+                       // Because of a Firefox bug HTML data are not available in some cases (e.g. paste from Word), in such cases we\r
+                       // need to use the pastebin (#13528, https://bugzilla.mozilla.org/show_bug.cgi?id=1183686).\r
+                       if ( CKEDITOR.env.gecko && ( dataTransfer.getData( 'text/html' ) || dataTransfer.getFilesCount() ) ) {\r
+                               return true;\r
+                       }\r
+\r
+                       // In Safari and IE HTML data is not available though the Clipboard API.\r
+                       // In Edge things are a bit messy at the moment -\r
+                       // https://connect.microsoft.com/IE/feedback/details/1572456/edge-clipboard-api-text-html-content-messed-up-in-event-clipboarddata\r
+                       // It is safer to use the paste bin in unknown cases.\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                * Returns the element that should be used as the target for the drop event.\r
+                *\r
+                * @since 4.5\r
+                * @param {CKEDITOR.editor} editor The editor instance.\r
+                * @returns {CKEDITOR.dom.domObject} the element that should be used as the target for the drop event.\r
+                */\r
+               getDropTarget: function( editor ) {\r
+                       var editable = editor.editable();\r
+\r
+                       // #11123 Firefox needs to listen on document, because otherwise event won't be fired.\r
+                       // #11086 IE8 cannot listen on document.\r
+                       if ( ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) || editable.isInline() ) {\r
+                               return editable;\r
+                       } else {\r
+                               return editor.document;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * IE 8 & 9 split text node on drop so the first node contains the\r
+                * text before the drop position and the second contains the rest. If you\r
+                * drag the content from the same node you will be not be able to get\r
+                * it (the range becomes invalid), so you need to join them back.\r
+                *\r
+                * Note that the first node in IE 8 & 9 is the original node object\r
+                * but with shortened content.\r
+                *\r
+                *              Before:\r
+                *                --- Text Node A ----------------------------------\r
+                *                                                           /\\r
+                *                                                      Drag position\r
+                *\r
+                *              After (IE 8 & 9):\r
+                *                --- Text Node A -----  --- Text Node B -----------\r
+                *                                     /\                    /\\r
+                *                                Drop position        Drag position\r
+                *                                                       (invalid)\r
+                *\r
+                *              After (other browsers):\r
+                *                --- Text Node A ----------------------------------\r
+                *                                     /\                    /\\r
+                *                                Drop position        Drag position\r
+                *\r
+                * **Note:** This function is in the public scope for tests usage only.\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @param {CKEDITOR.dom.range} dragRange The drag range.\r
+                * @param {CKEDITOR.dom.range} dropRange The drop range.\r
+                * @param {Number} preDragStartContainerChildCount The number of children of the drag range start container before the drop.\r
+                * @param {Number} preDragEndContainerChildCount The number of children of the drag range end container before the drop.\r
+                */\r
+               fixSplitNodesAfterDrop: function( dragRange, dropRange, preDragStartContainerChildCount, preDragEndContainerChildCount ) {\r
+                       var dropContainer = dropRange.startContainer;\r
+\r
+                       if (\r
+                               typeof preDragEndContainerChildCount != 'number' ||\r
+                               typeof preDragStartContainerChildCount != 'number'\r
+                       ) {\r
+                               return;\r
+                       }\r
+\r
+                       // We are only concerned about ranges anchored in elements.\r
+                       if ( dropContainer.type != CKEDITOR.NODE_ELEMENT ) {\r
+                               return;\r
+                       }\r
+\r
+                       if ( handleContainer( dragRange.startContainer, dropContainer, preDragStartContainerChildCount ) ) {\r
+                               return;\r
+                       }\r
+\r
+                       if ( handleContainer( dragRange.endContainer, dropContainer, preDragEndContainerChildCount ) ) {\r
+                               return;\r
+                       }\r
+\r
+                       function handleContainer( dragContainer, dropContainer, preChildCount ) {\r
+                               var dragElement = dragContainer;\r
+                               if ( dragElement.type == CKEDITOR.NODE_TEXT ) {\r
+                                       dragElement = dragContainer.getParent();\r
+                               }\r
+\r
+                               if ( dragElement.equals( dropContainer ) && preChildCount != dropContainer.getChildCount() ) {\r
+                                       applyFix( dropRange );\r
+                                       return true;\r
+                               }\r
+                       }\r
+\r
+                       function applyFix( dropRange ) {\r
+                               var nodeBefore = dropRange.startContainer.getChild( dropRange.startOffset - 1 ),\r
+                                       nodeAfter = dropRange.startContainer.getChild( dropRange.startOffset );\r
+\r
+                               if (\r
+                                       nodeBefore && nodeBefore.type == CKEDITOR.NODE_TEXT &&\r
+                                       nodeAfter && nodeAfter.type == CKEDITOR.NODE_TEXT\r
+                               ) {\r
+                                       var offset = nodeBefore.getLength();\r
+\r
+                                       nodeBefore.setText( nodeBefore.getText() + nodeAfter.getText() );\r
+                                       nodeAfter.remove();\r
+\r
+                                       dropRange.setStart( nodeBefore, offset );\r
+                                       dropRange.collapse( true );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Checks whether turning the drag range into bookmarks will invalidate the drop range.\r
+                * This usually happens when the drop range shares the container with the drag range and is\r
+                * located after the drag range, but there are countless edge cases.\r
+                *\r
+                * This function is stricly related to {@link #internalDrop} which toggles\r
+                * order in which it creates bookmarks for both ranges based on a value returned\r
+                * by this method. In some cases this method returns a value which is not necessarily\r
+                * true in terms of what it was meant to check, but it is convenient, because\r
+                * we know how it is interpreted in {@link #internalDrop}, so the correct\r
+                * behavior of the entire algorithm is assured.\r
+                *\r
+                * **Note:** This function is in the public scope for tests usage only.\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @param {CKEDITOR.dom.range} dragRange The first range to compare.\r
+                * @param {CKEDITOR.dom.range} dropRange The second range to compare.\r
+                * @returns {Boolean} `true` if the first range is before the second range.\r
+                */\r
+               isDropRangeAffectedByDragRange: function( dragRange, dropRange ) {\r
+                       var dropContainer = dropRange.startContainer,\r
+                               dropOffset = dropRange.endOffset;\r
+\r
+                       // Both containers are the same and drop offset is at the same position or later.\r
+                       // " A L] A " " M A "\r
+                       //       ^ ^\r
+                       if ( dragRange.endContainer.equals( dropContainer ) && dragRange.endOffset <= dropOffset ) {\r
+                               return true;\r
+                       }\r
+\r
+                       // Bookmark for drag start container will mess up with offsets.\r
+                       // " O [L A " " M A "\r
+                       //           ^       ^\r
+                       if (\r
+                               dragRange.startContainer.getParent().equals( dropContainer ) &&\r
+                               dragRange.startContainer.getIndex() < dropOffset\r
+                       ) {\r
+                               return true;\r
+                       }\r
+\r
+                       // Bookmark for drag end container will mess up with offsets.\r
+                       // " O] L A " " M A "\r
+                       //           ^       ^\r
+                       if (\r
+                               dragRange.endContainer.getParent().equals( dropContainer ) &&\r
+                               dragRange.endContainer.getIndex() < dropOffset\r
+                       ) {\r
+                               return true;\r
+                       }\r
+\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                * Internal drag and drop (drag and drop in the same editor instance).\r
+                *\r
+                * **Note:** This function is in the public scope for tests usage only.\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @param {CKEDITOR.dom.range} dragRange The first range to compare.\r
+                * @param {CKEDITOR.dom.range} dropRange The second range to compare.\r
+                * @param {CKEDITOR.plugins.clipboard.dataTransfer} dataTransfer\r
+                * @param {CKEDITOR.editor} editor\r
+                */\r
+               internalDrop: function( dragRange, dropRange, dataTransfer, editor ) {\r
+                       var clipboard = CKEDITOR.plugins.clipboard,\r
+                               editable = editor.editable(),\r
+                               dragBookmark, dropBookmark, isDropRangeAffected;\r
+\r
+                       // Save and lock snapshot so there will be only\r
+                       // one snapshot for both remove and insert content.\r
+                       editor.fire( 'saveSnapshot' );\r
+                       editor.fire( 'lockSnapshot', { dontUpdate: 1 } );\r
+\r
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {\r
+                               this.fixSplitNodesAfterDrop(\r
+                                       dragRange,\r
+                                       dropRange,\r
+                                       clipboard.dragStartContainerChildCount,\r
+                                       clipboard.dragEndContainerChildCount\r
+                               );\r
+                       }\r
+\r
+                       // Because we manipulate multiple ranges we need to do it carefully,\r
+                       // changing one range (event creating a bookmark) may make other invalid.\r
+                       // We need to change ranges into bookmarks so we can manipulate them easily in the future.\r
+                       // We can change the range which is later in the text before we change the preceding range.\r
+                       // We call isDropRangeAffectedByDragRange to test the order of ranges.\r
+                       isDropRangeAffected = this.isDropRangeAffectedByDragRange( dragRange, dropRange );\r
+                       if ( !isDropRangeAffected ) {\r
+                               dragBookmark = dragRange.createBookmark( false );\r
+                       }\r
+                       dropBookmark = dropRange.clone().createBookmark( false );\r
+                       if ( isDropRangeAffected ) {\r
+                               dragBookmark = dragRange.createBookmark( false );\r
+                       }\r
+\r
+                       // Check if drop range is inside range.\r
+                       // This is an edge case when we drop something on editable's margin/padding.\r
+                       // That space is not treated as a part of the range we drag, so it is possible to drop there.\r
+                       // When we drop, browser tries to find closest drop position and it finds it inside drag range. (#13453)\r
+                       var startNode = dragBookmark.startNode,\r
+                               endNode = dragBookmark.endNode,\r
+                               dropNode = dropBookmark.startNode,\r
+                               dropInsideDragRange =\r
+                                       // Must check endNode because dragRange could be collapsed in some edge cases (simulated DnD).\r
+                                       endNode &&\r
+                                       ( startNode.getPosition( dropNode ) & CKEDITOR.POSITION_PRECEDING ) &&\r
+                                       ( endNode.getPosition( dropNode ) & CKEDITOR.POSITION_FOLLOWING );\r
+\r
+                       // If the drop range happens to be inside drag range change it's position to the beginning of the drag range.\r
+                       if ( dropInsideDragRange ) {\r
+                               // We only change position of bookmark span that is connected with dropBookmark.\r
+                               // dropRange will be overwritten and set to the dropBookmark later.\r
+                               dropNode.insertBefore( startNode );\r
+                       }\r
+\r
+                       // No we can safely delete content for the drag range...\r
+                       dragRange = editor.createRange();\r
+                       dragRange.moveToBookmark( dragBookmark );\r
+                       editable.extractHtmlFromRange( dragRange, 1 );\r
+\r
+                       // ...and paste content into the drop position.\r
+                       dropRange = editor.createRange();\r
+                       dropRange.moveToBookmark( dropBookmark );\r
+\r
+                       // We do not select drop range, because of may be in the place we can not set the selection\r
+                       // (e.g. between blocks, in case of block widget D&D). We put range to the paste event instead.\r
+                       firePasteEvents( editor, { dataTransfer: dataTransfer, method: 'drop', range: dropRange }, 1 );\r
+\r
+                       editor.fire( 'unlockSnapshot' );\r
+               },\r
+\r
+               /**\r
+                * Gets the range from the `drop` event.\r
+                *\r
+                * @since 4.5\r
+                * @param {Object} domEvent A native DOM drop event object.\r
+                * @param {CKEDITOR.editor} editor The source editor instance.\r
+                * @returns {CKEDITOR.dom.range} range at drop position.\r
+                */\r
+               getRangeAtDropPosition: function( dropEvt, editor ) {\r
+                       var $evt = dropEvt.data.$,\r
+                               x = $evt.clientX,\r
+                               y = $evt.clientY,\r
+                               $range,\r
+                               defaultRange = editor.getSelection( true ).getRanges()[ 0 ],\r
+                               range = editor.createRange();\r
+\r
+                       // Make testing possible.\r
+                       if ( dropEvt.data.testRange )\r
+                               return dropEvt.data.testRange;\r
+\r
+                       // Webkits.\r
+                       if ( document.caretRangeFromPoint ) {\r
+                               $range = editor.document.$.caretRangeFromPoint( x, y );\r
+                               range.setStart( CKEDITOR.dom.node( $range.startContainer ), $range.startOffset );\r
+                               range.collapse( true );\r
+                       }\r
+                       // FF.\r
+                       else if ( $evt.rangeParent ) {\r
+                               range.setStart( CKEDITOR.dom.node( $evt.rangeParent ), $evt.rangeOffset );\r
+                               range.collapse( true );\r
+                       }\r
+                       // IEs 9+.\r
+                       // We check if editable is focused to make sure that it's an internal DnD. External DnD must use the second\r
+                       // mechanism because of http://dev.ckeditor.com/ticket/13472#comment:6.\r
+                       else if ( CKEDITOR.env.ie && CKEDITOR.env.version > 8 && defaultRange && editor.editable().hasFocus ) {\r
+                               // On IE 9+ range by default is where we expected it.\r
+                               // defaultRange may be undefined if dragover was canceled (file drop).\r
+                               return defaultRange;\r
+                       }\r
+                       // IE 8 and all IEs if !defaultRange or external DnD.\r
+                       else if ( document.body.createTextRange ) {\r
+                               // To use this method we need a focus (which may be somewhere else in case of external drop).\r
+                               editor.focus();\r
+\r
+                               $range = editor.document.getBody().$.createTextRange();\r
+                               try {\r
+                                       var sucess = false;\r
+\r
+                                       // If user drop between text line IEs moveToPoint throws exception:\r
+                                       //\r
+                                       //              Lorem ipsum pulvinar purus et euismod\r
+                                       //\r
+                                       //              dolor sit amet,| consectetur adipiscing\r
+                                       //                             *\r
+                                       //              vestibulum tincidunt augue eget tempus.\r
+                                       //\r
+                                       // * - drop position\r
+                                       // | - expected cursor position\r
+                                       //\r
+                                       // So we try to call moveToPoint with +-1px up to +-20px above or\r
+                                       // below original drop position to find nearest good drop position.\r
+                                       for ( var i = 0; i < 20 && !sucess; i++ ) {\r
+                                               if ( !sucess ) {\r
+                                                       try {\r
+                                                               $range.moveToPoint( x, y - i );\r
+                                                               sucess = true;\r
+                                                       } catch ( err ) {\r
+                                                       }\r
+                                               }\r
+                                               if ( !sucess ) {\r
+                                                       try {\r
+                                                               $range.moveToPoint( x, y + i );\r
+                                                               sucess = true;\r
+                                                       } catch ( err ) {\r
+                                                       }\r
+                                               }\r
+                                       }\r
+\r
+                                       if ( sucess ) {\r
+                                               var id = 'cke-temp-' + ( new Date() ).getTime();\r
+                                               $range.pasteHTML( '<span id="' + id + '">\u200b</span>' );\r
+\r
+                                               var span = editor.document.getById( id );\r
+                                               range.moveToPosition( span, CKEDITOR.POSITION_BEFORE_START );\r
+                                               span.remove();\r
+                                       } else {\r
+                                               // If the fist method does not succeed we might be next to\r
+                                               // the short element (like header):\r
+                                               //\r
+                                               //              Lorem ipsum pulvinar purus et euismod.\r
+                                               //\r
+                                               //\r
+                                               //              SOME HEADER|        *\r
+                                               //\r
+                                               //\r
+                                               //              vestibulum tincidunt augue eget tempus.\r
+                                               //\r
+                                               // * - drop position\r
+                                               // | - expected cursor position\r
+                                               //\r
+                                               // In such situation elementFromPoint returns proper element. Using getClientRect\r
+                                               // it is possible to check if the cursor should be at the beginning or at the end\r
+                                               // of paragraph.\r
+                                               var $element = editor.document.$.elementFromPoint( x, y ),\r
+                                                       element = new CKEDITOR.dom.element( $element ),\r
+                                                       rect;\r
+\r
+                                               if ( !element.equals( editor.editable() ) && element.getName() != 'html' ) {\r
+                                                       rect = element.getClientRect();\r
+\r
+                                                       if ( x < rect.left ) {\r
+                                                               range.setStartAt( element, CKEDITOR.POSITION_AFTER_START );\r
+                                                               range.collapse( true );\r
+                                                       } else {\r
+                                                               range.setStartAt( element, CKEDITOR.POSITION_BEFORE_END );\r
+                                                               range.collapse( true );\r
+                                                       }\r
+                                               }\r
+                                               // If drop happens on no element elementFromPoint returns html or body.\r
+                                               //\r
+                                               //              *      |Lorem ipsum pulvinar purus et euismod.\r
+                                               //\r
+                                               //                     vestibulum tincidunt augue eget tempus.\r
+                                               //\r
+                                               // * - drop position\r
+                                               // | - expected cursor position\r
+                                               //\r
+                                               // In such case we can try to use default selection. If startContainer is not\r
+                                               // 'editable' element it is probably proper selection.\r
+                                               else if ( defaultRange && defaultRange.startContainer &&\r
+                                                       !defaultRange.startContainer.equals( editor.editable() ) ) {\r
+                                                       return defaultRange;\r
+\r
+                                               // Otherwise we can not find any drop position and we have to return null\r
+                                               // and cancel drop event.\r
+                                               } else {\r
+                                                       return null;\r
+                                               }\r
+\r
+                                       }\r
+                               } catch ( err ) {\r
+                                       return null;\r
+                               }\r
+                       } else {\r
+                               return null;\r
+                       }\r
+\r
+                       return range;\r
+               },\r
+\r
+               /**\r
+                * This function tries to link the `evt.data.dataTransfer` property of the {@link CKEDITOR.editor#dragstart},\r
+                * {@link CKEDITOR.editor#dragend} and {@link CKEDITOR.editor#drop} events to a single\r
+                * {@link CKEDITOR.plugins.clipboard.dataTransfer} object.\r
+                *\r
+                * This method is automatically used by the core of the drag and drop functionality and\r
+                * usually does not have to be called manually when using the drag and drop events.\r
+                *\r
+                * This method behaves differently depending on whether the drag and drop events were fired\r
+                * artificially (to represent a non-native drag and drop) or whether they were caused by the native drag and drop.\r
+                *\r
+                * If the native event is not available, then it will create a new {@link CKEDITOR.plugins.clipboard.dataTransfer}\r
+                * instance (if it does not exist already) and will link it to this and all following event objects until\r
+                * the {@link #resetDragDataTransfer} method is called. It means that all three drag and drop events must be fired\r
+                * in order to ensure that the data transfer is bound correctly.\r
+                *\r
+                * If the native event is available, then the {@link CKEDITOR.plugins.clipboard.dataTransfer} is identified\r
+                * by its ID and a new instance is assigned to the `evt.data.dataTransfer` only if the ID changed or\r
+                * the {@link #resetDragDataTransfer} method was called.\r
+                *\r
+                * @since 4.5\r
+                * @param {CKEDITOR.dom.event} [evt] A drop event object.\r
+                * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.\r
+                */\r
+               initDragDataTransfer: function( evt, sourceEditor ) {\r
+                       // Create a new dataTransfer object based on the drop event.\r
+                       // If this event was used on dragstart to create dataTransfer\r
+                       // both dataTransfer objects will have the same id.\r
+                       var nativeDataTransfer = evt.data.$ ? evt.data.$.dataTransfer : null,\r
+                               dataTransfer = new this.dataTransfer( nativeDataTransfer, sourceEditor );\r
+\r
+                       if ( !nativeDataTransfer ) {\r
+                               // No native event.\r
+                               if ( this.dragData ) {\r
+                                       dataTransfer = this.dragData;\r
+                               } else {\r
+                                       this.dragData = dataTransfer;\r
+                               }\r
+                       } else {\r
+                               // Native event. If there is the same id we will replace dataTransfer with the one\r
+                               // created on drag, because it contains drag editor, drag content and so on.\r
+                               // Otherwise (in case of drag from external source) we save new object to\r
+                               // the global clipboard.dragData.\r
+                               if ( this.dragData && dataTransfer.id == this.dragData.id ) {\r
+                                       dataTransfer = this.dragData;\r
+                               } else {\r
+                                       this.dragData = dataTransfer;\r
+                               }\r
+                       }\r
+\r
+                       evt.data.dataTransfer = dataTransfer;\r
+               },\r
+\r
+               /**\r
+                * Removes the global {@link #dragData} so the next call to {@link #initDragDataTransfer}\r
+                * always creates a new instance of {@link CKEDITOR.plugins.clipboard.dataTransfer}.\r
+                *\r
+                * @since 4.5\r
+                */\r
+               resetDragDataTransfer: function() {\r
+                       this.dragData = null;\r
+               },\r
+\r
+               /**\r
+                * Global object storing the data transfer of the current drag and drop operation.\r
+                * Do not use it directly, use {@link #initDragDataTransfer} and {@link #resetDragDataTransfer}.\r
+                *\r
+                * Note: This object is global (meaning that it is not related to a single editor instance)\r
+                * in order to handle drag and drop from one editor into another.\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @property {CKEDITOR.plugins.clipboard.dataTransfer} dragData\r
+                */\r
+\r
+               /**\r
+                * Range object to save the drag range and remove its content after the drop.\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @property {CKEDITOR.dom.range} dragRange\r
+                */\r
+\r
+               /**\r
+                * Initializes and links data transfer objects based on the paste event. If the data\r
+                * transfer object was already initialized on this event, the function will\r
+                * return that object. In IE it is not possible to link copy/cut and paste events\r
+                * so the method always returns a new object. The same happens if there is no paste event\r
+                * passed to the method.\r
+                *\r
+                * @since 4.5\r
+                * @param {CKEDITOR.dom.event} [evt] A paste event object.\r
+                * @param {CKEDITOR.editor} [sourceEditor] The source editor instance.\r
+                * @returns {CKEDITOR.plugins.clipboard.dataTransfer} The data transfer object.\r
+                */\r
+               initPasteDataTransfer: function( evt, sourceEditor ) {\r
+                       if ( !this.isCustomCopyCutSupported ) {\r
+                               // Edge does not support custom copy/cut, but it have some useful data in the clipboardData (#13755).\r
+                               return new this.dataTransfer( ( CKEDITOR.env.edge && evt && evt.data.$ && evt.data.$.clipboardData ) || null, sourceEditor );\r
+                       } else if ( evt && evt.data && evt.data.$ ) {\r
+                               var dataTransfer = new this.dataTransfer( evt.data.$.clipboardData, sourceEditor );\r
+\r
+                               if ( this.copyCutData && dataTransfer.id == this.copyCutData.id ) {\r
+                                       dataTransfer = this.copyCutData;\r
+                                       dataTransfer.$ = evt.data.$.clipboardData;\r
+                               } else {\r
+                                       this.copyCutData = dataTransfer;\r
+                               }\r
+\r
+                               return dataTransfer;\r
+                       } else {\r
+                               return new this.dataTransfer( null, sourceEditor );\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Prevents dropping on the specified element.\r
+                *\r
+                * @since 4.5\r
+                * @param {CKEDITOR.dom.element} element The element on which dropping should be disabled.\r
+                */\r
+               preventDefaultDropOnElement: function( element ) {\r
+                       element && element.on( 'dragover', preventDefaultSetDropEffectToNone );\r
+               }\r
+       };\r
+\r
+       // Data type used to link drag and drop events.\r
+       //\r
+       // In IE URL data type is buggie and there is no way to mark drag & drop  without\r
+       // modifying text data (which would be displayed if user drop content to the textarea)\r
+       // so we just read dragged text.\r
+       //\r
+       // In Chrome and Firefox we can use custom data types.\r
+       var clipboardIdDataType = CKEDITOR.plugins.clipboard.isCustomDataTypesSupported ? 'cke/id' : 'Text';\r
+       /**\r
+        * Facade for the native `dataTransfer`/`clipboadData` object to hide all differences\r
+        * between browsers.\r
+        *\r
+        * @since 4.5\r
+        * @class CKEDITOR.plugins.clipboard.dataTransfer\r
+        * @constructor Creates a class instance.\r
+        * @param {Object} [nativeDataTransfer] A native data transfer object.\r
+        * @param {CKEDITOR.editor} [editor] The source editor instance. If the editor is defined, dataValue will\r
+        * be created based on the editor content and the type will be 'html'.\r
+        */\r
+       CKEDITOR.plugins.clipboard.dataTransfer = function( nativeDataTransfer, editor ) {\r
+               if ( nativeDataTransfer ) {\r
+                       this.$ = nativeDataTransfer;\r
+               }\r
+\r
+               this._ = {\r
+                       metaRegExp: /^<meta.*?>/i,\r
+                       bodyRegExp: /<body(?:[\s\S]*?)>([\s\S]*)<\/body>/i,\r
+                       fragmentRegExp: /<!--(?:Start|End)Fragment-->/g,\r
+\r
+                       data: {},\r
+                       files: [],\r
+\r
+                       normalizeType: function( type ) {\r
+                               type = type.toLowerCase();\r
+\r
+                               if ( type == 'text' || type == 'text/plain' ) {\r
+                                       return 'Text'; // IE support only Text and URL;\r
+                               } else if ( type == 'url' ) {\r
+                                       return 'URL'; // IE support only Text and URL;\r
+                               } else {\r
+                                       return type;\r
+                               }\r
+                       }\r
+               };\r
+\r
+               // Check if ID is already created.\r
+               this.id = this.getData( clipboardIdDataType );\r
+\r
+               // If there is no ID we need to create it. Different browsers needs different ID.\r
+               if ( !this.id ) {\r
+                       if ( clipboardIdDataType == 'Text' ) {\r
+                               // For IE10+ only Text data type is supported and we have to compare dragged\r
+                               // and dropped text. If the ID is not set it means that empty string was dragged\r
+                               // (ex. image with no alt). We change null to empty string.\r
+                               this.id = '';\r
+                       } else {\r
+                               // String for custom data type.\r
+                               this.id = 'cke-' + CKEDITOR.tools.getUniqueId();\r
+                       }\r
+               }\r
+\r
+               // In IE10+ we can not use any data type besides text, so we do not call setData.\r
+               if ( clipboardIdDataType != 'Text' ) {\r
+                       // Try to set ID so it will be passed from the drag to the drop event.\r
+                       // On some browsers with some event it is not possible to setData so we\r
+                       // need to catch exceptions.\r
+                       try {\r
+                               this.$.setData( clipboardIdDataType, this.id );\r
+                       } catch ( err ) {}\r
+               }\r
+\r
+               if ( editor ) {\r
+                       this.sourceEditor = editor;\r
+\r
+                       this.setData( 'text/html', editor.getSelectedHtml( 1 ) );\r
+\r
+                       // Without setData( 'text', ... ) on dragstart there is no drop event in Safari.\r
+                       // Also 'text' data is empty as drop to the textarea does not work if we do not put there text.\r
+                       if ( clipboardIdDataType != 'Text' && !this.getData( 'text/plain' ) ) {\r
+                               this.setData( 'text/plain', editor.getSelection().getSelectedText() );\r
+                       }\r
+               }\r
+\r
+               /**\r
+                * Data transfer ID used to bind all dataTransfer\r
+                * objects based on the same event (e.g. in drag and drop events).\r
+                *\r
+                * @readonly\r
+                * @property {String} id\r
+                */\r
+\r
+               /**\r
+                * A native DOM event object.\r
+                *\r
+                * @readonly\r
+                * @property {Object} $\r
+                */\r
+\r
+               /**\r
+                * Source editor &mdash; the editor where the drag starts.\r
+                * Might be undefined if the drag starts outside the editor (e.g. when dropping files to the editor).\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.editor} sourceEditor\r
+                */\r
+\r
+               /**\r
+                * Private properties and methods.\r
+                *\r
+                * @private\r
+                * @property {Object} _\r
+                */\r
+       };\r
+\r
+       /**\r
+        * Data transfer operation (drag and drop or copy and paste) started and ended in the same\r
+        * editor instance.\r
+        *\r
+        * @since 4.5\r
+        * @readonly\r
+        * @property {Number} [=1]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.DATA_TRANSFER_INTERNAL = 1;\r
+\r
+       /**\r
+        * Data transfer operation (drag and drop or copy and paste) started in one editor\r
+        * instance and ended in another.\r
+        *\r
+        * @since 4.5\r
+        * @readonly\r
+        * @property {Number} [=2]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.DATA_TRANSFER_CROSS_EDITORS = 2;\r
+\r
+       /**\r
+        * Data transfer operation (drag and drop or copy and paste) started outside of the editor.\r
+        * The source of the data may be a textarea, HTML, another application, etc.\r
+        *\r
+        * @since 4.5\r
+        * @readonly\r
+        * @property {Number} [=3]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.DATA_TRANSFER_EXTERNAL = 3;\r
+\r
+       CKEDITOR.plugins.clipboard.dataTransfer.prototype = {\r
+               /**\r
+                * Facade for the native `getData` method.\r
+                *\r
+                * @param {String} type The type of data to retrieve.\r
+                * @returns {String} type Stored data for the given type or an empty string if the data for that type does not exist.\r
+                */\r
+               getData: function( type ) {\r
+                       function isEmpty( data ) {\r
+                               return data === undefined || data === null || data === '';\r
+                       }\r
+\r
+                       type = this._.normalizeType( type );\r
+\r
+                       var data = this._.data[ type ],\r
+                               result;\r
+\r
+                       if ( isEmpty( data ) ) {\r
+                               try {\r
+                                       data = this.$.getData( type );\r
+                               } catch ( e ) {}\r
+                       }\r
+\r
+                       if ( isEmpty( data ) ) {\r
+                               data = '';\r
+                       }\r
+\r
+                       // Some browsers add <meta http-equiv="content-type" content="text/html; charset=utf-8"> at the begging of the HTML data\r
+                       // or surround it with <html><head>...</head><body>(some content)<!--StartFragment--> and <!--EndFragment-->(some content)</body></html>\r
+                       // This code removes meta tags and returns only the contents of the <body> element if found. Note that\r
+                       // some significant content may be placed outside Start/EndFragment comments so it's kept.\r
+                       //\r
+                       // See #13583 for more details.\r
+                       if ( type == 'text/html' ) {\r
+                               data = data.replace( this._.metaRegExp, '' );\r
+\r
+                               // Keep only contents of the <body> element\r
+                               result = this._.bodyRegExp.exec( data );\r
+                               if ( result && result.length ) {\r
+                                       data = result[ 1 ];\r
+\r
+                                       // Remove also comments.\r
+                                       data = data.replace( this._.fragmentRegExp, '' );\r
+                               }\r
+                       }\r
+                       // Firefox on Linux put files paths as a text/plain data if there are files\r
+                       // in the dataTransfer object. We need to hide it, because files should be\r
+                       // handled on paste only if dataValue is empty.\r
+                       else if ( type == 'Text' && CKEDITOR.env.gecko && this.getFilesCount() &&\r
+                               data.substring( 0, 7 ) == 'file://' ) {\r
+                               data = '';\r
+                       }\r
+\r
+                       return data;\r
+               },\r
+\r
+               /**\r
+                * Facade for the native `setData` method.\r
+                *\r
+                * @param {String} type The type of data to retrieve.\r
+                * @param {String} value The data to add.\r
+                */\r
+               setData: function( type, value ) {\r
+                       type = this._.normalizeType( type );\r
+\r
+                       this._.data[ type ] = value;\r
+\r
+                       // There is "Unexpected call to method or property access." error if you try\r
+                       // to set data of unsupported type on IE.\r
+                       if ( !CKEDITOR.plugins.clipboard.isCustomDataTypesSupported && type != 'URL' && type != 'Text' ) {\r
+                               return;\r
+                       }\r
+\r
+                       // If we use the text type to bind the ID, then if someone tries to set the text, we must also\r
+                       // update ID accordingly. #13468.\r
+                       if ( clipboardIdDataType == 'Text' && type == 'Text' ) {\r
+                               this.id = value;\r
+                       }\r
+\r
+                       try {\r
+                               this.$.setData( type, value );\r
+                       } catch ( e ) {}\r
+               },\r
+\r
+               /**\r
+                * Gets the data transfer type.\r
+                *\r
+                * @param {CKEDITOR.editor} targetEditor The drop/paste target editor instance.\r
+                * @returns {Number} Possible values: {@link CKEDITOR#DATA_TRANSFER_INTERNAL},\r
+                * {@link CKEDITOR#DATA_TRANSFER_CROSS_EDITORS}, {@link CKEDITOR#DATA_TRANSFER_EXTERNAL}.\r
+                */\r
+               getTransferType: function( targetEditor ) {\r
+                       if ( !this.sourceEditor ) {\r
+                               return CKEDITOR.DATA_TRANSFER_EXTERNAL;\r
+                       } else if ( this.sourceEditor == targetEditor ) {\r
+                               return CKEDITOR.DATA_TRANSFER_INTERNAL;\r
+                       } else {\r
+                               return CKEDITOR.DATA_TRANSFER_CROSS_EDITORS;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Copies the data from the native data transfer to a private cache.\r
+                * This function is needed because the data from the native data transfer\r
+                * is available only synchronously to the event listener. It is not possible\r
+                * to get the data asynchronously, after a timeout, and the {@link CKEDITOR.editor#paste}\r
+                * event is fired asynchronously &mdash; hence the need for caching the data.\r
+                */\r
+               cacheData: function() {\r
+                       if ( !this.$ ) {\r
+                               return;\r
+                       }\r
+\r
+                       var that = this,\r
+                               i, file;\r
+\r
+                       function getAndSetData( type ) {\r
+                               type = that._.normalizeType( type );\r
+\r
+                               var data = that.getData( type );\r
+                               if ( data ) {\r
+                                       that._.data[ type ] = data;\r
+                               }\r
+                       }\r
+\r
+                       // Copy data.\r
+                       if ( CKEDITOR.plugins.clipboard.isCustomDataTypesSupported ) {\r
+                               if ( this.$.types ) {\r
+                                       for ( i = 0; i < this.$.types.length; i++ ) {\r
+                                               getAndSetData( this.$.types[ i ] );\r
+                                       }\r
+                               }\r
+                       } else {\r
+                               getAndSetData( 'Text' );\r
+                               getAndSetData( 'URL' );\r
+                       }\r
+\r
+                       // Copy files references.\r
+                       file = this._getImageFromClipboard();\r
+                       if ( ( this.$ && this.$.files ) || file ) {\r
+                               this._.files = [];\r
+\r
+                               // Edge have empty files property with no length (#13755).\r
+                               if ( this.$.files && this.$.files.length ) {\r
+                                       for ( i = 0; i < this.$.files.length; i++ ) {\r
+                                               this._.files.push( this.$.files[ i ] );\r
+                                       }\r
+                               }\r
+\r
+                               // Don't include $.items if both $.files and $.items contains files, because,\r
+                               // according to spec and browsers behavior, they contain the same files.\r
+                               if ( this._.files.length === 0 && file ) {\r
+                                       this._.files.push( file );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Gets the number of files in the dataTransfer object.\r
+                *\r
+                * @returns {Number} The number of files.\r
+                */\r
+               getFilesCount: function() {\r
+                       if ( this._.files.length ) {\r
+                               return this._.files.length;\r
+                       }\r
+\r
+                       if ( this.$ && this.$.files && this.$.files.length ) {\r
+                               return this.$.files.length;\r
+                       }\r
+\r
+                       return this._getImageFromClipboard() ? 1 : 0;\r
+               },\r
+\r
+               /**\r
+                * Gets the file at the index given.\r
+                *\r
+                * @param {Number} i Index.\r
+                * @returns {File} File instance.\r
+                */\r
+               getFile: function( i ) {\r
+                       if ( this._.files.length ) {\r
+                               return this._.files[ i ];\r
+                       }\r
+\r
+                       if ( this.$ && this.$.files && this.$.files.length ) {\r
+                               return this.$.files[ i ];\r
+                       }\r
+\r
+                       // File or null if the file was not found.\r
+                       return i === 0 ? this._getImageFromClipboard() : undefined;\r
+               },\r
+\r
+               /**\r
+                * Checks if the data transfer contains any data.\r
+                *\r
+                * @returns {Boolean} `true` if the object contains no data.\r
+                */\r
+               isEmpty: function() {\r
+                       var typesToCheck = {},\r
+                               type;\r
+\r
+                       // If dataTransfer contains files it is not empty.\r
+                       if ( this.getFilesCount() ) {\r
+                               return false;\r
+                       }\r
+\r
+                       // Add custom types.\r
+                       for ( type in this._.data ) {\r
+                               typesToCheck[ type ] = 1;\r
+                       }\r
+\r
+                       // Add native types.\r
+                       if ( this.$ ) {\r
+                               if ( CKEDITOR.plugins.clipboard.isCustomDataTypesSupported ) {\r
+                                       if ( this.$.types ) {\r
+                                               for ( var i = 0; i < this.$.types.length; i++ ) {\r
+                                                       typesToCheck[ this.$.types[ i ] ] = 1;\r
+                                               }\r
+                                       }\r
+                               } else {\r
+                                       typesToCheck.Text = 1;\r
+                                       typesToCheck.URL = 1;\r
+                               }\r
+                       }\r
+\r
+                       // Remove ID.\r
+                       if ( clipboardIdDataType != 'Text' ) {\r
+                               typesToCheck[ clipboardIdDataType ] = 0;\r
+                       }\r
+\r
+                       for ( type in typesToCheck ) {\r
+                               if ( typesToCheck[ type ] && this.getData( type ) !== '' ) {\r
+                                       return false;\r
+                               }\r
+                       }\r
+\r
+                       return true;\r
+               },\r
+\r
+               /**\r
+                * When the content of the clipboard is pasted in Chrome, the clipboard data object has an empty `files` property,\r
+                * but it is possible to get the file as `items[0].getAsFile();` (#12961).\r
+                *\r
+                * @private\r
+                * @returns {File} File instance or `null` if not found.\r
+                */\r
+               _getImageFromClipboard: function() {\r
+                       var file;\r
+\r
+                       if ( this.$ && this.$.items && this.$.items[ 0 ] ) {\r
+                               try {\r
+                                       file = this.$.items[ 0 ].getAsFile();\r
+                                       // Duck typing\r
+                                       if ( file && file.type ) {\r
+                                               return file;\r
+                                       }\r
+                               } catch ( err ) {\r
+                                       // noop\r
+                               }\r
+                       }\r
+\r
+                       return undefined;\r
+               }\r
+       };\r
+} )();\r
+\r
+/**\r
+ * The default content type that is used when pasted data cannot be clearly recognized as HTML or text.\r
+ *\r
+ * For example: `'foo'` may come from a plain text editor or a website. It is not possible to recognize the content\r
+ * type in this case, so the default type will be used. At the same time it is clear that `'<b>example</b> text'` is\r
+ * HTML and its origin is a web page, email or another rich text editor.\r
+ *\r
+ * **Note:** If content type is text, then styles of the paste context are preserved.\r
+ *\r
+ *             CKEDITOR.config.clipboard_defaultContentType = 'text';\r
+ *\r
+ * See also the {@link CKEDITOR.editor#paste} event and read more about the integration with clipboard\r
+ * in the [Clipboard Deep Dive guide](#!/guide/dev_clipboard).\r
+ *\r
+ * @since 4.0\r
+ * @cfg {'html'/'text'} [clipboard_defaultContentType='html']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Fired after the user initiated a paste action, but before the data is inserted into the editor.\r
+ * The listeners to this event are able to process the content before its insertion into the document.\r
+ *\r
+ * Read more about the integration with clipboard in the [Clipboard Deep Dive guide](#!/guide/dev_clipboard).\r
+ *\r
+ * See also:\r
+ *\r
+ * * the {@link CKEDITOR.config#pasteFilter} option,\r
+ * * the {@link CKEDITOR.editor#drop} event,\r
+ * * the {@link CKEDITOR.plugins.clipboard.dataTransfer} class.\r
+ *\r
+ * @since 3.1\r
+ * @event paste\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {String} data.type The type of data in `data.dataValue`. Usually `'html'` or `'text'`, but for listeners\r
+ * with a priority smaller than `6` it may also be `'auto'` which means that the content type has not been recognised yet\r
+ * (this will be done by the content type sniffer that listens with priority `6`).\r
+ * @param {String} data.dataValue HTML to be pasted.\r
+ * @param {String} data.method Indicates the data transfer method. It could be drag and drop or copy and paste.\r
+ * Possible values: `'drop'`, `'paste'`. Introduced in CKEditor 4.5.\r
+ * @param {CKEDITOR.plugins.clipboard.dataTransfer} data.dataTransfer Facade for the native dataTransfer object\r
+ * which provides access to various data types and files, and passes some data between linked events\r
+ * (like drag and drop). Introduced in CKEditor 4.5.\r
+ * @param {Boolean} [data.dontFilter=false] Whether the {@link CKEDITOR.editor#pasteFilter paste filter} should not\r
+ * be applied to data. This option has no effect when `data.type` equals `'text'` which means that for instance\r
+ * {@link CKEDITOR.config#forcePasteAsPlainText} has a higher priority. Introduced in CKEditor 4.5.\r
+ */\r
+\r
+/**\r
+ * Fired before the {@link #paste} event. Allows to preset data type.\r
+ *\r
+ * **Note:** This event is deprecated. Add a `0` priority listener for the\r
+ * {@link #paste} event instead.\r
+ *\r
+ * @deprecated\r
+ * @event beforePaste\r
+ * @member CKEDITOR.editor\r
+ */\r
+\r
+ /**\r
+ * Fired after the {@link #paste} event if content was modified. Note that if the paste\r
+ * event does not insert any data, the `afterPaste` event will not be fired.\r
+ *\r
+ * @event afterPaste\r
+ * @member CKEDITOR.editor\r
+ */\r
+\r
+/**\r
+ * Internal event to open the Paste dialog window.\r
+ *\r
+ * @private\r
+ * @event pasteDialog\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {Function} [data] Callback that will be passed to {@link CKEDITOR.editor#openDialog}.\r
+ */\r
+\r
+/**\r
+ * Facade for the native `drop` event. Fired when the native `drop` event occurs.\r
+ *\r
+ * **Note:** To manipulate dropped data, use the {@link CKEDITOR.editor#paste} event.\r
+ * Use the `drop` event only to control drag and drop operations (e.g. to prevent the ability to drop some content).\r
+ *\r
+ * Read more about integration with drag and drop in the [Clipboard Deep Dive guide](#!/guide/dev_clipboard).\r
+ *\r
+ * See also:\r
+ *\r
+ * * The {@link CKEDITOR.editor#paste} event,\r
+ * * The {@link CKEDITOR.editor#dragstart} and {@link CKEDITOR.editor#dragend} events,\r
+ * * The {@link CKEDITOR.plugins.clipboard.dataTransfer} class.\r
+ *\r
+ * @since 4.5\r
+ * @event drop\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {Object} data.$ Native drop event.\r
+ * @param {CKEDITOR.dom.node} data.target Drop target.\r
+ * @param {CKEDITOR.plugins.clipboard.dataTransfer} data.dataTransfer DataTransfer facade.\r
+ * @param {CKEDITOR.dom.range} data.dragRange Drag range, lets you manipulate the drag range.\r
+ * Note that dragged HTML is saved as `text/html` data on `dragstart` so if you change the drag range\r
+ * on drop, dropped HTML will not change. You need to change it manually using\r
+ * {@link CKEDITOR.plugins.clipboard.dataTransfer#setData dataTransfer.setData}.\r
+ * @param {CKEDITOR.dom.range} data.dropRange Drop range, lets you manipulate the drop range.\r
+ */\r
+\r
+/**\r
+ * Facade for the native `dragstart` event. Fired when the native `dragstart` event occurs.\r
+ *\r
+ * This event can be canceled in order to block the drag start operation. It can also be fired to mimic the start of the drag and drop\r
+ * operation. For instance, the `widget` plugin uses this option to integrate its custom block widget drag and drop with\r
+ * the entire system.\r
+ *\r
+ * Read more about integration with drag and drop in the [Clipboard Deep Dive guide](#!/guide/dev_clipboard).\r
+ *\r
+ * See also:\r
+ *\r
+ * * The {@link CKEDITOR.editor#paste} event,\r
+ * * The {@link CKEDITOR.editor#drop} and {@link CKEDITOR.editor#dragend} events,\r
+ * * The {@link CKEDITOR.plugins.clipboard.dataTransfer} class.\r
+ *\r
+ * @since 4.5\r
+ * @event dragstart\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {Object} data.$ Native dragstart event.\r
+ * @param {CKEDITOR.dom.node} data.target Drag target.\r
+ * @param {CKEDITOR.plugins.clipboard.dataTransfer} data.dataTransfer DataTransfer facade.\r
+ */\r
+\r
+/**\r
+ * Facade for the native `dragend` event. Fired when the native `dragend` event occurs.\r
+ *\r
+ * Read more about integration with drag and drop in the [Clipboard Deep Dive guide](#!/guide/dev_clipboard).\r
+ *\r
+ * See also:\r
+ *\r
+ * * The {@link CKEDITOR.editor#paste} event,\r
+ * * The {@link CKEDITOR.editor#drop} and {@link CKEDITOR.editor#dragend} events,\r
+ * * The {@link CKEDITOR.plugins.clipboard.dataTransfer} class.\r
+ *\r
+ * @since 4.5\r
+ * @event dragend\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {Object} data.$ Native dragend event.\r
+ * @param {CKEDITOR.dom.node} data.target Drag target.\r
+ * @param {CKEDITOR.plugins.clipboard.dataTransfer} data.dataTransfer DataTransfer facade.\r
+ */\r
+\r
+/**\r
+ * Defines a filter which is applied to external data pasted or dropped into the editor. Possible values are:\r
+ *\r
+ * * `'plain-text'` &ndash; Content will be pasted as a plain text.\r
+ * * `'semantic-content'` &ndash; Known tags (except `div`, `span`) with all attributes (except\r
+ * `style` and `class`) will be kept.\r
+ * * `'h1 h2 p div'` &ndash; Custom rules compatible with {@link CKEDITOR.filter}.\r
+ * * `null` &ndash; Content will not be filtered by the paste filter (but it still may be filtered\r
+ * by [Advanced Content Filter](#!/guide/dev_advanced_content_filter)). This value can be used to\r
+ * disable the paste filter in Chrome and Safari, where this option defaults to `'semantic-content'`.\r
+ *\r
+ * Example:\r
+ *\r
+ *             config.pasteFilter = 'plain-text';\r
+ *\r
+ * Custom setting:\r
+ *\r
+ *             config.pasteFilter = 'h1 h2 p ul ol li; img[!src, alt]; a[!href]';\r
+ *\r
+ * Based on this configuration option, a proper {@link CKEDITOR.filter} instance will be defined and assigned to the editor\r
+ * as a {@link CKEDITOR.editor#pasteFilter}. You can tweak the paste filter settings on the fly on this object\r
+ * as well as delete or replace it.\r
+ *\r
+ *             var editor = CKEDITOR.replace( 'editor', {\r
+ *                     pasteFilter: 'semantic-content'\r
+ *             } );\r
+ *\r
+ *             editor.on( 'instanceReady', function() {\r
+ *                     // The result of this will be that all semantic content will be preserved\r
+ *                     // except tables.\r
+ *                     editor.pasteFilter.disallow( 'table' );\r
+ *             } );\r
+ *\r
+ * Note that the paste filter is applied only to **external** data. There are three data sources:\r
+ *\r
+ * * copied and pasted in the same editor (internal),\r
+ * * copied from one editor and pasted into another (cross-editor),\r
+ * * coming from all other sources like websites, MS Word, etc. (external).\r
+ *\r
+ * If {@link CKEDITOR.config#allowedContent Advanced Content Filter} is not disabled, then\r
+ * it will also be applied to pasted and dropped data. The paste filter job is to "normalize"\r
+ * external data which often needs to be handled differently than content produced by the editor.\r
+ *\r
+ * This setting defaults to `'semantic-content'` in Chrome, Opera and Safari (all Blink and Webkit based browsers)\r
+ * due to messy HTML which these browsers keep in the clipboard. In other browsers it defaults to `null`.\r
+ *\r
+ * @since 4.5\r
+ * @cfg {String} [pasteFilter='semantic-content' in Chrome and Safari and `null` in other browsers]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * {@link CKEDITOR.filter Content filter} which is used when external data is pasted or dropped into the editor\r
+ * or a forced paste as plain text occurs.\r
+ *\r
+ * This object might be used on the fly to define rules for pasted external content.\r
+ * This object is available and used if the {@link CKEDITOR.plugins.clipboard clipboard} plugin is enabled and\r
+ * {@link CKEDITOR.config#pasteFilter} or {@link CKEDITOR.config#forcePasteAsPlainText} was defined.\r
+ *\r
+ * To enable the filter:\r
+ *\r
+ *             var editor = CKEDITOR.replace( 'editor', {\r
+ *                     pasteFilter: 'plain-text'\r
+ *             } );\r
+ *\r
+ * You can also modify the filter on the fly later on:\r
+ *\r
+ *             editor.pasteFilter = new CKEDITOR.filter( 'p h1 h2; a[!href]' );\r
+ *\r
+ * Note that the paste filter is only applied to **external** data. There are three data sources:\r
+ *\r
+ * * copied and pasted in the same editor (internal),\r
+ * * copied from one editor and pasted into another (cross-editor),\r
+ * * coming from all other sources like websites, MS Word, etc. (external).\r
+ *\r
+ * If {@link CKEDITOR.config#allowedContent Advanced Content Filter} is not disabled, then\r
+ * it will also be applied to pasted and dropped data. The paste filter job is to "normalize"\r
+ * external data which often needs to be handled differently than content produced by the editor.\r
+ *\r
+ * @since 4.5\r
+ * @readonly\r
+ * @property {CKEDITOR.filter} [pasteFilter]\r
+ * @member CKEDITOR.editor\r
+ */\r
diff --git a/sources/plugins/contextmenu/lang/af.js b/sources/plugins/contextmenu/lang/af.js
new file mode 100644 (file)
index 0000000..76b5b96
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'af', {\r
+       options: 'Konteks Spyskaart-opsies'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ar.js b/sources/plugins/contextmenu/lang/ar.js
new file mode 100644 (file)
index 0000000..c81b063
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ar', {\r
+       options: 'خصائص قائمة السياق'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/az.js b/sources/plugins/contextmenu/lang/az.js
new file mode 100644 (file)
index 0000000..651f2f8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'az', {\r
+       options: 'Əlavə əməliyyatlar'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/bg.js b/sources/plugins/contextmenu/lang/bg.js
new file mode 100644 (file)
index 0000000..6bb7a40
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'bg', {\r
+       options: 'Опции на контекстното меню'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/bn.js b/sources/plugins/contextmenu/lang/bn.js
new file mode 100644 (file)
index 0000000..fe93ec8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'bn', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/bs.js b/sources/plugins/contextmenu/lang/bs.js
new file mode 100644 (file)
index 0000000..9354351
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'bs', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ca.js b/sources/plugins/contextmenu/lang/ca.js
new file mode 100644 (file)
index 0000000..91c7ec8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ca', {\r
+       options: 'Opcions del menú contextual'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/cs.js b/sources/plugins/contextmenu/lang/cs.js
new file mode 100644 (file)
index 0000000..e53a0f5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'cs', {\r
+       options: 'Nastavení kontextové nabídky'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/cy.js b/sources/plugins/contextmenu/lang/cy.js
new file mode 100644 (file)
index 0000000..1816b84
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'cy', {\r
+       options: 'Opsiynau Dewislen Cyd-destun'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/da.js b/sources/plugins/contextmenu/lang/da.js
new file mode 100644 (file)
index 0000000..10043a5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'da', {\r
+       options: 'Muligheder for hjælpemenu'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/de-ch.js b/sources/plugins/contextmenu/lang/de-ch.js
new file mode 100644 (file)
index 0000000..216cd18
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'de-ch', {\r
+       options: 'Kontextmenüoptionen'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/de.js b/sources/plugins/contextmenu/lang/de.js
new file mode 100644 (file)
index 0000000..aa0c098
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'de', {\r
+       options: 'Kontextmenüoptionen'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/el.js b/sources/plugins/contextmenu/lang/el.js
new file mode 100644 (file)
index 0000000..bdad720
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'el', {\r
+       options: 'Επιλογές Αναδυόμενου Μενού'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/en-au.js b/sources/plugins/contextmenu/lang/en-au.js
new file mode 100644 (file)
index 0000000..cd6b202
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'en-au', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/en-ca.js b/sources/plugins/contextmenu/lang/en-ca.js
new file mode 100644 (file)
index 0000000..25950c9
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'en-ca', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/en-gb.js b/sources/plugins/contextmenu/lang/en-gb.js
new file mode 100644 (file)
index 0000000..62f08d5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'en-gb', {\r
+       options: 'Context Menu Options'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/en.js b/sources/plugins/contextmenu/lang/en.js
new file mode 100644 (file)
index 0000000..10b5f47
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'en', {\r
+       options: 'Context Menu Options'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/eo.js b/sources/plugins/contextmenu/lang/eo.js
new file mode 100644 (file)
index 0000000..6a9760c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'eo', {\r
+       options: 'Opcioj de Kunteksta Menuo'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/es.js b/sources/plugins/contextmenu/lang/es.js
new file mode 100644 (file)
index 0000000..1e8e06d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'es', {\r
+       options: 'Opciones del menú contextual'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/et.js b/sources/plugins/contextmenu/lang/et.js
new file mode 100644 (file)
index 0000000..d7ece9a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'et', {\r
+       options: 'Kontekstimenüü valikud'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/eu.js b/sources/plugins/contextmenu/lang/eu.js
new file mode 100644 (file)
index 0000000..32018e0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'eu', {\r
+       options: 'Testuinguru-menuaren aukerak'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/fa.js b/sources/plugins/contextmenu/lang/fa.js
new file mode 100644 (file)
index 0000000..233d30d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'fa', {\r
+       options: 'گزینه​های منوی زمینه'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/fi.js b/sources/plugins/contextmenu/lang/fi.js
new file mode 100644 (file)
index 0000000..5c11832
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'fi', {\r
+       options: 'Pikavalikon ominaisuudet'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/fo.js b/sources/plugins/contextmenu/lang/fo.js
new file mode 100644 (file)
index 0000000..6069a48
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'fo', {\r
+       options: 'Context Menu Options'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/fr-ca.js b/sources/plugins/contextmenu/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..d7aca5c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'fr-ca', {\r
+       options: 'Options du menu contextuel'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/fr.js b/sources/plugins/contextmenu/lang/fr.js
new file mode 100644 (file)
index 0000000..7af3f33
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'fr', {\r
+       options: 'Options du menu contextuel'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/gl.js b/sources/plugins/contextmenu/lang/gl.js
new file mode 100644 (file)
index 0000000..de69eae
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'gl', {\r
+       options: 'Opcións do menú contextual'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/gu.js b/sources/plugins/contextmenu/lang/gu.js
new file mode 100644 (file)
index 0000000..d9a83da
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'gu', {\r
+       options: 'કોન્તેક્ષ્ત્ મેનુના વિકલ્પો'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/he.js b/sources/plugins/contextmenu/lang/he.js
new file mode 100644 (file)
index 0000000..a276534
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'he', {\r
+       options: 'אפשרויות תפריט ההקשר'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/hi.js b/sources/plugins/contextmenu/lang/hi.js
new file mode 100644 (file)
index 0000000..a3f501d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'hi', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/hr.js b/sources/plugins/contextmenu/lang/hr.js
new file mode 100644 (file)
index 0000000..149c1eb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'hr', {\r
+       options: 'Opcije izbornika'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/hu.js b/sources/plugins/contextmenu/lang/hu.js
new file mode 100644 (file)
index 0000000..60bb66c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'hu', {\r
+       options: 'Helyi menü opciók'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/id.js b/sources/plugins/contextmenu/lang/id.js
new file mode 100644 (file)
index 0000000..8d19e50
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'id', {\r
+       options: 'Opsi Konteks Pilihan'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/is.js b/sources/plugins/contextmenu/lang/is.js
new file mode 100644 (file)
index 0000000..4404c99
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'is', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/it.js b/sources/plugins/contextmenu/lang/it.js
new file mode 100644 (file)
index 0000000..0453e18
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'it', {\r
+       options: 'Opzioni del menù contestuale'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ja.js b/sources/plugins/contextmenu/lang/ja.js
new file mode 100644 (file)
index 0000000..5887847
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ja', {\r
+       options: 'コンテキストメニューオプション'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ka.js b/sources/plugins/contextmenu/lang/ka.js
new file mode 100644 (file)
index 0000000..f279b0a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ka', {\r
+       options: 'კონტექსტური მენიუს პარამეტრები'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/km.js b/sources/plugins/contextmenu/lang/km.js
new file mode 100644 (file)
index 0000000..9f5d965
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'km', {\r
+       options: 'ជម្រើស​ម៉ឺនុយ​បរិបទ'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ko.js b/sources/plugins/contextmenu/lang/ko.js
new file mode 100644 (file)
index 0000000..45273b5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ko', {\r
+       options: '컨텍스트 메뉴 옵션'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ku.js b/sources/plugins/contextmenu/lang/ku.js
new file mode 100644 (file)
index 0000000..c183cb2
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ku', {\r
+       options: 'هەڵبژاردەی لیستەی کلیکی دەستی ڕاست'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/lt.js b/sources/plugins/contextmenu/lang/lt.js
new file mode 100644 (file)
index 0000000..e16597a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'lt', {\r
+       options: 'Kontekstinio meniu parametrai'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/lv.js b/sources/plugins/contextmenu/lang/lv.js
new file mode 100644 (file)
index 0000000..b14f0eb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'lv', {\r
+       options: 'Uznirstošās izvēlnes uzstādījumi'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/mk.js b/sources/plugins/contextmenu/lang/mk.js
new file mode 100644 (file)
index 0000000..1d7c4c7
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'mk', {\r
+       options: 'Контекст-мени опции'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/mn.js b/sources/plugins/contextmenu/lang/mn.js
new file mode 100644 (file)
index 0000000..5076f18
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'mn', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ms.js b/sources/plugins/contextmenu/lang/ms.js
new file mode 100644 (file)
index 0000000..019ba76
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ms', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/nb.js b/sources/plugins/contextmenu/lang/nb.js
new file mode 100644 (file)
index 0000000..c7c41b0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'nb', {\r
+       options: 'Alternativer for høyreklikkmeny'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/nl.js b/sources/plugins/contextmenu/lang/nl.js
new file mode 100644 (file)
index 0000000..0ceb7cb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'nl', {\r
+       options: 'Contextmenu opties'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/no.js b/sources/plugins/contextmenu/lang/no.js
new file mode 100644 (file)
index 0000000..ee283cf
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'no', {\r
+       options: 'Alternativer for høyreklikkmeny'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/oc.js b/sources/plugins/contextmenu/lang/oc.js
new file mode 100644 (file)
index 0000000..8fab98f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'oc', {\r
+       options: 'Opcions del menú contextual'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/pl.js b/sources/plugins/contextmenu/lang/pl.js
new file mode 100644 (file)
index 0000000..99ef5d9
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'pl', {\r
+       options: 'Opcje menu kontekstowego'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/pt-br.js b/sources/plugins/contextmenu/lang/pt-br.js
new file mode 100644 (file)
index 0000000..ec91513
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'pt-br', {\r
+       options: 'Opções Menu de Contexto'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/pt.js b/sources/plugins/contextmenu/lang/pt.js
new file mode 100644 (file)
index 0000000..c2c969d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'pt', {\r
+       options: 'Menu de opções de contexto'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ro.js b/sources/plugins/contextmenu/lang/ro.js
new file mode 100644 (file)
index 0000000..928c4b3
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ro', {\r
+       options: 'Opțiuni Meniu Contextual'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ru.js b/sources/plugins/contextmenu/lang/ru.js
new file mode 100644 (file)
index 0000000..f671b6a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ru', {\r
+       options: 'Параметры контекстного меню'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/si.js b/sources/plugins/contextmenu/lang/si.js
new file mode 100644 (file)
index 0000000..ec603a3
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'si', {\r
+       options: 'අනතර්ග ලේඛණ  විකල්ප'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sk.js b/sources/plugins/contextmenu/lang/sk.js
new file mode 100644 (file)
index 0000000..fda2b3d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sk', {\r
+       options: 'Možnosti kontextového menu'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sl.js b/sources/plugins/contextmenu/lang/sl.js
new file mode 100644 (file)
index 0000000..9c7fc29
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sl', {\r
+       options: 'Možnosti kontekstnega menija'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sq.js b/sources/plugins/contextmenu/lang/sq.js
new file mode 100644 (file)
index 0000000..698ca2d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sq', {\r
+       options: 'Mundësitë e Menysë së Kontekstit'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sr-latn.js b/sources/plugins/contextmenu/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..d550e84
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sr-latn', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sr.js b/sources/plugins/contextmenu/lang/sr.js
new file mode 100644 (file)
index 0000000..2f7ba14
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sr', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/sv.js b/sources/plugins/contextmenu/lang/sv.js
new file mode 100644 (file)
index 0000000..a3b043f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'sv', {\r
+       options: 'Context Menu Options'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/th.js b/sources/plugins/contextmenu/lang/th.js
new file mode 100644 (file)
index 0000000..ce77065
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'th', {\r
+       options: 'Context Menu Options' // MISSING\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/tr.js b/sources/plugins/contextmenu/lang/tr.js
new file mode 100644 (file)
index 0000000..4d5a550
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'tr', {\r
+       options: 'İçerik Menüsü Seçenekleri'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/tt.js b/sources/plugins/contextmenu/lang/tt.js
new file mode 100644 (file)
index 0000000..0531370
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'tt', {\r
+       options: 'Контекст меню үзлекләре'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/ug.js b/sources/plugins/contextmenu/lang/ug.js
new file mode 100644 (file)
index 0000000..95a9d0a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'ug', {\r
+       options: 'قىسقا يول تىزىملىك تاللانمىسى'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/uk.js b/sources/plugins/contextmenu/lang/uk.js
new file mode 100644 (file)
index 0000000..0a4ffb9
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'uk', {\r
+       options: 'Опції контекстного меню'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/vi.js b/sources/plugins/contextmenu/lang/vi.js
new file mode 100644 (file)
index 0000000..42c39b0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'vi', {\r
+       options: 'Tùy chọn menu bổ xung'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/zh-cn.js b/sources/plugins/contextmenu/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..56879ee
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'zh-cn', {\r
+       options: '快捷菜单选项'\r
+} );\r
diff --git a/sources/plugins/contextmenu/lang/zh.js b/sources/plugins/contextmenu/lang/zh.js
new file mode 100644 (file)
index 0000000..c8d8b93
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'contextmenu', 'zh', {\r
+       options: '內容功能表選項'\r
+} );\r
diff --git a/sources/plugins/contextmenu/plugin.js b/sources/plugins/contextmenu/plugin.js
new file mode 100644 (file)
index 0000000..6cd3935
--- /dev/null
@@ -0,0 +1,159 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'contextmenu', {\r
+       requires: 'menu',\r
+\r
+       // jscs:disable maximumLineLength\r
+       lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+       // jscs:enable maximumLineLength\r
+\r
+       // Make sure the base class (CKEDITOR.menu) is loaded before it (#3318).\r
+       onLoad: function() {\r
+               /**\r
+                * Class replacing the non-configurable native context menu with a configurable CKEditor's equivalent.\r
+                *\r
+                * @class\r
+                * @extends CKEDITOR.menu\r
+                */\r
+               CKEDITOR.plugins.contextMenu = CKEDITOR.tools.createClass( {\r
+                       base: CKEDITOR.menu,\r
+\r
+                       /**\r
+                        * Creates the CKEDITOR.plugins.contextMenu class instance.\r
+                        *\r
+                        * @constructor\r
+                        * @param {CKEDITOR.editor} editor\r
+                        */\r
+                       $: function( editor ) {\r
+                               this.base.call( this, editor, {\r
+                                       panel: {\r
+                                               className: 'cke_menu_panel',\r
+                                               attributes: {\r
+                                                       'aria-label': editor.lang.contextmenu.options\r
+                                               }\r
+                                       }\r
+                               } );\r
+                       },\r
+\r
+                       proto: {\r
+                               /**\r
+                                * Starts watching on native context menu triggers (<kbd>Option</kbd> key, right click) on the given element.\r
+                                *\r
+                                * @param {CKEDITOR.dom.element} element\r
+                                * @param {Boolean} [nativeContextMenuOnCtrl] Whether to open native context menu if the\r
+                                * <kbd>Ctrl</kbd> key is held on opening the context menu. See {@link CKEDITOR.config#browserContextMenuOnCtrl}.\r
+                                */\r
+                               addTarget: function( element, nativeContextMenuOnCtrl ) {\r
+                                       element.on( 'contextmenu', function( event ) {\r
+                                               var domEvent = event.data,\r
+                                                       isCtrlKeyDown =\r
+                                                               // Safari on Windows always show 'ctrlKey' as true in 'contextmenu' event,\r
+                                                               // which make this property unreliable. (#4826)\r
+                                                               ( CKEDITOR.env.webkit ? holdCtrlKey : ( CKEDITOR.env.mac ? domEvent.$.metaKey : domEvent.$.ctrlKey ) );\r
+\r
+                                               if ( nativeContextMenuOnCtrl && isCtrlKeyDown )\r
+                                                       return;\r
+\r
+                                               // Cancel the browser context menu.\r
+                                               domEvent.preventDefault();\r
+\r
+                                               // Fix selection when non-editable element in Webkit/Blink (Mac) (#11306).\r
+                                               if ( CKEDITOR.env.mac && CKEDITOR.env.webkit ) {\r
+                                                       var editor = this.editor,\r
+                                                               contentEditableParent = new CKEDITOR.dom.elementPath( domEvent.getTarget(), editor.editable() ).contains( function( el ) {\r
+                                                                       // Return when non-editable or nested editable element is found.\r
+                                                                       return el.hasAttribute( 'contenteditable' );\r
+                                                               }, true ); // Exclude editor's editable.\r
+\r
+                                                       // Fake selection for non-editables only (to exclude nested editables).\r
+                                                       if ( contentEditableParent && contentEditableParent.getAttribute( 'contenteditable' ) == 'false' )\r
+                                                               editor.getSelection().fake( contentEditableParent );\r
+                                               }\r
+\r
+                                               var doc = domEvent.getTarget().getDocument(),\r
+                                                       offsetParent = domEvent.getTarget().getDocument().getDocumentElement(),\r
+                                                       fromFrame = !doc.equals( CKEDITOR.document ),\r
+                                                       scroll = doc.getWindow().getScrollPosition(),\r
+                                                       offsetX = fromFrame ? domEvent.$.clientX : domEvent.$.pageX || scroll.x + domEvent.$.clientX,\r
+                                                       offsetY = fromFrame ? domEvent.$.clientY : domEvent.$.pageY || scroll.y + domEvent.$.clientY;\r
+\r
+                                               CKEDITOR.tools.setTimeout( function() {\r
+                                                       this.open( offsetParent, null, offsetX, offsetY );\r
+\r
+                                                       // IE needs a short while to allow selection change before opening menu. (#7908)\r
+                                               }, CKEDITOR.env.ie ? 200 : 0, this );\r
+                                       }, this );\r
+\r
+                                       if ( CKEDITOR.env.webkit ) {\r
+                                               var holdCtrlKey,\r
+                                                       onKeyDown = function( event ) {\r
+                                                               holdCtrlKey = CKEDITOR.env.mac ? event.data.$.metaKey : event.data.$.ctrlKey;\r
+                                                       },\r
+                                                       resetOnKeyUp = function() {\r
+                                                               holdCtrlKey = 0;\r
+                                                       };\r
+\r
+                                               element.on( 'keydown', onKeyDown );\r
+                                               element.on( 'keyup', resetOnKeyUp );\r
+                                               element.on( 'contextmenu', resetOnKeyUp );\r
+                                       }\r
+                               },\r
+\r
+                               /**\r
+                                * Opens the context menu in the given location. See the {@link CKEDITOR.menu#show} method.\r
+                                *\r
+                                * @param {CKEDITOR.dom.element} offsetParent\r
+                                * @param {Number} [corner]\r
+                                * @param {Number} [offsetX]\r
+                                * @param {Number} [offsetY]\r
+                                */\r
+                               open: function( offsetParent, corner, offsetX, offsetY ) {\r
+                                       this.editor.focus();\r
+                                       offsetParent = offsetParent || CKEDITOR.document.getDocumentElement();\r
+\r
+                                       // #9362: Force selection check to update commands' states in the new context.\r
+                                       this.editor.selectionChange( 1 );\r
+\r
+                                       this.show( offsetParent, corner, offsetX, offsetY );\r
+                               }\r
+                       }\r
+               } );\r
+       },\r
+\r
+       beforeInit: function( editor ) {\r
+               /**\r
+                * @readonly\r
+                * @property {CKEDITOR.plugins.contextMenu} contextMenu\r
+                * @member CKEDITOR.editor\r
+                */\r
+               var contextMenu = editor.contextMenu = new CKEDITOR.plugins.contextMenu( editor );\r
+\r
+               editor.on( 'contentDom', function() {\r
+                       contextMenu.addTarget( editor.editable(), editor.config.browserContextMenuOnCtrl !== false );\r
+               } );\r
+\r
+               editor.addCommand( 'contextMenu', {\r
+                       exec: function() {\r
+                               editor.contextMenu.open( editor.document.getBody() );\r
+                       }\r
+               } );\r
+\r
+               editor.setKeystroke( CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' );\r
+               editor.setKeystroke( CKEDITOR.CTRL + CKEDITOR.SHIFT + 121 /*F10*/, 'contextMenu' );\r
+       }\r
+} );\r
+\r
+/**\r
+ * Whether to show the browser native context menu when the <kbd>Ctrl</kbd> or\r
+ * <kbd>Meta</kbd> (Mac) key is pressed on opening the context menu with the\r
+ * right mouse button click or the <kbd>Menu</kbd> key.\r
+ *\r
+ *             config.browserContextMenuOnCtrl = false;\r
+ *\r
+ * @since 3.0.2\r
+ * @cfg {Boolean} [browserContextMenuOnCtrl=true]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/dialog/dialogDefinition.js b/sources/plugins/dialog/dialogDefinition.js
new file mode 100644 (file)
index 0000000..6ecb491
--- /dev/null
@@ -0,0 +1,1032 @@
+// jscs:disable disallowMixedSpacesAndTabs\r
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Defines the "virtual" dialog, dialog content and dialog button\r
+ * definition classes.\r
+ */\r
+\r
+/**\r
+ * The definition of a dialog window.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create dialogs.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             CKEDITOR.dialog.add( 'testOnly', function( editor ) {\r
+ *                     return {\r
+ *                             title:                  'Test Dialog',\r
+ *                             resizable:              CKEDITOR.DIALOG_RESIZE_BOTH,\r
+ *                             minWidth:               500,\r
+ *                             minHeight:              400,\r
+ *                             contents: [\r
+ *                                     {\r
+ *                                             id:                     'tab1',\r
+ *                                             label:          'First Tab',\r
+ *                                             title:          'First Tab Title',\r
+ *                                             accessKey:      'Q',\r
+ *                                             elements: [\r
+ *                                                     {\r
+ *                                                             type:                   'text',\r
+ *                                                             label:                  'Test Text 1',\r
+ *                                                             id:                             'testText1',\r
+ *                                                             'default':              'hello world!'\r
+ *                                                     }\r
+ *                                             ]\r
+ *                                     }\r
+ *                             ]\r
+ *                     };\r
+ *             } );\r
+ *\r
+ * @class CKEDITOR.dialog.definition\r
+ */\r
+\r
+/**\r
+ * The dialog title, displayed in the dialog's header. Required.\r
+ *\r
+ * @property {String} title\r
+ */\r
+\r
+/**\r
+ * How the dialog can be resized, must be one of the four contents defined below.\r
+ *\r
+ * * {@link CKEDITOR#DIALOG_RESIZE_NONE}\r
+ * * {@link CKEDITOR#DIALOG_RESIZE_WIDTH}\r
+ * * {@link CKEDITOR#DIALOG_RESIZE_HEIGHT}\r
+ * * {@link CKEDITOR#DIALOG_RESIZE_BOTH}\r
+ *\r
+ * @property {Number} [resizable=CKEDITOR.DIALOG_RESIZE_NONE]\r
+ */\r
+\r
+/**\r
+ * The minimum width of the dialog, in pixels.\r
+ *\r
+ * @property {Number} [minWidth=600]\r
+ */\r
+\r
+/**\r
+ * The minimum height of the dialog, in pixels.\r
+ *\r
+ * @property {Number} [minHeight=400]\r
+ */\r
+\r
+\r
+/**\r
+ * The initial width of the dialog, in pixels.\r
+ *\r
+ * @since 3.5.3\r
+ * @property {Number} [width=CKEDITOR.dialog.definition#minWidth]\r
+ */\r
+\r
+/**\r
+ * The initial height of the dialog, in pixels.\r
+ *\r
+ * @since 3.5.3\r
+ * @property {Number} [height=CKEDITOR.dialog.definition.minHeight]\r
+ */\r
+\r
+/**\r
+ * The buttons in the dialog, defined as an array of\r
+ * {@link CKEDITOR.dialog.definition.button} objects.\r
+ *\r
+ * @property {Array} [buttons=[ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]]\r
+ */\r
+\r
+/**\r
+ * The contents in the dialog, defined as an array of\r
+ * {@link CKEDITOR.dialog.definition.content} objects. Required.\r
+ *\r
+ * @property {Array} contents\r
+ */\r
+\r
+/**\r
+ * The function to execute when OK is pressed.\r
+ *\r
+ * @property {Function} onOk\r
+ */\r
+\r
+/**\r
+ * The function to execute when Cancel is pressed.\r
+ *\r
+ * @property {Function} onCancel\r
+ */\r
+\r
+/**\r
+ * The function to execute when the dialog is displayed for the first time.\r
+ *\r
+ * @property {Function} onLoad\r
+ */\r
+\r
+/**\r
+ * The function to execute when the dialog is loaded (executed every time the dialog is opened).\r
+ *\r
+ * @property {Function} onShow\r
+ */\r
+\r
+/**\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create dialog content pages.\r
+ *\r
+ * @class CKEDITOR.dialog.definition.content.\r
+ */\r
+\r
+/**\r
+ * The id of the content page.\r
+ *\r
+ * @property {String} id\r
+ */\r
+\r
+/**\r
+ * The tab label of the content page.\r
+ *\r
+ * @property {String} label\r
+ */\r
+\r
+/**\r
+ * The popup message of the tab label.\r
+ *\r
+ * @property {String} title\r
+ */\r
+\r
+/**\r
+ * The CTRL hotkey for switching to the tab.\r
+ *\r
+ *             contentDefinition.accessKey = 'Q'; // Switch to this page when CTRL-Q is pressed.\r
+ *\r
+ * @property {String} accessKey\r
+ */\r
+\r
+/**\r
+ * The UI elements contained in this content page, defined as an array of\r
+ * {@link CKEDITOR.dialog.definition.uiElement} objects.\r
+ *\r
+ * @property {Array} elements\r
+ */\r
+\r
+/**\r
+ * The definition of user interface element (textarea, radio etc).\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create dialog UI elements.\r
+ *\r
+ * @class CKEDITOR.dialog.definition.uiElement\r
+ * @see CKEDITOR.ui.dialog.uiElement\r
+ */\r
+\r
+/**\r
+ * The id of the UI element.\r
+ *\r
+ * @property {String} id\r
+ */\r
+\r
+/**\r
+ * The type of the UI element. Required.\r
+ *\r
+ * @property {String} type\r
+ */\r
+\r
+/**\r
+ * The popup label of the UI element.\r
+ *\r
+ * @property {String} title\r
+ */\r
+\r
+/**\r
+ * The content that needs to be allowed to enable this UI element.\r
+ * All formats accepted by {@link CKEDITOR.filter#check} may be used.\r
+ *\r
+ * When all UI elements in a tab are disabled, this tab will be disabled automatically.\r
+ *\r
+ * @property {String/Object/CKEDITOR.style} requiredContent\r
+ */\r
+\r
+/**\r
+ * CSS class names to append to the UI element.\r
+ *\r
+ * @property {String} className\r
+ */\r
+\r
+/**\r
+ * Inline CSS classes to append to the UI element.\r
+ *\r
+ * @property {String} style\r
+ */\r
+\r
+/**\r
+ * Horizontal alignment (in container) of the UI element.\r
+ *\r
+ * @property {String} align\r
+ */\r
+\r
+/**\r
+ * Function to execute the first time the UI element is displayed.\r
+ *\r
+ * @property {Function} onLoad\r
+ */\r
+\r
+/**\r
+ * Function to execute whenever the UI element's parent dialog is displayed.\r
+ *\r
+ * @property {Function} onShow\r
+ */\r
+\r
+/**\r
+ * Function to execute whenever the UI element's parent dialog is closed.\r
+ *\r
+ * @property {Function} onHide\r
+ */\r
+\r
+/**\r
+ * Function to execute whenever the UI element's parent\r
+ * dialog's {@link CKEDITOR.dialog#setupContent} method is executed.\r
+ * It usually takes care of the respective UI element as a standalone element.\r
+ *\r
+ * @property {Function} setup\r
+ */\r
+\r
+/**\r
+ * Function to execute whenever the UI element's parent\r
+ * dialog's {@link CKEDITOR.dialog#commitContent} method is executed.\r
+ * It usually takes care of the respective UI element as a standalone element.\r
+ *\r
+ * @property {Function} commit\r
+ */\r
+\r
+// ----- hbox -----------------------------------------------------------------\r
+\r
+/**\r
+ * Horizontal layout box for dialog UI elements, auto-expends to available width of container.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create horizontal layouts.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.hbox} object and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'hbox',\r
+ *                     widths: [ '25%', '25%', '50%' ],\r
+ *                     children: [\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'id1',\r
+ *                                     width: '40px',\r
+ *                             },\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'id2',\r
+ *                                     width: '40px',\r
+ *                             },\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'id3'\r
+ *                             }\r
+ *                     ]\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.hbox\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.\r
+ *\r
+ * @property {Array} children\r
+ */\r
+\r
+/**\r
+ * (Optional) The widths of child cells.\r
+ *\r
+ * @property {Array} widths\r
+ */\r
+\r
+/**\r
+ * (Optional) The height of the layout.\r
+ *\r
+ * @property {Number} height\r
+ */\r
+\r
+/**\r
+ * The CSS styles to apply to this element.\r
+ *\r
+ * @property {String} styles\r
+ */\r
+\r
+/**\r
+ * (Optional) The padding width inside child cells. Example: 0, 1.\r
+ *\r
+ * @property {Number} padding\r
+ */\r
+\r
+/**\r
+ * (Optional) The alignment of the whole layout. Example: center, top.\r
+ *\r
+ * @property {String} align\r
+ */\r
+\r
+// ----- vbox -----------------------------------------------------------------\r
+\r
+/**\r
+ * Vertical layout box for dialog UI elements.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create vertical layouts.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.vbox} object and can\r
+ * be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'vbox',\r
+ *                     align: 'right',\r
+ *                     width: '200px',\r
+ *                     children: [\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'age',\r
+ *                                     label: 'Age'\r
+ *                             },\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'sex',\r
+ *                                     label: 'Sex'\r
+ *                             },\r
+ *                             {\r
+ *                                     type: 'text',\r
+ *                                     id: 'nationality',\r
+ *                                     label: 'Nationality'\r
+ *                             }\r
+ *                     ]\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.vbox\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.\r
+ *\r
+ * @property {Array} children\r
+ */\r
+\r
+/**\r
+ * (Optional) The width of the layout.\r
+ *\r
+ * @property {Array} width\r
+ */\r
+\r
+/**\r
+ * (Optional) The heights of individual cells.\r
+ *\r
+ * @property {Number} heights\r
+ */\r
+\r
+/**\r
+ * The CSS styles to apply to this element.\r
+ *\r
+ * @property {String} styles\r
+ */\r
+\r
+/**\r
+ * (Optional) The padding width inside child cells. Example: 0, 1.\r
+ *\r
+ * @property {Number} padding\r
+ */\r
+\r
+/**\r
+ * (Optional) The alignment of the whole layout. Example: center, top.\r
+ *\r
+ * @property {String} align\r
+ */\r
+\r
+/**\r
+ * (Optional) Whether the layout should expand vertically to fill its container.\r
+ *\r
+ * @property {Boolean} expand\r
+ */\r
+\r
+// ----- labeled element ------------------------------------------------------\r
+\r
+/**\r
+ * The definition of labeled user interface element (textarea, textInput etc).\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create dialog UI elements.\r
+ *\r
+ * @class CKEDITOR.dialog.definition.labeledElement\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ * @see CKEDITOR.ui.dialog.labeledElement\r
+ */\r
+\r
+/**\r
+ * The label of the UI element.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label'\r
+ *             }\r
+ *\r
+ * @property {String} label\r
+ */\r
+\r
+/**\r
+ * (Optional) Specify the layout of the label. Set to `'horizontal'` for horizontal layout.\r
+ * The default layout is vertical.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label',\r
+ *                     labelLayout: 'horizontal'\r
+ *             }\r
+ *\r
+ * @property {String} labelLayout\r
+ */\r
+\r
+/**\r
+ * (Optional) Applies only to horizontal layouts: a two elements array of lengths to specify the widths of the\r
+ * label and the content element. See also {@link CKEDITOR.dialog.definition.labeledElement#labelLayout}.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label',\r
+ *                     labelLayout: 'horizontal',\r
+ *                     widths: [100, 200]\r
+ *             }\r
+ *\r
+ * @property {Array} widths\r
+ */\r
+\r
+/**\r
+ * Specify the inline style of the uiElement label.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label',\r
+ *                     labelStyle: 'color: red'\r
+ *             }\r
+ *\r
+ * @property {String} labelStyle\r
+ */\r
+\r
+\r
+/**\r
+ * Specify the inline style of the input element.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label',\r
+ *                     inputStyle: 'text-align: center'\r
+ *             }\r
+ *\r
+ * @since 3.6.1\r
+ * @property {String} inputStyle\r
+ */\r
+\r
+/**\r
+ * Specify the inline style of the input element container.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     label: 'My Label',\r
+ *                     controlStyle: 'width: 3em'\r
+ *             }\r
+ *\r
+ * @since 3.6.1\r
+ * @property {String} controlStyle\r
+ */\r
+\r
+// ----- button ---------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a button.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create buttons.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.button} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'button',\r
+ *                     id: 'buttonId',\r
+ *                     label: 'Click me',\r
+ *                     title: 'My title',\r
+ *                     onClick: function() {\r
+ *                             // this = CKEDITOR.ui.dialog.button\r
+ *                             alert( 'Clicked: ' + this.id );\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.button\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * Whether the button is disabled.\r
+ *\r
+ * @property {Boolean} disabled\r
+ */\r
+\r
+/**\r
+ * The label of the UI element.\r
+ *\r
+ * @property {String} label\r
+ */\r
+\r
+// ----- checkbox ------\r
+/**\r
+ * The definition of a checkbox element.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create groups of checkbox buttons.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.checkbox} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'checkbox',\r
+ *                     id: 'agree',\r
+ *                     label: 'I agree',\r
+ *                     'default': 'checked',\r
+ *                     onClick: function() {\r
+ *                             // this = CKEDITOR.ui.dialog.checkbox\r
+ *                             alert( 'Checked: ' + this.getValue() );\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.checkbox\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * The label of the UI element.\r
+ *\r
+ * @property {String} label\r
+ */\r
+\r
+/**\r
+ * The default state.\r
+ *\r
+ * @property {String} [default='' (unchecked)]\r
+ */\r
+\r
+// ----- file -----------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a file upload input.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create file upload elements.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.file} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'file',\r
+ *                     id: 'upload',\r
+ *                     label: 'Select file from your computer',\r
+ *                     size: 38\r
+ *             },\r
+ *             {\r
+ *                     type: 'fileButton',\r
+ *                     id: 'fileId',\r
+ *                     label: 'Upload file',\r
+ *                     'for': [ 'tab1', 'upload' ],\r
+ *                     filebrowser: {\r
+ *                             onSelect: function( fileUrl, data ) {\r
+ *                                     alert( 'Successfully uploaded: ' + fileUrl );\r
+ *                             }\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.file\r
+ * @extends CKEDITOR.dialog.definition.labeledElement\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * (Optional) The action attribute of the form element associated with this file upload input.\r
+ * If empty, CKEditor will use path to server connector for currently opened folder.\r
+ *\r
+ * @property {String} action\r
+ */\r
+\r
+/**\r
+ * The size of the UI element.\r
+ *\r
+ * @property {Number} size\r
+ */\r
+\r
+// ----- fileButton -----------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a button for submitting the file in a file upload input.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create a button for submitting the file in a file upload input.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.fileButton} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ * @class CKEDITOR.dialog.definition.fileButton\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * The label of the UI element.\r
+ *\r
+ * @property {String} label\r
+ */\r
+\r
+/**\r
+ * The instruction for CKEditor how to deal with file upload.\r
+ * By default, the file and fileButton elements will not work "as expected" if this attribute is not set.\r
+ *\r
+ *             // Update field with id 'txtUrl' in the 'tab1' tab when file is uploaded.\r
+ *             filebrowser: 'tab1:txtUrl'\r
+ *\r
+ *             // Call custom onSelect function when file is successfully uploaded.\r
+ *             filebrowser: {\r
+ *                     onSelect: function( fileUrl, data ) {\r
+ *                             alert( 'Successfully uploaded: ' + fileUrl );\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @property {String} filebrowser/Object\r
+ */\r
+\r
+/**\r
+ * An array that contains pageId and elementId of the file upload input element for which this button is created.\r
+ *\r
+ *             [ pageId, elementId ]\r
+ *\r
+ * @property {String} for\r
+ */\r
+\r
+// ----- html -----------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a raw HTML element.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create elements made from raw HTML code.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.html} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ * To access HTML elements use {@link CKEDITOR.dom.document#getById}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example 1:\r
+ *             {\r
+ *                     type: 'html',\r
+ *                     html: '<h3>This is some sample HTML content.</h3>'\r
+ *             }\r
+ *\r
+ *             // Example 2:\r
+ *             // Complete sample with document.getById() call when the "Ok" button is clicked.\r
+ *             var dialogDefinition = {\r
+ *                     title: 'Sample dialog',\r
+ *                     minWidth: 300,\r
+ *                     minHeight: 200,\r
+ *                     onOk: function() {\r
+ *                             // "this" is now a CKEDITOR.dialog object.\r
+ *                             var document = this.getElement().getDocument();\r
+ *                             // document = CKEDITOR.dom.document\r
+ *                             var element = <b>document.getById( 'myDiv' );</b>\r
+ *                             if ( element )\r
+ *                                     alert( element.getHtml() );\r
+ *                     },\r
+ *                     contents: [\r
+ *                             {\r
+ *                                     id: 'tab1',\r
+ *                                     label: '',\r
+ *                                     title: '',\r
+ *                                     elements: [\r
+ *                                             {\r
+ *                                                     type: 'html',\r
+ *                                                     html: '<div id="myDiv">Sample <b>text</b>.</div><div id="otherId">Another div.</div>'\r
+ *                                             }\r
+ *                                     ]\r
+ *                             }\r
+ *                     ],\r
+ *                     buttons: [ CKEDITOR.dialog.cancelButton, CKEDITOR.dialog.okButton ]\r
+ *             };\r
+ *\r
+ * @class CKEDITOR.dialog.definition.html\r
+ * @extends CKEDITOR.dialog.definition.uiElement\r
+ */\r
+\r
+/**\r
+ * (Required) HTML code of this element.\r
+ *\r
+ * @property {String} html\r
+ */\r
+\r
+// ----- radio ----------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a radio group.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create groups of radio buttons.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.radio} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'radio',\r
+ *                     id: 'country',\r
+ *                     label: 'Which country is bigger',\r
+ *                     items: [ [ 'France', 'FR' ], [ 'Germany', 'DE' ] ],\r
+ *                     style: 'color: green',\r
+ *                     'default': 'DE',\r
+ *                     onClick: function() {\r
+ *                             // this = CKEDITOR.ui.dialog.radio\r
+ *                             alert( 'Current value: ' + this.getValue() );\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.radio\r
+ * @extends CKEDITOR.dialog.definition.labeledElement\r
+ */\r
+\r
+/**\r
+ * The default value.\r
+ *\r
+ * @property {String} default\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * An array of options. Each option is a 1- or 2-item array of format `[ 'Description', 'Value' ]`.\r
+ * If `'Value'` is missing, then the value would be assumed to be the same as the description.\r
+ *\r
+ * @property {Array} items\r
+ */\r
+\r
+// ----- selectElement --------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a select element.\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create select elements.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.select} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             // Example:\r
+ *             {\r
+ *                     type: 'select',\r
+ *                     id: 'sport',\r
+ *                     label: 'Select your favourite sport',\r
+ *                     items: [ [ 'Basketball' ], [ 'Baseball' ], [ 'Hockey' ], [ 'Football' ] ],\r
+ *                     'default': 'Football',\r
+ *                     onChange: function( api ) {\r
+ *                             // this = CKEDITOR.ui.dialog.select\r
+ *                             alert( 'Current value: ' + this.getValue() );\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.select\r
+ * @extends CKEDITOR.dialog.definition.labeledElement\r
+ */\r
+\r
+/**\r
+ * The default value.\r
+ *\r
+ * @property {String} default\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * An array of options. Each option is a 1- or 2-item array of format `[ 'Description', 'Value' ]`.\r
+ * If `'Value'` is missing, then the value would be assumed to be the same as the description.\r
+ *\r
+ * @property {Array} items\r
+ */\r
+\r
+/**\r
+ * (Optional) Set this to true if you'd like to have a multiple-choice select box.\r
+ *\r
+ * @property {Boolean} [multiple=false]\r
+ */\r
+\r
+/**\r
+ * (Optional) The number of items to display in the select box.\r
+ *\r
+ * @property {Number} size\r
+ */\r
+\r
+// ----- textInput ------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a text field (single line).\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create text fields.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.textInput} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+ *             // There is no constructor for this class, the user just has to define an\r
+ *             // object with the appropriate properties.\r
+ *\r
+ *             {\r
+ *                     type: 'text',\r
+ *                     id: 'name',\r
+ *                     label: 'Your name',\r
+ *                     'default': '',\r
+ *                     validate: function() {\r
+ *                             if ( !this.getValue() ) {\r
+ *                                     api.openMsgDialog( '', 'Name cannot be empty.' );\r
+ *                                     return false;\r
+ *                             }\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.textInput\r
+ * @extends CKEDITOR.dialog.definition.labeledElement\r
+ */\r
+\r
+/**\r
+ * The default value.\r
+ *\r
+ * @property {String} default\r
+ */\r
+\r
+/**\r
+ * (Optional) The maximum length.\r
+ *\r
+ * @property {Number} maxLength\r
+ */\r
+\r
+/**\r
+ * (Optional) The size of the input field.\r
+ *\r
+ * @property {Number} size\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * @property bidi\r
+ * @inheritdoc CKEDITOR.dialog.definition.textarea#bidi\r
+ */\r
+\r
+// ----- textarea -------------------------------------------------------------\r
+\r
+/**\r
+ * The definition of a text field (multiple lines).\r
+ *\r
+ * This class is not really part of the API. It just illustrates the properties\r
+ * that developers can use to define and create textarea.\r
+ *\r
+ * Once the dialog is opened, the created element becomes a {@link CKEDITOR.ui.dialog.textarea} object\r
+ * and can be accessed with {@link CKEDITOR.dialog#getContentElement}.\r
+ *\r
+ * For a complete example of dialog definition, please check {@link CKEDITOR.dialog#add}.\r
+ *\r
+*              // There is no constructor for this class, the user just has to define an\r
+*              // object with the appropriate properties.\r
+*\r
+*              // Example:\r
+*              {\r
+*                      type: 'textarea',\r
+*                      id: 'message',\r
+*                      label: 'Your comment',\r
+*                      'default': '',\r
+*                      validate: function() {\r
+*                              if ( this.getValue().length < 5 ) {\r
+*                                      api.openMsgDialog( 'The comment is too short.' );\r
+*                                      return false;\r
+*                              }\r
+*                      }\r
+*              }\r
+ *\r
+ * @class CKEDITOR.dialog.definition.textarea\r
+ * @extends CKEDITOR.dialog.definition.labeledElement\r
+ */\r
+\r
+/**\r
+ * The number of rows.\r
+ *\r
+ * @property {Number} rows\r
+ */\r
+\r
+/**\r
+ * The number of columns.\r
+ *\r
+ * @property {Number} cols\r
+ */\r
+\r
+/**\r
+ * (Optional) The validation function.\r
+ *\r
+ * @property {Function} validate\r
+ */\r
+\r
+/**\r
+ * The default value.\r
+ *\r
+ * @property {String} default\r
+ */\r
+\r
+/**\r
+ * Whether the text direction of this input should be togglable using the following keystrokes:\r
+ *\r
+ * * *Shift+Alt+End* &ndash; switch to Right-To-Left,\r
+ * * *Shift+Alt+Home* &ndash; switch to Left-To-Right.\r
+ *\r
+ * By default the input will be loaded without any text direction set, which means that\r
+ * the direction will be inherited from the editor's text direction.\r
+ *\r
+ * If the direction was set, a marker will be prepended to every non-empty value of this input:\r
+ *\r
+ * * [`\u202A`](http://unicode.org/cldr/utility/character.jsp?a=202A) &ndash; for Right-To-Left,\r
+ * * [`\u202B`](http://unicode.org/cldr/utility/character.jsp?a=202B) &ndash; for Left-To-Right.\r
+ *\r
+ * This marker allows for restoring the same text direction upon the next dialog opening.\r
+ *\r
+ * @since 4.5\r
+ * @property {Boolean} bidi\r
+ */\r
diff --git a/sources/plugins/dialog/plugin.js b/sources/plugins/dialog/plugin.js
new file mode 100644 (file)
index 0000000..d6af6a2
--- /dev/null
@@ -0,0 +1,3399 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The floating dialog plugin.\r
+ */\r
+\r
+/**\r
+ * No resize for this dialog.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=0]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_RESIZE_NONE = 0;\r
+\r
+/**\r
+ * Only allow horizontal resizing for this dialog, disable vertical resizing.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=1]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_RESIZE_WIDTH = 1;\r
+\r
+/**\r
+ * Only allow vertical resizing for this dialog, disable horizontal resizing.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=2]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_RESIZE_HEIGHT = 2;\r
+\r
+/**\r
+ * Allow the dialog to be resized in both directions.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=3]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_RESIZE_BOTH = 3;\r
+\r
+/**\r
+ * Dialog state when idle.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=1]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_STATE_IDLE = 1;\r
+\r
+/**\r
+ * Dialog state when busy.\r
+ *\r
+ * @readonly\r
+ * @property {Number} [=2]\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.DIALOG_STATE_BUSY = 2;\r
+\r
+( function() {\r
+       var cssLength = CKEDITOR.tools.cssLength;\r
+\r
+       function isTabVisible( tabId ) {\r
+               return !!this._.tabs[ tabId ][ 0 ].$.offsetHeight;\r
+       }\r
+\r
+       function getPreviousVisibleTab() {\r
+               var tabId = this._.currentTabId,\r
+                       length = this._.tabIdList.length,\r
+                       tabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, tabId ) + length;\r
+\r
+               for ( var i = tabIndex - 1; i > tabIndex - length; i-- ) {\r
+                       if ( isTabVisible.call( this, this._.tabIdList[ i % length ] ) )\r
+                               return this._.tabIdList[ i % length ];\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       function getNextVisibleTab() {\r
+               var tabId = this._.currentTabId,\r
+                       length = this._.tabIdList.length,\r
+                       tabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, tabId );\r
+\r
+               for ( var i = tabIndex + 1; i < tabIndex + length; i++ ) {\r
+                       if ( isTabVisible.call( this, this._.tabIdList[ i % length ] ) )\r
+                               return this._.tabIdList[ i % length ];\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+\r
+       function clearOrRecoverTextInputValue( container, isRecover ) {\r
+               var inputs = container.$.getElementsByTagName( 'input' );\r
+               for ( var i = 0, length = inputs.length; i < length; i++ ) {\r
+                       var item = new CKEDITOR.dom.element( inputs[ i ] );\r
+\r
+                       if ( item.getAttribute( 'type' ).toLowerCase() == 'text' ) {\r
+                               if ( isRecover ) {\r
+                                       item.setAttribute( 'value', item.getCustomData( 'fake_value' ) || '' );\r
+                                       item.removeCustomData( 'fake_value' );\r
+                               } else {\r
+                                       item.setCustomData( 'fake_value', item.getAttribute( 'value' ) );\r
+                                       item.setAttribute( 'value', '' );\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Handle dialog element validation state UI changes.\r
+       function handleFieldValidated( isValid, msg ) {\r
+               var input = this.getInputElement();\r
+               if ( input )\r
+                       isValid ? input.removeAttribute( 'aria-invalid' ) : input.setAttribute( 'aria-invalid', true );\r
+\r
+               if ( !isValid ) {\r
+                       if ( this.select )\r
+                               this.select();\r
+                       else\r
+                               this.focus();\r
+               }\r
+\r
+               msg && alert( msg ); // jshint ignore:line\r
+\r
+               this.fire( 'validated', { valid: isValid, msg: msg } );\r
+       }\r
+\r
+       function resetField() {\r
+               var input = this.getInputElement();\r
+               input && input.removeAttribute( 'aria-invalid' );\r
+       }\r
+\r
+       var templateSource = '<div class="cke_reset_all {editorId} {editorDialogClass} {hidpi}' +\r
+               '" dir="{langDir}"' +\r
+               ' lang="{langCode}"' +\r
+               ' role="dialog"' +\r
+               ' aria-labelledby="cke_dialog_title_{id}"' +\r
+               '>' +\r
+               '<table class="cke_dialog ' + CKEDITOR.env.cssClass + ' cke_{langDir}"' +\r
+                       ' style="position:absolute" role="presentation">' +\r
+                       '<tr><td role="presentation">' +\r
+                       '<div class="cke_dialog_body" role="presentation">' +\r
+                               '<div id="cke_dialog_title_{id}" class="cke_dialog_title" role="presentation"></div>' +\r
+                               '<a id="cke_dialog_close_button_{id}" class="cke_dialog_close_button" href="javascript:void(0)" title="{closeTitle}" role="button"><span class="cke_label">X</span></a>' +\r
+                               '<div id="cke_dialog_tabs_{id}" class="cke_dialog_tabs" role="tablist"></div>' +\r
+                               '<table class="cke_dialog_contents" role="presentation">' +\r
+                               '<tr>' +\r
+                                       '<td id="cke_dialog_contents_{id}" class="cke_dialog_contents_body" role="presentation"></td>' +\r
+                               '</tr>' +\r
+                               '<tr>' +\r
+                                       '<td id="cke_dialog_footer_{id}" class="cke_dialog_footer" role="presentation"></td>' +\r
+                               '</tr>' +\r
+                               '</table>' +\r
+                       '</div>' +\r
+                       '</td></tr>' +\r
+               '</table>' +\r
+               '</div>';\r
+\r
+       function buildDialog( editor ) {\r
+               var element = CKEDITOR.dom.element.createFromHtml( CKEDITOR.addTemplate( 'dialog', templateSource ).output( {\r
+                       id: CKEDITOR.tools.getNextNumber(),\r
+                       editorId: editor.id,\r
+                       langDir: editor.lang.dir,\r
+                       langCode: editor.langCode,\r
+                       editorDialogClass: 'cke_editor_' + editor.name.replace( /\./g, '\\.' ) + '_dialog',\r
+                       closeTitle: editor.lang.common.close,\r
+                       hidpi: CKEDITOR.env.hidpi ? 'cke_hidpi' : ''\r
+               } ) );\r
+\r
+               // TODO: Change this to getById(), so it'll support custom templates.\r
+               var body = element.getChild( [ 0, 0, 0, 0, 0 ] ),\r
+                       title = body.getChild( 0 ),\r
+                       close = body.getChild( 1 );\r
+\r
+               // Don't allow dragging on dialog (#13184).\r
+               editor.plugins.clipboard && CKEDITOR.plugins.clipboard.preventDefaultDropOnElement( body );\r
+\r
+               // IFrame shim for dialog that masks activeX in IE. (#7619)\r
+               if ( CKEDITOR.env.ie && !CKEDITOR.env.quirks && !CKEDITOR.env.edge ) {\r
+                       var src = 'javascript:void(function(){' + encodeURIComponent( 'document.open();(' + CKEDITOR.tools.fixDomain + ')();document.close();' ) + '}())', // jshint ignore:line\r
+                               iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +\r
+                                       ' frameBorder="0"' +\r
+                                       ' class="cke_iframe_shim"' +\r
+                                       ' src="' + src + '"' +\r
+                                       ' tabIndex="-1"' +\r
+                                       '></iframe>' );\r
+                       iframe.appendTo( body.getParent() );\r
+               }\r
+\r
+               // Make the Title and Close Button unselectable.\r
+               title.unselectable();\r
+               close.unselectable();\r
+\r
+               return {\r
+                       element: element,\r
+                       parts: {\r
+                               dialog: element.getChild( 0 ),\r
+                               title: title,\r
+                               close: close,\r
+                               tabs: body.getChild( 2 ),\r
+                               contents: body.getChild( [ 3, 0, 0, 0 ] ),\r
+                               footer: body.getChild( [ 3, 0, 1, 0 ] )\r
+                       }\r
+               };\r
+       }\r
+\r
+       /**\r
+        * This is the base class for runtime dialog objects. An instance of this\r
+        * class represents a single named dialog for a single editor instance.\r
+        *\r
+        *              var dialogObj = new CKEDITOR.dialog( editor, 'smiley' );\r
+        *\r
+        * @class\r
+        * @constructor Creates a dialog class instance.\r
+        * @param {Object} editor The editor which created the dialog.\r
+        * @param {String} dialogName The dialog's registered name.\r
+        */\r
+       CKEDITOR.dialog = function( editor, dialogName ) {\r
+               // Load the dialog definition.\r
+               var definition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ],\r
+                       defaultDefinition = CKEDITOR.tools.clone( defaultDialogDefinition ),\r
+                       buttonsOrder = editor.config.dialog_buttonsOrder || 'OS',\r
+                       dir = editor.lang.dir,\r
+                       tabsToRemove = {},\r
+                       i, processed, stopPropagation;\r
+\r
+               if ( ( buttonsOrder == 'OS' && CKEDITOR.env.mac ) || // The buttons in MacOS Apps are in reverse order (#4750)\r
+               ( buttonsOrder == 'rtl' && dir == 'ltr' ) || ( buttonsOrder == 'ltr' && dir == 'rtl' ) )\r
+                       defaultDefinition.buttons.reverse();\r
+\r
+\r
+               // Completes the definition with the default values.\r
+               definition = CKEDITOR.tools.extend( definition( editor ), defaultDefinition );\r
+\r
+               // Clone a functionally independent copy for this dialog.\r
+               definition = CKEDITOR.tools.clone( definition );\r
+\r
+               // Create a complex definition object, extending it with the API\r
+               // functions.\r
+               definition = new definitionObject( this, definition );\r
+\r
+               var themeBuilt = buildDialog( editor );\r
+\r
+               // Initialize some basic parameters.\r
+               this._ = {\r
+                       editor: editor,\r
+                       element: themeBuilt.element,\r
+                       name: dialogName,\r
+                       contentSize: { width: 0, height: 0 },\r
+                       size: { width: 0, height: 0 },\r
+                       contents: {},\r
+                       buttons: {},\r
+                       accessKeyMap: {},\r
+\r
+                       // Initialize the tab and page map.\r
+                       tabs: {},\r
+                       tabIdList: [],\r
+                       currentTabId: null,\r
+                       currentTabIndex: null,\r
+                       pageCount: 0,\r
+                       lastTab: null,\r
+                       tabBarMode: false,\r
+\r
+                       // Initialize the tab order array for input widgets.\r
+                       focusList: [],\r
+                       currentFocusIndex: 0,\r
+                       hasFocus: false\r
+               };\r
+\r
+               this.parts = themeBuilt.parts;\r
+\r
+               CKEDITOR.tools.setTimeout( function() {\r
+                       editor.fire( 'ariaWidget', this.parts.contents );\r
+               }, 0, this );\r
+\r
+               // Set the startup styles for the dialog, avoiding it enlarging the\r
+               // page size on the dialog creation.\r
+               var startStyles = {\r
+                       position: CKEDITOR.env.ie6Compat ? 'absolute' : 'fixed',\r
+                       top: 0,\r
+                       visibility: 'hidden'\r
+               };\r
+\r
+               startStyles[ dir == 'rtl' ? 'right' : 'left' ] = 0;\r
+               this.parts.dialog.setStyles( startStyles );\r
+\r
+\r
+               // Call the CKEDITOR.event constructor to initialize this instance.\r
+               CKEDITOR.event.call( this );\r
+\r
+               // Fire the "dialogDefinition" event, making it possible to customize\r
+               // the dialog definition.\r
+               this.definition = definition = CKEDITOR.fire( 'dialogDefinition', {\r
+                       name: dialogName,\r
+                       definition: definition\r
+               }, editor ).definition;\r
+\r
+               // Cache tabs that should be removed.\r
+               if ( !( 'removeDialogTabs' in editor._ ) && editor.config.removeDialogTabs ) {\r
+                       var removeContents = editor.config.removeDialogTabs.split( ';' );\r
+\r
+                       for ( i = 0; i < removeContents.length; i++ ) {\r
+                               var parts = removeContents[ i ].split( ':' );\r
+                               if ( parts.length == 2 ) {\r
+                                       var removeDialogName = parts[ 0 ];\r
+                                       if ( !tabsToRemove[ removeDialogName ] )\r
+                                               tabsToRemove[ removeDialogName ] = [];\r
+                                       tabsToRemove[ removeDialogName ].push( parts[ 1 ] );\r
+                               }\r
+                       }\r
+                       editor._.removeDialogTabs = tabsToRemove;\r
+               }\r
+\r
+               // Remove tabs of this dialog.\r
+               if ( editor._.removeDialogTabs && ( tabsToRemove = editor._.removeDialogTabs[ dialogName ] ) ) {\r
+                       for ( i = 0; i < tabsToRemove.length; i++ )\r
+                               definition.removeContents( tabsToRemove[ i ] );\r
+               }\r
+\r
+               // Initialize load, show, hide, ok and cancel events.\r
+               if ( definition.onLoad )\r
+                       this.on( 'load', definition.onLoad );\r
+\r
+               if ( definition.onShow )\r
+                       this.on( 'show', definition.onShow );\r
+\r
+               if ( definition.onHide )\r
+                       this.on( 'hide', definition.onHide );\r
+\r
+               if ( definition.onOk ) {\r
+                       this.on( 'ok', function( evt ) {\r
+                               // Dialog confirm might probably introduce content changes (#5415).\r
+                               editor.fire( 'saveSnapshot' );\r
+                               setTimeout( function() {\r
+                                       editor.fire( 'saveSnapshot' );\r
+                               }, 0 );\r
+                               if ( definition.onOk.call( this, evt ) === false )\r
+                                       evt.data.hide = false;\r
+                       } );\r
+               }\r
+\r
+               // Set default dialog state.\r
+               this.state = CKEDITOR.DIALOG_STATE_IDLE;\r
+\r
+               if ( definition.onCancel ) {\r
+                       this.on( 'cancel', function( evt ) {\r
+                               if ( definition.onCancel.call( this, evt ) === false )\r
+                                       evt.data.hide = false;\r
+                       } );\r
+               }\r
+\r
+               var me = this;\r
+\r
+               // Iterates over all items inside all content in the dialog, calling a\r
+               // function for each of them.\r
+               var iterContents = function( func ) {\r
+                               var contents = me._.contents,\r
+                                       stop = false;\r
+\r
+                               for ( var i in contents ) {\r
+                                       for ( var j in contents[ i ] ) {\r
+                                               stop = func.call( this, contents[ i ][ j ] );\r
+                                               if ( stop )\r
+                                                       return;\r
+                                       }\r
+                               }\r
+                       };\r
+\r
+               this.on( 'ok', function( evt ) {\r
+                       iterContents( function( item ) {\r
+                               if ( item.validate ) {\r
+                                       var retval = item.validate( this ),\r
+                                               invalid = ( typeof retval == 'string' ) || retval === false;\r
+\r
+                                       if ( invalid ) {\r
+                                               evt.data.hide = false;\r
+                                               evt.stop();\r
+                                       }\r
+\r
+                                       handleFieldValidated.call( item, !invalid, typeof retval == 'string' ? retval : undefined );\r
+                                       return invalid;\r
+                               }\r
+                       } );\r
+               }, this, null, 0 );\r
+\r
+               this.on( 'cancel', function( evt ) {\r
+                       iterContents( function( item ) {\r
+                               if ( item.isChanged() ) {\r
+                                       if ( !editor.config.dialog_noConfirmCancel && !confirm( editor.lang.common.confirmCancel ) ) // jshint ignore:line\r
+                                               evt.data.hide = false;\r
+                                       return true;\r
+                               }\r
+                       } );\r
+               }, this, null, 0 );\r
+\r
+               this.parts.close.on( 'click', function( evt ) {\r
+                       if ( this.fire( 'cancel', { hide: true } ).hide !== false )\r
+                               this.hide();\r
+                       evt.data.preventDefault();\r
+               }, this );\r
+\r
+               // Sort focus list according to tab order definitions.\r
+               function setupFocus() {\r
+                       var focusList = me._.focusList;\r
+                       focusList.sort( function( a, b ) {\r
+                               // Mimics browser tab order logics;\r
+                               if ( a.tabIndex != b.tabIndex )\r
+                                       return b.tabIndex - a.tabIndex;\r
+                               //  Sort is not stable in some browsers,\r
+                               // fall-back the comparator to 'focusIndex';\r
+                               else\r
+                                       return a.focusIndex - b.focusIndex;\r
+                       } );\r
+\r
+                       var size = focusList.length;\r
+                       for ( var i = 0; i < size; i++ )\r
+                               focusList[ i ].focusIndex = i;\r
+               }\r
+\r
+               // Expects 1 or -1 as an offset, meaning direction of the offset change.\r
+               function changeFocus( offset ) {\r
+                       var focusList = me._.focusList;\r
+                       offset = offset || 0;\r
+\r
+                       if ( focusList.length < 1 )\r
+                               return;\r
+\r
+                       var startIndex = me._.currentFocusIndex;\r
+\r
+                       if ( me._.tabBarMode && offset < 0 ) {\r
+                               // If we are in tab mode, we need to mimic that we started tabbing back from the first\r
+                               // focusList (so it will go to the last one).\r
+                               startIndex = 0;\r
+                       }\r
+\r
+                       // Trigger the 'blur' event of  any input element before anything,\r
+                       // since certain UI updates may depend on it.\r
+                       try {\r
+                               focusList[ startIndex ].getInputElement().$.blur();\r
+                       } catch ( e ) {}\r
+\r
+                       var currentIndex = startIndex,\r
+                               hasTabs = me._.pageCount > 1;\r
+\r
+                       do {\r
+                               currentIndex = currentIndex + offset;\r
+\r
+                               if ( hasTabs && !me._.tabBarMode && ( currentIndex == focusList.length || currentIndex == -1 ) ) {\r
+                                       // If the dialog was not in tab mode, then focus the first tab (#13027).\r
+                                       me._.tabBarMode = true;\r
+                                       me._.tabs[ me._.currentTabId ][ 0 ].focus();\r
+                                       me._.currentFocusIndex = -1;\r
+\r
+                                       // Early return, in order to avoid accessing focusList[ -1 ].\r
+                                       return;\r
+                               }\r
+\r
+                               currentIndex = ( currentIndex + focusList.length ) % focusList.length;\r
+\r
+                               if ( currentIndex == startIndex ) {\r
+                                       break;\r
+                               }\r
+                       } while ( offset && !focusList[ currentIndex ].isFocusable() );\r
+\r
+                       focusList[ currentIndex ].focus();\r
+\r
+                       // Select whole field content.\r
+                       if ( focusList[ currentIndex ].type == 'text' )\r
+                               focusList[ currentIndex ].select();\r
+               }\r
+\r
+               this.changeFocus = changeFocus;\r
+\r
+\r
+               function keydownHandler( evt ) {\r
+                       // If I'm not the top dialog, ignore.\r
+                       if ( me != CKEDITOR.dialog._.currentTop )\r
+                               return;\r
+\r
+                       var keystroke = evt.data.getKeystroke(),\r
+                               rtl = editor.lang.dir == 'rtl',\r
+                               arrowKeys = [ 37, 38, 39, 40 ],\r
+                               button;\r
+\r
+                       processed = stopPropagation = 0;\r
+\r
+                       if ( keystroke == 9 || keystroke == CKEDITOR.SHIFT + 9 ) {\r
+                               var shiftPressed = ( keystroke == CKEDITOR.SHIFT + 9 );\r
+                               changeFocus( shiftPressed ? -1 : 1 );\r
+                               processed = 1;\r
+                       } else if ( keystroke == CKEDITOR.ALT + 121 && !me._.tabBarMode && me.getPageCount() > 1 ) {\r
+                               // Alt-F10 puts focus into the current tab item in the tab bar.\r
+                               me._.tabBarMode = true;\r
+                               me._.tabs[ me._.currentTabId ][ 0 ].focus();\r
+                               me._.currentFocusIndex = -1;\r
+                               processed = 1;\r
+                       } else if ( CKEDITOR.tools.indexOf( arrowKeys, keystroke ) != -1 && me._.tabBarMode ) {\r
+                               // Array with key codes that activate previous tab.\r
+                               var prevKeyCodes = [\r
+                                               // Depending on the lang dir: right or left key\r
+                                               rtl ? 39 : 37,\r
+                                               // Top/bot arrow: actually for both cases it's the same.\r
+                                               38\r
+                                       ],\r
+                                       nextId = CKEDITOR.tools.indexOf( prevKeyCodes, keystroke ) != -1 ? getPreviousVisibleTab.call( me ) : getNextVisibleTab.call( me );\r
+\r
+                               me.selectPage( nextId );\r
+                               me._.tabs[ nextId ][ 0 ].focus();\r
+                               processed = 1;\r
+                       } else if ( ( keystroke == 13 || keystroke == 32 ) && me._.tabBarMode ) {\r
+                               this.selectPage( this._.currentTabId );\r
+                               this._.tabBarMode = false;\r
+                               this._.currentFocusIndex = -1;\r
+                               changeFocus( 1 );\r
+                               processed = 1;\r
+                       }\r
+                       // If user presses enter key in a text box, it implies clicking OK for the dialog.\r
+                       else if ( keystroke == 13 /*ENTER*/ ) {\r
+                               // Don't do that for a target that handles ENTER.\r
+                               var target = evt.data.getTarget();\r
+                               if ( !target.is( 'a', 'button', 'select', 'textarea' ) && ( !target.is( 'input' ) || target.$.type != 'button' ) ) {\r
+                                       button = this.getButton( 'ok' );\r
+                                       button && CKEDITOR.tools.setTimeout( button.click, 0, button );\r
+                                       processed = 1;\r
+                               }\r
+                               stopPropagation = 1; // Always block the propagation (#4269)\r
+                       } else if ( keystroke == 27 /*ESC*/ ) {\r
+                               button = this.getButton( 'cancel' );\r
+\r
+                               // If there's a Cancel button, click it, else just fire the cancel event and hide the dialog.\r
+                               if ( button )\r
+                                       CKEDITOR.tools.setTimeout( button.click, 0, button );\r
+                               else {\r
+                                       if ( this.fire( 'cancel', { hide: true } ).hide !== false )\r
+                                               this.hide();\r
+                               }\r
+                               stopPropagation = 1; // Always block the propagation (#4269)\r
+                       } else {\r
+                               return;\r
+                       }\r
+\r
+                       keypressHandler( evt );\r
+               }\r
+\r
+               function keypressHandler( evt ) {\r
+                       if ( processed )\r
+                               evt.data.preventDefault( 1 );\r
+                       else if ( stopPropagation )\r
+                               evt.data.stopPropagation();\r
+               }\r
+\r
+               var dialogElement = this._.element;\r
+\r
+               editor.focusManager.add( dialogElement, 1 );\r
+\r
+               // Add the dialog keyboard handlers.\r
+               this.on( 'show', function() {\r
+                       dialogElement.on( 'keydown', keydownHandler, this );\r
+\r
+                       // Some browsers instead, don't cancel key events in the keydown, but in the\r
+                       // keypress. So we must do a longer trip in those cases. (#4531,#8985)\r
+                       if ( CKEDITOR.env.gecko )\r
+                               dialogElement.on( 'keypress', keypressHandler, this );\r
+\r
+               } );\r
+               this.on( 'hide', function() {\r
+                       dialogElement.removeListener( 'keydown', keydownHandler );\r
+                       if ( CKEDITOR.env.gecko )\r
+                               dialogElement.removeListener( 'keypress', keypressHandler );\r
+\r
+                       // Reset fields state when closing dialog.\r
+                       iterContents( function( item ) {\r
+                               resetField.apply( item );\r
+                       } );\r
+               } );\r
+               this.on( 'iframeAdded', function( evt ) {\r
+                       var doc = new CKEDITOR.dom.document( evt.data.iframe.$.contentWindow.document );\r
+                       doc.on( 'keydown', keydownHandler, this, null, 0 );\r
+               } );\r
+\r
+               // Auto-focus logic in dialog.\r
+               this.on( 'show', function() {\r
+                       // Setup tabIndex on showing the dialog instead of on loading\r
+                       // to allow dynamic tab order happen in dialog definition.\r
+                       setupFocus();\r
+\r
+                       var hasTabs = me._.pageCount > 1;\r
+\r
+                       if ( editor.config.dialog_startupFocusTab && hasTabs ) {\r
+                               me._.tabBarMode = true;\r
+                               me._.tabs[ me._.currentTabId ][ 0 ].focus();\r
+                               me._.currentFocusIndex = -1;\r
+                       } else if ( !this._.hasFocus ) {\r
+                               // http://dev.ckeditor.com/ticket/13114#comment:4.\r
+                               this._.currentFocusIndex = hasTabs ? -1 : this._.focusList.length - 1;\r
+\r
+                               // Decide where to put the initial focus.\r
+                               if ( definition.onFocus ) {\r
+                                       var initialFocus = definition.onFocus.call( this );\r
+                                       // Focus the field that the user specified.\r
+                                       initialFocus && initialFocus.focus();\r
+                               }\r
+                               // Focus the first field in layout order.\r
+                               else {\r
+                                       changeFocus( 1 );\r
+                               }\r
+                       }\r
+               }, this, null, 0xffffffff );\r
+\r
+               // IE6 BUG: Text fields and text areas are only half-rendered the first time the dialog appears in IE6 (#2661).\r
+               // This is still needed after [2708] and [2709] because text fields in hidden TR tags are still broken.\r
+               if ( CKEDITOR.env.ie6Compat ) {\r
+                       this.on( 'load', function() {\r
+                               var outer = this.getElement(),\r
+                                       inner = outer.getFirst();\r
+                               inner.remove();\r
+                               inner.appendTo( outer );\r
+                       }, this );\r
+               }\r
+\r
+               initDragAndDrop( this );\r
+               initResizeHandles( this );\r
+\r
+               // Insert the title.\r
+               ( new CKEDITOR.dom.text( definition.title, CKEDITOR.document ) ).appendTo( this.parts.title );\r
+\r
+               // Insert the tabs and contents.\r
+               for ( i = 0; i < definition.contents.length; i++ ) {\r
+                       var page = definition.contents[ i ];\r
+                       page && this.addPage( page );\r
+               }\r
+\r
+               this.parts.tabs.on( 'click', function( evt ) {\r
+                       var target = evt.data.getTarget();\r
+                       // If we aren't inside a tab, bail out.\r
+                       if ( target.hasClass( 'cke_dialog_tab' ) ) {\r
+                               // Get the ID of the tab, without the 'cke_' prefix and the unique number suffix.\r
+                               var id = target.$.id;\r
+                               this.selectPage( id.substring( 4, id.lastIndexOf( '_' ) ) );\r
+\r
+                               if ( this._.tabBarMode ) {\r
+                                       this._.tabBarMode = false;\r
+                                       this._.currentFocusIndex = -1;\r
+                                       changeFocus( 1 );\r
+                               }\r
+                               evt.data.preventDefault();\r
+                       }\r
+               }, this );\r
+\r
+               // Insert buttons.\r
+               var buttonsHtml = [],\r
+                       buttons = CKEDITOR.dialog._.uiElementBuilders.hbox.build( this, {\r
+                               type: 'hbox',\r
+                               className: 'cke_dialog_footer_buttons',\r
+                               widths: [],\r
+                               children: definition.buttons\r
+                       }, buttonsHtml ).getChild();\r
+               this.parts.footer.setHtml( buttonsHtml.join( '' ) );\r
+\r
+               for ( i = 0; i < buttons.length; i++ )\r
+                       this._.buttons[ buttons[ i ].id ] = buttons[ i ];\r
+\r
+               /**\r
+                * Current state of the dialog. Use the {@link #setState} method to update it.\r
+                * See the {@link #event-state} event to know more.\r
+                *\r
+                * @readonly\r
+                * @property {Number} [state=CKEDITOR.DIALOG_STATE_IDLE]\r
+                */\r
+       };\r
+\r
+       // Focusable interface. Use it via dialog.addFocusable.\r
+       function Focusable( dialog, element, index ) {\r
+               this.element = element;\r
+               this.focusIndex = index;\r
+               // TODO: support tabIndex for focusables.\r
+               this.tabIndex = 0;\r
+               this.isFocusable = function() {\r
+                       return !element.getAttribute( 'disabled' ) && element.isVisible();\r
+               };\r
+               this.focus = function() {\r
+                       dialog._.currentFocusIndex = this.focusIndex;\r
+                       this.element.focus();\r
+               };\r
+               // Bind events\r
+               element.on( 'keydown', function( e ) {\r
+                       if ( e.data.getKeystroke() in { 32: 1, 13: 1 } )\r
+                               this.fire( 'click' );\r
+               } );\r
+               element.on( 'focus', function() {\r
+                       this.fire( 'mouseover' );\r
+               } );\r
+               element.on( 'blur', function() {\r
+                       this.fire( 'mouseout' );\r
+               } );\r
+       }\r
+\r
+       // Re-layout the dialog on window resize.\r
+       function resizeWithWindow( dialog ) {\r
+               var win = CKEDITOR.document.getWindow();\r
+               function resizeHandler() {\r
+                       dialog.layout();\r
+               }\r
+               win.on( 'resize', resizeHandler );\r
+               dialog.on( 'hide', function() {\r
+                       win.removeListener( 'resize', resizeHandler );\r
+               } );\r
+       }\r
+\r
+       CKEDITOR.dialog.prototype = {\r
+               destroy: function() {\r
+                       this.hide();\r
+                       this._.element.remove();\r
+               },\r
+\r
+               /**\r
+                * Resizes the dialog.\r
+                *\r
+                *              dialogObj.resize( 800, 640 );\r
+                *\r
+                * @method\r
+                * @param {Number} width The width of the dialog in pixels.\r
+                * @param {Number} height The height of the dialog in pixels.\r
+                */\r
+               resize: ( function() {\r
+                       return function( width, height ) {\r
+                               if ( this._.contentSize && this._.contentSize.width == width && this._.contentSize.height == height )\r
+                                       return;\r
+\r
+                               CKEDITOR.dialog.fire( 'resize', {\r
+                                       dialog: this,\r
+                                       width: width,\r
+                                       height: height\r
+                               }, this._.editor );\r
+\r
+                               this.fire( 'resize', {\r
+                                       width: width,\r
+                                       height: height\r
+                               }, this._.editor );\r
+\r
+                               var contents = this.parts.contents;\r
+                               contents.setStyles( {\r
+                                       width: width + 'px',\r
+                                       height: height + 'px'\r
+                               } );\r
+\r
+                               // Update dialog position when dimension get changed in RTL.\r
+                               if ( this._.editor.lang.dir == 'rtl' && this._.position )\r
+                                       this._.position.x = CKEDITOR.document.getWindow().getViewPaneSize().width - this._.contentSize.width - parseInt( this._.element.getFirst().getStyle( 'right' ), 10 );\r
+\r
+                               this._.contentSize = { width: width, height: height };\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Gets the current size of the dialog in pixels.\r
+                *\r
+                * var width = dialogObj.getSize().width;\r
+                *\r
+                * @returns {Object}\r
+                * @returns {Number} return.width\r
+                * @returns {Number} return.height\r
+                */\r
+               getSize: function() {\r
+                       var element = this._.element.getFirst();\r
+                       return { width: element.$.offsetWidth || 0, height: element.$.offsetHeight || 0 };\r
+               },\r
+\r
+               /**\r
+                * Moves the dialog to an `(x, y)` coordinate relative to the window.\r
+                *\r
+                * dialogObj.move( 10, 40 );\r
+                *\r
+                * @method\r
+                * @param {Number} x The target x-coordinate.\r
+                * @param {Number} y The target y-coordinate.\r
+                * @param {Boolean} save Flag indicate whether the dialog position should be remembered on next open up.\r
+                */\r
+               move: function( x, y, save ) {\r
+\r
+                       // The dialog may be fixed positioned or absolute positioned. Ask the\r
+                       // browser what is the current situation first.\r
+                       var element = this._.element.getFirst(), rtl = this._.editor.lang.dir == 'rtl';\r
+                       var isFixed = element.getComputedStyle( 'position' ) == 'fixed';\r
+\r
+                       // (#8888) In some cases of a very small viewport, dialog is incorrectly\r
+                       // positioned in IE7. It also happens that it remains sticky and user cannot\r
+                       // scroll down/up to reveal dialog's content below/above the viewport; this is\r
+                       // cumbersome.\r
+                       // The only way to fix this is to move mouse out of the browser and\r
+                       // go back to see that dialog position is automagically fixed. No events,\r
+                       // no style change - pure magic. This is a IE7 rendering issue, which can be\r
+                       // fixed with dummy style redraw on each move.\r
+                       if ( CKEDITOR.env.ie )\r
+                               element.setStyle( 'zoom', '100%' );\r
+\r
+                       if ( isFixed && this._.position && this._.position.x == x && this._.position.y == y )\r
+                               return;\r
+\r
+                       // Save the current position.\r
+                       this._.position = { x: x, y: y };\r
+\r
+                       // If not fixed positioned, add scroll position to the coordinates.\r
+                       if ( !isFixed ) {\r
+                               var scrollPosition = CKEDITOR.document.getWindow().getScrollPosition();\r
+                               x += scrollPosition.x;\r
+                               y += scrollPosition.y;\r
+                       }\r
+\r
+                       // Translate coordinate for RTL.\r
+                       if ( rtl ) {\r
+                               var dialogSize = this.getSize(), viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize();\r
+                               x = viewPaneSize.width - dialogSize.width - x;\r
+                       }\r
+\r
+                       var styles = { 'top': ( y > 0 ? y : 0 ) + 'px' };\r
+                       styles[ rtl ? 'right' : 'left' ] = ( x > 0 ? x : 0 ) + 'px';\r
+\r
+                       element.setStyles( styles );\r
+\r
+                       save && ( this._.moved = 1 );\r
+               },\r
+\r
+               /**\r
+                * Gets the dialog's position in the window.\r
+                *\r
+                *              var dialogX = dialogObj.getPosition().x;\r
+                *\r
+                * @returns {Object}\r
+                * @returns {Number} return.x\r
+                * @returns {Number} return.y\r
+                */\r
+               getPosition: function() {\r
+                       return CKEDITOR.tools.extend( {}, this._.position );\r
+               },\r
+\r
+               /**\r
+                * Shows the dialog box.\r
+                *\r
+                *              dialogObj.show();\r
+                */\r
+               show: function() {\r
+                       // Insert the dialog's element to the root document.\r
+                       var element = this._.element;\r
+                       var definition = this.definition;\r
+                       if ( !( element.getParent() && element.getParent().equals( CKEDITOR.document.getBody() ) ) )\r
+                               element.appendTo( CKEDITOR.document.getBody() );\r
+                       else\r
+                               element.setStyle( 'display', 'block' );\r
+\r
+                       // First, set the dialog to an appropriate size.\r
+                       this.resize(\r
+                               this._.contentSize && this._.contentSize.width || definition.width || definition.minWidth,\r
+                               this._.contentSize && this._.contentSize.height || definition.height || definition.minHeight\r
+                       );\r
+\r
+                       // Reset all inputs back to their default value.\r
+                       this.reset();\r
+\r
+                       // Select the first tab by default.\r
+                       this.selectPage( this.definition.contents[ 0 ].id );\r
+\r
+                       // Set z-index.\r
+                       if ( CKEDITOR.dialog._.currentZIndex === null )\r
+                               CKEDITOR.dialog._.currentZIndex = this._.editor.config.baseFloatZIndex;\r
+                       this._.element.getFirst().setStyle( 'z-index', CKEDITOR.dialog._.currentZIndex += 10 );\r
+\r
+                       // Maintain the dialog ordering and dialog cover.\r
+                       if ( CKEDITOR.dialog._.currentTop === null ) {\r
+                               CKEDITOR.dialog._.currentTop = this;\r
+                               this._.parentDialog = null;\r
+                               showCover( this._.editor );\r
+\r
+                       } else {\r
+                               this._.parentDialog = CKEDITOR.dialog._.currentTop;\r
+                               var parentElement = this._.parentDialog.getElement().getFirst();\r
+                               parentElement.$.style.zIndex -= Math.floor( this._.editor.config.baseFloatZIndex / 2 );\r
+                               CKEDITOR.dialog._.currentTop = this;\r
+                       }\r
+\r
+                       element.on( 'keydown', accessKeyDownHandler );\r
+                       element.on( 'keyup', accessKeyUpHandler );\r
+\r
+                       // Reset the hasFocus state.\r
+                       this._.hasFocus = false;\r
+\r
+                       for ( var i in definition.contents ) {\r
+                               if ( !definition.contents[ i ] )\r
+                                       continue;\r
+\r
+                               var content = definition.contents[ i ],\r
+                                       tab = this._.tabs[ content.id ],\r
+                                       requiredContent = content.requiredContent,\r
+                                       enableElements = 0;\r
+\r
+                               if ( !tab )\r
+                                       continue;\r
+\r
+                               for ( var j in this._.contents[ content.id ] ) {\r
+                                       var elem = this._.contents[ content.id ][ j ];\r
+\r
+                                       if ( elem.type == 'hbox' || elem.type == 'vbox' || !elem.getInputElement() )\r
+                                               continue;\r
+\r
+                                       if ( elem.requiredContent && !this._.editor.activeFilter.check( elem.requiredContent ) )\r
+                                               elem.disable();\r
+                                       else {\r
+                                               elem.enable();\r
+                                               enableElements++;\r
+                                       }\r
+                               }\r
+\r
+                               if ( !enableElements || ( requiredContent && !this._.editor.activeFilter.check( requiredContent ) ) )\r
+                                       tab[ 0 ].addClass( 'cke_dialog_tab_disabled' );\r
+                               else\r
+                                       tab[ 0 ].removeClass( 'cke_dialog_tab_disabled' );\r
+                       }\r
+\r
+                       CKEDITOR.tools.setTimeout( function() {\r
+                               this.layout();\r
+                               resizeWithWindow( this );\r
+\r
+                               this.parts.dialog.setStyle( 'visibility', '' );\r
+\r
+                               // Execute onLoad for the first show.\r
+                               this.fireOnce( 'load', {} );\r
+                               CKEDITOR.ui.fire( 'ready', this );\r
+\r
+                               this.fire( 'show', {} );\r
+                               this._.editor.fire( 'dialogShow', this );\r
+\r
+                               if ( !this._.parentDialog )\r
+                                       this._.editor.focusManager.lock();\r
+\r
+                               // Save the initial values of the dialog.\r
+                               this.foreach( function( contentObj ) {\r
+                                       contentObj.setInitValue && contentObj.setInitValue();\r
+                               } );\r
+\r
+                       }, 100, this );\r
+               },\r
+\r
+               /**\r
+                * Rearrange the dialog to its previous position or the middle of the window.\r
+                *\r
+                * @since 3.5\r
+                */\r
+               layout: function() {\r
+                       var el = this.parts.dialog;\r
+                       var dialogSize = this.getSize();\r
+                       var win = CKEDITOR.document.getWindow(),\r
+                                       viewSize = win.getViewPaneSize();\r
+\r
+                       var posX = ( viewSize.width - dialogSize.width ) / 2,\r
+                               posY = ( viewSize.height - dialogSize.height ) / 2;\r
+\r
+                       // Switch to absolute position when viewport is smaller than dialog size.\r
+                       if ( !CKEDITOR.env.ie6Compat ) {\r
+                               if ( dialogSize.height + ( posY > 0 ? posY : 0 ) > viewSize.height || dialogSize.width + ( posX > 0 ? posX : 0 ) > viewSize.width ) {\r
+                                       el.setStyle( 'position', 'absolute' );\r
+                               } else {\r
+                                       el.setStyle( 'position', 'fixed' );\r
+                               }\r
+                       }\r
+\r
+                       this.move( this._.moved ? this._.position.x : posX, this._.moved ? this._.position.y : posY );\r
+               },\r
+\r
+               /**\r
+                * Executes a function for each UI element.\r
+                *\r
+                * @param {Function} fn Function to execute for each UI element.\r
+                * @returns {CKEDITOR.dialog} The current dialog object.\r
+                */\r
+               foreach: function( fn ) {\r
+                       for ( var i in this._.contents ) {\r
+                               for ( var j in this._.contents[ i ] ) {\r
+                                       fn.call( this, this._.contents[i][j] );\r
+                               }\r
+                       }\r
+\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Resets all input values in the dialog.\r
+                *\r
+                *              dialogObj.reset();\r
+                *\r
+                * @method\r
+                * @chainable\r
+                */\r
+               reset: ( function() {\r
+                       var fn = function( widget ) {\r
+                                       if ( widget.reset )\r
+                                               widget.reset( 1 );\r
+                               };\r
+                       return function() {\r
+                               this.foreach( fn );\r
+                               return this;\r
+                       };\r
+               } )(),\r
+\r
+\r
+               /**\r
+                * Calls the {@link CKEDITOR.dialog.definition.uiElement#setup} method of each\r
+                * of the UI elements, with the arguments passed through it.\r
+                * It is usually being called when the dialog is opened, to put the initial value inside the field.\r
+                *\r
+                *              dialogObj.setupContent();\r
+                *\r
+                *              var timestamp = ( new Date() ).valueOf();\r
+                *              dialogObj.setupContent( timestamp );\r
+                */\r
+               setupContent: function() {\r
+                       var args = arguments;\r
+                       this.foreach( function( widget ) {\r
+                               if ( widget.setup )\r
+                                       widget.setup.apply( widget, args );\r
+                       } );\r
+               },\r
+\r
+               /**\r
+                * Calls the {@link CKEDITOR.dialog.definition.uiElement#commit} method of each\r
+                * of the UI elements, with the arguments passed through it.\r
+                * It is usually being called when the user confirms the dialog, to process the values.\r
+                *\r
+                *              dialogObj.commitContent();\r
+                *\r
+                *              var timestamp = ( new Date() ).valueOf();\r
+                *              dialogObj.commitContent( timestamp );\r
+                */\r
+               commitContent: function() {\r
+                       var args = arguments;\r
+                       this.foreach( function( widget ) {\r
+                               // Make sure IE triggers "change" event on last focused input before closing the dialog. (#7915)\r
+                               if ( CKEDITOR.env.ie && this._.currentFocusIndex == widget.focusIndex )\r
+                                       widget.getInputElement().$.blur();\r
+\r
+                               if ( widget.commit )\r
+                                       widget.commit.apply( widget, args );\r
+                       } );\r
+               },\r
+\r
+               /**\r
+                * Hides the dialog box.\r
+                *\r
+                *              dialogObj.hide();\r
+                */\r
+               hide: function() {\r
+                       if ( !this.parts.dialog.isVisible() )\r
+                               return;\r
+\r
+                       this.fire( 'hide', {} );\r
+                       this._.editor.fire( 'dialogHide', this );\r
+                       // Reset the tab page.\r
+                       this.selectPage( this._.tabIdList[ 0 ] );\r
+                       var element = this._.element;\r
+                       element.setStyle( 'display', 'none' );\r
+                       this.parts.dialog.setStyle( 'visibility', 'hidden' );\r
+                       // Unregister all access keys associated with this dialog.\r
+                       unregisterAccessKey( this );\r
+\r
+                       // Close any child(top) dialogs first.\r
+                       while ( CKEDITOR.dialog._.currentTop != this )\r
+                               CKEDITOR.dialog._.currentTop.hide();\r
+\r
+                       // Maintain dialog ordering and remove cover if needed.\r
+                       if ( !this._.parentDialog )\r
+                               hideCover( this._.editor );\r
+                       else {\r
+                               var parentElement = this._.parentDialog.getElement().getFirst();\r
+                               parentElement.setStyle( 'z-index', parseInt( parentElement.$.style.zIndex, 10 ) + Math.floor( this._.editor.config.baseFloatZIndex / 2 ) );\r
+                       }\r
+                       CKEDITOR.dialog._.currentTop = this._.parentDialog;\r
+\r
+                       // Deduct or clear the z-index.\r
+                       if ( !this._.parentDialog ) {\r
+                               CKEDITOR.dialog._.currentZIndex = null;\r
+\r
+                               // Remove access key handlers.\r
+                               element.removeListener( 'keydown', accessKeyDownHandler );\r
+                               element.removeListener( 'keyup', accessKeyUpHandler );\r
+\r
+                               var editor = this._.editor;\r
+                               editor.focus();\r
+\r
+                               // Give a while before unlock, waiting for focus to return to the editable. (#172)\r
+                               setTimeout( function() {\r
+                                       editor.focusManager.unlock();\r
+\r
+                                       // Fixed iOS focus issue (#12381).\r
+                                       // Keep in mind that editor.focus() does not work in this case.\r
+                                       if ( CKEDITOR.env.iOS ) {\r
+                                               editor.window.focus();\r
+                                       }\r
+                               }, 0 );\r
+\r
+                       } else {\r
+                               CKEDITOR.dialog._.currentZIndex -= 10;\r
+                       }\r
+\r
+                       delete this._.parentDialog;\r
+                       // Reset the initial values of the dialog.\r
+                       this.foreach( function( contentObj ) {\r
+                               contentObj.resetInitValue && contentObj.resetInitValue();\r
+                       } );\r
+\r
+                       // Reset dialog state back to IDLE, if busy (#13213).\r
+                       this.setState( CKEDITOR.DIALOG_STATE_IDLE );\r
+               },\r
+\r
+               /**\r
+                * Adds a tabbed page into the dialog.\r
+                *\r
+                * @param {Object} contents Content definition.\r
+                */\r
+               addPage: function( contents ) {\r
+                       if ( contents.requiredContent && !this._.editor.filter.check( contents.requiredContent ) )\r
+                               return;\r
+\r
+                       var pageHtml = [],\r
+                               titleHtml = contents.label ? ' title="' + CKEDITOR.tools.htmlEncode( contents.label ) + '"' : '',\r
+                               vbox = CKEDITOR.dialog._.uiElementBuilders.vbox.build( this, {\r
+                                       type: 'vbox',\r
+                                       className: 'cke_dialog_page_contents',\r
+                                       children: contents.elements,\r
+                                       expand: !!contents.expand,\r
+                                       padding: contents.padding,\r
+                                       style: contents.style || 'width: 100%;'\r
+                               }, pageHtml );\r
+\r
+                       var contentMap = this._.contents[ contents.id ] = {},\r
+                               cursor,\r
+                               children = vbox.getChild(),\r
+                               enabledFields = 0;\r
+\r
+                       while ( ( cursor = children.shift() ) ) {\r
+                               // Count all allowed fields.\r
+                               if ( !cursor.notAllowed && cursor.type != 'hbox' && cursor.type != 'vbox' )\r
+                                       enabledFields++;\r
+\r
+                               contentMap[ cursor.id ] = cursor;\r
+                               if ( typeof cursor.getChild == 'function' )\r
+                                       children.push.apply( children, cursor.getChild() );\r
+                       }\r
+\r
+                       // If all fields are disabled (because they are not allowed) hide this tab.\r
+                       if ( !enabledFields )\r
+                               contents.hidden = true;\r
+\r
+                       // Create the HTML for the tab and the content block.\r
+                       var page = CKEDITOR.dom.element.createFromHtml( pageHtml.join( '' ) );\r
+                       page.setAttribute( 'role', 'tabpanel' );\r
+\r
+                       var env = CKEDITOR.env;\r
+                       var tabId = 'cke_' + contents.id + '_' + CKEDITOR.tools.getNextNumber(),\r
+                               tab = CKEDITOR.dom.element.createFromHtml( [\r
+                                       '<a class="cke_dialog_tab"',\r
+                                       ( this._.pageCount > 0 ? ' cke_last' : 'cke_first' ),\r
+                                       titleHtml,\r
+                                       ( !!contents.hidden ? ' style="display:none"' : '' ),\r
+                                       ' id="', tabId, '"',\r
+                                       env.gecko && !env.hc ? '' : ' href="javascript:void(0)"',\r
+                                       ' tabIndex="-1"',\r
+                                       ' hidefocus="true"',\r
+                                       ' role="tab">',\r
+                                       contents.label,\r
+                                       '</a>'\r
+                               ].join( '' ) );\r
+\r
+                       page.setAttribute( 'aria-labelledby', tabId );\r
+\r
+                       // Take records for the tabs and elements created.\r
+                       this._.tabs[ contents.id ] = [ tab, page ];\r
+                       this._.tabIdList.push( contents.id );\r
+                       !contents.hidden && this._.pageCount++;\r
+                       this._.lastTab = tab;\r
+                       this.updateStyle();\r
+\r
+                       // Attach the DOM nodes.\r
+\r
+                       page.setAttribute( 'name', contents.id );\r
+                       page.appendTo( this.parts.contents );\r
+\r
+                       tab.unselectable();\r
+                       this.parts.tabs.append( tab );\r
+\r
+                       // Add access key handlers if access key is defined.\r
+                       if ( contents.accessKey ) {\r
+                               registerAccessKey( this, this, 'CTRL+' + contents.accessKey, tabAccessKeyDown, tabAccessKeyUp );\r
+                               this._.accessKeyMap[ 'CTRL+' + contents.accessKey ] = contents.id;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Activates a tab page in the dialog by its id.\r
+                *\r
+                *              dialogObj.selectPage( 'tab_1' );\r
+                *\r
+                * @param {String} id The id of the dialog tab to be activated.\r
+                */\r
+               selectPage: function( id ) {\r
+                       if ( this._.currentTabId == id )\r
+                               return;\r
+\r
+                       if ( this._.tabs[ id ][ 0 ].hasClass( 'cke_dialog_tab_disabled' ) )\r
+                               return;\r
+\r
+                       // If event was canceled - do nothing.\r
+                       if ( this.fire( 'selectPage', { page: id, currentPage: this._.currentTabId } ) === false )\r
+                               return;\r
+\r
+                       // Hide the non-selected tabs and pages.\r
+                       for ( var i in this._.tabs ) {\r
+                               var tab = this._.tabs[ i ][ 0 ],\r
+                                       page = this._.tabs[ i ][ 1 ];\r
+                               if ( i != id ) {\r
+                                       tab.removeClass( 'cke_dialog_tab_selected' );\r
+                                       page.hide();\r
+                               }\r
+                               page.setAttribute( 'aria-hidden', i != id );\r
+                       }\r
+\r
+                       var selected = this._.tabs[ id ];\r
+                       selected[ 0 ].addClass( 'cke_dialog_tab_selected' );\r
+\r
+                       // [IE] an invisible input[type='text'] will enlarge it's width\r
+                       // if it's value is long when it shows, so we clear it's value\r
+                       // before it shows and then recover it (#5649)\r
+                       if ( CKEDITOR.env.ie6Compat || CKEDITOR.env.ie7Compat ) {\r
+                               clearOrRecoverTextInputValue( selected[ 1 ] );\r
+                               selected[ 1 ].show();\r
+                               setTimeout( function() {\r
+                                       clearOrRecoverTextInputValue( selected[ 1 ], 1 );\r
+                               }, 0 );\r
+                       } else {\r
+                               selected[ 1 ].show();\r
+                       }\r
+\r
+                       this._.currentTabId = id;\r
+                       this._.currentTabIndex = CKEDITOR.tools.indexOf( this._.tabIdList, id );\r
+               },\r
+\r
+               /**\r
+                * Dialog state-specific style updates.\r
+                */\r
+               updateStyle: function() {\r
+                       // If only a single page shown, a different style is used in the central pane.\r
+                       this.parts.dialog[ ( this._.pageCount === 1 ? 'add' : 'remove' ) + 'Class' ]( 'cke_single_page' );\r
+               },\r
+\r
+               /**\r
+                * Hides a page's tab away from the dialog.\r
+                *\r
+                *              dialog.hidePage( 'tab_3' );\r
+                *\r
+                * @param {String} id The page's Id.\r
+                */\r
+               hidePage: function( id ) {\r
+                       var tab = this._.tabs[ id ] && this._.tabs[ id ][ 0 ];\r
+                       if ( !tab || this._.pageCount == 1 || !tab.isVisible() )\r
+                               return;\r
+                       // Switch to other tab first when we're hiding the active tab.\r
+                       else if ( id == this._.currentTabId )\r
+                               this.selectPage( getPreviousVisibleTab.call( this ) );\r
+\r
+                       tab.hide();\r
+                       this._.pageCount--;\r
+                       this.updateStyle();\r
+               },\r
+\r
+               /**\r
+                * Unhides a page's tab.\r
+                *\r
+                *              dialog.showPage( 'tab_2' );\r
+                *\r
+                * @param {String} id The page's Id.\r
+                */\r
+               showPage: function( id ) {\r
+                       var tab = this._.tabs[ id ] && this._.tabs[ id ][ 0 ];\r
+                       if ( !tab )\r
+                               return;\r
+                       tab.show();\r
+                       this._.pageCount++;\r
+                       this.updateStyle();\r
+               },\r
+\r
+               /**\r
+                * Gets the root DOM element of the dialog.\r
+                *\r
+                *              var dialogElement = dialogObj.getElement().getFirst();\r
+                *              dialogElement.setStyle( 'padding', '5px' );\r
+                *\r
+                * @returns {CKEDITOR.dom.element} The `<span>` element containing this dialog.\r
+                */\r
+               getElement: function() {\r
+                       return this._.element;\r
+               },\r
+\r
+               /**\r
+                * Gets the name of the dialog.\r
+                *\r
+                *              var dialogName = dialogObj.getName();\r
+                *\r
+                * @returns {String} The name of this dialog.\r
+                */\r
+               getName: function() {\r
+                       return this._.name;\r
+               },\r
+\r
+               /**\r
+                * Gets a dialog UI element object from a dialog page.\r
+                *\r
+                *              dialogObj.getContentElement( 'tabId', 'elementId' ).setValue( 'Example' );\r
+                *\r
+                * @param {String} pageId id of dialog page.\r
+                * @param {String} elementId id of UI element.\r
+                * @returns {CKEDITOR.ui.dialog.uiElement} The dialog UI element.\r
+                */\r
+               getContentElement: function( pageId, elementId ) {\r
+                       var page = this._.contents[ pageId ];\r
+                       return page && page[ elementId ];\r
+               },\r
+\r
+               /**\r
+                * Gets the value of a dialog UI element.\r
+                *\r
+                *              alert( dialogObj.getValueOf( 'tabId', 'elementId' ) );\r
+                *\r
+                * @param {String} pageId id of dialog page.\r
+                * @param {String} elementId id of UI element.\r
+                * @returns {Object} The value of the UI element.\r
+                */\r
+               getValueOf: function( pageId, elementId ) {\r
+                       return this.getContentElement( pageId, elementId ).getValue();\r
+               },\r
+\r
+               /**\r
+                * Sets the value of a dialog UI element.\r
+                *\r
+                *              dialogObj.setValueOf( 'tabId', 'elementId', 'Example' );\r
+                *\r
+                * @param {String} pageId id of the dialog page.\r
+                * @param {String} elementId id of the UI element.\r
+                * @param {Object} value The new value of the UI element.\r
+                */\r
+               setValueOf: function( pageId, elementId, value ) {\r
+                       return this.getContentElement( pageId, elementId ).setValue( value );\r
+               },\r
+\r
+               /**\r
+                * Gets the UI element of a button in the dialog's button row.\r
+                *\r
+                *              @returns {CKEDITOR.ui.dialog.button} The button object.\r
+                *\r
+                * @param {String} id The id of the button.\r
+                */\r
+               getButton: function( id ) {\r
+                       return this._.buttons[ id ];\r
+               },\r
+\r
+               /**\r
+                * Simulates a click to a dialog button in the dialog's button row.\r
+                *\r
+                * @returns The return value of the dialog's `click` event.\r
+                *\r
+                * @param {String} id The id of the button.\r
+                */\r
+               click: function( id ) {\r
+                       return this._.buttons[ id ].click();\r
+               },\r
+\r
+               /**\r
+                * Disables a dialog button.\r
+                *\r
+                * @param {String} id The id of the button.\r
+                */\r
+               disableButton: function( id ) {\r
+                       return this._.buttons[ id ].disable();\r
+               },\r
+\r
+               /**\r
+                * Enables a dialog button.\r
+                *\r
+                * @param {String} id The id of the button.\r
+                */\r
+               enableButton: function( id ) {\r
+                       return this._.buttons[ id ].enable();\r
+               },\r
+\r
+               /**\r
+                * Gets the number of pages in the dialog.\r
+                *\r
+                * @returns {Number} Page count.\r
+                */\r
+               getPageCount: function() {\r
+                       return this._.pageCount;\r
+               },\r
+\r
+               /**\r
+                * Gets the editor instance which opened this dialog.\r
+                *\r
+                * @returns {CKEDITOR.editor} Parent editor instances.\r
+                */\r
+               getParentEditor: function() {\r
+                       return this._.editor;\r
+               },\r
+\r
+               /**\r
+                * Gets the element that was selected when opening the dialog, if any.\r
+                *\r
+                * @returns {CKEDITOR.dom.element} The element that was selected, or `null`.\r
+                */\r
+               getSelectedElement: function() {\r
+                       return this.getParentEditor().getSelection().getSelectedElement();\r
+               },\r
+\r
+               /**\r
+                * Adds element to dialog's focusable list.\r
+                *\r
+                * @param {CKEDITOR.dom.element} element\r
+                * @param {Number} [index]\r
+                */\r
+               addFocusable: function( element, index ) {\r
+                       if ( typeof index == 'undefined' ) {\r
+                               index = this._.focusList.length;\r
+                               this._.focusList.push( new Focusable( this, element, index ) );\r
+                       } else {\r
+                               this._.focusList.splice( index, 0, new Focusable( this, element, index ) );\r
+                               for ( var i = index + 1; i < this._.focusList.length; i++ )\r
+                                       this._.focusList[ i ].focusIndex++;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Sets the dialog {@link #property-state}.\r
+                *\r
+                * @since 4.5\r
+                * @param {Number} state Either {@link CKEDITOR#DIALOG_STATE_IDLE} or {@link CKEDITOR#DIALOG_STATE_BUSY}.\r
+                */\r
+               setState: function( state ) {\r
+                       var oldState = this.state;\r
+\r
+                       if ( oldState == state ) {\r
+                               return;\r
+                       }\r
+\r
+                       this.state = state;\r
+\r
+                       if ( state == CKEDITOR.DIALOG_STATE_BUSY ) {\r
+                               // Insert the spinner on demand.\r
+                               if ( !this.parts.spinner ) {\r
+                                       var dir = this.getParentEditor().lang.dir,\r
+                                               spinnerDef = {\r
+                                                       attributes: {\r
+                                                               'class': 'cke_dialog_spinner'\r
+                                                       },\r
+                                                       styles: {\r
+                                                               'float': dir == 'rtl' ? 'right' : 'left'\r
+                                                       }\r
+                                               };\r
+\r
+                                       spinnerDef.styles[ 'margin-' + ( dir == 'rtl' ? 'left' : 'right' ) ] = '8px';\r
+\r
+                                       this.parts.spinner = CKEDITOR.document.createElement( 'div', spinnerDef );\r
+\r
+                                       this.parts.spinner.setHtml( '&#8987;' );\r
+                                       this.parts.spinner.appendTo( this.parts.title, 1 );\r
+                               }\r
+\r
+                               // Finally, show the spinner.\r
+                               this.parts.spinner.show();\r
+\r
+                               this.getButton( 'ok' ).disable();\r
+                       } else if ( state == CKEDITOR.DIALOG_STATE_IDLE ) {\r
+                               // Hide the spinner. But don't do anything if there is no spinner yet.\r
+                               this.parts.spinner && this.parts.spinner.hide();\r
+\r
+                               this.getButton( 'ok' ).enable();\r
+                       }\r
+\r
+                       this.fire( 'state', state );\r
+               }\r
+       };\r
+\r
+       CKEDITOR.tools.extend( CKEDITOR.dialog, {\r
+               /**\r
+                * Registers a dialog.\r
+                *\r
+                *              // Full sample plugin, which does not only register a dialog window but also adds an item to the context menu.\r
+                *              // To open the dialog window, choose "Open dialog" in the context menu.\r
+                *              CKEDITOR.plugins.add( 'myplugin', {\r
+                *                      init: function( editor ) {\r
+                *                              editor.addCommand( 'mydialog',new CKEDITOR.dialogCommand( 'mydialog' ) );\r
+                *\r
+                *                              if ( editor.contextMenu ) {\r
+                *                                      editor.addMenuGroup( 'mygroup', 10 );\r
+                *                                      editor.addMenuItem( 'My Dialog', {\r
+                *                                              label: 'Open dialog',\r
+                *                                              command: 'mydialog',\r
+                *                                              group: 'mygroup'\r
+                *                                      } );\r
+                *                                      editor.contextMenu.addListener( function( element ) {\r
+                *                                              return { 'My Dialog': CKEDITOR.TRISTATE_OFF };\r
+                *                                      } );\r
+                *                              }\r
+                *\r
+                *                              CKEDITOR.dialog.add( 'mydialog', function( api ) {\r
+                *                                      // CKEDITOR.dialog.definition\r
+                *                                      var dialogDefinition = {\r
+                *                                              title: 'Sample dialog',\r
+                *                                              minWidth: 390,\r
+                *                                              minHeight: 130,\r
+                *                                              contents: [\r
+                *                                                      {\r
+                *                                                              id: 'tab1',\r
+                *                                                              label: 'Label',\r
+                *                                                              title: 'Title',\r
+                *                                                              expand: true,\r
+                *                                                              padding: 0,\r
+                *                                                              elements: [\r
+                *                                                                      {\r
+                *                                                                              type: 'html',\r
+                *                                                                              html: '<p>This is some sample HTML content.</p>'\r
+                *                                                                      },\r
+                *                                                                      {\r
+                *                                                                              type: 'textarea',\r
+                *                                                                              id: 'textareaId',\r
+                *                                                                              rows: 4,\r
+                *                                                                              cols: 40\r
+                *                                                                      }\r
+                *                                                              ]\r
+                *                                                      }\r
+                *                                              ],\r
+                *                                              buttons: [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ],\r
+                *                                              onOk: function() {\r
+                *                                                      // "this" is now a CKEDITOR.dialog object.\r
+                *                                                      // Accessing dialog elements:\r
+                *                                                      var textareaObj = this.getContentElement( 'tab1', 'textareaId' );\r
+                *                                                      alert( "You have entered: " + textareaObj.getValue() );\r
+                *                                              }\r
+                *                                      };\r
+                *\r
+                *                                      return dialogDefinition;\r
+                *                              } );\r
+                *                      }\r
+                *              } );\r
+                *\r
+                *              CKEDITOR.replace( 'editor1', { extraPlugins: 'myplugin' } );\r
+                *\r
+                * @static\r
+                * @param {String} name The dialog's name.\r
+                * @param {Function/String} dialogDefinition\r
+                * A function returning the dialog's definition, or the URL to the `.js` file holding the function.\r
+                * The function should accept an argument `editor` which is the current editor instance, and\r
+                * return an object conforming to {@link CKEDITOR.dialog.definition}.\r
+                * @see CKEDITOR.dialog.definition\r
+                */\r
+               add: function( name, dialogDefinition ) {\r
+                       // Avoid path registration from multiple instances override definition.\r
+                       if ( !this._.dialogDefinitions[ name ] || typeof dialogDefinition == 'function' )\r
+                               this._.dialogDefinitions[ name ] = dialogDefinition;\r
+               },\r
+\r
+               /**\r
+                * @static\r
+                * @todo\r
+                */\r
+               exists: function( name ) {\r
+                       return !!this._.dialogDefinitions[ name ];\r
+               },\r
+\r
+               /**\r
+                * @static\r
+                * @todo\r
+                */\r
+               getCurrent: function() {\r
+                       return CKEDITOR.dialog._.currentTop;\r
+               },\r
+\r
+               /**\r
+                * Check whether tab wasn't removed by {@link CKEDITOR.config#removeDialogTabs}.\r
+                *\r
+                * @since 4.1\r
+                * @static\r
+                * @param {CKEDITOR.editor} editor\r
+                * @param {String} dialogName\r
+                * @param {String} tabName\r
+                * @returns {Boolean}\r
+                */\r
+               isTabEnabled: function( editor, dialogName, tabName ) {\r
+                       var cfg = editor.config.removeDialogTabs;\r
+\r
+                       return !( cfg && cfg.match( new RegExp( '(?:^|;)' + dialogName + ':' + tabName + '(?:$|;)', 'i' ) ) );\r
+               },\r
+\r
+               /**\r
+                * The default OK button for dialogs. Fires the `ok` event and closes the dialog if the event succeeds.\r
+                *\r
+                * @static\r
+                * @method\r
+                */\r
+               okButton: ( function() {\r
+                       var retval = function( editor, override ) {\r
+                                       override = override || {};\r
+                                       return CKEDITOR.tools.extend( {\r
+                                               id: 'ok',\r
+                                               type: 'button',\r
+                                               label: editor.lang.common.ok,\r
+                                               'class': 'cke_dialog_ui_button_ok',\r
+                                               onClick: function( evt ) {\r
+                                                       var dialog = evt.data.dialog;\r
+                                                       if ( dialog.fire( 'ok', { hide: true } ).hide !== false )\r
+                                                               dialog.hide();\r
+                                               }\r
+                                       }, override, true );\r
+                               };\r
+                       retval.type = 'button';\r
+                       retval.override = function( override ) {\r
+                               return CKEDITOR.tools.extend( function( editor ) {\r
+                                       return retval( editor, override );\r
+                               }, { type: 'button' }, true );\r
+                       };\r
+                       return retval;\r
+               } )(),\r
+\r
+               /**\r
+                * The default cancel button for dialogs. Fires the `cancel` event and\r
+                * closes the dialog if no UI element value changed.\r
+                *\r
+                * @static\r
+                * @method\r
+                */\r
+               cancelButton: ( function() {\r
+                       var retval = function( editor, override ) {\r
+                                       override = override || {};\r
+                                       return CKEDITOR.tools.extend( {\r
+                                               id: 'cancel',\r
+                                               type: 'button',\r
+                                               label: editor.lang.common.cancel,\r
+                                               'class': 'cke_dialog_ui_button_cancel',\r
+                                               onClick: function( evt ) {\r
+                                                       var dialog = evt.data.dialog;\r
+                                                       if ( dialog.fire( 'cancel', { hide: true } ).hide !== false )\r
+                                                               dialog.hide();\r
+                                               }\r
+                                       }, override, true );\r
+                               };\r
+                       retval.type = 'button';\r
+                       retval.override = function( override ) {\r
+                               return CKEDITOR.tools.extend( function( editor ) {\r
+                                       return retval( editor, override );\r
+                               }, { type: 'button' }, true );\r
+                       };\r
+                       return retval;\r
+               } )(),\r
+\r
+               /**\r
+                * Registers a dialog UI element.\r
+                *\r
+                * @static\r
+                * @param {String} typeName The name of the UI element.\r
+                * @param {Function} builder The function to build the UI element.\r
+                */\r
+               addUIElement: function( typeName, builder ) {\r
+                       this._.uiElementBuilders[ typeName ] = builder;\r
+               }\r
+       } );\r
+\r
+       CKEDITOR.dialog._ = {\r
+               uiElementBuilders: {},\r
+\r
+               dialogDefinitions: {},\r
+\r
+               currentTop: null,\r
+\r
+               currentZIndex: null\r
+       };\r
+\r
+       // "Inherit" (copy actually) from CKEDITOR.event.\r
+       CKEDITOR.event.implementOn( CKEDITOR.dialog );\r
+       CKEDITOR.event.implementOn( CKEDITOR.dialog.prototype );\r
+\r
+       var defaultDialogDefinition = {\r
+               resizable: CKEDITOR.DIALOG_RESIZE_BOTH,\r
+               minWidth: 600,\r
+               minHeight: 400,\r
+               buttons: [ CKEDITOR.dialog.okButton, CKEDITOR.dialog.cancelButton ]\r
+       };\r
+\r
+       // Tool function used to return an item from an array based on its id\r
+       // property.\r
+       var getById = function( array, id, recurse ) {\r
+                       for ( var i = 0, item;\r
+                       ( item = array[ i ] ); i++ ) {\r
+                               if ( item.id == id )\r
+                                       return item;\r
+                               if ( recurse && item[ recurse ] ) {\r
+                                       var retval = getById( item[ recurse ], id, recurse );\r
+                                       if ( retval )\r
+                                               return retval;\r
+                               }\r
+                       }\r
+                       return null;\r
+               };\r
+\r
+       // Tool function used to add an item into an array.\r
+       var addById = function( array, newItem, nextSiblingId, recurse, nullIfNotFound ) {\r
+                       if ( nextSiblingId ) {\r
+                               for ( var i = 0, item;\r
+                               ( item = array[ i ] ); i++ ) {\r
+                                       if ( item.id == nextSiblingId ) {\r
+                                               array.splice( i, 0, newItem );\r
+                                               return newItem;\r
+                                       }\r
+\r
+                                       if ( recurse && item[ recurse ] ) {\r
+                                               var retval = addById( item[ recurse ], newItem, nextSiblingId, recurse, true );\r
+                                               if ( retval )\r
+                                                       return retval;\r
+                                       }\r
+                               }\r
+\r
+                               if ( nullIfNotFound )\r
+                                       return null;\r
+                       }\r
+\r
+                       array.push( newItem );\r
+                       return newItem;\r
+               };\r
+\r
+       // Tool function used to remove an item from an array based on its id.\r
+       var removeById = function( array, id, recurse ) {\r
+                       for ( var i = 0, item;\r
+                       ( item = array[ i ] ); i++ ) {\r
+                               if ( item.id == id )\r
+                                       return array.splice( i, 1 );\r
+                               if ( recurse && item[ recurse ] ) {\r
+                                       var retval = removeById( item[ recurse ], id, recurse );\r
+                                       if ( retval )\r
+                                               return retval;\r
+                               }\r
+                       }\r
+                       return null;\r
+               };\r
+\r
+       /**\r
+        * This class is not really part of the API. It is the `definition` property value\r
+        * passed to `dialogDefinition` event handlers.\r
+        *\r
+        *              CKEDITOR.on( 'dialogDefinition', function( evt ) {\r
+        *                      var definition = evt.data.definition;\r
+        *                      var content = definition.getContents( 'page1' );\r
+        *                      // ...\r
+        *              } );\r
+        *\r
+        * @private\r
+        * @class CKEDITOR.dialog.definitionObject\r
+        * @extends CKEDITOR.dialog.definition\r
+        * @constructor Creates a definitionObject class instance.\r
+        */\r
+       var definitionObject = function( dialog, dialogDefinition ) {\r
+                       // TODO : Check if needed.\r
+                       this.dialog = dialog;\r
+\r
+                       // Transform the contents entries in contentObjects.\r
+                       var contents = dialogDefinition.contents;\r
+                       for ( var i = 0, content;\r
+                       ( content = contents[ i ] ); i++ )\r
+                               contents[ i ] = content && new contentObject( dialog, content );\r
+\r
+                       CKEDITOR.tools.extend( this, dialogDefinition );\r
+               };\r
+\r
+       definitionObject.prototype = {\r
+               /**\r
+                * Gets a content definition.\r
+                *\r
+                * @param {String} id The id of the content definition.\r
+                * @returns {CKEDITOR.dialog.definition.content} The content definition matching id.\r
+                */\r
+               getContents: function( id ) {\r
+                       return getById( this.contents, id );\r
+               },\r
+\r
+               /**\r
+                * Gets a button definition.\r
+                *\r
+                * @param {String} id The id of the button definition.\r
+                * @returns {CKEDITOR.dialog.definition.button} The button definition matching id.\r
+                */\r
+               getButton: function( id ) {\r
+                       return getById( this.buttons, id );\r
+               },\r
+\r
+               /**\r
+                * Adds a content definition object under this dialog definition.\r
+                *\r
+                * @param {CKEDITOR.dialog.definition.content} contentDefinition The\r
+                * content definition.\r
+                * @param {String} [nextSiblingId] The id of an existing content\r
+                * definition which the new content definition will be inserted\r
+                * before. Omit if the new content definition is to be inserted as\r
+                * the last item.\r
+                * @returns {CKEDITOR.dialog.definition.content} The inserted content definition.\r
+                */\r
+               addContents: function( contentDefinition, nextSiblingId ) {\r
+                       return addById( this.contents, contentDefinition, nextSiblingId );\r
+               },\r
+\r
+               /**\r
+                * Adds a button definition object under this dialog definition.\r
+                *\r
+                * @param {CKEDITOR.dialog.definition.button} buttonDefinition The\r
+                * button definition.\r
+                * @param {String} [nextSiblingId] The id of an existing button\r
+                * definition which the new button definition will be inserted\r
+                * before. Omit if the new button definition is to be inserted as\r
+                * the last item.\r
+                * @returns {CKEDITOR.dialog.definition.button} The inserted button definition.\r
+                */\r
+               addButton: function( buttonDefinition, nextSiblingId ) {\r
+                       return addById( this.buttons, buttonDefinition, nextSiblingId );\r
+               },\r
+\r
+               /**\r
+                * Removes a content definition from this dialog definition.\r
+                *\r
+                * @param {String} id The id of the content definition to be removed.\r
+                * @returns {CKEDITOR.dialog.definition.content} The removed content definition.\r
+                */\r
+               removeContents: function( id ) {\r
+                       removeById( this.contents, id );\r
+               },\r
+\r
+               /**\r
+                * Removes a button definition from the dialog definition.\r
+                *\r
+                * @param {String} id The id of the button definition to be removed.\r
+                * @returns {CKEDITOR.dialog.definition.button} The removed button definition.\r
+                */\r
+               removeButton: function( id ) {\r
+                       removeById( this.buttons, id );\r
+               }\r
+       };\r
+\r
+       /**\r
+        * This class is not really part of the API. It is the template of the\r
+        * objects representing content pages inside the\r
+        * CKEDITOR.dialog.definitionObject.\r
+        *\r
+        *              CKEDITOR.on( 'dialogDefinition', function( evt ) {\r
+        *                      var definition = evt.data.definition;\r
+        *                      var content = definition.getContents( 'page1' );\r
+        *                      content.remove( 'textInput1' );\r
+        *                      // ...\r
+        *              } );\r
+        *\r
+        * @private\r
+        * @class CKEDITOR.dialog.definition.contentObject\r
+        * @constructor Creates a contentObject class instance.\r
+        */\r
+       function contentObject( dialog, contentDefinition ) {\r
+               this._ = {\r
+                       dialog: dialog\r
+               };\r
+\r
+               CKEDITOR.tools.extend( this, contentDefinition );\r
+       }\r
+\r
+       contentObject.prototype = {\r
+               /**\r
+                * Gets a UI element definition under the content definition.\r
+                *\r
+                * @param {String} id The id of the UI element definition.\r
+                * @returns {CKEDITOR.dialog.definition.uiElement}\r
+                */\r
+               get: function( id ) {\r
+                       return getById( this.elements, id, 'children' );\r
+               },\r
+\r
+               /**\r
+                * Adds a UI element definition to the content definition.\r
+                *\r
+                * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition The\r
+                * UI elemnet definition to be added.\r
+                * @param {String} nextSiblingId The id of an existing UI element\r
+                * definition which the new UI element definition will be inserted\r
+                * before. Omit if the new button definition is to be inserted as\r
+                * the last item.\r
+                * @returns {CKEDITOR.dialog.definition.uiElement} The element definition inserted.\r
+                */\r
+               add: function( elementDefinition, nextSiblingId ) {\r
+                       return addById( this.elements, elementDefinition, nextSiblingId, 'children' );\r
+               },\r
+\r
+               /**\r
+                * Removes a UI element definition from the content definition.\r
+                *\r
+                * @param {String} id The id of the UI element definition to be removed.\r
+                * @returns {CKEDITOR.dialog.definition.uiElement} The element definition removed.\r
+                */\r
+               remove: function( id ) {\r
+                       removeById( this.elements, id, 'children' );\r
+               }\r
+       };\r
+\r
+       function initDragAndDrop( dialog ) {\r
+               var lastCoords = null,\r
+                       abstractDialogCoords = null,\r
+                       editor = dialog.getParentEditor(),\r
+                       magnetDistance = editor.config.dialog_magnetDistance,\r
+                       margins = CKEDITOR.skin.margins || [ 0, 0, 0, 0 ];\r
+\r
+               if ( typeof magnetDistance == 'undefined' )\r
+                       magnetDistance = 20;\r
+\r
+               function mouseMoveHandler( evt ) {\r
+                       var dialogSize = dialog.getSize(),\r
+                               viewPaneSize = CKEDITOR.document.getWindow().getViewPaneSize(),\r
+                               x = evt.data.$.screenX,\r
+                               y = evt.data.$.screenY,\r
+                               dx = x - lastCoords.x,\r
+                               dy = y - lastCoords.y,\r
+                               realX, realY;\r
+\r
+                       lastCoords = { x: x, y: y };\r
+                       abstractDialogCoords.x += dx;\r
+                       abstractDialogCoords.y += dy;\r
+\r
+                       if ( abstractDialogCoords.x + margins[ 3 ] < magnetDistance )\r
+                               realX = -margins[ 3 ];\r
+                       else if ( abstractDialogCoords.x - margins[ 1 ] > viewPaneSize.width - dialogSize.width - magnetDistance )\r
+                               realX = viewPaneSize.width - dialogSize.width + ( editor.lang.dir == 'rtl' ? 0 : margins[ 1 ] );\r
+                       else\r
+                               realX = abstractDialogCoords.x;\r
+\r
+                       if ( abstractDialogCoords.y + margins[ 0 ] < magnetDistance )\r
+                               realY = -margins[ 0 ];\r
+                       else if ( abstractDialogCoords.y - margins[ 2 ] > viewPaneSize.height - dialogSize.height - magnetDistance )\r
+                               realY = viewPaneSize.height - dialogSize.height + margins[ 2 ];\r
+                       else\r
+                               realY = abstractDialogCoords.y;\r
+\r
+                       dialog.move( realX, realY, 1 );\r
+\r
+                       evt.data.preventDefault();\r
+               }\r
+\r
+               function mouseUpHandler() {\r
+                       CKEDITOR.document.removeListener( 'mousemove', mouseMoveHandler );\r
+                       CKEDITOR.document.removeListener( 'mouseup', mouseUpHandler );\r
+\r
+                       if ( CKEDITOR.env.ie6Compat ) {\r
+                               var coverDoc = currentCover.getChild( 0 ).getFrameDocument();\r
+                               coverDoc.removeListener( 'mousemove', mouseMoveHandler );\r
+                               coverDoc.removeListener( 'mouseup', mouseUpHandler );\r
+                       }\r
+               }\r
+\r
+               dialog.parts.title.on( 'mousedown', function( evt ) {\r
+                       lastCoords = { x: evt.data.$.screenX, y: evt.data.$.screenY };\r
+\r
+                       CKEDITOR.document.on( 'mousemove', mouseMoveHandler );\r
+                       CKEDITOR.document.on( 'mouseup', mouseUpHandler );\r
+                       abstractDialogCoords = dialog.getPosition();\r
+\r
+                       if ( CKEDITOR.env.ie6Compat ) {\r
+                               var coverDoc = currentCover.getChild( 0 ).getFrameDocument();\r
+                               coverDoc.on( 'mousemove', mouseMoveHandler );\r
+                               coverDoc.on( 'mouseup', mouseUpHandler );\r
+                       }\r
+\r
+                       evt.data.preventDefault();\r
+               }, dialog );\r
+       }\r
+\r
+       function initResizeHandles( dialog ) {\r
+               var def = dialog.definition,\r
+                       resizable = def.resizable;\r
+\r
+               if ( resizable == CKEDITOR.DIALOG_RESIZE_NONE )\r
+                       return;\r
+\r
+               var editor = dialog.getParentEditor();\r
+               var wrapperWidth, wrapperHeight, viewSize, origin, startSize, dialogCover;\r
+\r
+               var mouseDownFn = CKEDITOR.tools.addFunction( function( $event ) {\r
+                       startSize = dialog.getSize();\r
+\r
+                       var content = dialog.parts.contents,\r
+                               iframeDialog = content.$.getElementsByTagName( 'iframe' ).length;\r
+\r
+                       // Shim to help capturing "mousemove" over iframe.\r
+                       if ( iframeDialog ) {\r
+                               dialogCover = CKEDITOR.dom.element.createFromHtml( '<div class="cke_dialog_resize_cover" style="height: 100%; position: absolute; width: 100%;"></div>' );\r
+                               content.append( dialogCover );\r
+                       }\r
+\r
+                       // Calculate the offset between content and chrome size.\r
+                       wrapperHeight = startSize.height - dialog.parts.contents.getSize( 'height', !( CKEDITOR.env.gecko || CKEDITOR.env.ie && CKEDITOR.env.quirks ) );\r
+                       wrapperWidth = startSize.width - dialog.parts.contents.getSize( 'width', 1 );\r
+\r
+                       origin = { x: $event.screenX, y: $event.screenY };\r
+\r
+                       viewSize = CKEDITOR.document.getWindow().getViewPaneSize();\r
+\r
+                       CKEDITOR.document.on( 'mousemove', mouseMoveHandler );\r
+                       CKEDITOR.document.on( 'mouseup', mouseUpHandler );\r
+\r
+                       if ( CKEDITOR.env.ie6Compat ) {\r
+                               var coverDoc = currentCover.getChild( 0 ).getFrameDocument();\r
+                               coverDoc.on( 'mousemove', mouseMoveHandler );\r
+                               coverDoc.on( 'mouseup', mouseUpHandler );\r
+                       }\r
+\r
+                       $event.preventDefault && $event.preventDefault();\r
+               } );\r
+\r
+               // Prepend the grip to the dialog.\r
+               dialog.on( 'load', function() {\r
+                       var direction = '';\r
+                       if ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH )\r
+                               direction = ' cke_resizer_horizontal';\r
+                       else if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT )\r
+                               direction = ' cke_resizer_vertical';\r
+                       var resizer = CKEDITOR.dom.element.createFromHtml(\r
+                               '<div' +\r
+                               ' class="cke_resizer' + direction + ' cke_resizer_' + editor.lang.dir + '"' +\r
+                               ' title="' + CKEDITOR.tools.htmlEncode( editor.lang.common.resize ) + '"' +\r
+                               ' onmousedown="CKEDITOR.tools.callFunction(' + mouseDownFn + ', event )">' +\r
+                               // BLACK LOWER RIGHT TRIANGLE (ltr)\r
+                               // BLACK LOWER LEFT TRIANGLE (rtl)\r
+                               ( editor.lang.dir == 'ltr' ? '\u25E2' : '\u25E3' ) +\r
+                               '</div>' );\r
+                       dialog.parts.footer.append( resizer, 1 );\r
+               } );\r
+               editor.on( 'destroy', function() {\r
+                       CKEDITOR.tools.removeFunction( mouseDownFn );\r
+               } );\r
+\r
+               function mouseMoveHandler( evt ) {\r
+                       var rtl = editor.lang.dir == 'rtl',\r
+                               dx = ( evt.data.$.screenX - origin.x ) * ( rtl ? -1 : 1 ),\r
+                               dy = evt.data.$.screenY - origin.y,\r
+                               width = startSize.width,\r
+                               height = startSize.height,\r
+                               internalWidth = width + dx * ( dialog._.moved ? 1 : 2 ),\r
+                               internalHeight = height + dy * ( dialog._.moved ? 1 : 2 ),\r
+                               element = dialog._.element.getFirst(),\r
+                               right = rtl && element.getComputedStyle( 'right' ),\r
+                               position = dialog.getPosition();\r
+\r
+                       if ( position.y + internalHeight > viewSize.height )\r
+                               internalHeight = viewSize.height - position.y;\r
+\r
+                       if ( ( rtl ? right : position.x ) + internalWidth > viewSize.width )\r
+                               internalWidth = viewSize.width - ( rtl ? right : position.x );\r
+\r
+                       // Make sure the dialog will not be resized to the wrong side when it's in the leftmost position for RTL.\r
+                       if ( ( resizable == CKEDITOR.DIALOG_RESIZE_WIDTH || resizable == CKEDITOR.DIALOG_RESIZE_BOTH ) )\r
+                               width = Math.max( def.minWidth || 0, internalWidth - wrapperWidth );\r
+\r
+                       if ( resizable == CKEDITOR.DIALOG_RESIZE_HEIGHT || resizable == CKEDITOR.DIALOG_RESIZE_BOTH )\r
+                               height = Math.max( def.minHeight || 0, internalHeight - wrapperHeight );\r
+\r
+                       dialog.resize( width, height );\r
+\r
+                       if ( !dialog._.moved )\r
+                               dialog.layout();\r
+\r
+                       evt.data.preventDefault();\r
+               }\r
+\r
+               function mouseUpHandler() {\r
+                       CKEDITOR.document.removeListener( 'mouseup', mouseUpHandler );\r
+                       CKEDITOR.document.removeListener( 'mousemove', mouseMoveHandler );\r
+\r
+                       if ( dialogCover ) {\r
+                               dialogCover.remove();\r
+                               dialogCover = null;\r
+                       }\r
+\r
+                       if ( CKEDITOR.env.ie6Compat ) {\r
+                               var coverDoc = currentCover.getChild( 0 ).getFrameDocument();\r
+                               coverDoc.removeListener( 'mouseup', mouseUpHandler );\r
+                               coverDoc.removeListener( 'mousemove', mouseMoveHandler );\r
+                       }\r
+               }\r
+       }\r
+\r
+       var resizeCover;\r
+       // Caching resuable covers and allowing only one cover\r
+       // on screen.\r
+       var covers = {},\r
+               currentCover;\r
+\r
+       function cancelEvent( ev ) {\r
+               ev.data.preventDefault( 1 );\r
+       }\r
+\r
+       function showCover( editor ) {\r
+               var win = CKEDITOR.document.getWindow(),\r
+                       config = editor.config,\r
+                       skinName = ( CKEDITOR.skinName || editor.config.skin ),\r
+                       backgroundColorStyle = config.dialog_backgroundCoverColor || ( skinName == 'moono-lisa' ? 'black' : 'white' ),\r
+                       backgroundCoverOpacity = config.dialog_backgroundCoverOpacity,\r
+                       baseFloatZIndex = config.baseFloatZIndex,\r
+                       coverKey = CKEDITOR.tools.genKey( backgroundColorStyle, backgroundCoverOpacity, baseFloatZIndex ),\r
+                       coverElement = covers[ coverKey ];\r
+\r
+               if ( !coverElement ) {\r
+                       var html = [\r
+                               '<div tabIndex="-1" style="position: ', ( CKEDITOR.env.ie6Compat ? 'absolute' : 'fixed' ),\r
+                               '; z-index: ', baseFloatZIndex,\r
+                               '; top: 0px; left: 0px; ',\r
+                               ( !CKEDITOR.env.ie6Compat ? 'background-color: ' + backgroundColorStyle : '' ),\r
+                               '" class="cke_dialog_background_cover">'\r
+                       ];\r
+\r
+                       if ( CKEDITOR.env.ie6Compat ) {\r
+                               // Support for custom document.domain in IE.\r
+                               var iframeHtml = '<html><body style=\\\'background-color:' + backgroundColorStyle + ';\\\'></body></html>';\r
+\r
+                               html.push( '<iframe' +\r
+                                       ' hidefocus="true"' +\r
+                                       ' frameborder="0"' +\r
+                                       ' id="cke_dialog_background_iframe"' +\r
+                                       ' src="javascript:' );\r
+\r
+                               html.push( 'void((function(){' + encodeURIComponent(\r
+                                       'document.open();' +\r
+                                       // Support for custom document.domain in IE.\r
+                                       '(' + CKEDITOR.tools.fixDomain + ')();' +\r
+                                       'document.write( \'' + iframeHtml + '\' );' +\r
+                                       'document.close();'\r
+                               ) + '})())' );\r
+\r
+                               html.push( '"' +\r
+                                       ' style="' +\r
+                                               'position:absolute;' +\r
+                                               'left:0;' +\r
+                                               'top:0;' +\r
+                                               'width:100%;' +\r
+                                               'height: 100%;' +\r
+                                               'filter: progid:DXImageTransform.Microsoft.Alpha(opacity=0)">' +\r
+                                       '</iframe>' );\r
+                       }\r
+\r
+                       html.push( '</div>' );\r
+\r
+                       coverElement = CKEDITOR.dom.element.createFromHtml( html.join( '' ) );\r
+                       coverElement.setOpacity( backgroundCoverOpacity !== undefined ? backgroundCoverOpacity : 0.5 );\r
+\r
+                       coverElement.on( 'keydown', cancelEvent );\r
+                       coverElement.on( 'keypress', cancelEvent );\r
+                       coverElement.on( 'keyup', cancelEvent );\r
+\r
+                       coverElement.appendTo( CKEDITOR.document.getBody() );\r
+                       covers[ coverKey ] = coverElement;\r
+               } else {\r
+                       coverElement.show();\r
+               }\r
+\r
+               // Makes the dialog cover a focus holder as well.\r
+               editor.focusManager.add( coverElement );\r
+\r
+               currentCover = coverElement;\r
+               var resizeFunc = function() {\r
+                               var size = win.getViewPaneSize();\r
+                               coverElement.setStyles( {\r
+                                       width: size.width + 'px',\r
+                                       height: size.height + 'px'\r
+                               } );\r
+                       };\r
+\r
+               var scrollFunc = function() {\r
+                               var pos = win.getScrollPosition(),\r
+                                       cursor = CKEDITOR.dialog._.currentTop;\r
+                               coverElement.setStyles( {\r
+                                       left: pos.x + 'px',\r
+                                       top: pos.y + 'px'\r
+                               } );\r
+\r
+                               if ( cursor ) {\r
+                                       do {\r
+                                               var dialogPos = cursor.getPosition();\r
+                                               cursor.move( dialogPos.x, dialogPos.y );\r
+                                       } while ( ( cursor = cursor._.parentDialog ) );\r
+                               }\r
+                       };\r
+\r
+               resizeCover = resizeFunc;\r
+               win.on( 'resize', resizeFunc );\r
+               resizeFunc();\r
+               // Using Safari/Mac, focus must be kept where it is (#7027)\r
+               if ( !( CKEDITOR.env.mac && CKEDITOR.env.webkit ) )\r
+                       coverElement.focus();\r
+\r
+               if ( CKEDITOR.env.ie6Compat ) {\r
+                       // IE BUG: win.$.onscroll assignment doesn't work.. it must be window.onscroll.\r
+                       // So we need to invent a really funny way to make it work.\r
+                       var myScrollHandler = function() {\r
+                                       scrollFunc();\r
+                                       arguments.callee.prevScrollHandler.apply( this, arguments );\r
+                               };\r
+                       win.$.setTimeout( function() {\r
+                               myScrollHandler.prevScrollHandler = window.onscroll ||\r
+                               function() {};\r
+                               window.onscroll = myScrollHandler;\r
+                       }, 0 );\r
+                       scrollFunc();\r
+               }\r
+       }\r
+\r
+       function hideCover( editor ) {\r
+               if ( !currentCover )\r
+                       return;\r
+\r
+               editor.focusManager.remove( currentCover );\r
+               var win = CKEDITOR.document.getWindow();\r
+               currentCover.hide();\r
+               win.removeListener( 'resize', resizeCover );\r
+\r
+               if ( CKEDITOR.env.ie6Compat ) {\r
+                       win.$.setTimeout( function() {\r
+                               var prevScrollHandler = window.onscroll && window.onscroll.prevScrollHandler;\r
+                               window.onscroll = prevScrollHandler || null;\r
+                       }, 0 );\r
+               }\r
+               resizeCover = null;\r
+       }\r
+\r
+       function removeCovers() {\r
+               for ( var coverId in covers )\r
+                       covers[ coverId ].remove();\r
+               covers = {};\r
+       }\r
+\r
+       var accessKeyProcessors = {};\r
+\r
+       var accessKeyDownHandler = function( evt ) {\r
+                       var ctrl = evt.data.$.ctrlKey || evt.data.$.metaKey,\r
+                               alt = evt.data.$.altKey,\r
+                               shift = evt.data.$.shiftKey,\r
+                               key = String.fromCharCode( evt.data.$.keyCode ),\r
+                               keyProcessor = accessKeyProcessors[ ( ctrl ? 'CTRL+' : '' ) + ( alt ? 'ALT+' : '' ) + ( shift ? 'SHIFT+' : '' ) + key ];\r
+\r
+                       if ( !keyProcessor || !keyProcessor.length )\r
+                               return;\r
+\r
+                       keyProcessor = keyProcessor[ keyProcessor.length - 1 ];\r
+                       keyProcessor.keydown && keyProcessor.keydown.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key );\r
+                       evt.data.preventDefault();\r
+               };\r
+\r
+       var accessKeyUpHandler = function( evt ) {\r
+                       var ctrl = evt.data.$.ctrlKey || evt.data.$.metaKey,\r
+                               alt = evt.data.$.altKey,\r
+                               shift = evt.data.$.shiftKey,\r
+                               key = String.fromCharCode( evt.data.$.keyCode ),\r
+                               keyProcessor = accessKeyProcessors[ ( ctrl ? 'CTRL+' : '' ) + ( alt ? 'ALT+' : '' ) + ( shift ? 'SHIFT+' : '' ) + key ];\r
+\r
+                       if ( !keyProcessor || !keyProcessor.length )\r
+                               return;\r
+\r
+                       keyProcessor = keyProcessor[ keyProcessor.length - 1 ];\r
+                       if ( keyProcessor.keyup ) {\r
+                               keyProcessor.keyup.call( keyProcessor.uiElement, keyProcessor.dialog, keyProcessor.key );\r
+                               evt.data.preventDefault();\r
+                       }\r
+               };\r
+\r
+       var registerAccessKey = function( uiElement, dialog, key, downFunc, upFunc ) {\r
+                       var procList = accessKeyProcessors[ key ] || ( accessKeyProcessors[ key ] = [] );\r
+                       procList.push( {\r
+                               uiElement: uiElement,\r
+                               dialog: dialog,\r
+                               key: key,\r
+                               keyup: upFunc || uiElement.accessKeyUp,\r
+                               keydown: downFunc || uiElement.accessKeyDown\r
+                       } );\r
+               };\r
+\r
+       var unregisterAccessKey = function( obj ) {\r
+                       for ( var i in accessKeyProcessors ) {\r
+                               var list = accessKeyProcessors[ i ];\r
+                               for ( var j = list.length - 1; j >= 0; j-- ) {\r
+                                       if ( list[ j ].dialog == obj || list[ j ].uiElement == obj )\r
+                                               list.splice( j, 1 );\r
+                               }\r
+                               if ( list.length === 0 )\r
+                                       delete accessKeyProcessors[ i ];\r
+                       }\r
+               };\r
+\r
+       var tabAccessKeyUp = function( dialog, key ) {\r
+                       if ( dialog._.accessKeyMap[ key ] )\r
+                               dialog.selectPage( dialog._.accessKeyMap[ key ] );\r
+               };\r
+\r
+       var tabAccessKeyDown = function() {};\r
+\r
+       ( function() {\r
+               CKEDITOR.ui.dialog = {\r
+                       /**\r
+                        * The base class of all dialog UI elements.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a uiElement class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition Element\r
+                        * definition.\r
+                        *\r
+                        * Accepted fields:\r
+                        *\r
+                        * * `id` (Required) The id of the UI element. See {@link CKEDITOR.dialog#getContentElement}.\r
+                        * * `type` (Required) The type of the UI element. The\r
+                        *     value to this field specifies which UI element class will be used to\r
+                        *     generate the final widget.\r
+                        * * `title` (Optional) The popup tooltip for the UI\r
+                        *     element.\r
+                        * * `hidden` (Optional) A flag that tells if the element\r
+                        *     should be initially visible.\r
+                        * * `className` (Optional) Additional CSS class names\r
+                        *     to add to the UI element. Separated by space.\r
+                        * * `style` (Optional) Additional CSS inline styles\r
+                        *     to add to the UI element. A semicolon (;) is required after the last\r
+                        *     style declaration.\r
+                        * * `accessKey` (Optional) The alphanumeric access key\r
+                        *     for this element. Access keys are automatically prefixed by CTRL.\r
+                        * * `on*` (Optional) Any UI element definition field that\r
+                        *     starts with `on` followed immediately by a capital letter and\r
+                        *     probably more letters is an event handler. Event handlers may be further\r
+                        *     divided into registered event handlers and DOM event handlers. Please\r
+                        *     refer to {@link CKEDITOR.ui.dialog.uiElement#registerEvents} and\r
+                        *     {@link CKEDITOR.ui.dialog.uiElement#eventProcessors} for more information.\r
+                        *\r
+                        * @param {Array} htmlList\r
+                        * List of HTML code to be added to the dialog's content area.\r
+                        * @param {Function/String} [nodeNameArg='div']\r
+                        * A function returning a string, or a simple string for the node name for\r
+                        * the root DOM node.\r
+                        * @param {Function/Object} [stylesArg={}]\r
+                        * A function returning an object, or a simple object for CSS styles applied\r
+                        * to the DOM node.\r
+                        * @param {Function/Object} [attributesArg={}]\r
+                        * A fucntion returning an object, or a simple object for attributes applied\r
+                        * to the DOM node.\r
+                        * @param {Function/String} [contentsArg='']\r
+                        * A function returning a string, or a simple string for the HTML code inside\r
+                        * the root DOM node. Default is empty string.\r
+                        */\r
+                       uiElement: function( dialog, elementDefinition, htmlList, nodeNameArg, stylesArg, attributesArg, contentsArg ) {\r
+                               if ( arguments.length < 4 )\r
+                                       return;\r
+\r
+                               var nodeName = ( nodeNameArg.call ? nodeNameArg( elementDefinition ) : nodeNameArg ) || 'div',\r
+                                       html = [ '<', nodeName, ' ' ],\r
+                                       styles = ( stylesArg && stylesArg.call ? stylesArg( elementDefinition ) : stylesArg ) || {},\r
+                                       attributes = ( attributesArg && attributesArg.call ? attributesArg( elementDefinition ) : attributesArg ) || {},\r
+                                       innerHTML = ( contentsArg && contentsArg.call ? contentsArg.call( this, dialog, elementDefinition ) : contentsArg ) || '',\r
+                                       domId = this.domId = attributes.id || CKEDITOR.tools.getNextId() + '_uiElement',\r
+                                       i;\r
+\r
+                               if ( elementDefinition.requiredContent && !dialog.getParentEditor().filter.check( elementDefinition.requiredContent ) ) {\r
+                                       styles.display = 'none';\r
+                                       this.notAllowed = true;\r
+                               }\r
+\r
+                               // Set the id, a unique id is required for getElement() to work.\r
+                               attributes.id = domId;\r
+\r
+                               // Set the type and definition CSS class names.\r
+                               var classes = {};\r
+                               if ( elementDefinition.type )\r
+                                       classes[ 'cke_dialog_ui_' + elementDefinition.type ] = 1;\r
+                               if ( elementDefinition.className )\r
+                                       classes[ elementDefinition.className ] = 1;\r
+                               if ( elementDefinition.disabled )\r
+                                       classes.cke_disabled = 1;\r
+\r
+                               var attributeClasses = ( attributes[ 'class' ] && attributes[ 'class' ].split ) ? attributes[ 'class' ].split( ' ' ) : [];\r
+                               for ( i = 0; i < attributeClasses.length; i++ ) {\r
+                                       if ( attributeClasses[ i ] )\r
+                                               classes[ attributeClasses[ i ] ] = 1;\r
+                               }\r
+                               var finalClasses = [];\r
+                               for ( i in classes )\r
+                                       finalClasses.push( i );\r
+                               attributes[ 'class' ] = finalClasses.join( ' ' );\r
+\r
+                               // Set the popup tooltop.\r
+                               if ( elementDefinition.title )\r
+                                       attributes.title = elementDefinition.title;\r
+\r
+                               // Write the inline CSS styles.\r
+                               var styleStr = ( elementDefinition.style || '' ).split( ';' );\r
+\r
+                               // Element alignment support.\r
+                               if ( elementDefinition.align ) {\r
+                                       var align = elementDefinition.align;\r
+                                       styles[ 'margin-left' ] = align == 'left' ? 0 : 'auto';\r
+                                       styles[ 'margin-right' ] = align == 'right' ? 0 : 'auto';\r
+                               }\r
+\r
+                               for ( i in styles )\r
+                                       styleStr.push( i + ':' + styles[ i ] );\r
+                               if ( elementDefinition.hidden )\r
+                                       styleStr.push( 'display:none' );\r
+                               for ( i = styleStr.length - 1; i >= 0; i-- ) {\r
+                                       if ( styleStr[ i ] === '' )\r
+                                               styleStr.splice( i, 1 );\r
+                               }\r
+                               if ( styleStr.length > 0 )\r
+                                       attributes.style = ( attributes.style ? ( attributes.style + '; ' ) : '' ) + styleStr.join( '; ' );\r
+\r
+                               // Write the attributes.\r
+                               for ( i in attributes )\r
+                                       html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[ i ] ) + '" ' );\r
+\r
+                               // Write the content HTML.\r
+                               html.push( '>', innerHTML, '</', nodeName, '>' );\r
+\r
+                               // Add contents to the parent HTML array.\r
+                               htmlList.push( html.join( '' ) );\r
+\r
+                               ( this._ || ( this._ = {} ) ).dialog = dialog;\r
+\r
+                               // Override isChanged if it is defined in element definition.\r
+                               if ( typeof elementDefinition.isChanged == 'boolean' )\r
+                                       this.isChanged = function() {\r
+                                               return elementDefinition.isChanged;\r
+                                       };\r
+                               if ( typeof elementDefinition.isChanged == 'function' )\r
+                                       this.isChanged = elementDefinition.isChanged;\r
+\r
+                               // Overload 'get(set)Value' on definition.\r
+                               if ( typeof elementDefinition.setValue == 'function' ) {\r
+                                       this.setValue = CKEDITOR.tools.override( this.setValue, function( org ) {\r
+                                               return function( val ) {\r
+                                                       org.call( this, elementDefinition.setValue.call( this, val ) );\r
+                                               };\r
+                                       } );\r
+                               }\r
+\r
+                               if ( typeof elementDefinition.getValue == 'function' ) {\r
+                                       this.getValue = CKEDITOR.tools.override( this.getValue, function( org ) {\r
+                                               return function() {\r
+                                                       return elementDefinition.getValue.call( this, org.call( this ) );\r
+                                               };\r
+                                       } );\r
+                               }\r
+\r
+                               // Add events.\r
+                               CKEDITOR.event.implementOn( this );\r
+\r
+                               this.registerEvents( elementDefinition );\r
+                               if ( this.accessKeyUp && this.accessKeyDown && elementDefinition.accessKey )\r
+                                       registerAccessKey( this, dialog, 'CTRL+' + elementDefinition.accessKey );\r
+\r
+                               var me = this;\r
+                               dialog.on( 'load', function() {\r
+                                       var input = me.getInputElement();\r
+                                       if ( input ) {\r
+                                               var focusClass = me.type in { 'checkbox': 1, 'ratio': 1 } && CKEDITOR.env.ie && CKEDITOR.env.version < 8 ? 'cke_dialog_ui_focused' : '';\r
+                                               input.on( 'focus', function() {\r
+                                                       dialog._.tabBarMode = false;\r
+                                                       dialog._.hasFocus = true;\r
+                                                       me.fire( 'focus' );\r
+                                                       focusClass && this.addClass( focusClass );\r
+\r
+                                               } );\r
+\r
+                                               input.on( 'blur', function() {\r
+                                                       me.fire( 'blur' );\r
+                                                       focusClass && this.removeClass( focusClass );\r
+                                               } );\r
+                                       }\r
+                               } );\r
+\r
+                               // Completes this object with everything we have in the\r
+                               // definition.\r
+                               CKEDITOR.tools.extend( this, elementDefinition );\r
+\r
+                               // Register the object as a tab focus if it can be included.\r
+                               if ( this.keyboardFocusable ) {\r
+                                       this.tabIndex = elementDefinition.tabIndex || 0;\r
+\r
+                                       this.focusIndex = dialog._.focusList.push( this ) - 1;\r
+                                       this.on( 'focus', function() {\r
+                                               dialog._.currentFocusIndex = me.focusIndex;\r
+                                       } );\r
+                               }\r
+                       },\r
+\r
+                       /**\r
+                        * Horizontal layout box for dialog UI elements, auto-expends to available width of container.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.hbox\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a hbox class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog object.\r
+                        * @param {Array} childObjList\r
+                        * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.\r
+                        * @param {Array} childHtmlList\r
+                        * Array of HTML code that correspond to the HTML output of all the\r
+                        * objects in childObjList.\r
+                        * @param {Array} htmlList\r
+                        * Array of HTML code that this element will output to.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `widths` (Optional) The widths of child cells.\r
+                        * * `height` (Optional) The height of the layout.\r
+                        * * `padding` (Optional) The padding width inside child cells.\r
+                        * * `align` (Optional) The alignment of the whole layout.\r
+                        */\r
+                       hbox: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) {\r
+                               if ( arguments.length < 4 )\r
+                                       return;\r
+\r
+                               this._ || ( this._ = {} );\r
+\r
+                               var children = this._.children = childObjList,\r
+                                       widths = elementDefinition && elementDefinition.widths || null,\r
+                                       height = elementDefinition && elementDefinition.height || null,\r
+                                       styles = {},\r
+                                       i;\r
+                               /** @ignore */\r
+                               var innerHTML = function() {\r
+                                               var html = [ '<tbody><tr class="cke_dialog_ui_hbox">' ];\r
+                                               for ( i = 0; i < childHtmlList.length; i++ ) {\r
+                                                       var className = 'cke_dialog_ui_hbox_child',\r
+                                                               styles = [];\r
+                                                       if ( i === 0 ) {\r
+                                                               className = 'cke_dialog_ui_hbox_first';\r
+                                                       }\r
+                                                       if ( i == childHtmlList.length - 1 ) {\r
+                                                               className = 'cke_dialog_ui_hbox_last';\r
+                                                       }\r
+\r
+                                                       html.push( '<td class="', className, '" role="presentation" ' );\r
+                                                       if ( widths ) {\r
+                                                               if ( widths[ i ] ) {\r
+                                                                       styles.push( 'width:' + cssLength( widths[i] ) );\r
+                                                               }\r
+                                                       } else {\r
+                                                               styles.push( 'width:' + Math.floor( 100 / childHtmlList.length ) + '%' );\r
+                                                       }\r
+                                                       if ( height ) {\r
+                                                               styles.push( 'height:' + cssLength( height ) );\r
+                                                       }\r
+                                                       if ( elementDefinition && elementDefinition.padding !== undefined ) {\r
+                                                               styles.push( 'padding:' + cssLength( elementDefinition.padding ) );\r
+                                                       }\r
+                                                       // In IE Quirks alignment has to be done on table cells. (#7324)\r
+                                                       if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align ) {\r
+                                                               styles.push( 'text-align:' + children[ i ].align );\r
+                                                       }\r
+                                                       if ( styles.length > 0 ) {\r
+                                                               html.push( 'style="' + styles.join( '; ' ) + '" ' );\r
+                                                       }\r
+                                                       html.push( '>', childHtmlList[ i ], '</td>' );\r
+                                               }\r
+                                               html.push( '</tr></tbody>' );\r
+                                               return html.join( '' );\r
+                                       };\r
+\r
+                               var attribs = { role: 'presentation' };\r
+                               elementDefinition && elementDefinition.align && ( attribs.align = elementDefinition.align );\r
+\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'hbox' }, htmlList, 'table', styles, attribs, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * Vertical layout box for dialog UI elements.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.vbox\r
+                        * @extends CKEDITOR.ui.dialog.hbox\r
+                        * @constructor Creates a vbox class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog object.\r
+                        * @param {Array} childObjList\r
+                        * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.\r
+                        * @param {Array} childHtmlList\r
+                        * Array of HTML code that correspond to the HTML output of all the\r
+                        * objects in childObjList.\r
+                        * @param {Array} htmlList Array of HTML code that this element will output to.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `width` (Optional) The width of the layout.\r
+                        * * `heights` (Optional) The heights of individual cells.\r
+                        * * `align` (Optional) The alignment of the layout.\r
+                        * * `padding` (Optional) The padding width inside child cells.\r
+                        * * `expand` (Optional) Whether the layout should expand\r
+                        *     vertically to fill its container.\r
+                        */\r
+                       vbox: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               this._ || ( this._ = {} );\r
+\r
+                               var children = this._.children = childObjList,\r
+                                       width = elementDefinition && elementDefinition.width || null,\r
+                                       heights = elementDefinition && elementDefinition.heights || null;\r
+                               /** @ignore */\r
+                               var innerHTML = function() {\r
+                                               var html = [ '<table role="presentation" cellspacing="0" border="0" ' ];\r
+                                               html.push( 'style="' );\r
+                                               if ( elementDefinition && elementDefinition.expand )\r
+                                                       html.push( 'height:100%;' );\r
+                                               html.push( 'width:' + cssLength( width || '100%' ), ';' );\r
+\r
+                                               // (#10123) Temp fix for dialog broken layout in latest webkit.\r
+                                               if ( CKEDITOR.env.webkit )\r
+                                                       html.push( 'float:none;' );\r
+\r
+                                               html.push( '"' );\r
+                                               html.push( 'align="', CKEDITOR.tools.htmlEncode(\r
+                                               ( elementDefinition && elementDefinition.align ) || ( dialog.getParentEditor().lang.dir == 'ltr' ? 'left' : 'right' ) ), '" ' );\r
+\r
+                                               html.push( '><tbody>' );\r
+                                               for ( var i = 0; i < childHtmlList.length; i++ ) {\r
+                                                       var styles = [];\r
+                                                       html.push( '<tr><td role="presentation" ' );\r
+                                                       if ( width )\r
+                                                               styles.push( 'width:' + cssLength( width || '100%' ) );\r
+                                                       if ( heights )\r
+                                                               styles.push( 'height:' + cssLength( heights[ i ] ) );\r
+                                                       else if ( elementDefinition && elementDefinition.expand )\r
+                                                               styles.push( 'height:' + Math.floor( 100 / childHtmlList.length ) + '%' );\r
+                                                       if ( elementDefinition && elementDefinition.padding !== undefined )\r
+                                                               styles.push( 'padding:' + cssLength( elementDefinition.padding ) );\r
+                                                       // In IE Quirks alignment has to be done on table cells. (#7324)\r
+                                                       if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && children[ i ].align )\r
+                                                               styles.push( 'text-align:' + children[ i ].align );\r
+                                                       if ( styles.length > 0 )\r
+                                                               html.push( 'style="', styles.join( '; ' ), '" ' );\r
+                                                       html.push( ' class="cke_dialog_ui_vbox_child">', childHtmlList[ i ], '</td></tr>' );\r
+                                               }\r
+                                               html.push( '</tbody></table>' );\r
+                                               return html.join( '' );\r
+                                       };\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition || { type: 'vbox' }, htmlList, 'div', null, { role: 'presentation' }, innerHTML );\r
+                       }\r
+               };\r
+       } )();\r
+\r
+       /** @class CKEDITOR.ui.dialog.uiElement */\r
+       CKEDITOR.ui.dialog.uiElement.prototype = {\r
+               /**\r
+                * Gets the root DOM element of this dialog UI object.\r
+                *\r
+                *              uiElement.getElement().hide();\r
+                *\r
+                * @returns {CKEDITOR.dom.element} Root DOM element of UI object.\r
+                */\r
+               getElement: function() {\r
+                       return CKEDITOR.document.getById( this.domId );\r
+               },\r
+\r
+               /**\r
+                * Gets the DOM element that the user inputs values.\r
+                *\r
+                * This function is used by {@link #setValue}, {@link #getValue} and {@link #focus}. It should\r
+                * be overrided in child classes where the input element isn't the root\r
+                * element.\r
+                *\r
+                *              var rawValue = textInput.getInputElement().$.value;\r
+                *\r
+                * @returns {CKEDITOR.dom.element} The element where the user input values.\r
+                */\r
+               getInputElement: function() {\r
+                       return this.getElement();\r
+               },\r
+\r
+               /**\r
+                * Gets the parent dialog object containing this UI element.\r
+                *\r
+                *              var dialog = uiElement.getDialog();\r
+                *\r
+                * @returns {CKEDITOR.dialog} Parent dialog object.\r
+                */\r
+               getDialog: function() {\r
+                       return this._.dialog;\r
+               },\r
+\r
+               /**\r
+                * Sets the value of this dialog UI object.\r
+                *\r
+                *              uiElement.setValue( 'Dingo' );\r
+                *\r
+                * @chainable\r
+                * @param {Object} value The new value.\r
+                * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element.\r
+                */\r
+               setValue: function( value, noChangeEvent ) {\r
+                       this.getInputElement().setValue( value );\r
+                       !noChangeEvent && this.fire( 'change', { value: value } );\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Gets the current value of this dialog UI object.\r
+                *\r
+                *              var myValue = uiElement.getValue();\r
+                *\r
+                * @returns {Object} The current value.\r
+                */\r
+               getValue: function() {\r
+                       return this.getInputElement().getValue();\r
+               },\r
+\r
+               /**\r
+                * Tells whether the UI object's value has changed.\r
+                *\r
+                *              if ( uiElement.isChanged() )\r
+                *                      confirm( 'Value changed! Continue?' );\r
+                *\r
+                * @returns {Boolean} `true` if changed, `false` if not changed.\r
+                */\r
+               isChanged: function() {\r
+                       // Override in input classes.\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                * Selects the parent tab of this element. Usually called by focus() or overridden focus() methods.\r
+                *\r
+                *              focus : function() {\r
+                *                      this.selectParentTab();\r
+                *                      // do something else.\r
+                *              }\r
+                *\r
+                * @chainable\r
+                */\r
+               selectParentTab: function() {\r
+                       var element = this.getInputElement(),\r
+                               cursor = element,\r
+                               tabId;\r
+                       while ( ( cursor = cursor.getParent() ) && cursor.$.className.search( 'cke_dialog_page_contents' ) == -1 ) {\r
+\r
+                       }\r
+\r
+                       // Some widgets don't have parent tabs (e.g. OK and Cancel buttons).\r
+                       if ( !cursor )\r
+                               return this;\r
+\r
+                       tabId = cursor.getAttribute( 'name' );\r
+                       // Avoid duplicate select.\r
+                       if ( this._.dialog._.currentTabId != tabId )\r
+                               this._.dialog.selectPage( tabId );\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Puts the focus to the UI object. Switches tabs if the UI object isn't in the active tab page.\r
+                *\r
+                *              uiElement.focus();\r
+                *\r
+                * @chainable\r
+                */\r
+               focus: function() {\r
+                       this.selectParentTab().getInputElement().focus();\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Registers the `on*` event handlers defined in the element definition.\r
+                *\r
+                * The default behavior of this function is:\r
+                *\r
+                * 1. If the on* event is defined in the class's eventProcesors list,\r
+                *     then the registration is delegated to the corresponding function\r
+                *     in the eventProcessors list.\r
+                * 2. If the on* event is not defined in the eventProcessors list, then\r
+                *     register the event handler under the corresponding DOM event of\r
+                *     the UI element's input DOM element (as defined by the return value\r
+                *     of {@link #getInputElement}).\r
+                *\r
+                * This function is only called at UI element instantiation, but can\r
+                * be overridded in child classes if they require more flexibility.\r
+                *\r
+                * @chainable\r
+                * @param {CKEDITOR.dialog.definition.uiElement} definition The UI element\r
+                * definition.\r
+                */\r
+               registerEvents: function( definition ) {\r
+                       var regex = /^on([A-Z]\w+)/,\r
+                               match;\r
+\r
+                       var registerDomEvent = function( uiElement, dialog, eventName, func ) {\r
+                                       dialog.on( 'load', function() {\r
+                                               uiElement.getInputElement().on( eventName, func, uiElement );\r
+                                       } );\r
+                               };\r
+\r
+                       for ( var i in definition ) {\r
+                               if ( !( match = i.match( regex ) ) )\r
+                                       continue;\r
+                               if ( this.eventProcessors[ i ] )\r
+                                       this.eventProcessors[ i ].call( this, this._.dialog, definition[ i ] );\r
+                               else\r
+                                       registerDomEvent( this, this._.dialog, match[ 1 ].toLowerCase(), definition[ i ] );\r
+                       }\r
+\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * The event processor list used by\r
+                * {@link CKEDITOR.ui.dialog.uiElement#getInputElement} at UI element\r
+                * instantiation. The default list defines three `on*` events:\r
+                *\r
+                * 1. `onLoad` - Called when the element's parent dialog opens for the\r
+                *     first time.\r
+                * 2. `onShow` - Called whenever the element's parent dialog opens.\r
+                * 3. `onHide` - Called whenever the element's parent dialog closes.\r
+                *\r
+                *              // This connects the 'click' event in CKEDITOR.ui.dialog.button to onClick\r
+                *              // handlers in the UI element's definitions.\r
+                *              CKEDITOR.ui.dialog.button.eventProcessors = CKEDITOR.tools.extend( {},\r
+                *                      CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors,\r
+                *                      { onClick : function( dialog, func ) { this.on( 'click', func ); } },\r
+                *                      true\r
+                *              );\r
+                *\r
+                * @property {Object}\r
+                */\r
+               eventProcessors: {\r
+                       onLoad: function( dialog, func ) {\r
+                               dialog.on( 'load', func, this );\r
+                       },\r
+\r
+                       onShow: function( dialog, func ) {\r
+                               dialog.on( 'show', func, this );\r
+                       },\r
+\r
+                       onHide: function( dialog, func ) {\r
+                               dialog.on( 'hide', func, this );\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * The default handler for a UI element's access key down event, which\r
+                * tries to put focus to the UI element.\r
+                *\r
+                * Can be overridded in child classes for more sophisticaed behavior.\r
+                *\r
+                * @param {CKEDITOR.dialog} dialog The parent dialog object.\r
+                * @param {String} key The key combination pressed. Since access keys\r
+                * are defined to always include the `CTRL` key, its value should always\r
+                * include a `'CTRL+'` prefix.\r
+                */\r
+               accessKeyDown: function() {\r
+                       this.focus();\r
+               },\r
+\r
+               /**\r
+                * The default handler for a UI element's access key up event, which\r
+                * does nothing.\r
+                *\r
+                * Can be overridded in child classes for more sophisticated behavior.\r
+                *\r
+                * @param {CKEDITOR.dialog} dialog The parent dialog object.\r
+                * @param {String} key The key combination pressed. Since access keys\r
+                * are defined to always include the `CTRL` key, its value should always\r
+                * include a `'CTRL+'` prefix.\r
+                */\r
+               accessKeyUp: function() {},\r
+\r
+               /**\r
+                * Disables a UI element.\r
+                */\r
+               disable: function() {\r
+                       var element = this.getElement(),\r
+                               input = this.getInputElement();\r
+                       input.setAttribute( 'disabled', 'true' );\r
+                       element.addClass( 'cke_disabled' );\r
+               },\r
+\r
+               /**\r
+                * Enables a UI element.\r
+                */\r
+               enable: function() {\r
+                       var element = this.getElement(),\r
+                               input = this.getInputElement();\r
+                       input.removeAttribute( 'disabled' );\r
+                       element.removeClass( 'cke_disabled' );\r
+               },\r
+\r
+               /**\r
+                * Determines whether an UI element is enabled or not.\r
+                *\r
+                * @returns {Boolean} Whether the UI element is enabled.\r
+                */\r
+               isEnabled: function() {\r
+                       return !this.getElement().hasClass( 'cke_disabled' );\r
+               },\r
+\r
+               /**\r
+                * Determines whether an UI element is visible or not.\r
+                *\r
+                * @returns {Boolean} Whether the UI element is visible.\r
+                */\r
+               isVisible: function() {\r
+                       return this.getInputElement().isVisible();\r
+               },\r
+\r
+               /**\r
+                * Determines whether an UI element is focus-able or not.\r
+                * Focus-able is defined as being both visible and enabled.\r
+                *\r
+                * @returns {Boolean} Whether the UI element can be focused.\r
+                */\r
+               isFocusable: function() {\r
+                       if ( !this.isEnabled() || !this.isVisible() )\r
+                               return false;\r
+                       return true;\r
+               }\r
+       };\r
+\r
+       /** @class CKEDITOR.ui.dialog.hbox */\r
+       CKEDITOR.ui.dialog.hbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {\r
+               /**\r
+                * Gets a child UI element inside this container.\r
+                *\r
+                *              var checkbox = hbox.getChild( [0,1] );\r
+                *              checkbox.setValue( true );\r
+                *\r
+                * @param {Array/Number} indices An array or a single number to indicate the child's\r
+                * position in the container's descendant tree. Omit to get all the children in an array.\r
+                * @returns {Array/CKEDITOR.ui.dialog.uiElement} Array of all UI elements in the container\r
+                * if no argument given, or the specified UI element if indices is given.\r
+                */\r
+               getChild: function( indices ) {\r
+                       // If no arguments, return a clone of the children array.\r
+                       if ( arguments.length < 1 )\r
+                               return this._.children.concat();\r
+\r
+                       // If indices isn't array, make it one.\r
+                       if ( !indices.splice )\r
+                               indices = [ indices ];\r
+\r
+                       // Retrieve the child element according to tree position.\r
+                       if ( indices.length < 2 )\r
+                               return this._.children[ indices[ 0 ] ];\r
+                       else\r
+                               return ( this._.children[ indices[ 0 ] ] && this._.children[ indices[ 0 ] ].getChild ) ? this._.children[ indices[ 0 ] ].getChild( indices.slice( 1, indices.length ) ) : null;\r
+               }\r
+       }, true );\r
+\r
+       CKEDITOR.ui.dialog.vbox.prototype = new CKEDITOR.ui.dialog.hbox();\r
+\r
+       ( function() {\r
+               var commonBuilder = {\r
+                       build: function( dialog, elementDefinition, output ) {\r
+                               var children = elementDefinition.children,\r
+                                       child,\r
+                                       childHtmlList = [],\r
+                                       childObjList = [];\r
+                               for ( var i = 0;\r
+                               ( i < children.length && ( child = children[ i ] ) ); i++ ) {\r
+                                       var childHtml = [];\r
+                                       childHtmlList.push( childHtml );\r
+                                       childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );\r
+                               }\r
+                               return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );\r
+                       }\r
+               };\r
+\r
+               CKEDITOR.dialog.addUIElement( 'hbox', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'vbox', commonBuilder );\r
+       } )();\r
+\r
+       /**\r
+        * Generic dialog command. It opens a specific dialog when executed.\r
+        *\r
+        *              // Register the "link" command, which opens the "link" dialog.\r
+        *              editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link' ) );\r
+        *\r
+        * @class\r
+        * @constructor Creates a dialogCommand class instance.\r
+        * @extends CKEDITOR.commandDefinition\r
+        * @param {String} dialogName The name of the dialog to open when executing\r
+        * this command.\r
+        * @param {Object} [ext] Additional command definition's properties.\r
+        */\r
+       CKEDITOR.dialogCommand = function( dialogName, ext ) {\r
+               this.dialogName = dialogName;\r
+               CKEDITOR.tools.extend( this, ext, true );\r
+       };\r
+\r
+       CKEDITOR.dialogCommand.prototype = {\r
+               exec: function( editor ) {\r
+                       editor.openDialog( this.dialogName );\r
+               },\r
+\r
+               // Dialog commands just open a dialog ui, thus require no undo logic,\r
+               // undo support should dedicate to specific dialog implementation.\r
+               canUndo: false,\r
+\r
+               editorFocus: 1\r
+       };\r
+\r
+       ( function() {\r
+               var notEmptyRegex = /^([a]|[^a])+$/,\r
+                       integerRegex = /^\d*$/,\r
+                       numberRegex = /^\d*(?:\.\d+)?$/,\r
+                       htmlLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|\%)?)?$/,\r
+                       cssLengthRegex = /^(((\d*(\.\d+))|(\d*))(px|em|ex|in|cm|mm|pt|pc|\%)?)?$/i,\r
+                       inlineStyleRegex = /^(\s*[\w-]+\s*:\s*[^:;]+(?:;|$))*$/;\r
+\r
+               CKEDITOR.VALIDATE_OR = 1;\r
+               CKEDITOR.VALIDATE_AND = 2;\r
+\r
+               CKEDITOR.dialog.validate = {\r
+                       functions: function() {\r
+                               var args = arguments;\r
+                               return function() {\r
+                                       /**\r
+                                        * It's important for validate functions to be able to accept the value\r
+                                        * as argument in addition to this.getValue(), so that it is possible to\r
+                                        * combine validate functions together to make more sophisticated\r
+                                        * validators.\r
+                                        */\r
+                                       var value = this && this.getValue ? this.getValue() : args[ 0 ];\r
+\r
+                                       var msg,\r
+                                               relation = CKEDITOR.VALIDATE_AND,\r
+                                               functions = [],\r
+                                               i;\r
+\r
+                                       for ( i = 0; i < args.length; i++ ) {\r
+                                               if ( typeof args[ i ] == 'function' )\r
+                                                       functions.push( args[ i ] );\r
+                                               else\r
+                                                       break;\r
+                                       }\r
+\r
+                                       if ( i < args.length && typeof args[ i ] == 'string' ) {\r
+                                               msg = args[ i ];\r
+                                               i++;\r
+                                       }\r
+\r
+                                       if ( i < args.length && typeof args[ i ] == 'number' )\r
+                                               relation = args[ i ];\r
+\r
+                                       var passed = ( relation == CKEDITOR.VALIDATE_AND ? true : false );\r
+                                       for ( i = 0; i < functions.length; i++ ) {\r
+                                               if ( relation == CKEDITOR.VALIDATE_AND )\r
+                                                       passed = passed && functions[ i ]( value );\r
+                                               else\r
+                                                       passed = passed || functions[ i ]( value );\r
+                                       }\r
+\r
+                                       return !passed ? msg : true;\r
+                               };\r
+                       },\r
+\r
+                       regex: function( regex, msg ) {\r
+                               /*\r
+                                * Can be greatly shortened by deriving from functions validator if code size\r
+                                * turns out to be more important than performance.\r
+                                */\r
+                               return function() {\r
+                                       var value = this && this.getValue ? this.getValue() : arguments[ 0 ];\r
+                                       return !regex.test( value ) ? msg : true;\r
+                               };\r
+                       },\r
+\r
+                       notEmpty: function( msg ) {\r
+                               return this.regex( notEmptyRegex, msg );\r
+                       },\r
+\r
+                       integer: function( msg ) {\r
+                               return this.regex( integerRegex, msg );\r
+                       },\r
+\r
+                       'number': function( msg ) {\r
+                               return this.regex( numberRegex, msg );\r
+                       },\r
+\r
+                       'cssLength': function( msg ) {\r
+                               return this.functions( function( val ) {\r
+                                       return cssLengthRegex.test( CKEDITOR.tools.trim( val ) );\r
+                               }, msg );\r
+                       },\r
+\r
+                       'htmlLength': function( msg ) {\r
+                               return this.functions( function( val ) {\r
+                                       return htmlLengthRegex.test( CKEDITOR.tools.trim( val ) );\r
+                               }, msg );\r
+                       },\r
+\r
+                       'inlineStyle': function( msg ) {\r
+                               return this.functions( function( val ) {\r
+                                       return inlineStyleRegex.test( CKEDITOR.tools.trim( val ) );\r
+                               }, msg );\r
+                       },\r
+\r
+                       equals: function( value, msg ) {\r
+                               return this.functions( function( val ) {\r
+                                       return val == value;\r
+                               }, msg );\r
+                       },\r
+\r
+                       notEqual: function( value, msg ) {\r
+                               return this.functions( function( val ) {\r
+                                       return val != value;\r
+                               }, msg );\r
+                       }\r
+               };\r
+\r
+               CKEDITOR.on( 'instanceDestroyed', function( evt ) {\r
+                       // Remove dialog cover on last instance destroy.\r
+                       if ( CKEDITOR.tools.isEmpty( CKEDITOR.instances ) ) {\r
+                               var currentTopDialog;\r
+                               while ( ( currentTopDialog = CKEDITOR.dialog._.currentTop ) )\r
+                                       currentTopDialog.hide();\r
+                               removeCovers();\r
+                       }\r
+\r
+                       var dialogs = evt.editor._.storedDialogs;\r
+                       for ( var name in dialogs )\r
+                               dialogs[ name ].destroy();\r
+\r
+               } );\r
+\r
+       } )();\r
+\r
+       // Extend the CKEDITOR.editor class with dialog specific functions.\r
+       CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {\r
+               /**\r
+                * Loads and opens a registered dialog.\r
+                *\r
+                *              CKEDITOR.instances.editor1.openDialog( 'smiley' );\r
+                *\r
+                * @member CKEDITOR.editor\r
+                * @param {String} dialogName The registered name of the dialog.\r
+                * @param {Function} callback The function to be invoked after dialog instance created.\r
+                * @returns {CKEDITOR.dialog} The dialog object corresponding to the dialog displayed.\r
+                * `null` if the dialog name is not registered.\r
+                * @see CKEDITOR.dialog#add\r
+                */\r
+               openDialog: function( dialogName, callback ) {\r
+                       var dialog = null, dialogDefinitions = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];\r
+\r
+                       if ( CKEDITOR.dialog._.currentTop === null )\r
+                               showCover( this );\r
+\r
+                       // If the dialogDefinition is already loaded, open it immediately.\r
+                       if ( typeof dialogDefinitions == 'function' ) {\r
+                               var storedDialogs = this._.storedDialogs || ( this._.storedDialogs = {} );\r
+\r
+                               dialog = storedDialogs[ dialogName ] || ( storedDialogs[ dialogName ] = new CKEDITOR.dialog( this, dialogName ) );\r
+\r
+                               callback && callback.call( dialog, dialog );\r
+                               dialog.show();\r
+\r
+                       } else if ( dialogDefinitions == 'failed' ) {\r
+                               hideCover( this );\r
+                               throw new Error( '[CKEDITOR.dialog.openDialog] Dialog "' + dialogName + '" failed when loading definition.' );\r
+                       } else if ( typeof dialogDefinitions == 'string' ) {\r
+\r
+                               CKEDITOR.scriptLoader.load( CKEDITOR.getUrl( dialogDefinitions ),\r
+                                       function() {\r
+                                               var dialogDefinition = CKEDITOR.dialog._.dialogDefinitions[ dialogName ];\r
+                                               // In case of plugin error, mark it as loading failed.\r
+                                               if ( typeof dialogDefinition != 'function' )\r
+                                                       CKEDITOR.dialog._.dialogDefinitions[ dialogName ] = 'failed';\r
+\r
+                                               this.openDialog( dialogName, callback );\r
+                                       }, this, 0, 1 );\r
+                       }\r
+\r
+                       CKEDITOR.skin.loadPart( 'dialog' );\r
+\r
+                       return dialog;\r
+               }\r
+       } );\r
+} )();\r
+\r
+CKEDITOR.plugins.add( 'dialog', {\r
+       requires: 'dialogui',\r
+       init: function( editor ) {\r
+               editor.on( 'doubleclick', function( evt ) {\r
+                       if ( evt.data.dialog )\r
+                               editor.openDialog( evt.data.dialog );\r
+               }, null, null, 999 );\r
+       }\r
+} );\r
+\r
+// Dialog related configurations.\r
+\r
+/**\r
+ * The color of the dialog background cover. It should be a valid CSS color string.\r
+ *\r
+ *             config.dialog_backgroundCoverColor = 'rgb(255, 254, 253)';\r
+ *\r
+ * @cfg {String} [dialog_backgroundCoverColor='white']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The opacity of the dialog background cover. It should be a number within the\r
+ * range `[0.0, 1.0]`.\r
+ *\r
+ *             config.dialog_backgroundCoverOpacity = 0.7;\r
+ *\r
+ * @cfg {Number} [dialog_backgroundCoverOpacity=0.5]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * If the dialog has more than one tab, put focus into the first tab as soon as dialog is opened.\r
+ *\r
+ *             config.dialog_startupFocusTab = true;\r
+ *\r
+ * @cfg {Boolean} [dialog_startupFocusTab=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The distance of magnetic borders used in moving and resizing dialogs,\r
+ * measured in pixels.\r
+ *\r
+ *             config.dialog_magnetDistance = 30;\r
+ *\r
+ * @cfg {Number} [dialog_magnetDistance=20]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The guideline to follow when generating the dialog buttons. There are 3 possible options:\r
+ *\r
+ * * `'OS'` - the buttons will be displayed in the default order of the user's OS;\r
+ * * `'ltr'` - for Left-To-Right order;\r
+ * * `'rtl'` - for Right-To-Left order.\r
+ *\r
+ * Example:\r
+ *\r
+ *             config.dialog_buttonsOrder = 'rtl';\r
+ *\r
+ * @since 3.5\r
+ * @cfg {String} [dialog_buttonsOrder='OS']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The dialog contents to removed. It's a string composed by dialog name and tab name with a colon between them.\r
+ *\r
+ * Separate each pair with semicolon (see example).\r
+ *\r
+ * **Note:** All names are case-sensitive.\r
+ *\r
+ * **Note:** Be cautious when specifying dialog tabs that are mandatory,\r
+ * like `'info'`, dialog functionality might be broken because of this!\r
+ *\r
+ *             config.removeDialogTabs = 'flash:advanced;image:Link';\r
+ *\r
+ * @since 3.5\r
+ * @cfg {String} [removeDialogTabs='']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Tells if user should not be asked to confirm close, if any dialog field was modified.\r
+ * By default it is set to `false` meaning that the confirmation dialog will be shown.\r
+ *\r
+ *             config.dialog_noConfirmCancel = true;\r
+ *\r
+ * @since 4.3\r
+ * @cfg {Boolean} [dialog_noConfirmCancel=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog definition is about to be used to create a dialog into\r
+ * an editor instance. This event makes it possible to customize the definition\r
+ * before creating it.\r
+ *\r
+ * Note that this event is called only the first time a specific dialog is\r
+ * opened. Successive openings will use the cached dialog, and this event will\r
+ * not get fired.\r
+ *\r
+ * @event dialogDefinition\r
+ * @member CKEDITOR\r
+ * @param {CKEDITOR.dialog.definition} data The dialog defination that\r
+ * is being loaded.\r
+ * @param {CKEDITOR.editor} editor The editor instance that will use the dialog.\r
+ */\r
+\r
+/**\r
+ * Event fired when a tab is going to be selected in a dialog.\r
+ *\r
+ * @event selectPage\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {String} data.page The id of the page that it's gonna be selected.\r
+ * @param {String} data.currentPage The id of the current page.\r
+ */\r
+\r
+/**\r
+ * Event fired when the user tries to dismiss a dialog.\r
+ *\r
+ * @event cancel\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {Boolean} data.hide Whether the event should proceed or not.\r
+ */\r
+\r
+/**\r
+ * Event fired when the user tries to confirm a dialog.\r
+ *\r
+ * @event ok\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {Boolean} data.hide Whether the event should proceed or not.\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is shown.\r
+ *\r
+ * @event show\r
+ * @member CKEDITOR.dialog\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is shown.\r
+ *\r
+ * @event dialogShow\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {CKEDITOR.dialog} data The opened dialog instance.\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is hidden.\r
+ *\r
+ * @event hide\r
+ * @member CKEDITOR.dialog\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is hidden.\r
+ *\r
+ * @event dialogHide\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {CKEDITOR.dialog} data The hidden dialog instance.\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is being resized. The event is fired on\r
+ * both the {@link CKEDITOR.dialog} object and the dialog instance\r
+ * since 3.5.3, previously it was only available in the global object.\r
+ *\r
+ * @static\r
+ * @event resize\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {CKEDITOR.dialog} data.dialog The dialog being resized (if\r
+ * it is fired on the dialog itself, this parameter is not sent).\r
+ * @param {String} data.skin The skin name.\r
+ * @param {Number} data.width The new width.\r
+ * @param {Number} data.height The new height.\r
+ */\r
+\r
+/**\r
+ * Event fired when a dialog is being resized. The event is fired on\r
+ * both the {@link CKEDITOR.dialog} object and the dialog instance\r
+ * since 3.5.3, previously it was only available in the global object.\r
+ *\r
+ * @since 3.5\r
+ * @event resize\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {Number} data.width The new width.\r
+ * @param {Number} data.height The new height.\r
+ */\r
+\r
+/**\r
+ * Event fired when the dialog state changes, usually by {@link CKEDITOR.dialog#setState}.\r
+ *\r
+ * @since 4.5\r
+ * @event state\r
+ * @member CKEDITOR.dialog\r
+ * @param data\r
+ * @param {Number} data The new state. Either {@link CKEDITOR#DIALOG_STATE_IDLE} or {@link CKEDITOR#DIALOG_STATE_BUSY}.\r
+ */\r
diff --git a/sources/plugins/dialog/samples/assets/my_dialog.js b/sources/plugins/dialog/samples/assets/my_dialog.js
new file mode 100644 (file)
index 0000000..6239dea
--- /dev/null
@@ -0,0 +1,49 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.dialog.add( 'myDialog', function() {\r
+       return {\r
+               title: 'My Dialog',\r
+               minWidth: 400,\r
+               minHeight: 200,\r
+               contents: [\r
+                       {\r
+                               id: 'tab1',\r
+                               label: 'First Tab',\r
+                               title: 'First Tab',\r
+                               elements: [\r
+                                       {\r
+                                               id: 'input1',\r
+                                               type: 'text',\r
+                                               label: 'Text Field'\r
+                                       },\r
+                                       {\r
+                                               id: 'select1',\r
+                                               type: 'select',\r
+                                               label: 'Select Field',\r
+                                               items: [\r
+                                                       [ 'option1', 'value1' ],\r
+                                                       [ 'option2', 'value2' ]\r
+                                               ]\r
+                                       }\r
+                               ]\r
+                       },\r
+                       {\r
+                               id: 'tab2',\r
+                               label: 'Second Tab',\r
+                               title: 'Second Tab',\r
+                               elements: [\r
+                                       {\r
+                                               id: 'button1',\r
+                                               type: 'button',\r
+                                               label: 'Button Field'\r
+                                       }\r
+                               ]\r
+                       }\r
+               ]\r
+       };\r
+} );\r
+\r
+// %LEAVE_UNMINIFIED% %REMOVE_LINE%\r
diff --git a/sources/plugins/dialog/samples/dialog.html b/sources/plugins/dialog/samples/dialog.html
new file mode 100644 (file)
index 0000000..0f22a1a
--- /dev/null
@@ -0,0 +1,190 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Using API to Customize Dialog Windows &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-name" content="Using the JavaScript API to customize dialog windows">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Using the dialog windows API to customize dialog windows without changing the original editor code.">\r
+       <style>\r
+\r
+               .cke_button__mybutton_icon\r
+               {\r
+                       display: none !important;\r
+               }\r
+\r
+               .cke_button__mybutton_label\r
+               {\r
+                       display: inline !important;\r
+               }\r
+\r
+       </style>\r
+       <script>\r
+\r
+               CKEDITOR.on( 'instanceCreated', function( ev ){\r
+                       var editor = ev.editor;\r
+\r
+                       // Listen for the "pluginsLoaded" event, so we are sure that the\r
+                       // "dialog" plugin has been loaded and we are able to do our\r
+                       // customizations.\r
+                       editor.on( 'pluginsLoaded', function() {\r
+\r
+                               // If our custom dialog has not been registered, do that now.\r
+                               if ( !CKEDITOR.dialog.exists( 'myDialog' ) ) {\r
+                                       // We need to do the following trick to find out the dialog\r
+                                       // definition file URL path. In the real world, you would simply\r
+                                       // point to an absolute path directly, like "/mydir/mydialog.js".\r
+                                       var href = document.location.href.split( '/' );\r
+                                       href.pop();\r
+                                       href.push( 'assets/my_dialog.js' );\r
+                                       href = href.join( '/' );\r
+\r
+                                       // Finally, register the dialog.\r
+                                       CKEDITOR.dialog.add( 'myDialog', href );\r
+                               }\r
+\r
+                               // Register the command used to open the dialog.\r
+                               editor.addCommand( 'myDialogCmd', new CKEDITOR.dialogCommand( 'myDialog' ) );\r
+\r
+                               // Add the a custom toolbar buttons, which fires the above\r
+                               // command..\r
+                               editor.ui.add( 'MyButton', CKEDITOR.UI_BUTTON, {\r
+                                       label: 'My Dialog',\r
+                                       command: 'myDialogCmd'\r
+                               });\r
+                       });\r
+               });\r
+\r
+               // When opening a dialog, its "definition" is created for it, for\r
+               // each editor instance. The "dialogDefinition" event is then\r
+               // fired. We should use this event to make customizations to the\r
+               // definition of existing dialogs.\r
+               CKEDITOR.on( 'dialogDefinition', function( ev ) {\r
+                       // Take the dialog name and its definition from the event data.\r
+                       var dialogName = ev.data.name;\r
+                       var dialogDefinition = ev.data.definition;\r
+\r
+                       // Check if the definition is from the dialog we're\r
+                       // interested on (the "Link" dialog).\r
+                       if ( dialogName == 'myDialog' && ev.editor.name == 'editor2' ) {\r
+                               // Get a reference to the "Link Info" tab.\r
+                               var infoTab = dialogDefinition.getContents( 'tab1' );\r
+\r
+                               // Add a new text field to the "tab1" tab page.\r
+                               infoTab.add( {\r
+                                       type: 'text',\r
+                                       label: 'My Custom Field',\r
+                                       id: 'customField',\r
+                                       'default': 'Sample!',\r
+                                       validate: function() {\r
+                                               if ( ( /\d/ ).test( this.getValue() ) )\r
+                                                       return 'My Custom Field must not contain digits';\r
+                                       }\r
+                               });\r
+\r
+                               // Remove the "select1" field from the "tab1" tab.\r
+                               infoTab.remove( 'select1' );\r
+\r
+                               // Set the default value for "input1" field.\r
+                               var input1 = infoTab.get( 'input1' );\r
+                               input1[ 'default' ] = 'www.example.com';\r
+\r
+                               // Remove the "tab2" tab page.\r
+                               dialogDefinition.removeContents( 'tab2' );\r
+\r
+                               // Add a new tab to the "Link" dialog.\r
+                               dialogDefinition.addContents( {\r
+                                       id: 'customTab',\r
+                                       label: 'My Tab',\r
+                                       accessKey: 'M',\r
+                                       elements: [\r
+                                               {\r
+                                                       id: 'myField1',\r
+                                                       type: 'text',\r
+                                                       label: 'My Text Field'\r
+                                               },\r
+                                               {\r
+                                                       id: 'myField2',\r
+                                                       type: 'text',\r
+                                                       label: 'Another Text Field'\r
+                                               }\r
+                                       ]\r
+                               });\r
+\r
+                               // Provide the focus handler to start initial focus in "customField" field.\r
+                               dialogDefinition.onFocus = function() {\r
+                                       var urlField = this.getContentElement( 'tab1', 'customField' );\r
+                                       urlField.select();\r
+                               };\r
+                       }\r
+               });\r
+\r
+               var config = {\r
+                       extraPlugins: 'dialog',\r
+                       toolbar: [ [ 'MyButton' ] ]\r
+               };\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Using CKEditor Dialog API\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to use the\r
+                       <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.dialog">CKEditor Dialog API</a>\r
+                       to customize CKEditor dialog windows without changing the original editor code.\r
+                       The following customizations are being done in the example below:\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <p>A custom dialog is added to the editors using the <code>pluginsLoaded</code> event, from an external <a target="_blank" href="assets/my_dialog.js">dialog definition file</a>:</p>\r
+       <ol>\r
+               <li><strong>Creating a custom dialog window</strong> &ndash; "My Dialog" dialog window opened with the "My Dialog" toolbar button.</li>\r
+               <li><strong>Creating a custom button</strong> &ndash; Add button to open the dialog with "My Dialog" toolbar button.</li>\r
+       </ol>\r
+       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+       <script>\r
+               // Replace the <textarea id="editor1"> with an CKEditor instance.\r
+               CKEDITOR.replace( 'editor1', config );\r
+       </script>\r
+       <p>The below editor modify the dialog definition of the above added dialog using the <code>dialogDefinition</code> event:</p>\r
+       <ol>\r
+               <li><strong>Adding dialog tab</strong> &ndash; Add new tab "My Tab" to dialog window.</li>\r
+               <li><strong>Removing a dialog window tab</strong> &ndash; Remove "Second Tab" page from the dialog window.</li>\r
+               <li><strong>Adding dialog window fields</strong> &ndash; Add "My Custom Field" to the dialog window.</li>\r
+               <li><strong>Removing dialog window field</strong> &ndash; Remove "Select Field" selection field from the dialog window.</li>\r
+               <li><strong>Setting default values for dialog window fields</strong> &ndash; Set default value of "Text Field" text field. </li>\r
+               <li><strong>Setup initial focus for dialog window</strong> &ndash; Put initial focus on "My Custom Field" text field. </li>\r
+       </ol>\r
+       <textarea cols="80" id="editor2" name="editor2" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+       <script>\r
+\r
+               // Replace the <textarea id="editor1"> with an CKEditor instance.\r
+               CKEDITOR.replace( 'editor2', config );\r
+\r
+       </script>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/dialogadvtab/plugin.js b/sources/plugins/dialogadvtab/plugin.js
new file mode 100644 (file)
index 0000000..460b534
--- /dev/null
@@ -0,0 +1,196 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+\r
+       function setupAdvParams( element ) {\r
+               var attrName = this.att;\r
+\r
+               var value = element && element.hasAttribute( attrName ) && element.getAttribute( attrName ) || '';\r
+\r
+               if ( value !== undefined )\r
+                       this.setValue( value );\r
+       }\r
+\r
+       function commitAdvParams() {\r
+               // Dialogs may use different parameters in the commit list, so, by\r
+               // definition, we take the first CKEDITOR.dom.element available.\r
+               var element;\r
+\r
+               for ( var i = 0; i < arguments.length; i++ ) {\r
+                       if ( arguments[ i ] instanceof CKEDITOR.dom.element ) {\r
+                               element = arguments[ i ];\r
+                               break;\r
+                       }\r
+               }\r
+\r
+               if ( element ) {\r
+                       var attrName = this.att,\r
+                               value = this.getValue();\r
+\r
+                       if ( value )\r
+                               element.setAttribute( attrName, value );\r
+                       else\r
+                               element.removeAttribute( attrName, value );\r
+               }\r
+       }\r
+\r
+       var defaultTabConfig = { id: 1, dir: 1, classes: 1, styles: 1 };\r
+\r
+       CKEDITOR.plugins.add( 'dialogadvtab', {\r
+               requires: 'dialog',\r
+\r
+               // Returns allowed content rule for the content created by this plugin.\r
+               allowedContent: function( tabConfig ) {\r
+                       if ( !tabConfig )\r
+                               tabConfig = defaultTabConfig;\r
+\r
+                       var allowedAttrs = [];\r
+                       if ( tabConfig.id )\r
+                               allowedAttrs.push( 'id' );\r
+                       if ( tabConfig.dir )\r
+                               allowedAttrs.push( 'dir' );\r
+\r
+                       var allowed = '';\r
+\r
+                       if ( allowedAttrs.length )\r
+                               allowed += '[' + allowedAttrs.join( ',' ) +  ']';\r
+\r
+                       if ( tabConfig.classes )\r
+                               allowed += '(*)';\r
+                       if ( tabConfig.styles )\r
+                               allowed += '{*}';\r
+\r
+                       return allowed;\r
+               },\r
+\r
+               // @param tabConfig\r
+               // id, dir, classes, styles\r
+               createAdvancedTab: function( editor, tabConfig, element ) {\r
+                       if ( !tabConfig )\r
+                               tabConfig = defaultTabConfig;\r
+\r
+                       var lang = editor.lang.common;\r
+\r
+                       var result = {\r
+                               id: 'advanced',\r
+                               label: lang.advancedTab,\r
+                               title: lang.advancedTab,\r
+                               elements: [ {\r
+                                       type: 'vbox',\r
+                                       padding: 1,\r
+                                       children: []\r
+                               } ]\r
+                       };\r
+\r
+                       var contents = [];\r
+\r
+                       if ( tabConfig.id || tabConfig.dir ) {\r
+                               if ( tabConfig.id ) {\r
+                                       contents.push( {\r
+                                               id: 'advId',\r
+                                               att: 'id',\r
+                                               type: 'text',\r
+                                               requiredContent: element ? element + '[id]' : null,\r
+                                               label: lang.id,\r
+                                               setup: setupAdvParams,\r
+                                               commit: commitAdvParams\r
+                                       } );\r
+                               }\r
+\r
+                               if ( tabConfig.dir ) {\r
+                                       contents.push( {\r
+                                               id: 'advLangDir',\r
+                                               att: 'dir',\r
+                                               type: 'select',\r
+                                               requiredContent: element ? element + '[dir]' : null,\r
+                                               label: lang.langDir,\r
+                                               'default': '',\r
+                                               style: 'width:100%',\r
+                                               items: [\r
+                                                       [ lang.notSet, '' ],\r
+                                                       [ lang.langDirLTR, 'ltr' ],\r
+                                                       [ lang.langDirRTL, 'rtl' ]\r
+                                               ],\r
+                                               setup: setupAdvParams,\r
+                                               commit: commitAdvParams\r
+                                       } );\r
+                               }\r
+\r
+                               result.elements[ 0 ].children.push( {\r
+                                       type: 'hbox',\r
+                                       widths: [ '50%', '50%' ],\r
+                                       children: [].concat( contents )\r
+                               } );\r
+                       }\r
+\r
+                       if ( tabConfig.styles || tabConfig.classes ) {\r
+                               contents = [];\r
+\r
+                               if ( tabConfig.styles ) {\r
+                                       contents.push( {\r
+                                               id: 'advStyles',\r
+                                               att: 'style',\r
+                                               type: 'text',\r
+                                               requiredContent: element ? element + '{cke-xyz}' : null,\r
+                                               label: lang.styles,\r
+                                               'default': '',\r
+\r
+                                               validate: CKEDITOR.dialog.validate.inlineStyle( lang.invalidInlineStyle ),\r
+                                               onChange: function() {},\r
+\r
+                                               getStyle: function( name, defaultValue ) {\r
+                                                       var match = this.getValue().match( new RegExp( '(?:^|;)\\s*' + name + '\\s*:\\s*([^;]*)', 'i' ) );\r
+                                                       return match ? match[ 1 ] : defaultValue;\r
+                                               },\r
+\r
+                                               updateStyle: function( name, value ) {\r
+                                                       var styles = this.getValue();\r
+\r
+                                                       var tmp = editor.document.createElement( 'span' );\r
+                                                       tmp.setAttribute( 'style', styles );\r
+                                                       tmp.setStyle( name, value );\r
+                                                       styles = CKEDITOR.tools.normalizeCssText( tmp.getAttribute( 'style' ) );\r
+\r
+                                                       this.setValue( styles, 1 );\r
+                                               },\r
+\r
+                                               setup: setupAdvParams,\r
+\r
+                                               commit: commitAdvParams\r
+\r
+                                       } );\r
+                               }\r
+\r
+                               if ( tabConfig.classes ) {\r
+                                       contents.push( {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '55%' ],\r
+                                               children: [ {\r
+                                                       id: 'advCSSClasses',\r
+                                                       att: 'class',\r
+                                                       type: 'text',\r
+                                                       requiredContent: element ? element + '(cke-xyz)' : null,\r
+                                                       label: lang.cssClasses,\r
+                                                       'default': '',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               } ]\r
+                                       } );\r
+                               }\r
+\r
+                               result.elements[ 0 ].children.push( {\r
+                                       type: 'hbox',\r
+                                       widths: [ '50%', '50%' ],\r
+                                       children: [].concat( contents )\r
+                               } );\r
+                       }\r
+\r
+                       return result;\r
+               }\r
+       } );\r
+\r
+} )();\r
diff --git a/sources/plugins/dialogui/plugin.js b/sources/plugins/dialogui/plugin.js
new file mode 100644 (file)
index 0000000..cf91407
--- /dev/null
@@ -0,0 +1,1530 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The Dialog User Interface plugin.\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'dialogui', {\r
+       onLoad: function() {\r
+\r
+               var initPrivateObject = function( elementDefinition ) {\r
+                               this._ || ( this._ = {} );\r
+                               this._[ 'default' ] = this._.initValue = elementDefinition[ 'default' ] || '';\r
+                               this._.required = elementDefinition.required || false;\r
+                               var args = [ this._ ];\r
+                               for ( var i = 1; i < arguments.length; i++ )\r
+                                       args.push( arguments[ i ] );\r
+                               args.push( true );\r
+                               CKEDITOR.tools.extend.apply( CKEDITOR.tools, args );\r
+                               return this._;\r
+                       },\r
+                       textBuilder = {\r
+                               build: function( dialog, elementDefinition, output ) {\r
+                                       return new CKEDITOR.ui.dialog.textInput( dialog, elementDefinition, output );\r
+                               }\r
+                       },\r
+                       commonBuilder = {\r
+                               build: function( dialog, elementDefinition, output ) {\r
+                                       return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, elementDefinition, output );\r
+                               }\r
+                       },\r
+                       containerBuilder = {\r
+                               build: function( dialog, elementDefinition, output ) {\r
+                                       var children = elementDefinition.children,\r
+                                               child,\r
+                                               childHtmlList = [],\r
+                                               childObjList = [];\r
+                                       for ( var i = 0;\r
+                                       ( i < children.length && ( child = children[ i ] ) ); i++ ) {\r
+                                               var childHtml = [];\r
+                                               childHtmlList.push( childHtml );\r
+                                               childObjList.push( CKEDITOR.dialog._.uiElementBuilders[ child.type ].build( dialog, child, childHtml ) );\r
+                                       }\r
+                                       return new CKEDITOR.ui.dialog[ elementDefinition.type ]( dialog, childObjList, childHtmlList, output, elementDefinition );\r
+                               }\r
+                       },\r
+                       commonPrototype = {\r
+                               isChanged: function() {\r
+                                       return this.getValue() != this.getInitValue();\r
+                               },\r
+\r
+                               reset: function( noChangeEvent ) {\r
+                                       this.setValue( this.getInitValue(), noChangeEvent );\r
+                               },\r
+\r
+                               setInitValue: function() {\r
+                                       this._.initValue = this.getValue();\r
+                               },\r
+\r
+                               resetInitValue: function() {\r
+                                       this._.initValue = this._[ 'default' ];\r
+                               },\r
+\r
+                               getInitValue: function() {\r
+                                       return this._.initValue;\r
+                               }\r
+                       },\r
+                       commonEventProcessors = CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, {\r
+                               onChange: function( dialog, func ) {\r
+                                       if ( !this._.domOnChangeRegistered ) {\r
+                                               dialog.on( 'load', function() {\r
+                                                       this.getInputElement().on( 'change', function() {\r
+                                                               // Make sure 'onchange' doesn't get fired after dialog closed. (#5719)\r
+                                                               if ( !dialog.parts.dialog.isVisible() )\r
+                                                                       return;\r
+\r
+                                                               this.fire( 'change', { value: this.getValue() } );\r
+                                                       }, this );\r
+                                               }, this );\r
+                                               this._.domOnChangeRegistered = true;\r
+                                       }\r
+\r
+                                       this.on( 'change', func );\r
+                               }\r
+                       }, true ),\r
+                       eventRegex = /^on([A-Z]\w+)/,\r
+                       cleanInnerDefinition = function( def ) {\r
+                               // An inner UI element should not have the parent's type, title or events.\r
+                               for ( var i in def ) {\r
+                                       if ( eventRegex.test( i ) || i == 'title' || i == 'type' )\r
+                                               delete def[ i ];\r
+                               }\r
+                               return def;\r
+                       },\r
+                       // @context {CKEDITOR.dialog.uiElement} UI element (textarea or textInput)\r
+                       // @param {CKEDITOR.dom.event} evt\r
+                       toggleBidiKeyUpHandler = function( evt ) {\r
+                               var keystroke = evt.data.getKeystroke();\r
+\r
+                               // ALT + SHIFT + Home for LTR direction.\r
+                               if ( keystroke == CKEDITOR.SHIFT + CKEDITOR.ALT + 36 )\r
+                                       this.setDirectionMarker( 'ltr' );\r
+\r
+                               // ALT + SHIFT + End for RTL direction.\r
+                               else if ( keystroke == CKEDITOR.SHIFT + CKEDITOR.ALT + 35 )\r
+                                       this.setDirectionMarker( 'rtl' );\r
+                       };\r
+\r
+               CKEDITOR.tools.extend( CKEDITOR.ui.dialog, {\r
+                       /**\r
+                        * Base class for all dialog window elements with a textual label on the left.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.labeledElement\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a labeledElement class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `label` (Required) The label string.\r
+                        * * `labelLayout` (Optional) Put 'horizontal' here if the\r
+                        *     label element is to be laid out horizontally. Otherwise a vertical\r
+                        *     layout will be used.\r
+                        * * `widths` (Optional) This applies only to horizontal\r
+                        *     layouts &mdash; a two-element array of lengths to specify the widths of the\r
+                        *     label and the content element.\r
+                        * * `role` (Optional) Value for the `role` attribute.\r
+                        * * `includeLabel` (Optional) If set to `true`, the `aria-labelledby` attribute\r
+                        *     will be included.\r
+                        *\r
+                        * @param {Array} htmlList The list of HTML code to output to.\r
+                        * @param {Function} contentHtml\r
+                        * A function returning the HTML code string to be added inside the content\r
+                        * cell.\r
+                        */\r
+                       labeledElement: function( dialog, elementDefinition, htmlList, contentHtml ) {\r
+                               if ( arguments.length < 4 )\r
+                                       return;\r
+\r
+                               var _ = initPrivateObject.call( this, elementDefinition );\r
+                               _.labelId = CKEDITOR.tools.getNextId() + '_label';\r
+                               this._.children = [];\r
+\r
+                               var innerHTML = function() {\r
+                                               var html = [],\r
+                                                       requiredClass = elementDefinition.required ? ' cke_required' : '';\r
+                                               if ( elementDefinition.labelLayout != 'horizontal' ) {\r
+                                                       html.push(\r
+                                                               '<label class="cke_dialog_ui_labeled_label' + requiredClass + '" ', ' id="' + _.labelId + '"',\r
+                                                                       ( _.inputId ? ' for="' + _.inputId + '"' : '' ),\r
+                                                                       ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>',\r
+                                                                       elementDefinition.label,\r
+                                                               '</label>',\r
+                                                               '<div class="cke_dialog_ui_labeled_content"',\r
+                                                                       ( elementDefinition.controlStyle ? ' style="' + elementDefinition.controlStyle + '"' : '' ),\r
+                                                                       ' role="presentation">',\r
+                                                                       contentHtml.call( this, dialog, elementDefinition ),\r
+                                                               '</div>' );\r
+                                               } else {\r
+                                                       var hboxDefinition = {\r
+                                                               type: 'hbox',\r
+                                                               widths: elementDefinition.widths,\r
+                                                               padding: 0,\r
+                                                               children: [ {\r
+                                                                       type: 'html',\r
+                                                                       html: '<label class="cke_dialog_ui_labeled_label' + requiredClass + '"' +\r
+                                                                               ' id="' + _.labelId + '"' +\r
+                                                                               ' for="' + _.inputId + '"' +\r
+                                                                               ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>' +\r
+                                                                                       CKEDITOR.tools.htmlEncode( elementDefinition.label ) +\r
+                                                                               '</label>'\r
+                                                               },\r
+                                                               {\r
+                                                                       type: 'html',\r
+                                                                       html: '<span class="cke_dialog_ui_labeled_content"' + ( elementDefinition.controlStyle ? ' style="' + elementDefinition.controlStyle + '"' : '' ) + '>' +\r
+                                                                               contentHtml.call( this, dialog, elementDefinition ) +\r
+                                                                               '</span>'\r
+                                                               } ]\r
+                                                       };\r
+                                                       CKEDITOR.dialog._.uiElementBuilders.hbox.build( dialog, hboxDefinition, html );\r
+                                               }\r
+                                               return html.join( '' );\r
+                                       };\r
+                               var attributes = { role: elementDefinition.role || 'presentation' };\r
+\r
+                               if ( elementDefinition.includeLabel )\r
+                                       attributes[ 'aria-labelledby' ] = _.labelId;\r
+\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'div', null, attributes, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A text input with a label. This UI element class represents both the\r
+                        * single-line text inputs and password inputs in dialog boxes.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.textInput\r
+                        * @extends CKEDITOR.ui.dialog.labeledElement\r
+                        * @constructor Creates a textInput class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `default` (Optional) The default value.\r
+                        * * `validate` (Optional) The validation function.\r
+                        * * `maxLength` (Optional) The maximum length of text box contents.\r
+                        * * `size` (Optional) The size of the text box. This is\r
+                        *     usually overridden by the size defined by the skin, though.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       textInput: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               initPrivateObject.call( this, elementDefinition );\r
+                               var domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textInput',\r
+                                       attributes = { 'class': 'cke_dialog_ui_input_' + elementDefinition.type, id: domId, type: elementDefinition.type };\r
+\r
+                               // Set the validator, if any.\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               // Set the max length and size.\r
+                               if ( elementDefinition.maxLength )\r
+                                       attributes.maxlength = elementDefinition.maxLength;\r
+                               if ( elementDefinition.size )\r
+                                       attributes.size = elementDefinition.size;\r
+\r
+                               if ( elementDefinition.inputStyle )\r
+                                       attributes.style = elementDefinition.inputStyle;\r
+\r
+                               // If user presses Enter in a text box, it implies clicking OK for the dialog.\r
+                               var me = this,\r
+                                       keyPressedOnMe = false;\r
+                               dialog.on( 'load', function() {\r
+                                       me.getInputElement().on( 'keydown', function( evt ) {\r
+                                               if ( evt.data.getKeystroke() == 13 )\r
+                                                       keyPressedOnMe = true;\r
+                                       } );\r
+\r
+                                       // Lower the priority this 'keyup' since 'ok' will close the dialog.(#3749)\r
+                                       me.getInputElement().on( 'keyup', function( evt ) {\r
+                                               if ( evt.data.getKeystroke() == 13 && keyPressedOnMe ) {\r
+                                                       dialog.getButton( 'ok' ) && setTimeout( function() {\r
+                                                               dialog.getButton( 'ok' ).click();\r
+                                                       }, 0 );\r
+                                                       keyPressedOnMe = false;\r
+                                               }\r
+\r
+                                               if ( me.bidi )\r
+                                                       toggleBidiKeyUpHandler.call( me, evt );\r
+                                       }, null, null, 1000 );\r
+                               } );\r
+\r
+                               var innerHTML = function() {\r
+                                               // IE BUG: Text input fields in IE at 100% would exceed a <td> or inline\r
+                                               // container's width, so need to wrap it inside a <div>.\r
+                                               var html = [ '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' ];\r
+\r
+                                               if ( elementDefinition.width )\r
+                                                       html.push( 'style="width:' + elementDefinition.width + '" ' );\r
+\r
+                                               html.push( '><input ' );\r
+\r
+                                               attributes[ 'aria-labelledby' ] = this._.labelId;\r
+                                               this._.required && ( attributes[ 'aria-required' ] = this._.required );\r
+                                               for ( var i in attributes )\r
+                                                       html.push( i + '="' + attributes[ i ] + '" ' );\r
+                                               html.push( ' /></div>' );\r
+                                               return html.join( '' );\r
+                                       };\r
+                               CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A text area with a label at the top or on the left.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.textarea\r
+                        * @extends CKEDITOR.ui.dialog.labeledElement\r
+                        * @constructor Creates a textarea class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        *\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `rows` (Optional) The number of rows displayed.\r
+                        *     Defaults to 5 if not defined.\r
+                        * * `cols` (Optional) The number of cols displayed.\r
+                        *     Defaults to 20 if not defined. Usually overridden by skins.\r
+                        * * `default` (Optional) The default value.\r
+                        * * `validate` (Optional) The validation function.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       textarea: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               initPrivateObject.call( this, elementDefinition );\r
+                               var me = this,\r
+                                       domId = this._.inputId = CKEDITOR.tools.getNextId() + '_textarea',\r
+                                       attributes = {};\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               // Generates the essential attributes for the textarea tag.\r
+                               attributes.rows = elementDefinition.rows || 5;\r
+                               attributes.cols = elementDefinition.cols || 20;\r
+\r
+                               attributes[ 'class' ] = 'cke_dialog_ui_input_textarea ' + ( elementDefinition[ 'class' ] || '' );\r
+\r
+                               if ( typeof elementDefinition.inputStyle != 'undefined' )\r
+                                       attributes.style = elementDefinition.inputStyle;\r
+\r
+                               if ( elementDefinition.dir )\r
+                                       attributes.dir = elementDefinition.dir;\r
+\r
+                               if ( me.bidi ) {\r
+                                       dialog.on( 'load', function() {\r
+                                               me.getInputElement().on( 'keyup', toggleBidiKeyUpHandler );\r
+                                       }, me );\r
+                               }\r
+\r
+                               var innerHTML = function() {\r
+                                               attributes[ 'aria-labelledby' ] = this._.labelId;\r
+                                               this._.required && ( attributes[ 'aria-required' ] = this._.required );\r
+                                               var html = [ '<div class="cke_dialog_ui_input_textarea" role="presentation"><textarea id="', domId, '" ' ];\r
+                                               for ( var i in attributes )\r
+                                                       html.push( i + '="' + CKEDITOR.tools.htmlEncode( attributes[ i ] ) + '" ' );\r
+                                               html.push( '>', CKEDITOR.tools.htmlEncode( me._[ 'default' ] ), '</textarea></div>' );\r
+                                               return html.join( '' );\r
+                                       };\r
+                               CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A single checkbox with a label on the right.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.checkbox\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a checkbox class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `checked` (Optional) Whether the checkbox is checked\r
+                        *     on instantiation. Defaults to `false`.\r
+                        * * `validate` (Optional) The validation function.\r
+                        * * `label` (Optional) The checkbox label.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       checkbox: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               var _ = initPrivateObject.call( this, elementDefinition, { 'default': !!elementDefinition[ 'default' ] } );\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               var innerHTML = function() {\r
+                                               var myDefinition = CKEDITOR.tools.extend(\r
+                                                               {},\r
+                                                               elementDefinition,\r
+                                                               {\r
+                                                                       id: elementDefinition.id ? elementDefinition.id + '_checkbox' : CKEDITOR.tools.getNextId() + '_checkbox'\r
+                                                               },\r
+                                                               true\r
+                                                       ),\r
+                                                       html = [];\r
+\r
+                                               var labelId = CKEDITOR.tools.getNextId() + '_label';\r
+                                               var attributes = { 'class': 'cke_dialog_ui_checkbox_input', type: 'checkbox', 'aria-labelledby': labelId };\r
+                                               cleanInnerDefinition( myDefinition );\r
+                                               if ( elementDefinition[ 'default' ] )\r
+                                                       attributes.checked = 'checked';\r
+\r
+                                               if ( typeof myDefinition.inputStyle != 'undefined' )\r
+                                                       myDefinition.style = myDefinition.inputStyle;\r
+\r
+                                               _.checkbox = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'input', null, attributes );\r
+                                               html.push(\r
+                                                       ' <label id="',\r
+                                                       labelId,\r
+                                                       '" for="',\r
+                                                       attributes.id,\r
+                                                       '"' + ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) + '>',\r
+                                                       CKEDITOR.tools.htmlEncode( elementDefinition.label ),\r
+                                                       '</label>'\r
+                                               );\r
+                                               return html.join( '' );\r
+                                       };\r
+\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'span', null, null, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A group of radio buttons.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.radio\r
+                        * @extends CKEDITOR.ui.dialog.labeledElement\r
+                        * @constructor Creates a radio class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `default` (Required) The default value.\r
+                        * * `validate` (Optional) The validation function.\r
+                        * * `items` (Required) An array of options. Each option\r
+                        *     is a one- or two-item array of format `[ 'Description', 'Value' ]`. If `'Value'`\r
+                        *     is missing, then the value would be assumed to be the same as the description.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       radio: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               initPrivateObject.call( this, elementDefinition );\r
+\r
+                               if ( !this._[ 'default' ] )\r
+                                       this._[ 'default' ] = this._.initValue = elementDefinition.items[ 0 ][ 1 ];\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               var children = [],\r
+                                       me = this;\r
+\r
+                               var innerHTML = function() {\r
+                                       var inputHtmlList = [],\r
+                                               html = [],\r
+                                               commonName = ( elementDefinition.id ? elementDefinition.id : CKEDITOR.tools.getNextId() ) + '_radio';\r
+\r
+                                       for ( var i = 0; i < elementDefinition.items.length; i++ ) {\r
+                                               var item = elementDefinition.items[ i ],\r
+                                                       title = item[ 2 ] !== undefined ? item[ 2 ] : item[ 0 ],\r
+                                                       value = item[ 1 ] !== undefined ? item[ 1 ] : item[ 0 ],\r
+                                                       inputId = CKEDITOR.tools.getNextId() + '_radio_input',\r
+                                                       labelId = inputId + '_label',\r
+\r
+                                                       inputDefinition = CKEDITOR.tools.extend( {}, elementDefinition, {\r
+                                                               id: inputId,\r
+                                                               title: null,\r
+                                                               type: null\r
+                                                       }, true ),\r
+\r
+                                                       labelDefinition = CKEDITOR.tools.extend( {}, inputDefinition, {\r
+                                                               title: title\r
+                                                       }, true ),\r
+\r
+                                                       inputAttributes = {\r
+                                                               type: 'radio',\r
+                                                               'class': 'cke_dialog_ui_radio_input',\r
+                                                               name: commonName,\r
+                                                               value: value,\r
+                                                               'aria-labelledby': labelId\r
+                                                       },\r
+\r
+                                                       inputHtml = [];\r
+\r
+                                               if ( me._[ 'default' ] == value )\r
+                                                       inputAttributes.checked = 'checked';\r
+\r
+                                               cleanInnerDefinition( inputDefinition );\r
+                                               cleanInnerDefinition( labelDefinition );\r
+\r
+                                               if ( typeof inputDefinition.inputStyle != 'undefined' )\r
+                                                       inputDefinition.style = inputDefinition.inputStyle;\r
+\r
+                                               // Make inputs of radio type focusable (#10866).\r
+                                               inputDefinition.keyboardFocusable = true;\r
+\r
+                                               children.push( new CKEDITOR.ui.dialog.uiElement( dialog, inputDefinition, inputHtml, 'input', null, inputAttributes ) );\r
+\r
+                                               inputHtml.push( ' ' );\r
+\r
+                                               new CKEDITOR.ui.dialog.uiElement( dialog, labelDefinition, inputHtml, 'label', null, {\r
+                                                       id: labelId,\r
+                                                       'for': inputAttributes.id\r
+                                               }, item[ 0 ] );\r
+\r
+                                               inputHtmlList.push( inputHtml.join( '' ) );\r
+                                       }\r
+\r
+                                       new CKEDITOR.ui.dialog.hbox( dialog, children, inputHtmlList, html );\r
+\r
+                                       return html.join( '' );\r
+                               };\r
+\r
+                               // Adding a role="radiogroup" to definition used for wrapper.\r
+                               elementDefinition.role = 'radiogroup';\r
+                               elementDefinition.includeLabel = true;\r
+\r
+                               CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );\r
+                               this._.children = children;\r
+                       },\r
+\r
+                       /**\r
+                        * A button with a label inside.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.button\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a button class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `label` (Required) The button label.\r
+                        * * `disabled` (Optional) Set to `true` if you want the\r
+                        *     button to appear in the disabled state.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       button: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( !arguments.length )\r
+                                       return;\r
+\r
+                               if ( typeof elementDefinition == 'function' )\r
+                                       elementDefinition = elementDefinition( dialog.getParentEditor() );\r
+\r
+                               initPrivateObject.call( this, elementDefinition, { disabled: elementDefinition.disabled || false } );\r
+\r
+                               // Add OnClick event to this input.\r
+                               CKEDITOR.event.implementOn( this );\r
+\r
+                               var me = this;\r
+\r
+                               // Register an event handler for processing button clicks.\r
+                               dialog.on( 'load', function() {\r
+                                       var element = this.getElement();\r
+\r
+                                       ( function() {\r
+                                               element.on( 'click', function( evt ) {\r
+                                                       me.click();\r
+                                                       // #9958\r
+                                                       evt.data.preventDefault();\r
+                                               } );\r
+\r
+                                               element.on( 'keydown', function( evt ) {\r
+                                                       if ( evt.data.getKeystroke() in { 32: 1 } ) {\r
+                                                               me.click();\r
+                                                               evt.data.preventDefault();\r
+                                                       }\r
+                                               } );\r
+                                       } )();\r
+\r
+                                       element.unselectable();\r
+                               }, this );\r
+\r
+                               var outerDefinition = CKEDITOR.tools.extend( {}, elementDefinition );\r
+                               delete outerDefinition.style;\r
+\r
+                               var labelId = CKEDITOR.tools.getNextId() + '_label';\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, outerDefinition, htmlList, 'a', null, {\r
+                                       style: elementDefinition.style,\r
+                                       href: 'javascript:void(0)', // jshint ignore:line\r
+                                       title: elementDefinition.label,\r
+                                       hidefocus: 'true',\r
+                                       'class': elementDefinition[ 'class' ],\r
+                                       role: 'button',\r
+                                       'aria-labelledby': labelId\r
+                               }, '<span id="' + labelId + '" class="cke_dialog_ui_button">' +\r
+                                                                                       CKEDITOR.tools.htmlEncode( elementDefinition.label ) +\r
+                                                                               '</span>' );\r
+                       },\r
+\r
+                       /**\r
+                        * A select box.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.select\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a button class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `default` (Required) The default value.\r
+                        * * `validate` (Optional) The validation function.\r
+                        * * `items` (Required) An array of options. Each option\r
+                        *     is a one- or two-item array of format `[ 'Description', 'Value' ]`. If `'Value'`\r
+                        *     is missing, then the value would be assumed to be the same as the\r
+                        *     description.\r
+                        * * `multiple` (Optional) Set this to `true` if you would like\r
+                        *     to have a multiple-choice select box.\r
+                        * * `size` (Optional) The number of items to display in\r
+                        *     the select box.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       select: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               var _ = initPrivateObject.call( this, elementDefinition );\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               _.inputId = CKEDITOR.tools.getNextId() + '_select';\r
+\r
+                               var innerHTML = function() {\r
+                                               var myDefinition = CKEDITOR.tools.extend(\r
+                                                               {},\r
+                                                               elementDefinition,\r
+                                                               {\r
+                                                                       id: ( elementDefinition.id ? elementDefinition.id + '_select' : CKEDITOR.tools.getNextId() + '_select' )\r
+                                                               },\r
+                                                               true\r
+                                                       ),\r
+                                                       html = [],\r
+                                                       innerHTML = [],\r
+                                                       attributes = { 'id': _.inputId, 'class': 'cke_dialog_ui_input_select', 'aria-labelledby': this._.labelId };\r
+\r
+                                               html.push( '<div class="cke_dialog_ui_input_', elementDefinition.type, '" role="presentation"' );\r
+                                               if ( elementDefinition.width )\r
+                                                       html.push( 'style="width:' + elementDefinition.width + '" ' );\r
+                                               html.push( '>' );\r
+\r
+                                               // Add multiple and size attributes from element definition.\r
+                                               if ( elementDefinition.size !== undefined )\r
+                                                       attributes.size = elementDefinition.size;\r
+                                               if ( elementDefinition.multiple !== undefined )\r
+                                                       attributes.multiple = elementDefinition.multiple;\r
+\r
+                                               cleanInnerDefinition( myDefinition );\r
+                                               for ( var i = 0, item; i < elementDefinition.items.length && ( item = elementDefinition.items[ i ] ); i++ ) {\r
+                                                       innerHTML.push( '<option value="', CKEDITOR.tools.htmlEncode( item[ 1 ] !== undefined ? item[ 1 ] : item[ 0 ] ).replace( /"/g, '&quot;' ), '" /> ', CKEDITOR.tools.htmlEncode( item[ 0 ] ) );\r
+                                               }\r
+\r
+                                               if ( typeof myDefinition.inputStyle != 'undefined' )\r
+                                                       myDefinition.style = myDefinition.inputStyle;\r
+\r
+                                               _.select = new CKEDITOR.ui.dialog.uiElement( dialog, myDefinition, html, 'select', null, attributes, innerHTML.join( '' ) );\r
+\r
+                                               html.push( '</div>' );\r
+\r
+                                               return html.join( '' );\r
+                                       };\r
+\r
+                               CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A file upload input.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.file\r
+                        * @extends CKEDITOR.ui.dialog.labeledElement\r
+                        * @constructor Creates a file class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `validate` (Optional) The validation function.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       file: function( dialog, elementDefinition, htmlList ) {\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               if ( elementDefinition[ 'default' ] === undefined )\r
+                                       elementDefinition[ 'default' ] = '';\r
+\r
+                               var _ = CKEDITOR.tools.extend( initPrivateObject.call( this, elementDefinition ), { definition: elementDefinition, buttons: [] } );\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               /** @ignore */\r
+                               var innerHTML = function() {\r
+                                       _.frameId = CKEDITOR.tools.getNextId() + '_fileInput';\r
+\r
+                                       var html = [\r
+                                               '<iframe' +\r
+                                                       ' frameborder="0"' +\r
+                                                       ' allowtransparency="0"' +\r
+                                                       ' class="cke_dialog_ui_input_file"' +\r
+                                                       ' role="presentation"' +\r
+                                                       ' id="', _.frameId, '"' +\r
+                                                       ' title="', elementDefinition.label, '"' +\r
+                                                       ' src="javascript:void('\r
+                                       ];\r
+\r
+                                       // Support for custom document.domain on IE. (#10165)\r
+                                       html.push( CKEDITOR.env.ie ?\r
+                                               '(function(){' + encodeURIComponent(\r
+                                                       'document.open();' +\r
+                                                       '(' + CKEDITOR.tools.fixDomain + ')();' +\r
+                                                       'document.close();'\r
+                                               ) + '})()'\r
+                                               :\r
+                                               '0'\r
+                                       );\r
+\r
+                                       html.push( ')"></iframe>' );\r
+\r
+                                       return html.join( '' );\r
+                               };\r
+\r
+                               // IE BUG: Parent container does not resize to contain the iframe automatically.\r
+                               dialog.on( 'load', function() {\r
+                                       var iframe = CKEDITOR.document.getById( _.frameId ),\r
+                                               contentDiv = iframe.getParent();\r
+                                       contentDiv.addClass( 'cke_dialog_ui_input_file' );\r
+                               } );\r
+\r
+                               CKEDITOR.ui.dialog.labeledElement.call( this, dialog, elementDefinition, htmlList, innerHTML );\r
+                       },\r
+\r
+                       /**\r
+                        * A button for submitting the file in a file upload input.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.fileButton\r
+                        * @extends CKEDITOR.ui.dialog.button\r
+                        * @constructor Creates a fileButton class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `for` (Required) The file input's page and element ID\r
+                        *     to associate with, in a two-item array format: `[ 'page_id', 'element_id' ]`.\r
+                        * * `validate` (Optional) The validation function.\r
+                        *\r
+                        * @param {Array} htmlList List of HTML code to output to.\r
+                        */\r
+                       fileButton: function( dialog, elementDefinition, htmlList ) {\r
+                               var me = this;\r
+                               if ( arguments.length < 3 )\r
+                                       return;\r
+\r
+                               initPrivateObject.call( this, elementDefinition );\r
+\r
+                               if ( elementDefinition.validate )\r
+                                       this.validate = elementDefinition.validate;\r
+\r
+                               var myDefinition = CKEDITOR.tools.extend( {}, elementDefinition );\r
+                               var onClick = myDefinition.onClick;\r
+                               myDefinition.className = ( myDefinition.className ? myDefinition.className + ' ' : '' ) + 'cke_dialog_ui_button';\r
+                               myDefinition.onClick = function( evt ) {\r
+                                       var target = elementDefinition[ 'for' ]; // [ pageId, elementId ]\r
+                                       if ( !onClick || onClick.call( this, evt ) !== false ) {\r
+                                               dialog.getContentElement( target[ 0 ], target[ 1 ] ).submit();\r
+                                               this.disable();\r
+                                       }\r
+                               };\r
+\r
+                               dialog.on( 'load', function() {\r
+                                       dialog.getContentElement( elementDefinition[ 'for' ][ 0 ], elementDefinition[ 'for' ][ 1 ] )._.buttons.push( me );\r
+                               } );\r
+\r
+                               CKEDITOR.ui.dialog.button.call( this, dialog, myDefinition, htmlList );\r
+                       },\r
+\r
+                       html: ( function() {\r
+                               var myHtmlRe = /^\s*<[\w:]+\s+([^>]*)?>/,\r
+                                       theirHtmlRe = /^(\s*<[\w:]+(?:\s+[^>]*)?)((?:.|\r|\n)+)$/,\r
+                                       emptyTagRe = /\/$/;\r
+                               /**\r
+                                * A dialog window element made from raw HTML code.\r
+                                *\r
+                                * @class CKEDITOR.ui.dialog.html\r
+                                * @extends CKEDITOR.ui.dialog.uiElement\r
+                                * @constructor Creates a html class instance.\r
+                                * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                                * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition Element definition.\r
+                                * Accepted fields:\r
+                                *\r
+                                * * `html` (Required) HTML code of this element.\r
+                                *\r
+                                * @param {Array} htmlList List of HTML code to be added to the dialog's content area.\r
+                                */\r
+                               return function( dialog, elementDefinition, htmlList ) {\r
+                                       if ( arguments.length < 3 )\r
+                                               return;\r
+\r
+                                       var myHtmlList = [],\r
+                                               myHtml,\r
+                                               theirHtml = elementDefinition.html,\r
+                                               myMatch, theirMatch;\r
+\r
+                                       // If the HTML input doesn't contain any tags at the beginning, add a <span> tag around it.\r
+                                       if ( theirHtml.charAt( 0 ) != '<' )\r
+                                               theirHtml = '<span>' + theirHtml + '</span>';\r
+\r
+                                       // Look for focus function in definition.\r
+                                       var focus = elementDefinition.focus;\r
+                                       if ( focus ) {\r
+                                               var oldFocus = this.focus;\r
+                                               this.focus = function() {\r
+                                                       ( typeof focus == 'function' ? focus : oldFocus ).call( this );\r
+                                                       this.fire( 'focus' );\r
+                                               };\r
+                                               if ( elementDefinition.isFocusable ) {\r
+                                                       var oldIsFocusable = this.isFocusable;\r
+                                                       this.isFocusable = oldIsFocusable;\r
+                                               }\r
+                                               this.keyboardFocusable = true;\r
+                                       }\r
+\r
+                                       CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, myHtmlList, 'span', null, null, '' );\r
+\r
+                                       // Append the attributes created by the uiElement call to the real HTML.\r
+                                       myHtml = myHtmlList.join( '' );\r
+                                       myMatch = myHtml.match( myHtmlRe );\r
+                                       theirMatch = theirHtml.match( theirHtmlRe ) || [ '', '', '' ];\r
+\r
+                                       if ( emptyTagRe.test( theirMatch[ 1 ] ) ) {\r
+                                               theirMatch[ 1 ] = theirMatch[ 1 ].slice( 0, -1 );\r
+                                               theirMatch[ 2 ] = '/' + theirMatch[ 2 ];\r
+                                       }\r
+\r
+                                       htmlList.push( [ theirMatch[ 1 ], ' ', myMatch[ 1 ] || '', theirMatch[ 2 ] ].join( '' ) );\r
+                               };\r
+                       } )(),\r
+\r
+                       /**\r
+                        * Form fieldset for grouping dialog UI elements.\r
+                        *\r
+                        * @class CKEDITOR.ui.dialog.fieldset\r
+                        * @extends CKEDITOR.ui.dialog.uiElement\r
+                        * @constructor Creates a fieldset class instance.\r
+                        * @param {CKEDITOR.dialog} dialog Parent dialog window object.\r
+                        * @param {Array} childObjList\r
+                        * Array of {@link CKEDITOR.ui.dialog.uiElement} objects inside this container.\r
+                        * @param {Array} childHtmlList Array of HTML code that corresponds to the HTML output of all the\r
+                        * objects in childObjList.\r
+                        * @param {Array} htmlList Array of HTML code that this element will output to.\r
+                        * @param {CKEDITOR.dialog.definition.uiElement} elementDefinition\r
+                        * The element definition. Accepted fields:\r
+                        *\r
+                        * * `label` (Optional) The legend of the this fieldset.\r
+                        * * `children` (Required) An array of dialog window field definitions which will be grouped inside this fieldset.\r
+                        *\r
+                        */\r
+                       fieldset: function( dialog, childObjList, childHtmlList, htmlList, elementDefinition ) {\r
+                               var legendLabel = elementDefinition.label;\r
+                               /** @ignore */\r
+                               var innerHTML = function() {\r
+                                               var html = [];\r
+                                               legendLabel && html.push( '<legend' +\r
+                                                       ( elementDefinition.labelStyle ? ' style="' + elementDefinition.labelStyle + '"' : '' ) +\r
+                                                       '>' + legendLabel + '</legend>' );\r
+                                               for ( var i = 0; i < childHtmlList.length; i++ )\r
+                                                       html.push( childHtmlList[ i ] );\r
+                                               return html.join( '' );\r
+                                       };\r
+\r
+                               this._ = { children: childObjList };\r
+                               CKEDITOR.ui.dialog.uiElement.call( this, dialog, elementDefinition, htmlList, 'fieldset', null, null, innerHTML );\r
+                       }\r
+\r
+               }, true );\r
+\r
+               CKEDITOR.ui.dialog.html.prototype = new CKEDITOR.ui.dialog.uiElement();\r
+\r
+               /** @class CKEDITOR.ui.dialog.labeledElement */\r
+               CKEDITOR.ui.dialog.labeledElement.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {\r
+                       /**\r
+                        * Sets the label text of the element.\r
+                        *\r
+                        * @param {String} label The new label text.\r
+                        * @returns {CKEDITOR.ui.dialog.labeledElement} The current labeled element.\r
+                        */\r
+                       setLabel: function( label ) {\r
+                               var node = CKEDITOR.document.getById( this._.labelId );\r
+                               if ( node.getChildCount() < 1 )\r
+                               ( new CKEDITOR.dom.text( label, CKEDITOR.document ) ).appendTo( node );\r
+                               else\r
+                                       node.getChild( 0 ).$.nodeValue = label;\r
+                               return this;\r
+                       },\r
+\r
+                       /**\r
+                        * Retrieves the current label text of the elment.\r
+                        *\r
+                        * @returns {String} The current label text.\r
+                        */\r
+                       getLabel: function() {\r
+                               var node = CKEDITOR.document.getById( this._.labelId );\r
+                               if ( !node || node.getChildCount() < 1 )\r
+                                       return '';\r
+                               else\r
+                                       return node.getChild( 0 ).getText();\r
+                       },\r
+\r
+                       /**\r
+                        * Defines the `onChange` event for UI element definitions.\r
+                        * @property {Object}\r
+                        */\r
+                       eventProcessors: commonEventProcessors\r
+               }, true );\r
+\r
+               /** @class CKEDITOR.ui.dialog.button */\r
+               CKEDITOR.ui.dialog.button.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {\r
+                       /**\r
+                        * Simulates a click to the button.\r
+                        *\r
+                        * @returns {Object} Return value of the `click` event.\r
+                        */\r
+                       click: function() {\r
+                               if ( !this._.disabled )\r
+                                       return this.fire( 'click', { dialog: this._.dialog } );\r
+                               return false;\r
+                       },\r
+\r
+                       /**\r
+                        * Enables the button.\r
+                        */\r
+                       enable: function() {\r
+                               this._.disabled = false;\r
+                               var element = this.getElement();\r
+                               element && element.removeClass( 'cke_disabled' );\r
+                       },\r
+\r
+                       /**\r
+                        * Disables the button.\r
+                        */\r
+                       disable: function() {\r
+                               this._.disabled = true;\r
+                               this.getElement().addClass( 'cke_disabled' );\r
+                       },\r
+\r
+                       /**\r
+                        * Checks whether a field is visible.\r
+                        *\r
+                        * @returns {Boolean}\r
+                        */\r
+                       isVisible: function() {\r
+                               return this.getElement().getFirst().isVisible();\r
+                       },\r
+\r
+                       /**\r
+                        * Checks whether a field is enabled. Fields can be disabled by using the\r
+                        * {@link #disable} method and enabled by using the {@link #enable} method.\r
+                        *\r
+                        * @returns {Boolean}\r
+                        */\r
+                       isEnabled: function() {\r
+                               return !this._.disabled;\r
+                       },\r
+\r
+                       /**\r
+                        * Defines the `onChange` event and `onClick` for button element definitions.\r
+                        *\r
+                        * @property {Object}\r
+                        */\r
+                       eventProcessors: CKEDITOR.tools.extend( {}, CKEDITOR.ui.dialog.uiElement.prototype.eventProcessors, {\r
+                               onClick: function( dialog, func ) {\r
+                                       this.on( 'click', function() {\r
+                                               func.apply( this, arguments );\r
+                                       } );\r
+                               }\r
+                       }, true ),\r
+\r
+                       /**\r
+                        * Handler for the element's access key up event. Simulates a click to\r
+                        * the button.\r
+                        */\r
+                       accessKeyUp: function() {\r
+                               this.click();\r
+                       },\r
+\r
+                       /**\r
+                        * Handler for the element's access key down event. Simulates a mouse\r
+                        * down to the button.\r
+                        */\r
+                       accessKeyDown: function() {\r
+                               this.focus();\r
+                       },\r
+\r
+                       keyboardFocusable: true\r
+               }, true );\r
+\r
+               /** @class CKEDITOR.ui.dialog.textInput */\r
+               CKEDITOR.ui.dialog.textInput.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement(), {\r
+                       /**\r
+                        * Gets the text input DOM element under this UI object.\r
+                        *\r
+                        * @returns {CKEDITOR.dom.element} The DOM element of the text input.\r
+                        */\r
+                       getInputElement: function() {\r
+                               return CKEDITOR.document.getById( this._.inputId );\r
+                       },\r
+\r
+                       /**\r
+                        * Puts focus into the text input.\r
+                        */\r
+                       focus: function() {\r
+                               var me = this.selectParentTab();\r
+\r
+                               // GECKO BUG: setTimeout() is needed to workaround invisible selections.\r
+                               setTimeout( function() {\r
+                                       var element = me.getInputElement();\r
+                                       element && element.$.focus();\r
+                               }, 0 );\r
+                       },\r
+\r
+                       /**\r
+                        * Selects all the text in the text input.\r
+                        */\r
+                       select: function() {\r
+                               var me = this.selectParentTab();\r
+\r
+                               // GECKO BUG: setTimeout() is needed to workaround invisible selections.\r
+                               setTimeout( function() {\r
+                                       var e = me.getInputElement();\r
+                                       if ( e ) {\r
+                                               e.$.focus();\r
+                                               e.$.select();\r
+                                       }\r
+                               }, 0 );\r
+                       },\r
+\r
+                       /**\r
+                        * Handler for the text input's access key up event. Makes a `select()`\r
+                        * call to the text input.\r
+                        */\r
+                       accessKeyUp: function() {\r
+                               this.select();\r
+                       },\r
+\r
+                       /**\r
+                        * Sets the value of this text input object.\r
+                        *\r
+                        *              uiElement.setValue( 'Blamo' );\r
+                        *\r
+                        * @param {Object} value The new value.\r
+                        * @returns {CKEDITOR.ui.dialog.textInput} The current UI element.\r
+                        */\r
+                       setValue: function( value ) {\r
+                               if ( this.bidi ) {\r
+                                       var marker = value && value.charAt( 0 ),\r
+                                               dir = ( marker == '\u202A' ? 'ltr' : marker == '\u202B' ? 'rtl' : null );\r
+\r
+                                       if ( dir ) {\r
+                                               value = value.slice( 1 );\r
+                                       }\r
+\r
+                                       // Set the marker or reset it (if dir==null).\r
+                                       this.setDirectionMarker( dir );\r
+                               }\r
+\r
+                               if ( !value ) {\r
+                                       value = '';\r
+                               }\r
+\r
+                               return CKEDITOR.ui.dialog.uiElement.prototype.setValue.apply( this, arguments );\r
+                       },\r
+\r
+                       /**\r
+                        * Gets the value of this text input object.\r
+                        *\r
+                        * @returns {String} The value.\r
+                        */\r
+                       getValue: function() {\r
+                               var value = CKEDITOR.ui.dialog.uiElement.prototype.getValue.call( this );\r
+\r
+                               if ( this.bidi && value ) {\r
+                                       var dir = this.getDirectionMarker();\r
+                                       if ( dir ) {\r
+                                               value = ( dir == 'ltr' ? '\u202A' : '\u202B' ) + value;\r
+                                       }\r
+                               }\r
+\r
+                               return value;\r
+                       },\r
+\r
+                       /**\r
+                        * Sets the text direction marker and the `dir` attribute of the input element.\r
+                        *\r
+                        * @since 4.5\r
+                        * @param {String} dir The text direction. Pass `null` to reset.\r
+                        */\r
+                       setDirectionMarker: function( dir ) {\r
+                               var inputElement = this.getInputElement();\r
+\r
+                               if ( dir ) {\r
+                                       inputElement.setAttributes( {\r
+                                               dir: dir,\r
+                                               'data-cke-dir-marker': dir\r
+                                       } );\r
+                               // Don't remove the dir attribute if this field hasn't got the marker,\r
+                               // because the dir attribute could be set independently.\r
+                               } else if ( this.getDirectionMarker() ) {\r
+                                       inputElement.removeAttributes( [ 'dir', 'data-cke-dir-marker' ] );\r
+                               }\r
+                       },\r
+\r
+                       /**\r
+                        * Gets the value of the text direction marker.\r
+                        *\r
+                        * @since 4.5\r
+                        * @returns {String} `'ltr'`, `'rtl'` or `null` if the marker is not set.\r
+                        */\r
+                       getDirectionMarker: function() {\r
+                               return this.getInputElement().data( 'cke-dir-marker' );\r
+                       },\r
+\r
+                       keyboardFocusable: true\r
+               }, commonPrototype, true );\r
+\r
+               CKEDITOR.ui.dialog.textarea.prototype = new CKEDITOR.ui.dialog.textInput();\r
+\r
+               /** @class CKEDITOR.ui.dialog.select */\r
+               CKEDITOR.ui.dialog.select.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement(), {\r
+                       /**\r
+                        * Gets the DOM element of the select box.\r
+                        *\r
+                        * @returns {CKEDITOR.dom.element} The `<select>` element of this UI element.\r
+                        */\r
+                       getInputElement: function() {\r
+                               return this._.select.getElement();\r
+                       },\r
+\r
+                       /**\r
+                        * Adds an option to the select box.\r
+                        *\r
+                        * @param {String} label Option label.\r
+                        * @param {String} value (Optional) Option value, if not defined it will be\r
+                        * assumed to be the same as the label.\r
+                        * @param {Number} index (Optional) Position of the option to be inserted\r
+                        * to. If not defined, the new option will be inserted to the end of list.\r
+                        * @returns {CKEDITOR.ui.dialog.select} The current select UI element.\r
+                        */\r
+                       add: function( label, value, index ) {\r
+                               var option = new CKEDITOR.dom.element( 'option', this.getDialog().getParentEditor().document ),\r
+                                       selectElement = this.getInputElement().$;\r
+                               option.$.text = label;\r
+                               option.$.value = ( value === undefined || value === null ) ? label : value;\r
+                               if ( index === undefined || index === null ) {\r
+                                       if ( CKEDITOR.env.ie ) {\r
+                                               selectElement.add( option.$ );\r
+                                       } else {\r
+                                               selectElement.add( option.$, null );\r
+                                       }\r
+                               } else {\r
+                                       selectElement.add( option.$, index );\r
+                               }\r
+                               return this;\r
+                       },\r
+\r
+                       /**\r
+                        * Removes an option from the selection list.\r
+                        *\r
+                        * @param {Number} index Index of the option to be removed.\r
+                        * @returns {CKEDITOR.ui.dialog.select} The current select UI element.\r
+                        */\r
+                       remove: function( index ) {\r
+                               var selectElement = this.getInputElement().$;\r
+                               selectElement.remove( index );\r
+                               return this;\r
+                       },\r
+\r
+                       /**\r
+                        * Clears all options out of the selection list.\r
+                        *\r
+                        * @returns {CKEDITOR.ui.dialog.select} The current select UI element.\r
+                        */\r
+                       clear: function() {\r
+                               var selectElement = this.getInputElement().$;\r
+                               while ( selectElement.length > 0 )\r
+                                       selectElement.remove( 0 );\r
+                               return this;\r
+                       },\r
+\r
+                       keyboardFocusable: true\r
+               }, commonPrototype, true );\r
+\r
+               /** @class CKEDITOR.ui.dialog.checkbox */\r
+               CKEDITOR.ui.dialog.checkbox.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {\r
+                       /**\r
+                        * Gets the checkbox DOM element.\r
+                        *\r
+                        * @returns {CKEDITOR.dom.element} The DOM element of the checkbox.\r
+                        */\r
+                       getInputElement: function() {\r
+                               return this._.checkbox.getElement();\r
+                       },\r
+\r
+                       /**\r
+                        * Sets the state of the checkbox.\r
+                        *\r
+                        * @param {Boolean} checked `true` to tick the checkbox, `false` to untick it.\r
+                        * @param {Boolean} noChangeEvent Internal commit, to supress `change` event on this element.\r
+                        */\r
+                       setValue: function( checked, noChangeEvent ) {\r
+                               this.getInputElement().$.checked = checked;\r
+                               !noChangeEvent && this.fire( 'change', { value: checked } );\r
+                       },\r
+\r
+                       /**\r
+                        * Gets the state of the checkbox.\r
+                        *\r
+                        * @returns {Boolean} `true` means that the checkbox is ticked, `false` means it is not ticked.\r
+                        */\r
+                       getValue: function() {\r
+                               return this.getInputElement().$.checked;\r
+                       },\r
+\r
+                       /**\r
+                        * Handler for the access key up event. Toggles the checkbox.\r
+                        */\r
+                       accessKeyUp: function() {\r
+                               this.setValue( !this.getValue() );\r
+                       },\r
+\r
+                       /**\r
+                        * Defines the `onChange` event for UI element definitions.\r
+                        *\r
+                        * @property {Object}\r
+                        */\r
+                       eventProcessors: {\r
+                               onChange: function( dialog, func ) {\r
+                                       if ( !CKEDITOR.env.ie || ( CKEDITOR.env.version > 8 ) )\r
+                                               return commonEventProcessors.onChange.apply( this, arguments );\r
+                                       else {\r
+                                               dialog.on( 'load', function() {\r
+                                                       var element = this._.checkbox.getElement();\r
+                                                       element.on( 'propertychange', function( evt ) {\r
+                                                               evt = evt.data.$;\r
+                                                               if ( evt.propertyName == 'checked' )\r
+                                                                       this.fire( 'change', { value: element.$.checked } );\r
+                                                       }, this );\r
+                                               }, this );\r
+                                               this.on( 'change', func );\r
+                                       }\r
+                                       return null;\r
+                               }\r
+                       },\r
+\r
+                       keyboardFocusable: true\r
+               }, commonPrototype, true );\r
+\r
+               /** @class CKEDITOR.ui.dialog.radio */\r
+               CKEDITOR.ui.dialog.radio.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.uiElement(), {\r
+                       /**\r
+                        * Selects one of the radio buttons in this button group.\r
+                        *\r
+                        * @param {String} value The value of the button to be chcked.\r
+                        * @param {Boolean} noChangeEvent Internal commit, to supress the `change` event on this element.\r
+                        */\r
+                       setValue: function( value, noChangeEvent ) {\r
+                               var children = this._.children,\r
+                                       item;\r
+                               for ( var i = 0;\r
+                               ( i < children.length ) && ( item = children[ i ] ); i++ )\r
+                                       item.getElement().$.checked = ( item.getValue() == value );\r
+                               !noChangeEvent && this.fire( 'change', { value: value } );\r
+                       },\r
+\r
+                       /**\r
+                        * Gets the value of the currently selected radio button.\r
+                        *\r
+                        * @returns {String} The currently selected button's value.\r
+                        */\r
+                       getValue: function() {\r
+                               var children = this._.children;\r
+                               for ( var i = 0; i < children.length; i++ ) {\r
+                                       if ( children[ i ].getElement().$.checked )\r
+                                               return children[ i ].getValue();\r
+                               }\r
+                               return null;\r
+                       },\r
+\r
+                       /**\r
+                        * Handler for the access key up event. Focuses the currently\r
+                        * selected radio button, or the first radio button if none is selected.\r
+                        */\r
+                       accessKeyUp: function() {\r
+                               var children = this._.children,\r
+                                       i;\r
+                               for ( i = 0; i < children.length; i++ ) {\r
+                                       if ( children[ i ].getElement().$.checked ) {\r
+                                               children[ i ].getElement().focus();\r
+                                               return;\r
+                                       }\r
+                               }\r
+                               children[ 0 ].getElement().focus();\r
+                       },\r
+\r
+                       /**\r
+                        * Defines the `onChange` event for UI element definitions.\r
+                        *\r
+                        * @property {Object}\r
+                        */\r
+                       eventProcessors: {\r
+                               onChange: function( dialog, func ) {\r
+                                       if ( !CKEDITOR.env.ie || ( CKEDITOR.env.version > 8 ) )\r
+                                               return commonEventProcessors.onChange.apply( this, arguments );\r
+                                       else {\r
+                                               dialog.on( 'load', function() {\r
+                                                       var children = this._.children,\r
+                                                               me = this;\r
+                                                       for ( var i = 0; i < children.length; i++ ) {\r
+                                                               var element = children[ i ].getElement();\r
+                                                               element.on( 'propertychange', function( evt ) {\r
+                                                                       evt = evt.data.$;\r
+                                                                       if ( evt.propertyName == 'checked' && this.$.checked )\r
+                                                                               me.fire( 'change', { value: this.getAttribute( 'value' ) } );\r
+                                                               } );\r
+                                                       }\r
+                                               }, this );\r
+                                               this.on( 'change', func );\r
+                                       }\r
+                                       return null;\r
+                               }\r
+                       }\r
+               }, commonPrototype, true );\r
+\r
+               /** @class CKEDITOR.ui.dialog.file */\r
+               CKEDITOR.ui.dialog.file.prototype = CKEDITOR.tools.extend( new CKEDITOR.ui.dialog.labeledElement(), commonPrototype, {\r
+                       /**\r
+                        * Gets the `<input>` element of this file input.\r
+                        *\r
+                        * @returns {CKEDITOR.dom.element} The file input element.\r
+                        */\r
+                       getInputElement: function() {\r
+                               var frameDocument = CKEDITOR.document.getById( this._.frameId ).getFrameDocument();\r
+                               return frameDocument.$.forms.length > 0 ? new CKEDITOR.dom.element( frameDocument.$.forms[ 0 ].elements[ 0 ] ) : this.getElement();\r
+                       },\r
+\r
+                       /**\r
+                        * Uploads the file in the file input.\r
+                        *\r
+                        * @returns {CKEDITOR.ui.dialog.file} This object.\r
+                        */\r
+                       submit: function() {\r
+                               this.getInputElement().getParent().$.submit();\r
+                               return this;\r
+                       },\r
+\r
+                       /**\r
+                        * Gets the action assigned to the form.\r
+                        *\r
+                        * @returns {String} The value of the action.\r
+                        */\r
+                       getAction: function() {\r
+                               return this.getInputElement().getParent().$.action;\r
+                       },\r
+\r
+                       /**\r
+                        * The events must be applied to the inner input element, and\r
+                        * this must be done when the iframe and form have been loaded.\r
+                        */\r
+                       registerEvents: function( definition ) {\r
+                               var regex = /^on([A-Z]\w+)/,\r
+                                       match;\r
+\r
+                               var registerDomEvent = function( uiElement, dialog, eventName, func ) {\r
+                                               uiElement.on( 'formLoaded', function() {\r
+                                                       uiElement.getInputElement().on( eventName, func, uiElement );\r
+                                               } );\r
+                                       };\r
+\r
+                               for ( var i in definition ) {\r
+                                       if ( !( match = i.match( regex ) ) )\r
+                                               continue;\r
+\r
+                                       if ( this.eventProcessors[ i ] )\r
+                                               this.eventProcessors[ i ].call( this, this._.dialog, definition[ i ] );\r
+                                       else\r
+                                               registerDomEvent( this, this._.dialog, match[ 1 ].toLowerCase(), definition[ i ] );\r
+                               }\r
+\r
+                               return this;\r
+                       },\r
+\r
+                       /**\r
+                        * Redraws the file input and resets the file path in the file input.\r
+                        * The redrawing logic is necessary because non-IE browsers tend to clear\r
+                        * the `<iframe>` containing the file input after closing the dialog window.\r
+                        */\r
+                       reset: function() {\r
+                               var _ = this._,\r
+                                       frameElement = CKEDITOR.document.getById( _.frameId ),\r
+                                       frameDocument = frameElement.getFrameDocument(),\r
+                                       elementDefinition = _.definition,\r
+                                       buttons = _.buttons,\r
+                                       callNumber = this.formLoadedNumber,\r
+                                       unloadNumber = this.formUnloadNumber,\r
+                                       langDir = _.dialog._.editor.lang.dir,\r
+                                       langCode = _.dialog._.editor.langCode;\r
+\r
+                               // The callback function for the iframe, but we must call tools.addFunction only once\r
+                               // so we store the function number in this.formLoadedNumber\r
+                               if ( !callNumber ) {\r
+                                       callNumber = this.formLoadedNumber = CKEDITOR.tools.addFunction( function() {\r
+                                               // Now we can apply the events to the input type=file\r
+                                               this.fire( 'formLoaded' );\r
+                                       }, this );\r
+\r
+                                       // Remove listeners attached to the content of the iframe (the file input)\r
+                                       unloadNumber = this.formUnloadNumber = CKEDITOR.tools.addFunction( function() {\r
+                                               this.getInputElement().clearCustomData();\r
+                                       }, this );\r
+\r
+                                       this.getDialog()._.editor.on( 'destroy', function() {\r
+                                               CKEDITOR.tools.removeFunction( callNumber );\r
+                                               CKEDITOR.tools.removeFunction( unloadNumber );\r
+                                       } );\r
+                               }\r
+\r
+                               function generateFormField() {\r
+                                       frameDocument.$.open();\r
+\r
+                                       var size = '';\r
+                                       if ( elementDefinition.size )\r
+                                               size = elementDefinition.size - ( CKEDITOR.env.ie ? 7 : 0 ); // "Browse" button is bigger in IE.\r
+\r
+                                       var inputId = _.frameId + '_input';\r
+\r
+                                       frameDocument.$.write( [\r
+                                               '<html dir="' + langDir + '" lang="' + langCode + '"><head><title></title></head><body style="margin: 0; overflow: hidden; background: transparent;">',\r
+                                                       '<form enctype="multipart/form-data" method="POST" dir="' + langDir + '" lang="' + langCode + '" action="',\r
+                                                               CKEDITOR.tools.htmlEncode( elementDefinition.action ),\r
+                                                       '">',\r
+                                                               // Replicate the field label inside of iframe.\r
+                                                               '<label id="', _.labelId, '" for="', inputId, '" style="display:none">',\r
+                                                                       CKEDITOR.tools.htmlEncode( elementDefinition.label ),\r
+                                                               '</label>',\r
+                                                               // Set width to make sure that input is not clipped by the iframe (#11253).\r
+                                                               '<input style="width:100%" id="', inputId, '" aria-labelledby="', _.labelId, '" type="file" name="',\r
+                                                                       CKEDITOR.tools.htmlEncode( elementDefinition.id || 'cke_upload' ),\r
+                                                                       '" size="',\r
+                                                                       CKEDITOR.tools.htmlEncode( size > 0 ? size : '' ),\r
+                                                               '" />',\r
+                                                       '</form>',\r
+                                               '</body></html>',\r
+                                               '<script>',\r
+                                                       // Support for custom document.domain in IE.\r
+                                                       CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '',\r
+\r
+                                                       'window.parent.CKEDITOR.tools.callFunction(' + callNumber + ');',\r
+                                                       'window.onbeforeunload = function() {window.parent.CKEDITOR.tools.callFunction(' + unloadNumber + ')}',\r
+                                               '</script>'\r
+                                       ].join( '' ) );\r
+\r
+                                       frameDocument.$.close();\r
+\r
+                                       for ( var i = 0; i < buttons.length; i++ )\r
+                                               buttons[ i ].enable();\r
+                               }\r
+\r
+                               // #3465: Wait for the browser to finish rendering the dialog first.\r
+                               if ( CKEDITOR.env.gecko )\r
+                                       setTimeout( generateFormField, 500 );\r
+                               else\r
+                                       generateFormField();\r
+                       },\r
+\r
+                       getValue: function() {\r
+                               return this.getInputElement().$.value || '';\r
+                       },\r
+\r
+                       /**\r
+                        * The default value of input `type="file"` is an empty string, but during the initialization\r
+                        * of this UI element, the iframe still is not ready so it cannot be read from that object.\r
+                        * Setting it manually prevents later issues with the current value (`''`) being different\r
+                        * than the initial value (undefined as it asked for `.value` of a div).\r
+                        */\r
+                       setInitValue: function() {\r
+                               this._.initValue = '';\r
+                       },\r
+\r
+                       /**\r
+                        * Defines the `onChange` event for UI element definitions.\r
+                        *\r
+                        * @property {Object}\r
+                        */\r
+                       eventProcessors: {\r
+                               onChange: function( dialog, func ) {\r
+                                       // If this method is called several times (I'm not sure about how this can happen but the default\r
+                                       // onChange processor includes this protection)\r
+                                       // In order to reapply to the new element, the property is deleted at the beggining of the registerEvents method\r
+                                       if ( !this._.domOnChangeRegistered ) {\r
+                                               // By listening for the formLoaded event, this handler will get reapplied when a new\r
+                                               // form is created\r
+                                               this.on( 'formLoaded', function() {\r
+                                                       this.getInputElement().on( 'change', function() {\r
+                                                               this.fire( 'change', { value: this.getValue() } );\r
+                                                       }, this );\r
+                                               }, this );\r
+                                               this._.domOnChangeRegistered = true;\r
+                                       }\r
+\r
+                                       this.on( 'change', func );\r
+                               }\r
+                       },\r
+\r
+                       keyboardFocusable: true\r
+               }, true );\r
+\r
+               CKEDITOR.ui.dialog.fileButton.prototype = new CKEDITOR.ui.dialog.button();\r
+\r
+               CKEDITOR.ui.dialog.fieldset.prototype = CKEDITOR.tools.clone( CKEDITOR.ui.dialog.hbox.prototype );\r
+\r
+               CKEDITOR.dialog.addUIElement( 'text', textBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'password', textBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'textarea', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'checkbox', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'radio', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'button', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'select', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'file', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'fileButton', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'html', commonBuilder );\r
+               CKEDITOR.dialog.addUIElement( 'fieldset', containerBuilder );\r
+       }\r
+} );\r
+\r
+/**\r
+ * Fired when the value of the uiElement is changed.\r
+ *\r
+ * @event change\r
+ * @member CKEDITOR.ui.dialog.uiElement\r
+ */\r
+\r
+/**\r
+ * Fired when the inner frame created by the element is ready.\r
+ * Each time the button is used or the dialog window is loaded, a new\r
+ * form might be created.\r
+ *\r
+ * @event formLoaded\r
+ * @member CKEDITOR.ui.dialog.fileButton\r
+ */\r
diff --git a/sources/plugins/elementspath/lang/af.js b/sources/plugins/elementspath/lang/af.js
new file mode 100644 (file)
index 0000000..c07fa39
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'af', {\r
+       eleLabel: 'Elemente-pad',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ar.js b/sources/plugins/elementspath/lang/ar.js
new file mode 100644 (file)
index 0000000..fa0147c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ar', {\r
+       eleLabel: 'مسار العنصر',\r
+       eleTitle: 'عنصر 1%'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/az.js b/sources/plugins/elementspath/lang/az.js
new file mode 100644 (file)
index 0000000..c344c1e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'az', {\r
+       eleLabel: 'Elementin izləri',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/bg.js b/sources/plugins/elementspath/lang/bg.js
new file mode 100644 (file)
index 0000000..07b990b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'bg', {\r
+       eleLabel: 'Път за елементите',\r
+       eleTitle: '%1 елемент'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/bn.js b/sources/plugins/elementspath/lang/bn.js
new file mode 100644 (file)
index 0000000..493caad
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'bn', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/bs.js b/sources/plugins/elementspath/lang/bs.js
new file mode 100644 (file)
index 0000000..f432973
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'bs', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ca.js b/sources/plugins/elementspath/lang/ca.js
new file mode 100644 (file)
index 0000000..d9573c2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ca', {\r
+       eleLabel: 'Ruta dels elements',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/cs.js b/sources/plugins/elementspath/lang/cs.js
new file mode 100644 (file)
index 0000000..427e5bf
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'cs', {\r
+       eleLabel: 'Cesta objektu',\r
+       eleTitle: '%1 objekt'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/cy.js b/sources/plugins/elementspath/lang/cy.js
new file mode 100644 (file)
index 0000000..5c9c77d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'cy', {\r
+       eleLabel: 'Llwybr elfennau',\r
+       eleTitle: 'Elfen %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/da.js b/sources/plugins/elementspath/lang/da.js
new file mode 100644 (file)
index 0000000..3cd404e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'da', {\r
+       eleLabel: 'Sti på element',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/de-ch.js b/sources/plugins/elementspath/lang/de-ch.js
new file mode 100644 (file)
index 0000000..ad13b78
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'de-ch', {\r
+       eleLabel: 'Elementepfad',\r
+       eleTitle: '%1 Element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/de.js b/sources/plugins/elementspath/lang/de.js
new file mode 100644 (file)
index 0000000..5072d3b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'de', {\r
+       eleLabel: 'Elementepfad',\r
+       eleTitle: '%1 Element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/el.js b/sources/plugins/elementspath/lang/el.js
new file mode 100644 (file)
index 0000000..00a4812
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'el', {\r
+       eleLabel: 'Διαδρομή Στοιχείων',\r
+       eleTitle: 'Στοιχείο %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/en-au.js b/sources/plugins/elementspath/lang/en-au.js
new file mode 100644 (file)
index 0000000..60a838a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'en-au', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/en-ca.js b/sources/plugins/elementspath/lang/en-ca.js
new file mode 100644 (file)
index 0000000..8acb5c4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'en-ca', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/en-gb.js b/sources/plugins/elementspath/lang/en-gb.js
new file mode 100644 (file)
index 0000000..86fb78e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'en-gb', {\r
+       eleLabel: 'Elements path',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/en.js b/sources/plugins/elementspath/lang/en.js
new file mode 100644 (file)
index 0000000..96feac7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'en', {\r
+       eleLabel: 'Elements path',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/eo.js b/sources/plugins/elementspath/lang/eo.js
new file mode 100644 (file)
index 0000000..20e0320
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'eo', {\r
+       eleLabel: 'Vojo al Elementoj',\r
+       eleTitle: '%1 elementoj'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/es.js b/sources/plugins/elementspath/lang/es.js
new file mode 100644 (file)
index 0000000..815a18d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'es', {\r
+       eleLabel: 'Ruta de los elementos',\r
+       eleTitle: '%1 elemento'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/et.js b/sources/plugins/elementspath/lang/et.js
new file mode 100644 (file)
index 0000000..ab62d21
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'et', {\r
+       eleLabel: 'Elementide asukoht',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/eu.js b/sources/plugins/elementspath/lang/eu.js
new file mode 100644 (file)
index 0000000..f3d0bb9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'eu', {\r
+       eleLabel: 'Elementuen bidea',\r
+       eleTitle: '%1 elementua'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/fa.js b/sources/plugins/elementspath/lang/fa.js
new file mode 100644 (file)
index 0000000..faeb18e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'fa', {\r
+       eleLabel: 'مسیر عناصر',\r
+       eleTitle: '%1 عنصر'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/fi.js b/sources/plugins/elementspath/lang/fi.js
new file mode 100644 (file)
index 0000000..5f975cf
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'fi', {\r
+       eleLabel: 'Elementin polku',\r
+       eleTitle: '%1 elementti'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/fo.js b/sources/plugins/elementspath/lang/fo.js
new file mode 100644 (file)
index 0000000..0935eb9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'fo', {\r
+       eleLabel: 'Slóð til elementir',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/fr-ca.js b/sources/plugins/elementspath/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..0b8796c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'fr-ca', {\r
+       eleLabel: 'Chemin d\'éléments',\r
+       eleTitle: 'element %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/fr.js b/sources/plugins/elementspath/lang/fr.js
new file mode 100644 (file)
index 0000000..78488bb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'fr', {\r
+       eleLabel: 'Chemin des éléments',\r
+       eleTitle: 'Élément %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/gl.js b/sources/plugins/elementspath/lang/gl.js
new file mode 100644 (file)
index 0000000..7dfc457
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'gl', {\r
+       eleLabel: 'Ruta dos elementos',\r
+       eleTitle: 'Elemento %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/gu.js b/sources/plugins/elementspath/lang/gu.js
new file mode 100644 (file)
index 0000000..d6f4f40
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'gu', {\r
+       eleLabel: 'એલીમેન્ટ્સ નો ',\r
+       eleTitle: 'એલીમેન્ટ %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/he.js b/sources/plugins/elementspath/lang/he.js
new file mode 100644 (file)
index 0000000..3e2773f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'he', {\r
+       eleLabel: 'עץ האלמנטים',\r
+       eleTitle: '%1 אלמנט'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/hi.js b/sources/plugins/elementspath/lang/hi.js
new file mode 100644 (file)
index 0000000..3d514f2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'hi', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/hr.js b/sources/plugins/elementspath/lang/hr.js
new file mode 100644 (file)
index 0000000..90a7fd0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'hr', {\r
+       eleLabel: 'Putanja elemenata',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/hu.js b/sources/plugins/elementspath/lang/hu.js
new file mode 100644 (file)
index 0000000..23701f2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'hu', {\r
+       eleLabel: 'Elem utak',\r
+       eleTitle: '%1 elem'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/is.js b/sources/plugins/elementspath/lang/is.js
new file mode 100644 (file)
index 0000000..b5711de
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'is', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/it.js b/sources/plugins/elementspath/lang/it.js
new file mode 100644 (file)
index 0000000..2e3ed4d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'it', {\r
+       eleLabel: 'Percorso degli elementi',\r
+       eleTitle: '%1 elemento'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ja.js b/sources/plugins/elementspath/lang/ja.js
new file mode 100644 (file)
index 0000000..6fba524
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ja', {\r
+       eleLabel: '要素パス',\r
+       eleTitle: '%1 要素'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ka.js b/sources/plugins/elementspath/lang/ka.js
new file mode 100644 (file)
index 0000000..9923902
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ka', {\r
+       eleLabel: 'ელემეტის გზა',\r
+       eleTitle: '%1 ელემენტი'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/km.js b/sources/plugins/elementspath/lang/km.js
new file mode 100644 (file)
index 0000000..2fc661d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'km', {\r
+       eleLabel: 'ទីតាំង​ធាតុ',\r
+       eleTitle: 'ធាតុ %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ko.js b/sources/plugins/elementspath/lang/ko.js
new file mode 100644 (file)
index 0000000..843a2de
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ko', {\r
+       eleLabel: '요소 경로',\r
+       eleTitle: '%1 요소'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ku.js b/sources/plugins/elementspath/lang/ku.js
new file mode 100644 (file)
index 0000000..f425c90
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ku', {\r
+       eleLabel: 'ڕێڕەوی توخمەکان',\r
+       eleTitle: '%1 توخم'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/lt.js b/sources/plugins/elementspath/lang/lt.js
new file mode 100644 (file)
index 0000000..14c5345
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'lt', {\r
+       eleLabel: 'Elemento kelias',\r
+       eleTitle: '%1 elementas'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/lv.js b/sources/plugins/elementspath/lang/lv.js
new file mode 100644 (file)
index 0000000..7459ce8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'lv', {\r
+       eleLabel: 'Elementa ceļš',\r
+       eleTitle: '%1 elements'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/mk.js b/sources/plugins/elementspath/lang/mk.js
new file mode 100644 (file)
index 0000000..3fb1549
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'mk', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/mn.js b/sources/plugins/elementspath/lang/mn.js
new file mode 100644 (file)
index 0000000..e3e9285
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'mn', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ms.js b/sources/plugins/elementspath/lang/ms.js
new file mode 100644 (file)
index 0000000..143b4cd
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ms', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/nb.js b/sources/plugins/elementspath/lang/nb.js
new file mode 100644 (file)
index 0000000..d797354
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'nb', {\r
+       eleLabel: 'Element-sti',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/nl.js b/sources/plugins/elementspath/lang/nl.js
new file mode 100644 (file)
index 0000000..14a3585
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'nl', {\r
+       eleLabel: 'Elementenpad',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/no.js b/sources/plugins/elementspath/lang/no.js
new file mode 100644 (file)
index 0000000..64d05f5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'no', {\r
+       eleLabel: 'Element-sti',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/oc.js b/sources/plugins/elementspath/lang/oc.js
new file mode 100644 (file)
index 0000000..04c1b30
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'oc', {\r
+       eleLabel: 'Camin dels elements',\r
+       eleTitle: 'Element %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/pl.js b/sources/plugins/elementspath/lang/pl.js
new file mode 100644 (file)
index 0000000..082224d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'pl', {\r
+       eleLabel: 'Ścieżka elementów',\r
+       eleTitle: 'element %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/pt-br.js b/sources/plugins/elementspath/lang/pt-br.js
new file mode 100644 (file)
index 0000000..ec265b6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'pt-br', {\r
+       eleLabel: 'Caminho dos Elementos',\r
+       eleTitle: 'Elemento %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/pt.js b/sources/plugins/elementspath/lang/pt.js
new file mode 100644 (file)
index 0000000..5eed642
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'pt', {\r
+       eleLabel: 'Caminho dos elementos',\r
+       eleTitle: 'Elemento %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ro.js b/sources/plugins/elementspath/lang/ro.js
new file mode 100644 (file)
index 0000000..bc79113
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ro', {\r
+       eleLabel: 'Calea elementelor',\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ru.js b/sources/plugins/elementspath/lang/ru.js
new file mode 100644 (file)
index 0000000..ce9529e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ru', {\r
+       eleLabel: 'Путь элементов',\r
+       eleTitle: 'Элемент %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/si.js b/sources/plugins/elementspath/lang/si.js
new file mode 100644 (file)
index 0000000..ff4e5dc
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'si', {\r
+       eleLabel: 'මුලද්‍රව්‍ය මාර්ගය',\r
+       eleTitle: '%1 මුල'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sk.js b/sources/plugins/elementspath/lang/sk.js
new file mode 100644 (file)
index 0000000..b3eb725
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sk', {\r
+       eleLabel: 'Cesta prvkov',\r
+       eleTitle: '%1 prvok'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sl.js b/sources/plugins/elementspath/lang/sl.js
new file mode 100644 (file)
index 0000000..2d2a1c6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sl', {\r
+       eleLabel: 'Pot elementov',\r
+       eleTitle: 'Element %1'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sq.js b/sources/plugins/elementspath/lang/sq.js
new file mode 100644 (file)
index 0000000..0018d6f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sq', {\r
+       eleLabel: 'Rruga e elementeve',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sr-latn.js b/sources/plugins/elementspath/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..65ae9f4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sr-latn', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sr.js b/sources/plugins/elementspath/lang/sr.js
new file mode 100644 (file)
index 0000000..80d1ba4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sr', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/sv.js b/sources/plugins/elementspath/lang/sv.js
new file mode 100644 (file)
index 0000000..e34dd0e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'sv', {\r
+       eleLabel: 'Elementets sökväg',\r
+       eleTitle: '%1 element'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/th.js b/sources/plugins/elementspath/lang/th.js
new file mode 100644 (file)
index 0000000..d56fb77
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'th', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 element' // MISSING\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/tr.js b/sources/plugins/elementspath/lang/tr.js
new file mode 100644 (file)
index 0000000..e32e4ff
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'tr', {\r
+       eleLabel: 'Elementlerin yolu',\r
+       eleTitle: '%1 elementi'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/tt.js b/sources/plugins/elementspath/lang/tt.js
new file mode 100644 (file)
index 0000000..63b171c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'tt', {\r
+       eleLabel: 'Elements path', // MISSING\r
+       eleTitle: '%1 элемент'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/ug.js b/sources/plugins/elementspath/lang/ug.js
new file mode 100644 (file)
index 0000000..5b66e0f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'ug', {\r
+       eleLabel: 'ئېلېمېنت يولى',\r
+       eleTitle: '%1 ئېلېمېنت'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/uk.js b/sources/plugins/elementspath/lang/uk.js
new file mode 100644 (file)
index 0000000..0d247c6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'uk', {\r
+       eleLabel: 'Шлях',\r
+       eleTitle: '%1 елемент'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/vi.js b/sources/plugins/elementspath/lang/vi.js
new file mode 100644 (file)
index 0000000..5ba86b4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'vi', {\r
+       eleLabel: 'Nhãn thành phần',\r
+       eleTitle: '%1 thành phần'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/zh-cn.js b/sources/plugins/elementspath/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..e585d13
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'zh-cn', {\r
+       eleLabel: '元素路径',\r
+       eleTitle: '%1 元素'\r
+} );\r
diff --git a/sources/plugins/elementspath/lang/zh.js b/sources/plugins/elementspath/lang/zh.js
new file mode 100644 (file)
index 0000000..5031d0f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'elementspath', 'zh', {\r
+       eleLabel: '元件路徑',\r
+       eleTitle: '%1 個元件'\r
+} );\r
diff --git a/sources/plugins/elementspath/plugin.js b/sources/plugins/elementspath/plugin.js
new file mode 100644 (file)
index 0000000..07ba5c2
--- /dev/null
@@ -0,0 +1,244 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The "elementspath" plugin. It shows all elements in the DOM\r
+ *             parent tree relative to the current selection in the editing area.\r
+ */\r
+\r
+( function() {\r
+       var commands = {\r
+               toolbarFocus: {\r
+                       editorFocus: false,\r
+                       readOnly: 1,\r
+                       exec: function( editor ) {\r
+                               var idBase = editor._.elementsPath.idBase;\r
+                               var element = CKEDITOR.document.getById( idBase + '0' );\r
+\r
+                               // Make the first button focus accessible for IE. (#3417)\r
+                               // Adobe AIR instead need while of delay.\r
+                               element && element.focus( CKEDITOR.env.ie || CKEDITOR.env.air );\r
+                       }\r
+               }\r
+       };\r
+\r
+       var emptyHtml = '<span class="cke_path_empty">&nbsp;</span>';\r
+\r
+       var extra = '';\r
+\r
+       // Some browsers don't cancel key events in the keydown but in the\r
+       // keypress.\r
+       // TODO: Check if really needed.\r
+       if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )\r
+               extra += ' onkeypress="return false;"';\r
+\r
+       // With Firefox, we need to force the button to redraw, otherwise it\r
+       // will remain in the focus state.\r
+       if ( CKEDITOR.env.gecko )\r
+               extra += ' onblur="this.style.cssText = this.style.cssText;"';\r
+\r
+       var pathItemTpl = CKEDITOR.addTemplate( 'pathItem', '<a' +\r
+               ' id="{id}"' +\r
+               ' href="{jsTitle}"' +\r
+               ' tabindex="-1"' +\r
+               ' class="cke_path_item"' +\r
+               ' title="{label}"' +\r
+               extra +\r
+               ' hidefocus="true" ' +\r
+               ' onkeydown="return CKEDITOR.tools.callFunction({keyDownFn},{index}, event );"' +\r
+               ' onclick="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' +\r
+               ' role="button" aria-label="{label}">' +\r
+               '{text}' +\r
+               '</a>' );\r
+\r
+       CKEDITOR.plugins.add( 'elementspath', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               init: function( editor ) {\r
+                       editor._.elementsPath = {\r
+                               idBase: 'cke_elementspath_' + CKEDITOR.tools.getNextNumber() + '_',\r
+                               filters: []\r
+                       };\r
+\r
+                       editor.on( 'uiSpace', function( event ) {\r
+                               if ( event.data.space == 'bottom' )\r
+                                       initElementsPath( editor, event.data );\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       function initElementsPath( editor, bottomSpaceData ) {\r
+               var spaceId = editor.ui.spaceId( 'path' ),\r
+                       spaceElement,\r
+                       getSpaceElement = function() {\r
+                               if ( !spaceElement )\r
+                                       spaceElement = CKEDITOR.document.getById( spaceId );\r
+                               return spaceElement;\r
+                       },\r
+                       elementsPath = editor._.elementsPath,\r
+                       idBase = elementsPath.idBase;\r
+\r
+               bottomSpaceData.html += '<span id="' + spaceId + '_label" class="cke_voice_label">' + editor.lang.elementspath.eleLabel + '</span>' +\r
+                       '<span id="' + spaceId + '" class="cke_path" role="group" aria-labelledby="' + spaceId + '_label">' + emptyHtml + '</span>';\r
+\r
+               // Register the ui element to the focus manager.\r
+               editor.on( 'uiReady', function() {\r
+                       var element = editor.ui.space( 'path' );\r
+                       element && editor.focusManager.add( element, 1 );\r
+               } );\r
+\r
+               function onClick( elementIndex ) {\r
+                       var element = elementsPath.list[ elementIndex ],\r
+                               selection;\r
+\r
+                       if ( element.equals( editor.editable() ) || element.getAttribute( 'contenteditable' ) == 'true' ) {\r
+                               var range = editor.createRange();\r
+                               range.selectNodeContents( element );\r
+\r
+                               selection = range.select();\r
+                       } else {\r
+                               selection = editor.getSelection();\r
+                               selection.selectElement( element );\r
+                       }\r
+\r
+                       // Explicitly fire selectionChange when clicking on an element path button. (#13548)\r
+                       if ( CKEDITOR.env.ie ) {\r
+                               editor.fire( 'selectionChange', { selection: selection, path: new CKEDITOR.dom.elementPath( element ) } );\r
+                       }\r
+\r
+                       // It is important to focus() *after* the above selection\r
+                       // manipulation, otherwise Firefox will have troubles. #10119\r
+                       editor.focus();\r
+               }\r
+\r
+               elementsPath.onClick = onClick;\r
+\r
+               var onClickHanlder = CKEDITOR.tools.addFunction( onClick ),\r
+                       onKeyDownHandler = CKEDITOR.tools.addFunction( function( elementIndex, ev ) {\r
+                               var idBase = elementsPath.idBase,\r
+                                       element;\r
+\r
+                               ev = new CKEDITOR.dom.event( ev );\r
+\r
+                               var rtl = editor.lang.dir == 'rtl';\r
+                               switch ( ev.getKeystroke() ) {\r
+                                       case rtl ? 39 : 37: // LEFT-ARROW\r
+                                       case 9: // TAB\r
+                                               element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) );\r
+                                               if ( !element )\r
+                                                       element = CKEDITOR.document.getById( idBase + '0' );\r
+                                               element.focus();\r
+                                               return false;\r
+\r
+                                       case rtl ? 37 : 39: // RIGHT-ARROW\r
+                                       case CKEDITOR.SHIFT + 9: // SHIFT + TAB\r
+                                               element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) );\r
+                                               if ( !element )\r
+                                                       element = CKEDITOR.document.getById( idBase + ( elementsPath.list.length - 1 ) );\r
+                                               element.focus();\r
+                                               return false;\r
+\r
+                                       case 27: // ESC\r
+                                               editor.focus();\r
+                                               return false;\r
+\r
+                                       case 13: // ENTER       // Opera\r
+                                       case 32: // SPACE\r
+                                               onClick( elementIndex );\r
+                                               return false;\r
+                               }\r
+                               return true;\r
+                       } );\r
+\r
+               editor.on( 'selectionChange', function() {\r
+                       var html = [],\r
+                               elementsList = elementsPath.list = [],\r
+                               namesList = [],\r
+                               filters = elementsPath.filters,\r
+                               isContentEditable = true,\r
+\r
+                               // Use elementPath to consider children of editable only (#11124).\r
+                               elementsChain = editor.elementPath().elements,\r
+                               name;\r
+\r
+                       // Starts iteration from body element, skipping html.\r
+                       for ( var j = elementsChain.length; j--; ) {\r
+                               var element = elementsChain[ j ],\r
+                                       ignore = 0;\r
+\r
+                               if ( element.data( 'cke-display-name' ) )\r
+                                       name = element.data( 'cke-display-name' );\r
+                               else if ( element.data( 'cke-real-element-type' ) )\r
+                                       name = element.data( 'cke-real-element-type' );\r
+                               else\r
+                                       name = element.getName();\r
+\r
+                               isContentEditable = element.hasAttribute( 'contenteditable' ) ?\r
+                                       element.getAttribute( 'contenteditable' ) == 'true' : isContentEditable;\r
+\r
+                               // If elem is non-contenteditable, and it's not specifying contenteditable\r
+                               // attribute - then elem should be ignored.\r
+                               if ( !isContentEditable && !element.hasAttribute( 'contenteditable' ) )\r
+                                       ignore = 1;\r
+\r
+                               for ( var i = 0; i < filters.length; i++ ) {\r
+                                       var ret = filters[ i ]( element, name );\r
+                                       if ( ret === false ) {\r
+                                               ignore = 1;\r
+                                               break;\r
+                                       }\r
+                                       name = ret || name;\r
+                               }\r
+\r
+                               if ( !ignore ) {\r
+                                       elementsList.unshift( element );\r
+                                       namesList.unshift( name );\r
+                               }\r
+                       }\r
+\r
+                       for ( var iterationLimit = elementsList.length, index = 0; index < iterationLimit; index++ ) {\r
+                               name = namesList[ index ];\r
+                               var label = editor.lang.elementspath.eleTitle.replace( /%1/, name ),\r
+                                       item = pathItemTpl.output( {\r
+                                               id: idBase + index,\r
+                                               label: label,\r
+                                               text: name,\r
+                                               jsTitle: 'javascript:void(\'' + name + '\')', // jshint ignore:line\r
+                                               index: index,\r
+                                               keyDownFn: onKeyDownHandler,\r
+                                               clickFn: onClickHanlder\r
+                                       } );\r
+\r
+                               html.unshift( item );\r
+                       }\r
+\r
+                       var space = getSpaceElement();\r
+                       space.setHtml( html.join( '' ) + emptyHtml );\r
+                       editor.fire( 'elementsPathUpdate', { space: space } );\r
+               } );\r
+\r
+               function empty() {\r
+                       spaceElement && spaceElement.setHtml( emptyHtml );\r
+                       delete elementsPath.list;\r
+               }\r
+\r
+               editor.on( 'readOnly', empty );\r
+               editor.on( 'contentDomUnload', empty );\r
+\r
+               editor.addCommand( 'elementsPathFocus', commands.toolbarFocus );\r
+               editor.setKeystroke( CKEDITOR.ALT + 122 /*F11*/, 'elementsPathFocus' );\r
+       }\r
+} )();\r
+\r
+/**\r
+ * Fired when the contents of the elementsPath are changed.\r
+ *\r
+ * @event elementsPathUpdate\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {CKEDITOR.dom.element} data.space The elementsPath container.\r
+ */\r
diff --git a/sources/plugins/enterkey/plugin.js b/sources/plugins/enterkey/plugin.js
new file mode 100644 (file)
index 0000000..9410bbd
--- /dev/null
@@ -0,0 +1,566 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'enterkey', {\r
+               init: function( editor ) {\r
+                       editor.addCommand( 'enter', {\r
+                               modes: { wysiwyg: 1 },\r
+                               editorFocus: false,\r
+                               exec: function( editor ) {\r
+                                       enter( editor );\r
+                               }\r
+                       } );\r
+\r
+                       editor.addCommand( 'shiftEnter', {\r
+                               modes: { wysiwyg: 1 },\r
+                               editorFocus: false,\r
+                               exec: function( editor ) {\r
+                                       shiftEnter( editor );\r
+                               }\r
+                       } );\r
+\r
+                       editor.setKeystroke( [\r
+                               [ 13, 'enter' ],\r
+                               [ CKEDITOR.SHIFT + 13, 'shiftEnter' ]\r
+                       ] );\r
+               }\r
+       } );\r
+\r
+       var whitespaces = CKEDITOR.dom.walker.whitespaces(),\r
+               bookmark = CKEDITOR.dom.walker.bookmark();\r
+\r
+       CKEDITOR.plugins.enterkey = {\r
+               enterBlock: function( editor, mode, range, forceMode ) {\r
+                       // Get the range for the current selection.\r
+                       range = range || getRange( editor );\r
+\r
+                       // We may not have valid ranges to work on, like when inside a\r
+                       // contenteditable=false element.\r
+                       if ( !range )\r
+                               return;\r
+\r
+                       // When range is in nested editable, we have to replace range with this one,\r
+                       // which have root property set to closest editable, to make auto paragraphing work. (#12162)\r
+                       range = replaceRangeWithClosestEditableRoot( range );\r
+\r
+                       var doc = range.document;\r
+\r
+                       var atBlockStart = range.checkStartOfBlock(),\r
+                               atBlockEnd = range.checkEndOfBlock(),\r
+                               path = editor.elementPath( range.startContainer ),\r
+                               block = path.block,\r
+\r
+                               // Determine the block element to be used.\r
+                               blockTag = ( mode == CKEDITOR.ENTER_DIV ? 'div' : 'p' ),\r
+\r
+                               newBlock;\r
+\r
+                       // Exit the list when we're inside an empty list item block. (#5376)\r
+                       if ( atBlockStart && atBlockEnd ) {\r
+                               // Exit the list when we're inside an empty list item block. (#5376)\r
+                               if ( block && ( block.is( 'li' ) || block.getParent().is( 'li' ) ) ) {\r
+                                       // Make sure to point to the li when dealing with empty list item.\r
+                                       if ( !block.is( 'li' ) )\r
+                                               block = block.getParent();\r
+\r
+                                       var blockParent = block.getParent(),\r
+                                               blockGrandParent = blockParent.getParent(),\r
+\r
+                                               firstChild = !block.hasPrevious(),\r
+                                               lastChild = !block.hasNext(),\r
+\r
+                                               selection = editor.getSelection(),\r
+                                               bookmarks = selection.createBookmarks(),\r
+\r
+                                               orgDir = block.getDirection( 1 ),\r
+                                               className = block.getAttribute( 'class' ),\r
+                                               style = block.getAttribute( 'style' ),\r
+                                               dirLoose = blockGrandParent.getDirection( 1 ) != orgDir,\r
+\r
+                                               enterMode = editor.enterMode,\r
+                                               needsBlock = enterMode != CKEDITOR.ENTER_BR || dirLoose || style || className,\r
+\r
+                                               child;\r
+\r
+                                       if ( blockGrandParent.is( 'li' ) ) {\r
+\r
+                                               // If block is the first or the last child of the parent\r
+                                               // list, degrade it and move to the outer list:\r
+                                               // before the parent list if block is first child and after\r
+                                               // the parent list if block is the last child, respectively.\r
+                                               //\r
+                                               //  <ul>                         =>      <ul>\r
+                                               //      <li>                     =>          <li>\r
+                                               //          <ul>                 =>              <ul>\r
+                                               //              <li>x</li>       =>                  <li>x</li>\r
+                                               //              <li>^</li>       =>              </ul>\r
+                                               //          </ul>                =>          </li>\r
+                                               //      </li>                    =>          <li>^</li>\r
+                                               //  </ul>                        =>      </ul>\r
+                                               //\r
+                                               //                              AND\r
+                                               //\r
+                                               //  <ul>                         =>      <ul>\r
+                                               //      <li>                     =>          <li>^</li>\r
+                                               //          <ul>                 =>          <li>\r
+                                               //              <li>^</li>       =>              <ul>\r
+                                               //              <li>x</li>       =>                  <li>x</li>\r
+                                               //          </ul>                =>              </ul>\r
+                                               //      </li>                    =>          </li>\r
+                                               //  </ul>                        =>      </ul>\r
+\r
+                                               if ( firstChild || lastChild ) {\r
+\r
+                                                       // If it's only child, we don't want to keep perent ul anymore.\r
+                                                       if ( firstChild && lastChild ) {\r
+                                                               blockParent.remove();\r
+                                                       }\r
+\r
+                                                       block[lastChild ? 'insertAfter' : 'insertBefore']( blockGrandParent );\r
+\r
+                                                       // If the empty block is neither first nor last child\r
+                                                       // then split the list and the block as an element\r
+                                                       // of outer list.\r
+                                                       //\r
+                                                       //                              =>      <ul>\r
+                                                       //                              =>          <li>\r
+                                                       //  <ul>                        =>              <ul>\r
+                                                       //      <li>                    =>                  <li>x</li>\r
+                                                       //          <ul>                =>              </ul>\r
+                                                       //              <li>x</li>      =>          </li>\r
+                                                       //              <li>^</li>      =>          <li>^</li>\r
+                                                       //              <li>y</li>      =>          <li>\r
+                                                       //          </ul>               =>              <ul>\r
+                                                       //      </li>                   =>                  <li>y</li>\r
+                                                       //  </ul>                       =>              </ul>\r
+                                                       //                              =>          </li>\r
+                                                       //                              =>      </ul>\r
+\r
+                                               } else {\r
+                                                       block.breakParent( blockGrandParent );\r
+                                               }\r
+                                       }\r
+\r
+                                       else if ( !needsBlock ) {\r
+                                               block.appendBogus( true );\r
+\r
+                                               // If block is the first or last child of the parent\r
+                                               // list, move all block's children out of the list:\r
+                                               // before the list if block is first child and after the list\r
+                                               // if block is the last child, respectively.\r
+                                               //\r
+                                               //  <ul>                       =>      <ul>\r
+                                               //      <li>x</li>             =>          <li>x</li>\r
+                                               //      <li>^</li>             =>      </ul>\r
+                                               //  </ul>                      =>      ^\r
+                                               //\r
+                                               //                            AND\r
+                                               //\r
+                                               //  <ul>                       =>      ^\r
+                                               //      <li>^</li>             =>      <ul>\r
+                                               //      <li>x</li>             =>          <li>x</li>\r
+                                               //  </ul>                      =>      </ul>\r
+\r
+                                               if ( firstChild || lastChild ) {\r
+                                                       while ( ( child = block[ firstChild ? 'getFirst' : 'getLast' ]() ) )\r
+                                                               child[ firstChild ? 'insertBefore' : 'insertAfter' ]( blockParent );\r
+                                               }\r
+\r
+                                               // If the empty block is neither first nor last child\r
+                                               // then split the list and put all the block contents\r
+                                               // between two lists.\r
+                                               //\r
+                                               //  <ul>                       =>      <ul>\r
+                                               //      <li>x</li>             =>          <li>x</li>\r
+                                               //      <li>^</li>             =>      </ul>\r
+                                               //      <li>y</li>             =>      ^\r
+                                               //  </ul>                      =>      <ul>\r
+                                               //                             =>          <li>y</li>\r
+                                               //                             =>      </ul>\r
+\r
+                                               else {\r
+                                                       block.breakParent( blockParent );\r
+\r
+                                                       while ( ( child = block.getLast() ) )\r
+                                                               child.insertAfter( blockParent );\r
+                                               }\r
+\r
+                                               block.remove();\r
+                                       } else {\r
+                                               // Original path block is the list item, create new block for the list item content.\r
+                                               if ( path.block.is( 'li' ) ) {\r
+                                                       // Use <div> block for ENTER_BR and ENTER_DIV.\r
+                                                       newBlock = doc.createElement( mode == CKEDITOR.ENTER_P ? 'p' : 'div' );\r
+\r
+                                                       if ( dirLoose )\r
+                                                               newBlock.setAttribute( 'dir', orgDir );\r
+\r
+                                                       style && newBlock.setAttribute( 'style', style );\r
+                                                       className && newBlock.setAttribute( 'class', className );\r
+\r
+                                                       // Move all the child nodes to the new block.\r
+                                                       block.moveChildren( newBlock );\r
+                                               }\r
+                                               // The original path block is not a list item, just copy the block to out side of the list.\r
+                                               else {\r
+                                                       newBlock = path.block;\r
+                                               }\r
+\r
+                                               // If block is the first or last child of the parent\r
+                                               // list, move it out of the list:\r
+                                               // before the list if block is first child and after the list\r
+                                               // if block is the last child, respectively.\r
+                                               //\r
+                                               //  <ul>                       =>      <ul>\r
+                                               //      <li>x</li>             =>          <li>x</li>\r
+                                               //      <li>^</li>             =>      </ul>\r
+                                               //  </ul>                      =>      <p>^</p>\r
+                                               //\r
+                                               //                            AND\r
+                                               //\r
+                                               //  <ul>                       =>      <p>^</p>\r
+                                               //      <li>^</li>             =>      <ul>\r
+                                               //      <li>x</li>             =>          <li>x</li>\r
+                                               //  </ul>                      =>      </ul>\r
+\r
+                                               if ( firstChild || lastChild )\r
+                                                       newBlock[ firstChild ? 'insertBefore' : 'insertAfter' ]( blockParent );\r
+\r
+                                               // If the empty block is neither first nor last child\r
+                                               // then split the list and put the new block between\r
+                                               // two lists.\r
+                                               //\r
+                                               //                             =>       <ul>\r
+                                               //     <ul>                    =>           <li>x</li>\r
+                                               //         <li>x</li>          =>       </ul>\r
+                                               //         <li>^</li>          =>       <p>^</p>\r
+                                               //         <li>y</li>          =>       <ul>\r
+                                               //     </ul>                   =>           <li>y</li>\r
+                                               //                             =>       </ul>\r
+\r
+                                               else {\r
+                                                       block.breakParent( blockParent );\r
+                                                       newBlock.insertAfter( blockParent );\r
+                                               }\r
+\r
+                                               block.remove();\r
+                                       }\r
+\r
+                                       selection.selectBookmarks( bookmarks );\r
+\r
+                                       return;\r
+                               }\r
+\r
+                               if ( block && block.getParent().is( 'blockquote' ) ) {\r
+                                       block.breakParent( block.getParent() );\r
+\r
+                                       // If we were at the start of <blockquote>, there will be an empty element before it now.\r
+                                       if ( !block.getPrevious().getFirst( CKEDITOR.dom.walker.invisible( 1 ) ) )\r
+                                               block.getPrevious().remove();\r
+\r
+                                       // If we were at the end of <blockquote>, there will be an empty element after it now.\r
+                                       if ( !block.getNext().getFirst( CKEDITOR.dom.walker.invisible( 1 ) ) )\r
+                                               block.getNext().remove();\r
+\r
+                                       range.moveToElementEditStart( block );\r
+                                       range.select();\r
+                                       return;\r
+                               }\r
+                       }\r
+                       // Don't split <pre> if we're in the middle of it, act as shift enter key.\r
+                       else if ( block && block.is( 'pre' ) ) {\r
+                               if ( !atBlockEnd ) {\r
+                                       enterBr( editor, mode, range, forceMode );\r
+                                       return;\r
+                               }\r
+                       }\r
+\r
+                       // Split the range.\r
+                       var splitInfo = range.splitBlock( blockTag );\r
+\r
+                       if ( !splitInfo )\r
+                               return;\r
+\r
+                       // Get the current blocks.\r
+                       var previousBlock = splitInfo.previousBlock,\r
+                               nextBlock = splitInfo.nextBlock;\r
+\r
+                       var isStartOfBlock = splitInfo.wasStartOfBlock,\r
+                               isEndOfBlock = splitInfo.wasEndOfBlock;\r
+\r
+                       var node;\r
+\r
+                       // If this is a block under a list item, split it as well. (#1647)\r
+                       if ( nextBlock ) {\r
+                               node = nextBlock.getParent();\r
+                               if ( node.is( 'li' ) ) {\r
+                                       nextBlock.breakParent( node );\r
+                                       nextBlock.move( nextBlock.getNext(), 1 );\r
+                               }\r
+                       } else if ( previousBlock && ( node = previousBlock.getParent() ) && node.is( 'li' ) ) {\r
+                               previousBlock.breakParent( node );\r
+                               node = previousBlock.getNext();\r
+                               range.moveToElementEditStart( node );\r
+                               previousBlock.move( previousBlock.getPrevious() );\r
+                       }\r
+\r
+                       // If we have both the previous and next blocks, it means that the\r
+                       // boundaries were on separated blocks, or none of them where on the\r
+                       // block limits (start/end).\r
+                       if ( !isStartOfBlock && !isEndOfBlock ) {\r
+                               // If the next block is an <li> with another list tree as the first\r
+                               // child, we'll need to append a filler (<br>/NBSP) or the list item\r
+                               // wouldn't be editable. (#1420)\r
+                               if ( nextBlock.is( 'li' ) ) {\r
+                                       var walkerRange = range.clone();\r
+                                       walkerRange.selectNodeContents( nextBlock );\r
+                                       var walker = new CKEDITOR.dom.walker( walkerRange );\r
+                                       walker.evaluator = function( node ) {\r
+                                               return !( bookmark( node ) || whitespaces( node ) || node.type == CKEDITOR.NODE_ELEMENT && node.getName() in CKEDITOR.dtd.$inline && !( node.getName() in CKEDITOR.dtd.$empty ) );\r
+                                       };\r
+\r
+                                       node = walker.next();\r
+                                       if ( node && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'ul', 'ol' ) )\r
+                                               ( CKEDITOR.env.needsBrFiller ? doc.createElement( 'br' ) : doc.createText( '\xa0' ) ).insertBefore( node );\r
+                               }\r
+\r
+                               // Move the selection to the end block.\r
+                               if ( nextBlock )\r
+                                       range.moveToElementEditStart( nextBlock );\r
+                       } else {\r
+                               var newBlockDir;\r
+\r
+                               if ( previousBlock ) {\r
+                                       // Do not enter this block if it's a header tag, or we are in\r
+                                       // a Shift+Enter (#77). Create a new block element instead\r
+                                       // (later in the code).\r
+                                       if ( previousBlock.is( 'li' ) || !( headerTagRegex.test( previousBlock.getName() ) || previousBlock.is( 'pre' ) ) ) {\r
+                                               // Otherwise, duplicate the previous block.\r
+                                               newBlock = previousBlock.clone();\r
+                                       }\r
+                               } else if ( nextBlock ) {\r
+                                       newBlock = nextBlock.clone();\r
+                               }\r
+\r
+                               if ( !newBlock ) {\r
+                                       // We have already created a new list item. (#6849)\r
+                                       if ( node && node.is( 'li' ) )\r
+                                               newBlock = node;\r
+                                       else {\r
+                                               newBlock = doc.createElement( blockTag );\r
+                                               if ( previousBlock && ( newBlockDir = previousBlock.getDirection() ) )\r
+                                                       newBlock.setAttribute( 'dir', newBlockDir );\r
+                                       }\r
+                               }\r
+                               // Force the enter block unless we're talking of a list item.\r
+                               else if ( forceMode && !newBlock.is( 'li' ) ) {\r
+                                       newBlock.renameNode( blockTag );\r
+                               }\r
+\r
+                               // Recreate the inline elements tree, which was available\r
+                               // before hitting enter, so the same styles will be available in\r
+                               // the new block.\r
+                               var elementPath = splitInfo.elementPath;\r
+                               if ( elementPath ) {\r
+                                       for ( var i = 0, len = elementPath.elements.length; i < len; i++ ) {\r
+                                               var element = elementPath.elements[ i ];\r
+\r
+                                               if ( element.equals( elementPath.block ) || element.equals( elementPath.blockLimit ) )\r
+                                                       break;\r
+\r
+                                               if ( CKEDITOR.dtd.$removeEmpty[ element.getName() ] ) {\r
+                                                       element = element.clone();\r
+                                                       newBlock.moveChildren( element );\r
+                                                       newBlock.append( element );\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               newBlock.appendBogus();\r
+\r
+                               if ( !newBlock.getParent() )\r
+                                       range.insertNode( newBlock );\r
+\r
+                               // list item start number should not be duplicated (#7330), but we need\r
+                               // to remove the attribute after it's onto the DOM tree because of old IEs (#7581).\r
+                               newBlock.is( 'li' ) && newBlock.removeAttribute( 'value' );\r
+\r
+                               // This is tricky, but to make the new block visible correctly\r
+                               // we must select it.\r
+                               // The previousBlock check has been included because it may be\r
+                               // empty if we have fixed a block-less space (like ENTER into an\r
+                               // empty table cell).\r
+                               if ( CKEDITOR.env.ie && isStartOfBlock && ( !isEndOfBlock || !previousBlock.getChildCount() ) ) {\r
+                                       // Move the selection to the new block.\r
+                                       range.moveToElementEditStart( isEndOfBlock ? previousBlock : newBlock );\r
+                                       range.select();\r
+                               }\r
+\r
+                               // Move the selection to the new block.\r
+                               range.moveToElementEditStart( isStartOfBlock && !isEndOfBlock ? nextBlock : newBlock );\r
+                       }\r
+\r
+                       range.select();\r
+                       range.scrollIntoView();\r
+               },\r
+\r
+               enterBr: function( editor, mode, range, forceMode ) {\r
+                       // Get the range for the current selection.\r
+                       range = range || getRange( editor );\r
+\r
+                       // We may not have valid ranges to work on, like when inside a\r
+                       // contenteditable=false element.\r
+                       if ( !range )\r
+                               return;\r
+\r
+                       var doc = range.document;\r
+\r
+                       var isEndOfBlock = range.checkEndOfBlock();\r
+\r
+                       var elementPath = new CKEDITOR.dom.elementPath( editor.getSelection().getStartElement() );\r
+\r
+                       var startBlock = elementPath.block,\r
+                               startBlockTag = startBlock && elementPath.block.getName();\r
+\r
+                       if ( !forceMode && startBlockTag == 'li' ) {\r
+                               enterBlock( editor, mode, range, forceMode );\r
+                               return;\r
+                       }\r
+\r
+                       // If we are at the end of a header block.\r
+                       if ( !forceMode && isEndOfBlock && headerTagRegex.test( startBlockTag ) ) {\r
+                               var newBlock, newBlockDir;\r
+\r
+                               if ( ( newBlockDir = startBlock.getDirection() ) ) {\r
+                                       newBlock = doc.createElement( 'div' );\r
+                                       newBlock.setAttribute( 'dir', newBlockDir );\r
+                                       newBlock.insertAfter( startBlock );\r
+                                       range.setStart( newBlock, 0 );\r
+                               } else {\r
+                                       // Insert a <br> after the current paragraph.\r
+                                       doc.createElement( 'br' ).insertAfter( startBlock );\r
+\r
+                                       // A text node is required by Gecko only to make the cursor blink.\r
+                                       if ( CKEDITOR.env.gecko )\r
+                                               doc.createText( '' ).insertAfter( startBlock );\r
+\r
+                                       // IE has different behaviors regarding position.\r
+                                       range.setStartAt( startBlock.getNext(), CKEDITOR.env.ie ? CKEDITOR.POSITION_BEFORE_START : CKEDITOR.POSITION_AFTER_START );\r
+                               }\r
+                       } else {\r
+                               var lineBreak;\r
+\r
+                               // IE<8 prefers text node as line-break inside of <pre> (#4711).\r
+                               if ( startBlockTag == 'pre' && CKEDITOR.env.ie && CKEDITOR.env.version < 8 )\r
+                                       lineBreak = doc.createText( '\r' );\r
+                               else\r
+                                       lineBreak = doc.createElement( 'br' );\r
+\r
+                               range.deleteContents();\r
+                               range.insertNode( lineBreak );\r
+\r
+                               // Old IEs have different behavior regarding position.\r
+                               if ( !CKEDITOR.env.needsBrFiller )\r
+                                       range.setStartAt( lineBreak, CKEDITOR.POSITION_AFTER_END );\r
+                               else {\r
+                                       // A text node is required by Gecko only to make the cursor blink.\r
+                                       // We need some text inside of it, so the bogus <br> is properly\r
+                                       // created.\r
+                                       doc.createText( '\ufeff' ).insertAfter( lineBreak );\r
+\r
+                                       // If we are at the end of a block, we must be sure the bogus node is available in that block.\r
+                                       if ( isEndOfBlock ) {\r
+                                               // In most situations we've got an elementPath.block (e.g. <p>), but in a\r
+                                               // blockless editor or when autoP is false that needs to be a block limit.\r
+                                               ( startBlock || elementPath.blockLimit ).appendBogus();\r
+                                       }\r
+\r
+                                       // Now we can remove the text node contents, so the caret doesn't\r
+                                       // stop on it.\r
+                                       lineBreak.getNext().$.nodeValue = '';\r
+\r
+                                       range.setStartAt( lineBreak.getNext(), CKEDITOR.POSITION_AFTER_START );\r
+\r
+                               }\r
+                       }\r
+\r
+                       // This collapse guarantees the cursor will be blinking.\r
+                       range.collapse( true );\r
+\r
+                       range.select();\r
+                       range.scrollIntoView();\r
+               }\r
+       };\r
+\r
+       var plugin = CKEDITOR.plugins.enterkey,\r
+               enterBr = plugin.enterBr,\r
+               enterBlock = plugin.enterBlock,\r
+               headerTagRegex = /^h[1-6]$/;\r
+\r
+       function shiftEnter( editor ) {\r
+               // On SHIFT+ENTER:\r
+               // 1. We want to enforce the mode to be respected, instead\r
+               // of cloning the current block. (#77)\r
+               return enter( editor, editor.activeShiftEnterMode, 1 );\r
+       }\r
+\r
+       function enter( editor, mode, forceMode ) {\r
+               forceMode = editor.config.forceEnterMode || forceMode;\r
+\r
+               // Only effective within document.\r
+               if ( editor.mode != 'wysiwyg' )\r
+                       return;\r
+\r
+               if ( !mode )\r
+                       mode = editor.activeEnterMode;\r
+\r
+               // TODO this should be handled by setting editor.activeEnterMode on selection change.\r
+               // Check path block specialities:\r
+               // 1. Cannot be a un-splittable element, e.g. table caption;\r
+               var path = editor.elementPath();\r
+               if ( !path.isContextFor( 'p' ) ) {\r
+                       mode = CKEDITOR.ENTER_BR;\r
+                       forceMode = 1;\r
+               }\r
+\r
+               editor.fire( 'saveSnapshot' ); // Save undo step.\r
+\r
+               if ( mode == CKEDITOR.ENTER_BR )\r
+                       enterBr( editor, mode, null, forceMode );\r
+               else\r
+                       enterBlock( editor, mode, null, forceMode );\r
+\r
+               editor.fire( 'saveSnapshot' );\r
+       }\r
+\r
+       function getRange( editor ) {\r
+               // Get the selection ranges.\r
+               var ranges = editor.getSelection().getRanges( true );\r
+\r
+               // Delete the contents of all ranges except the first one.\r
+               for ( var i = ranges.length - 1; i > 0; i-- ) {\r
+                       ranges[ i ].deleteContents();\r
+               }\r
+\r
+               // Return the first range.\r
+               return ranges[ 0 ];\r
+       }\r
+\r
+       function replaceRangeWithClosestEditableRoot( range ) {\r
+               var closestEditable = range.startContainer.getAscendant( function( node ) {\r
+                       return node.type == CKEDITOR.NODE_ELEMENT && node.getAttribute( 'contenteditable' ) == 'true';\r
+               }, true );\r
+\r
+               if ( range.root.equals( closestEditable ) ) {\r
+                       return range;\r
+               } else {\r
+                       var newRange = new CKEDITOR.dom.range( closestEditable );\r
+\r
+                       newRange.moveToRange( range );\r
+                       return newRange;\r
+               }\r
+       }\r
+} )();\r
diff --git a/sources/plugins/enterkey/samples/enterkey.html b/sources/plugins/enterkey/samples/enterkey.html
new file mode 100644 (file)
index 0000000..79afee3
--- /dev/null
@@ -0,0 +1,106 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>ENTER Key Configuration &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-name" content="Using the &quot;Enter&quot; key in CKEditor">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring the behavior of &lt;em&gt;Enter&lt;/em&gt; and &lt;em&gt;Shift+Enter&lt;/em&gt; keys.">\r
+       <script>\r
+\r
+               var editor;\r
+\r
+               function changeEnter() {\r
+                       // If we already have an editor, let's destroy it first.\r
+                       if ( editor )\r
+                               editor.destroy( true );\r
+\r
+                       // Create the editor again, with the appropriate settings.\r
+                       editor = CKEDITOR.replace( 'editor1', {\r
+                               extraPlugins: 'enterkey',\r
+                               enterMode: Number( document.getElementById( 'xEnter' ).value ),\r
+                               shiftEnterMode: Number( document.getElementById( 'xShiftEnter' ).value )\r
+                       });\r
+               }\r
+\r
+               window.onload = changeEnter;\r
+\r
+       </script>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; ENTER Key Configuration\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/enterkey.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure the <em>Enter</em> and <em>Shift+Enter</em> keys\r
+                       to perform actions specified in the\r
+                       <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-enterMode"><code>enterMode</code></a>\r
+                       and <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-shiftEnterMode"><code>shiftEnterMode</code></a>\r
+                       parameters, respectively.\r
+                       You can choose from the following options:\r
+               </p>\r
+               <ul class="samples">\r
+                       <li><strong><code>ENTER_P</code></strong> &ndash; new <code>&lt;p&gt;</code> paragraphs are created;</li>\r
+                       <li><strong><code>ENTER_BR</code></strong> &ndash; lines are broken with <code>&lt;br&gt;</code> elements;</li>\r
+                       <li><strong><code>ENTER_DIV</code></strong> &ndash; new <code>&lt;div&gt;</code> blocks are created.</li>\r
+               </ul>\r
+               <p>\r
+                       The sample code below shows how to configure CKEditor to create a <code>&lt;div&gt;</code> block when <em>Enter</em> key is pressed.\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       <strong>enterMode: CKEDITOR.ENTER_DIV</strong>\r
+});</pre>\r
+               <p>\r
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+                       the <code>&lt;textarea&gt;</code> element to be replaced.\r
+               </p>\r
+       </div>\r
+       <div style="float: left; margin-right: 20px">\r
+               When <em>Enter</em> is pressed:<br>\r
+               <select id="xEnter" onchange="changeEnter();">\r
+                       <option selected="selected" value="1">Create a new &lt;P&gt; (recommended)</option>\r
+                       <option value="3">Create a new &lt;DIV&gt;</option>\r
+                       <option value="2">Break the line with a &lt;BR&gt;</option>\r
+               </select>\r
+       </div>\r
+       <div style="float: left">\r
+               When <em>Shift+Enter</em> is pressed:<br>\r
+               <select id="xShiftEnter" onchange="changeEnter();">\r
+                       <option value="1">Create a new &lt;P&gt;</option>\r
+                       <option value="3">Create a new &lt;DIV&gt;</option>\r
+                       <option selected="selected" value="2">Break the line with a &lt;BR&gt; (recommended)</option>\r
+               </select>\r
+       </div>\r
+       <br style="clear: both">\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <p>\r
+                       <br>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.</textarea>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/entities/plugin.js b/sources/plugins/entities/plugin.js
new file mode 100644 (file)
index 0000000..d457ad1
--- /dev/null
@@ -0,0 +1,239 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       // Basic HTML entities.\r
+       var htmlbase = 'nbsp,gt,lt,amp';\r
+\r
+       var entities =\r
+       // Latin-1 entities\r
+       'quot,iexcl,cent,pound,curren,yen,brvbar,sect,uml,copy,ordf,laquo,' +\r
+               'not,shy,reg,macr,deg,plusmn,sup2,sup3,acute,micro,para,middot,' +\r
+               'cedil,sup1,ordm,raquo,frac14,frac12,frac34,iquest,times,divide,' +\r
+\r
+               // Symbols\r
+               'fnof,bull,hellip,prime,Prime,oline,frasl,weierp,image,real,trade,' +\r
+               'alefsym,larr,uarr,rarr,darr,harr,crarr,lArr,uArr,rArr,dArr,hArr,' +\r
+               'forall,part,exist,empty,nabla,isin,notin,ni,prod,sum,minus,lowast,' +\r
+               'radic,prop,infin,ang,and,or,cap,cup,int,there4,sim,cong,asymp,ne,' +\r
+               'equiv,le,ge,sub,sup,nsub,sube,supe,oplus,otimes,perp,sdot,lceil,' +\r
+               'rceil,lfloor,rfloor,lang,rang,loz,spades,clubs,hearts,diams,' +\r
+\r
+               // Other special characters\r
+               'circ,tilde,ensp,emsp,thinsp,zwnj,zwj,lrm,rlm,ndash,mdash,lsquo,' +\r
+               'rsquo,sbquo,ldquo,rdquo,bdquo,dagger,Dagger,permil,lsaquo,rsaquo,' +\r
+               'euro';\r
+\r
+       // Latin letters entities\r
+       var latin = 'Agrave,Aacute,Acirc,Atilde,Auml,Aring,AElig,Ccedil,Egrave,Eacute,' +\r
+               'Ecirc,Euml,Igrave,Iacute,Icirc,Iuml,ETH,Ntilde,Ograve,Oacute,Ocirc,' +\r
+               'Otilde,Ouml,Oslash,Ugrave,Uacute,Ucirc,Uuml,Yacute,THORN,szlig,' +\r
+               'agrave,aacute,acirc,atilde,auml,aring,aelig,ccedil,egrave,eacute,' +\r
+               'ecirc,euml,igrave,iacute,icirc,iuml,eth,ntilde,ograve,oacute,ocirc,' +\r
+               'otilde,ouml,oslash,ugrave,uacute,ucirc,uuml,yacute,thorn,yuml,' +\r
+               'OElig,oelig,Scaron,scaron,Yuml';\r
+\r
+       // Greek letters entities.\r
+       var greek = 'Alpha,Beta,Gamma,Delta,Epsilon,Zeta,Eta,Theta,Iota,Kappa,Lambda,Mu,' +\r
+               'Nu,Xi,Omicron,Pi,Rho,Sigma,Tau,Upsilon,Phi,Chi,Psi,Omega,alpha,' +\r
+               'beta,gamma,delta,epsilon,zeta,eta,theta,iota,kappa,lambda,mu,nu,xi,' +\r
+               'omicron,pi,rho,sigmaf,sigma,tau,upsilon,phi,chi,psi,omega,thetasym,' +\r
+               'upsih,piv';\r
+\r
+       // Create a mapping table between one character and its entity form from a list of entity names.\r
+       // @param reverse {Boolean} Whether to create a reverse map from the entity string form to an actual character.\r
+       function buildTable( entities, reverse ) {\r
+               var table = {},\r
+                       regex = [];\r
+\r
+               // Entities that the browsers' DOM does not automatically transform to the\r
+               // final character.\r
+               var specialTable = {\r
+                       nbsp: '\u00A0', // IE | FF\r
+                       shy: '\u00AD', // IE\r
+                       gt: '\u003E', // IE | FF |   --   | Opera\r
+                       lt: '\u003C', // IE | FF | Safari | Opera\r
+                       amp: '\u0026', // ALL\r
+                       apos: '\u0027', // IE\r
+                       quot: '\u0022' // IE\r
+               };\r
+\r
+               entities = entities.replace( /\b(nbsp|shy|gt|lt|amp|apos|quot)(?:,|$)/g, function( match, entity ) {\r
+                       var org = reverse ? '&' + entity + ';' : specialTable[ entity ],\r
+                               result = reverse ? specialTable[ entity ] : '&' + entity + ';';\r
+\r
+                       table[ org ] = result;\r
+                       regex.push( org );\r
+                       return '';\r
+               } );\r
+\r
+               if ( !reverse && entities ) {\r
+                       // Transforms the entities string into an array.\r
+                       entities = entities.split( ',' );\r
+\r
+                       // Put all entities inside a DOM element, transforming them to their\r
+                       // final characters.\r
+                       var div = document.createElement( 'div' ),\r
+                               chars;\r
+                       div.innerHTML = '&' + entities.join( ';&' ) + ';';\r
+                       chars = div.innerHTML;\r
+                       div = null;\r
+\r
+                       // Add all characters to the table.\r
+                       for ( var i = 0; i < chars.length; i++ ) {\r
+                               var charAt = chars.charAt( i );\r
+                               table[ charAt ] = '&' + entities[ i ] + ';';\r
+                               regex.push( charAt );\r
+                       }\r
+               }\r
+\r
+               table.regex = regex.join( reverse ? '|' : '' );\r
+\r
+               return table;\r
+       }\r
+\r
+       CKEDITOR.plugins.add( 'entities', {\r
+               afterInit: function( editor ) {\r
+                       var config = editor.config;\r
+\r
+                       function getChar( character ) {\r
+                               return baseEntitiesTable[ character ];\r
+                       }\r
+\r
+                       function getEntity( character ) {\r
+                               return config.entities_processNumerical == 'force' || !entitiesTable[ character ] ? '&#' + character.charCodeAt( 0 ) + ';'\r
+                               : entitiesTable[ character ];\r
+                       }\r
+\r
+                       var dataProcessor = editor.dataProcessor,\r
+                               htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
+                       if ( htmlFilter ) {\r
+                               // Mandatory HTML basic entities.\r
+                               var selectedEntities = [];\r
+\r
+                               if ( config.basicEntities !== false )\r
+                                       selectedEntities.push( htmlbase );\r
+\r
+                               if ( config.entities ) {\r
+                                       if ( selectedEntities.length )\r
+                                               selectedEntities.push( entities );\r
+\r
+                                       if ( config.entities_latin )\r
+                                               selectedEntities.push( latin );\r
+\r
+                                       if ( config.entities_greek )\r
+                                               selectedEntities.push( greek );\r
+\r
+                                       if ( config.entities_additional )\r
+                                               selectedEntities.push( config.entities_additional );\r
+                               }\r
+\r
+                               var entitiesTable = buildTable( selectedEntities.join( ',' ) );\r
+\r
+                               // Create the Regex used to find entities in the text, leave it matches nothing if entities are empty.\r
+                               var entitiesRegex = entitiesTable.regex ? '[' + entitiesTable.regex + ']' : 'a^';\r
+                               delete entitiesTable.regex;\r
+\r
+                               if ( config.entities && config.entities_processNumerical )\r
+                                       entitiesRegex = '[^ -~]|' + entitiesRegex;\r
+\r
+                               entitiesRegex = new RegExp( entitiesRegex, 'g' );\r
+\r
+                               // Decode entities that the browsers has transformed\r
+                               // at first place.\r
+                               var baseEntitiesTable = buildTable( [ htmlbase, 'shy' ].join( ',' ), true ),\r
+                                       baseEntitiesRegex = new RegExp( baseEntitiesTable.regex, 'g' );\r
+\r
+                               htmlFilter.addRules( {\r
+                                       text: function( text ) {\r
+                                               return text.replace( baseEntitiesRegex, getChar ).replace( entitiesRegex, getEntity );\r
+                                       }\r
+                               }, {\r
+                                       applyToAll: true,\r
+                                       excludeNestedEditable: true\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+} )();\r
+\r
+/**\r
+ * Whether to escape basic HTML entities in the document, including:\r
+ *\r
+ * * `&nbsp;`\r
+ * * `&gt;`\r
+ * * `&lt;`\r
+ * * `&amp;`\r
+ *\r
+ * **Note:** This option should not be changed unless when outputting a non-HTML data format like BBCode.\r
+ *\r
+ *             config.basicEntities = false;\r
+ *\r
+ * @cfg {Boolean} [basicEntities=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.basicEntities = true;\r
+\r
+/**\r
+ * Whether to use HTML entities in the editor output.\r
+ *\r
+ *             config.entities = false;\r
+ *\r
+ * @cfg {Boolean} [entities=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.entities = true;\r
+\r
+/**\r
+ * Whether to convert some Latin characters (Latin alphabet No. 1, ISO 8859-1)\r
+ * to HTML entities. The list of entities can be found in the\r
+ * [W3C HTML 4.01 Specification, section 24.2.1](http://www.w3.org/TR/html4/sgml/entities.html#h-24.2.1).\r
+ *\r
+ *             config.entities_latin = false;\r
+ *\r
+ * @cfg {Boolean} [entities_latin=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.entities_latin = true;\r
+\r
+/**\r
+ * Whether to convert some symbols, mathematical symbols, and Greek letters to\r
+ * HTML entities. This may be more relevant for users typing text written in Greek.\r
+ * The list of entities can be found in the\r
+ * [W3C HTML 4.01 Specification, section 24.3.1](http://www.w3.org/TR/html4/sgml/entities.html#h-24.3.1).\r
+ *\r
+ *             config.entities_greek = false;\r
+ *\r
+ * @cfg {Boolean} [entities_greek=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.entities_greek = true;\r
+\r
+/**\r
+ * Whether to convert all remaining characters not included in the ASCII\r
+ * character table to their relative decimal numeric representation of HTML entity.\r
+ * When set to `force`, it will convert all entities into this format.\r
+ *\r
+ * For example the phrase: `'This is Chinese: 汉语.'` would be output\r
+ * as: `'This is Chinese: &#27721;&#35821;.'`\r
+ *\r
+ *             config.entities_processNumerical = true;\r
+ *             config.entities_processNumerical = 'force'; // Converts from '&nbsp;' into '&#160;';\r
+ *\r
+ * @cfg {Boolean/String} [entities_processNumerical=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * A comma-separated list of  additional entities to be used. Entity names\r
+ * or numbers must be used in a form that excludes the `'&amp;'` prefix and the `';'` ending.\r
+ *\r
+ *             config.entities_additional = '#1049'; // Adds Cyrillic capital letter Short I (Й).\r
+ *\r
+ * @cfg {String} [entities_additional='#39' (The single quote (') character)]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.entities_additional = '#39';\r
diff --git a/sources/plugins/fakeobjects/lang/af.js b/sources/plugins/fakeobjects/lang/af.js
new file mode 100644 (file)
index 0000000..835d45b
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'af', {\r
+       anchor: 'Anker',\r
+       flash: 'Flash animasie',\r
+       hiddenfield: 'Verborge veld',\r
+       iframe: 'IFrame',\r
+       unknown: 'Onbekende objek'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ar.js b/sources/plugins/fakeobjects/lang/ar.js
new file mode 100644 (file)
index 0000000..44363c9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ar', {\r
+       anchor: 'إرساء',\r
+       flash: 'رسم متحرك بالفلاش',\r
+       hiddenfield: 'إدراج حقل خفي',\r
+       iframe: 'iframe',\r
+       unknown: 'عنصر غير معروف'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/az.js b/sources/plugins/fakeobjects/lang/az.js
new file mode 100644 (file)
index 0000000..01fa87d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'az', {\r
+       anchor: 'Lövbər',\r
+       flash: 'Flash animasiya',\r
+       hiddenfield: 'Gizli xana',\r
+       iframe: 'IFrame',\r
+       unknown: 'Tanımamış obyekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/bg.js b/sources/plugins/fakeobjects/lang/bg.js
new file mode 100644 (file)
index 0000000..538cdf1
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'bg', {\r
+       anchor: 'Кука',\r
+       flash: 'Флаш анимация',\r
+       hiddenfield: 'Скрито поле',\r
+       iframe: 'IFrame',\r
+       unknown: 'Неизвестен обект'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/bn.js b/sources/plugins/fakeobjects/lang/bn.js
new file mode 100644 (file)
index 0000000..70c9ce9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'bn', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/bs.js b/sources/plugins/fakeobjects/lang/bs.js
new file mode 100644 (file)
index 0000000..4a17242
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'bs', {\r
+       anchor: 'Anchor',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ca.js b/sources/plugins/fakeobjects/lang/ca.js
new file mode 100644 (file)
index 0000000..cc09e6c
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ca', {\r
+       anchor: 'Àncora',\r
+       flash: 'Animació Flash',\r
+       hiddenfield: 'Camp ocult',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objecte desconegut'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/cs.js b/sources/plugins/fakeobjects/lang/cs.js
new file mode 100644 (file)
index 0000000..7355f4a
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'cs', {\r
+       anchor: 'Záložka',\r
+       flash: 'Flash animace',\r
+       hiddenfield: 'Skryté pole',\r
+       iframe: 'IFrame',\r
+       unknown: 'Neznámý objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/cy.js b/sources/plugins/fakeobjects/lang/cy.js
new file mode 100644 (file)
index 0000000..8b0ffc9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'cy', {\r
+       anchor: 'Angor',\r
+       flash: 'Animeiddiant Flash',\r
+       hiddenfield: 'Maes Cudd',\r
+       iframe: 'IFrame',\r
+       unknown: 'Gwrthrych Anhysbys'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/da.js b/sources/plugins/fakeobjects/lang/da.js
new file mode 100644 (file)
index 0000000..06a869f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'da', {\r
+       anchor: 'Anker',\r
+       flash: 'Flashanimation',\r
+       hiddenfield: 'Skjult felt',\r
+       iframe: 'Iframe',\r
+       unknown: 'Ukendt objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/de-ch.js b/sources/plugins/fakeobjects/lang/de-ch.js
new file mode 100644 (file)
index 0000000..068a003
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'de-ch', {\r
+       anchor: 'Anker',\r
+       flash: 'Flash-Animation',\r
+       hiddenfield: 'Verstecktes Feld',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unbekanntes Objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/de.js b/sources/plugins/fakeobjects/lang/de.js
new file mode 100644 (file)
index 0000000..32326cf
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'de', {\r
+       anchor: 'Anker',\r
+       flash: 'Flash-Animation',\r
+       hiddenfield: 'Verstecktes Feld',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unbekanntes Objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/el.js b/sources/plugins/fakeobjects/lang/el.js
new file mode 100644 (file)
index 0000000..211c8d4
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'el', {\r
+       anchor: 'Άγκυρα',\r
+       flash: 'Ταινία Flash',\r
+       hiddenfield: 'Κρυφό Πεδίο',\r
+       iframe: 'IFrame',\r
+       unknown: 'Άγνωστο Αντικείμενο'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/en-au.js b/sources/plugins/fakeobjects/lang/en-au.js
new file mode 100644 (file)
index 0000000..189e5c8
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'en-au', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/en-ca.js b/sources/plugins/fakeobjects/lang/en-ca.js
new file mode 100644 (file)
index 0000000..071bc10
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'en-ca', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/en-gb.js b/sources/plugins/fakeobjects/lang/en-gb.js
new file mode 100644 (file)
index 0000000..e38f16c
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'en-gb', {\r
+       anchor: 'Anchor',\r
+       flash: 'Flash Animation',\r
+       hiddenfield: 'Hidden Field',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unknown Object'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/en.js b/sources/plugins/fakeobjects/lang/en.js
new file mode 100644 (file)
index 0000000..d871231
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'en', {\r
+       anchor: 'Anchor',\r
+       flash: 'Flash Animation',\r
+       hiddenfield: 'Hidden Field',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unknown Object'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/eo.js b/sources/plugins/fakeobjects/lang/eo.js
new file mode 100644 (file)
index 0000000..bbce7f8
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'eo', {\r
+       anchor: 'Ankro',\r
+       flash: 'FlaŝAnimacio',\r
+       hiddenfield: 'Kaŝita kampo',\r
+       iframe: 'Enlinia Kadro (IFrame)',\r
+       unknown: 'Nekonata objekto'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/es.js b/sources/plugins/fakeobjects/lang/es.js
new file mode 100644 (file)
index 0000000..46ac72f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'es', {\r
+       anchor: 'Ancla',\r
+       flash: 'Animación flash',\r
+       hiddenfield: 'Campo oculto',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objeto desconocido'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/et.js b/sources/plugins/fakeobjects/lang/et.js
new file mode 100644 (file)
index 0000000..2c25f43
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'et', {\r
+       anchor: 'Ankur',\r
+       flash: 'Flashi animatsioon',\r
+       hiddenfield: 'Varjatud väli',\r
+       iframe: 'IFrame',\r
+       unknown: 'Tundmatu objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/eu.js b/sources/plugins/fakeobjects/lang/eu.js
new file mode 100644 (file)
index 0000000..dfc4460
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'eu', {\r
+       anchor: 'Aingura',\r
+       flash: 'Flash animazioa',\r
+       hiddenfield: 'Ezkutuko eremua',\r
+       iframe: 'IFrame-a',\r
+       unknown: 'Objektu ezezaguna'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/fa.js b/sources/plugins/fakeobjects/lang/fa.js
new file mode 100644 (file)
index 0000000..4104d1f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'fa', {\r
+       anchor: 'لنگر',\r
+       flash: 'انیمشن فلش',\r
+       hiddenfield: 'فیلد پنهان',\r
+       iframe: 'IFrame',\r
+       unknown: 'شیء ناشناخته'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/fi.js b/sources/plugins/fakeobjects/lang/fi.js
new file mode 100644 (file)
index 0000000..c663093
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'fi', {\r
+       anchor: 'Ankkuri',\r
+       flash: 'Flash animaatio',\r
+       hiddenfield: 'Piilokenttä',\r
+       iframe: 'IFrame-kehys',\r
+       unknown: 'Tuntematon objekti'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/fo.js b/sources/plugins/fakeobjects/lang/fo.js
new file mode 100644 (file)
index 0000000..8b7c2f9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'fo', {\r
+       anchor: 'Anchor',\r
+       flash: 'Flash Animation',\r
+       hiddenfield: 'Fjaldur teigur',\r
+       iframe: 'IFrame',\r
+       unknown: 'Ókent Object'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/fr-ca.js b/sources/plugins/fakeobjects/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..c281f4f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'fr-ca', {\r
+       anchor: 'Ancre',\r
+       flash: 'Animation Flash',\r
+       hiddenfield: 'Champ caché',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objet inconnu'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/fr.js b/sources/plugins/fakeobjects/lang/fr.js
new file mode 100644 (file)
index 0000000..be306ec
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'fr', {\r
+       anchor: 'Ancre',\r
+       flash: 'Animation Flash',\r
+       hiddenfield: 'Champ invisible',\r
+       iframe: 'Cadre de contenu incorporé',\r
+       unknown: 'Objet inconnu'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/gl.js b/sources/plugins/fakeobjects/lang/gl.js
new file mode 100644 (file)
index 0000000..2c353a4
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'gl', {\r
+       anchor: 'Ancoraxe',\r
+       flash: 'Animación «Flash»',\r
+       hiddenfield: 'Campo agochado',\r
+       iframe: 'IFrame',\r
+       unknown: 'Obxecto descoñecido'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/gu.js b/sources/plugins/fakeobjects/lang/gu.js
new file mode 100644 (file)
index 0000000..66fb428
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'gu', {\r
+       anchor: 'અનકર',\r
+       flash: 'ફ્લેશ ',\r
+       hiddenfield: 'હિડન ',\r
+       iframe: 'IFrame',\r
+       unknown: 'અનનોન ઓબ્જેક્ટ'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/he.js b/sources/plugins/fakeobjects/lang/he.js
new file mode 100644 (file)
index 0000000..bc0d472
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'he', {\r
+       anchor: 'עוגן',\r
+       flash: 'סרטון פלאש',\r
+       hiddenfield: 'שדה חבוי',\r
+       iframe: 'חלון פנימי (iframe)',\r
+       unknown: 'אובייקט לא ידוע'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/hi.js b/sources/plugins/fakeobjects/lang/hi.js
new file mode 100644 (file)
index 0000000..e2cc724
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'hi', {\r
+       anchor: 'ऐंकर इन्सर्ट/संपादन',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'गुप्त फ़ील्ड',\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/hr.js b/sources/plugins/fakeobjects/lang/hr.js
new file mode 100644 (file)
index 0000000..11f3574
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'hr', {\r
+       anchor: 'Sidro',\r
+       flash: 'Flash animacija',\r
+       hiddenfield: 'Sakriveno polje',\r
+       iframe: 'IFrame',\r
+       unknown: 'Nepoznati objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/hu.js b/sources/plugins/fakeobjects/lang/hu.js
new file mode 100644 (file)
index 0000000..24cec55
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'hu', {\r
+       anchor: 'Horgony',\r
+       flash: 'Flash animáció',\r
+       hiddenfield: 'Rejtett mezõ',\r
+       iframe: 'IFrame',\r
+       unknown: 'Ismeretlen objektum'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/id.js b/sources/plugins/fakeobjects/lang/id.js
new file mode 100644 (file)
index 0000000..85d8c14
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'id', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Animasi Flash',\r
+       hiddenfield: 'Kolom Tersembunyi',\r
+       iframe: 'IFrame',\r
+       unknown: 'Obyek Tak Dikenal'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/is.js b/sources/plugins/fakeobjects/lang/is.js
new file mode 100644 (file)
index 0000000..40df479
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'is', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/it.js b/sources/plugins/fakeobjects/lang/it.js
new file mode 100644 (file)
index 0000000..8993951
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'it', {\r
+       anchor: 'Ancora',\r
+       flash: 'Animazione Flash',\r
+       hiddenfield: 'Campo Nascosto',\r
+       iframe: 'IFrame',\r
+       unknown: 'Oggetto sconosciuto'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ja.js b/sources/plugins/fakeobjects/lang/ja.js
new file mode 100644 (file)
index 0000000..db21eeb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ja', {\r
+       anchor: 'アンカー',\r
+       flash: 'Flash Animation',\r
+       hiddenfield: '不可視フィールド',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unknown Object'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ka.js b/sources/plugins/fakeobjects/lang/ka.js
new file mode 100644 (file)
index 0000000..3544161
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ka', {\r
+       anchor: 'ღუზა',\r
+       flash: 'Flash ანიმაცია',\r
+       hiddenfield: 'მალული ველი',\r
+       iframe: 'IFrame',\r
+       unknown: 'უცნობი ობიექტი'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/km.js b/sources/plugins/fakeobjects/lang/km.js
new file mode 100644 (file)
index 0000000..54be6d0
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'km', {\r
+       anchor: 'យុថ្កា',\r
+       flash: 'Flash មាន​ចលនា',\r
+       hiddenfield: 'វាល​កំបាំង',\r
+       iframe: 'IFrame',\r
+       unknown: 'វត្ថុ​មិន​ស្គាល់'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ko.js b/sources/plugins/fakeobjects/lang/ko.js
new file mode 100644 (file)
index 0000000..b5c0593
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ko', {\r
+       anchor: '책갈피',\r
+       flash: '플래시 애니메이션',\r
+       hiddenfield: '숨은 입력 칸',\r
+       iframe: '아이프레임',\r
+       unknown: '알 수 없는 객체'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ku.js b/sources/plugins/fakeobjects/lang/ku.js
new file mode 100644 (file)
index 0000000..bbfb9f6
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ku', {\r
+       anchor: 'لەنگەر',\r
+       flash: 'فلاش',\r
+       hiddenfield: 'شاردنەوەی خانه',\r
+       iframe: 'لەچوارچێوە',\r
+       unknown: 'بەرکارێکی نەناسراو'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/lt.js b/sources/plugins/fakeobjects/lang/lt.js
new file mode 100644 (file)
index 0000000..e14c211
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'lt', {\r
+       anchor: 'Žymė',\r
+       flash: 'Flash animacija',\r
+       hiddenfield: 'Paslėptas laukas',\r
+       iframe: 'IFrame',\r
+       unknown: 'Nežinomas objektas'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/lv.js b/sources/plugins/fakeobjects/lang/lv.js
new file mode 100644 (file)
index 0000000..388e486
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'lv', {\r
+       anchor: 'Iezīme',\r
+       flash: 'Flash animācija',\r
+       hiddenfield: 'Slēpts lauks',\r
+       iframe: 'Iframe',\r
+       unknown: 'Nezināms objekts'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/mk.js b/sources/plugins/fakeobjects/lang/mk.js
new file mode 100644 (file)
index 0000000..deacc87
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'mk', {\r
+       anchor: 'Anchor',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Скриено поле',\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/mn.js b/sources/plugins/fakeobjects/lang/mn.js
new file mode 100644 (file)
index 0000000..a2857cc
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'mn', {\r
+       anchor: 'Зангуу',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Нууц талбар',\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ms.js b/sources/plugins/fakeobjects/lang/ms.js
new file mode 100644 (file)
index 0000000..7325f14
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ms', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/nb.js b/sources/plugins/fakeobjects/lang/nb.js
new file mode 100644 (file)
index 0000000..b6a6527
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'nb', {\r
+       anchor: 'Anker',\r
+       flash: 'Flash-animasjon',\r
+       hiddenfield: 'Skjult felt',\r
+       iframe: 'IFrame',\r
+       unknown: 'Ukjent objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/nl.js b/sources/plugins/fakeobjects/lang/nl.js
new file mode 100644 (file)
index 0000000..158985a
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'nl', {\r
+       anchor: 'Interne link',\r
+       flash: 'Flash animatie',\r
+       hiddenfield: 'Verborgen veld',\r
+       iframe: 'IFrame',\r
+       unknown: 'Onbekend object'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/no.js b/sources/plugins/fakeobjects/lang/no.js
new file mode 100644 (file)
index 0000000..cbbb4cf
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'no', {\r
+       anchor: 'Anker',\r
+       flash: 'Flash-animasjon',\r
+       hiddenfield: 'Skjult felt',\r
+       iframe: 'IFrame',\r
+       unknown: 'Ukjent objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/oc.js b/sources/plugins/fakeobjects/lang/oc.js
new file mode 100644 (file)
index 0000000..0ecfcf8
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'oc', {\r
+       anchor: 'Ancòra',\r
+       flash: 'Animacion Flash',\r
+       hiddenfield: 'Camp invisible',\r
+       iframe: 'Quadre de contengut incorporat',\r
+       unknown: 'Objècte desconegut'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/pl.js b/sources/plugins/fakeobjects/lang/pl.js
new file mode 100644 (file)
index 0000000..06b3a20
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'pl', {\r
+       anchor: 'Kotwica',\r
+       flash: 'Animacja Flash',\r
+       hiddenfield: 'Pole ukryte',\r
+       iframe: 'IFrame',\r
+       unknown: 'Nieznany obiekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/pt-br.js b/sources/plugins/fakeobjects/lang/pt-br.js
new file mode 100644 (file)
index 0000000..6198bf3
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'pt-br', {\r
+       anchor: 'Âncora',\r
+       flash: 'Animação em Flash',\r
+       hiddenfield: 'Campo Oculto',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objeto desconhecido'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/pt.js b/sources/plugins/fakeobjects/lang/pt.js
new file mode 100644 (file)
index 0000000..c3d762f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'pt', {\r
+       anchor: ' Inserir/Editar âncora',\r
+       flash: 'Animação Flash',\r
+       hiddenfield: 'Campo oculto',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objeto desconhecido'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ro.js b/sources/plugins/fakeobjects/lang/ro.js
new file mode 100644 (file)
index 0000000..25535d3
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ro', {\r
+       anchor: 'Inserează/Editează ancoră',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Câmp ascuns (HiddenField)',\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ru.js b/sources/plugins/fakeobjects/lang/ru.js
new file mode 100644 (file)
index 0000000..7f93bc7
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ru', {\r
+       anchor: 'Якорь',\r
+       flash: 'Flash анимация',\r
+       hiddenfield: 'Скрытое поле',\r
+       iframe: 'iFrame',\r
+       unknown: 'Неизвестный объект'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/si.js b/sources/plugins/fakeobjects/lang/si.js
new file mode 100644 (file)
index 0000000..319240b
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'si', {\r
+       anchor: 'ආධාරය',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'සැඟවුණු ප්‍රදේශය',\r
+       iframe: 'IFrame',\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sk.js b/sources/plugins/fakeobjects/lang/sk.js
new file mode 100644 (file)
index 0000000..1372c54
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sk', {\r
+       anchor: 'Kotva',\r
+       flash: 'Flash animácia',\r
+       hiddenfield: 'Skryté pole',\r
+       iframe: 'IFrame',\r
+       unknown: 'Neznámy objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sl.js b/sources/plugins/fakeobjects/lang/sl.js
new file mode 100644 (file)
index 0000000..f6d9827
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sl', {\r
+       anchor: 'Sidro',\r
+       flash: 'Animacija flash',\r
+       hiddenfield: 'Skrito polje',\r
+       iframe: 'IFrame',\r
+       unknown: 'Neznan objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sq.js b/sources/plugins/fakeobjects/lang/sq.js
new file mode 100644 (file)
index 0000000..05f0987
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sq', {\r
+       anchor: 'Spirancë',\r
+       flash: 'Objekt flash',\r
+       hiddenfield: 'Fushë e fshehur',\r
+       iframe: 'IFrame',\r
+       unknown: 'Objekt i Panjohur'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sr-latn.js b/sources/plugins/fakeobjects/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..fb497f0
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sr-latn', {\r
+       anchor: 'Unesi/izmeni sidro',\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Skriveno polje',\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sr.js b/sources/plugins/fakeobjects/lang/sr.js
new file mode 100644 (file)
index 0000000..82a59cb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sr', {\r
+       anchor: 'Anchor', // MISSING\r
+       flash: 'Flash Animation', // MISSING\r
+       hiddenfield: 'Hidden Field', // MISSING\r
+       iframe: 'IFrame', // MISSING\r
+       unknown: 'Unknown Object' // MISSING\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/sv.js b/sources/plugins/fakeobjects/lang/sv.js
new file mode 100644 (file)
index 0000000..3db31fb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'sv', {\r
+       anchor: 'Ankare',\r
+       flash: 'Flashanimation',\r
+       hiddenfield: 'Gömt fält',\r
+       iframe: 'iFrame',\r
+       unknown: 'Okänt objekt'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/th.js b/sources/plugins/fakeobjects/lang/th.js
new file mode 100644 (file)
index 0000000..c0d1f4e
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'th', {\r
+       anchor: 'แทรก/แก้ไข Anchor',\r
+       flash: 'ภาพอนิเมชั่นแฟลช',\r
+       hiddenfield: 'ฮิดเดนฟิลด์',\r
+       iframe: 'IFrame',\r
+       unknown: 'วัตถุไม่ทราบชนิด'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/tr.js b/sources/plugins/fakeobjects/lang/tr.js
new file mode 100644 (file)
index 0000000..768b7c1
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'tr', {\r
+       anchor: 'Bağlantı',\r
+       flash: 'Flash Animasyonu',\r
+       hiddenfield: 'Gizli Alan',\r
+       iframe: 'IFrame',\r
+       unknown: 'Bilinmeyen Nesne'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/tt.js b/sources/plugins/fakeobjects/lang/tt.js
new file mode 100644 (file)
index 0000000..df1a714
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'tt', {\r
+       anchor: 'Якорь',\r
+       flash: 'Флеш анимациясы',\r
+       hiddenfield: 'Яшерен кыр',\r
+       iframe: 'IFrame',\r
+       unknown: 'Танылмаган объект'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/ug.js b/sources/plugins/fakeobjects/lang/ug.js
new file mode 100644 (file)
index 0000000..c44b8de
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'ug', {\r
+       anchor: 'لەڭگەرلىك نۇقتا',\r
+       flash: 'Flash جانلاندۇرۇم',\r
+       hiddenfield: 'يوشۇرۇن دائىرە',\r
+       iframe: 'IFrame',\r
+       unknown: 'يوچۇن نەڭ'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/uk.js b/sources/plugins/fakeobjects/lang/uk.js
new file mode 100644 (file)
index 0000000..81da8ca
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'uk', {\r
+       anchor: 'Якір',\r
+       flash: 'Flash-анімація',\r
+       hiddenfield: 'Приховані Поля',\r
+       iframe: 'IFrame',\r
+       unknown: 'Невідомий об\'єкт'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/vi.js b/sources/plugins/fakeobjects/lang/vi.js
new file mode 100644 (file)
index 0000000..f1346aa
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'vi', {\r
+       anchor: 'Điểm neo',\r
+       flash: 'Flash',\r
+       hiddenfield: 'Trường ẩn',\r
+       iframe: 'IFrame',\r
+       unknown: 'Đối tượng không rõ ràng'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/zh-cn.js b/sources/plugins/fakeobjects/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..8d304c2
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'zh-cn', {\r
+       anchor: '锚点',\r
+       flash: 'Flash 动画',\r
+       hiddenfield: '隐藏域',\r
+       iframe: 'IFrame',\r
+       unknown: '未知对象'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/lang/zh.js b/sources/plugins/fakeobjects/lang/zh.js
new file mode 100644 (file)
index 0000000..1255003
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'fakeobjects', 'zh', {\r
+       anchor: '錨點',\r
+       flash: 'Flash 動畫',\r
+       hiddenfield: '隱藏欄位',\r
+       iframe: 'IFrame',\r
+       unknown: '無法辨識的物件'\r
+} );\r
diff --git a/sources/plugins/fakeobjects/plugin.js b/sources/plugins/fakeobjects/plugin.js
new file mode 100644 (file)
index 0000000..d35698b
--- /dev/null
@@ -0,0 +1,183 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       var cssStyle = CKEDITOR.htmlParser.cssStyle,\r
+               cssLength = CKEDITOR.tools.cssLength;\r
+\r
+       var cssLengthRegex = /^((?:\d*(?:\.\d+))|(?:\d+))(.*)?$/i;\r
+\r
+       // Replacing the former CSS length value with the later one, with\r
+       // adjustment to the length  unit.\r
+       function replaceCssLength( length1, length2 ) {\r
+               var parts1 = cssLengthRegex.exec( length1 ),\r
+                       parts2 = cssLengthRegex.exec( length2 );\r
+\r
+               // Omit pixel length unit when necessary,\r
+               // e.g. replaceCssLength( 10, '20px' ) -> 20\r
+               if ( parts1 ) {\r
+                       if ( !parts1[ 2 ] && parts2[ 2 ] == 'px' )\r
+                               return parts2[ 1 ];\r
+                       if ( parts1[ 2 ] == 'px' && !parts2[ 2 ] )\r
+                               return parts2[ 1 ] + 'px';\r
+               }\r
+\r
+               return length2;\r
+       }\r
+\r
+       var htmlFilterRules = {\r
+               elements: {\r
+                       $: function( element ) {\r
+                               var attributes = element.attributes,\r
+                                       realHtml = attributes && attributes[ 'data-cke-realelement' ],\r
+                                       realFragment = realHtml && new CKEDITOR.htmlParser.fragment.fromHtml( decodeURIComponent( realHtml ) ),\r
+                                       realElement = realFragment && realFragment.children[ 0 ];\r
+\r
+                               // Width/height in the fake object are subjected to clone into the real element.\r
+                               if ( realElement && element.attributes[ 'data-cke-resizable' ] ) {\r
+                                       var styles = new cssStyle( element ).rules,\r
+                                               realAttrs = realElement.attributes,\r
+                                               width = styles.width,\r
+                                               height = styles.height;\r
+\r
+                                       width && ( realAttrs.width = replaceCssLength( realAttrs.width, width ) );\r
+                                       height && ( realAttrs.height = replaceCssLength( realAttrs.height, height ) );\r
+                               }\r
+\r
+                               return realElement;\r
+                       }\r
+               }\r
+       };\r
+\r
+       CKEDITOR.plugins.add( 'fakeobjects', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+\r
+               init: function( editor ) {\r
+                       // Allow image with all styles and classes plus src, alt and title attributes.\r
+                       // We need them when fakeobject is pasted.\r
+                       editor.filter.allow( 'img[!data-cke-realelement,src,alt,title](*){*}', 'fakeobjects' );\r
+               },\r
+\r
+               afterInit: function( editor ) {\r
+                       var dataProcessor = editor.dataProcessor,\r
+                               htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
+                       if ( htmlFilter ) {\r
+                               htmlFilter.addRules( htmlFilterRules, {\r
+                                       applyToAll: true\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * @member CKEDITOR.editor\r
+        * @todo\r
+        */\r
+       CKEDITOR.editor.prototype.createFakeElement = function( realElement, className, realElementType, isResizable ) {\r
+               var lang = this.lang.fakeobjects,\r
+                       label = lang[ realElementType ] || lang.unknown;\r
+\r
+               var attributes = {\r
+                       'class': className,\r
+                       'data-cke-realelement': encodeURIComponent( realElement.getOuterHtml() ),\r
+                       'data-cke-real-node-type': realElement.type,\r
+                       alt: label,\r
+                       title: label,\r
+                       align: realElement.getAttribute( 'align' ) || ''\r
+               };\r
+\r
+               // Do not set "src" on high-contrast so the alt text is displayed. (#8945)\r
+               if ( !CKEDITOR.env.hc )\r
+                       attributes.src = CKEDITOR.tools.transparentImageData;\r
+\r
+               if ( realElementType )\r
+                       attributes[ 'data-cke-real-element-type' ] = realElementType;\r
+\r
+               if ( isResizable ) {\r
+                       attributes[ 'data-cke-resizable' ] = isResizable;\r
+\r
+                       var fakeStyle = new cssStyle();\r
+\r
+                       var width = realElement.getAttribute( 'width' ),\r
+                               height = realElement.getAttribute( 'height' );\r
+\r
+                       width && ( fakeStyle.rules.width = cssLength( width ) );\r
+                       height && ( fakeStyle.rules.height = cssLength( height ) );\r
+                       fakeStyle.populate( attributes );\r
+               }\r
+\r
+               return this.document.createElement( 'img', { attributes: attributes } );\r
+       };\r
+\r
+       /**\r
+        * @member CKEDITOR.editor\r
+        * @todo\r
+        */\r
+       CKEDITOR.editor.prototype.createFakeParserElement = function( realElement, className, realElementType, isResizable ) {\r
+               var lang = this.lang.fakeobjects,\r
+                       label = lang[ realElementType ] || lang.unknown,\r
+                       html;\r
+\r
+               var writer = new CKEDITOR.htmlParser.basicWriter();\r
+               realElement.writeHtml( writer );\r
+               html = writer.getHtml();\r
+\r
+               var attributes = {\r
+                       'class': className,\r
+                       'data-cke-realelement': encodeURIComponent( html ),\r
+                       'data-cke-real-node-type': realElement.type,\r
+                       alt: label,\r
+                       title: label,\r
+                       align: realElement.attributes.align || ''\r
+               };\r
+\r
+               // Do not set "src" on high-contrast so the alt text is displayed. (#8945)\r
+               if ( !CKEDITOR.env.hc )\r
+                       attributes.src = CKEDITOR.tools.transparentImageData;\r
+\r
+               if ( realElementType )\r
+                       attributes[ 'data-cke-real-element-type' ] = realElementType;\r
+\r
+               if ( isResizable ) {\r
+                       attributes[ 'data-cke-resizable' ] = isResizable;\r
+                       var realAttrs = realElement.attributes,\r
+                               fakeStyle = new cssStyle();\r
+\r
+                       var width = realAttrs.width,\r
+                               height = realAttrs.height;\r
+\r
+                       width !== undefined && ( fakeStyle.rules.width = cssLength( width ) );\r
+                       height !== undefined && ( fakeStyle.rules.height = cssLength( height ) );\r
+                       fakeStyle.populate( attributes );\r
+               }\r
+\r
+               return new CKEDITOR.htmlParser.element( 'img', attributes );\r
+       };\r
+\r
+       /**\r
+        * @member CKEDITOR.editor\r
+        * @todo\r
+        */\r
+       CKEDITOR.editor.prototype.restoreRealElement = function( fakeElement ) {\r
+               if ( fakeElement.data( 'cke-real-node-type' ) != CKEDITOR.NODE_ELEMENT )\r
+                       return null;\r
+\r
+               var element = CKEDITOR.dom.element.createFromHtml( decodeURIComponent( fakeElement.data( 'cke-realelement' ) ), this.document );\r
+\r
+               if ( fakeElement.data( 'cke-resizable' ) ) {\r
+                       var width = fakeElement.getStyle( 'width' ),\r
+                               height = fakeElement.getStyle( 'height' );\r
+\r
+                       width && element.setAttribute( 'width', replaceCssLength( element.getAttribute( 'width' ), width ) );\r
+                       height && element.setAttribute( 'height', replaceCssLength( element.getAttribute( 'height' ), height ) );\r
+               }\r
+\r
+               return element;\r
+       };\r
+\r
+} )();\r
diff --git a/sources/plugins/filebrowser/plugin.js b/sources/plugins/filebrowser/plugin.js
new file mode 100644 (file)
index 0000000..a622a37
--- /dev/null
@@ -0,0 +1,573 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The "filebrowser" plugin that adds support for file uploads and\r
+ *               browsing.\r
+ *\r
+ * When a file is uploaded or selected inside the file browser, its URL is\r
+ * inserted automatically into a field defined in the <code>filebrowser</code>\r
+ * attribute. In order to specify a field that should be updated, pass the tab ID and\r
+ * the element ID, separated with a colon.<br /><br />\r
+ *\r
+ * <strong>Example 1: (Browse)</strong>\r
+ *\r
+ * <pre>\r
+ * {\r
+ *     type : 'button',\r
+ *     id : 'browse',\r
+ *     filebrowser : 'tabId:elementId',\r
+ *     label : editor.lang.common.browseServer\r
+ * }\r
+ * </pre>\r
+ *\r
+ * If you set the <code>filebrowser</code> attribute for an element other than\r
+ * the <code>fileButton</code>, the <code>Browse</code> action will be triggered.<br /><br />\r
+ *\r
+ * <strong>Example 2: (Quick Upload)</strong>\r
+ *\r
+ * <pre>\r
+ * {\r
+ *     type : 'fileButton',\r
+ *     id : 'uploadButton',\r
+ *     filebrowser : 'tabId:elementId',\r
+ *     label : editor.lang.common.uploadSubmit,\r
+ *     'for' : [ 'upload', 'upload' ]\r
+ * }\r
+ * </pre>\r
+ *\r
+ * If you set the <code>filebrowser</code> attribute for a <code>fileButton</code>\r
+ * element, the <code>QuickUpload</code> action will be executed.<br /><br />\r
+ *\r
+ * The filebrowser plugin also supports more advanced configuration performed through\r
+ * a JavaScript object.\r
+ *\r
+ * The following settings are supported:\r
+ *\r
+ * <ul>\r
+ * <li><code>action</code> &ndash; <code>Browse</code> or <code>QuickUpload</code>.</li>\r
+ * <li><code>target</code> &ndash; the field to update in the <code><em>tabId:elementId</em></code> format.</li>\r
+ * <li><code>params</code> &ndash; additional arguments to be passed to the server connector (optional).</li>\r
+ * <li><code>onSelect</code> &ndash; a function to execute when the file is selected/uploaded (optional).</li>\r
+ * <li><code>url</code> &ndash; the URL to be called (optional).</li>\r
+ * </ul>\r
+ *\r
+ * <strong>Example 3: (Quick Upload)</strong>\r
+ *\r
+ * <pre>\r
+ * {\r
+ *     type : 'fileButton',\r
+ *     label : editor.lang.common.uploadSubmit,\r
+ *     id : 'buttonId',\r
+ *     filebrowser :\r
+ *     {\r
+ *             action : 'QuickUpload', // required\r
+ *             target : 'tab1:elementId', // required\r
+ *             params : // optional\r
+ *             {\r
+ *                     type : 'Files',\r
+ *                     currentFolder : '/folder/'\r
+ *             },\r
+ *             onSelect : function( fileUrl, errorMessage ) // optional\r
+ *             {\r
+ *                     // Do not call the built-in selectFuntion.\r
+ *                     // return false;\r
+ *             }\r
+ *     },\r
+ *     'for' : [ 'tab1', 'myFile' ]\r
+ * }\r
+ * </pre>\r
+ *\r
+ * Suppose you have a file element with an ID of <code>myFile</code>, a text\r
+ * field with an ID of <code>elementId</code> and a <code>fileButton</code>.\r
+ * If the <code>filebowser.url</code> attribute is not specified explicitly,\r
+ * the form action will be set to <code>filebrowser[<em>DialogWindowName</em>]UploadUrl</code>\r
+ * or, if not specified, to <code>filebrowserUploadUrl</code>. Additional parameters\r
+ * from the <code>params</code> object will be added to the query string. It is\r
+ * possible to create your own <code>uploadHandler</code> and cancel the built-in\r
+ * <code>updateTargetElement</code> command.<br /><br />\r
+ *\r
+ * <strong>Example 4: (Browse)</strong>\r
+ *\r
+ * <pre>\r
+ * {\r
+ *     type : 'button',\r
+ *     id : 'buttonId',\r
+ *     label : editor.lang.common.browseServer,\r
+ *     filebrowser :\r
+ *     {\r
+ *             action : 'Browse',\r
+ *             url : '/ckfinder/ckfinder.html&amp;type=Images',\r
+ *             target : 'tab1:elementId'\r
+ *     }\r
+ * }\r
+ * </pre>\r
+ *\r
+ * In this example, when the button is pressed, the file browser will be opened in a\r
+ * popup window. If you do not specify the <code>filebrowser.url</code> attribute,\r
+ * <code>filebrowser[<em>DialogName</em>]BrowseUrl</code> or\r
+ * <code>filebrowserBrowseUrl</code> will be used. After selecting a file in the file\r
+ * browser, an element with an ID of <code>elementId</code> will be updated. Just\r
+ * like in the third example, a custom <code>onSelect</code> function may be defined.\r
+ */\r
+\r
+( function() {\r
+       // Default input element name for CSRF protection token.\r
+       var TOKEN_INPUT_NAME = 'ckCsrfToken';\r
+\r
+       // Adds (additional) arguments to given url.\r
+       //\r
+       // @param {String}\r
+       //            url The url.\r
+       // @param {Object}\r
+       //            params Additional parameters.\r
+       function addQueryString( url, params ) {\r
+               var queryString = [];\r
+\r
+               if ( !params )\r
+                       return url;\r
+               else {\r
+                       for ( var i in params )\r
+                               queryString.push( i + '=' + encodeURIComponent( params[ i ] ) );\r
+               }\r
+\r
+               return url + ( ( url.indexOf( '?' ) != -1 ) ? '&' : '?' ) + queryString.join( '&' );\r
+       }\r
+\r
+       // Make a string's first character uppercase.\r
+       //\r
+       // @param {String}\r
+       //            str String.\r
+       function ucFirst( str ) {\r
+               str += '';\r
+               var f = str.charAt( 0 ).toUpperCase();\r
+               return f + str.substr( 1 );\r
+       }\r
+\r
+       // The onlick function assigned to the 'Browse Server' button. Opens the\r
+       // file browser and updates target field when file is selected.\r
+       //\r
+       // @param {CKEDITOR.event}\r
+       //            evt The event object.\r
+       function browseServer() {\r
+               var dialog = this.getDialog();\r
+               var editor = dialog.getParentEditor();\r
+\r
+               editor._.filebrowserSe = this;\r
+\r
+               var width = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowWidth' ] || editor.config.filebrowserWindowWidth || '80%';\r
+               var height = editor.config[ 'filebrowser' + ucFirst( dialog.getName() ) + 'WindowHeight' ] || editor.config.filebrowserWindowHeight || '70%';\r
+\r
+               var params = this.filebrowser.params || {};\r
+               params.CKEditor = editor.name;\r
+               params.CKEditorFuncNum = editor._.filebrowserFn;\r
+               if ( !params.langCode )\r
+                       params.langCode = editor.langCode;\r
+\r
+               var url = addQueryString( this.filebrowser.url, params );\r
+               // TODO: V4: Remove backward compatibility (#8163).\r
+               editor.popup( url, width, height, editor.config.filebrowserWindowFeatures || editor.config.fileBrowserWindowFeatures );\r
+       }\r
+\r
+       // Appends token preventing CSRF attacks to the form of provided file input.\r
+       //\r
+       // @since 4.5.6\r
+       // @param {CKEDITOR.dom.element} fileInput\r
+       function appendToken( fileInput ) {\r
+               var tokenElement;\r
+               var form = new CKEDITOR.dom.element( fileInput.$.form );\r
+\r
+               if ( form ) {\r
+                       // Check if token input element already exists.\r
+                       tokenElement = form.$.elements[ TOKEN_INPUT_NAME ];\r
+\r
+                       // Create new if needed.\r
+                       if ( !tokenElement ) {\r
+                               tokenElement = new CKEDITOR.dom.element( 'input' );\r
+                               tokenElement.setAttributes( {\r
+                                       name: TOKEN_INPUT_NAME,\r
+                                       type: 'hidden'\r
+                               } );\r
+\r
+                               form.append( tokenElement );\r
+                       } else {\r
+                               tokenElement = new CKEDITOR.dom.element( tokenElement );\r
+                       }\r
+\r
+                       tokenElement.setAttribute( 'value', CKEDITOR.tools.getCsrfToken() );\r
+               }\r
+       }\r
+\r
+       // The onlick function assigned to the 'Upload' button. Makes the final\r
+       // decision whether form is really submitted and updates target field when\r
+       // file is uploaded.\r
+       //\r
+       // @param {CKEDITOR.event}\r
+       //            evt The event object.\r
+       function uploadFile() {\r
+               var dialog = this.getDialog();\r
+               var editor = dialog.getParentEditor();\r
+\r
+               editor._.filebrowserSe = this;\r
+\r
+               // If user didn't select the file, stop the upload.\r
+               if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getInputElement().$.value )\r
+                       return false;\r
+\r
+               if ( !dialog.getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getAction() )\r
+                       return false;\r
+\r
+               return true;\r
+       }\r
+\r
+       // Setups the file element.\r
+       //\r
+       // @param {CKEDITOR.ui.dialog.file}\r
+       //            fileInput The file element used during file upload.\r
+       // @param {Object}\r
+       //            filebrowser Object containing filebrowser settings assigned to\r
+       //            the fileButton associated with this file element.\r
+       function setupFileElement( editor, fileInput, filebrowser ) {\r
+               var params = filebrowser.params || {};\r
+               params.CKEditor = editor.name;\r
+               params.CKEditorFuncNum = editor._.filebrowserFn;\r
+               if ( !params.langCode )\r
+                       params.langCode = editor.langCode;\r
+\r
+               fileInput.action = addQueryString( filebrowser.url, params );\r
+               fileInput.filebrowser = filebrowser;\r
+       }\r
+\r
+       // Traverse through the content definition and attach filebrowser to\r
+       // elements with 'filebrowser' attribute.\r
+       //\r
+       // @param String\r
+       //            dialogName Dialog name.\r
+       // @param {CKEDITOR.dialog.definitionObject}\r
+       //            definition Dialog definition.\r
+       // @param {Array}\r
+       //            elements Array of {@link CKEDITOR.dialog.definition.content}\r
+       //            objects.\r
+       function attachFileBrowser( editor, dialogName, definition, elements ) {\r
+               if ( !elements || !elements.length )\r
+                       return;\r
+\r
+               var element;\r
+\r
+               for ( var i = elements.length; i--; ) {\r
+                       element = elements[ i ];\r
+\r
+                       if ( element.type == 'hbox' || element.type == 'vbox' || element.type == 'fieldset' )\r
+                               attachFileBrowser( editor, dialogName, definition, element.children );\r
+\r
+                       if ( !element.filebrowser )\r
+                               continue;\r
+\r
+                       if ( typeof element.filebrowser == 'string' ) {\r
+                               var fb = {\r
+                                       action: ( element.type == 'fileButton' ) ? 'QuickUpload' : 'Browse',\r
+                                       target: element.filebrowser\r
+                               };\r
+                               element.filebrowser = fb;\r
+                       }\r
+\r
+                       if ( element.filebrowser.action == 'Browse' ) {\r
+                               var url = element.filebrowser.url;\r
+                               if ( url === undefined ) {\r
+                                       url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'BrowseUrl' ];\r
+                                       if ( url === undefined )\r
+                                               url = editor.config.filebrowserBrowseUrl;\r
+                               }\r
+\r
+                               if ( url ) {\r
+                                       element.onClick = browseServer;\r
+                                       element.filebrowser.url = url;\r
+                                       element.hidden = false;\r
+                               }\r
+                       } else if ( element.filebrowser.action == 'QuickUpload' && element[ 'for' ] ) {\r
+                               url = element.filebrowser.url;\r
+                               if ( url === undefined ) {\r
+                                       url = editor.config[ 'filebrowser' + ucFirst( dialogName ) + 'UploadUrl' ];\r
+                                       if ( url === undefined )\r
+                                               url = editor.config.filebrowserUploadUrl;\r
+                               }\r
+\r
+                               if ( url ) {\r
+                                       var onClick = element.onClick;\r
+                                       element.onClick = function( evt ) {\r
+                                               // "element" here means the definition object, so we need to find the correct\r
+                                               // button to scope the event call\r
+                                               var sender = evt.sender;\r
+                                               if ( onClick && onClick.call( sender, evt ) === false )\r
+                                                       return false;\r
+\r
+                                               if ( uploadFile.call( sender, evt ) ) {\r
+                                                       var fileInput = sender.getDialog().getContentElement( this[ 'for' ][ 0 ], this[ 'for' ][ 1 ] ).getInputElement();\r
+\r
+                                                       // Append token preventing CSRF attacks.\r
+                                                       appendToken( fileInput );\r
+                                                       return true;\r
+                                               }\r
+\r
+\r
+                                               return false;\r
+                                       };\r
+\r
+                                       element.filebrowser.url = url;\r
+                                       element.hidden = false;\r
+                                       setupFileElement( editor, definition.getContents( element[ 'for' ][ 0 ] ).get( element[ 'for' ][ 1 ] ), element.filebrowser );\r
+                               }\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Updates the target element with the url of uploaded/selected file.\r
+       //\r
+       // @param {String}\r
+       //            url The url of a file.\r
+       function updateTargetElement( url, sourceElement ) {\r
+               var dialog = sourceElement.getDialog();\r
+               var targetElement = sourceElement.filebrowser.target || null;\r
+\r
+               // If there is a reference to targetElement, update it.\r
+               if ( targetElement ) {\r
+                       var target = targetElement.split( ':' );\r
+                       var element = dialog.getContentElement( target[ 0 ], target[ 1 ] );\r
+                       if ( element ) {\r
+                               element.setValue( url );\r
+                               dialog.selectPage( target[ 0 ] );\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Returns true if filebrowser is configured in one of the elements.\r
+       //\r
+       // @param {CKEDITOR.dialog.definitionObject}\r
+       //            definition Dialog definition.\r
+       // @param String\r
+       //            tabId The tab id where element(s) can be found.\r
+       // @param String\r
+       //            elementId The element id (or ids, separated with a semicolon) to check.\r
+       function isConfigured( definition, tabId, elementId ) {\r
+               if ( elementId.indexOf( ';' ) !== -1 ) {\r
+                       var ids = elementId.split( ';' );\r
+                       for ( var i = 0; i < ids.length; i++ ) {\r
+                               if ( isConfigured( definition, tabId, ids[ i ] ) )\r
+                                       return true;\r
+                       }\r
+                       return false;\r
+               }\r
+\r
+               var elementFileBrowser = definition.getContents( tabId ).get( elementId ).filebrowser;\r
+               return ( elementFileBrowser && elementFileBrowser.url );\r
+       }\r
+\r
+       function setUrl( fileUrl, data ) {\r
+               var dialog = this._.filebrowserSe.getDialog(),\r
+                       targetInput = this._.filebrowserSe[ 'for' ],\r
+                       onSelect = this._.filebrowserSe.filebrowser.onSelect;\r
+\r
+               if ( targetInput )\r
+                       dialog.getContentElement( targetInput[ 0 ], targetInput[ 1 ] ).reset();\r
+\r
+               if ( typeof data == 'function' && data.call( this._.filebrowserSe ) === false )\r
+                       return;\r
+\r
+               if ( onSelect && onSelect.call( this._.filebrowserSe, fileUrl, data ) === false )\r
+                       return;\r
+\r
+               // The "data" argument may be used to pass the error message to the editor.\r
+               if ( typeof data == 'string' && data )\r
+                       alert( data ); // jshint ignore:line\r
+\r
+               if ( fileUrl )\r
+                       updateTargetElement( fileUrl, this._.filebrowserSe );\r
+       }\r
+\r
+       CKEDITOR.plugins.add( 'filebrowser', {\r
+               requires: 'popup',\r
+               init: function( editor ) {\r
+                       editor._.filebrowserFn = CKEDITOR.tools.addFunction( setUrl, editor );\r
+                       editor.on( 'destroy', function() {\r
+                               CKEDITOR.tools.removeFunction( this._.filebrowserFn );\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       CKEDITOR.on( 'dialogDefinition', function( evt ) {\r
+               // We require filebrowser plugin to be loaded.\r
+               if ( !evt.editor.plugins.filebrowser )\r
+                       return;\r
+\r
+               var definition = evt.data.definition,\r
+                       element;\r
+               // Associate filebrowser to elements with 'filebrowser' attribute.\r
+               for ( var i = 0; i < definition.contents.length; ++i ) {\r
+                       if ( ( element = definition.contents[ i ] ) ) {\r
+                               attachFileBrowser( evt.editor, evt.data.name, definition, element.elements );\r
+                               if ( element.hidden && element.filebrowser )\r
+                                       element.hidden = !isConfigured( definition, element.id, element.filebrowser );\r
+\r
+                       }\r
+               }\r
+       } );\r
+\r
+} )();\r
+\r
+/**\r
+ * The location of an external file manager that should be launched when the **Browse Server**\r
+ * button is pressed. If configured, the **Browse Server** button will appear in the\r
+ * **Link**, **Image**, and **Flash** dialog windows.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_browse_upload)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserBrowseUrl = '/browser/browse.php';\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} [filebrowserBrowseUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of the script that handles file uploads.\r
+ * If set, the **Upload** tab will appear in the **Link**, **Image**,\r
+ * and **Flash** dialog windows.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_browse_upload)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserUploadUrl = '/uploader/upload.php';\r
+ *\r
+ * **Note:** This is a configuration setting for a [file browser/uploader](#!/guide/dev_file_browse_upload).\r
+ * To configure [uploading dropped or pasted files](#!/guide/dev_file_upload) use the {@link CKEDITOR.config#uploadUrl}\r
+ * configuration option.\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} [filebrowserUploadUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of an external file manager that should be launched when the **Browse Server**\r
+ * button is pressed in the **Image** dialog window.\r
+ *\r
+ * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-adding-file-manager-scripts-for-selected-dialog-windows)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserImageBrowseUrl = '/browser/browse.php?type=Images';\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} [filebrowserImageBrowseUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of an external file browser that should be launched when the **Browse Server**\r
+ * button is pressed in the **Flash** dialog window.\r
+ *\r
+ * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-adding-file-manager-scripts-for-selected-dialog-windows)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserFlashBrowseUrl = '/browser/browse.php?type=Flash';\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} [filebrowserFlashBrowseUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of the script that handles file uploads in the **Image** dialog window.\r
+ *\r
+ * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserUploadUrl}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-adding-file-manager-scripts-for-selected-dialog-windows)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserImageUploadUrl = '/uploader/upload.php?type=Images';\r
+ *\r
+ * **Note:** This is a configuration setting for a [file browser/uploader](#!/guide/dev_file_browse_upload).\r
+ * To configure [uploading dropped or pasted files](#!/guide/dev_file_upload) use the {@link CKEDITOR.config#uploadUrl}\r
+ * or {@link CKEDITOR.config#imageUploadUrl} configuration option.\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} [filebrowserImageUploadUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of the script that handles file uploads in the **Flash** dialog window.\r
+ *\r
+ * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserUploadUrl}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-adding-file-manager-scripts-for-selected-dialog-windows)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserFlashUploadUrl = '/uploader/upload.php?type=Flash';\r
+ *\r
+ * @since 3.0\r
+ * @cfg {String} filebrowserFlashUploadUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The location of an external file manager that should be launched when the **Browse Server**\r
+ * button is pressed in the **Link** tab of the **Image** dialog window.\r
+ *\r
+ * If not set, CKEditor will use {@link CKEDITOR.config#filebrowserBrowseUrl}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-adding-file-manager-scripts-for-selected-dialog-windows)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserImageBrowseLinkUrl = '/browser/browse.php';\r
+ *\r
+ * @since 3.2\r
+ * @cfg {String} [filebrowserImageBrowseLinkUrl='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The features to use in the file manager popup window.\r
+ *\r
+ *             config.filebrowserWindowFeatures = 'resizable=yes,scrollbars=no';\r
+ *\r
+ * @since 3.4.1\r
+ * @cfg {String} [filebrowserWindowFeatures='location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The width of the file manager popup window. It can be a number denoting a value in\r
+ * pixels or a percent string.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-file-manager-window-size)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserWindowWidth = 750;\r
+ *\r
+ *             config.filebrowserWindowWidth = '50%';\r
+ *\r
+ * @cfg {Number/String} [filebrowserWindowWidth='80%']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The height of the file manager popup window. It can be a number denoting a value in\r
+ * pixels or a percent string.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_file_manager_configuration-section-file-manager-window-size)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/fileupload.html).\r
+ *\r
+ *             config.filebrowserWindowHeight = 580;\r
+ *\r
+ *             config.filebrowserWindowHeight = '50%';\r
+ *\r
+ * @cfg {Number/String} [filebrowserWindowHeight='70%']\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/floatingspace/plugin.js b/sources/plugins/floatingspace/plugin.js
new file mode 100644 (file)
index 0000000..878d952
--- /dev/null
@@ -0,0 +1,406 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       var win = CKEDITOR.document.getWindow(),\r
+               pixelate = CKEDITOR.tools.cssLength;\r
+\r
+       CKEDITOR.plugins.add( 'floatingspace', {\r
+               init: function( editor ) {\r
+                       // Add listener with lower priority than that in themedui creator.\r
+                       // Thereby floatingspace will be created only if themedui wasn't used.\r
+                       editor.on( 'loaded', function() {\r
+                               attach( this );\r
+                       }, null, null, 20 );\r
+               }\r
+       } );\r
+\r
+       function scrollOffset( side ) {\r
+               var pageOffset = side == 'left' ? 'pageXOffset' : 'pageYOffset',\r
+                       docScrollOffset = side == 'left' ? 'scrollLeft' : 'scrollTop';\r
+\r
+               return ( pageOffset in win.$ ) ? win.$[ pageOffset ] : CKEDITOR.document.$.documentElement[ docScrollOffset ];\r
+       }\r
+\r
+       function attach( editor ) {\r
+               var config = editor.config,\r
+\r
+                       // Get the HTML for the predefined spaces.\r
+                       topHtml = editor.fire( 'uiSpace', { space: 'top', html: '' } ).html,\r
+\r
+                       // Re-positioning of the space.\r
+                       layout = ( function() {\r
+                               // Mode indicates the vertical aligning mode.\r
+                               var mode, editable,\r
+                                       spaceRect, editorRect, viewRect, spaceHeight, pageScrollX,\r
+\r
+                                       // Allow minor adjustments of the float space from custom configs.\r
+                                       dockedOffsetX = config.floatSpaceDockedOffsetX || 0,\r
+                                       dockedOffsetY = config.floatSpaceDockedOffsetY || 0,\r
+                                       pinnedOffsetX = config.floatSpacePinnedOffsetX || 0,\r
+                                       pinnedOffsetY = config.floatSpacePinnedOffsetY || 0;\r
+\r
+                               // Update the float space position.\r
+                               function updatePos( pos, prop, val ) {\r
+                                       floatSpace.setStyle( prop, pixelate( val ) );\r
+                                       floatSpace.setStyle( 'position', pos );\r
+                               }\r
+\r
+                               // Change the current mode and update float space position accordingly.\r
+                               function changeMode( newMode ) {\r
+                                       var editorPos = editable.getDocumentPosition();\r
+\r
+                                       switch ( newMode ) {\r
+                                               case 'top':\r
+                                                       updatePos( 'absolute', 'top', editorPos.y - spaceHeight - dockedOffsetY );\r
+                                                       break;\r
+                                               case 'pin':\r
+                                                       updatePos( 'fixed', 'top', pinnedOffsetY );\r
+                                                       break;\r
+                                               case 'bottom':\r
+                                                       updatePos( 'absolute', 'top', editorPos.y + ( editorRect.height || editorRect.bottom - editorRect.top ) + dockedOffsetY );\r
+                                                       break;\r
+                                       }\r
+\r
+                                       mode = newMode;\r
+                               }\r
+\r
+                               return function( evt ) {\r
+                                       // #10112 Do not fail on editable-less editor.\r
+                                       if ( !( editable = editor.editable() ) )\r
+                                               return;\r
+\r
+                                       var show = ( evt && evt.name == 'focus' );\r
+\r
+                                       // Show up the space on focus gain.\r
+                                       if ( show ) {\r
+                                               floatSpace.show();\r
+                                       }\r
+\r
+                                       editor.fire( 'floatingSpaceLayout', { show: show } );\r
+\r
+                                       // Reset the horizontal position for below measurement.\r
+                                       floatSpace.removeStyle( 'left' );\r
+                                       floatSpace.removeStyle( 'right' );\r
+\r
+                                       // Compute the screen position from the TextRectangle object would\r
+                                       // be very simple, even though the "width"/"height" property is not\r
+                                       // available for all, it's safe to figure that out from the rest.\r
+\r
+                                       // http://help.dottoro.com/ljgupwlp.php\r
+                                       spaceRect = floatSpace.getClientRect();\r
+                                       editorRect = editable.getClientRect();\r
+                                       viewRect = win.getViewPaneSize();\r
+                                       spaceHeight = spaceRect.height;\r
+                                       pageScrollX = scrollOffset( 'left' );\r
+\r
+                                       // We initialize it as pin mode.\r
+                                       if ( !mode ) {\r
+                                               mode = 'pin';\r
+                                               changeMode( 'pin' );\r
+                                               // Call for a refresh to the actual layout.\r
+                                               layout( evt );\r
+                                               return;\r
+                                       }\r
+\r
+                                       // +------------------------ Viewport -+ \\r
+                                       // |                                   |  |-> floatSpaceDockedOffsetY\r
+                                       // | ................................. | /\r
+                                       // |                                   |\r
+                                       // |   +------ Space -+                |\r
+                                       // |   |              |                |\r
+                                       // |   +--------------+                |\r
+                                       // |   +------------------ Editor -+   |\r
+                                       // |   |                           |   |\r
+                                       //\r
+                                       if ( spaceHeight + dockedOffsetY <= editorRect.top )\r
+                                               changeMode( 'top' );\r
+\r
+                                       //     +- - - - - - - - -  Editor -+\r
+                                       //     |                           |\r
+                                       // +------------------------ Viewport -+ \\r
+                                       // |   |                           |   |  |-> floatSpacePinnedOffsetY\r
+                                       // | ................................. | /\r
+                                       // |   +------ Space -+            |   |\r
+                                       // |   |              |            |   |\r
+                                       // |   +--------------+            |   |\r
+                                       // |   |                           |   |\r
+                                       // |   +---------------------------+   |\r
+                                       // +-----------------------------------+\r
+                                       //\r
+                                       else if ( spaceHeight + dockedOffsetY > viewRect.height - editorRect.bottom )\r
+                                               changeMode( 'pin' );\r
+\r
+                                       //     +- - - - - - - - -  Editor -+\r
+                                       //     |                           |\r
+                                       // +------------------------ Viewport -+ \\r
+                                       // |   |                           |   |  |-> floatSpacePinnedOffsetY\r
+                                       // | ................................. | /\r
+                                       // |   |                           |   |\r
+                                       // |   |                           |   |\r
+                                       // |   +---------------------------+   |\r
+                                       // |   +------ Space -+                |\r
+                                       // |   |              |                |\r
+                                       // |   +--------------+                |\r
+                                       //\r
+                                       else\r
+                                               changeMode( 'bottom' );\r
+\r
+                                       var mid = viewRect.width / 2,\r
+                                               alignSide, offset;\r
+\r
+                                       if ( config.floatSpacePreferRight ) {\r
+                                               alignSide = 'right';\r
+                                       } else if ( editorRect.left > 0 && editorRect.right < viewRect.width && editorRect.width > spaceRect.width ) {\r
+                                               alignSide = config.contentsLangDirection == 'rtl' ? 'right' : 'left';\r
+                                       } else {\r
+                                               alignSide = mid - editorRect.left > editorRect.right - mid ? 'left' : 'right';\r
+                                       }\r
+\r
+                                       // (#9769) If viewport width is less than space width,\r
+                                       // make sure space never cross the left boundary of the viewport.\r
+                                       // In other words: top-left corner of the space is always visible.\r
+                                       if ( spaceRect.width > viewRect.width ) {\r
+                                               alignSide = 'left';\r
+                                               offset = 0;\r
+                                       }\r
+                                       else {\r
+                                               if ( alignSide == 'left' ) {\r
+                                                       // If the space rect fits into viewport, align it\r
+                                                       // to the left edge of editor:\r
+                                                       //\r
+                                                       // +------------------------ Viewport -+\r
+                                                       // |                                   |\r
+                                                       // |   +------------- Space -+         |\r
+                                                       // |   |                     |         |\r
+                                                       // |   +---------------------+         |\r
+                                                       // |   +------------------ Editor -+   |\r
+                                                       // |   |                           |   |\r
+                                                       //\r
+                                                       if ( editorRect.left > 0 )\r
+                                                               offset = editorRect.left;\r
+\r
+                                                       // If the left part of the editor is cut off by the left\r
+                                                       // edge of the viewport, stick the space to the viewport:\r
+                                                       //\r
+                                                       //       +------------------------ Viewport -+\r
+                                                       //       |                                   |\r
+                                                       //       +---------------- Space -+          |\r
+                                                       //       |                        |          |\r
+                                                       //       +------------------------+          |\r
+                                                       //  +----|------------- Editor -+            |\r
+                                                       //  |    |                      |            |\r
+                                                       //\r
+                                                       else\r
+                                                               offset = 0;\r
+                                               }\r
+                                               else {\r
+                                                       // If the space rect fits into viewport, align it\r
+                                                       // to the right edge of editor:\r
+                                                       //\r
+                                                       // +------------------------ Viewport -+\r
+                                                       // |                                   |\r
+                                                       // |         +------------- Space -+   |\r
+                                                       // |         |                     |   |\r
+                                                       // |         +---------------------+   |\r
+                                                       // |   +------------------ Editor -+   |\r
+                                                       // |   |                           |   |\r
+                                                       //\r
+                                                       if ( editorRect.right < viewRect.width )\r
+                                                               offset = viewRect.width - editorRect.right;\r
+\r
+                                                       // If the right part of the editor is cut off by the right\r
+                                                       // edge of the viewport, stick the space to the viewport:\r
+                                                       //\r
+                                                       // +------------------------ Viewport -+\r
+                                                       // |                                   |\r
+                                                       // |             +------------- Space -+\r
+                                                       // |             |                     |\r
+                                                       // |             +---------------------+\r
+                                                       // |                 +-----------------|- Editor -+\r
+                                                       // |                 |                 |          |\r
+                                                       //\r
+                                                       else\r
+                                                               offset = 0;\r
+                                               }\r
+\r
+                                               // (#9769) Finally, stick the space to the opposite side of\r
+                                               // the viewport when it's cut off horizontally on the left/right\r
+                                               // side like below.\r
+                                               //\r
+                                               // This trick reveals cut off space in some edge cases and\r
+                                               // hence it improves accessibility.\r
+                                               //\r
+                                               // +------------------------ Viewport -+\r
+                                               // |                                   |\r
+                                               // |              +--------------------|-- Space -+\r
+                                               // |              |                    |          |\r
+                                               // |              +--------------------|----------+\r
+                                               // |              +------- Editor -+   |\r
+                                               // |              |                |   |\r
+                                               //\r
+                                               //                              becomes:\r
+                                               //\r
+                                               // +------------------------ Viewport -+\r
+                                               // |                                   |\r
+                                               // |   +----------------------- Space -+\r
+                                               // |   |                               |\r
+                                               // |   +-------------------------------+\r
+                                               // |              +------- Editor -+   |\r
+                                               // |              |                |   |\r
+                                               //\r
+                                               if ( offset + spaceRect.width > viewRect.width ) {\r
+                                                       alignSide = alignSide == 'left' ? 'right' : 'left';\r
+                                                       offset = 0;\r
+                                               }\r
+                                       }\r
+\r
+                                       // Pin mode is fixed, so don't include scroll-x.\r
+                                       // (#9903) For mode is "top" or "bottom", add opposite scroll-x for right-aligned space.\r
+                                       var scroll = mode == 'pin' ? 0 : alignSide == 'left' ? pageScrollX : -pageScrollX;\r
+\r
+                                       floatSpace.setStyle( alignSide, pixelate( ( mode == 'pin' ? pinnedOffsetX : dockedOffsetX ) + offset + scroll ) );\r
+                               };\r
+                       } )();\r
+\r
+               if ( topHtml ) {\r
+                       var floatSpaceTpl = new CKEDITOR.template(\r
+                               '<div' +\r
+                                       ' id="cke_{name}"' +\r
+                                       ' class="cke {id} cke_reset_all cke_chrome cke_editor_{name} cke_float cke_{langDir} ' + CKEDITOR.env.cssClass + '"' +\r
+                                       ' dir="{langDir}"' +\r
+                                       ' title="' + ( CKEDITOR.env.gecko ? ' ' : '' ) + '"' +\r
+                                       ' lang="{langCode}"' +\r
+                                       ' role="application"' +\r
+                                       ' style="{style}"' +\r
+                                       ( editor.title ? ' aria-labelledby="cke_{name}_arialbl"' : ' ' ) +\r
+                                       '>' +\r
+                                       ( editor.title ? '<span id="cke_{name}_arialbl" class="cke_voice_label">{voiceLabel}</span>' : ' ' ) +\r
+                                       '<div class="cke_inner">' +\r
+                                               '<div id="{topId}" class="cke_top" role="presentation">{content}</div>' +\r
+                                       '</div>' +\r
+                               '</div>' ),\r
+                               floatSpace = CKEDITOR.document.getBody().append( CKEDITOR.dom.element.createFromHtml( floatSpaceTpl.output( {\r
+                                       content: topHtml,\r
+                                       id: editor.id,\r
+                                       langDir: editor.lang.dir,\r
+                                       langCode: editor.langCode,\r
+                                       name: editor.name,\r
+                                       style: 'display:none;z-index:' + ( config.baseFloatZIndex - 1 ),\r
+                                       topId: editor.ui.spaceId( 'top' ),\r
+                                       voiceLabel: editor.title\r
+                               } ) ) ),\r
+\r
+                               // Use event buffers to reduce CPU load when tons of events are fired.\r
+                               changeBuffer = CKEDITOR.tools.eventsBuffer( 500, layout ),\r
+                               uiBuffer = CKEDITOR.tools.eventsBuffer( 100, layout );\r
+\r
+                       // There's no need for the floatSpace to be selectable.\r
+                       floatSpace.unselectable();\r
+\r
+                       // Prevent clicking on non-buttons area of the space from blurring editor.\r
+                       floatSpace.on( 'mousedown', function( evt ) {\r
+                               evt = evt.data;\r
+                               if ( !evt.getTarget().hasAscendant( 'a', 1 ) )\r
+                                       evt.preventDefault();\r
+                       } );\r
+\r
+                       editor.on( 'focus', function( evt ) {\r
+                               layout( evt );\r
+                               editor.on( 'change', changeBuffer.input );\r
+                               win.on( 'scroll', uiBuffer.input );\r
+                               win.on( 'resize', uiBuffer.input );\r
+                       } );\r
+\r
+                       editor.on( 'blur', function() {\r
+                               floatSpace.hide();\r
+                               editor.removeListener( 'change', changeBuffer.input );\r
+                               win.removeListener( 'scroll', uiBuffer.input );\r
+                               win.removeListener( 'resize', uiBuffer.input );\r
+                       } );\r
+\r
+                       editor.on( 'destroy', function() {\r
+                               win.removeListener( 'scroll', uiBuffer.input );\r
+                               win.removeListener( 'resize', uiBuffer.input );\r
+                               floatSpace.clearCustomData();\r
+                               floatSpace.remove();\r
+                       } );\r
+\r
+                       // Handle initial focus.\r
+                       if ( editor.focusManager.hasFocus )\r
+                               floatSpace.show();\r
+\r
+                       // Register this UI space to the focus manager.\r
+                       editor.focusManager.add( floatSpace, 1 );\r
+               }\r
+       }\r
+} )();\r
+\r
+/**\r
+ * Along with {@link #floatSpaceDockedOffsetY} it defines the\r
+ * amount of offset (in pixels) between the float space and the editable left/right\r
+ * boundaries when the space element is docked on either side of the editable.\r
+ *\r
+ *             config.floatSpaceDockedOffsetX = 10;\r
+ *\r
+ * @cfg {Number} [floatSpaceDockedOffsetX=0]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Along with {@link #floatSpaceDockedOffsetX} it defines the\r
+ * amount of offset (in pixels) between the float space and the editable top/bottom\r
+ * boundaries when the space element is docked on either side of the editable.\r
+ *\r
+ *             config.floatSpaceDockedOffsetY = 10;\r
+ *\r
+ * @cfg {Number} [floatSpaceDockedOffsetY=0]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Along with {@link #floatSpacePinnedOffsetY} it defines the\r
+ * amount of offset (in pixels) between the float space and the viewport boundaries\r
+ * when the space element is pinned.\r
+ *\r
+ *             config.floatSpacePinnedOffsetX = 20;\r
+ *\r
+ * @cfg {Number} [floatSpacePinnedOffsetX=0]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Along with {@link #floatSpacePinnedOffsetX} it defines the\r
+ * amount of offset (in pixels) between the float space and the viewport boundaries\r
+ * when the space element is pinned.\r
+ *\r
+ *             config.floatSpacePinnedOffsetY = 20;\r
+ *\r
+ * @cfg {Number} [floatSpacePinnedOffsetY=0]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Indicates that the float space should be aligned to the right side\r
+ * of the editable area rather than to the left (if possible).\r
+ *\r
+ *             config.floatSpacePreferRight = true;\r
+ *\r
+ * @since 4.5\r
+ * @cfg {Boolean} [floatSpacePreferRight=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Fired when the viewport or editor parameters change and the floating space needs to check and\r
+ * eventually update its position and dimensions.\r
+ *\r
+ * @since 4.5\r
+ * @event floatingSpaceLayout\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor The editor instance.\r
+ * @param data\r
+ * @param {Boolean} data.show True if the float space should show up as a result of this event.\r
+ */\r
diff --git a/sources/plugins/floatpanel/plugin.js b/sources/plugins/floatpanel/plugin.js
new file mode 100644 (file)
index 0000000..1a851f9
--- /dev/null
@@ -0,0 +1,598 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'floatpanel', {\r
+       requires: 'panel'\r
+} );\r
+\r
+( function() {\r
+       var panels = {};\r
+\r
+       function getPanel( editor, doc, parentElement, definition, level ) {\r
+               // Generates the panel key: docId-eleId-skinName-langDir[-uiColor][-CSSs][-level]\r
+               var key = CKEDITOR.tools.genKey( doc.getUniqueId(), parentElement.getUniqueId(), editor.lang.dir, editor.uiColor || '', definition.css || '', level || '' ),\r
+                       panel = panels[ key ];\r
+\r
+               if ( !panel ) {\r
+                       panel = panels[ key ] = new CKEDITOR.ui.panel( doc, definition );\r
+                       panel.element = parentElement.append( CKEDITOR.dom.element.createFromHtml( panel.render( editor ), doc ) );\r
+\r
+                       panel.element.setStyles( {\r
+                               display: 'none',\r
+                               position: 'absolute'\r
+                       } );\r
+               }\r
+\r
+               return panel;\r
+       }\r
+\r
+       /**\r
+        * Represents a floating panel UI element.\r
+        *\r
+        * It is reused by rich combos, color combos, menus, etc.\r
+        * and it renders its content using {@link CKEDITOR.ui.panel}.\r
+        *\r
+        * @class\r
+        * @todo\r
+        */\r
+       CKEDITOR.ui.floatPanel = CKEDITOR.tools.createClass( {\r
+               /**\r
+                * Creates a floatPanel class instance.\r
+                *\r
+                * @constructor\r
+                * @param {CKEDITOR.editor} editor\r
+                * @param {CKEDITOR.dom.element} parentElement\r
+                * @param {Object} definition Definition of the panel that will be floating.\r
+                * @param {Number} level\r
+                */\r
+               $: function( editor, parentElement, definition, level ) {\r
+                       definition.forceIFrame = 1;\r
+\r
+                       // In case of editor with floating toolbar append panels that should float\r
+                       // to the main UI element.\r
+                       if ( definition.toolbarRelated && editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )\r
+                               parentElement = CKEDITOR.document.getById( 'cke_' + editor.name );\r
+\r
+                       var doc = parentElement.getDocument(),\r
+                               panel = getPanel( editor, doc, parentElement, definition, level || 0 ),\r
+                               element = panel.element,\r
+                               iframe = element.getFirst(),\r
+                               that = this;\r
+\r
+                       // Disable native browser menu. (#4825)\r
+                       element.disableContextMenu();\r
+\r
+                       this.element = element;\r
+\r
+                       this._ = {\r
+                               editor: editor,\r
+                               // The panel that will be floating.\r
+                               panel: panel,\r
+                               parentElement: parentElement,\r
+                               definition: definition,\r
+                               document: doc,\r
+                               iframe: iframe,\r
+                               children: [],\r
+                               dir: editor.lang.dir,\r
+                               showBlockParams: null\r
+                       };\r
+\r
+                       editor.on( 'mode', hide );\r
+                       editor.on( 'resize', hide );\r
+\r
+                       // When resize of the window is triggered floatpanel should be repositioned according to new dimensions.\r
+                       // #11724. Fixes issue with undesired panel hiding on Android and iOS.\r
+                       doc.getWindow().on( 'resize', function() {\r
+                               this.reposition();\r
+                       }, this );\r
+\r
+                       // We need a wrapper because events implementation doesn't allow to attach\r
+                       // one listener more than once for the same event on the same object.\r
+                       // Remember that floatPanel#hide is shared between all instances.\r
+                       function hide() {\r
+                               that.hide();\r
+                       }\r
+               },\r
+\r
+               proto: {\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       addBlock: function( name, block ) {\r
+                               return this._.panel.addBlock( name, block );\r
+                       },\r
+\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       addListBlock: function( name, multiSelect ) {\r
+                               return this._.panel.addListBlock( name, multiSelect );\r
+                       },\r
+\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       getBlock: function( name ) {\r
+                               return this._.panel.getBlock( name );\r
+                       },\r
+\r
+                       /**\r
+                        * Shows the panel block.\r
+                        *\r
+                        * @param {String} name\r
+                        * @param {CKEDITOR.dom.element} offsetParent Positioned parent.\r
+                        * @param {Number} corner\r
+                        *\r
+                        * * For LTR (left to right) oriented editor:\r
+                        *      * `1` = top-left\r
+                        *      * `2` = top-right\r
+                        *      * `3` = bottom-right\r
+                        *      * `4` = bottom-left\r
+                        * * For RTL (right to left):\r
+                        *      * `1` = top-right\r
+                        *      * `2` = top-left\r
+                        *      * `3` = bottom-left\r
+                        *      * `4` = bottom-right\r
+                        *\r
+                        * @param {Number} [offsetX=0]\r
+                        * @param {Number} [offsetY=0]\r
+                        * @param {Function} [callback] A callback function executed when block positioning is done.\r
+                        * @todo what do exactly these params mean (especially corner)?\r
+                        */\r
+                       showBlock: function( name, offsetParent, corner, offsetX, offsetY, callback ) {\r
+                               var panel = this._.panel,\r
+                                       block = panel.showBlock( name );\r
+\r
+                               this._.showBlockParams = [].slice.call( arguments );\r
+                               this.allowBlur( false );\r
+\r
+                               // Record from where the focus is when open panel.\r
+                               var editable = this._.editor.editable();\r
+                               this._.returnFocus = editable.hasFocus ? editable : new CKEDITOR.dom.element( CKEDITOR.document.$.activeElement );\r
+                               this._.hideTimeout = 0;\r
+\r
+                               var element = this.element,\r
+                                       iframe = this._.iframe,\r
+                                       // Edge prefers iframe's window to the iframe, just like the rest of the browsers (#13143).\r
+                                       focused = CKEDITOR.env.ie && !CKEDITOR.env.edge ? iframe : new CKEDITOR.dom.window( iframe.$.contentWindow ),\r
+                                       doc = element.getDocument(),\r
+                                       positionedAncestor = this._.parentElement.getPositionedAncestor(),\r
+                                       position = offsetParent.getDocumentPosition( doc ),\r
+                                       positionedAncestorPosition = positionedAncestor ? positionedAncestor.getDocumentPosition( doc ) : { x: 0, y: 0 },\r
+                                       rtl = this._.dir == 'rtl',\r
+                                       left = position.x + ( offsetX || 0 ) - positionedAncestorPosition.x,\r
+                                       top = position.y + ( offsetY || 0 ) - positionedAncestorPosition.y;\r
+\r
+                               // Floating panels are off by (-1px, 0px) in RTL mode. (#3438)\r
+                               if ( rtl && ( corner == 1 || corner == 4 ) )\r
+                                       left += offsetParent.$.offsetWidth;\r
+                               else if ( !rtl && ( corner == 2 || corner == 3 ) )\r
+                                       left += offsetParent.$.offsetWidth - 1;\r
+\r
+                               if ( corner == 3 || corner == 4 )\r
+                                       top += offsetParent.$.offsetHeight - 1;\r
+\r
+                               // Memorize offsetParent by it's ID.\r
+                               this._.panel._.offsetParentId = offsetParent.getId();\r
+\r
+                               element.setStyles( {\r
+                                       top: top + 'px',\r
+                                       left: 0,\r
+                                       display: ''\r
+                               } );\r
+\r
+                               // Don't use display or visibility style because we need to\r
+                               // calculate the rendering layout later and focus the element.\r
+                               element.setOpacity( 0 );\r
+\r
+                               // To allow the context menu to decrease back their width\r
+                               element.getFirst().removeStyle( 'width' );\r
+\r
+                               // Report to focus manager.\r
+                               this._.editor.focusManager.add( focused );\r
+\r
+                               // Configure the IFrame blur event. Do that only once.\r
+                               if ( !this._.blurSet ) {\r
+\r
+                                       // With addEventListener compatible browsers, we must\r
+                                       // useCapture when registering the focus/blur events to\r
+                                       // guarantee they will be firing in all situations. (#3068, #3222 )\r
+                                       CKEDITOR.event.useCapture = true;\r
+\r
+                                       focused.on( 'blur', function( ev ) {\r
+                                               // As we are using capture to register the listener,\r
+                                               // the blur event may get fired even when focusing\r
+                                               // inside the window itself, so we must ensure the\r
+                                               // target is out of it.\r
+                                               if ( !this.allowBlur() || ev.data.getPhase() != CKEDITOR.EVENT_PHASE_AT_TARGET )\r
+                                                       return;\r
+\r
+                                               if ( this.visible && !this._.activeChild ) {\r
+                                                       // [iOS] Allow hide to be prevented if touch is bound\r
+                                                       // to any parent of the iframe blur happens before touch (#10714).\r
+                                                       if ( CKEDITOR.env.iOS ) {\r
+                                                               if ( !this._.hideTimeout )\r
+                                                                       this._.hideTimeout = CKEDITOR.tools.setTimeout( doHide, 0, this );\r
+                                                       } else {\r
+                                                               doHide.call( this );\r
+                                                       }\r
+                                               }\r
+\r
+                                               function doHide() {\r
+                                                       // Panel close is caused by user's navigating away the focus, e.g. click outside the panel.\r
+                                                       // DO NOT restore focus in this case.\r
+                                                       delete this._.returnFocus;\r
+                                                       this.hide();\r
+                                               }\r
+                                       }, this );\r
+\r
+                                       focused.on( 'focus', function() {\r
+                                               this._.focused = true;\r
+                                               this.hideChild();\r
+                                               this.allowBlur( true );\r
+                                       }, this );\r
+\r
+                                       // [iOS] if touch is bound to any parent of the iframe blur\r
+                                       // happens twice before touchstart and before touchend (#10714).\r
+                                       if ( CKEDITOR.env.iOS ) {\r
+                                               // Prevent false hiding on blur.\r
+                                               // We don't need to return focus here because touchend will fire anyway.\r
+                                               // If user scrolls and pointer gets out of the panel area touchend will also fire.\r
+                                               focused.on( 'touchstart', function() {\r
+                                                       clearTimeout( this._.hideTimeout );\r
+                                               }, this );\r
+\r
+                                               // Set focus back to handle blur and hide panel when needed.\r
+                                               focused.on( 'touchend', function() {\r
+                                                       this._.hideTimeout = 0;\r
+                                                       this.focus();\r
+                                               }, this );\r
+                                       }\r
+\r
+                                       CKEDITOR.event.useCapture = false;\r
+\r
+                                       this._.blurSet = 1;\r
+                               }\r
+\r
+                               panel.onEscape = CKEDITOR.tools.bind( function( keystroke ) {\r
+                                       if ( this.onEscape && this.onEscape( keystroke ) === false )\r
+                                               return false;\r
+                               }, this );\r
+\r
+                               CKEDITOR.tools.setTimeout( function() {\r
+                                       var panelLoad = CKEDITOR.tools.bind( function() {\r
+                                               var target = element;\r
+\r
+                                               // Reset panel width as the new content can be narrower\r
+                                               // than the old one. (#9355)\r
+                                               target.removeStyle( 'width' );\r
+\r
+                                               if ( block.autoSize ) {\r
+                                                       var panelDoc = block.element.getDocument(),\r
+                                                               width = ( ( CKEDITOR.env.webkit || CKEDITOR.env.edge ) ? block.element : panelDoc.getBody() ).$.scrollWidth;\r
+\r
+                                                       // Account for extra height needed due to IE quirks box model bug:\r
+                                                       // http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug\r
+                                                       // (#3426)\r
+                                                       if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && width > 0 )\r
+                                                               width += ( target.$.offsetWidth || 0 ) - ( target.$.clientWidth || 0 ) + 3;\r
+\r
+                                                       // Add some extra pixels to improve the appearance.\r
+                                                       width += 10;\r
+\r
+                                                       target.setStyle( 'width', width + 'px' );\r
+\r
+                                                       var height = block.element.$.scrollHeight;\r
+\r
+                                                       // Account for extra height needed due to IE quirks box model bug:\r
+                                                       // http://en.wikipedia.org/wiki/Internet_Explorer_box_model_bug\r
+                                                       // (#3426)\r
+                                                       if ( CKEDITOR.env.ie && CKEDITOR.env.quirks && height > 0 )\r
+                                                               height += ( target.$.offsetHeight || 0 ) - ( target.$.clientHeight || 0 ) + 3;\r
+\r
+                                                       target.setStyle( 'height', height + 'px' );\r
+\r
+                                                       // Fix IE < 8 visibility.\r
+                                                       panel._.currentBlock.element.setStyle( 'display', 'none' ).removeStyle( 'display' );\r
+                                               } else {\r
+                                                       target.removeStyle( 'height' );\r
+                                               }\r
+\r
+                                               // Flip panel layout horizontally in RTL with known width.\r
+                                               if ( rtl )\r
+                                                       left -= element.$.offsetWidth;\r
+\r
+                                               // Pop the style now for measurement.\r
+                                               element.setStyle( 'left', left + 'px' );\r
+\r
+                                               /* panel layout smartly fit the viewport size. */\r
+                                               var panelElement = panel.element,\r
+                                                       panelWindow = panelElement.getWindow(),\r
+                                                       rect = element.$.getBoundingClientRect(),\r
+                                                       viewportSize = panelWindow.getViewPaneSize();\r
+\r
+                                               // Compensation for browsers that dont support "width" and "height".\r
+                                               var rectWidth = rect.width || rect.right - rect.left,\r
+                                                       rectHeight = rect.height || rect.bottom - rect.top;\r
+\r
+                                               // Check if default horizontal layout is impossible.\r
+                                               var spaceAfter = rtl ? rect.right : viewportSize.width - rect.left,\r
+                                                       spaceBefore = rtl ? viewportSize.width - rect.right : rect.left;\r
+\r
+                                               if ( rtl ) {\r
+                                                       if ( spaceAfter < rectWidth ) {\r
+                                                               // Flip to show on right.\r
+                                                               if ( spaceBefore > rectWidth )\r
+                                                                       left += rectWidth;\r
+                                                               // Align to window left.\r
+                                                               else if ( viewportSize.width > rectWidth )\r
+                                                                       left = left - rect.left;\r
+                                                               // Align to window right, never cutting the panel at right.\r
+                                                               else\r
+                                                                       left = left - rect.right + viewportSize.width;\r
+                                                       }\r
+                                               } else if ( spaceAfter < rectWidth ) {\r
+                                                       // Flip to show on left.\r
+                                                       if ( spaceBefore > rectWidth )\r
+                                                               left -= rectWidth;\r
+                                                       // Align to window right.\r
+                                                       else if ( viewportSize.width > rectWidth )\r
+                                                               left = left - rect.right + viewportSize.width;\r
+                                                       // Align to window left, never cutting the panel at left.\r
+                                                       else\r
+                                                               left = left - rect.left;\r
+                                               }\r
+\r
+\r
+                                               // Check if the default vertical layout is possible.\r
+                                               var spaceBelow = viewportSize.height - rect.top,\r
+                                                       spaceAbove = rect.top;\r
+\r
+                                               if ( spaceBelow < rectHeight ) {\r
+                                                       // Flip to show above.\r
+                                                       if ( spaceAbove > rectHeight )\r
+                                                               top -= rectHeight;\r
+                                                       // Align to window bottom.\r
+                                                       else if ( viewportSize.height > rectHeight )\r
+                                                               top = top - rect.bottom + viewportSize.height;\r
+                                                       // Align to top, never cutting the panel at top.\r
+                                                       else\r
+                                                               top = top - rect.top;\r
+                                               }\r
+\r
+                                               // If IE is in RTL, we have troubles with absolute\r
+                                               // position and horizontal scrolls. Here we have a\r
+                                               // series of hacks to workaround it. (#6146)\r
+                                               if ( CKEDITOR.env.ie ) {\r
+                                                       var offsetParent = new CKEDITOR.dom.element( element.$.offsetParent ),\r
+                                                               scrollParent = offsetParent;\r
+\r
+                                                       // Quirks returns <body>, but standards returns <html>.\r
+                                                       if ( scrollParent.getName() == 'html' )\r
+                                                               scrollParent = scrollParent.getDocument().getBody();\r
+\r
+                                                       if ( scrollParent.getComputedStyle( 'direction' ) == 'rtl' ) {\r
+                                                               // For IE8, there is not much logic on this, but it works.\r
+                                                               if ( CKEDITOR.env.ie8Compat )\r
+                                                                       left -= element.getDocument().getDocumentElement().$.scrollLeft * 2;\r
+                                                               else\r
+                                                                       left -= ( offsetParent.$.scrollWidth - offsetParent.$.clientWidth );\r
+                                                       }\r
+                                               }\r
+\r
+                                               // Trigger the onHide event of the previously active panel to prevent\r
+                                               // incorrect styles from being applied (#6170)\r
+                                               var innerElement = element.getFirst(),\r
+                                                       activePanel;\r
+                                               if ( ( activePanel = innerElement.getCustomData( 'activePanel' ) ) )\r
+                                                       activePanel.onHide && activePanel.onHide.call( this, 1 );\r
+                                               innerElement.setCustomData( 'activePanel', this );\r
+\r
+                                               element.setStyles( {\r
+                                                       top: top + 'px',\r
+                                                       left: left + 'px'\r
+                                               } );\r
+                                               element.setOpacity( 1 );\r
+\r
+                                               callback && callback();\r
+                                       }, this );\r
+\r
+                                       panel.isLoaded ? panelLoad() : panel.onLoad = panelLoad;\r
+\r
+                                       CKEDITOR.tools.setTimeout( function() {\r
+                                               var scrollTop = CKEDITOR.env.webkit && CKEDITOR.document.getWindow().getScrollPosition().y;\r
+\r
+                                               // Focus the panel frame first, so blur gets fired.\r
+                                               this.focus();\r
+\r
+                                               // Focus the block now.\r
+                                               block.element.focus();\r
+\r
+                                               // #10623, #10951 - restore the viewport's scroll position after focusing list element.\r
+                                               if ( CKEDITOR.env.webkit )\r
+                                                       CKEDITOR.document.getBody().$.scrollTop = scrollTop;\r
+\r
+                                               // We need this get fired manually because of unfired focus() function.\r
+                                               this.allowBlur( true );\r
+                                               this._.editor.fire( 'panelShow', this );\r
+                                       }, 0, this );\r
+                               }, CKEDITOR.env.air ? 200 : 0, this );\r
+                               this.visible = 1;\r
+\r
+                               if ( this.onShow )\r
+                                       this.onShow.call( this );\r
+                       },\r
+\r
+                       /**\r
+                        * Repositions the panel with the same parameters that were used in the last {@link #showBlock} call.\r
+                        *\r
+                        * @since 4.5.4\r
+                        */\r
+                       reposition: function() {\r
+                               var blockParams = this._.showBlockParams;\r
+\r
+                               if ( this.visible && this._.showBlockParams ) {\r
+                                       this.hide();\r
+                                       this.showBlock.apply( this, blockParams );\r
+                               }\r
+                       },\r
+\r
+                       /**\r
+                        * Restores the last focused element or simply focuses the panel window.\r
+                        */\r
+                       focus: function() {\r
+                               // Webkit requires to blur any previous focused page element, in\r
+                               // order to properly fire the "focus" event.\r
+                               if ( CKEDITOR.env.webkit ) {\r
+                                       var active = CKEDITOR.document.getActive();\r
+                                       active && !active.equals( this._.iframe ) && active.$.blur();\r
+                               }\r
+\r
+                               // Restore last focused element or simply focus panel window.\r
+                               var focus = this._.lastFocused || this._.iframe.getFrameDocument().getWindow();\r
+                               focus.focus();\r
+                       },\r
+\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       blur: function() {\r
+                               var doc = this._.iframe.getFrameDocument(),\r
+                                       active = doc.getActive();\r
+\r
+                               active && active.is( 'a' ) && ( this._.lastFocused = active );\r
+                       },\r
+\r
+                       /**\r
+                        * Hides the panel.\r
+                        *\r
+                        * @todo\r
+                        */\r
+                       hide: function( returnFocus ) {\r
+                               if ( this.visible && ( !this.onHide || this.onHide.call( this ) !== true ) ) {\r
+                                       this.hideChild();\r
+                                       // Blur previously focused element. (#6671)\r
+                                       CKEDITOR.env.gecko && this._.iframe.getFrameDocument().$.activeElement.blur();\r
+                                       this.element.setStyle( 'display', 'none' );\r
+                                       this.visible = 0;\r
+                                       this.element.getFirst().removeCustomData( 'activePanel' );\r
+\r
+                                       // Return focus properly. (#6247)\r
+                                       var focusReturn = returnFocus && this._.returnFocus;\r
+                                       if ( focusReturn ) {\r
+                                               // Webkit requires focus moved out panel iframe first.\r
+                                               if ( CKEDITOR.env.webkit && focusReturn.type )\r
+                                                       focusReturn.getWindow().$.focus();\r
+\r
+                                               focusReturn.focus();\r
+                                       }\r
+\r
+                                       delete this._.lastFocused;\r
+                                       this._.showBlockParams = null;\r
+\r
+                                       this._.editor.fire( 'panelHide', this );\r
+                               }\r
+                       },\r
+\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       allowBlur: function( allow ) {\r
+                               // Prevent editor from hiding the panel. (#3222)\r
+                               var panel = this._.panel;\r
+                               if ( allow !== undefined )\r
+                                       panel.allowBlur = allow;\r
+\r
+                               return panel.allowBlur;\r
+                       },\r
+\r
+                       /**\r
+                        * Shows the specified panel as a child of one block of this one.\r
+                        *\r
+                        * @param {CKEDITOR.ui.floatPanel} panel\r
+                        * @param {String} blockName\r
+                        * @param {CKEDITOR.dom.element} offsetParent Positioned parent.\r
+                        * @param {Number} corner\r
+                        *\r
+                        * * For LTR (left to right) oriented editor:\r
+                        *      * `1` = top-left\r
+                        *      * `2` = top-right\r
+                        *      * `3` = bottom-right\r
+                        *      * `4` = bottom-left\r
+                        * * For RTL (right to left):\r
+                        *      * `1` = top-right\r
+                        *      * `2` = top-left\r
+                        *      * `3` = bottom-left\r
+                        *      * `4` = bottom-right\r
+                        *\r
+                        * @param {Number} [offsetX=0]\r
+                        * @param {Number} [offsetY=0]\r
+                        * @todo\r
+                        */\r
+                       showAsChild: function( panel, blockName, offsetParent, corner, offsetX, offsetY ) {\r
+                               // Skip reshowing of child which is already visible.\r
+                               if ( this._.activeChild == panel && panel._.panel._.offsetParentId == offsetParent.getId() )\r
+                                       return;\r
+\r
+                               this.hideChild();\r
+\r
+                               panel.onHide = CKEDITOR.tools.bind( function() {\r
+                                       // Use a timeout, so we give time for this menu to get\r
+                                       // potentially focused.\r
+                                       CKEDITOR.tools.setTimeout( function() {\r
+                                               if ( !this._.focused )\r
+                                                       this.hide();\r
+                                       }, 0, this );\r
+                               }, this );\r
+\r
+                               this._.activeChild = panel;\r
+                               this._.focused = false;\r
+\r
+                               panel.showBlock( blockName, offsetParent, corner, offsetX, offsetY );\r
+                               this.blur();\r
+\r
+                               /* #3767 IE: Second level menu may not have borders */\r
+                               if ( CKEDITOR.env.ie7Compat || CKEDITOR.env.ie6Compat ) {\r
+                                       setTimeout( function() {\r
+                                               panel.element.getChild( 0 ).$.style.cssText += '';\r
+                                       }, 100 );\r
+                               }\r
+                       },\r
+\r
+                       /**\r
+                        * @todo\r
+                        */\r
+                       hideChild: function( restoreFocus ) {\r
+                               var activeChild = this._.activeChild;\r
+\r
+                               if ( activeChild ) {\r
+                                       delete activeChild.onHide;\r
+                                       delete this._.activeChild;\r
+                                       activeChild.hide();\r
+\r
+                                       // At this point focus should be moved back to parent panel.\r
+                                       restoreFocus && this.focus();\r
+                               }\r
+                       }\r
+               }\r
+       } );\r
+\r
+       CKEDITOR.on( 'instanceDestroyed', function() {\r
+               var isLastInstance = CKEDITOR.tools.isEmpty( CKEDITOR.instances );\r
+\r
+               for ( var i in panels ) {\r
+                       var panel = panels[ i ];\r
+                       // Safe to destroy it since there're no more instances.(#4241)\r
+                       if ( isLastInstance )\r
+                               panel.destroy();\r
+                       // Panel might be used by other instances, just hide them.(#4552)\r
+                       else\r
+                               panel.element.hide();\r
+               }\r
+               // Remove the registration.\r
+               isLastInstance && ( panels = {} );\r
+\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/format/lang/af.js b/sources/plugins/format/lang/af.js
new file mode 100644 (file)
index 0000000..b38cd33
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'af', {\r
+       label: 'Opmaak',\r
+       panelTitle: 'Opmaak',\r
+       tag_address: 'Adres',\r
+       tag_div: 'Normaal (DIV)',\r
+       tag_h1: 'Opskrif 1',\r
+       tag_h2: 'Opskrif 2',\r
+       tag_h3: 'Opskrif 3',\r
+       tag_h4: 'Opskrif 4',\r
+       tag_h5: 'Opskrif 5',\r
+       tag_h6: 'Opskrif 6',\r
+       tag_p: 'Normaal',\r
+       tag_pre: 'Opgemaak'\r
+} );\r
diff --git a/sources/plugins/format/lang/ar.js b/sources/plugins/format/lang/ar.js
new file mode 100644 (file)
index 0000000..8fc1c38
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ar', {\r
+       label: 'تنسيق',\r
+       panelTitle: 'تنسيق الفقرة',\r
+       tag_address: 'عنوان',\r
+       tag_div: 'عادي (DIV)',\r
+       tag_h1: 'العنوان 1',\r
+       tag_h2: 'العنوان  2',\r
+       tag_h3: 'العنوان  3',\r
+       tag_h4: 'العنوان  4',\r
+       tag_h5: 'العنوان  5',\r
+       tag_h6: 'العنوان  6',\r
+       tag_p: 'عادي',\r
+       tag_pre: 'منسّق'\r
+} );\r
diff --git a/sources/plugins/format/lang/az.js b/sources/plugins/format/lang/az.js
new file mode 100644 (file)
index 0000000..05b2d54
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'az', {\r
+       label: 'Format',\r
+       panelTitle: 'Abzasın formatı',\r
+       tag_address: 'Ünvan',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Başlıq 1',\r
+       tag_h2: 'Başlıq 2',\r
+       tag_h3: 'Başlıq 3',\r
+       tag_h4: 'Başlıq 4',\r
+       tag_h5: 'Başlıq 5',\r
+       tag_h6: 'Başlıq 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatı saxla'\r
+} );\r
diff --git a/sources/plugins/format/lang/bg.js b/sources/plugins/format/lang/bg.js
new file mode 100644 (file)
index 0000000..3de0ac4
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'bg', {\r
+       label: 'Формат',\r
+       panelTitle: 'Формат',\r
+       tag_address: 'Адрес',\r
+       tag_div: 'Параграф (DIV)',\r
+       tag_h1: 'Заглавие 1',\r
+       tag_h2: 'Заглавие 2',\r
+       tag_h3: 'Заглавие 3',\r
+       tag_h4: 'Заглавие 4',\r
+       tag_h5: 'Заглавие 5',\r
+       tag_h6: 'Заглавие 6',\r
+       tag_p: 'Нормален',\r
+       tag_pre: 'Форматиран'\r
+} );\r
diff --git a/sources/plugins/format/lang/bn.js b/sources/plugins/format/lang/bn.js
new file mode 100644 (file)
index 0000000..45857a2
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'bn', {\r
+       label: 'ধরন-প্রকৃতি',\r
+       panelTitle: 'ফন্ট ফরমেট',\r
+       tag_address: 'ঠিকানা',\r
+       tag_div: 'শীর্ষক (DIV)',\r
+       tag_h1: 'শীর্ষক ১',\r
+       tag_h2: 'শীর্ষক ২',\r
+       tag_h3: 'শীর্ষক ৩',\r
+       tag_h4: 'শীর্ষক ৪',\r
+       tag_h5: 'শীর্ষক ৫',\r
+       tag_h6: 'শীর্ষক ৬',\r
+       tag_p: 'সাধারণ',\r
+       tag_pre: 'ফর্মেটেড'\r
+} );\r
diff --git a/sources/plugins/format/lang/bs.js b/sources/plugins/format/lang/bs.js
new file mode 100644 (file)
index 0000000..4e9482a
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'bs', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)', // MISSING\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/ca.js b/sources/plugins/format/lang/ca.js
new file mode 100644 (file)
index 0000000..5345898
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ca', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Adreça',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Encapçalament 1',\r
+       tag_h2: 'Encapçalament 2',\r
+       tag_h3: 'Encapçalament 3',\r
+       tag_h4: 'Encapçalament 4',\r
+       tag_h5: 'Encapçalament 5',\r
+       tag_h6: 'Encapçalament 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatejat'\r
+} );\r
diff --git a/sources/plugins/format/lang/cs.js b/sources/plugins/format/lang/cs.js
new file mode 100644 (file)
index 0000000..b96a6c4
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'cs', {\r
+       label: 'Formát',\r
+       panelTitle: 'Formát',\r
+       tag_address: 'Adresa',\r
+       tag_div: 'Normální (DIV)',\r
+       tag_h1: 'Nadpis 1',\r
+       tag_h2: 'Nadpis 2',\r
+       tag_h3: 'Nadpis 3',\r
+       tag_h4: 'Nadpis 4',\r
+       tag_h5: 'Nadpis 5',\r
+       tag_h6: 'Nadpis 6',\r
+       tag_p: 'Normální',\r
+       tag_pre: 'Naformátováno'\r
+} );\r
diff --git a/sources/plugins/format/lang/cy.js b/sources/plugins/format/lang/cy.js
new file mode 100644 (file)
index 0000000..a8f618f
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'cy', {\r
+       label: 'Fformat',\r
+       panelTitle: 'Fformat Paragraff',\r
+       tag_address: 'Cyfeiriad',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Pennawd 1',\r
+       tag_h2: 'Pennawd 2',\r
+       tag_h3: 'Pennawd 3',\r
+       tag_h4: 'Pennawd 4',\r
+       tag_h5: 'Pennawd 5',\r
+       tag_h6: 'Pennawd 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Wedi\'i Fformatio'\r
+} );\r
diff --git a/sources/plugins/format/lang/da.js b/sources/plugins/format/lang/da.js
new file mode 100644 (file)
index 0000000..1f7c654
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'da', {\r
+       label: 'Formatering',\r
+       panelTitle: 'Formatering',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Overskrift 1',\r
+       tag_h2: 'Overskrift 2',\r
+       tag_h3: 'Overskrift 3',\r
+       tag_h4: 'Overskrift 4',\r
+       tag_h5: 'Overskrift 5',\r
+       tag_h6: 'Overskrift 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formateret'\r
+} );\r
diff --git a/sources/plugins/format/lang/de-ch.js b/sources/plugins/format/lang/de-ch.js
new file mode 100644 (file)
index 0000000..68b8879
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'de-ch', {\r
+       label: 'Format',\r
+       panelTitle: 'Absatzformat',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Überschrift 1',\r
+       tag_h2: 'Überschrift 2',\r
+       tag_h3: 'Überschrift 3',\r
+       tag_h4: 'Überschrift 4',\r
+       tag_h5: 'Überschrift 5',\r
+       tag_h6: 'Überschrift 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatiert'\r
+} );\r
diff --git a/sources/plugins/format/lang/de.js b/sources/plugins/format/lang/de.js
new file mode 100644 (file)
index 0000000..e6f6677
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'de', {\r
+       label: 'Format',\r
+       panelTitle: 'Absatzformat',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Überschrift 1',\r
+       tag_h2: 'Überschrift 2',\r
+       tag_h3: 'Überschrift 3',\r
+       tag_h4: 'Überschrift 4',\r
+       tag_h5: 'Überschrift 5',\r
+       tag_h6: 'Überschrift 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatiert'\r
+} );\r
diff --git a/sources/plugins/format/lang/el.js b/sources/plugins/format/lang/el.js
new file mode 100644 (file)
index 0000000..9b34051
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'el', {\r
+       label: 'Μορφοποίηση',\r
+       panelTitle: 'Μορφοποίηση Παραγράφου',\r
+       tag_address: 'Διεύθυνση',\r
+       tag_div: 'Κανονική (DIV)',\r
+       tag_h1: 'Κεφαλίδα 1',\r
+       tag_h2: 'Κεφαλίδα 2',\r
+       tag_h3: 'Κεφαλίδα 3',\r
+       tag_h4: 'Κεφαλίδα 4',\r
+       tag_h5: 'Κεφαλίδα 5',\r
+       tag_h6: 'Κεφαλίδα 6',\r
+       tag_p: 'Κανονική',\r
+       tag_pre: 'Προ-μορφοποιημένη'\r
+} );\r
diff --git a/sources/plugins/format/lang/en-au.js b/sources/plugins/format/lang/en-au.js
new file mode 100644 (file)
index 0000000..5ec7d8e
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'en-au', {\r
+       label: 'Format',\r
+       panelTitle: 'Paragraph Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/en-ca.js b/sources/plugins/format/lang/en-ca.js
new file mode 100644 (file)
index 0000000..75d66c3
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'en-ca', {\r
+       label: 'Format',\r
+       panelTitle: 'Paragraph Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/en-gb.js b/sources/plugins/format/lang/en-gb.js
new file mode 100644 (file)
index 0000000..a91bcbf
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'en-gb', {\r
+       label: 'Format',\r
+       panelTitle: 'Paragraph Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/en.js b/sources/plugins/format/lang/en.js
new file mode 100644 (file)
index 0000000..3a6ebda
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'en', {\r
+       label: 'Format',\r
+       panelTitle: 'Paragraph Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/eo.js b/sources/plugins/format/lang/eo.js
new file mode 100644 (file)
index 0000000..0d77730
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'eo', {\r
+       label: 'Formato',\r
+       panelTitle: 'ParagrafFormato',\r
+       tag_address: 'Adreso',\r
+       tag_div: 'Normala (DIV)',\r
+       tag_h1: 'Titolo 1',\r
+       tag_h2: 'Titolo 2',\r
+       tag_h3: 'Titolo 3',\r
+       tag_h4: 'Titolo 4',\r
+       tag_h5: 'Titolo 5',\r
+       tag_h6: 'Titolo 6',\r
+       tag_p: 'Normala',\r
+       tag_pre: 'Formatita'\r
+} );\r
diff --git a/sources/plugins/format/lang/es.js b/sources/plugins/format/lang/es.js
new file mode 100644 (file)
index 0000000..549f611
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'es', {\r
+       label: 'Formato',\r
+       panelTitle: 'Formato',\r
+       tag_address: 'Dirección',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Encabezado 1',\r
+       tag_h2: 'Encabezado 2',\r
+       tag_h3: 'Encabezado 3',\r
+       tag_h4: 'Encabezado 4',\r
+       tag_h5: 'Encabezado 5',\r
+       tag_h6: 'Encabezado 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Con formato'\r
+} );\r
diff --git a/sources/plugins/format/lang/et.js b/sources/plugins/format/lang/et.js
new file mode 100644 (file)
index 0000000..43bc350
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'et', {\r
+       label: 'Vorming',\r
+       panelTitle: 'Vorming',\r
+       tag_address: 'Aadress',\r
+       tag_div: 'Tavaline (DIV)',\r
+       tag_h1: 'Pealkiri 1',\r
+       tag_h2: 'Pealkiri 2',\r
+       tag_h3: 'Pealkiri 3',\r
+       tag_h4: 'Pealkiri 4',\r
+       tag_h5: 'Pealkiri 5',\r
+       tag_h6: 'Pealkiri 6',\r
+       tag_p: 'Tavaline',\r
+       tag_pre: 'Vormindatud'\r
+} );\r
diff --git a/sources/plugins/format/lang/eu.js b/sources/plugins/format/lang/eu.js
new file mode 100644 (file)
index 0000000..18832bc
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'eu', {\r
+       label: 'Formatua',\r
+       panelTitle: 'Paragrafoaren formatua',\r
+       tag_address: 'Helbidea',\r
+       tag_div: 'Normala (DIV)',\r
+       tag_h1: 'Izenburua 1',\r
+       tag_h2: 'Izenburua 2',\r
+       tag_h3: 'Izenburua 3',\r
+       tag_h4: 'Izenburua 4',\r
+       tag_h5: 'Izenburua 5',\r
+       tag_h6: 'Izenburua 6',\r
+       tag_p: 'Normala',\r
+       tag_pre: 'Formatuduna'\r
+} );\r
diff --git a/sources/plugins/format/lang/fa.js b/sources/plugins/format/lang/fa.js
new file mode 100644 (file)
index 0000000..c92db53
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'fa', {\r
+       label: 'قالب',\r
+       panelTitle: 'قالب بند',\r
+       tag_address: 'نشانی',\r
+       tag_div: 'بند',\r
+       tag_h1: 'سرنویس ۱',\r
+       tag_h2: 'سرنویس ۲',\r
+       tag_h3: 'سرنویس ۳',\r
+       tag_h4: 'سرنویس ۴',\r
+       tag_h5: 'سرنویس ۵',\r
+       tag_h6: 'سرنویس ۶',\r
+       tag_p: 'معمولی',\r
+       tag_pre: 'قالب‌دار'\r
+} );\r
diff --git a/sources/plugins/format/lang/fi.js b/sources/plugins/format/lang/fi.js
new file mode 100644 (file)
index 0000000..249183d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'fi', {\r
+       label: 'Muotoilu',\r
+       panelTitle: 'Muotoilu',\r
+       tag_address: 'Osoite',\r
+       tag_div: 'Normaali (DIV)',\r
+       tag_h1: 'Otsikko 1',\r
+       tag_h2: 'Otsikko 2',\r
+       tag_h3: 'Otsikko 3',\r
+       tag_h4: 'Otsikko 4',\r
+       tag_h5: 'Otsikko 5',\r
+       tag_h6: 'Otsikko 6',\r
+       tag_p: 'Normaali',\r
+       tag_pre: 'Muotoiltu'\r
+} );\r
diff --git a/sources/plugins/format/lang/fo.js b/sources/plugins/format/lang/fo.js
new file mode 100644 (file)
index 0000000..2c88021
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'fo', {\r
+       label: 'Skriftsnið',\r
+       panelTitle: 'Skriftsnið',\r
+       tag_address: 'Adressa',\r
+       tag_div: 'Vanligt (DIV)',\r
+       tag_h1: 'Yvirskrift 1',\r
+       tag_h2: 'Yvirskrift 2',\r
+       tag_h3: 'Yvirskrift 3',\r
+       tag_h4: 'Yvirskrift 4',\r
+       tag_h5: 'Yvirskrift 5',\r
+       tag_h6: 'Yvirskrift 6',\r
+       tag_p: 'Vanligt',\r
+       tag_pre: 'Sniðgivið'\r
+} );\r
diff --git a/sources/plugins/format/lang/fr-ca.js b/sources/plugins/format/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..8f190c2
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'fr-ca', {\r
+       label: 'Format',\r
+       panelTitle: 'Format de paragraphe',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'En-tête 1',\r
+       tag_h2: 'En-tête 2',\r
+       tag_h3: 'En-tête 3',\r
+       tag_h4: 'En-tête 4',\r
+       tag_h5: 'En-tête 5',\r
+       tag_h6: 'En-tête 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formaté'\r
+} );\r
diff --git a/sources/plugins/format/lang/fr.js b/sources/plugins/format/lang/fr.js
new file mode 100644 (file)
index 0000000..6962da7
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'fr', {\r
+       label: 'Format',\r
+       panelTitle: 'Format de paragraphe',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Division',\r
+       tag_h1: 'Titre 1',\r
+       tag_h2: 'Titre 2',\r
+       tag_h3: 'Titre 3',\r
+       tag_h4: 'Titre 4',\r
+       tag_h5: 'Titre 5',\r
+       tag_h6: 'Titre 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Préformaté'\r
+} );\r
diff --git a/sources/plugins/format/lang/gl.js b/sources/plugins/format/lang/gl.js
new file mode 100644 (file)
index 0000000..d14946c
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'gl', {\r
+       label: 'Formato',\r
+       panelTitle: 'Formato do parágrafo',\r
+       tag_address: 'Enderezo',\r
+       tag_div: 'Normal  (DIV)',\r
+       tag_h1: 'Enacabezado 1',\r
+       tag_h2: 'Encabezado 2',\r
+       tag_h3: 'Encabezado 3',\r
+       tag_h4: 'Encabezado 4',\r
+       tag_h5: 'Encabezado 5',\r
+       tag_h6: 'Encabezado 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatado'\r
+} );\r
diff --git a/sources/plugins/format/lang/gu.js b/sources/plugins/format/lang/gu.js
new file mode 100644 (file)
index 0000000..8d8897a
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'gu', {\r
+       label: 'ફૉન્ટ ફૉર્મટ, રચનાની શૈલી',\r
+       panelTitle: 'ફૉન્ટ ફૉર્મટ, રચનાની શૈલી',\r
+       tag_address: 'સરનામું',\r
+       tag_div: 'શીર્ષક (DIV)',\r
+       tag_h1: 'શીર્ષક 1',\r
+       tag_h2: 'શીર્ષક 2',\r
+       tag_h3: 'શીર્ષક 3',\r
+       tag_h4: 'શીર્ષક 4',\r
+       tag_h5: 'શીર્ષક 5',\r
+       tag_h6: 'શીર્ષક 6',\r
+       tag_p: 'સામાન્ય',\r
+       tag_pre: 'ફૉર્મટેડ'\r
+} );\r
diff --git a/sources/plugins/format/lang/he.js b/sources/plugins/format/lang/he.js
new file mode 100644 (file)
index 0000000..5fb53a7
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'he', {\r
+       label: 'עיצוב',\r
+       panelTitle: 'עיצוב',\r
+       tag_address: 'כתובת',\r
+       tag_div: 'נורמלי (DIV)',\r
+       tag_h1: 'כותרת',\r
+       tag_h2: 'כותרת 2',\r
+       tag_h3: 'כותרת 3',\r
+       tag_h4: 'כותרת 4',\r
+       tag_h5: 'כותרת 5',\r
+       tag_h6: 'כותרת 6',\r
+       tag_p: 'נורמלי',\r
+       tag_pre: 'קוד'\r
+} );\r
diff --git a/sources/plugins/format/lang/hi.js b/sources/plugins/format/lang/hi.js
new file mode 100644 (file)
index 0000000..ce4224d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'hi', {\r
+       label: 'फ़ॉर्मैट',\r
+       panelTitle: 'फ़ॉर्मैट',\r
+       tag_address: 'पता',\r
+       tag_div: 'शीर्षक (DIV)',\r
+       tag_h1: 'शीर्षक 1',\r
+       tag_h2: 'शीर्षक 2',\r
+       tag_h3: 'शीर्षक 3',\r
+       tag_h4: 'शीर्षक 4',\r
+       tag_h5: 'शीर्षक 5',\r
+       tag_h6: 'शीर्षक 6',\r
+       tag_p: 'साधारण',\r
+       tag_pre: 'फ़ॉर्मैटॅड'\r
+} );\r
diff --git a/sources/plugins/format/lang/hr.js b/sources/plugins/format/lang/hr.js
new file mode 100644 (file)
index 0000000..2d6ec21
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'hr', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Address',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatirano'\r
+} );\r
diff --git a/sources/plugins/format/lang/hu.js b/sources/plugins/format/lang/hu.js
new file mode 100644 (file)
index 0000000..a5467cf
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'hu', {\r
+       label: 'Formátum',\r
+       panelTitle: 'Formátum',\r
+       tag_address: 'Címsor',\r
+       tag_div: 'Bekezdés (DIV)',\r
+       tag_h1: 'Fejléc 1',\r
+       tag_h2: 'Fejléc 2',\r
+       tag_h3: 'Fejléc 3',\r
+       tag_h4: 'Fejléc 4',\r
+       tag_h5: 'Fejléc 5',\r
+       tag_h6: 'Fejléc 6',\r
+       tag_p: 'Normál',\r
+       tag_pre: 'Formázott'\r
+} );\r
diff --git a/sources/plugins/format/lang/id.js b/sources/plugins/format/lang/id.js
new file mode 100644 (file)
index 0000000..e8e83f7
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'id', {\r
+       label: 'Bentuk',\r
+       panelTitle: 'Bentuk Paragraf',\r
+       tag_address: 'Alamat',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Membentuk'\r
+} );\r
diff --git a/sources/plugins/format/lang/is.js b/sources/plugins/format/lang/is.js
new file mode 100644 (file)
index 0000000..862e52e
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'is', {\r
+       label: 'Stílsnið',\r
+       panelTitle: 'Stílsnið',\r
+       tag_address: 'Vistfang',\r
+       tag_div: 'Venjulegt (DIV)',\r
+       tag_h1: 'Fyrirsögn 1',\r
+       tag_h2: 'Fyrirsögn 2',\r
+       tag_h3: 'Fyrirsögn 3',\r
+       tag_h4: 'Fyrirsögn 4',\r
+       tag_h5: 'Fyrirsögn 5',\r
+       tag_h6: 'Fyrirsögn 6',\r
+       tag_p: 'Venjulegt letur',\r
+       tag_pre: 'Forsniðið'\r
+} );\r
diff --git a/sources/plugins/format/lang/it.js b/sources/plugins/format/lang/it.js
new file mode 100644 (file)
index 0000000..6d47500
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'it', {\r
+       label: 'Formato',\r
+       panelTitle: 'Formato',\r
+       tag_address: 'Indirizzo',\r
+       tag_div: 'Paragrafo (DIV)',\r
+       tag_h1: 'Titolo 1',\r
+       tag_h2: 'Titolo 2',\r
+       tag_h3: 'Titolo 3',\r
+       tag_h4: 'Titolo 4',\r
+       tag_h5: 'Titolo 5',\r
+       tag_h6: 'Titolo 6',\r
+       tag_p: 'Normale',\r
+       tag_pre: 'Formattato'\r
+} );\r
diff --git a/sources/plugins/format/lang/ja.js b/sources/plugins/format/lang/ja.js
new file mode 100644 (file)
index 0000000..a611f3d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ja', {\r
+       label: '書式',\r
+       panelTitle: '段落の書式',\r
+       tag_address: 'アドレス',\r
+       tag_div: '標準 (DIV)',\r
+       tag_h1: '見出し 1',\r
+       tag_h2: '見出し 2',\r
+       tag_h3: '見出し 3',\r
+       tag_h4: '見出し 4',\r
+       tag_h5: '見出し 5',\r
+       tag_h6: '見出し 6',\r
+       tag_p: '標準',\r
+       tag_pre: '書式付き'\r
+} );\r
diff --git a/sources/plugins/format/lang/ka.js b/sources/plugins/format/lang/ka.js
new file mode 100644 (file)
index 0000000..f5c95b8
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ka', {\r
+       label: 'ფიორმატირება',\r
+       panelTitle: 'ფორმატირება',\r
+       tag_address: 'მისამართი',\r
+       tag_div: 'ჩვეულებრივი (DIV)',\r
+       tag_h1: 'სათაური 1',\r
+       tag_h2: 'სათაური 2',\r
+       tag_h3: 'სათაური 3',\r
+       tag_h4: 'სათაური 4',\r
+       tag_h5: 'სათაური 5',\r
+       tag_h6: 'სათაური 6',\r
+       tag_p: 'ჩვეულებრივი',\r
+       tag_pre: 'ფორმატირებული'\r
+} );\r
diff --git a/sources/plugins/format/lang/km.js b/sources/plugins/format/lang/km.js
new file mode 100644 (file)
index 0000000..74ca185
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'km', {\r
+       label: 'ទម្រង់',\r
+       panelTitle: 'ទម្រង់​កថាខណ្ឌ',\r
+       tag_address: 'អាសយដ្ឋាន',\r
+       tag_div: 'ធម្មតា (DIV)',\r
+       tag_h1: 'ចំណង​ជើង 1',\r
+       tag_h2: 'ចំណង​ជើង 2',\r
+       tag_h3: 'ចំណង​ជើង 3',\r
+       tag_h4: 'ចំណង​ជើង 4',\r
+       tag_h5: 'ចំណង​ជើង 5',\r
+       tag_h6: 'ចំណង​ជើង 6',\r
+       tag_p: 'ធម្មតា',\r
+       tag_pre: 'Formatted' // MISSING\r
+} );\r
diff --git a/sources/plugins/format/lang/ko.js b/sources/plugins/format/lang/ko.js
new file mode 100644 (file)
index 0000000..e5ed44c
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ko', {\r
+       label: '문단',\r
+       panelTitle: '문단 형식',\r
+       tag_address: '글쓴이',\r
+       tag_div: '기본 (DIV)',\r
+       tag_h1: '제목 1',\r
+       tag_h2: '제목 2',\r
+       tag_h3: '제목 3',\r
+       tag_h4: '제목 4',\r
+       tag_h5: '제목 5',\r
+       tag_h6: '제목 6',\r
+       tag_p: '본문',\r
+       tag_pre: '정형 문단'\r
+} );\r
diff --git a/sources/plugins/format/lang/ku.js b/sources/plugins/format/lang/ku.js
new file mode 100644 (file)
index 0000000..277bf8e
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ku', {\r
+       label: 'ڕازاندنەوە',\r
+       panelTitle: 'بەشی ڕازاندنەوه',\r
+       tag_address: 'ناونیشان',\r
+       tag_div: '(DIV)-ی ئاسایی',\r
+       tag_h1: 'سەرنووسەی ١',\r
+       tag_h2: 'سەرنووسەی ٢',\r
+       tag_h3: 'سەرنووسەی ٣',\r
+       tag_h4: 'سەرنووسەی ٤',\r
+       tag_h5: 'سەرنووسەی ٥',\r
+       tag_h6: 'سەرنووسەی ٦',\r
+       tag_p: 'ئاسایی',\r
+       tag_pre: 'شێوازکراو'\r
+} );\r
diff --git a/sources/plugins/format/lang/lt.js b/sources/plugins/format/lang/lt.js
new file mode 100644 (file)
index 0000000..9733443
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'lt', {\r
+       label: 'Šrifto formatas',\r
+       panelTitle: 'Šrifto formatas',\r
+       tag_address: 'Kreipinio',\r
+       tag_div: 'Normalus (DIV)',\r
+       tag_h1: 'Antraštinis 1',\r
+       tag_h2: 'Antraštinis 2',\r
+       tag_h3: 'Antraštinis 3',\r
+       tag_h4: 'Antraštinis 4',\r
+       tag_h5: 'Antraštinis 5',\r
+       tag_h6: 'Antraštinis 6',\r
+       tag_p: 'Normalus',\r
+       tag_pre: 'Formuotas'\r
+} );\r
diff --git a/sources/plugins/format/lang/lv.js b/sources/plugins/format/lang/lv.js
new file mode 100644 (file)
index 0000000..ace8333
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'lv', {\r
+       label: 'Formāts',\r
+       panelTitle: 'Formāts',\r
+       tag_address: 'Adrese',\r
+       tag_div: 'Rindkopa (DIV)',\r
+       tag_h1: 'Virsraksts 1',\r
+       tag_h2: 'Virsraksts 2',\r
+       tag_h3: 'Virsraksts 3',\r
+       tag_h4: 'Virsraksts 4',\r
+       tag_h5: 'Virsraksts 5',\r
+       tag_h6: 'Virsraksts 6',\r
+       tag_p: 'Normāls teksts',\r
+       tag_pre: 'Formatēts teksts'\r
+} );\r
diff --git a/sources/plugins/format/lang/mk.js b/sources/plugins/format/lang/mk.js
new file mode 100644 (file)
index 0000000..5c0bb3b
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'mk', {\r
+       label: 'Format', // MISSING\r
+       panelTitle: 'Paragraph Format', // MISSING\r
+       tag_address: 'Address', // MISSING\r
+       tag_div: 'Normal (DIV)', // MISSING\r
+       tag_h1: 'Heading 1', // MISSING\r
+       tag_h2: 'Heading 2', // MISSING\r
+       tag_h3: 'Heading 3', // MISSING\r
+       tag_h4: 'Heading 4', // MISSING\r
+       tag_h5: 'Heading 5', // MISSING\r
+       tag_h6: 'Heading 6', // MISSING\r
+       tag_p: 'Normal', // MISSING\r
+       tag_pre: 'Formatted' // MISSING\r
+} );\r
diff --git a/sources/plugins/format/lang/mn.js b/sources/plugins/format/lang/mn.js
new file mode 100644 (file)
index 0000000..f3c0dfd
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'mn', {\r
+       label: 'Параргафын загвар',\r
+       panelTitle: 'Параргафын загвар',\r
+       tag_address: 'Хаяг',\r
+       tag_div: 'Paragraph (DIV)',\r
+       tag_h1: 'Гарчиг 1',\r
+       tag_h2: 'Гарчиг 2',\r
+       tag_h3: 'Гарчиг 3',\r
+       tag_h4: 'Гарчиг 4',\r
+       tag_h5: 'Гарчиг 5',\r
+       tag_h6: 'Гарчиг 6',\r
+       tag_p: 'Хэвийн',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/ms.js b/sources/plugins/format/lang/ms.js
new file mode 100644 (file)
index 0000000..56deba9
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ms', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Alamat',\r
+       tag_div: 'Perenggan (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Telah Diformat'\r
+} );\r
diff --git a/sources/plugins/format/lang/nb.js b/sources/plugins/format/lang/nb.js
new file mode 100644 (file)
index 0000000..6bfffb5
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'nb', {\r
+       label: 'Format',\r
+       panelTitle: 'Avsnittsformat',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Overskrift 1',\r
+       tag_h2: 'Overskrift 2',\r
+       tag_h3: 'Overskrift 3',\r
+       tag_h4: 'Overskrift 4',\r
+       tag_h5: 'Overskrift 5',\r
+       tag_h6: 'Overskrift 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatert'\r
+} );\r
diff --git a/sources/plugins/format/lang/nl.js b/sources/plugins/format/lang/nl.js
new file mode 100644 (file)
index 0000000..ef2676a
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'nl', {\r
+       label: 'Opmaak',\r
+       panelTitle: 'Opmaak',\r
+       tag_address: 'Adres',\r
+       tag_div: 'Normaal (DIV)',\r
+       tag_h1: 'Kop 1',\r
+       tag_h2: 'Kop 2',\r
+       tag_h3: 'Kop 3',\r
+       tag_h4: 'Kop 4',\r
+       tag_h5: 'Kop 5',\r
+       tag_h6: 'Kop 6',\r
+       tag_p: 'Normaal',\r
+       tag_pre: 'Met opmaak'\r
+} );\r
diff --git a/sources/plugins/format/lang/no.js b/sources/plugins/format/lang/no.js
new file mode 100644 (file)
index 0000000..d9b0586
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'no', {\r
+       label: 'Format',\r
+       panelTitle: 'Avsnittsformat',\r
+       tag_address: 'Adresse',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Overskrift 1',\r
+       tag_h2: 'Overskrift 2',\r
+       tag_h3: 'Overskrift 3',\r
+       tag_h4: 'Overskrift 4',\r
+       tag_h5: 'Overskrift 5',\r
+       tag_h6: 'Overskrift 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatert'\r
+} );\r
diff --git a/sources/plugins/format/lang/oc.js b/sources/plugins/format/lang/oc.js
new file mode 100644 (file)
index 0000000..5083f3f
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'oc', {\r
+       label: 'Format',\r
+       panelTitle: 'Format de paragraf',\r
+       tag_address: 'Adreça',\r
+       tag_div: 'Division (DIV)',\r
+       tag_h1: 'Títol 1',\r
+       tag_h2: 'Títol 2',\r
+       tag_h3: 'Títol 3',\r
+       tag_h4: 'Títol 4',\r
+       tag_h5: 'Títol 5',\r
+       tag_h6: 'Títol 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Preformatat'\r
+} );\r
diff --git a/sources/plugins/format/lang/pl.js b/sources/plugins/format/lang/pl.js
new file mode 100644 (file)
index 0000000..d1274f9
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'pl', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Adres',\r
+       tag_div: 'Normalny (DIV)',\r
+       tag_h1: 'Nagłówek 1',\r
+       tag_h2: 'Nagłówek 2',\r
+       tag_h3: 'Nagłówek 3',\r
+       tag_h4: 'Nagłówek 4',\r
+       tag_h5: 'Nagłówek 5',\r
+       tag_h6: 'Nagłówek 6',\r
+       tag_p: 'Normalny',\r
+       tag_pre: 'Tekst sformatowany'\r
+} );\r
diff --git a/sources/plugins/format/lang/pt-br.js b/sources/plugins/format/lang/pt-br.js
new file mode 100644 (file)
index 0000000..151d1d1
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'pt-br', {\r
+       label: 'Formatação',\r
+       panelTitle: 'Formatação',\r
+       tag_address: 'Endereço',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Título 1',\r
+       tag_h2: 'Título 2',\r
+       tag_h3: 'Título 3',\r
+       tag_h4: 'Título 4',\r
+       tag_h5: 'Título 5',\r
+       tag_h6: 'Título 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatado'\r
+} );\r
diff --git a/sources/plugins/format/lang/pt.js b/sources/plugins/format/lang/pt.js
new file mode 100644 (file)
index 0000000..013021d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'pt', {\r
+       label: 'Formatar',\r
+       panelTitle: 'Formatar Parágrafo',\r
+       tag_address: 'Endereço',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Título 1',\r
+       tag_h2: 'Título 2',\r
+       tag_h3: 'Título 3',\r
+       tag_h4: 'Título 4',\r
+       tag_h5: 'Título 5',\r
+       tag_h6: 'Título 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatado'\r
+} );\r
diff --git a/sources/plugins/format/lang/ro.js b/sources/plugins/format/lang/ro.js
new file mode 100644 (file)
index 0000000..549a1b5
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ro', {\r
+       label: 'Formatare',\r
+       panelTitle: 'Formatare',\r
+       tag_address: 'Adresă',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatat'\r
+} );\r
diff --git a/sources/plugins/format/lang/ru.js b/sources/plugins/format/lang/ru.js
new file mode 100644 (file)
index 0000000..8e63455
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ru', {\r
+       label: 'Форматирование',\r
+       panelTitle: 'Форматирование',\r
+       tag_address: 'Адрес',\r
+       tag_div: 'Обычное (div)',\r
+       tag_h1: 'Заголовок 1',\r
+       tag_h2: 'Заголовок 2',\r
+       tag_h3: 'Заголовок 3',\r
+       tag_h4: 'Заголовок 4',\r
+       tag_h5: 'Заголовок 5',\r
+       tag_h6: 'Заголовок 6',\r
+       tag_p: 'Обычное',\r
+       tag_pre: 'Моноширинное'\r
+} );\r
diff --git a/sources/plugins/format/lang/si.js b/sources/plugins/format/lang/si.js
new file mode 100644 (file)
index 0000000..f27eb7f
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'si', {\r
+       label: 'ආකෘතිය',\r
+       panelTitle: 'චේදයේ ',\r
+       tag_address: 'ලිපිනය',\r
+       tag_div: 'සාමාන්‍ය(DIV)',\r
+       tag_h1: 'ශීර්ෂය 1',\r
+       tag_h2: 'ශීර්ෂය 2',\r
+       tag_h3: 'ශීර්ෂය 3',\r
+       tag_h4: 'ශීර්ෂය 4',\r
+       tag_h5: 'ශීර්ෂය 5',\r
+       tag_h6: 'ශීර්ෂය 6',\r
+       tag_p: 'සාමාන්‍ය',\r
+       tag_pre: 'ආකෘතියන්'\r
+} );\r
diff --git a/sources/plugins/format/lang/sk.js b/sources/plugins/format/lang/sk.js
new file mode 100644 (file)
index 0000000..30ca66c
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sk', {\r
+       label: 'Formát',\r
+       panelTitle: 'Odsek',\r
+       tag_address: 'Adresa',\r
+       tag_div: 'Normálny (DIV)',\r
+       tag_h1: 'Nadpis 1',\r
+       tag_h2: 'Nadpis 2',\r
+       tag_h3: 'Nadpis 3',\r
+       tag_h4: 'Nadpis 4',\r
+       tag_h5: 'Nadpis 5',\r
+       tag_h6: 'Nadpis 6',\r
+       tag_p: 'Normálny',\r
+       tag_pre: 'Formátovaný'\r
+} );\r
diff --git a/sources/plugins/format/lang/sl.js b/sources/plugins/format/lang/sl.js
new file mode 100644 (file)
index 0000000..2dad54f
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sl', {\r
+       label: 'Oblika',\r
+       panelTitle: 'Oblika odstavka',\r
+       tag_address: 'Napis',\r
+       tag_div: 'Navaden (DIV)',\r
+       tag_h1: 'Naslov 1',\r
+       tag_h2: 'Naslov 2',\r
+       tag_h3: 'Naslov 3',\r
+       tag_h4: 'Naslov 4',\r
+       tag_h5: 'Naslov 5',\r
+       tag_h6: 'Naslov 6',\r
+       tag_p: 'Navaden',\r
+       tag_pre: 'Oblikovan'\r
+} );\r
diff --git a/sources/plugins/format/lang/sq.js b/sources/plugins/format/lang/sq.js
new file mode 100644 (file)
index 0000000..5ddb6ef
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sq', {\r
+       label: 'Formati',\r
+       panelTitle: 'Formati i Paragrafit',\r
+       tag_address: 'Adresa',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Titulli 1',\r
+       tag_h2: 'Titulli 2',\r
+       tag_h3: 'Titulli 3',\r
+       tag_h4: 'Titulli 4',\r
+       tag_h5: 'Titulli 5',\r
+       tag_h6: 'Titulli 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatuar'\r
+} );\r
diff --git a/sources/plugins/format/lang/sr-latn.js b/sources/plugins/format/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..d971950
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sr-latn', {\r
+       label: 'Format',\r
+       panelTitle: 'Format',\r
+       tag_address: 'Adresa',\r
+       tag_div: 'Normalno (DIV)',\r
+       tag_h1: 'Naslov 1',\r
+       tag_h2: 'Naslov 2',\r
+       tag_h3: 'Naslov 3',\r
+       tag_h4: 'Naslov 4',\r
+       tag_h5: 'Naslov 5',\r
+       tag_h6: 'Naslov 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatirano'\r
+} );\r
diff --git a/sources/plugins/format/lang/sr.js b/sources/plugins/format/lang/sr.js
new file mode 100644 (file)
index 0000000..012a14d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sr', {\r
+       label: 'Формат',\r
+       panelTitle: 'Формат',\r
+       tag_address: 'Adresa',\r
+       tag_div: 'Нормално (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatirano'\r
+} );\r
diff --git a/sources/plugins/format/lang/sv.js b/sources/plugins/format/lang/sv.js
new file mode 100644 (file)
index 0000000..31850e0
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'sv', {\r
+       label: 'Teckenformat',\r
+       panelTitle: 'Teckenformat',\r
+       tag_address: 'Adress',\r
+       tag_div: 'Normal (DIV)',\r
+       tag_h1: 'Rubrik 1',\r
+       tag_h2: 'Rubrik 2',\r
+       tag_h3: 'Rubrik 3',\r
+       tag_h4: 'Rubrik 4',\r
+       tag_h5: 'Rubrik 5',\r
+       tag_h6: 'Rubrik 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formaterad'\r
+} );\r
diff --git a/sources/plugins/format/lang/th.js b/sources/plugins/format/lang/th.js
new file mode 100644 (file)
index 0000000..4c8a1d2
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'th', {\r
+       label: 'รูปแบบ',\r
+       panelTitle: 'รูปแบบ',\r
+       tag_address: 'Address',\r
+       tag_div: 'Paragraph (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Formatted'\r
+} );\r
diff --git a/sources/plugins/format/lang/tr.js b/sources/plugins/format/lang/tr.js
new file mode 100644 (file)
index 0000000..2de6ce2
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'tr', {\r
+       label: 'Biçim',\r
+       panelTitle: 'Biçim',\r
+       tag_address: 'Adres',\r
+       tag_div: 'Paragraf (DIV)',\r
+       tag_h1: 'Başlık 1',\r
+       tag_h2: 'Başlık 2',\r
+       tag_h3: 'Başlık 3',\r
+       tag_h4: 'Başlık 4',\r
+       tag_h5: 'Başlık 5',\r
+       tag_h6: 'Başlık 6',\r
+       tag_p: 'Normal',\r
+       tag_pre: 'Biçimli'\r
+} );\r
diff --git a/sources/plugins/format/lang/tt.js b/sources/plugins/format/lang/tt.js
new file mode 100644 (file)
index 0000000..160a192
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'tt', {\r
+       label: 'Форматлау',\r
+       panelTitle: 'Параграф форматлавы',\r
+       tag_address: 'Адрес',\r
+       tag_div: 'Гади (DIV)',\r
+       tag_h1: 'Башлам 1',\r
+       tag_h2: 'Башлам 2',\r
+       tag_h3: 'Башлам 3',\r
+       tag_h4: 'Башлам 4',\r
+       tag_h5: 'Башлам 5',\r
+       tag_h6: 'Башлам 6',\r
+       tag_p: 'Гади',\r
+       tag_pre: 'Форматлаулы'\r
+} );\r
diff --git a/sources/plugins/format/lang/ug.js b/sources/plugins/format/lang/ug.js
new file mode 100644 (file)
index 0000000..0be2a15
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'ug', {\r
+       label: 'پىچىم',\r
+       panelTitle: 'پىچىم',\r
+       tag_address: 'ئادرېس',\r
+       tag_div: 'ئابزاس (DIV)',\r
+       tag_h1: 'ماۋزۇ 1',\r
+       tag_h2: 'ماۋزۇ 2',\r
+       tag_h3: 'ماۋزۇ 3',\r
+       tag_h4: 'ماۋزۇ 4',\r
+       tag_h5: 'ماۋزۇ 5',\r
+       tag_h6: 'ماۋزۇ 6',\r
+       tag_p: 'ئادەتتىكى',\r
+       tag_pre: 'تىزىلغان پىچىم'\r
+} );\r
diff --git a/sources/plugins/format/lang/uk.js b/sources/plugins/format/lang/uk.js
new file mode 100644 (file)
index 0000000..2e2726d
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'uk', {\r
+       label: 'Форматування',\r
+       panelTitle: 'Форматування параграфа',\r
+       tag_address: 'Адреса',\r
+       tag_div: 'Нормальний (div)',\r
+       tag_h1: 'Заголовок 1',\r
+       tag_h2: 'Заголовок 2',\r
+       tag_h3: 'Заголовок 3',\r
+       tag_h4: 'Заголовок 4',\r
+       tag_h5: 'Заголовок 5',\r
+       tag_h6: 'Заголовок 6',\r
+       tag_p: 'Нормальний',\r
+       tag_pre: 'Форматований'\r
+} );\r
diff --git a/sources/plugins/format/lang/vi.js b/sources/plugins/format/lang/vi.js
new file mode 100644 (file)
index 0000000..d051440
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'vi', {\r
+       label: 'Định dạng',\r
+       panelTitle: 'Định dạng',\r
+       tag_address: 'Address',\r
+       tag_div: 'Bình thường (DIV)',\r
+       tag_h1: 'Heading 1',\r
+       tag_h2: 'Heading 2',\r
+       tag_h3: 'Heading 3',\r
+       tag_h4: 'Heading 4',\r
+       tag_h5: 'Heading 5',\r
+       tag_h6: 'Heading 6',\r
+       tag_p: 'Bình thường (P)',\r
+       tag_pre: 'Đã thiết lập'\r
+} );\r
diff --git a/sources/plugins/format/lang/zh-cn.js b/sources/plugins/format/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..addaa23
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'zh-cn', {\r
+       label: '格式',\r
+       panelTitle: '格式',\r
+       tag_address: '地址',\r
+       tag_div: '段落(DIV)',\r
+       tag_h1: '标题 1',\r
+       tag_h2: '标题 2',\r
+       tag_h3: '标题 3',\r
+       tag_h4: '标题 4',\r
+       tag_h5: '标题 5',\r
+       tag_h6: '标题 6',\r
+       tag_p: '普通',\r
+       tag_pre: '已编排格式'\r
+} );\r
diff --git a/sources/plugins/format/lang/zh.js b/sources/plugins/format/lang/zh.js
new file mode 100644 (file)
index 0000000..bb044ad
--- /dev/null
@@ -0,0 +1,18 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'format', 'zh', {\r
+       label: '格式',\r
+       panelTitle: '段落格式',\r
+       tag_address: '地址',\r
+       tag_div: '標準 (DIV)',\r
+       tag_h1: '標題 1',\r
+       tag_h2: '標題 2',\r
+       tag_h3: '標題 3',\r
+       tag_h4: '標題 4',\r
+       tag_h5: '標題 5',\r
+       tag_h6: '標題 6',\r
+       tag_p: '標準',\r
+       tag_pre: '格式設定'\r
+} );\r
diff --git a/sources/plugins/format/plugin.js b/sources/plugins/format/plugin.js
new file mode 100644 (file)
index 0000000..826cbcf
--- /dev/null
@@ -0,0 +1,279 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'format', {\r
+       requires: 'richcombo',\r
+       // jscs:disable maximumLineLength\r
+       lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+       // jscs:enable maximumLineLength\r
+       init: function( editor ) {\r
+               if ( editor.blockless )\r
+                       return;\r
+\r
+               var config = editor.config,\r
+                       lang = editor.lang.format;\r
+\r
+               // Gets the list of tags from the settings.\r
+               var tags = config.format_tags.split( ';' );\r
+\r
+               // Create style objects for all defined styles.\r
+               var styles = {},\r
+                       stylesCount = 0,\r
+                       allowedContent = [];\r
+               for ( var i = 0; i < tags.length; i++ ) {\r
+                       var tag = tags[ i ];\r
+                       var style = new CKEDITOR.style( config[ 'format_' + tag ] );\r
+                       if ( !editor.filter.customConfig || editor.filter.check( style ) ) {\r
+                               stylesCount++;\r
+                               styles[ tag ] = style;\r
+                               styles[ tag ]._.enterMode = editor.config.enterMode;\r
+                               allowedContent.push( style );\r
+                       }\r
+               }\r
+\r
+               // Hide entire combo when all formats are rejected.\r
+               if ( stylesCount === 0 )\r
+                       return;\r
+\r
+               editor.ui.addRichCombo( 'Format', {\r
+                       label: lang.label,\r
+                       title: lang.panelTitle,\r
+                       toolbar: 'styles,20',\r
+                       allowedContent: allowedContent,\r
+\r
+                       panel: {\r
+                               css: [ CKEDITOR.skin.getPath( 'editor' ) ].concat( config.contentsCss ),\r
+                               multiSelect: false,\r
+                               attributes: { 'aria-label': lang.panelTitle }\r
+                       },\r
+\r
+                       init: function() {\r
+                               this.startGroup( lang.panelTitle );\r
+\r
+                               for ( var tag in styles ) {\r
+                                       var label = lang[ 'tag_' + tag ];\r
+\r
+                                       // Add the tag entry to the panel list.\r
+                                       this.add( tag, styles[ tag ].buildPreview( label ), label );\r
+                               }\r
+                       },\r
+\r
+                       onClick: function( value ) {\r
+                               editor.focus();\r
+                               editor.fire( 'saveSnapshot' );\r
+\r
+                               var style = styles[ value ],\r
+                                       elementPath = editor.elementPath();\r
+\r
+                               editor[ style.checkActive( elementPath, editor ) ? 'removeStyle' : 'applyStyle' ]( style );\r
+\r
+                               // Save the undo snapshot after all changes are affected. (#4899)\r
+                               setTimeout( function() {\r
+                                       editor.fire( 'saveSnapshot' );\r
+                               }, 0 );\r
+                       },\r
+\r
+                       onRender: function() {\r
+                               editor.on( 'selectionChange', function( ev ) {\r
+                                       var currentTag = this.getValue(),\r
+                                               elementPath = ev.data.path;\r
+\r
+                                       this.refresh();\r
+\r
+                                       for ( var tag in styles ) {\r
+                                               if ( styles[ tag ].checkActive( elementPath, editor ) ) {\r
+                                                       if ( tag != currentTag )\r
+                                                               this.setValue( tag, editor.lang.format[ 'tag_' + tag ] );\r
+                                                       return;\r
+                                               }\r
+                                       }\r
+\r
+                                       // If no styles match, just empty it.\r
+                                       this.setValue( '' );\r
+\r
+                               }, this );\r
+                       },\r
+\r
+                       onOpen: function() {\r
+                               this.showAll();\r
+                               for ( var name in styles ) {\r
+                                       var style = styles[ name ];\r
+\r
+                                       // Check if that style is enabled in activeFilter.\r
+                                       if ( !editor.activeFilter.check( style ) )\r
+                                               this.hideItem( name );\r
+\r
+                               }\r
+                       },\r
+\r
+                       refresh: function() {\r
+                               var elementPath = editor.elementPath();\r
+\r
+                               if ( !elementPath )\r
+                                               return;\r
+\r
+                               // Check if element path contains 'p' element.\r
+                               if ( !elementPath.isContextFor( 'p' ) ) {\r
+                                       this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+                                       return;\r
+                               }\r
+\r
+                               // Check if there is any available style.\r
+                               for ( var name in styles ) {\r
+                                       if ( editor.activeFilter.check( styles[ name ] ) )\r
+                                               return;\r
+                               }\r
+                               this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+                       }\r
+               } );\r
+       }\r
+} );\r
+\r
+/**\r
+ * A list of semicolon-separated style names (by default: tags) representing\r
+ * the style definition for each entry to be displayed in the Format drop-down list\r
+ * in the toolbar. Each entry must have a corresponding configuration in a\r
+ * setting named `'format_(tagName)'`. For example, the `'p'` entry has its\r
+ * definition taken from [config.format_p](#!/api/CKEDITOR.config-cfg-format_p).\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_tags = 'p;h2;h3;pre';\r
+ *\r
+ * @cfg {String} [format_tags='p;h1;h2;h3;h4;h5;h6;pre;address;div']\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_tags = 'p;h1;h2;h3;h4;h5;h6;pre;address;div';\r
+\r
+/**\r
+ * The style definition to be used to apply the `Normal` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_p = { element: 'p', attributes: { 'class': 'normalPara' } };\r
+ *\r
+ * @cfg {Object} [format_p={ element: 'p' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_p = { element: 'p' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Normal (DIV)` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_div = { element: 'div', attributes: { 'class': 'normalDiv' } };\r
+ *\r
+ * @cfg {Object} [format_div={ element: 'div' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_div = { element: 'div' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Formatted` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_pre = { element: 'pre', attributes: { 'class': 'code' } };\r
+ *\r
+ * @cfg {Object} [format_pre={ element: 'pre' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_pre = { element: 'pre' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Address` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_address = { element: 'address', attributes: { 'class': 'styledAddress' } };\r
+ *\r
+ * @cfg {Object} [format_address={ element: 'address' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_address = { element: 'address' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 1` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h1 = { element: 'h1', attributes: { 'class': 'contentTitle1' } };\r
+ *\r
+ * @cfg {Object} [format_h1={ element: 'h1' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h1 = { element: 'h1' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 2` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h2 = { element: 'h2', attributes: { 'class': 'contentTitle2' } };\r
+ *\r
+ * @cfg {Object} [format_h2={ element: 'h2' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h2 = { element: 'h2' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 3` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h3 = { element: 'h3', attributes: { 'class': 'contentTitle3' } };\r
+ *\r
+ * @cfg {Object} [format_h3={ element: 'h3' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h3 = { element: 'h3' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 4` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h4 = { element: 'h4', attributes: { 'class': 'contentTitle4' } };\r
+ *\r
+ * @cfg {Object} [format_h4={ element: 'h4' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h4 = { element: 'h4' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 5` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h5 = { element: 'h5', attributes: { 'class': 'contentTitle5' } };\r
+ *\r
+ * @cfg {Object} [format_h5={ element: 'h5' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h5 = { element: 'h5' };\r
+\r
+/**\r
+ * The style definition to be used to apply the `Heading 6` format.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_format)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/format.html).\r
+ *\r
+ *             config.format_h6 = { element: 'h6', attributes: { 'class': 'contentTitle6' } };\r
+ *\r
+ * @cfg {Object} [format_h6={ element: 'h6' }]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.format_h6 = { element: 'h6' };\r
diff --git a/sources/plugins/horizontalrule/icons/hidpi/horizontalrule.png b/sources/plugins/horizontalrule/icons/hidpi/horizontalrule.png
new file mode 100644 (file)
index 0000000..ad97e09
Binary files /dev/null and b/sources/plugins/horizontalrule/icons/hidpi/horizontalrule.png differ
diff --git a/sources/plugins/horizontalrule/icons/horizontalrule.png b/sources/plugins/horizontalrule/icons/horizontalrule.png
new file mode 100644 (file)
index 0000000..0592614
Binary files /dev/null and b/sources/plugins/horizontalrule/icons/horizontalrule.png differ
diff --git a/sources/plugins/horizontalrule/lang/af.js b/sources/plugins/horizontalrule/lang/af.js
new file mode 100644 (file)
index 0000000..9232187
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'af', {\r
+       toolbar: 'Horisontale lyn invoeg'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ar.js b/sources/plugins/horizontalrule/lang/ar.js
new file mode 100644 (file)
index 0000000..edf9101
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ar', {\r
+       toolbar: 'خط فاصل'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/az.js b/sources/plugins/horizontalrule/lang/az.js
new file mode 100644 (file)
index 0000000..2343630
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'az', {\r
+       toolbar: 'Sərhəd xətti yarat'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/bg.js b/sources/plugins/horizontalrule/lang/bg.js
new file mode 100644 (file)
index 0000000..b20914c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'bg', {\r
+       toolbar: 'Вмъкване на хоризонтална линия'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/bn.js b/sources/plugins/horizontalrule/lang/bn.js
new file mode 100644 (file)
index 0000000..d846125
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'bn', {\r
+       toolbar: 'অনুভূমিক লাইন যোগ করি'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/bs.js b/sources/plugins/horizontalrule/lang/bs.js
new file mode 100644 (file)
index 0000000..3917873
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'bs', {\r
+       toolbar: 'Ubaci horizontalnu liniju'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ca.js b/sources/plugins/horizontalrule/lang/ca.js
new file mode 100644 (file)
index 0000000..81d9457
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ca', {\r
+       toolbar: 'Insereix línia horitzontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/cs.js b/sources/plugins/horizontalrule/lang/cs.js
new file mode 100644 (file)
index 0000000..5178139
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'cs', {\r
+       toolbar: 'Vložit vodorovnou linku'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/cy.js b/sources/plugins/horizontalrule/lang/cy.js
new file mode 100644 (file)
index 0000000..df74af5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'cy', {\r
+       toolbar: 'Mewnosod Llinell Lorweddol'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/da.js b/sources/plugins/horizontalrule/lang/da.js
new file mode 100644 (file)
index 0000000..cd8cb2a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'da', {\r
+       toolbar: 'Indsæt vandret streg'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/de-ch.js b/sources/plugins/horizontalrule/lang/de-ch.js
new file mode 100644 (file)
index 0000000..64230b5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'de-ch', {\r
+       toolbar: 'Horizontale Linie einfügen'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/de.js b/sources/plugins/horizontalrule/lang/de.js
new file mode 100644 (file)
index 0000000..a1705a6
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'de', {\r
+       toolbar: 'Horizontale Linie einfügen'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/el.js b/sources/plugins/horizontalrule/lang/el.js
new file mode 100644 (file)
index 0000000..d281f47
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'el', {\r
+       toolbar: 'Εισαγωγή Οριζόντιας Γραμμής'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/en-au.js b/sources/plugins/horizontalrule/lang/en-au.js
new file mode 100644 (file)
index 0000000..0548518
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'en-au', {\r
+       toolbar: 'Insert Horizontal Line'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/en-ca.js b/sources/plugins/horizontalrule/lang/en-ca.js
new file mode 100644 (file)
index 0000000..feab44d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'en-ca', {\r
+       toolbar: 'Insert Horizontal Line'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/en-gb.js b/sources/plugins/horizontalrule/lang/en-gb.js
new file mode 100644 (file)
index 0000000..5cf987f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'en-gb', {\r
+       toolbar: 'Insert Horizontal Line'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/en.js b/sources/plugins/horizontalrule/lang/en.js
new file mode 100644 (file)
index 0000000..6c750d1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'en', {\r
+       toolbar: 'Insert Horizontal Line'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/eo.js b/sources/plugins/horizontalrule/lang/eo.js
new file mode 100644 (file)
index 0000000..f2ddd72
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'eo', {\r
+       toolbar: 'Enmeti Horizontalan Linion'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/es.js b/sources/plugins/horizontalrule/lang/es.js
new file mode 100644 (file)
index 0000000..ac42e14
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'es', {\r
+       toolbar: 'Insertar Línea Horizontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/et.js b/sources/plugins/horizontalrule/lang/et.js
new file mode 100644 (file)
index 0000000..156b1c1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'et', {\r
+       toolbar: 'Horisontaaljoone sisestamine'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/eu.js b/sources/plugins/horizontalrule/lang/eu.js
new file mode 100644 (file)
index 0000000..7eeabb8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'eu', {\r
+       toolbar: 'Txertatu marra horizontala'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/fa.js b/sources/plugins/horizontalrule/lang/fa.js
new file mode 100644 (file)
index 0000000..f18d1d0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'fa', {\r
+       toolbar: 'گنجاندن خط افقی'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/fi.js b/sources/plugins/horizontalrule/lang/fi.js
new file mode 100644 (file)
index 0000000..c18cd70
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'fi', {\r
+       toolbar: 'Lisää murtoviiva'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/fo.js b/sources/plugins/horizontalrule/lang/fo.js
new file mode 100644 (file)
index 0000000..d0d3bea
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'fo', {\r
+       toolbar: 'Ger vatnrætta linju'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/fr-ca.js b/sources/plugins/horizontalrule/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..a232a14
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'fr-ca', {\r
+       toolbar: 'Insérer un séparateur horizontale'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/fr.js b/sources/plugins/horizontalrule/lang/fr.js
new file mode 100644 (file)
index 0000000..c0c6322
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'fr', {\r
+       toolbar: 'Ligne horizontale'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/gl.js b/sources/plugins/horizontalrule/lang/gl.js
new file mode 100644 (file)
index 0000000..6215e71
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'gl', {\r
+       toolbar: 'Inserir unha liña horizontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/gu.js b/sources/plugins/horizontalrule/lang/gu.js
new file mode 100644 (file)
index 0000000..f6abc17
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'gu', {\r
+       toolbar: 'સમસ્તરીય રેખા ઇન્સર્ટ/દાખલ કરવી'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/he.js b/sources/plugins/horizontalrule/lang/he.js
new file mode 100644 (file)
index 0000000..56c4ebd
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'he', {\r
+       toolbar: 'הוספת קו אופקי'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/hi.js b/sources/plugins/horizontalrule/lang/hi.js
new file mode 100644 (file)
index 0000000..1d576c2
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'hi', {\r
+       toolbar: 'हॉरिज़ॉन्टल रेखा इन्सर्ट करें'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/hr.js b/sources/plugins/horizontalrule/lang/hr.js
new file mode 100644 (file)
index 0000000..53d80f3
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'hr', {\r
+       toolbar: 'Ubaci vodoravnu liniju'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/hu.js b/sources/plugins/horizontalrule/lang/hu.js
new file mode 100644 (file)
index 0000000..31fcbfc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'hu', {\r
+       toolbar: 'Elválasztóvonal beillesztése'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/id.js b/sources/plugins/horizontalrule/lang/id.js
new file mode 100644 (file)
index 0000000..3d341ad
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'id', {\r
+       toolbar: 'Sisip Garis Horisontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/is.js b/sources/plugins/horizontalrule/lang/is.js
new file mode 100644 (file)
index 0000000..1515abc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'is', {\r
+       toolbar: 'Lóðrétt lína'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/it.js b/sources/plugins/horizontalrule/lang/it.js
new file mode 100644 (file)
index 0000000..c2e23fb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'it', {\r
+       toolbar: 'Inserisci riga orizzontale'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ja.js b/sources/plugins/horizontalrule/lang/ja.js
new file mode 100644 (file)
index 0000000..e174c32
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ja', {\r
+       toolbar: '水平線'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ka.js b/sources/plugins/horizontalrule/lang/ka.js
new file mode 100644 (file)
index 0000000..2c798c2
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ka', {\r
+       toolbar: 'ჰორიზონტალური ხაზის ჩასმა'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/km.js b/sources/plugins/horizontalrule/lang/km.js
new file mode 100644 (file)
index 0000000..8c8ab9f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'km', {\r
+       toolbar: 'បន្ថែមបន្ទាត់ផ្តេក'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ko.js b/sources/plugins/horizontalrule/lang/ko.js
new file mode 100644 (file)
index 0000000..69df02c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ko', {\r
+       toolbar: '가로 줄 삽입'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ku.js b/sources/plugins/horizontalrule/lang/ku.js
new file mode 100644 (file)
index 0000000..c8a0fa5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ku', {\r
+       toolbar: 'دانانی هێلی ئاسۆیی'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/lt.js b/sources/plugins/horizontalrule/lang/lt.js
new file mode 100644 (file)
index 0000000..86cbdaf
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'lt', {\r
+       toolbar: 'Įterpti horizontalią liniją'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/lv.js b/sources/plugins/horizontalrule/lang/lv.js
new file mode 100644 (file)
index 0000000..a227a00
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'lv', {\r
+       toolbar: 'Ievietot horizontālu Atdalītājsvītru'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/mk.js b/sources/plugins/horizontalrule/lang/mk.js
new file mode 100644 (file)
index 0000000..51efe3d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'mk', {\r
+       toolbar: 'Insert Horizontal Line' // MISSING\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/mn.js b/sources/plugins/horizontalrule/lang/mn.js
new file mode 100644 (file)
index 0000000..bd0ba0f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'mn', {\r
+       toolbar: 'Хөндлөн зураас оруулах'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ms.js b/sources/plugins/horizontalrule/lang/ms.js
new file mode 100644 (file)
index 0000000..fa22359
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ms', {\r
+       toolbar: 'Masukkan Garisan Membujur'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/nb.js b/sources/plugins/horizontalrule/lang/nb.js
new file mode 100644 (file)
index 0000000..7edefa5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'nb', {\r
+       toolbar: 'Sett inn horisontal linje'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/nl.js b/sources/plugins/horizontalrule/lang/nl.js
new file mode 100644 (file)
index 0000000..47efd3f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'nl', {\r
+       toolbar: 'Horizontale lijn invoegen'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/no.js b/sources/plugins/horizontalrule/lang/no.js
new file mode 100644 (file)
index 0000000..009fc4b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'no', {\r
+       toolbar: 'Sett inn horisontal linje'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/oc.js b/sources/plugins/horizontalrule/lang/oc.js
new file mode 100644 (file)
index 0000000..42d1797
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'oc', {\r
+       toolbar: 'Inserir una linha orizontala'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/pl.js b/sources/plugins/horizontalrule/lang/pl.js
new file mode 100644 (file)
index 0000000..0604f4d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'pl', {\r
+       toolbar: 'Wstaw poziomą linię'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/pt-br.js b/sources/plugins/horizontalrule/lang/pt-br.js
new file mode 100644 (file)
index 0000000..038616b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'pt-br', {\r
+       toolbar: 'Inserir Linha Horizontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/pt.js b/sources/plugins/horizontalrule/lang/pt.js
new file mode 100644 (file)
index 0000000..c8d710d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'pt', {\r
+       toolbar: 'Inserir linha horizontal'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ro.js b/sources/plugins/horizontalrule/lang/ro.js
new file mode 100644 (file)
index 0000000..4b8f9b8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ro', {\r
+       toolbar: 'Inserează linie orizontală'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ru.js b/sources/plugins/horizontalrule/lang/ru.js
new file mode 100644 (file)
index 0000000..5424765
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ru', {\r
+       toolbar: 'Вставить горизонтальную линию'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/si.js b/sources/plugins/horizontalrule/lang/si.js
new file mode 100644 (file)
index 0000000..b0bb9b1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'si', {\r
+       toolbar: 'තිරස් රේඛාවක් ඇතුලත් කරන්න'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sk.js b/sources/plugins/horizontalrule/lang/sk.js
new file mode 100644 (file)
index 0000000..07bce6c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sk', {\r
+       toolbar: 'Vložiť vodorovnú čiaru'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sl.js b/sources/plugins/horizontalrule/lang/sl.js
new file mode 100644 (file)
index 0000000..44e19ae
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sl', {\r
+       toolbar: 'Vstavi vodoravno črto'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sq.js b/sources/plugins/horizontalrule/lang/sq.js
new file mode 100644 (file)
index 0000000..9fa6a40
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sq', {\r
+       toolbar: 'Vendos Vijë Horizontale'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sr-latn.js b/sources/plugins/horizontalrule/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..eb16b98
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sr-latn', {\r
+       toolbar: 'Unesi horizontalnu liniju'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sr.js b/sources/plugins/horizontalrule/lang/sr.js
new file mode 100644 (file)
index 0000000..a260b4a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sr', {\r
+       toolbar: 'Унеси хоризонталну линију'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/sv.js b/sources/plugins/horizontalrule/lang/sv.js
new file mode 100644 (file)
index 0000000..bf6280f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'sv', {\r
+       toolbar: 'Infoga horisontal linje'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/th.js b/sources/plugins/horizontalrule/lang/th.js
new file mode 100644 (file)
index 0000000..164f496
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'th', {\r
+       toolbar: 'แทรกเส้นคั่นบรรทัด'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/tr.js b/sources/plugins/horizontalrule/lang/tr.js
new file mode 100644 (file)
index 0000000..aeb6fb8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'tr', {\r
+       toolbar: 'Yatay Satır Ekle'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/tt.js b/sources/plugins/horizontalrule/lang/tt.js
new file mode 100644 (file)
index 0000000..411166d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'tt', {\r
+       toolbar: 'Ятма сызык өстәү'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/ug.js b/sources/plugins/horizontalrule/lang/ug.js
new file mode 100644 (file)
index 0000000..92f2434
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'ug', {\r
+       toolbar: 'توغرا سىزىق قىستۇر'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/uk.js b/sources/plugins/horizontalrule/lang/uk.js
new file mode 100644 (file)
index 0000000..d84f428
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'uk', {\r
+       toolbar: 'Горизонтальна лінія'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/vi.js b/sources/plugins/horizontalrule/lang/vi.js
new file mode 100644 (file)
index 0000000..339eb06
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'vi', {\r
+       toolbar: 'Chèn đường phân cách ngang'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/zh-cn.js b/sources/plugins/horizontalrule/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..2dfdb50
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'zh-cn', {\r
+       toolbar: '插入水平线'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/lang/zh.js b/sources/plugins/horizontalrule/lang/zh.js
new file mode 100644 (file)
index 0000000..b2e4272
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'horizontalrule', 'zh', {\r
+       toolbar: '插入水平線'\r
+} );\r
diff --git a/sources/plugins/horizontalrule/plugin.js b/sources/plugins/horizontalrule/plugin.js
new file mode 100644 (file)
index 0000000..6e52c31
--- /dev/null
@@ -0,0 +1,43 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Horizontal Rule plugin.\r
+ */\r
+\r
+( function() {\r
+       var horizontalruleCmd = {\r
+               canUndo: false, // The undo snapshot will be handled by 'insertElement'.\r
+               exec: function( editor ) {\r
+                       var hr = editor.document.createElement( 'hr' );\r
+                       editor.insertElement( hr );\r
+               },\r
+\r
+               allowedContent: 'hr',\r
+               requiredContent: 'hr'\r
+       };\r
+\r
+       var pluginName = 'horizontalrule';\r
+\r
+       // Register a plugin named "horizontalrule".\r
+       CKEDITOR.plugins.add( pluginName, {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'horizontalrule', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       if ( editor.blockless )\r
+                               return;\r
+\r
+                       editor.addCommand( pluginName, horizontalruleCmd );\r
+                       editor.ui.addButton && editor.ui.addButton( 'HorizontalRule', {\r
+                               label: editor.lang.horizontalrule.toolbar,\r
+                               command: pluginName,\r
+                               toolbar: 'insert,40'\r
+                       } );\r
+               }\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/htmlwriter/plugin.js b/sources/plugins/htmlwriter/plugin.js
new file mode 100644 (file)
index 0000000..b6d2716
--- /dev/null
@@ -0,0 +1,360 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'htmlwriter', {\r
+       init: function( editor ) {\r
+               var writer = new CKEDITOR.htmlWriter();\r
+\r
+               writer.forceSimpleAmpersand = editor.config.forceSimpleAmpersand;\r
+               writer.indentationChars = editor.config.dataIndentationChars || '\t';\r
+\r
+               // Overwrite default basicWriter initialized in hmtlDataProcessor constructor.\r
+               editor.dataProcessor.writer = writer;\r
+       }\r
+} );\r
+\r
+/**\r
+ * The class used to write HTML data.\r
+ *\r
+ *             var writer = new CKEDITOR.htmlWriter();\r
+ *             writer.openTag( 'p' );\r
+ *             writer.attribute( 'class', 'MyClass' );\r
+ *             writer.openTagClose( 'p' );\r
+ *             writer.text( 'Hello' );\r
+ *             writer.closeTag( 'p' );\r
+ *             alert( writer.getHtml() ); // '<p class="MyClass">Hello</p>'\r
+ *\r
+ * @class\r
+ * @extends CKEDITOR.htmlParser.basicWriter\r
+ */\r
+CKEDITOR.htmlWriter = CKEDITOR.tools.createClass( {\r
+       base: CKEDITOR.htmlParser.basicWriter,\r
+\r
+       /**\r
+        * Creates an `htmlWriter` class instance.\r
+        *\r
+        * @constructor\r
+        */\r
+       $: function() {\r
+               // Call the base contructor.\r
+               this.base();\r
+\r
+               /**\r
+                * The characters to be used for each indentation step.\r
+                *\r
+                *              // Use tab for indentation.\r
+                *              editorInstance.dataProcessor.writer.indentationChars = '\t';\r
+                */\r
+               this.indentationChars = '\t';\r
+\r
+               /**\r
+                * The characters to be used to close "self-closing" elements, like `<br>` or `<img>`.\r
+                *\r
+                *              // Use HTML4 notation for self-closing elements.\r
+                *              editorInstance.dataProcessor.writer.selfClosingEnd = '>';\r
+                */\r
+               this.selfClosingEnd = ' />';\r
+\r
+               /**\r
+                * The characters to be used for line breaks.\r
+                *\r
+                *              // Use CRLF for line breaks.\r
+                *              editorInstance.dataProcessor.writer.lineBreakChars = '\r\n';\r
+                */\r
+               this.lineBreakChars = '\n';\r
+\r
+               this.sortAttributes = 1;\r
+\r
+               this._.indent = 0;\r
+               this._.indentation = '';\r
+               // Indicate preformatted block context status. (#5789)\r
+               this._.inPre = 0;\r
+               this._.rules = {};\r
+\r
+               var dtd = CKEDITOR.dtd;\r
+\r
+               for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {\r
+                       this.setRules( e, {\r
+                               indent: !dtd[ e ][ '#' ],\r
+                               breakBeforeOpen: 1,\r
+                               breakBeforeClose: !dtd[ e ][ '#' ],\r
+                               breakAfterClose: 1,\r
+                               needsSpace: ( e in dtd.$block ) && !( e in { li: 1, dt: 1, dd: 1 } )\r
+                       } );\r
+               }\r
+\r
+               this.setRules( 'br', { breakAfterOpen: 1 } );\r
+\r
+               this.setRules( 'title', {\r
+                       indent: 0,\r
+                       breakAfterOpen: 0\r
+               } );\r
+\r
+               this.setRules( 'style', {\r
+                       indent: 0,\r
+                       breakBeforeClose: 1\r
+               } );\r
+\r
+               this.setRules( 'pre', {\r
+                       breakAfterOpen: 1, // Keep line break after the opening tag\r
+                       indent: 0 // Disable indentation on <pre>.\r
+               } );\r
+       },\r
+\r
+       proto: {\r
+               /**\r
+                * Writes the tag opening part for an opener tag.\r
+                *\r
+                *              // Writes '<p'.\r
+                *              writer.openTag( 'p', { class : 'MyClass', id : 'MyId' } );\r
+                *\r
+                * @param {String} tagName The element name for this tag.\r
+                * @param {Object} attributes The attributes defined for this tag. The\r
+                * attributes could be used to inspect the tag.\r
+                */\r
+               openTag: function( tagName ) {\r
+                       var rules = this._.rules[ tagName ];\r
+\r
+                       if ( this._.afterCloser && rules && rules.needsSpace && this._.needsSpace )\r
+                               this._.output.push( '\n' );\r
+\r
+                       if ( this._.indent )\r
+                               this.indentation();\r
+                       // Do not break if indenting.\r
+                       else if ( rules && rules.breakBeforeOpen ) {\r
+                               this.lineBreak();\r
+                               this.indentation();\r
+                       }\r
+\r
+                       this._.output.push( '<', tagName );\r
+\r
+                       this._.afterCloser = 0;\r
+               },\r
+\r
+               /**\r
+                * Writes the tag closing part for an opener tag.\r
+                *\r
+                *              // Writes '>'.\r
+                *              writer.openTagClose( 'p', false );\r
+                *\r
+                *              // Writes ' />'.\r
+                *              writer.openTagClose( 'br', true );\r
+                *\r
+                * @param {String} tagName The element name for this tag.\r
+                * @param {Boolean} isSelfClose Indicates that this is a self-closing tag,\r
+                * like `<br>` or `<img>`.\r
+                */\r
+               openTagClose: function( tagName, isSelfClose ) {\r
+                       var rules = this._.rules[ tagName ];\r
+\r
+                       if ( isSelfClose ) {\r
+                               this._.output.push( this.selfClosingEnd );\r
+\r
+                               if ( rules && rules.breakAfterClose )\r
+                                       this._.needsSpace = rules.needsSpace;\r
+                       } else {\r
+                               this._.output.push( '>' );\r
+\r
+                               if ( rules && rules.indent )\r
+                                       this._.indentation += this.indentationChars;\r
+                       }\r
+\r
+                       if ( rules && rules.breakAfterOpen )\r
+                               this.lineBreak();\r
+                       tagName == 'pre' && ( this._.inPre = 1 );\r
+               },\r
+\r
+               /**\r
+                * Writes an attribute. This function should be called after opening the\r
+                * tag with {@link #openTagClose}.\r
+                *\r
+                *              // Writes ' class="MyClass"'.\r
+                *              writer.attribute( 'class', 'MyClass' );\r
+                *\r
+                * @param {String} attName The attribute name.\r
+                * @param {String} attValue The attribute value.\r
+                */\r
+               attribute: function( attName, attValue ) {\r
+\r
+                       if ( typeof attValue == 'string' ) {\r
+                               this.forceSimpleAmpersand && ( attValue = attValue.replace( /&amp;/g, '&' ) );\r
+                               // Browsers don't always escape special character in attribute values. (#4683, #4719).\r
+                               attValue = CKEDITOR.tools.htmlEncodeAttr( attValue );\r
+                       }\r
+\r
+                       this._.output.push( ' ', attName, '="', attValue, '"' );\r
+               },\r
+\r
+               /**\r
+                * Writes a closer tag.\r
+                *\r
+                *              // Writes '</p>'.\r
+                *              writer.closeTag( 'p' );\r
+                *\r
+                * @param {String} tagName The element name for this tag.\r
+                */\r
+               closeTag: function( tagName ) {\r
+                       var rules = this._.rules[ tagName ];\r
+\r
+                       if ( rules && rules.indent )\r
+                               this._.indentation = this._.indentation.substr( this.indentationChars.length );\r
+\r
+                       if ( this._.indent )\r
+                               this.indentation();\r
+                       // Do not break if indenting.\r
+                       else if ( rules && rules.breakBeforeClose ) {\r
+                               this.lineBreak();\r
+                               this.indentation();\r
+                       }\r
+\r
+                       this._.output.push( '</', tagName, '>' );\r
+                       tagName == 'pre' && ( this._.inPre = 0 );\r
+\r
+                       if ( rules && rules.breakAfterClose ) {\r
+                               this.lineBreak();\r
+                               this._.needsSpace = rules.needsSpace;\r
+                       }\r
+\r
+                       this._.afterCloser = 1;\r
+               },\r
+\r
+               /**\r
+                * Writes text.\r
+                *\r
+                *              // Writes 'Hello Word'.\r
+                *              writer.text( 'Hello Word' );\r
+                *\r
+                * @param {String} text The text value\r
+                */\r
+               text: function( text ) {\r
+                       if ( this._.indent ) {\r
+                               this.indentation();\r
+                               !this._.inPre && ( text = CKEDITOR.tools.ltrim( text ) );\r
+                       }\r
+\r
+                       this._.output.push( text );\r
+               },\r
+\r
+               /**\r
+                * Writes a comment.\r
+                *\r
+                *              // Writes "<!-- My comment -->".\r
+                *              writer.comment( ' My comment ' );\r
+                *\r
+                * @param {String} comment The comment text.\r
+                */\r
+               comment: function( comment ) {\r
+                       if ( this._.indent )\r
+                               this.indentation();\r
+\r
+                       this._.output.push( '<!--', comment, '-->' );\r
+               },\r
+\r
+               /**\r
+                * Writes a line break. It uses the {@link #lineBreakChars} property for it.\r
+                *\r
+                *              // Writes '\n' (e.g.).\r
+                *              writer.lineBreak();\r
+                */\r
+               lineBreak: function() {\r
+                       if ( !this._.inPre && this._.output.length > 0 )\r
+                               this._.output.push( this.lineBreakChars );\r
+                       this._.indent = 1;\r
+               },\r
+\r
+               /**\r
+                * Writes the current indentation character. It uses the {@link #indentationChars}\r
+                * property, repeating it for the current indentation steps.\r
+                *\r
+                *              // Writes '\t' (e.g.).\r
+                *              writer.indentation();\r
+                */\r
+               indentation: function() {\r
+                       if ( !this._.inPre && this._.indentation )\r
+                               this._.output.push( this._.indentation );\r
+                       this._.indent = 0;\r
+               },\r
+\r
+               /**\r
+                * Empties the current output buffer. It also brings back the default\r
+                * values of the writer flags.\r
+                *\r
+                *              writer.reset();\r
+                */\r
+               reset: function() {\r
+                       this._.output = [];\r
+                       this._.indent = 0;\r
+                       this._.indentation = '';\r
+                       this._.afterCloser = 0;\r
+                       this._.inPre = 0;\r
+                       this._.needsSpace = 0;\r
+               },\r
+\r
+               /**\r
+                * Sets formatting rules for a given element. Possible rules are:\r
+                *\r
+                * * `indent` &ndash; indent the element content.\r
+                * * `breakBeforeOpen` &ndash; break line before the opener tag for this element.\r
+                * * `breakAfterOpen` &ndash; break line after the opener tag for this element.\r
+                * * `breakBeforeClose` &ndash; break line before the closer tag for this element.\r
+                * * `breakAfterClose` &ndash; break line after the closer tag for this element.\r
+                *\r
+                * All rules default to `false`. Each function call overrides rules that are\r
+                * already present, leaving the undefined ones untouched.\r
+                *\r
+                * By default, all elements available in the {@link CKEDITOR.dtd#$block},\r
+                * {@link CKEDITOR.dtd#$listItem}, and {@link CKEDITOR.dtd#$tableContent}\r
+                * lists have all the above rules set to `true`. Additionaly, the `<br>`\r
+                * element has the `breakAfterOpen` rule set to `true`.\r
+                *\r
+                *              // Break line before and after "img" tags.\r
+                *              writer.setRules( 'img', {\r
+                *                      breakBeforeOpen: true\r
+                *                      breakAfterOpen: true\r
+                *              } );\r
+                *\r
+                *              // Reset the rules for the "h1" tag.\r
+                *              writer.setRules( 'h1', {} );\r
+                *\r
+                * @param {String} tagName The name of the element for which the rules are set.\r
+                * @param {Object} rules An object containing the element rules.\r
+                */\r
+               setRules: function( tagName, rules ) {\r
+                       var currentRules = this._.rules[ tagName ];\r
+\r
+                       if ( currentRules )\r
+                               CKEDITOR.tools.extend( currentRules, rules, true );\r
+                       else\r
+                               this._.rules[ tagName ] = rules;\r
+               }\r
+       }\r
+} );\r
+\r
+/**\r
+ * Whether to force using `'&'` instead of `'&amp;'` in element attributes\r
+ * values. It is not recommended to change this setting for compliance with the\r
+ * W3C XHTML 1.0 standards ([C.12, XHTML 1.0](http://www.w3.org/TR/xhtml1/#C_12)).\r
+ *\r
+ *             // Use `'&'` instead of `'&amp;'`\r
+ *             CKEDITOR.config.forceSimpleAmpersand = true;\r
+ *\r
+ * @cfg {Boolean} [forceSimpleAmpersand=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The characters to be used for indenting HTML output produced by the editor.\r
+ * Using characters different from `' '` (space) and `'\t'` (tab) is not recommended\r
+ * as it will mess the code.\r
+ *\r
+ *             // No indentation.\r
+ *             CKEDITOR.config.dataIndentationChars = '';\r
+ *\r
+ *             // Use two spaces for indentation.\r
+ *             CKEDITOR.config.dataIndentationChars = '  ';\r
+ *\r
+ * @cfg {String} [dataIndentationChars='\t']\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.fla b/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.fla
new file mode 100644 (file)
index 0000000..27e68cc
Binary files /dev/null and b/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.fla differ
diff --git a/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.swf b/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.swf
new file mode 100644 (file)
index 0000000..dbe17b6
Binary files /dev/null and b/sources/plugins/htmlwriter/samples/assets/outputforflash/outputforflash.swf differ
diff --git a/sources/plugins/htmlwriter/samples/assets/outputforflash/swfobject.js b/sources/plugins/htmlwriter/samples/assets/outputforflash/swfobject.js
new file mode 100644 (file)
index 0000000..90cdcc9
--- /dev/null
@@ -0,0 +1,5 @@
+\r
+/*     SWFObject v2.2 <http://code.google.com/p/swfobject/>\r
+       is released under the MIT License <http://www.opensource.org/licenses/mit-license.php>\r
+*/\r
+var swfobject=function(){var D="undefined",r="object",S="Shockwave Flash",W="ShockwaveFlash.ShockwaveFlash",q="application/x-shockwave-flash",R="SWFObjectExprInst",x="onreadystatechange",O=window,j=document,t=navigator,T=false,U=[h],o=[],N=[],I=[],l,Q,E,B,J=false,a=false,n,G,m=true,M=function(){var aa=typeof j.getElementById!=D&&typeof j.getElementsByTagName!=D&&typeof j.createElement!=D,ah=t.userAgent.toLowerCase(),Y=t.platform.toLowerCase(),ae=Y?/win/.test(Y):/win/.test(ah),ac=Y?/mac/.test(Y):/mac/.test(ah),af=/webkit/.test(ah)?parseFloat(ah.replace(/^.*webkit\/(\d+(\.\d+)?).*$/,"$1")):false,X=!+"\v1",ag=[0,0,0],ab=null;if(typeof t.plugins!=D&&typeof t.plugins[S]==r){ab=t.plugins[S].description;if(ab&&!(typeof t.mimeTypes!=D&&t.mimeTypes[q]&&!t.mimeTypes[q].enabledPlugin)){T=true;X=false;ab=ab.replace(/^.*\s+(\S+\s+\S+$)/,"$1");ag[0]=parseInt(ab.replace(/^(.*)\..*$/,"$1"),10);ag[1]=parseInt(ab.replace(/^.*\.(.*)\s.*$/,"$1"),10);ag[2]=/[a-zA-Z]/.test(ab)?parseInt(ab.replace(/^.*[a-zA-Z]+(.*)$/,"$1"),10):0}}else{if(typeof O.ActiveXObject!=D){try{var ad=new ActiveXObject(W);if(ad){ab=ad.GetVariable("$version");if(ab){X=true;ab=ab.split(" ")[1].split(",");ag=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}}catch(Z){}}}return{w3:aa,pv:ag,wk:af,ie:X,win:ae,mac:ac}}(),k=function(){if(!M.w3){return}if((typeof j.readyState!=D&&j.readyState=="complete")||(typeof j.readyState==D&&(j.getElementsByTagName("body")[0]||j.body))){f()}if(!J){if(typeof j.addEventListener!=D){j.addEventListener("DOMContentLoaded",f,false)}if(M.ie&&M.win){j.attachEvent(x,function(){if(j.readyState=="complete"){j.detachEvent(x,arguments.callee);f()}});if(O==top){(function(){if(J){return}try{j.documentElement.doScroll("left")}catch(X){setTimeout(arguments.callee,0);return}f()})()}}if(M.wk){(function(){if(J){return}if(!/loaded|complete/.test(j.readyState)){setTimeout(arguments.callee,0);return}f()})()}s(f)}}();function f(){if(J){return}try{var Z=j.getElementsByTagName("body")[0].appendChild(C("span"));Z.parentNode.removeChild(Z)}catch(aa){return}J=true;var X=U.length;for(var Y=0;Y<X;Y++){U[Y]()}}function K(X){if(J){X()}else{U[U.length]=X}}function s(Y){if(typeof O.addEventListener!=D){O.addEventListener("load",Y,false)}else{if(typeof j.addEventListener!=D){j.addEventListener("load",Y,false)}else{if(typeof O.attachEvent!=D){i(O,"onload",Y)}else{if(typeof O.onload=="function"){var X=O.onload;O.onload=function(){X();Y()}}else{O.onload=Y}}}}}function h(){if(T){V()}else{H()}}function V(){var X=j.getElementsByTagName("body")[0];var aa=C(r);aa.setAttribute("type",q);var Z=X.appendChild(aa);if(Z){var Y=0;(function(){if(typeof Z.GetVariable!=D){var ab=Z.GetVariable("$version");if(ab){ab=ab.split(" ")[1].split(",");M.pv=[parseInt(ab[0],10),parseInt(ab[1],10),parseInt(ab[2],10)]}}else{if(Y<10){Y++;setTimeout(arguments.callee,10);return}}X.removeChild(aa);Z=null;H()})()}else{H()}}function H(){var ag=o.length;if(ag>0){for(var af=0;af<ag;af++){var Y=o[af].id;var ab=o[af].callbackFn;var aa={success:false,id:Y};if(M.pv[0]>0){var ae=c(Y);if(ae){if(F(o[af].swfVersion)&&!(M.wk&&M.wk<312)){w(Y,true);if(ab){aa.success=true;aa.ref=z(Y);ab(aa)}}else{if(o[af].expressInstall&&A()){var ai={};ai.data=o[af].expressInstall;ai.width=ae.getAttribute("width")||"0";ai.height=ae.getAttribute("height")||"0";if(ae.getAttribute("class")){ai.styleclass=ae.getAttribute("class")}if(ae.getAttribute("align")){ai.align=ae.getAttribute("align")}var ah={};var X=ae.getElementsByTagName("param");var ac=X.length;for(var ad=0;ad<ac;ad++){if(X[ad].getAttribute("name").toLowerCase()!="movie"){ah[X[ad].getAttribute("name")]=X[ad].getAttribute("value")}}P(ai,ah,Y,ab)}else{p(ae);if(ab){ab(aa)}}}}}else{w(Y,true);if(ab){var Z=z(Y);if(Z&&typeof Z.SetVariable!=D){aa.success=true;aa.ref=Z}ab(aa)}}}}}function z(aa){var X=null;var Y=c(aa);if(Y&&Y.nodeName=="OBJECT"){if(typeof Y.SetVariable!=D){X=Y}else{var Z=Y.getElementsByTagName(r)[0];if(Z){X=Z}}}return X}function A(){return !a&&F("6.0.65")&&(M.win||M.mac)&&!(M.wk&&M.wk<312)}function P(aa,ab,X,Z){a=true;E=Z||null;B={success:false,id:X};var ae=c(X);if(ae){if(ae.nodeName=="OBJECT"){l=g(ae);Q=null}else{l=ae;Q=X}aa.id=R;if(typeof aa.width==D||(!/%$/.test(aa.width)&&parseInt(aa.width,10)<310)){aa.width="310"}if(typeof aa.height==D||(!/%$/.test(aa.height)&&parseInt(aa.height,10)<137)){aa.height="137"}j.title=j.title.slice(0,47)+" - Flash Player Installation";var ad=M.ie&&M.win?"ActiveX":"PlugIn",ac="MMredirectURL="+O.location.toString().replace(/&/g,"%26")+"&MMplayerType="+ad+"&MMdoctitle="+j.title;if(typeof ab.flashvars!=D){ab.flashvars+="&"+ac}else{ab.flashvars=ac}if(M.ie&&M.win&&ae.readyState!=4){var Y=C("div");X+="SWFObjectNew";Y.setAttribute("id",X);ae.parentNode.insertBefore(Y,ae);ae.style.display="none";(function(){if(ae.readyState==4){ae.parentNode.removeChild(ae)}else{setTimeout(arguments.callee,10)}})()}u(aa,ab,X)}}function p(Y){if(M.ie&&M.win&&Y.readyState!=4){var X=C("div");Y.parentNode.insertBefore(X,Y);X.parentNode.replaceChild(g(Y),X);Y.style.display="none";(function(){if(Y.readyState==4){Y.parentNode.removeChild(Y)}else{setTimeout(arguments.callee,10)}})()}else{Y.parentNode.replaceChild(g(Y),Y)}}function g(ab){var aa=C("div");if(M.win&&M.ie){aa.innerHTML=ab.innerHTML}else{var Y=ab.getElementsByTagName(r)[0];if(Y){var ad=Y.childNodes;if(ad){var X=ad.length;for(var Z=0;Z<X;Z++){if(!(ad[Z].nodeType==1&&ad[Z].nodeName=="PARAM")&&!(ad[Z].nodeType==8)){aa.appendChild(ad[Z].cloneNode(true))}}}}}return aa}function u(ai,ag,Y){var X,aa=c(Y);if(M.wk&&M.wk<312){return X}if(aa){if(typeof ai.id==D){ai.id=Y}if(M.ie&&M.win){var ah="";for(var ae in ai){if(ai[ae]!=Object.prototype[ae]){if(ae.toLowerCase()=="data"){ag.movie=ai[ae]}else{if(ae.toLowerCase()=="styleclass"){ah+=' class="'+ai[ae]+'"'}else{if(ae.toLowerCase()!="classid"){ah+=" "+ae+'="'+ai[ae]+'"'}}}}}var af="";for(var ad in ag){if(ag[ad]!=Object.prototype[ad]){af+='<param name="'+ad+'" value="'+ag[ad]+'" />'}}aa.outerHTML='<object classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"'+ah+">"+af+"</object>";N[N.length]=ai.id;X=c(ai.id)}else{var Z=C(r);Z.setAttribute("type",q);for(var ac in ai){if(ai[ac]!=Object.prototype[ac]){if(ac.toLowerCase()=="styleclass"){Z.setAttribute("class",ai[ac])}else{if(ac.toLowerCase()!="classid"){Z.setAttribute(ac,ai[ac])}}}}for(var ab in ag){if(ag[ab]!=Object.prototype[ab]&&ab.toLowerCase()!="movie"){e(Z,ab,ag[ab])}}aa.parentNode.replaceChild(Z,aa);X=Z}}return X}function e(Z,X,Y){var aa=C("param");aa.setAttribute("name",X);aa.setAttribute("value",Y);Z.appendChild(aa)}function y(Y){var X=c(Y);if(X&&X.nodeName=="OBJECT"){if(M.ie&&M.win){X.style.display="none";(function(){if(X.readyState==4){b(Y)}else{setTimeout(arguments.callee,10)}})()}else{X.parentNode.removeChild(X)}}}function b(Z){var Y=c(Z);if(Y){for(var X in Y){if(typeof Y[X]=="function"){Y[X]=null}}Y.parentNode.removeChild(Y)}}function c(Z){var X=null;try{X=j.getElementById(Z)}catch(Y){}return X}function C(X){return j.createElement(X)}function i(Z,X,Y){Z.attachEvent(X,Y);I[I.length]=[Z,X,Y]}function F(Z){var Y=M.pv,X=Z.split(".");X[0]=parseInt(X[0],10);X[1]=parseInt(X[1],10)||0;X[2]=parseInt(X[2],10)||0;return(Y[0]>X[0]||(Y[0]==X[0]&&Y[1]>X[1])||(Y[0]==X[0]&&Y[1]==X[1]&&Y[2]>=X[2]))?true:false}function v(ac,Y,ad,ab){if(M.ie&&M.mac){return}var aa=j.getElementsByTagName("head")[0];if(!aa){return}var X=(ad&&typeof ad=="string")?ad:"screen";if(ab){n=null;G=null}if(!n||G!=X){var Z=C("style");Z.setAttribute("type","text/css");Z.setAttribute("media",X);n=aa.appendChild(Z);if(M.ie&&M.win&&typeof j.styleSheets!=D&&j.styleSheets.length>0){n=j.styleSheets[j.styleSheets.length-1]}G=X}if(M.ie&&M.win){if(n&&typeof n.addRule==r){n.addRule(ac,Y)}}else{if(n&&typeof j.createTextNode!=D){n.appendChild(j.createTextNode(ac+" {"+Y+"}"))}}}function w(Z,X){if(!m){return}var Y=X?"visible":"hidden";if(J&&c(Z)){c(Z).style.visibility=Y}else{v("#"+Z,"visibility:"+Y)}}function L(Y){var Z=/[\\\"<>\.;]/;var X=Z.exec(Y)!=null;return X&&typeof encodeURIComponent!=D?encodeURIComponent(Y):Y}var d=function(){if(M.ie&&M.win){window.attachEvent("onunload",function(){var ac=I.length;for(var ab=0;ab<ac;ab++){I[ab][0].detachEvent(I[ab][1],I[ab][2])}var Z=N.length;for(var aa=0;aa<Z;aa++){y(N[aa])}for(var Y in M){M[Y]=null}M=null;for(var X in swfobject){swfobject[X]=null}swfobject=null})}}();return{registerObject:function(ab,X,aa,Z){if(M.w3&&ab&&X){var Y={};Y.id=ab;Y.swfVersion=X;Y.expressInstall=aa;Y.callbackFn=Z;o[o.length]=Y;w(ab,false)}else{if(Z){Z({success:false,id:ab})}}},getObjectById:function(X){if(M.w3){return z(X)}},embedSWF:function(ab,ah,ae,ag,Y,aa,Z,ad,af,ac){var X={success:false,id:ah};if(M.w3&&!(M.wk&&M.wk<312)&&ab&&ah&&ae&&ag&&Y){w(ah,false);K(function(){ae+="";ag+="";var aj={};if(af&&typeof af===r){for(var al in af){aj[al]=af[al]}}aj.data=ab;aj.width=ae;aj.height=ag;var am={};if(ad&&typeof ad===r){for(var ak in ad){am[ak]=ad[ak]}}if(Z&&typeof Z===r){for(var ai in Z){if(typeof am.flashvars!=D){am.flashvars+="&"+ai+"="+Z[ai]}else{am.flashvars=ai+"="+Z[ai]}}}if(F(Y)){var an=u(aj,am,ah);if(aj.id==ah){w(ah,true)}X.success=true;X.ref=an}else{if(aa&&A()){aj.data=aa;P(aj,am,ah,ac);return}else{w(ah,true)}}if(ac){ac(X)}})}else{if(ac){ac(X)}}},switchOffAutoHideShow:function(){m=false},ua:M,getFlashPlayerVersion:function(){return{major:M.pv[0],minor:M.pv[1],release:M.pv[2]}},hasFlashPlayerVersion:F,createSWF:function(Z,Y,X){if(M.w3){return u(Z,Y,X)}else{return undefined}},showExpressInstall:function(Z,aa,X,Y){if(M.w3&&A()){P(Z,aa,X,Y)}},removeSWF:function(X){if(M.w3){y(X)}},createCSS:function(aa,Z,Y,X){if(M.w3){v(aa,Z,Y,X)}},addDomLoadEvent:K,addLoadEvent:s,getQueryParamValue:function(aa){var Z=j.location.search||j.location.hash;if(Z){if(/\?/.test(Z)){Z=Z.split("?")[1]}if(aa==null){return L(Z)}var Y=Z.split("&");for(var X=0;X<Y.length;X++){if(Y[X].substring(0,Y[X].indexOf("="))==aa){return L(Y[X].substring((Y[X].indexOf("=")+1)))}}}return""},expressInstallCallback:function(){if(a){var X=c(R);if(X&&l){X.parentNode.replaceChild(l,X);if(Q){w(Q,true);if(M.ie&&M.win){l.style.display="block"}}if(E){E(B)}}a=false}}}}();\r
diff --git a/sources/plugins/htmlwriter/samples/outputforflash.html b/sources/plugins/htmlwriter/samples/outputforflash.html
new file mode 100644 (file)
index 0000000..f72616d
--- /dev/null
@@ -0,0 +1,283 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Output for Flash &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <script src="assets/outputforflash/swfobject.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Output for Flash">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to produce HTML code that can be used with Adobe Flash.">\r
+       <style>\r
+\r
+               .alert\r
+               {\r
+                       background: #ffa84c;\r
+                       padding: 10px 15px;\r
+                       font-weight: bold;\r
+                       display: block;\r
+                       margin-bottom: 20px;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Producing Flash Compliant HTML Output\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to output\r
+                       HTML code that can be used with\r
+                       <a class="samples" href="http://www.adobe.com/livedocs/flash/9.0/main/wwhelp/wwhimpl/common/html/wwhelp.htm?context=LiveDocs_Parts&amp;file=00000922.html">\r
+                       Adobe Flash</a>.\r
+                       The code will contain a subset of standard HTML elements like <code>&lt;b&gt;</code>,\r
+                       <code>&lt;i&gt;</code>, and <code>&lt;p&gt;</code> as well as HTML attributes.\r
+               </p>\r
+               <p>\r
+                       To add a CKEditor instance outputting Flash compliant HTML code, load the editor using a standard\r
+                       JavaScript call, and define CKEditor features to use HTML elements and attributes.\r
+               </p>\r
+               <p>\r
+                       For details on how to create this setup check the source code of this sample page.\r
+               </p>\r
+       </div>\r
+       <p>\r
+               To see how it works, create some content in the editing area of CKEditor on the left\r
+               and send it to the Flash object on the right side of the page by using the\r
+               <strong>Send to Flash</strong> button.\r
+       </p>\r
+       <table style="width: 100%; border-spacing: 0; border-collapse:collapse;">\r
+               <tr>\r
+                       <td style="width: 100%">\r
+                               <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;&lt;b&gt;&lt;font size=&quot;18&quot; style=&quot;font-size:18px;&quot;&gt;Flash and HTML&lt;/font&gt;&lt;/b&gt;&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;It is possible to have &lt;a href=&quot;http://ckeditor.com&quot;&gt;CKEditor&lt;/a&gt; creating content that will be later loaded inside &lt;b&gt;Flash&lt;/b&gt; objects and animations.&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;p&gt;Flash has a few limitations when dealing with HTML:&lt;/p&gt;&lt;p&gt;&amp;nbsp;&lt;/p&gt;&lt;ul&gt;&lt;li&gt;It has limited support on tags.&lt;/li&gt;&lt;li&gt;There is no margin between block elements, like paragraphs.&lt;/li&gt;&lt;/ul&gt;</textarea>\r
+                               <script>\r
+\r
+                                       if ( document.location.protocol == 'file:' )\r
+                                               alert( 'Warning: This samples does not work when loaded from local filesystem' +\r
+                                                       'due to security restrictions implemented in Flash.' +\r
+                                                       '\n\nPlease load the sample from a web server instead.' );\r
+\r
+                                       var editor = CKEDITOR.replace( 'editor1', {\r
+                                               /*\r
+                                                * Ensure that htmlwriter plugin, which is required for this sample, is loaded.\r
+                                                */\r
+                                               extraPlugins: 'htmlwriter',\r
+\r
+                                               height: 290,\r
+                                               width: '100%',\r
+                                               toolbar: [\r
+                                                       [ 'Source', '-', 'Bold', 'Italic', 'Underline', '-', 'BulletedList', '-', 'Link', 'Unlink' ],\r
+                                                       [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyBlock' ],\r
+                                                       '/',\r
+                                                       [ 'Font', 'FontSize' ],\r
+                                                       [ 'TextColor', '-', 'About' ]\r
+                                               ],\r
+\r
+                                               /*\r
+                                                * Style sheet for the contents\r
+                                                */\r
+                                               contentsCss: 'body {color:#000; background-color#FFF; font-family: Arial; font-size:80%;} p, ol, ul {margin-top: 0px; margin-bottom: 0px;}',\r
+\r
+                                               /*\r
+                                                * Quirks doctype\r
+                                                */\r
+                                               docType: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">',\r
+\r
+                                               /*\r
+                                                * Core styles.\r
+                                                */\r
+                                               coreStyles_bold: { element: 'b' },\r
+                                               coreStyles_italic: { element: 'i' },\r
+                                               coreStyles_underline: { element: 'u' },\r
+\r
+                                               /*\r
+                                                * Font face.\r
+                                                */\r
+\r
+                                               // Define the way font elements will be applied to the document. The "font"\r
+                                               // element will be used.\r
+                                               font_style: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'face': '#(family)' }\r
+                                               },\r
+\r
+                                               /*\r
+                                                * Font sizes.\r
+                                                */\r
+\r
+                                               // The CSS part of the font sizes isn't used by Flash, it is there to get the\r
+                                               // font rendered correctly in CKEditor.\r
+                                               fontSize_sizes: '8px/8;9px/9;10px/10;11px/11;12px/12;14px/14;16px/16;18px/18;20px/20;22px/22;24px/24;26px/26;28px/28;36px/36;48px/48;72px/72',\r
+                                               fontSize_style: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'size': '#(size)' },\r
+                                                       styles: { 'font-size': '#(size)px' }\r
+                                               } ,\r
+\r
+                                               /*\r
+                                                * Font colors.\r
+                                                */\r
+                                               colorButton_enableMore: true,\r
+\r
+                                               colorButton_foreStyle: {\r
+                                                       element: 'font',\r
+                                                       attributes: { 'color': '#(color)' }\r
+                                               },\r
+\r
+                                               colorButton_backStyle: {\r
+                                                       element: 'font',\r
+                                                       styles: { 'background-color': '#(color)' }\r
+                                               },\r
+\r
+                                               on: { 'instanceReady': configureFlashOutput }\r
+                                       });\r
+\r
+                                       /*\r
+                                        * Adjust the behavior of the dataProcessor to match the\r
+                                        * requirements of Flash\r
+                                        */\r
+                                       function configureFlashOutput( ev ) {\r
+                                               var editor = ev.editor,\r
+                                                       dataProcessor = editor.dataProcessor,\r
+                                                       htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
+                                               // Out self closing tags the HTML4 way, like <br>.\r
+                                               dataProcessor.writer.selfClosingEnd = '>';\r
+\r
+                                               // Make output formatting match Flash expectations\r
+                                               var dtd = CKEDITOR.dtd;\r
+                                               for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {\r
+                                                       dataProcessor.writer.setRules( e, {\r
+                                                               indent: false,\r
+                                                               breakBeforeOpen: false,\r
+                                                               breakAfterOpen: false,\r
+                                                               breakBeforeClose: false,\r
+                                                               breakAfterClose: false\r
+                                                       });\r
+                                               }\r
+                                               dataProcessor.writer.setRules( 'br', {\r
+                                                       indent: false,\r
+                                                       breakBeforeOpen: false,\r
+                                                       breakAfterOpen: false,\r
+                                                       breakBeforeClose: false,\r
+                                                       breakAfterClose: false\r
+                                               });\r
+\r
+                                               // Output properties as attributes, not styles.\r
+                                               htmlFilter.addRules( {\r
+                                                       elements: {\r
+                                                               $: function( element ) {\r
+                                                                       var style, match, width, height, align;\r
+\r
+                                                                       // Output dimensions of images as width and height\r
+                                                                       if ( element.name == 'img' ) {\r
+                                                                               style = element.attributes.style;\r
+\r
+                                                                               if ( style ) {\r
+                                                                                       // Get the width from the style.\r
+                                                                                       match = ( /(?:^|\s)width\s*:\s*(\d+)px/i ).exec( style );\r
+                                                                                       width = match && match[1];\r
+\r
+                                                                                       // Get the height from the style.\r
+                                                                                       match = ( /(?:^|\s)height\s*:\s*(\d+)px/i ).exec( style );\r
+                                                                                       height = match && match[1];\r
+\r
+                                                                                       if ( width ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)width\s*:\s*(\d+)px;?/i , '' );\r
+                                                                                               element.attributes.width = width;\r
+                                                                                       }\r
+\r
+                                                                                       if ( height ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)height\s*:\s*(\d+)px;?/i , '' );\r
+                                                                                               element.attributes.height = height;\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       // Output alignment of paragraphs using align\r
+                                                                       if ( element.name == 'p' ) {\r
+                                                                               style = element.attributes.style;\r
+\r
+                                                                               if ( style ) {\r
+                                                                                       // Get the align from the style.\r
+                                                                                       match = ( /(?:^|\s)text-align\s*:\s*(\w*);?/i ).exec( style );\r
+                                                                                       align = match && match[1];\r
+\r
+                                                                                       if ( align ) {\r
+                                                                                               element.attributes.style = element.attributes.style.replace( /(?:^|\s)text-align\s*:\s*(\w*);?/i , '' );\r
+                                                                                               element.attributes.align = align;\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       if ( element.attributes.style === '' )\r
+                                                                               delete element.attributes.style;\r
+\r
+                                                                       return element;\r
+                                                               }\r
+                                                       }\r
+                                               });\r
+                                       }\r
+\r
+                                       function sendToFlash() {\r
+                                               var html = CKEDITOR.instances.editor1.getData() ;\r
+\r
+                                               // Quick fix for link color.\r
+                                               html = html.replace( /<a /g, '<font color="#0000FF"><u><a ' )\r
+                                               html = html.replace( /<\/a>/g, '</a></u></font>' )\r
+\r
+                                               var flash = document.getElementById( 'ckFlashContainer' ) ;\r
+                                               flash.setData( html ) ;\r
+                                       }\r
+\r
+                                       CKEDITOR.domReady( function() {\r
+                                               if ( !swfobject.hasFlashPlayerVersion( '8' ) ) {\r
+                                                       CKEDITOR.dom.element.createFromHtml( '<span class="alert">' +\r
+                                                                       'At least Adobe Flash Player 8 is required to run this sample. ' +\r
+                                                                       'You can download it from <a href="http://get.adobe.com/flashplayer">Adobe\'s website</a>.' +\r
+                                                               '</span>' ).insertBefore( editor.element );\r
+                                               }\r
+\r
+                                               swfobject.embedSWF(\r
+                                                       'assets/outputforflash/outputforflash.swf',\r
+                                                       'ckFlashContainer',\r
+                                                       '550',\r
+                                                       '400',\r
+                                                       '8',\r
+                                                       { wmode: 'transparent' }\r
+                                               );\r
+                                       });\r
+\r
+                               </script>\r
+                               <p>\r
+                                       <input type="button" value="Send to Flash" onclick="sendToFlash();">\r
+                               </p>\r
+                       </td>\r
+                       <td style="vertical-align: top; padding-left: 20px">\r
+                               <div id="ckFlashContainer"></div>\r
+                       </td>\r
+               </tr>\r
+       </table>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/htmlwriter/samples/outputhtml.html b/sources/plugins/htmlwriter/samples/outputhtml.html
new file mode 100644 (file)
index 0000000..a433025
--- /dev/null
@@ -0,0 +1,224 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>HTML Compliant Output &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Output HTML">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to produce legacy HTML 4 code.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Producing HTML Compliant Output\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to output valid\r
+                       <a class="samples" href="http://www.w3.org/TR/html401/">HTML 4.01</a> code.\r
+                       Traditional HTML elements like <code>&lt;b&gt;</code>,\r
+                       <code>&lt;i&gt;</code>, and <code>&lt;font&gt;</code> are used in place of\r
+                       <code>&lt;strong&gt;</code>, <code>&lt;em&gt;</code>, and CSS styles.\r
+               </p>\r
+               <p>\r
+                       To add a CKEditor instance outputting legacy HTML 4.01 code, load the editor using a standard\r
+                       JavaScript call, and define CKEditor features to use the HTML compliant elements and attributes.\r
+               </p>\r
+               <p>\r
+                       A snippet of the configuration code can be seen below; check the source of this page for\r
+                       full definition:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       coreStyles_bold: { element: 'b' },\r
+       coreStyles_italic: { element: 'i' },\r
+\r
+       fontSize_style: {\r
+               element: 'font',\r
+               attributes: { 'size': '#(size)' }\r
+       }\r
+\r
+       ...\r
+});</pre>\r
+       </div>\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <p>\r
+                       <label for="editor1">\r
+                               Editor 1:\r
+                       </label>\r
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;b&gt;sample text&lt;/b&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+                       <script>\r
+\r
+                               CKEDITOR.replace( 'editor1', {\r
+                                       /*\r
+                                        * Ensure that htmlwriter plugin, which is required for this sample, is loaded.\r
+                                        */\r
+                                       extraPlugins: 'htmlwriter',\r
+\r
+                                       /*\r
+                                        * Style sheet for the contents\r
+                                        */\r
+                                       contentsCss: 'body {color:#000; background-color#:FFF;}',\r
+\r
+                                       /*\r
+                                        * Simple HTML5 doctype\r
+                                        */\r
+                                       docType: '<!DOCTYPE HTML>',\r
+\r
+                                       /*\r
+                                        * Allowed content rules which beside limiting allowed HTML\r
+                                        * will also take care of transforming styles to attributes\r
+                                        * (currently only for img - see transformation rules defined below).\r
+                                        *\r
+                                        * Read more: http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter\r
+                                        */\r
+                                       allowedContent:\r
+                                               'h1 h2 h3 p pre[align]; ' +\r
+                                               'blockquote code kbd samp var del ins cite q b i u strike ul ol li hr table tbody tr td th caption; ' +\r
+                                               'img[!src,alt,align,width,height]; font[!face]; font[!family]; font[!color]; font[!size]; font{!background-color}; a[!href]; a[!name]',\r
+\r
+                                       /*\r
+                                        * Core styles.\r
+                                        */\r
+                                       coreStyles_bold: { element: 'b' },\r
+                                       coreStyles_italic: { element: 'i' },\r
+                                       coreStyles_underline: { element: 'u' },\r
+                                       coreStyles_strike: { element: 'strike' },\r
+\r
+                                       /*\r
+                                        * Font face.\r
+                                        */\r
+\r
+                                       // Define the way font elements will be applied to the document.\r
+                                       // The "font" element will be used.\r
+                                       font_style: {\r
+                                               element: 'font',\r
+                                               attributes: { 'face': '#(family)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font sizes.\r
+                                        */\r
+                                       fontSize_sizes: 'xx-small/1;x-small/2;small/3;medium/4;large/5;x-large/6;xx-large/7',\r
+                                       fontSize_style: {\r
+                                               element: 'font',\r
+                                               attributes: { 'size': '#(size)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Font colors.\r
+                                        */\r
+\r
+                                       colorButton_foreStyle: {\r
+                                               element: 'font',\r
+                                               attributes: { 'color': '#(color)' }\r
+                                       },\r
+\r
+                                       colorButton_backStyle: {\r
+                                               element: 'font',\r
+                                               styles: { 'background-color': '#(color)' }\r
+                                       },\r
+\r
+                                       /*\r
+                                        * Styles combo.\r
+                                        */\r
+                                       stylesSet: [\r
+                                               { name: 'Computer Code', element: 'code' },\r
+                                               { name: 'Keyboard Phrase', element: 'kbd' },\r
+                                               { name: 'Sample Text', element: 'samp' },\r
+                                               { name: 'Variable', element: 'var' },\r
+                                               { name: 'Deleted Text', element: 'del' },\r
+                                               { name: 'Inserted Text', element: 'ins' },\r
+                                               { name: 'Cited Work', element: 'cite' },\r
+                                               { name: 'Inline Quotation', element: 'q' }\r
+                                       ],\r
+\r
+                                       on: {\r
+                                               pluginsLoaded: configureTransformations,\r
+                                               loaded: configureHtmlWriter\r
+                                       }\r
+                               });\r
+\r
+                               /*\r
+                                * Add missing content transformations.\r
+                                */\r
+                               function configureTransformations( evt ) {\r
+                                       var editor = evt.editor;\r
+\r
+                                       editor.dataProcessor.htmlFilter.addRules( {\r
+                                               attributes: {\r
+                                                       style: function( value, element ) {\r
+                                                               // Return #RGB for background and border colors\r
+                                                               return CKEDITOR.tools.convertRgbToHex( value );\r
+                                                       }\r
+                                               }\r
+                                       } );\r
+\r
+                                       // Default automatic content transformations do not yet take care of\r
+                                       // align attributes on blocks, so we need to add our own transformation rules.\r
+                                       function alignToAttribute( element ) {\r
+                                               if ( element.styles[ 'text-align' ] ) {\r
+                                                       element.attributes.align = element.styles[ 'text-align' ];\r
+                                                       delete element.styles[ 'text-align' ];\r
+                                               }\r
+                                       }\r
+                                       editor.filter.addTransformations( [\r
+                                               [ { element: 'p',       right: alignToAttribute } ],\r
+                                               [ { element: 'h1',      right: alignToAttribute } ],\r
+                                               [ { element: 'h2',      right: alignToAttribute } ],\r
+                                               [ { element: 'h3',      right: alignToAttribute } ],\r
+                                               [ { element: 'pre',     right: alignToAttribute } ]\r
+                                       ] );\r
+                               }\r
+\r
+                               /*\r
+                                * Adjust the behavior of htmlWriter to make it output HTML like FCKeditor.\r
+                                */\r
+                               function configureHtmlWriter( evt ) {\r
+                                       var editor = evt.editor,\r
+                                               dataProcessor = editor.dataProcessor;\r
+\r
+                                       // Out self closing tags the HTML4 way, like <br>.\r
+                                       dataProcessor.writer.selfClosingEnd = '>';\r
+\r
+                                       // Make output formatting behave similar to FCKeditor.\r
+                                       var dtd = CKEDITOR.dtd;\r
+                                       for ( var e in CKEDITOR.tools.extend( {}, dtd.$nonBodyContent, dtd.$block, dtd.$listItem, dtd.$tableContent ) ) {\r
+                                               dataProcessor.writer.setRules( e, {\r
+                                                       indent: true,\r
+                                                       breakBeforeOpen: true,\r
+                                                       breakAfterOpen: false,\r
+                                                       breakBeforeClose: !dtd[ e ][ '#' ],\r
+                                                       breakAfterClose: true\r
+                                               });\r
+                                       }\r
+                               }\r
+\r
+                       </script>\r
+               </p>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/iframe/dialogs/iframe.js b/sources/plugins/iframe/dialogs/iframe.js
new file mode 100644 (file)
index 0000000..bb39bdf
--- /dev/null
@@ -0,0 +1,207 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       // Map 'true' and 'false' values to match W3C's specifications\r
+       // http://www.w3.org/TR/REC-html40/present/frames.html#h-16.5\r
+       var checkboxValues = {\r
+               scrolling: { 'true': 'yes', 'false': 'no' },\r
+               frameborder: { 'true': '1', 'false': '0' }\r
+       };\r
+\r
+       function loadValue( iframeNode ) {\r
+               var isCheckbox = this instanceof CKEDITOR.ui.dialog.checkbox;\r
+               if ( iframeNode.hasAttribute( this.id ) ) {\r
+                       var value = iframeNode.getAttribute( this.id );\r
+                       if ( isCheckbox )\r
+                               this.setValue( checkboxValues[ this.id ][ 'true' ] == value.toLowerCase() );\r
+                       else\r
+                               this.setValue( value );\r
+               }\r
+       }\r
+\r
+       function commitValue( iframeNode ) {\r
+               var isRemove = this.getValue() === '',\r
+                       isCheckbox = this instanceof CKEDITOR.ui.dialog.checkbox,\r
+                       value = this.getValue();\r
+               if ( isRemove )\r
+                       iframeNode.removeAttribute( this.att || this.id );\r
+               else if ( isCheckbox )\r
+                       iframeNode.setAttribute( this.id, checkboxValues[ this.id ][ value ] );\r
+               else\r
+                       iframeNode.setAttribute( this.att || this.id, value );\r
+       }\r
+\r
+       CKEDITOR.dialog.add( 'iframe', function( editor ) {\r
+               var iframeLang = editor.lang.iframe,\r
+                       commonLang = editor.lang.common,\r
+                       dialogadvtab = editor.plugins.dialogadvtab;\r
+               return {\r
+                       title: iframeLang.title,\r
+                       minWidth: 350,\r
+                       minHeight: 260,\r
+                       onShow: function() {\r
+                               // Clear previously saved elements.\r
+                               this.fakeImage = this.iframeNode = null;\r
+\r
+                               var fakeImage = this.getSelectedElement();\r
+                               if ( fakeImage && fakeImage.data( 'cke-real-element-type' ) && fakeImage.data( 'cke-real-element-type' ) == 'iframe' ) {\r
+                                       this.fakeImage = fakeImage;\r
+\r
+                                       var iframeNode = editor.restoreRealElement( fakeImage );\r
+                                       this.iframeNode = iframeNode;\r
+\r
+                                       this.setupContent( iframeNode );\r
+                               }\r
+                       },\r
+                       onOk: function() {\r
+                               var iframeNode;\r
+                               if ( !this.fakeImage )\r
+                                       iframeNode = new CKEDITOR.dom.element( 'iframe' );\r
+                               else\r
+                                       iframeNode = this.iframeNode;\r
+\r
+                               // A subset of the specified attributes/styles\r
+                               // should also be applied on the fake element to\r
+                               // have better visual effect. (#5240)\r
+                               var extraStyles = {},\r
+                                       extraAttributes = {};\r
+                               this.commitContent( iframeNode, extraStyles, extraAttributes );\r
+\r
+                               // Refresh the fake image.\r
+                               var newFakeImage = editor.createFakeElement( iframeNode, 'cke_iframe', 'iframe', true );\r
+                               newFakeImage.setAttributes( extraAttributes );\r
+                               newFakeImage.setStyles( extraStyles );\r
+                               if ( this.fakeImage ) {\r
+                                       newFakeImage.replace( this.fakeImage );\r
+                                       editor.getSelection().selectElement( newFakeImage );\r
+                               } else {\r
+                                       editor.insertElement( newFakeImage );\r
+                               }\r
+                       },\r
+                       contents: [ {\r
+                               id: 'info',\r
+                               label: commonLang.generalTab,\r
+                               accessKey: 'I',\r
+                               elements: [ {\r
+                                       type: 'vbox',\r
+                                       padding: 0,\r
+                                       children: [ {\r
+                                               id: 'src',\r
+                                               type: 'text',\r
+                                               label: commonLang.url,\r
+                                               required: true,\r
+                                               validate: CKEDITOR.dialog.validate.notEmpty( iframeLang.noUrl ),\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'hbox',\r
+                                       children: [ {\r
+                                               id: 'width',\r
+                                               type: 'text',\r
+                                               requiredContent: 'iframe[width]',\r
+                                               style: 'width:100%',\r
+                                               labelLayout: 'vertical',\r
+                                               label: commonLang.width,\r
+                                               validate: CKEDITOR.dialog.validate.htmlLength( commonLang.invalidHtmlLength.replace( '%1', commonLang.width ) ),\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       },\r
+                                       {\r
+                                               id: 'height',\r
+                                               type: 'text',\r
+                                               requiredContent: 'iframe[height]',\r
+                                               style: 'width:100%',\r
+                                               labelLayout: 'vertical',\r
+                                               label: commonLang.height,\r
+                                               validate: CKEDITOR.dialog.validate.htmlLength( commonLang.invalidHtmlLength.replace( '%1', commonLang.height ) ),\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       },\r
+                                       {\r
+                                               id: 'align',\r
+                                               type: 'select',\r
+                                               requiredContent: 'iframe[align]',\r
+                                               'default': '',\r
+                                               items: [\r
+                                                       [ commonLang.notSet, '' ],\r
+                                                       [ commonLang.alignLeft, 'left' ],\r
+                                                       [ commonLang.alignRight, 'right' ],\r
+                                                       [ commonLang.alignTop, 'top' ],\r
+                                                       [ commonLang.alignMiddle, 'middle' ],\r
+                                                       [ commonLang.alignBottom, 'bottom' ]\r
+                                               ],\r
+                                               style: 'width:100%',\r
+                                               labelLayout: 'vertical',\r
+                                               label: commonLang.align,\r
+                                               setup: function( iframeNode, fakeImage ) {\r
+                                                       loadValue.apply( this, arguments );\r
+                                                       if ( fakeImage ) {\r
+                                                               var fakeImageAlign = fakeImage.getAttribute( 'align' );\r
+                                                               this.setValue( fakeImageAlign && fakeImageAlign.toLowerCase() || '' );\r
+                                                       }\r
+                                               },\r
+                                               commit: function( iframeNode, extraStyles, extraAttributes ) {\r
+                                                       commitValue.apply( this, arguments );\r
+                                                       if ( this.getValue() )\r
+                                                               extraAttributes.align = this.getValue();\r
+                                               }\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'hbox',\r
+                                       widths: [ '50%', '50%' ],\r
+                                       children: [ {\r
+                                               id: 'scrolling',\r
+                                               type: 'checkbox',\r
+                                               requiredContent: 'iframe[scrolling]',\r
+                                               label: iframeLang.scrolling,\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       },\r
+                                       {\r
+                                               id: 'frameborder',\r
+                                               type: 'checkbox',\r
+                                               requiredContent: 'iframe[frameborder]',\r
+                                               label: iframeLang.border,\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'hbox',\r
+                                       widths: [ '50%', '50%' ],\r
+                                       children: [ {\r
+                                               id: 'name',\r
+                                               type: 'text',\r
+                                               requiredContent: 'iframe[name]',\r
+                                               label: commonLang.name,\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       },\r
+                                       {\r
+                                               id: 'title',\r
+                                               type: 'text',\r
+                                               requiredContent: 'iframe[title]',\r
+                                               label: commonLang.advisoryTitle,\r
+                                               setup: loadValue,\r
+                                               commit: commitValue\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       id: 'longdesc',\r
+                                       type: 'text',\r
+                                       requiredContent: 'iframe[longdesc]',\r
+                                       label: commonLang.longDescr,\r
+                                       setup: loadValue,\r
+                                       commit: commitValue\r
+                               } ]\r
+                       },\r
+                       dialogadvtab && dialogadvtab.createAdvancedTab( editor, { id: 1, classes: 1, styles: 1 }, 'iframe' )\r
+               ] };\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/iframe/icons/hidpi/iframe.png b/sources/plugins/iframe/icons/hidpi/iframe.png
new file mode 100644 (file)
index 0000000..d99d0f3
Binary files /dev/null and b/sources/plugins/iframe/icons/hidpi/iframe.png differ
diff --git a/sources/plugins/iframe/icons/iframe.png b/sources/plugins/iframe/icons/iframe.png
new file mode 100644 (file)
index 0000000..a2f5545
Binary files /dev/null and b/sources/plugins/iframe/icons/iframe.png differ
diff --git a/sources/plugins/iframe/images/placeholder.png b/sources/plugins/iframe/images/placeholder.png
new file mode 100644 (file)
index 0000000..4af0956
Binary files /dev/null and b/sources/plugins/iframe/images/placeholder.png differ
diff --git a/sources/plugins/iframe/lang/af.js b/sources/plugins/iframe/lang/af.js
new file mode 100644 (file)
index 0000000..9fa9387
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'af', {\r
+       border: 'Wys rand van raam',\r
+       noUrl: 'Gee die iframe URL',\r
+       scrolling: 'Skuifbalke aan',\r
+       title: 'IFrame Eienskappe',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ar.js b/sources/plugins/iframe/lang/ar.js
new file mode 100644 (file)
index 0000000..6388d75
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ar', {\r
+       border: 'إظهار حدود الإطار',\r
+       noUrl: 'فضلا أكتب رابط الـ iframe',\r
+       scrolling: 'تفعيل أشرطة الإنتقال',\r
+       title: 'خصائص iframe',\r
+       toolbar: 'iframe'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/az.js b/sources/plugins/iframe/lang/az.js
new file mode 100644 (file)
index 0000000..e4b72e6
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'az', {\r
+       border: 'Çərçivə sərhədlərini göstər',\r
+       noUrl: 'Çərçivənin ünvanı daxil edin',\r
+       scrolling: 'Şürüşdürmələri əlavə et',\r
+       title: 'İFRAME elementinin alətləri',\r
+       toolbar: 'İFRAME'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/bg.js b/sources/plugins/iframe/lang/bg.js
new file mode 100644 (file)
index 0000000..4adb22c
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'bg', {\r
+       border: 'Показва рамка на карето',\r
+       noUrl: 'Моля въведете URL за iFrame',\r
+       scrolling: 'Вкл. скролбаровете',\r
+       title: 'IFrame настройки',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/bn.js b/sources/plugins/iframe/lang/bn.js
new file mode 100644 (file)
index 0000000..3479c1f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'bn', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/bs.js b/sources/plugins/iframe/lang/bs.js
new file mode 100644 (file)
index 0000000..51ca8a7
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'bs', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ca.js b/sources/plugins/iframe/lang/ca.js
new file mode 100644 (file)
index 0000000..a0d7d92
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ca', {\r
+       border: 'Mostra la vora del marc',\r
+       noUrl: 'Si us plau, introdueixi la URL de l\'iframe',\r
+       scrolling: 'Activa les barres de desplaçament',\r
+       title: 'Propietats de l\'IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/cs.js b/sources/plugins/iframe/lang/cs.js
new file mode 100644 (file)
index 0000000..388fa61
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'cs', {\r
+       border: 'Zobrazit okraj',\r
+       noUrl: 'Zadejte prosím URL obsahu pro IFrame',\r
+       scrolling: 'Zapnout posuvníky',\r
+       title: 'Vlastnosti IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/cy.js b/sources/plugins/iframe/lang/cy.js
new file mode 100644 (file)
index 0000000..a23b2ff
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'cy', {\r
+       border: 'Dangos ymyl y ffrâm',\r
+       noUrl: 'Rhowch URL yr iframe',\r
+       scrolling: 'Galluogi bariau sgrolio',\r
+       title: 'Priodweddau IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/da.js b/sources/plugins/iframe/lang/da.js
new file mode 100644 (file)
index 0000000..88b4fab
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'da', {\r
+       border: 'Vis kant på rammen',\r
+       noUrl: 'Venligst indsæt URL på iframen',\r
+       scrolling: 'Aktiver scrollbars',\r
+       title: 'Iframe egenskaber',\r
+       toolbar: 'Iframe'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/de-ch.js b/sources/plugins/iframe/lang/de-ch.js
new file mode 100644 (file)
index 0000000..2a56ccf
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'de-ch', {\r
+       border: 'Rahmen anzeigen',\r
+       noUrl: 'Bitte geben Sie die IFrame-URL an',\r
+       scrolling: 'Rollbalken anzeigen',\r
+       title: 'IFrame-Eigenschaften',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/de.js b/sources/plugins/iframe/lang/de.js
new file mode 100644 (file)
index 0000000..7988dfa
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'de', {\r
+       border: 'Rahmen anzeigen',\r
+       noUrl: 'Bitte geben Sie die IFrame-URL an',\r
+       scrolling: 'Rollbalken anzeigen',\r
+       title: 'IFrame-Eigenschaften',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/el.js b/sources/plugins/iframe/lang/el.js
new file mode 100644 (file)
index 0000000..5abdfb0
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'el', {\r
+       border: 'Προβολή περιγράμματος πλαισίου',\r
+       noUrl: 'Παρακαλούμε εισάγεται το URL του iframe',\r
+       scrolling: 'Ενεργοποίηση μπαρών κύλισης',\r
+       title: 'Ιδιότητες IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/en-au.js b/sources/plugins/iframe/lang/en-au.js
new file mode 100644 (file)
index 0000000..59048db
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'en-au', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/en-ca.js b/sources/plugins/iframe/lang/en-ca.js
new file mode 100644 (file)
index 0000000..401ff49
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'en-ca', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/en-gb.js b/sources/plugins/iframe/lang/en-gb.js
new file mode 100644 (file)
index 0000000..78d4000
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'en-gb', {\r
+       border: 'Show frame border',\r
+       noUrl: 'Please type the iframe URL',\r
+       scrolling: 'Enable scrollbars',\r
+       title: 'IFrame Properties',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/en.js b/sources/plugins/iframe/lang/en.js
new file mode 100644 (file)
index 0000000..1e224b9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'en', {\r
+       border: 'Show frame border',\r
+       noUrl: 'Please type the iframe URL',\r
+       scrolling: 'Enable scrollbars',\r
+       title: 'IFrame Properties',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/eo.js b/sources/plugins/iframe/lang/eo.js
new file mode 100644 (file)
index 0000000..eba244d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'eo', {\r
+       border: 'Montri borderon de kadro (frame)',\r
+       noUrl: 'Bonvolu entajpi la retadreson de la ligilo al la enlinia kadro (IFrame)',\r
+       scrolling: 'Ebligi rulumskalon',\r
+       title: 'Atributoj de la enlinia kadro (IFrame)',\r
+       toolbar: 'Enlinia kadro (IFrame)'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/es.js b/sources/plugins/iframe/lang/es.js
new file mode 100644 (file)
index 0000000..1cf5c29
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'es', {\r
+       border: 'Mostrar borde del marco',\r
+       noUrl: 'Por favor, escriba la dirección del iframe',\r
+       scrolling: 'Activar barras de desplazamiento',\r
+       title: 'Propiedades de iframe',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/et.js b/sources/plugins/iframe/lang/et.js
new file mode 100644 (file)
index 0000000..aac467d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'et', {\r
+       border: 'Raami äärise näitamine',\r
+       noUrl: 'Vali iframe URLi liik',\r
+       scrolling: 'Kerimisribade lubamine',\r
+       title: 'IFrame omadused',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/eu.js b/sources/plugins/iframe/lang/eu.js
new file mode 100644 (file)
index 0000000..1f77367
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'eu', {\r
+       border: 'Erakutsi markoaren ertza',\r
+       noUrl: 'Idatzi iframe-aren URLa, mesedez.',\r
+       scrolling: 'Gaitu korritze-barrak',\r
+       title: 'IFrame-aren propietateak',\r
+       toolbar: 'IFrame-a'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/fa.js b/sources/plugins/iframe/lang/fa.js
new file mode 100644 (file)
index 0000000..0c7a09f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'fa', {\r
+       border: 'نمایش خطوط frame',\r
+       noUrl: 'لطفا مسیر URL iframe را درج کنید',\r
+       scrolling: 'نمایش خطکشها',\r
+       title: 'ویژگیهای IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/fi.js b/sources/plugins/iframe/lang/fi.js
new file mode 100644 (file)
index 0000000..0aa7f37
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'fi', {\r
+       border: 'Näytä kehyksen reunat',\r
+       noUrl: 'Anna IFrame-kehykselle lähdeosoite (src)',\r
+       scrolling: 'Näytä vierityspalkit',\r
+       title: 'IFrame-kehyksen ominaisuudet',\r
+       toolbar: 'IFrame-kehys'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/fo.js b/sources/plugins/iframe/lang/fo.js
new file mode 100644 (file)
index 0000000..05fdfe8
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'fo', {\r
+       border: 'Vís frame kant',\r
+       noUrl: 'Vinarliga skriva URL til iframe',\r
+       scrolling: 'Loyv scrollbars',\r
+       title: 'Møguleikar fyri IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/fr-ca.js b/sources/plugins/iframe/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..cf7947e
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'fr-ca', {\r
+       border: 'Afficher la bordure du cadre',\r
+       noUrl: 'Veuillez entre l\'URL du IFrame',\r
+       scrolling: 'Activer les barres de défilement',\r
+       title: 'Propriétés du IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/fr.js b/sources/plugins/iframe/lang/fr.js
new file mode 100644 (file)
index 0000000..34fc64e
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'fr', {\r
+       border: 'Afficher la bordure du cadre',\r
+       noUrl: 'Veuillez entrer l\'URL du contenu du cadre',\r
+       scrolling: 'Activer les barres de défilement',\r
+       title: 'Propriétés du cadre de contenu incorporé',\r
+       toolbar: 'Cadre de contenu incorporé'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/gl.js b/sources/plugins/iframe/lang/gl.js
new file mode 100644 (file)
index 0000000..449e28d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'gl', {\r
+       border: 'Amosar o bordo do marco',\r
+       noUrl: 'Escriba o enderezo do iframe',\r
+       scrolling: 'Activar as barras de desprazamento',\r
+       title: 'Propiedades do iFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/gu.js b/sources/plugins/iframe/lang/gu.js
new file mode 100644 (file)
index 0000000..91bb8bb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'gu', {\r
+       border: 'ફ્રેમ બોર્ડેર બતાવવી',\r
+       noUrl: 'iframe URL ટાઈપ્ કરો',\r
+       scrolling: 'સ્ક્રોલબાર ચાલુ કરવા',\r
+       title: 'IFrame વિકલ્પો',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/he.js b/sources/plugins/iframe/lang/he.js
new file mode 100644 (file)
index 0000000..87467be
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'he', {\r
+       border: 'הראה מסגרת לחלון',\r
+       noUrl: 'יש להכניס כתובת לחלון.',\r
+       scrolling: 'אפשר פסי גלילה',\r
+       title: 'מאפייני חלון פנימי (iframe)',\r
+       toolbar: 'חלון פנימי (iframe)'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/hi.js b/sources/plugins/iframe/lang/hi.js
new file mode 100644 (file)
index 0000000..96d30fb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'hi', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/hr.js b/sources/plugins/iframe/lang/hr.js
new file mode 100644 (file)
index 0000000..986e000
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'hr', {\r
+       border: 'Prikaži okvir IFrame-a',\r
+       noUrl: 'Unesite URL iframe-a',\r
+       scrolling: 'Omogući trake za skrolanje',\r
+       title: 'IFrame svojstva',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/hu.js b/sources/plugins/iframe/lang/hu.js
new file mode 100644 (file)
index 0000000..096d311
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'hu', {\r
+       border: 'Legyen keret',\r
+       noUrl: 'Kérem írja be a iframe URL-t',\r
+       scrolling: 'Gördítősáv bekapcsolása',\r
+       title: 'IFrame Tulajdonságok',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/id.js b/sources/plugins/iframe/lang/id.js
new file mode 100644 (file)
index 0000000..c351eda
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'id', {\r
+       border: 'Tampilkan Batas Bingkai',\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Aktifkan Scrollbar',\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/is.js b/sources/plugins/iframe/lang/is.js
new file mode 100644 (file)
index 0000000..bc7cf08
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'is', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/it.js b/sources/plugins/iframe/lang/it.js
new file mode 100644 (file)
index 0000000..e020c27
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'it', {\r
+       border: 'Mostra il bordo',\r
+       noUrl: 'Inserire l\'URL del campo IFrame',\r
+       scrolling: 'Abilita scrollbar',\r
+       title: 'Proprietà IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ja.js b/sources/plugins/iframe/lang/ja.js
new file mode 100644 (file)
index 0000000..b104ccd
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ja', {\r
+       border: 'フレームの枠を表示',\r
+       noUrl: 'iframeのURLを入力してください。',\r
+       scrolling: 'スクロールバーの表示を許可',\r
+       title: 'iFrameのプロパティ',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ka.js b/sources/plugins/iframe/lang/ka.js
new file mode 100644 (file)
index 0000000..7d98f68
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ka', {\r
+       border: 'ჩარჩოს გამოჩენა',\r
+       noUrl: 'აკრიფეთ iframe-ის URL',\r
+       scrolling: 'გადახვევის ზოლების დაშვება',\r
+       title: 'IFrame-ის პარამეტრები',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/km.js b/sources/plugins/iframe/lang/km.js
new file mode 100644 (file)
index 0000000..9331b23
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'km', {\r
+       border: 'បង្ហាញ​បន្ទាត់​ស៊ុម',\r
+       noUrl: 'សូម​បញ្ចូល URL របស់ iframe',\r
+       scrolling: 'ប្រើ​របារ​រំកិល',\r
+       title: 'លក្ខណៈ​សម្បត្តិ IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ko.js b/sources/plugins/iframe/lang/ko.js
new file mode 100644 (file)
index 0000000..f5c16a0
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ko', {\r
+       border: '프레임 테두리 표시',\r
+       noUrl: '아이프레임 주소(URL)를 입력해주세요.',\r
+       scrolling: '스크롤바 사용',\r
+       title: '아이프레임 속성',\r
+       toolbar: '아이프레임'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ku.js b/sources/plugins/iframe/lang/ku.js
new file mode 100644 (file)
index 0000000..852c3b4
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ku', {\r
+       border: 'نیشاندانی لاکێشه بە چوواردەوری چووارچێوە',\r
+       noUrl: 'تکایه ناونیشانی بەستەر بنووسه بۆ چووارچێوه',\r
+       scrolling: 'چالاککردنی هاتووچۆپێکردن',\r
+       title: 'دیالۆگی چووارچێوه',\r
+       toolbar: 'چووارچێوه'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/lt.js b/sources/plugins/iframe/lang/lt.js
new file mode 100644 (file)
index 0000000..c69817f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'lt', {\r
+       border: 'Rodyti rėmelį',\r
+       noUrl: 'Nurodykite iframe nuorodą',\r
+       scrolling: 'Įjungti slankiklius',\r
+       title: 'IFrame nustatymai',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/lv.js b/sources/plugins/iframe/lang/lv.js
new file mode 100644 (file)
index 0000000..50a6743
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'lv', {\r
+       border: 'Rādīt rāmi',\r
+       noUrl: 'Norādiet iframe adresi',\r
+       scrolling: 'Atļaut ritjoslas',\r
+       title: 'IFrame uzstādījumi',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/mk.js b/sources/plugins/iframe/lang/mk.js
new file mode 100644 (file)
index 0000000..d576e21
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'mk', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/mn.js b/sources/plugins/iframe/lang/mn.js
new file mode 100644 (file)
index 0000000..dd9d927
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'mn', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ms.js b/sources/plugins/iframe/lang/ms.js
new file mode 100644 (file)
index 0000000..f0342bf
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ms', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/nb.js b/sources/plugins/iframe/lang/nb.js
new file mode 100644 (file)
index 0000000..c02990e
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'nb', {\r
+       border: 'Vis ramme rundt iframe',\r
+       noUrl: 'Vennligst skriv inn URL for iframe',\r
+       scrolling: 'Aktiver scrollefelt',\r
+       title: 'Egenskaper for IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/nl.js b/sources/plugins/iframe/lang/nl.js
new file mode 100644 (file)
index 0000000..555025d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'nl', {\r
+       border: 'Framerand tonen',\r
+       noUrl: 'Vul de IFrame URL in',\r
+       scrolling: 'Scrollbalken inschakelen',\r
+       title: 'IFrame-eigenschappen',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/no.js b/sources/plugins/iframe/lang/no.js
new file mode 100644 (file)
index 0000000..bb44fe5
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'no', {\r
+       border: 'Viss ramme rundt iframe',\r
+       noUrl: 'Vennligst skriv inn URL for iframe',\r
+       scrolling: 'Aktiver scrollefelt',\r
+       title: 'Egenskaper for IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/oc.js b/sources/plugins/iframe/lang/oc.js
new file mode 100644 (file)
index 0000000..890a571
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'oc', {\r
+       border: 'Afichar la bordadura del quadre',\r
+       noUrl: 'Entratz l\'URL del contengut del quadre',\r
+       scrolling: 'Activar las barras de desfilament',\r
+       title: 'Proprietats del quadre de contengut incorporat',\r
+       toolbar: 'Quadre de contengut incorporat'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/pl.js b/sources/plugins/iframe/lang/pl.js
new file mode 100644 (file)
index 0000000..6d05dd1
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'pl', {\r
+       border: 'Pokaż obramowanie obiektu IFrame',\r
+       noUrl: 'Podaj adres URL elementu IFrame',\r
+       scrolling: 'Włącz paski przewijania',\r
+       title: 'Właściwości elementu IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/pt-br.js b/sources/plugins/iframe/lang/pt-br.js
new file mode 100644 (file)
index 0000000..58ec356
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'pt-br', {\r
+       border: 'Mostra borda do iframe',\r
+       noUrl: 'Insira a URL do iframe',\r
+       scrolling: 'Abilita scrollbars',\r
+       title: 'Propriedade do IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/pt.js b/sources/plugins/iframe/lang/pt.js
new file mode 100644 (file)
index 0000000..1b1cd9f
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'pt', {\r
+       border: 'Mostrar a borda da Frame',\r
+       noUrl: 'Por favor, digite o URL da iframe',\r
+       scrolling: 'Ativar barras de rolamento',\r
+       title: 'Propriedades da IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ro.js b/sources/plugins/iframe/lang/ro.js
new file mode 100644 (file)
index 0000000..deeb0c4
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ro', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ru.js b/sources/plugins/iframe/lang/ru.js
new file mode 100644 (file)
index 0000000..e352aa3
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ru', {\r
+       border: 'Показать границы фрейма',\r
+       noUrl: 'Пожалуйста, введите ссылку фрейма',\r
+       scrolling: 'Отображать полосы прокрутки',\r
+       title: 'Свойства iFrame',\r
+       toolbar: 'iFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/si.js b/sources/plugins/iframe/lang/si.js
new file mode 100644 (file)
index 0000000..d7660ef
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'si', {\r
+       border: 'සැකිල්ලේ කඩයිම් ',\r
+       noUrl: 'කරුණාකර රුපයේ URL ලියන්න',\r
+       scrolling: 'සක්ක්‍රිය කරන්න',\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sk.js b/sources/plugins/iframe/lang/sk.js
new file mode 100644 (file)
index 0000000..ac0b91d
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sk', {\r
+       border: 'Zobraziť rám frame-u',\r
+       noUrl: 'Prosím, vložte URL iframe',\r
+       scrolling: 'Povoliť skrolovanie',\r
+       title: 'Vlastnosti IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sl.js b/sources/plugins/iframe/lang/sl.js
new file mode 100644 (file)
index 0000000..2b0e375
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sl', {\r
+       border: 'Pokaži obrobo okvirja',\r
+       noUrl: 'Prosimo, vnesite iframe URL',\r
+       scrolling: 'Omogoči drsnike',\r
+       title: 'Lastnosti IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sq.js b/sources/plugins/iframe/lang/sq.js
new file mode 100644 (file)
index 0000000..a274000
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sq', {\r
+       border: 'Shfaq kufirin e kornizës',\r
+       noUrl: 'Ju lutemi shkruani URL-në e iframe-it',\r
+       scrolling: 'Lejo shiritët zvarritës',\r
+       title: 'Karakteristikat e IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sr-latn.js b/sources/plugins/iframe/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..29685a9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sr-latn', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sr.js b/sources/plugins/iframe/lang/sr.js
new file mode 100644 (file)
index 0000000..acd9876
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sr', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame' // MISSING\r
+} );\r
diff --git a/sources/plugins/iframe/lang/sv.js b/sources/plugins/iframe/lang/sv.js
new file mode 100644 (file)
index 0000000..fab04a5
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'sv', {\r
+       border: 'Visa ramkant',\r
+       noUrl: 'Skriv in URL för iFrame',\r
+       scrolling: 'Aktivera rullningslister',\r
+       title: 'iFrame-egenskaper',\r
+       toolbar: 'iFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/th.js b/sources/plugins/iframe/lang/th.js
new file mode 100644 (file)
index 0000000..57926b9
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'th', {\r
+       border: 'Show frame border', // MISSING\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame Properties', // MISSING\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/tr.js b/sources/plugins/iframe/lang/tr.js
new file mode 100644 (file)
index 0000000..d828f65
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'tr', {\r
+       border: 'Çerceve sınırlarını göster',\r
+       noUrl: 'Lütfen IFrame köprü (URL) bağlantısını yazın',\r
+       scrolling: 'Kaydırma çubuklarını aktif et',\r
+       title: 'IFrame Özellikleri',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/tt.js b/sources/plugins/iframe/lang/tt.js
new file mode 100644 (file)
index 0000000..869f67b
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'tt', {\r
+       border: 'Frame чикләрен күрсәтү',\r
+       noUrl: 'Please type the iframe URL', // MISSING\r
+       scrolling: 'Enable scrollbars', // MISSING\r
+       title: 'IFrame үзлекләре',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/ug.js b/sources/plugins/iframe/lang/ug.js
new file mode 100644 (file)
index 0000000..b46f6da
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'ug', {\r
+       border: 'كاندۇك گىرۋەكلىرىنى كۆرسەت',\r
+       noUrl: 'كاندۇكنىڭ ئادرېسى(Url)نى كىرگۈزۈڭ',\r
+       scrolling: 'دومىلىما سۈرگۈچكە يول قوي',\r
+       title: 'IFrame خاسلىق',\r
+       toolbar: 'IFrame '\r
+} );\r
diff --git a/sources/plugins/iframe/lang/uk.js b/sources/plugins/iframe/lang/uk.js
new file mode 100644 (file)
index 0000000..3f91ef6
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'uk', {\r
+       border: 'Показати рамки фрейму',\r
+       noUrl: 'Будь ласка введіть URL посилання для IFrame',\r
+       scrolling: 'Увімкнути прокрутку',\r
+       title: 'Налаштування для IFrame',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/vi.js b/sources/plugins/iframe/lang/vi.js
new file mode 100644 (file)
index 0000000..be8ebfb
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'vi', {\r
+       border: 'Hiển thị viền khung',\r
+       noUrl: 'Vui lòng nhập địa chỉ iframe',\r
+       scrolling: 'Kích hoạt thanh cuộn',\r
+       title: 'Thuộc tính iframe',\r
+       toolbar: 'Iframe'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/zh-cn.js b/sources/plugins/iframe/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..a35bd8c
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'zh-cn', {\r
+       border: '显示框架边框',\r
+       noUrl: '请输入框架的 URL',\r
+       scrolling: '允许滚动条',\r
+       title: 'IFrame 属性',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/lang/zh.js b/sources/plugins/iframe/lang/zh.js
new file mode 100644 (file)
index 0000000..4f7472a
--- /dev/null
@@ -0,0 +1,11 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'iframe', 'zh', {\r
+       border: '顯示框架框線',\r
+       noUrl: '請輸入 iframe URL',\r
+       scrolling: '啟用捲軸列',\r
+       title: 'IFrame 屬性',\r
+       toolbar: 'IFrame'\r
+} );\r
diff --git a/sources/plugins/iframe/plugin.js b/sources/plugins/iframe/plugin.js
new file mode 100644 (file)
index 0000000..52c816a
--- /dev/null
@@ -0,0 +1,85 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'iframe', {\r
+               requires: 'dialog,fakeobjects',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'iframe', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               onLoad: function() {\r
+                       CKEDITOR.addCss( 'img.cke_iframe' +\r
+                               '{' +\r
+                                       'background-image: url(' + CKEDITOR.getUrl( this.path + 'images/placeholder.png' ) + ');' +\r
+                                       'background-position: center center;' +\r
+                                       'background-repeat: no-repeat;' +\r
+                                       'border: 1px solid #a9a9a9;' +\r
+                                       'width: 80px;' +\r
+                                       'height: 80px;' +\r
+                               '}'\r
+                               );\r
+               },\r
+               init: function( editor ) {\r
+                       var pluginName = 'iframe',\r
+                               lang = editor.lang.iframe,\r
+                               allowed = 'iframe[align,longdesc,frameborder,height,name,scrolling,src,title,width]';\r
+\r
+                       if ( editor.plugins.dialogadvtab )\r
+                               allowed += ';iframe' + editor.plugins.dialogadvtab.allowedContent( { id: 1, classes: 1, styles: 1 } );\r
+\r
+                       CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/iframe.js' );\r
+                       editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName, {\r
+                               allowedContent: allowed,\r
+                               requiredContent: 'iframe'\r
+                       } ) );\r
+\r
+                       editor.ui.addButton && editor.ui.addButton( 'Iframe', {\r
+                               label: lang.toolbar,\r
+                               command: pluginName,\r
+                               toolbar: 'insert,80'\r
+                       } );\r
+\r
+                       editor.on( 'doubleclick', function( evt ) {\r
+                               var element = evt.data.element;\r
+                               if ( element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'iframe' )\r
+                                       evt.data.dialog = 'iframe';\r
+                       } );\r
+\r
+                       if ( editor.addMenuItems ) {\r
+                               editor.addMenuItems( {\r
+                                       iframe: {\r
+                                               label: lang.title,\r
+                                               command: 'iframe',\r
+                                               group: 'image'\r
+                                       }\r
+                               } );\r
+                       }\r
+\r
+                       // If the "contextmenu" plugin is loaded, register the listeners.\r
+                       if ( editor.contextMenu ) {\r
+                               editor.contextMenu.addListener( function( element ) {\r
+                                       if ( element && element.is( 'img' ) && element.data( 'cke-real-element-type' ) == 'iframe' )\r
+                                               return { iframe: CKEDITOR.TRISTATE_OFF };\r
+                               } );\r
+                       }\r
+               },\r
+               afterInit: function( editor ) {\r
+                       var dataProcessor = editor.dataProcessor,\r
+                               dataFilter = dataProcessor && dataProcessor.dataFilter;\r
+\r
+                       if ( dataFilter ) {\r
+                               dataFilter.addRules( {\r
+                                       elements: {\r
+                                               iframe: function( element ) {\r
+                                                       return editor.createFakeParserElement( element, 'cke_iframe', 'iframe', true );\r
+                                               }\r
+                                       }\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/image/dialogs/image.js b/sources/plugins/image/dialogs/image.js
new file mode 100644 (file)
index 0000000..7d7537a
--- /dev/null
@@ -0,0 +1,1254 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       var imageDialog = function( editor, dialogType ) {\r
+                       // Load image preview.\r
+                       var IMAGE = 1,\r
+                               LINK = 2,\r
+                               PREVIEW = 4,\r
+                               CLEANUP = 8,\r
+                               regexGetSize = /^\s*(\d+)((px)|\%)?\s*$/i,\r
+                               regexGetSizeOrEmpty = /(^\s*(\d+)((px)|\%)?\s*$)|^$/i,\r
+                               pxLengthRegex = /^\d+px$/;\r
+\r
+                       var onSizeChange = function() {\r
+                                       var value = this.getValue(),\r
+                                               // This = input element.\r
+                                               dialog = this.getDialog(),\r
+                                               aMatch = value.match( regexGetSize ); // Check value\r
+                                       if ( aMatch ) {\r
+                                               if ( aMatch[ 2 ] == '%' ) // % is allowed - > unlock ratio.\r
+                                               switchLockRatio( dialog, false ); // Unlock.\r
+                                               value = aMatch[ 1 ];\r
+                                       }\r
+\r
+                                       // Only if ratio is locked\r
+                                       if ( dialog.lockRatio ) {\r
+                                               var oImageOriginal = dialog.originalElement;\r
+                                               if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' ) {\r
+                                                       if ( this.id == 'txtHeight' ) {\r
+                                                               if ( value && value != '0' )\r
+                                                                       value = Math.round( oImageOriginal.$.width * ( value / oImageOriginal.$.height ) );\r
+                                                               if ( !isNaN( value ) )\r
+                                                                       dialog.setValueOf( 'info', 'txtWidth', value );\r
+                                                       }\r
+                                                       // this.id = txtWidth.\r
+                                                       else {\r
+                                                               if ( value && value != '0' )\r
+                                                                       value = Math.round( oImageOriginal.$.height * ( value / oImageOriginal.$.width ) );\r
+                                                               if ( !isNaN( value ) )\r
+                                                                       dialog.setValueOf( 'info', 'txtHeight', value );\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       updatePreview( dialog );\r
+                               };\r
+\r
+                       var updatePreview = function( dialog ) {\r
+                                       //Don't load before onShow.\r
+                                       if ( !dialog.originalElement || !dialog.preview )\r
+                                               return 1;\r
+\r
+                                       // Read attributes and update imagePreview;\r
+                                       dialog.commitContent( PREVIEW, dialog.preview );\r
+                                       return 0;\r
+                               };\r
+\r
+                       // Custom commit dialog logic, where we're intended to give inline style\r
+                       // field (txtdlgGenStyle) higher priority to avoid overwriting styles contribute\r
+                       // by other fields.\r
+                       function commitContent() {\r
+                               var args = arguments;\r
+                               var inlineStyleField = this.getContentElement( 'advanced', 'txtdlgGenStyle' );\r
+                               inlineStyleField && inlineStyleField.commit.apply( inlineStyleField, args );\r
+\r
+                               this.foreach( function( widget ) {\r
+                                       if ( widget.commit && widget.id != 'txtdlgGenStyle' )\r
+                                               widget.commit.apply( widget, args );\r
+                               } );\r
+                       }\r
+\r
+                       // Avoid recursions.\r
+                       var incommit;\r
+\r
+                       // Synchronous field values to other impacted fields is required, e.g. border\r
+                       // size change should alter inline-style text as well.\r
+                       function commitInternally( targetFields ) {\r
+                               if ( incommit )\r
+                                       return;\r
+\r
+                               incommit = 1;\r
+\r
+                               var dialog = this.getDialog(),\r
+                                       element = dialog.imageElement;\r
+                               if ( element ) {\r
+                                       // Commit this field and broadcast to target fields.\r
+                                       this.commit( IMAGE, element );\r
+\r
+                                       targetFields = [].concat( targetFields );\r
+                                       var length = targetFields.length,\r
+                                               field;\r
+                                       for ( var i = 0; i < length; i++ ) {\r
+                                               field = dialog.getContentElement.apply( dialog, targetFields[ i ].split( ':' ) );\r
+                                               // May cause recursion.\r
+                                               field && field.setup( IMAGE, element );\r
+                                       }\r
+                               }\r
+\r
+                               incommit = 0;\r
+                       }\r
+\r
+                       var switchLockRatio = function( dialog, value ) {\r
+                                       if ( !dialog.getContentElement( 'info', 'ratioLock' ) )\r
+                                               return null;\r
+\r
+                                       var oImageOriginal = dialog.originalElement;\r
+\r
+                                       // Dialog may already closed. (#5505)\r
+                                       if ( !oImageOriginal )\r
+                                               return null;\r
+\r
+                                       // Check image ratio and original image ratio, but respecting user's preference.\r
+                                       if ( value == 'check' ) {\r
+                                               if ( !dialog.userlockRatio && oImageOriginal.getCustomData( 'isReady' ) == 'true' ) {\r
+                                                       var width = dialog.getValueOf( 'info', 'txtWidth' ),\r
+                                                               height = dialog.getValueOf( 'info', 'txtHeight' ),\r
+                                                               originalRatio = oImageOriginal.$.width * 1000 / oImageOriginal.$.height,\r
+                                                               thisRatio = width * 1000 / height;\r
+                                                       dialog.lockRatio = false; // Default: unlock ratio\r
+\r
+                                                       if ( !width && !height )\r
+                                                               dialog.lockRatio = true;\r
+                                                       else if ( !isNaN( originalRatio ) && !isNaN( thisRatio ) ) {\r
+                                                               if ( Math.round( originalRatio ) == Math.round( thisRatio ) )\r
+                                                                       dialog.lockRatio = true;\r
+                                                       }\r
+                                               }\r
+                                       } else if ( value !== undefined )\r
+                                               dialog.lockRatio = value;\r
+                                       else {\r
+                                               dialog.userlockRatio = 1;\r
+                                               dialog.lockRatio = !dialog.lockRatio;\r
+                                       }\r
+\r
+                                       var ratioButton = CKEDITOR.document.getById( btnLockSizesId );\r
+                                       if ( dialog.lockRatio )\r
+                                               ratioButton.removeClass( 'cke_btn_unlocked' );\r
+                                       else\r
+                                               ratioButton.addClass( 'cke_btn_unlocked' );\r
+\r
+                                       ratioButton.setAttribute( 'aria-checked', dialog.lockRatio );\r
+\r
+                                       // Ratio button hc presentation - WHITE SQUARE / BLACK SQUARE\r
+                                       if ( CKEDITOR.env.hc ) {\r
+                                               var icon = ratioButton.getChild( 0 );\r
+                                               icon.setHtml( dialog.lockRatio ? CKEDITOR.env.ie ? '\u25A0' : '\u25A3' : CKEDITOR.env.ie ? '\u25A1' : '\u25A2' );\r
+                                       }\r
+\r
+                                       return dialog.lockRatio;\r
+                               };\r
+\r
+                       var resetSize = function( dialog, emptyValues ) {\r
+                                       var oImageOriginal = dialog.originalElement,\r
+                                               ready = oImageOriginal.getCustomData( 'isReady' ) == 'true';\r
+\r
+                                       if ( ready ) {\r
+                                               var widthField = dialog.getContentElement( 'info', 'txtWidth' ),\r
+                                                       heightField = dialog.getContentElement( 'info', 'txtHeight' ),\r
+                                                       widthValue, heightValue;\r
+\r
+                                               if ( emptyValues ) {\r
+                                                       widthValue = 0;\r
+                                                       heightValue = 0;\r
+                                               } else {\r
+                                                       widthValue = oImageOriginal.$.width;\r
+                                                       heightValue = oImageOriginal.$.height;\r
+                                               }\r
+\r
+                                               widthField && widthField.setValue( widthValue );\r
+                                               heightField && heightField.setValue( heightValue );\r
+                                       }\r
+                                       updatePreview( dialog );\r
+                               };\r
+\r
+                       var setupDimension = function( type, element ) {\r
+                                       if ( type != IMAGE )\r
+                                               return;\r
+\r
+                                       function checkDimension( size, defaultValue ) {\r
+                                               var aMatch = size.match( regexGetSize );\r
+                                               if ( aMatch ) {\r
+                                                       // % is allowed.\r
+                                                       if ( aMatch[ 2 ] == '%' ) {\r
+                                                               aMatch[ 1 ] += '%';\r
+                                                               switchLockRatio( dialog, false ); // Unlock ratio\r
+                                                       }\r
+                                                       return aMatch[ 1 ];\r
+                                               }\r
+                                               return defaultValue;\r
+                                       }\r
+\r
+                                       var dialog = this.getDialog(),\r
+                                               value = '',\r
+                                               dimension = this.id == 'txtWidth' ? 'width' : 'height',\r
+                                               size = element.getAttribute( dimension );\r
+\r
+                                       if ( size )\r
+                                               value = checkDimension( size, value );\r
+                                       value = checkDimension( element.getStyle( dimension ), value );\r
+\r
+                                       this.setValue( value );\r
+                               };\r
+\r
+                       var previewPreloader;\r
+\r
+                       var onImgLoadEvent = function() {\r
+                                       // Image is ready.\r
+                                       var original = this.originalElement,\r
+                                               loader = CKEDITOR.document.getById( imagePreviewLoaderId );\r
+\r
+                                       original.setCustomData( 'isReady', 'true' );\r
+                                       original.removeListener( 'load', onImgLoadEvent );\r
+                                       original.removeListener( 'error', onImgLoadErrorEvent );\r
+                                       original.removeListener( 'abort', onImgLoadErrorEvent );\r
+\r
+                                       // Hide loader.\r
+                                       if ( loader )\r
+                                               loader.setStyle( 'display', 'none' );\r
+\r
+                                       // New image -> new dimensions\r
+                                       if ( !this.dontResetSize ) {\r
+                                               resetSize( this, editor.config.image_prefillDimensions === false );\r
+                                       }\r
+\r
+                                       if ( this.firstLoad ) {\r
+                                               CKEDITOR.tools.setTimeout( function() {\r
+                                                       switchLockRatio( this, 'check' );\r
+                                               }, 0, this );\r
+                                       }\r
+\r
+                                       this.firstLoad = false;\r
+                                       this.dontResetSize = false;\r
+\r
+                                       // Possible fix for #12818.\r
+                                       updatePreview( this );\r
+                               };\r
+\r
+                       var onImgLoadErrorEvent = function() {\r
+                                       // Error. Image is not loaded.\r
+                                       var original = this.originalElement,\r
+                                               loader = CKEDITOR.document.getById( imagePreviewLoaderId );\r
+\r
+                                       original.removeListener( 'load', onImgLoadEvent );\r
+                                       original.removeListener( 'error', onImgLoadErrorEvent );\r
+                                       original.removeListener( 'abort', onImgLoadErrorEvent );\r
+\r
+                                       // Set Error image.\r
+                                       var noimage = CKEDITOR.getUrl( CKEDITOR.plugins.get( 'image' ).path + 'images/noimage.png' );\r
+\r
+                                       if ( this.preview )\r
+                                               this.preview.setAttribute( 'src', noimage );\r
+\r
+                                       // Hide loader.\r
+                                       if ( loader )\r
+                                               loader.setStyle( 'display', 'none' );\r
+\r
+                                       switchLockRatio( this, false ); // Unlock.\r
+                               };\r
+\r
+                       var numbering = function( id ) {\r
+                                       return CKEDITOR.tools.getNextId() + '_' + id;\r
+                               },\r
+                               btnLockSizesId = numbering( 'btnLockSizes' ),\r
+                               btnResetSizeId = numbering( 'btnResetSize' ),\r
+                               imagePreviewLoaderId = numbering( 'ImagePreviewLoader' ),\r
+                               previewLinkId = numbering( 'previewLink' ),\r
+                               previewImageId = numbering( 'previewImage' );\r
+\r
+                       return {\r
+                               title: editor.lang.image[ dialogType == 'image' ? 'title' : 'titleButton' ],\r
+                               minWidth: ( CKEDITOR.skinName || editor.config.skin ) == 'moono-lisa' ? 500 : 420,\r
+                               minHeight: 360,\r
+                               onShow: function() {\r
+                                       this.imageElement = false;\r
+                                       this.linkElement = false;\r
+\r
+                                       // Default: create a new element.\r
+                                       this.imageEditMode = false;\r
+                                       this.linkEditMode = false;\r
+\r
+                                       this.lockRatio = true;\r
+                                       this.userlockRatio = 0;\r
+                                       this.dontResetSize = false;\r
+                                       this.firstLoad = true;\r
+                                       this.addLink = false;\r
+\r
+                                       var editor = this.getParentEditor(),\r
+                                               sel = editor.getSelection(),\r
+                                               element = sel && sel.getSelectedElement(),\r
+                                               link = element && editor.elementPath( element ).contains( 'a', 1 ),\r
+                                               loader = CKEDITOR.document.getById( imagePreviewLoaderId );\r
+\r
+                                       // Hide loader.\r
+                                       if ( loader )\r
+                                               loader.setStyle( 'display', 'none' );\r
+\r
+                                       // Create the preview before setup the dialog contents.\r
+                                       previewPreloader = new CKEDITOR.dom.element( 'img', editor.document );\r
+                                       this.preview = CKEDITOR.document.getById( previewImageId );\r
+\r
+                                       // Copy of the image\r
+                                       this.originalElement = editor.document.createElement( 'img' );\r
+                                       this.originalElement.setAttribute( 'alt', '' );\r
+                                       this.originalElement.setCustomData( 'isReady', 'false' );\r
+\r
+                                       if ( link ) {\r
+                                               this.linkElement = link;\r
+                                               this.linkEditMode = true;\r
+\r
+                                               // If there is an existing link, by default keep it (true).\r
+                                               // It will be removed if certain conditions are met and Link tab is enabled. (#13351)\r
+                                               this.addLink = true;\r
+\r
+                                               // Look for Image element.\r
+                                               var linkChildren = link.getChildren();\r
+                                               if ( linkChildren.count() == 1 ) {\r
+                                                       var childTag = linkChildren.getItem( 0 );\r
+\r
+                                                       if ( childTag.type == CKEDITOR.NODE_ELEMENT ) {\r
+                                                               if ( childTag.is( 'img' ) || childTag.is( 'input' ) ) {\r
+                                                                       this.imageElement = linkChildren.getItem( 0 );\r
+                                                                       if ( this.imageElement.is( 'img' ) )\r
+                                                                               this.imageEditMode = 'img';\r
+                                                                       else if ( this.imageElement.is( 'input' ) )\r
+                                                                               this.imageEditMode = 'input';\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                               // Fill out all fields.\r
+                                               if ( dialogType == 'image' )\r
+                                                       this.setupContent( LINK, link );\r
+                                       }\r
+\r
+                                       // Edit given image element instead the one from selection.\r
+                                       if ( this.customImageElement ) {\r
+                                               this.imageEditMode = 'img';\r
+                                               this.imageElement = this.customImageElement;\r
+                                               delete this.customImageElement;\r
+                                       }\r
+                                       else if ( element && element.getName() == 'img' && !element.data( 'cke-realelement' ) ||\r
+                                               element && element.getName() == 'input' && element.getAttribute( 'type' ) == 'image' ) {\r
+                                               this.imageEditMode = element.getName();\r
+                                               this.imageElement = element;\r
+                                       }\r
+\r
+                                       if ( this.imageEditMode ) {\r
+                                               // Use the original element as a buffer from  since we don't want\r
+                                               // temporary changes to be committed, e.g. if the dialog is canceled.\r
+                                               this.cleanImageElement = this.imageElement;\r
+                                               this.imageElement = this.cleanImageElement.clone( true, true );\r
+\r
+                                               // Fill out all fields.\r
+                                               this.setupContent( IMAGE, this.imageElement );\r
+                                       }\r
+\r
+                                       // Refresh LockRatio button\r
+                                       switchLockRatio( this, true );\r
+\r
+                                       // Dont show preview if no URL given.\r
+                                       if ( !CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtUrl' ) ) ) {\r
+                                               this.preview.removeAttribute( 'src' );\r
+                                               this.preview.setStyle( 'display', 'none' );\r
+                                       }\r
+                               },\r
+                               onOk: function() {\r
+                                       // Edit existing Image.\r
+                                       if ( this.imageEditMode ) {\r
+                                               var imgTagName = this.imageEditMode;\r
+\r
+                                               // Image dialog and Input element.\r
+                                               if ( dialogType == 'image' && imgTagName == 'input' && confirm( editor.lang.image.button2Img ) ) { // jshint ignore:line\r
+                                                       // Replace INPUT-> IMG\r
+                                                       imgTagName = 'img';\r
+                                                       this.imageElement = editor.document.createElement( 'img' );\r
+                                                       this.imageElement.setAttribute( 'alt', '' );\r
+                                                       editor.insertElement( this.imageElement );\r
+                                               }\r
+                                               // ImageButton dialog and Image element.\r
+                                               else if ( dialogType != 'image' && imgTagName == 'img' && confirm( editor.lang.image.img2Button ) ) { // jshint ignore:line\r
+                                                       // Replace IMG -> INPUT\r
+                                                       imgTagName = 'input';\r
+                                                       this.imageElement = editor.document.createElement( 'input' );\r
+                                                       this.imageElement.setAttributes( {\r
+                                                               type: 'image',\r
+                                                               alt: ''\r
+                                                       } );\r
+                                                       editor.insertElement( this.imageElement );\r
+                                               } else {\r
+                                                       // Restore the original element before all commits.\r
+                                                       this.imageElement = this.cleanImageElement;\r
+                                                       delete this.cleanImageElement;\r
+                                               }\r
+                                       }\r
+                                       // Create a new image.\r
+                                       else {\r
+                                               // Image dialog -> create IMG element.\r
+                                               if ( dialogType == 'image' )\r
+                                                       this.imageElement = editor.document.createElement( 'img' );\r
+                                               else {\r
+                                                       this.imageElement = editor.document.createElement( 'input' );\r
+                                                       this.imageElement.setAttribute( 'type', 'image' );\r
+                                               }\r
+                                               this.imageElement.setAttribute( 'alt', '' );\r
+                                       }\r
+\r
+                                       // Create a new link.\r
+                                       if ( !this.linkEditMode )\r
+                                               this.linkElement = editor.document.createElement( 'a' );\r
+\r
+                                       // Set attributes.\r
+                                       this.commitContent( IMAGE, this.imageElement );\r
+                                       this.commitContent( LINK, this.linkElement );\r
+\r
+                                       // Remove empty style attribute.\r
+                                       if ( !this.imageElement.getAttribute( 'style' ) )\r
+                                               this.imageElement.removeAttribute( 'style' );\r
+\r
+                                       // Insert a new Image.\r
+                                       if ( !this.imageEditMode ) {\r
+                                               if ( this.addLink ) {\r
+                                                       if ( !this.linkEditMode ) {\r
+                                                               // Insert a new link.\r
+                                                               editor.insertElement( this.linkElement );\r
+                                                               this.linkElement.append( this.imageElement, false );\r
+                                                       } else {\r
+                                                               // We already have a link in editor.\r
+                                                               if ( this.linkElement.equals( editor.getSelection().getSelectedElement() ) ) {\r
+                                                                       // If the link is selected outside, replace it's content rather than the link itself. ([<a>foo</a>])\r
+                                                                       this.linkElement.setHtml( '' );\r
+                                                                       this.linkElement.append( this.imageElement, false );\r
+                                                               } else {\r
+                                                                       // Only inside of the link is selected, so replace it with image. (<a>[foo]</a>, <a>[f]oo</a>)\r
+                                                                       editor.insertElement( this.imageElement );\r
+                                                               }\r
+                                                       }\r
+                                               } else {\r
+                                                       editor.insertElement( this.imageElement );\r
+                                               }\r
+                                       }\r
+                                       // Image already exists.\r
+                                       else {\r
+                                               // Add a new link element.\r
+                                               if ( !this.linkEditMode && this.addLink ) {\r
+                                                       editor.insertElement( this.linkElement );\r
+                                                       this.imageElement.appendTo( this.linkElement );\r
+                                               }\r
+                                               // Remove Link, Image exists.\r
+                                               else if ( this.linkEditMode && !this.addLink ) {\r
+                                                       editor.getSelection().selectElement( this.linkElement );\r
+                                                       editor.insertElement( this.imageElement );\r
+                                               }\r
+                                       }\r
+                               },\r
+                               onLoad: function() {\r
+                                       if ( dialogType != 'image' )\r
+                                               this.hidePage( 'Link' ); //Hide Link tab.\r
+                                       var doc = this._.element.getDocument();\r
+\r
+                                       if ( this.getContentElement( 'info', 'ratioLock' ) ) {\r
+                                               this.addFocusable( doc.getById( btnResetSizeId ), 5 );\r
+                                               this.addFocusable( doc.getById( btnLockSizesId ), 5 );\r
+                                       }\r
+\r
+                                       this.commitContent = commitContent;\r
+                               },\r
+                               onHide: function() {\r
+                                       if ( this.preview )\r
+                                               this.commitContent( CLEANUP, this.preview );\r
+\r
+                                       if ( this.originalElement ) {\r
+                                               this.originalElement.removeListener( 'load', onImgLoadEvent );\r
+                                               this.originalElement.removeListener( 'error', onImgLoadErrorEvent );\r
+                                               this.originalElement.removeListener( 'abort', onImgLoadErrorEvent );\r
+                                               this.originalElement.remove();\r
+                                               this.originalElement = false; // Dialog is closed.\r
+                                       }\r
+\r
+                                       delete this.imageElement;\r
+                               },\r
+                               contents: [ {\r
+                                       id: 'info',\r
+                                       label: editor.lang.image.infoTab,\r
+                                       accessKey: 'I',\r
+                                       elements: [ {\r
+                                               type: 'vbox',\r
+                                               padding: 0,\r
+                                               children: [ {\r
+                                                       type: 'hbox',\r
+                                                       widths: [ '280px', '110px' ],\r
+                                                       align: 'right',\r
+                                                       className: 'cke_dialog_image_url',\r
+                                                       children: [ {\r
+                                                               id: 'txtUrl',\r
+                                                               type: 'text',\r
+                                                               label: editor.lang.common.url,\r
+                                                               required: true,\r
+                                                               onChange: function() {\r
+                                                                       var dialog = this.getDialog(),\r
+                                                                               newUrl = this.getValue();\r
+\r
+                                                                       // Update original image.\r
+                                                                       // Prevent from load before onShow.\r
+                                                                       if ( newUrl.length > 0 ) {\r
+                                                                               dialog = this.getDialog();\r
+                                                                               var original = dialog.originalElement;\r
+\r
+                                                                               if ( dialog.preview ) {\r
+                                                                                       dialog.preview.removeStyle( 'display' );\r
+                                                                               }\r
+\r
+                                                                               original.setCustomData( 'isReady', 'false' );\r
+                                                                               // Show loader.\r
+                                                                               var loader = CKEDITOR.document.getById( imagePreviewLoaderId );\r
+                                                                               if ( loader )\r
+                                                                                       loader.setStyle( 'display', '' );\r
+\r
+                                                                               original.on( 'load', onImgLoadEvent, dialog );\r
+                                                                               original.on( 'error', onImgLoadErrorEvent, dialog );\r
+                                                                               original.on( 'abort', onImgLoadErrorEvent, dialog );\r
+                                                                               original.setAttribute( 'src', newUrl );\r
+\r
+                                                                               if ( dialog.preview ) {\r
+                                                                                       // Query the preloader to figure out the url impacted by based href.\r
+                                                                                       previewPreloader.setAttribute( 'src', newUrl );\r
+                                                                                       dialog.preview.setAttribute( 'src', previewPreloader.$.src );\r
+                                                                                       updatePreview( dialog );\r
+                                                                               }\r
+                                                                       }\r
+                                                                       // Dont show preview if no URL given.\r
+                                                                       else if ( dialog.preview ) {\r
+                                                                               dialog.preview.removeAttribute( 'src' );\r
+                                                                               dialog.preview.setStyle( 'display', 'none' );\r
+                                                                       }\r
+                                                               },\r
+                                                               setup: function( type, element ) {\r
+                                                                       if ( type == IMAGE ) {\r
+                                                                               var url = element.data( 'cke-saved-src' ) || element.getAttribute( 'src' );\r
+                                                                               var field = this;\r
+\r
+                                                                               this.getDialog().dontResetSize = true;\r
+\r
+                                                                               field.setValue( url ); // And call this.onChange()\r
+                                                                               // Manually set the initial value.(#4191)\r
+                                                                               field.setInitValue();\r
+                                                                       }\r
+                                                               },\r
+                                                               commit: function( type, element ) {\r
+                                                                       if ( type == IMAGE && ( this.getValue() || this.isChanged() ) ) {\r
+                                                                               element.data( 'cke-saved-src', this.getValue() );\r
+                                                                               element.setAttribute( 'src', this.getValue() );\r
+                                                                       } else if ( type == CLEANUP ) {\r
+                                                                               element.setAttribute( 'src', '' ); // If removeAttribute doesn't work.\r
+                                                                               element.removeAttribute( 'src' );\r
+                                                                       }\r
+                                                               },\r
+                                                               validate: CKEDITOR.dialog.validate.notEmpty( editor.lang.image.urlMissing )\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'button',\r
+                                                               id: 'browse',\r
+                                                               // v-align with the 'txtUrl' field.\r
+                                                               // TODO: We need something better than a fixed size here.\r
+                                                               style: 'display:inline-block;margin-top:14px;',\r
+                                                               align: 'center',\r
+                                                               label: editor.lang.common.browseServer,\r
+                                                               hidden: true,\r
+                                                               filebrowser: 'info:txtUrl'\r
+                                                       } ]\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               id: 'txtAlt',\r
+                                               type: 'text',\r
+                                               label: editor.lang.image.alt,\r
+                                               accessKey: 'T',\r
+                                               'default': '',\r
+                                               onChange: function() {\r
+                                                       updatePreview( this.getDialog() );\r
+                                               },\r
+                                               setup: function( type, element ) {\r
+                                                       if ( type == IMAGE )\r
+                                                               this.setValue( element.getAttribute( 'alt' ) );\r
+                                               },\r
+                                               commit: function( type, element ) {\r
+                                                       if ( type == IMAGE ) {\r
+                                                               if ( this.getValue() || this.isChanged() )\r
+                                                                       element.setAttribute( 'alt', this.getValue() );\r
+                                                       } else if ( type == PREVIEW )\r
+                                                               element.setAttribute( 'alt', this.getValue() );\r
+                                                       else if ( type == CLEANUP ) {\r
+                                                               element.removeAttribute( 'alt' );\r
+                                                       }\r
+\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               children: [ {\r
+                                                       id: 'basic',\r
+                                                       type: 'vbox',\r
+                                                       children: [ {\r
+                                                               type: 'hbox',\r
+                                                               requiredContent: 'img{width,height}',\r
+                                                               widths: [ '50%', '50%' ],\r
+                                                               children: [ {\r
+                                                                       type: 'vbox',\r
+                                                                       padding: 1,\r
+                                                                       children: [ {\r
+                                                                               type: 'text',\r
+                                                                               width: '45px',\r
+                                                                               id: 'txtWidth',\r
+                                                                               label: editor.lang.common.width,\r
+                                                                               onKeyUp: onSizeChange,\r
+                                                                               onChange: function() {\r
+                                                                                       commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                               },\r
+                                                                               validate: function() {\r
+                                                                                       var aMatch = this.getValue().match( regexGetSizeOrEmpty ),\r
+                                                                                               isValid = !!( aMatch && parseInt( aMatch[ 1 ], 10 ) !== 0 );\r
+                                                                                       if ( !isValid )\r
+                                                                                               alert( editor.lang.common.invalidWidth ); // jshint ignore:line\r
+                                                                                       return isValid;\r
+                                                                               },\r
+                                                                               setup: setupDimension,\r
+                                                                               commit: function( type, element ) {\r
+                                                                                       var value = this.getValue();\r
+                                                                                       if ( type == IMAGE ) {\r
+                                                                                               if ( value && editor.activeFilter.check( 'img{width,height}' ) )\r
+                                                                                                       element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               else\r
+                                                                                                       element.removeStyle( 'width' );\r
+\r
+                                                                                               element.removeAttribute( 'width' );\r
+                                                                                       } else if ( type == PREVIEW ) {\r
+                                                                                               var aMatch = value.match( regexGetSize );\r
+                                                                                               if ( !aMatch ) {\r
+                                                                                                       var oImageOriginal = this.getDialog().originalElement;\r
+                                                                                                       if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
+                                                                                                               element.setStyle( 'width', oImageOriginal.$.width + 'px' );\r
+                                                                                               } else {\r
+                                                                                                       element.setStyle( 'width', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               }\r
+                                                                                       } else if ( type == CLEANUP ) {\r
+                                                                                               element.removeAttribute( 'width' );\r
+                                                                                               element.removeStyle( 'width' );\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       },\r
+                                                                       {\r
+                                                                               type: 'text',\r
+                                                                               id: 'txtHeight',\r
+                                                                               width: '45px',\r
+                                                                               label: editor.lang.common.height,\r
+                                                                               onKeyUp: onSizeChange,\r
+                                                                               onChange: function() {\r
+                                                                                       commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                               },\r
+                                                                               validate: function() {\r
+                                                                                       var aMatch = this.getValue().match( regexGetSizeOrEmpty ),\r
+                                                                                               isValid = !!( aMatch && parseInt( aMatch[ 1 ], 10 ) !== 0 );\r
+                                                                                       if ( !isValid )\r
+                                                                                               alert( editor.lang.common.invalidHeight ); // jshint ignore:line\r
+                                                                                       return isValid;\r
+                                                                               },\r
+                                                                               setup: setupDimension,\r
+                                                                               commit: function( type, element ) {\r
+                                                                                       var value = this.getValue();\r
+                                                                                       if ( type == IMAGE ) {\r
+                                                                                               if ( value && editor.activeFilter.check( 'img{width,height}' ) )\r
+                                                                                                       element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               else\r
+                                                                                                       element.removeStyle( 'height' );\r
+\r
+                                                                                               element.removeAttribute( 'height' );\r
+                                                                                       } else if ( type == PREVIEW ) {\r
+                                                                                               var aMatch = value.match( regexGetSize );\r
+                                                                                               if ( !aMatch ) {\r
+                                                                                                       var oImageOriginal = this.getDialog().originalElement;\r
+                                                                                                       if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' )\r
+                                                                                                               element.setStyle( 'height', oImageOriginal.$.height + 'px' );\r
+                                                                                               } else {\r
+                                                                                                       element.setStyle( 'height', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               }\r
+                                                                                       } else if ( type == CLEANUP ) {\r
+                                                                                               element.removeAttribute( 'height' );\r
+                                                                                               element.removeStyle( 'height' );\r
+                                                                                       }\r
+                                                                               }\r
+                                                                       } ]\r
+                                                               },\r
+                                                               {\r
+                                                                       id: 'ratioLock',\r
+                                                                       type: 'html',\r
+                                                                       className: 'cke_dialog_image_ratiolock',\r
+                                                                       style: 'margin-top:30px;width:40px;height:40px;',\r
+                                                                       onLoad: function() {\r
+                                                                               // Activate Reset button\r
+                                                                               var resetButton = CKEDITOR.document.getById( btnResetSizeId ),\r
+                                                                                       ratioButton = CKEDITOR.document.getById( btnLockSizesId );\r
+                                                                               if ( resetButton ) {\r
+                                                                                       resetButton.on( 'click', function( evt ) {\r
+                                                                                               resetSize( this );\r
+                                                                                               evt.data && evt.data.preventDefault();\r
+                                                                                       }, this.getDialog() );\r
+                                                                                       resetButton.on( 'mouseover', function() {\r
+                                                                                               this.addClass( 'cke_btn_over' );\r
+                                                                                       }, resetButton );\r
+                                                                                       resetButton.on( 'mouseout', function() {\r
+                                                                                               this.removeClass( 'cke_btn_over' );\r
+                                                                                       }, resetButton );\r
+                                                                               }\r
+                                                                               // Activate (Un)LockRatio button\r
+                                                                               if ( ratioButton ) {\r
+                                                                                       ratioButton.on( 'click', function( evt ) {\r
+                                                                                               switchLockRatio( this );\r
+\r
+                                                                                               var oImageOriginal = this.originalElement,\r
+                                                                                                       width = this.getValueOf( 'info', 'txtWidth' );\r
+\r
+                                                                                               if ( oImageOriginal.getCustomData( 'isReady' ) == 'true' && width ) {\r
+                                                                                                       var height = oImageOriginal.$.height / oImageOriginal.$.width * width;\r
+                                                                                                       if ( !isNaN( height ) ) {\r
+                                                                                                               this.setValueOf( 'info', 'txtHeight', Math.round( height ) );\r
+                                                                                                               updatePreview( this );\r
+                                                                                                       }\r
+                                                                                               }\r
+                                                                                               evt.data && evt.data.preventDefault();\r
+                                                                                       }, this.getDialog() );\r
+                                                                                       ratioButton.on( 'mouseover', function() {\r
+                                                                                               this.addClass( 'cke_btn_over' );\r
+                                                                                       }, ratioButton );\r
+                                                                                       ratioButton.on( 'mouseout', function() {\r
+                                                                                               this.removeClass( 'cke_btn_over' );\r
+                                                                                       }, ratioButton );\r
+                                                                               }\r
+                                                                       },\r
+                                                                       html: '<div>' +\r
+                                                                               '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.lockRatio +\r
+                                                                               '" class="cke_btn_locked" id="' + btnLockSizesId + '" role="checkbox"><span class="cke_icon"></span><span class="cke_label">' + editor.lang.image.lockRatio + '</span></a>' +\r
+                                                                               '<a href="javascript:void(0)" tabindex="-1" title="' + editor.lang.image.resetSize +\r
+                                                                               '" class="cke_btn_reset" id="' + btnResetSizeId + '" role="button"><span class="cke_label">' + editor.lang.image.resetSize + '</span></a>' +\r
+                                                                               '</div>'\r
+                                                               } ]\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'vbox',\r
+                                                               padding: 1,\r
+                                                               children: [ {\r
+                                                                       type: 'text',\r
+                                                                       id: 'txtBorder',\r
+                                                                       requiredContent: 'img{border-width}',\r
+                                                                       width: '60px',\r
+                                                                       label: editor.lang.image.border,\r
+                                                                       'default': '',\r
+                                                                       onKeyUp: function() {\r
+                                                                               updatePreview( this.getDialog() );\r
+                                                                       },\r
+                                                                       onChange: function() {\r
+                                                                               commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                       },\r
+                                                                       validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateBorder ),\r
+                                                                       setup: function( type, element ) {\r
+                                                                               if ( type == IMAGE ) {\r
+                                                                                       var value,\r
+                                                                                               borderStyle = element.getStyle( 'border-width' );\r
+                                                                                       borderStyle = borderStyle && borderStyle.match( /^(\d+px)(?: \1 \1 \1)?$/ );\r
+                                                                                       value = borderStyle && parseInt( borderStyle[ 1 ], 10 );\r
+                                                                                       isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'border' ) );\r
+                                                                                       this.setValue( value );\r
+                                                                               }\r
+                                                                       },\r
+                                                                       commit: function( type, element ) {\r
+                                                                               var value = parseInt( this.getValue(), 10 );\r
+                                                                               if ( type == IMAGE || type == PREVIEW ) {\r
+                                                                                       if ( !isNaN( value ) ) {\r
+                                                                                               element.setStyle( 'border-width', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               element.setStyle( 'border-style', 'solid' );\r
+                                                                                       } else if ( !value && this.isChanged() ) {\r
+                                                                                               element.removeStyle( 'border' );\r
+                                                                                       }\r
+\r
+                                                                                       if ( type == IMAGE )\r
+                                                                                               element.removeAttribute( 'border' );\r
+                                                                               } else if ( type == CLEANUP ) {\r
+                                                                                       element.removeAttribute( 'border' );\r
+                                                                                       element.removeStyle( 'border-width' );\r
+                                                                                       element.removeStyle( 'border-style' );\r
+                                                                                       element.removeStyle( 'border-color' );\r
+                                                                               }\r
+                                                                       }\r
+                                                               },\r
+                                                               {\r
+                                                                       type: 'text',\r
+                                                                       id: 'txtHSpace',\r
+                                                                       requiredContent: 'img{margin-left,margin-right}',\r
+                                                                       width: '60px',\r
+                                                                       label: editor.lang.image.hSpace,\r
+                                                                       'default': '',\r
+                                                                       onKeyUp: function() {\r
+                                                                               updatePreview( this.getDialog() );\r
+                                                                       },\r
+                                                                       onChange: function() {\r
+                                                                               commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                       },\r
+                                                                       validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateHSpace ),\r
+                                                                       setup: function( type, element ) {\r
+                                                                               if ( type == IMAGE ) {\r
+                                                                                       var value, marginLeftPx, marginRightPx,\r
+                                                                                               marginLeftStyle = element.getStyle( 'margin-left' ),\r
+                                                                                               marginRightStyle = element.getStyle( 'margin-right' );\r
+\r
+                                                                                       marginLeftStyle = marginLeftStyle && marginLeftStyle.match( pxLengthRegex );\r
+                                                                                       marginRightStyle = marginRightStyle && marginRightStyle.match( pxLengthRegex );\r
+                                                                                       marginLeftPx = parseInt( marginLeftStyle, 10 );\r
+                                                                                       marginRightPx = parseInt( marginRightStyle, 10 );\r
+\r
+                                                                                       value = ( marginLeftPx == marginRightPx ) && marginLeftPx;\r
+                                                                                       isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'hspace' ) );\r
+\r
+                                                                                       this.setValue( value );\r
+                                                                               }\r
+                                                                       },\r
+                                                                       commit: function( type, element ) {\r
+                                                                               var value = parseInt( this.getValue(), 10 );\r
+                                                                               if ( type == IMAGE || type == PREVIEW ) {\r
+                                                                                       if ( !isNaN( value ) ) {\r
+                                                                                               element.setStyle( 'margin-left', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               element.setStyle( 'margin-right', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                       } else if ( !value && this.isChanged() ) {\r
+                                                                                               element.removeStyle( 'margin-left' );\r
+                                                                                               element.removeStyle( 'margin-right' );\r
+                                                                                       }\r
+\r
+                                                                                       if ( type == IMAGE )\r
+                                                                                               element.removeAttribute( 'hspace' );\r
+                                                                               } else if ( type == CLEANUP ) {\r
+                                                                                       element.removeAttribute( 'hspace' );\r
+                                                                                       element.removeStyle( 'margin-left' );\r
+                                                                                       element.removeStyle( 'margin-right' );\r
+                                                                               }\r
+                                                                       }\r
+                                                               },\r
+                                                               {\r
+                                                                       type: 'text',\r
+                                                                       id: 'txtVSpace',\r
+                                                                       requiredContent: 'img{margin-top,margin-bottom}',\r
+                                                                       width: '60px',\r
+                                                                       label: editor.lang.image.vSpace,\r
+                                                                       'default': '',\r
+                                                                       onKeyUp: function() {\r
+                                                                               updatePreview( this.getDialog() );\r
+                                                                       },\r
+                                                                       onChange: function() {\r
+                                                                               commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                       },\r
+                                                                       validate: CKEDITOR.dialog.validate.integer( editor.lang.image.validateVSpace ),\r
+                                                                       setup: function( type, element ) {\r
+                                                                               if ( type == IMAGE ) {\r
+                                                                                       var value, marginTopPx, marginBottomPx,\r
+                                                                                               marginTopStyle = element.getStyle( 'margin-top' ),\r
+                                                                                               marginBottomStyle = element.getStyle( 'margin-bottom' );\r
+\r
+                                                                                       marginTopStyle = marginTopStyle && marginTopStyle.match( pxLengthRegex );\r
+                                                                                       marginBottomStyle = marginBottomStyle && marginBottomStyle.match( pxLengthRegex );\r
+                                                                                       marginTopPx = parseInt( marginTopStyle, 10 );\r
+                                                                                       marginBottomPx = parseInt( marginBottomStyle, 10 );\r
+\r
+                                                                                       value = ( marginTopPx == marginBottomPx ) && marginTopPx;\r
+                                                                                       isNaN( parseInt( value, 10 ) ) && ( value = element.getAttribute( 'vspace' ) );\r
+                                                                                       this.setValue( value );\r
+                                                                               }\r
+                                                                       },\r
+                                                                       commit: function( type, element ) {\r
+                                                                               var value = parseInt( this.getValue(), 10 );\r
+                                                                               if ( type == IMAGE || type == PREVIEW ) {\r
+                                                                                       if ( !isNaN( value ) ) {\r
+                                                                                               element.setStyle( 'margin-top', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                               element.setStyle( 'margin-bottom', CKEDITOR.tools.cssLength( value ) );\r
+                                                                                       } else if ( !value && this.isChanged() ) {\r
+                                                                                               element.removeStyle( 'margin-top' );\r
+                                                                                               element.removeStyle( 'margin-bottom' );\r
+                                                                                       }\r
+\r
+                                                                                       if ( type == IMAGE )\r
+                                                                                               element.removeAttribute( 'vspace' );\r
+                                                                               } else if ( type == CLEANUP ) {\r
+                                                                                       element.removeAttribute( 'vspace' );\r
+                                                                                       element.removeStyle( 'margin-top' );\r
+                                                                                       element.removeStyle( 'margin-bottom' );\r
+                                                                               }\r
+                                                                       }\r
+                                                               },\r
+                                                               {\r
+                                                                       id: 'cmbAlign',\r
+                                                                       requiredContent: 'img{float}',\r
+                                                                       type: 'select',\r
+                                                                       widths: [ '35%', '65%' ],\r
+                                                                       style: 'width:90px',\r
+                                                                       label: editor.lang.common.align,\r
+                                                                       'default': '',\r
+                                                                       items: [\r
+                                                                               [ editor.lang.common.notSet, '' ],\r
+                                                                               [ editor.lang.common.alignLeft, 'left' ],\r
+                                                                               [ editor.lang.common.alignRight, 'right' ]\r
+                                                                               // Backward compatible with v2 on setup when specified as attribute value,\r
+                                                                               // while these values are no more available as select options.\r
+                                                                               //      [ editor.lang.image.alignAbsBottom , 'absBottom'],\r
+                                                                               //      [ editor.lang.image.alignAbsMiddle , 'absMiddle'],\r
+                                                                               //  [ editor.lang.image.alignBaseline , 'baseline'],\r
+                                                                               //  [ editor.lang.image.alignTextTop , 'text-top'],\r
+                                                                               //  [ editor.lang.image.alignBottom , 'bottom'],\r
+                                                                               //  [ editor.lang.image.alignMiddle , 'middle'],\r
+                                                                               //  [ editor.lang.image.alignTop , 'top']\r
+                                                                       ],\r
+                                                                       onChange: function() {\r
+                                                                               updatePreview( this.getDialog() );\r
+                                                                               commitInternally.call( this, 'advanced:txtdlgGenStyle' );\r
+                                                                       },\r
+                                                                       setup: function( type, element ) {\r
+                                                                               if ( type == IMAGE ) {\r
+                                                                                       var value = element.getStyle( 'float' );\r
+                                                                                       switch ( value ) {\r
+                                                                                               // Ignore those unrelated values.\r
+                                                                                               case 'inherit':\r
+                                                                                               case 'none':\r
+                                                                                                       value = '';\r
+                                                                                       }\r
+\r
+                                                                                       !value && ( value = ( element.getAttribute( 'align' ) || '' ).toLowerCase() );\r
+                                                                                       this.setValue( value );\r
+                                                                               }\r
+                                                                       },\r
+                                                                       commit: function( type, element ) {\r
+                                                                               var value = this.getValue();\r
+                                                                               if ( type == IMAGE || type == PREVIEW ) {\r
+                                                                                       if ( value )\r
+                                                                                               element.setStyle( 'float', value );\r
+                                                                                       else\r
+                                                                                               element.removeStyle( 'float' );\r
+\r
+                                                                                       if ( type == IMAGE ) {\r
+                                                                                               value = ( element.getAttribute( 'align' ) || '' ).toLowerCase();\r
+                                                                                               switch ( value ) {\r
+                                                                                                       // we should remove it only if it matches "left" or "right",\r
+                                                                                                       // otherwise leave it intact.\r
+                                                                                                       case 'left':\r
+                                                                                                       case 'right':\r
+                                                                                                               element.removeAttribute( 'align' );\r
+                                                                                               }\r
+                                                                                       }\r
+                                                                               } else if ( type == CLEANUP ) {\r
+                                                                                       element.removeStyle( 'float' );\r
+                                                                               }\r
+                                                                       }\r
+                                                               } ]\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'vbox',\r
+                                                       height: '250px',\r
+                                                       children: [ {\r
+                                                               type: 'html',\r
+                                                               id: 'htmlPreview',\r
+                                                               style: 'width:95%;',\r
+                                                               html: '<div>' + CKEDITOR.tools.htmlEncode( editor.lang.common.preview ) + '<br>' +\r
+                                                                       '<div id="' + imagePreviewLoaderId + '" class="ImagePreviewLoader" style="display:none"><div class="loading">&nbsp;</div></div>' +\r
+                                                                       '<div class="ImagePreviewBox"><table><tr><td>' +\r
+                                                                               '<a href="javascript:void(0)" target="_blank" onclick="return false;" id="' + previewLinkId + '">' +\r
+                                                                               '<img id="' + previewImageId + '" alt="" /></a>' +\r
+                                                                       // jscs:disable maximumLineLength\r
+                                                                               ( editor.config.image_previewText || 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' +\r
+                                                                                       'Maecenas feugiat consequat diam. Maecenas metus. Vivamus diam purus, cursus a, commodo non, facilisis vitae, ' +\r
+                                                                                       'nulla. Aenean dictum lacinia tortor. Nunc iaculis, nibh non iaculis aliquam, orci felis euismod neque, sed ornare massa mauris sed velit. Nulla pretium mi et risus. Fusce mi pede, tempor id, cursus ac, ullamcorper nec, enim. Sed tortor. Curabitur molestie. Duis velit augue, condimentum at, ultrices a, luctus ut, orci. Donec pellentesque egestas eros. Integer cursus, augue in cursus faucibus, eros pede bibendum sem, in tempus tellus justo quis ligula. Etiam eget tortor. Vestibulum rutrum, est ut placerat elementum, lectus nisl aliquam velit, tempor aliquam eros nunc nonummy metus. In eros metus, gravida a, gravida sed, lobortis id, turpis. Ut ultrices, ipsum at venenatis fringilla, sem nulla lacinia tellus, eget aliquet turpis mauris non enim. Nam turpis. Suspendisse lacinia. Curabitur ac tortor ut ipsum egestas elementum. Nunc imperdiet gravida mauris.' ) +\r
+                                                                       // jscs:enable maximumLineLength\r
+                                                                       '</td></tr></table></div></div>'\r
+                                                       } ]\r
+                                               } ]\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       id: 'Link',\r
+                                       requiredContent: 'a[href]',\r
+                                       label: editor.lang.image.linkTab,\r
+                                       padding: 0,\r
+                                       elements: [ {\r
+                                               id: 'txtUrl',\r
+                                               type: 'text',\r
+                                               label: editor.lang.common.url,\r
+                                               style: 'width: 100%',\r
+                                               'default': '',\r
+                                               setup: function( type, element ) {\r
+                                                       if ( type == LINK ) {\r
+                                                               var href = element.data( 'cke-saved-href' );\r
+                                                               if ( !href )\r
+                                                                       href = element.getAttribute( 'href' );\r
+                                                               this.setValue( href );\r
+                                                       }\r
+                                               },\r
+                                               commit: function( type, element ) {\r
+                                                       if ( type == LINK ) {\r
+                                                               if ( this.getValue() || this.isChanged() ) {\r
+                                                                       var url = this.getValue();\r
+                                                                       element.data( 'cke-saved-href', url );\r
+                                                                       element.setAttribute( 'href', url );\r
+\r
+                                                                       if ( this.getValue() || !editor.config.image_removeLinkByEmptyURL )\r
+                                                                               this.getDialog().addLink = true;\r
+                                                                       else\r
+                                                                               this.getDialog().addLink = false;\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'button',\r
+                                               id: 'browse',\r
+                                               className: 'cke_dialog_image_browse',\r
+                                               filebrowser: {\r
+                                                       action: 'Browse',\r
+                                                       target: 'Link:txtUrl',\r
+                                                       url: editor.config.filebrowserImageBrowseLinkUrl\r
+                                               },\r
+                                               style: 'float:right',\r
+                                               hidden: true,\r
+                                               label: editor.lang.common.browseServer\r
+                                       },\r
+                                       {\r
+                                               id: 'cmbTarget',\r
+                                               type: 'select',\r
+                                               requiredContent: 'a[target]',\r
+                                               label: editor.lang.common.target,\r
+                                               'default': '',\r
+                                               items: [\r
+                                                       [ editor.lang.common.notSet, '' ],\r
+                                                       [ editor.lang.common.targetNew, '_blank' ],\r
+                                                       [ editor.lang.common.targetTop, '_top' ],\r
+                                                       [ editor.lang.common.targetSelf, '_self' ],\r
+                                                       [ editor.lang.common.targetParent, '_parent' ]\r
+                                               ],\r
+                                               setup: function( type, element ) {\r
+                                                       if ( type == LINK )\r
+                                                               this.setValue( element.getAttribute( 'target' ) || '' );\r
+                                               },\r
+                                               commit: function( type, element ) {\r
+                                                       if ( type == LINK ) {\r
+                                                               if ( this.getValue() || this.isChanged() )\r
+                                                                       element.setAttribute( 'target', this.getValue() );\r
+                                                       }\r
+                                               }\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       id: 'Upload',\r
+                                       hidden: true,\r
+                                       filebrowser: 'uploadButton',\r
+                                       label: editor.lang.image.upload,\r
+                                       elements: [ {\r
+                                               type: 'file',\r
+                                               id: 'upload',\r
+                                               label: editor.lang.image.btnUpload,\r
+                                               style: 'height:40px',\r
+                                               size: 38\r
+                                       },\r
+                                       {\r
+                                               type: 'fileButton',\r
+                                               id: 'uploadButton',\r
+                                               filebrowser: 'info:txtUrl',\r
+                                               label: editor.lang.image.btnUpload,\r
+                                               'for': [ 'Upload', 'upload' ]\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       id: 'advanced',\r
+                                       label: editor.lang.common.advancedTab,\r
+                                       elements: [ {\r
+                                               type: 'hbox',\r
+                                               widths: [ '50%', '25%', '25%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       id: 'linkId',\r
+                                                       requiredContent: 'img[id]',\r
+                                                       label: editor.lang.common.id,\r
+                                                       setup: function( type, element ) {\r
+                                                               if ( type == IMAGE )\r
+                                                                       this.setValue( element.getAttribute( 'id' ) );\r
+                                                       },\r
+                                                       commit: function( type, element ) {\r
+                                                               if ( type == IMAGE ) {\r
+                                                                       if ( this.getValue() || this.isChanged() )\r
+                                                                               element.setAttribute( 'id', this.getValue() );\r
+                                                               }\r
+                                                       }\r
+                                               },\r
+                                               {\r
+                                                       id: 'cmbLangDir',\r
+                                                       type: 'select',\r
+                                                       requiredContent: 'img[dir]',\r
+                                                       style: 'width : 100px;',\r
+                                                       label: editor.lang.common.langDir,\r
+                                                       'default': '',\r
+                                                       items: [\r
+                                                               [ editor.lang.common.notSet, '' ],\r
+                                                               [ editor.lang.common.langDirLtr, 'ltr' ],\r
+                                                               [ editor.lang.common.langDirRtl, 'rtl' ]\r
+                                                       ],\r
+                                                       setup: function( type, element ) {\r
+                                                               if ( type == IMAGE )\r
+                                                                       this.setValue( element.getAttribute( 'dir' ) );\r
+                                                       },\r
+                                                       commit: function( type, element ) {\r
+                                                               if ( type == IMAGE ) {\r
+                                                                       if ( this.getValue() || this.isChanged() )\r
+                                                                               element.setAttribute( 'dir', this.getValue() );\r
+                                                               }\r
+                                                       }\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       id: 'txtLangCode',\r
+                                                       requiredContent: 'img[lang]',\r
+                                                       label: editor.lang.common.langCode,\r
+                                                       'default': '',\r
+                                                       setup: function( type, element ) {\r
+                                                               if ( type == IMAGE )\r
+                                                                       this.setValue( element.getAttribute( 'lang' ) );\r
+                                                       },\r
+                                                       commit: function( type, element ) {\r
+                                                               if ( type == IMAGE ) {\r
+                                                                       if ( this.getValue() || this.isChanged() )\r
+                                                                               element.setAttribute( 'lang', this.getValue() );\r
+                                                               }\r
+                                                       }\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'text',\r
+                                               id: 'txtGenLongDescr',\r
+                                               requiredContent: 'img[longdesc]',\r
+                                               label: editor.lang.common.longDescr,\r
+                                               setup: function( type, element ) {\r
+                                                       if ( type == IMAGE )\r
+                                                               this.setValue( element.getAttribute( 'longDesc' ) );\r
+                                               },\r
+                                               commit: function( type, element ) {\r
+                                                       if ( type == IMAGE ) {\r
+                                                               if ( this.getValue() || this.isChanged() )\r
+                                                                       element.setAttribute( 'longDesc', this.getValue() );\r
+                                                       }\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               widths: [ '50%', '50%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       id: 'txtGenClass',\r
+                                                       requiredContent: 'img(cke-xyz)', // Random text like 'xyz' will check if all are allowed.\r
+                                                       label: editor.lang.common.cssClass,\r
+                                                       'default': '',\r
+                                                       setup: function( type, element ) {\r
+                                                               if ( type == IMAGE )\r
+                                                                       this.setValue( element.getAttribute( 'class' ) );\r
+                                                       },\r
+                                                       commit: function( type, element ) {\r
+                                                               if ( type == IMAGE ) {\r
+                                                                       if ( this.getValue() || this.isChanged() )\r
+                                                                               element.setAttribute( 'class', this.getValue() );\r
+                                                               }\r
+                                                       }\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       id: 'txtGenTitle',\r
+                                                       requiredContent: 'img[title]',\r
+                                                       label: editor.lang.common.advisoryTitle,\r
+                                                       'default': '',\r
+                                                       onChange: function() {\r
+                                                               updatePreview( this.getDialog() );\r
+                                                       },\r
+                                                       setup: function( type, element ) {\r
+                                                               if ( type == IMAGE )\r
+                                                                       this.setValue( element.getAttribute( 'title' ) );\r
+                                                       },\r
+                                                       commit: function( type, element ) {\r
+                                                               if ( type == IMAGE ) {\r
+                                                                       if ( this.getValue() || this.isChanged() )\r
+                                                                               element.setAttribute( 'title', this.getValue() );\r
+                                                               } else if ( type == PREVIEW )\r
+                                                                       element.setAttribute( 'title', this.getValue() );\r
+                                                               else if ( type == CLEANUP ) {\r
+                                                                       element.removeAttribute( 'title' );\r
+                                                               }\r
+                                                       }\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'text',\r
+                                               id: 'txtdlgGenStyle',\r
+                                               requiredContent: 'img{cke-xyz}', // Random text like 'xyz' will check if all are allowed.\r
+                                               label: editor.lang.common.cssStyle,\r
+                                               validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ),\r
+                                               'default': '',\r
+                                               setup: function( type, element ) {\r
+                                                       if ( type == IMAGE ) {\r
+                                                               var genStyle = element.getAttribute( 'style' );\r
+                                                               if ( !genStyle && element.$.style.cssText )\r
+                                                                       genStyle = element.$.style.cssText;\r
+                                                               this.setValue( genStyle );\r
+\r
+                                                               var height = element.$.style.height,\r
+                                                                       width = element.$.style.width,\r
+                                                                       aMatchH = ( height ? height : '' ).match( regexGetSize ),\r
+                                                                       aMatchW = ( width ? width : '' ).match( regexGetSize );\r
+\r
+                                                               this.attributesInStyle = {\r
+                                                                       height: !!aMatchH,\r
+                                                                       width: !!aMatchW\r
+                                                               };\r
+                                                       }\r
+                                               },\r
+                                               onChange: function() {\r
+                                                       commitInternally.call(\r
+                                                               this, [\r
+                                                                       'info:cmbFloat',\r
+                                                                       'info:cmbAlign',\r
+                                                                       'info:txtVSpace',\r
+                                                                       'info:txtHSpace',\r
+                                                                       'info:txtBorder',\r
+                                                                       'info:txtWidth',\r
+                                                                       'info:txtHeight'\r
+                                                               ]\r
+                                                       );\r
+                                                       updatePreview( this );\r
+                                               },\r
+                                               commit: function( type, element ) {\r
+                                                       if ( type == IMAGE && ( this.getValue() || this.isChanged() ) )\r
+                                                               element.setAttribute( 'style', this.getValue() );\r
+\r
+                                               }\r
+                                       } ]\r
+                               } ]\r
+                       };\r
+               };\r
+\r
+       CKEDITOR.dialog.add( 'image', function( editor ) {\r
+               return imageDialog( editor, 'image' );\r
+       } );\r
+\r
+       CKEDITOR.dialog.add( 'imagebutton', function( editor ) {\r
+               return imageDialog( editor, 'imagebutton' );\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/image/icons/hidpi/image.png b/sources/plugins/image/icons/hidpi/image.png
new file mode 100644 (file)
index 0000000..d0f21ae
Binary files /dev/null and b/sources/plugins/image/icons/hidpi/image.png differ
diff --git a/sources/plugins/image/icons/image.png b/sources/plugins/image/icons/image.png
new file mode 100644 (file)
index 0000000..8ea9725
Binary files /dev/null and b/sources/plugins/image/icons/image.png differ
diff --git a/sources/plugins/image/images/noimage.png b/sources/plugins/image/images/noimage.png
new file mode 100644 (file)
index 0000000..74c6ee9
Binary files /dev/null and b/sources/plugins/image/images/noimage.png differ
diff --git a/sources/plugins/image/lang/af.js b/sources/plugins/image/lang/af.js
new file mode 100644 (file)
index 0000000..8cc5b5f
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'af', {\r
+       alt: 'Alternatiewe teks',\r
+       border: 'Rand',\r
+       btnUpload: 'Stuur na bediener',\r
+       button2Img: 'Wil u die geselekteerde afbeeldingsknop vervang met \'n eenvoudige afbeelding?',\r
+       hSpace: 'HSpasie',\r
+       img2Button: 'Wil u die geselekteerde afbeelding vervang met \'n afbeeldingsknop?',\r
+       infoTab: 'Afbeelding informasie',\r
+       linkTab: 'Skakel',\r
+       lockRatio: 'Vaste proporsie',\r
+       menu: 'Afbeelding eienskappe',\r
+       resetSize: 'Herstel grootte',\r
+       title: 'Afbeelding eienskappe',\r
+       titleButton: 'Afbeeldingsknop eienskappe',\r
+       upload: 'Oplaai',\r
+       urlMissing: 'Die URL na die afbeelding ontbreek.',\r
+       vSpace: 'VSpasie',\r
+       validateBorder: 'Rand moet \'n heelgetal wees.',\r
+       validateHSpace: 'HSpasie moet \'n heelgetal wees.',\r
+       validateVSpace: 'VSpasie moet \'n heelgetal wees.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ar.js b/sources/plugins/image/lang/ar.js
new file mode 100644 (file)
index 0000000..a755b3e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ar', {\r
+       alt: 'عنوان الصورة',\r
+       border: 'سمك الحدود',\r
+       btnUpload: 'أرسلها للخادم',\r
+       button2Img: 'هل تريد تحويل زر الصورة المختار إلى صورة بسيطة؟',\r
+       hSpace: 'تباعد أفقي',\r
+       img2Button: 'هل تريد تحويل الصورة المختارة إلى زر صورة؟',\r
+       infoTab: 'معلومات الصورة',\r
+       linkTab: 'الرابط',\r
+       lockRatio: 'تناسق الحجم',\r
+       menu: 'خصائص الصورة',\r
+       resetSize: 'إستعادة الحجم الأصلي',\r
+       title: 'خصائص الصورة',\r
+       titleButton: 'خصائص زر الصورة',\r
+       upload: 'رفع',\r
+       urlMissing: 'عنوان مصدر الصورة مفقود',\r
+       vSpace: 'تباعد عمودي',\r
+       validateBorder: 'الإطار يجب أن يكون عددا',\r
+       validateHSpace: 'HSpace يجب أن يكون عدداً.',\r
+       validateVSpace: 'VSpace يجب أن يكون عدداً.'\r
+} );\r
diff --git a/sources/plugins/image/lang/az.js b/sources/plugins/image/lang/az.js
new file mode 100644 (file)
index 0000000..79009fa
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'az', {\r
+       alt: 'Alternativ mətn',\r
+       border: 'Sərhəd',\r
+       btnUpload: 'Serverə yüklə',\r
+       button2Img: 'Şəkil tipli düyməni şəklə çevirmək istədiyinizə əminsinizmi?',\r
+       hSpace: 'Üfüqi boşluq',\r
+       img2Button: 'Şəkli şəkil tipli düyməyə çevirmək istədiyinizə əminsinizmi?',\r
+       infoTab: 'Şəkil haqqında məlumat',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Ölçülərin uyğunluğu saxla',\r
+       menu: 'Şəklin seçimləri',\r
+       resetSize: 'Ölçüləri qaytar',\r
+       title: 'Şəklin seçimləri',\r
+       titleButton: 'Şəkil tipli düyməsinin seçimləri',\r
+       upload: 'Serverə yüklə',\r
+       urlMissing: 'Şəklin ünvanı yanlışdır.',\r
+       vSpace: 'Şaquli boşluq',\r
+       validateBorder: 'Sərhədin eni rəqəm olmalıdır.',\r
+       validateHSpace: 'Üfüqi boşluq rəqəm olmalıdır.',\r
+       validateVSpace: 'Şaquli boşluq rəqəm olmalıdır.'\r
+} );\r
diff --git a/sources/plugins/image/lang/bg.js b/sources/plugins/image/lang/bg.js
new file mode 100644 (file)
index 0000000..6c0b064
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'bg', {\r
+       alt: 'Алтернативен текст',\r
+       border: 'Рамка',\r
+       btnUpload: 'Изпрати я на сървъра',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'Хоризонтален отстъп',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Инфо за снимка',\r
+       linkTab: 'Връзка',\r
+       lockRatio: 'Заключване на съотношението',\r
+       menu: 'Настройки за снимка',\r
+       resetSize: 'Нулиране на размер',\r
+       title: 'Настройки за снимка',\r
+       titleButton: 'Настойки за бутон за снимка',\r
+       upload: 'Качване',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'Вертикален отстъп',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/bn.js b/sources/plugins/image/lang/bn.js
new file mode 100644 (file)
index 0000000..bbecfc6
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'bn', {\r
+       alt: 'বিকল্প টেক্সট',\r
+       border: 'বর্ডার',\r
+       btnUpload: 'ইহাকে সার্ভারে প্রেরন কর',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'হরাইজন্টাল স্পেস',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'ছবির তথ্য',\r
+       linkTab: 'লিংক',\r
+       lockRatio: 'অনুপাত লক কর',\r
+       menu: 'ছবির প্রোপার্টি',\r
+       resetSize: 'সাইজ পূর্বাবস্থায় ফিরিয়ে দাও',\r
+       title: 'ছবির প্রোপার্টি',\r
+       titleButton: 'ছবির বাটন সম্বন্ধীয়',\r
+       upload: 'আপলোড',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'ভার্টিকেল স্পেস',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/bs.js b/sources/plugins/image/lang/bs.js
new file mode 100644 (file)
index 0000000..06dd8bf
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'bs', {\r
+       alt: 'Tekst na slici',\r
+       border: 'Okvir',\r
+       btnUpload: 'Šalji na server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Info slike',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Zakljuèaj odnos',\r
+       menu: 'Svojstva slike',\r
+       resetSize: 'Resetuj dimenzije',\r
+       title: 'Svojstva slike',\r
+       titleButton: 'Image Button Properties', // MISSING\r
+       upload: 'Šalji',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/ca.js b/sources/plugins/image/lang/ca.js
new file mode 100644 (file)
index 0000000..858013e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ca', {\r
+       alt: 'Text alternatiu',\r
+       border: 'Vora',\r
+       btnUpload: 'Envia-la al servidor',\r
+       button2Img: 'Voleu transformar el botó d\'imatge seleccionat en una simple imatge?',\r
+       hSpace: 'Espaiat horit.',\r
+       img2Button: 'Voleu transformar la imatge seleccionada en un botó d\'imatge?',\r
+       infoTab: 'Informació de la imatge',\r
+       linkTab: 'Enllaç',\r
+       lockRatio: 'Bloqueja les proporcions',\r
+       menu: 'Propietats de la imatge',\r
+       resetSize: 'Restaura la mida',\r
+       title: 'Propietats de la imatge',\r
+       titleButton: 'Propietats del botó d\'imatge',\r
+       upload: 'Puja',\r
+       urlMissing: 'Falta la URL de la imatge.',\r
+       vSpace: 'Espaiat vert.',\r
+       validateBorder: 'La vora ha de ser un nombre enter.',\r
+       validateHSpace: 'HSpace ha de ser un nombre enter.',\r
+       validateVSpace: 'VSpace ha de ser un nombre enter.'\r
+} );\r
diff --git a/sources/plugins/image/lang/cs.js b/sources/plugins/image/lang/cs.js
new file mode 100644 (file)
index 0000000..a18a753
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'cs', {\r
+       alt: 'Alternativní text',\r
+       border: 'Okraje',\r
+       btnUpload: 'Odeslat na server',\r
+       button2Img: 'Skutečně chcete převést zvolené obrázkové tlačítko na obyčejný obrázek?',\r
+       hSpace: 'Horizontální mezera',\r
+       img2Button: 'Skutečně chcete převést zvolený obrázek na obrázkové tlačítko?',\r
+       infoTab: 'Informace o obrázku',\r
+       linkTab: 'Odkaz',\r
+       lockRatio: 'Zámek',\r
+       menu: 'Vlastnosti obrázku',\r
+       resetSize: 'Původní velikost',\r
+       title: 'Vlastnosti obrázku',\r
+       titleButton: 'Vlastností obrázkového tlačítka',\r
+       upload: 'Odeslat',\r
+       urlMissing: 'Zadané URL zdroje obrázku nebylo nalezeno.',\r
+       vSpace: 'Vertikální mezera',\r
+       validateBorder: 'Okraj musí být nastaven v celých číslech.',\r
+       validateHSpace: 'Horizontální mezera musí být nastavena v celých číslech.',\r
+       validateVSpace: 'Vertikální mezera musí být nastavena v celých číslech.'\r
+} );\r
diff --git a/sources/plugins/image/lang/cy.js b/sources/plugins/image/lang/cy.js
new file mode 100644 (file)
index 0000000..7407310
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'cy', {\r
+       alt: 'Testun Amgen',\r
+       border: 'Ymyl',\r
+       btnUpload: 'Anfon i\'r Gweinydd',\r
+       button2Img: 'Ydych am drawsffurfio\'r botwm ddelwedd hwn ar ddelwedd syml?',\r
+       hSpace: 'BwlchLl',\r
+       img2Button: 'Ydych am drawsffurfio\'r ddelwedd hon ar fotwm delwedd?',\r
+       infoTab: 'Gwyb Delwedd',\r
+       linkTab: 'Dolen',\r
+       lockRatio: 'Cloi Cymhareb',\r
+       menu: 'Priodweddau Delwedd',\r
+       resetSize: 'Ailosod Maint',\r
+       title: 'Priodweddau Delwedd',\r
+       titleButton: 'Priodweddau Botwm Delwedd',\r
+       upload: 'Lanlwytho',\r
+       urlMissing: 'URL gwreiddiol y ddelwedd ar goll.',\r
+       vSpace: 'BwlchF',\r
+       validateBorder: 'Rhaid i\'r ymyl fod yn gyfanrif.',\r
+       validateHSpace: 'Rhaid i\'r HSpace fod yn gyfanrif.',\r
+       validateVSpace: 'Rhaid i\'r VSpace fod yn gyfanrif.'\r
+} );\r
diff --git a/sources/plugins/image/lang/da.js b/sources/plugins/image/lang/da.js
new file mode 100644 (file)
index 0000000..bec69ba
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'da', {\r
+       alt: 'Alternativ tekst',\r
+       border: 'Ramme',\r
+       btnUpload: 'Upload fil til serveren',\r
+       button2Img: 'Vil du lave billedknappen om til et almindeligt billede?',\r
+       hSpace: 'Vandret margen',\r
+       img2Button: 'Vil du lave billedet om til en billedknap?',\r
+       infoTab: 'Generelt',\r
+       linkTab: 'Hyperlink',\r
+       lockRatio: 'Lås størrelsesforhold',\r
+       menu: 'Egenskaber for billede',\r
+       resetSize: 'Nulstil størrelse',\r
+       title: 'Egenskaber for billede',\r
+       titleButton: 'Egenskaber for billedknap',\r
+       upload: 'Upload',\r
+       urlMissing: 'Kilde på billed-URL mangler',\r
+       vSpace: 'Lodret margen',\r
+       validateBorder: 'Kant skal være et helt nummer.',\r
+       validateHSpace: 'HSpace skal være et helt nummer.',\r
+       validateVSpace: 'VSpace skal være et helt nummer.'\r
+} );\r
diff --git a/sources/plugins/image/lang/de-ch.js b/sources/plugins/image/lang/de-ch.js
new file mode 100644 (file)
index 0000000..6ba1570
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'de-ch', {\r
+       alt: 'Alternativer Text',\r
+       border: 'Rahmen',\r
+       btnUpload: 'Zum Server senden',\r
+       button2Img: 'Möchten Sie die ausgewählte Bildschaltfläche in ein einfaches Bild umwandeln?',\r
+       hSpace: 'Horizontal-Abstand',\r
+       img2Button: 'Möchten Sie das ausgewählte Bild in eine Bildschaltfläche umwandeln?',\r
+       infoTab: 'Bildinfo',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Grössenverhältnis beibehalten',\r
+       menu: 'Bildeigenschaften',\r
+       resetSize: 'Grösse zurücksetzen',\r
+       title: 'Bildeigenschaften',\r
+       titleButton: 'Bildschaltflächeneigenschaften',\r
+       upload: 'Hochladen',\r
+       urlMissing: 'Bildquellen-URL fehlt.',\r
+       vSpace: 'Vertikal-Abstand',\r
+       validateBorder: 'Rahmen muss eine ganze Zahl sein.',\r
+       validateHSpace: 'Horizontal-Abstand muss eine ganze Zahl sein.',\r
+       validateVSpace: 'Vertikal-Abstand muss eine ganze Zahl sein.'\r
+} );\r
diff --git a/sources/plugins/image/lang/de.js b/sources/plugins/image/lang/de.js
new file mode 100644 (file)
index 0000000..a391934
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'de', {\r
+       alt: 'Alternativer Text',\r
+       border: 'Rahmen',\r
+       btnUpload: 'Zum Server senden',\r
+       button2Img: 'Möchten Sie die ausgewählte Bildschaltfläche in ein einfaches Bild umwandeln?',\r
+       hSpace: 'Horizontal-Abstand',\r
+       img2Button: 'Möchten Sie das ausgewählte Bild in eine Bildschaltfläche umwandeln?',\r
+       infoTab: 'Bildinfo',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Größenverhältnis beibehalten',\r
+       menu: 'Bildeigenschaften',\r
+       resetSize: 'Größe zurücksetzen',\r
+       title: 'Bildeigenschaften',\r
+       titleButton: 'Bildschaltflächeneigenschaften',\r
+       upload: 'Hochladen',\r
+       urlMissing: 'Bildquellen-URL fehlt.',\r
+       vSpace: 'Vertikal-Abstand',\r
+       validateBorder: 'Rahmen muss eine ganze Zahl sein.',\r
+       validateHSpace: 'Horizontal-Abstand muss eine ganze Zahl sein.',\r
+       validateVSpace: 'Vertikal-Abstand muss eine ganze Zahl sein.'\r
+} );\r
diff --git a/sources/plugins/image/lang/el.js b/sources/plugins/image/lang/el.js
new file mode 100644 (file)
index 0000000..3453c3d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'el', {\r
+       alt: 'Εναλλακτικό Κείμενο',\r
+       border: 'Περίγραμμα',\r
+       btnUpload: 'Αποστολή στον Διακομιστή',\r
+       button2Img: 'Θέλετε να μετατρέψετε το επιλεγμένο κουμπί εικόνας σε απλή εικόνα;',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Θέλετε να μεταμορφώσετε την επιλεγμένη εικόνα που είναι πάνω σε ένα κουμπί;',\r
+       infoTab: 'Πληροφορίες Εικόνας',\r
+       linkTab: 'Σύνδεσμος',\r
+       lockRatio: 'Κλείδωμα Αναλογίας',\r
+       menu: 'Ιδιότητες Εικόνας',\r
+       resetSize: 'Επαναφορά Αρχικού Μεγέθους',\r
+       title: 'Ιδιότητες Εικόνας',\r
+       titleButton: 'Ιδιότητες Κουμπιού Εικόνας',\r
+       upload: 'Αποστολή',\r
+       urlMissing: 'Το URL πηγής για την εικόνα λείπει.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Το περίγραμμα πρέπει να είναι ένας ακέραιος αριθμός.',\r
+       validateHSpace: 'Το HSpace πρέπει να είναι ένας ακέραιος αριθμός.',\r
+       validateVSpace: 'Το VSpace πρέπει να είναι ένας ακέραιος αριθμός.'\r
+} );\r
diff --git a/sources/plugins/image/lang/en-au.js b/sources/plugins/image/lang/en-au.js
new file mode 100644 (file)
index 0000000..dba29c7
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'en-au', {\r
+       alt: 'Alternative Text',\r
+       border: 'Border',\r
+       btnUpload: 'Send it to the Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?',\r
+       infoTab: 'Image Info',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Lock Ratio',\r
+       menu: 'Image Properties',\r
+       resetSize: 'Reset Size',\r
+       title: 'Image Properties',\r
+       titleButton: 'Image Button Properties',\r
+       upload: 'Upload',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/en-ca.js b/sources/plugins/image/lang/en-ca.js
new file mode 100644 (file)
index 0000000..e78f83e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'en-ca', {\r
+       alt: 'Alternative Text',\r
+       border: 'Border',\r
+       btnUpload: 'Send it to the Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?',\r
+       infoTab: 'Image Info',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Lock Ratio',\r
+       menu: 'Image Properties',\r
+       resetSize: 'Reset Size',\r
+       title: 'Image Properties',\r
+       titleButton: 'Image Button Properties',\r
+       upload: 'Upload',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/en-gb.js b/sources/plugins/image/lang/en-gb.js
new file mode 100644 (file)
index 0000000..dcf335e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'en-gb', {\r
+       alt: 'Alternative Text',\r
+       border: 'Border',\r
+       btnUpload: 'Send it to the Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?',\r
+       infoTab: 'Image Info',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Lock Ratio',\r
+       menu: 'Image Properties',\r
+       resetSize: 'Reset Size',\r
+       title: 'Image Properties',\r
+       titleButton: 'Image Button Properties',\r
+       upload: 'Upload',\r
+       urlMissing: 'Image source URL is missing.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.',\r
+       validateHSpace: 'HSpace must be a whole number.',\r
+       validateVSpace: 'VSpace must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/image/lang/en.js b/sources/plugins/image/lang/en.js
new file mode 100644 (file)
index 0000000..4d0f50b
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'en', {\r
+       alt: 'Alternative Text',\r
+       border: 'Border',\r
+       btnUpload: 'Send it to the Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?',\r
+       infoTab: 'Image Info',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Lock Ratio',\r
+       menu: 'Image Properties',\r
+       resetSize: 'Reset Size',\r
+       title: 'Image Properties',\r
+       titleButton: 'Image Button Properties',\r
+       upload: 'Upload',\r
+       urlMissing: 'Image source URL is missing.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.',\r
+       validateHSpace: 'HSpace must be a whole number.',\r
+       validateVSpace: 'VSpace must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/image/lang/eo.js b/sources/plugins/image/lang/eo.js
new file mode 100644 (file)
index 0000000..276ef33
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'eo', {\r
+       alt: 'Anstataŭiga Teksto',\r
+       border: 'Bordero',\r
+       btnUpload: 'Sendu al Servilo',\r
+       button2Img: 'Ĉu vi volas transformi la selektitan bildbutonon en simplan bildon?',\r
+       hSpace: 'Horizontala Spaco',\r
+       img2Button: 'Ĉu vi volas transformi la selektitan bildon en bildbutonon?',\r
+       infoTab: 'Informoj pri Bildo',\r
+       linkTab: 'Ligilo',\r
+       lockRatio: 'Konservi Proporcion',\r
+       menu: 'Atributoj de Bildo',\r
+       resetSize: 'Origina Grando',\r
+       title: 'Atributoj de Bildo',\r
+       titleButton: 'Bildbutonaj Atributoj',\r
+       upload: 'Alŝuti',\r
+       urlMissing: 'La fontretadreso de la bildo mankas.',\r
+       vSpace: 'Vertikala Spaco',\r
+       validateBorder: 'La bordero devas esti entjera nombro.',\r
+       validateHSpace: 'La horizontala spaco devas esti entjera nombro.',\r
+       validateVSpace: 'La vertikala spaco devas esti entjera nombro.'\r
+} );\r
diff --git a/sources/plugins/image/lang/es.js b/sources/plugins/image/lang/es.js
new file mode 100644 (file)
index 0000000..1302a19
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'es', {\r
+       alt: 'Texto Alternativo',\r
+       border: 'Borde',\r
+       btnUpload: 'Enviar al Servidor',\r
+       button2Img: '¿Desea convertir el botón de imagen en una simple imagen?',\r
+       hSpace: 'Esp.Horiz',\r
+       img2Button: '¿Desea convertir la imagen en un botón de imagen?',\r
+       infoTab: 'Información de Imagen',\r
+       linkTab: 'Vínculo',\r
+       lockRatio: 'Proporcional',\r
+       menu: 'Propiedades de Imagen',\r
+       resetSize: 'Tamaño Original',\r
+       title: 'Propiedades de Imagen',\r
+       titleButton: 'Propiedades de Botón de Imagen',\r
+       upload: 'Cargar',\r
+       urlMissing: 'Debe indicar la URL de la imagen.',\r
+       vSpace: 'Esp.Vert',\r
+       validateBorder: 'El borde debe ser un número.',\r
+       validateHSpace: 'El espaciado horizontal debe ser un número.',\r
+       validateVSpace: 'El espaciado vertical debe ser un número.'\r
+} );\r
diff --git a/sources/plugins/image/lang/et.js b/sources/plugins/image/lang/et.js
new file mode 100644 (file)
index 0000000..4c7153a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'et', {\r
+       alt: 'Alternatiivne tekst',\r
+       border: 'Joon',\r
+       btnUpload: 'Saada serverisse',\r
+       button2Img: 'Kas tahad teisendada valitud pildiga nupu tavaliseks pildiks?',\r
+       hSpace: 'H. vaheruum',\r
+       img2Button: 'Kas tahad teisendada valitud tavalise pildi pildiga nupuks?',\r
+       infoTab: 'Pildi info',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Lukusta kuvasuhe',\r
+       menu: 'Pildi omadused',\r
+       resetSize: 'Lähtesta suurus',\r
+       title: 'Pildi omadused',\r
+       titleButton: 'Piltnupu omadused',\r
+       upload: 'Lae üles',\r
+       urlMissing: 'Pildi lähte-URL on puudu.',\r
+       vSpace: 'V. vaheruum',\r
+       validateBorder: 'Äärise laius peab olema täisarv.',\r
+       validateHSpace: 'Horisontaalne vaheruum peab olema täisarv.',\r
+       validateVSpace: 'Vertikaalne vaheruum peab olema täisarv.'\r
+} );\r
diff --git a/sources/plugins/image/lang/eu.js b/sources/plugins/image/lang/eu.js
new file mode 100644 (file)
index 0000000..52f8289
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'eu', {\r
+       alt: 'Ordezko testua',\r
+       border: 'Ertza',\r
+       btnUpload: 'Bidali zerbitzarira',\r
+       button2Img: 'Hautatutako irudi-botoia irudi arrunt bihurtu nahi duzu?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Hautatutako irudia irudi-botoi bihurtu nahi duzu?',\r
+       infoTab: 'Irudiaren informazioa',\r
+       linkTab: 'Esteka',\r
+       lockRatio: 'Blokeatu erlazioa',\r
+       menu: 'Irudiaren propietateak',\r
+       resetSize: 'Berrezarri tamaina',\r
+       title: 'Irudiaren propietateak',\r
+       titleButton: 'Irudi-botoiaren propietateak',\r
+       upload: 'Kargatu',\r
+       urlMissing: 'Irudiaren iturburuaren URLa falta da.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Ertza zenbaki oso bat izan behar da.',\r
+       validateHSpace: 'HSpace zenbaki oso bat izan behar da.',\r
+       validateVSpace: 'VSpace zenbaki oso bat izan behar da.'\r
+} );\r
diff --git a/sources/plugins/image/lang/fa.js b/sources/plugins/image/lang/fa.js
new file mode 100644 (file)
index 0000000..6628e99
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'fa', {\r
+       alt: 'متن جایگزین',\r
+       border: 'لبه',\r
+       btnUpload: 'به سرور بفرست',\r
+       button2Img: 'آیا مایلید از یک تصویر ساده روی دکمه تصویری انتخاب شده استفاده کنید؟',\r
+       hSpace: 'فاصلهٴ افقی',\r
+       img2Button: 'آیا مایلید از یک دکمه تصویری روی تصویر انتخاب شده استفاده کنید؟',\r
+       infoTab: 'اطلاعات تصویر',\r
+       linkTab: 'پیوند',\r
+       lockRatio: 'قفل کردن نسبت',\r
+       menu: 'ویژگی​های تصویر',\r
+       resetSize: 'بازنشانی اندازه',\r
+       title: 'ویژگی​های تصویر',\r
+       titleButton: 'ویژگی​های دکمهٴ تصویری',\r
+       upload: 'انتقال به سرور',\r
+       urlMissing: 'آدرس URL اصلی تصویر یافت نشد.',\r
+       vSpace: 'فاصلهٴ عمودی',\r
+       validateBorder: 'مقدار خطوط باید یک عدد باشد.',\r
+       validateHSpace: 'مقدار فاصله گذاری افقی باید یک عدد باشد.',\r
+       validateVSpace: 'مقدار فاصله گذاری عمودی باید یک عدد باشد.'\r
+} );\r
diff --git a/sources/plugins/image/lang/fi.js b/sources/plugins/image/lang/fi.js
new file mode 100644 (file)
index 0000000..665b615
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'fi', {\r
+       alt: 'Vaihtoehtoinen teksti',\r
+       border: 'Kehys',\r
+       btnUpload: 'Lähetä palvelimelle',\r
+       button2Img: 'Haluatko muuntaa valitun kuvanäppäimen kuvaksi?',\r
+       hSpace: 'Vaakatila',\r
+       img2Button: 'Haluatko muuntaa valitun kuvan kuvanäppäimeksi?',\r
+       infoTab: 'Kuvan tiedot',\r
+       linkTab: 'Linkki',\r
+       lockRatio: 'Lukitse suhteet',\r
+       menu: 'Kuvan ominaisuudet',\r
+       resetSize: 'Alkuperäinen koko',\r
+       title: 'Kuvan ominaisuudet',\r
+       titleButton: 'Kuvapainikkeen ominaisuudet',\r
+       upload: 'Lisää kuva',\r
+       urlMissing: 'Kuvan lähdeosoite puuttuu.',\r
+       vSpace: 'Pystytila',\r
+       validateBorder: 'Kehyksen täytyy olla kokonaisluku.',\r
+       validateHSpace: 'HSpace-määrityksen täytyy olla kokonaisluku.',\r
+       validateVSpace: 'VSpace-määrityksen täytyy olla kokonaisluku.'\r
+} );\r
diff --git a/sources/plugins/image/lang/fo.js b/sources/plugins/image/lang/fo.js
new file mode 100644 (file)
index 0000000..8332a38
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'fo', {\r
+       alt: 'Alternativur tekstur',\r
+       border: 'Bordi',\r
+       btnUpload: 'Send til ambætaran',\r
+       button2Img: 'Skal valdi myndaknøttur gerast til vanliga mynd?',\r
+       hSpace: 'Høgri breddi',\r
+       img2Button: 'Skal valda mynd gerast til myndaknøtt?',\r
+       infoTab: 'Myndaupplýsingar',\r
+       linkTab: 'Tilknýti',\r
+       lockRatio: 'Læs lutfallið',\r
+       menu: 'Myndaeginleikar',\r
+       resetSize: 'Upprunastødd',\r
+       title: 'Myndaeginleikar',\r
+       titleButton: 'Eginleikar fyri myndaknøtt',\r
+       upload: 'Send',\r
+       urlMissing: 'URL til mynd manglar.',\r
+       vSpace: 'Vinstri breddi',\r
+       validateBorder: 'Bordi má vera eitt heiltal.',\r
+       validateHSpace: 'HSpace má vera eitt heiltal.',\r
+       validateVSpace: 'VSpace má vera eitt heiltal.'\r
+} );\r
diff --git a/sources/plugins/image/lang/fr-ca.js b/sources/plugins/image/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..644a9f3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'fr-ca', {\r
+       alt: 'Texte alternatif',\r
+       border: 'Bordure',\r
+       btnUpload: 'Envoyer sur le serveur',\r
+       button2Img: 'Désirez-vous transformer l\'image sélectionnée en image simple?',\r
+       hSpace: 'Espacement horizontal',\r
+       img2Button: 'Désirez-vous transformer l\'image sélectionnée en bouton image?',\r
+       infoTab: 'Informations sur l\'image',\r
+       linkTab: 'Lien',\r
+       lockRatio: 'Verrouiller les proportions',\r
+       menu: 'Propriétés de l\'image',\r
+       resetSize: 'Taille originale',\r
+       title: 'Propriétés de l\'image',\r
+       titleButton: 'Propriétés du bouton image',\r
+       upload: 'Téléverser',\r
+       urlMissing: 'L\'URL de la source de l\'image est manquant.',\r
+       vSpace: 'Espacement vertical',\r
+       validateBorder: 'La bordure doit être un entier.',\r
+       validateHSpace: 'L\'espacement horizontal doit être un entier.',\r
+       validateVSpace: 'L\'espacement vertical doit être un entier.'\r
+} );\r
diff --git a/sources/plugins/image/lang/fr.js b/sources/plugins/image/lang/fr.js
new file mode 100644 (file)
index 0000000..299c379
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'fr', {\r
+       alt: 'Texte alternatif',\r
+       border: 'Bordure',\r
+       btnUpload: 'Envoyer sur le serveur',\r
+       button2Img: 'Voulez-vous transformer le bouton avec image sélectionné en simple image ?',\r
+       hSpace: 'Espacement horizontal',\r
+       img2Button: 'Voulez-vous transformer l\'image sélectionnée en bouton avec image ?',\r
+       infoTab: 'Informations sur l\'image',\r
+       linkTab: 'Lien',\r
+       lockRatio: 'Conserver les proportions',\r
+       menu: 'Propriétés de l\'image',\r
+       resetSize: 'Réinitialiser la taille',\r
+       title: 'Propriétés de l\'image',\r
+       titleButton: 'Propriétés du bouton avec image',\r
+       upload: 'Téléverser',\r
+       urlMissing: 'L\'URL source de l\'image est manquante.',\r
+       vSpace: 'Espacement vertical',\r
+       validateBorder: 'La bordure doit être un nombre entier.',\r
+       validateHSpace: 'L\'espacement horizontal doit être un nombre entier.',\r
+       validateVSpace: 'L\'espacement vertical doit être un nombre entier.'\r
+} );\r
diff --git a/sources/plugins/image/lang/gl.js b/sources/plugins/image/lang/gl.js
new file mode 100644 (file)
index 0000000..ba632b8
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'gl', {\r
+       alt: 'Texto alternativo',\r
+       border: 'Bordo',\r
+       btnUpload: 'Enviar ao servidor',\r
+       button2Img: 'Quere converter o botón da imaxe seleccionada nunha imaxe sinxela?',\r
+       hSpace: 'Esp.Horiz.',\r
+       img2Button: 'Quere converter a imaxe seleccionada nun botón de imaxe?',\r
+       infoTab: 'Información da imaxe',\r
+       linkTab: 'Ligazón',\r
+       lockRatio: 'Proporcional',\r
+       menu: 'Propiedades da imaxe',\r
+       resetSize: 'Tamaño orixinal',\r
+       title: 'Propiedades da imaxe',\r
+       titleButton: 'Propiedades do botón de imaxe',\r
+       upload: 'Cargar',\r
+       urlMissing: 'Non se atopa o URL da imaxe.',\r
+       vSpace: 'Esp.Vert.',\r
+       validateBorder: 'O bordo debe ser un número.',\r
+       validateHSpace: 'O espazado horizontal debe ser un número.',\r
+       validateVSpace: 'O espazado vertical debe ser un número.'\r
+} );\r
diff --git a/sources/plugins/image/lang/gu.js b/sources/plugins/image/lang/gu.js
new file mode 100644 (file)
index 0000000..f70ae28
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'gu', {\r
+       alt: 'ઑલ્ટર્નટ ટેક્સ્ટ',\r
+       border: 'બોર્ડર',\r
+       btnUpload: 'આ સર્વરને મોકલવું',\r
+       button2Img: 'તમારે ઈમેજ બટનને સાદી ઈમેજમાં બદલવું છે.',\r
+       hSpace: 'સમસ્તરીય જગ્યા',\r
+       img2Button: 'તમારે સાદી ઈમેજને ઈમેજ બટનમાં બદલવું છે.',\r
+       infoTab: 'ચિત્ર ની જાણકારી',\r
+       linkTab: 'લિંક',\r
+       lockRatio: 'લૉક ગુણોત્તર',\r
+       menu: 'ચિત્રના ગુણ',\r
+       resetSize: 'રીસેટ સાઇઝ',\r
+       title: 'ચિત્રના ગુણ',\r
+       titleButton: 'ચિત્ર બટનના ગુણ',\r
+       upload: 'અપલોડ',\r
+       urlMissing: 'ઈમેજની મૂળ URL છે નહી.',\r
+       vSpace: 'લંબરૂપ જગ્યા',\r
+       validateBorder: 'બોર્ડેર આંકડો હોવો જોઈએ.',\r
+       validateHSpace: 'HSpaceઆંકડો હોવો જોઈએ.',\r
+       validateVSpace: 'VSpace આંકડો હોવો જોઈએ. '\r
+} );\r
diff --git a/sources/plugins/image/lang/he.js b/sources/plugins/image/lang/he.js
new file mode 100644 (file)
index 0000000..41f207a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'he', {\r
+       alt: 'טקסט חלופי',\r
+       border: 'מסגרת',\r
+       btnUpload: 'שליחה לשרת',\r
+       button2Img: 'האם להפוך את תמונת הכפתור לתמונה פשוטה?',\r
+       hSpace: 'מרווח אופקי',\r
+       img2Button: 'האם להפוך את התמונה לכפתור תמונה?',\r
+       infoTab: 'מידע על התמונה',\r
+       linkTab: 'קישור',\r
+       lockRatio: 'נעילת היחס',\r
+       menu: 'תכונות התמונה',\r
+       resetSize: 'איפוס הגודל',\r
+       title: 'מאפייני התמונה',\r
+       titleButton: 'מאפיני כפתור תמונה',\r
+       upload: 'העלאה',\r
+       urlMissing: 'כתובת התמונה חסרה.',\r
+       vSpace: 'מרווח אנכי',\r
+       validateBorder: 'שדה המסגרת חייב להיות מספר שלם.',\r
+       validateHSpace: 'שדה המרווח האופקי חייב להיות מספר שלם.',\r
+       validateVSpace: 'שדה המרווח האנכי חייב להיות מספר שלם.'\r
+} );\r
diff --git a/sources/plugins/image/lang/hi.js b/sources/plugins/image/lang/hi.js
new file mode 100644 (file)
index 0000000..d4604b3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'hi', {\r
+       alt: 'वैकल्पिक टेक्स्ट',\r
+       border: 'बॉर्डर',\r
+       btnUpload: 'इसे सर्वर को भेजें',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'हॉरिज़ॉन्टल स्पेस',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'तस्वीर की जानकारी',\r
+       linkTab: 'लिंक',\r
+       lockRatio: 'लॉक अनुपात',\r
+       menu: 'तस्वीर प्रॉपर्टीज़',\r
+       resetSize: 'रीसॅट साइज़',\r
+       title: 'तस्वीर प्रॉपर्टीज़',\r
+       titleButton: 'तस्वीर बटन प्रॉपर्टीज़',\r
+       upload: 'अपलोड',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'वर्टिकल स्पेस',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/hr.js b/sources/plugins/image/lang/hr.js
new file mode 100644 (file)
index 0000000..8c272eb
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'hr', {\r
+       alt: 'Alternativni tekst',\r
+       border: 'Okvir',\r
+       btnUpload: 'Pošalji na server',\r
+       button2Img: 'Želite li promijeniti odabrani gumb u jednostavnu sliku?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Želite li promijeniti odabranu sliku u gumb?',\r
+       infoTab: 'Info slike',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Zaključaj odnos',\r
+       menu: 'Svojstva slika',\r
+       resetSize: 'Obriši veličinu',\r
+       title: 'Svojstva slika',\r
+       titleButton: 'Image Button svojstva',\r
+       upload: 'Pošalji',\r
+       urlMissing: 'Nedostaje URL slike.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Okvir mora biti cijeli broj.',\r
+       validateHSpace: 'HSpace mora biti cijeli broj',\r
+       validateVSpace: 'VSpace mora biti cijeli broj.'\r
+} );\r
diff --git a/sources/plugins/image/lang/hu.js b/sources/plugins/image/lang/hu.js
new file mode 100644 (file)
index 0000000..5a9e990
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'hu', {\r
+       alt: 'Alternatív szöveg',\r
+       border: 'Keret',\r
+       btnUpload: 'Küldés a szerverre',\r
+       button2Img: 'A kiválasztott képgombból sima képet szeretne csinálni?',\r
+       hSpace: 'Vízsz. táv',\r
+       img2Button: 'A kiválasztott képből képgombot szeretne csinálni?',\r
+       infoTab: 'Alaptulajdonságok',\r
+       linkTab: 'Hivatkozás',\r
+       lockRatio: 'Arány megtartása',\r
+       menu: 'Kép tulajdonságai',\r
+       resetSize: 'Eredeti méret',\r
+       title: 'Kép tulajdonságai',\r
+       titleButton: 'Képgomb tulajdonságai',\r
+       upload: 'Feltöltés',\r
+       urlMissing: 'Hiányzik a kép URL-je',\r
+       vSpace: 'Függ. táv',\r
+       validateBorder: 'A keret méretének egész számot kell beírni!',\r
+       validateHSpace: 'Vízszintes távolságnak egész számot kell beírni!',\r
+       validateVSpace: 'Függőleges távolságnak egész számot kell beírni!'\r
+} );\r
diff --git a/sources/plugins/image/lang/id.js b/sources/plugins/image/lang/id.js
new file mode 100644 (file)
index 0000000..8d27ad6
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'id', {\r
+       alt: 'Teks alternatif',\r
+       border: 'Batas',\r
+       btnUpload: 'Kirim ke Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'HSpace', // MISSING\r
+       img2Button: 'Apakah anda ingin mengubah gambar yang dipilih pada tombol gambar?',\r
+       infoTab: 'Info Gambar',\r
+       linkTab: 'Tautan',\r
+       lockRatio: 'Lock Ratio', // MISSING\r
+       menu: 'Image Properties', // MISSING\r
+       resetSize: 'Atur Ulang Ukuran',\r
+       title: 'Image Properties', // MISSING\r
+       titleButton: 'Image Button Properties', // MISSING\r
+       upload: 'Unggah',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border harus berupa angka',\r
+       validateHSpace: 'HSpace harus berupa angka',\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/is.js b/sources/plugins/image/lang/is.js
new file mode 100644 (file)
index 0000000..fc02308
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'is', {\r
+       alt: 'Baklægur texti',\r
+       border: 'Rammi',\r
+       btnUpload: 'Hlaða upp',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'Vinstri bil',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Almennt',\r
+       linkTab: 'Stikla',\r
+       lockRatio: 'Festa stærðarhlutfall',\r
+       menu: 'Eigindi myndar',\r
+       resetSize: 'Reikna stærð',\r
+       title: 'Eigindi myndar',\r
+       titleButton: 'Eigindi myndahnapps',\r
+       upload: 'Hlaða upp',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'Hægri bil',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/it.js b/sources/plugins/image/lang/it.js
new file mode 100644 (file)
index 0000000..7b066ca
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'it', {\r
+       alt: 'Testo alternativo',\r
+       border: 'Bordo',\r
+       btnUpload: 'Invia al server',\r
+       button2Img: 'Vuoi trasformare il bottone immagine selezionato in un\'immagine semplice?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Vuoi trasferomare l\'immagine selezionata in un bottone immagine?',\r
+       infoTab: 'Informazioni immagine',\r
+       linkTab: 'Collegamento',\r
+       lockRatio: 'Blocca rapporto',\r
+       menu: 'Proprietà immagine',\r
+       resetSize: 'Reimposta dimensione',\r
+       title: 'Proprietà immagine',\r
+       titleButton: 'Proprietà bottone immagine',\r
+       upload: 'Carica',\r
+       urlMissing: 'Manca l\'URL dell\'immagine.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Il campo Bordo deve essere un numero intero.',\r
+       validateHSpace: 'Il campo HSpace deve essere un numero intero.',\r
+       validateVSpace: 'Il campo VSpace deve essere un numero intero.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ja.js b/sources/plugins/image/lang/ja.js
new file mode 100644 (file)
index 0000000..a2d500c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ja', {\r
+       alt: '代替テキスト',\r
+       border: '枠線の幅',\r
+       btnUpload: 'サーバーに送信',\r
+       button2Img: '選択した画像ボタンを画像に変換しますか?',\r
+       hSpace: '水平間隔',\r
+       img2Button: '選択した画像を画像ボタンに変換しますか?',\r
+       infoTab: '画像情報',\r
+       linkTab: 'リンク',\r
+       lockRatio: '比率を固定',\r
+       menu: '画像のプロパティ',\r
+       resetSize: 'サイズをリセット',\r
+       title: '画像のプロパティ',\r
+       titleButton: '画像ボタンのプロパティ',\r
+       upload: 'アップロード',\r
+       urlMissing: '画像のURLを入力してください。',\r
+       vSpace: '垂直間隔',\r
+       validateBorder: '枠線の幅は数値で入力してください。',\r
+       validateHSpace: '水平間隔は数値で入力してください。',\r
+       validateVSpace: '垂直間隔は数値で入力してください。'\r
+} );\r
diff --git a/sources/plugins/image/lang/ka.js b/sources/plugins/image/lang/ka.js
new file mode 100644 (file)
index 0000000..0a634f0
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ka', {\r
+       alt: 'სანაცვლო ტექსტი',\r
+       border: 'ჩარჩო',\r
+       btnUpload: 'სერვერისთვის გაგზავნა',\r
+       button2Img: 'გსურთ არჩეული სურათიანი ღილაკის გადაქცევა ჩვეულებრივ ღილაკად?',\r
+       hSpace: 'ჰორიზონტალური სივრცე',\r
+       img2Button: 'გსურთ არჩეული ჩვეულებრივი ღილაკის გადაქცევა სურათიან ღილაკად?',\r
+       infoTab: 'სურათის ინფორმცია',\r
+       linkTab: 'ბმული',\r
+       lockRatio: 'პროპორციის შენარჩუნება',\r
+       menu: 'სურათის პარამეტრები',\r
+       resetSize: 'ზომის დაბრუნება',\r
+       title: 'სურათის პარამეტრები',\r
+       titleButton: 'სურათიანი ღილაკის პარამეტრები',\r
+       upload: 'ატვირთვა',\r
+       urlMissing: 'სურათის URL არაა შევსებული.',\r
+       vSpace: 'ვერტიკალური სივრცე',\r
+       validateBorder: 'ჩარჩო მთელი რიცხვი უნდა იყოს.',\r
+       validateHSpace: 'ჰორიზონტალური სივრცე მთელი რიცხვი უნდა იყოს.',\r
+       validateVSpace: 'ვერტიკალური სივრცე მთელი რიცხვი უნდა იყოს.'\r
+} );\r
diff --git a/sources/plugins/image/lang/km.js b/sources/plugins/image/lang/km.js
new file mode 100644 (file)
index 0000000..d60562a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'km', {\r
+       alt: 'អត្ថបទជំនួស',\r
+       border: 'ស៊ុម',\r
+       btnUpload: 'ផ្ញើ​ទៅ​ម៉ាស៊ីន​បម្រើ',\r
+       button2Img: 'តើ​អ្នក​ចង់​ផ្លាស់​ប្ដូរ​ប៊ូតុង​រូបភាព​ដែល​បាន​ជ្រើស នៅ​លើ​រូបភាព​ធម្មតា​មួយ​មែនទេ?',\r
+       hSpace: 'គម្លាត​ផ្ដេក',\r
+       img2Button: 'តើ​អ្នក​ចង់​ផ្លាស់​ប្ដូរ​រូបភាព​ដែល​បាន​ជ្រើស នៅ​លើ​ប៊ូតុង​រូបភាព​មែនទេ?',\r
+       infoTab: 'ពត៌មានអំពីរូបភាព',\r
+       linkTab: 'តំណ',\r
+       lockRatio: 'ចាក់​សោ​ផល​ធៀប',\r
+       menu: 'លក្ខណៈ​រូបភាព',\r
+       resetSize: 'កំណត់ទំហំឡើងវិញ',\r
+       title: 'លក្ខណៈ​រូបភាព',\r
+       titleButton: 'លក្ខណៈ​ប៊ូតុង​រូបភាព',\r
+       upload: 'ផ្ទុកឡើង',\r
+       urlMissing: 'ខ្វះ URL ប្រភព​រូប​ភាព។',\r
+       vSpace: 'គម្លាត​បញ្ឈរ',\r
+       validateBorder: 'ស៊ុម​ត្រូវ​តែ​ជា​លេខ។',\r
+       validateHSpace: 'គម្លាត​ផ្ដេក​ត្រូវ​តែ​ជា​លេខ។',\r
+       validateVSpace: 'គម្លាត​បញ្ឈរ​ត្រូវ​តែ​ជា​លេខ។'\r
+} );\r
diff --git a/sources/plugins/image/lang/ko.js b/sources/plugins/image/lang/ko.js
new file mode 100644 (file)
index 0000000..75e5252
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ko', {\r
+       alt: '대체 문자열',\r
+       border: '테두리',\r
+       btnUpload: '서버로 전송',\r
+       button2Img: '단순 이미지에서 선택한 이미지 버튼을 변환하시겠습니까?',\r
+       hSpace: '가로 여백',\r
+       img2Button: '이미지 버튼에 선택한 이미지를 변환하시겠습니까?',\r
+       infoTab: '이미지 정보',\r
+       linkTab: '링크',\r
+       lockRatio: '비율 유지',\r
+       menu: '이미지 속성',\r
+       resetSize: '원래 크기로',\r
+       title: '이미지 속성',\r
+       titleButton: '이미지 버튼 속성',\r
+       upload: '업로드',\r
+       urlMissing: '이미지 원본 주소(URL)가 없습니다.',\r
+       vSpace: '세로 여백',\r
+       validateBorder: '테두리 두께는 정수여야 합니다.',\r
+       validateHSpace: '가로 길이는 정수여야 합니다.',\r
+       validateVSpace: '세로 길이는 정수여야 합니다.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ku.js b/sources/plugins/image/lang/ku.js
new file mode 100644 (file)
index 0000000..2b70145
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ku', {\r
+       alt: 'جێگرەوەی دەق',\r
+       border: 'پەراوێز',\r
+       btnUpload: 'ناردنی بۆ ڕاژه',\r
+       button2Img: 'تۆ دەتەوێت دوگمەی وێنەی دیاریکراو بگۆڕیت بۆ وێنەیەکی ئاسایی؟',\r
+       hSpace: 'بۆشایی ئاسۆیی',\r
+       img2Button: 'تۆ دەتەوێت وێنەی دیاریکراو بگۆڕیت بۆ دوگمەی وێنه؟',\r
+       infoTab: 'زانیاری وێنه',\r
+       linkTab: 'بەستەر',\r
+       lockRatio: 'داخستنی ڕێژه',\r
+       menu: 'خاسیەتی وێنه',\r
+       resetSize: 'ڕێکخستنەوەی قەباره',\r
+       title: 'خاسیەتی وێنه',\r
+       titleButton: 'خاسیەتی دوگمەی وێنه',\r
+       upload: 'بارکردن',\r
+       urlMissing: 'سەرچاوەی بەستەری وێنه بزره',\r
+       vSpace: 'بۆشایی ئەستونی',\r
+       validateBorder: 'پەراوێز دەبێت بەتەواوی تەنها ژماره بێت.',\r
+       validateHSpace: 'بۆشایی ئاسۆیی دەبێت بەتەواوی تەنها ژمارە بێت.',\r
+       validateVSpace: 'بۆشایی ئەستونی دەبێت بەتەواوی تەنها ژماره بێت.'\r
+} );\r
diff --git a/sources/plugins/image/lang/lt.js b/sources/plugins/image/lang/lt.js
new file mode 100644 (file)
index 0000000..2343934
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'lt', {\r
+       alt: 'Alternatyvus Tekstas',\r
+       border: 'Rėmelis',\r
+       btnUpload: 'Siųsti į serverį',\r
+       button2Img: 'Ar norite mygtuką paversti paprastu paveiksliuku?',\r
+       hSpace: 'Hor.Erdvė',\r
+       img2Button: 'Ar norite paveiksliuką paversti mygtuku?',\r
+       infoTab: 'Vaizdo informacija',\r
+       linkTab: 'Nuoroda',\r
+       lockRatio: 'Išlaikyti proporciją',\r
+       menu: 'Vaizdo savybės',\r
+       resetSize: 'Atstatyti dydį',\r
+       title: 'Vaizdo savybės',\r
+       titleButton: 'Vaizdinio mygtuko savybės',\r
+       upload: 'Nusiųsti',\r
+       urlMissing: 'Paveiksliuko nuorodos nėra.',\r
+       vSpace: 'Vert.Erdvė',\r
+       validateBorder: 'Reikšmė turi būti sveikas skaičius.',\r
+       validateHSpace: 'Reikšmė turi būti sveikas skaičius.',\r
+       validateVSpace: 'Reikšmė turi būti sveikas skaičius.'\r
+} );\r
diff --git a/sources/plugins/image/lang/lv.js b/sources/plugins/image/lang/lv.js
new file mode 100644 (file)
index 0000000..cf20166
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'lv', {\r
+       alt: 'Alternatīvais teksts',\r
+       border: 'Rāmis',\r
+       btnUpload: 'Nosūtīt serverim',\r
+       button2Img: 'Vai vēlaties pārveidot izvēlēto attēla pogu uz attēla?',\r
+       hSpace: 'Horizontālā telpa',\r
+       img2Button: 'Vai vēlaties pārveidot izvēlēto attēlu uz attēla pogas?',\r
+       infoTab: 'Informācija par attēlu',\r
+       linkTab: 'Hipersaite',\r
+       lockRatio: 'Nemainīga Augstuma/Platuma attiecība',\r
+       menu: 'Attēla īpašības',\r
+       resetSize: 'Atjaunot sākotnējo izmēru',\r
+       title: 'Attēla īpašības',\r
+       titleButton: 'Attēlpogas īpašības',\r
+       upload: 'Augšupielādēt',\r
+       urlMissing: 'Trūkst attēla atrašanās adrese.',\r
+       vSpace: 'Vertikālā telpa',\r
+       validateBorder: 'Apmalei jābūt veselam skaitlim',\r
+       validateHSpace: 'HSpace jābūt veselam skaitlim',\r
+       validateVSpace: 'VSpace jābūt veselam skaitlim'\r
+} );\r
diff --git a/sources/plugins/image/lang/mk.js b/sources/plugins/image/lang/mk.js
new file mode 100644 (file)
index 0000000..9dd01cc
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'mk', {\r
+       alt: 'Алтернативен текст',\r
+       border: 'Раб',\r
+       btnUpload: 'Прикачи на сервер',\r
+       button2Img: 'Дали сакате да направите сликата-копче да биде само слика?',\r
+       hSpace: 'Хоризонтален простор',\r
+       img2Button: 'Дали сакате да ја претворите сликата во слика-копче?',\r
+       infoTab: 'Информации за сликата',\r
+       linkTab: 'Врска',\r
+       lockRatio: 'Зачувај пропорција',\r
+       menu: 'Својства на сликата',\r
+       resetSize: 'Ресетирај големина',\r
+       title: 'Својства на сликата',\r
+       titleButton: 'Својства на копче-сликата',\r
+       upload: 'Прикачи',\r
+       urlMissing: 'Недостасува URL-то на сликата.',\r
+       vSpace: 'Вертикален простор',\r
+       validateBorder: 'Работ мора да биде цел број.',\r
+       validateHSpace: 'Хор. простор мора да биде цел број.',\r
+       validateVSpace: 'Верт. простор мора да биде цел број.'\r
+} );\r
diff --git a/sources/plugins/image/lang/mn.js b/sources/plugins/image/lang/mn.js
new file mode 100644 (file)
index 0000000..4daf38a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'mn', {\r
+       alt: 'Зургийг орлох бичвэр',\r
+       border: 'Хүрээ',\r
+       btnUpload: 'Үүнийг сервэррүү илгээ',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'Хөндлөн зай',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Зурагны мэдээлэл',\r
+       linkTab: 'Холбоос',\r
+       lockRatio: 'Радио түгжих',\r
+       menu: 'Зураг',\r
+       resetSize: 'хэмжээ дахин оноох',\r
+       title: 'Зураг',\r
+       titleButton: 'Зурган товчны шинж чанар',\r
+       upload: 'Хуулах',\r
+       urlMissing: 'Зургийн эх сурвалжийн хаяг (URL) байхгүй байна.',\r
+       vSpace: 'Босоо зай',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/ms.js b/sources/plugins/image/lang/ms.js
new file mode 100644 (file)
index 0000000..28511d0
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ms', {\r
+       alt: 'Text Alternatif',\r
+       border: 'Border',\r
+       btnUpload: 'Hantar ke Server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'Ruang Melintang',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Info Imej',\r
+       linkTab: 'Sambungan',\r
+       lockRatio: 'Tetapkan Nisbah',\r
+       menu: 'Ciri-ciri Imej',\r
+       resetSize: 'Saiz Set Semula',\r
+       title: 'Ciri-ciri Imej',\r
+       titleButton: 'Ciri-ciri Butang Bergambar',\r
+       upload: 'Muat Naik',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'Ruang Menegak',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/nb.js b/sources/plugins/image/lang/nb.js
new file mode 100644 (file)
index 0000000..87208af
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'nb', {\r
+       alt: 'Alternativ tekst',\r
+       border: 'Ramme',\r
+       btnUpload: 'Send det til serveren',\r
+       button2Img: 'Vil du endre den valgte bildeknappen til et vanlig bilde?',\r
+       hSpace: 'HMarg',\r
+       img2Button: 'Vil du endre det valgte bildet til en bildeknapp?',\r
+       infoTab: 'Bildeinformasjon',\r
+       linkTab: 'Lenke',\r
+       lockRatio: 'Lås forhold',\r
+       menu: 'Bildeegenskaper',\r
+       resetSize: 'Tilbakestill størrelse',\r
+       title: 'Bildeegenskaper',\r
+       titleButton: 'Egenskaper for bildeknapp',\r
+       upload: 'Last opp',\r
+       urlMissing: 'Bildets adresse mangler.',\r
+       vSpace: 'VMarg',\r
+       validateBorder: 'Ramme må være et heltall.',\r
+       validateHSpace: 'HMarg må være et heltall.',\r
+       validateVSpace: 'VMarg må være et heltall.'\r
+} );\r
diff --git a/sources/plugins/image/lang/nl.js b/sources/plugins/image/lang/nl.js
new file mode 100644 (file)
index 0000000..bbe4943
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'nl', {\r
+       alt: 'Alternatieve tekst',\r
+       border: 'Rand',\r
+       btnUpload: 'Naar server verzenden',\r
+       button2Img: 'Wilt u de geselecteerde afbeeldingsknop vervangen door een eenvoudige afbeelding?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Wilt u de geselecteerde afbeelding vervangen door een afbeeldingsknop?',\r
+       infoTab: 'Informatie afbeelding',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Afmetingen vergrendelen',\r
+       menu: 'Eigenschappen afbeelding',\r
+       resetSize: 'Afmetingen resetten',\r
+       title: 'Eigenschappen afbeelding',\r
+       titleButton: 'Eigenschappen afbeeldingsknop',\r
+       upload: 'Upload',\r
+       urlMissing: 'De URL naar de afbeelding ontbreekt.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Rand moet een heel nummer zijn.',\r
+       validateHSpace: 'HSpace moet een heel nummer zijn.',\r
+       validateVSpace: 'VSpace moet een heel nummer zijn.'\r
+} );\r
diff --git a/sources/plugins/image/lang/no.js b/sources/plugins/image/lang/no.js
new file mode 100644 (file)
index 0000000..9d4898a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'no', {\r
+       alt: 'Alternativ tekst',\r
+       border: 'Ramme',\r
+       btnUpload: 'Send det til serveren',\r
+       button2Img: 'Vil du endre den valgte bildeknappen til et vanlig bilde?',\r
+       hSpace: 'HMarg',\r
+       img2Button: 'Vil du endre det valgte bildet til en bildeknapp?',\r
+       infoTab: 'Bildeinformasjon',\r
+       linkTab: 'Lenke',\r
+       lockRatio: 'Lås forhold',\r
+       menu: 'Bildeegenskaper',\r
+       resetSize: 'Tilbakestill størrelse',\r
+       title: 'Bildeegenskaper',\r
+       titleButton: 'Egenskaper for bildeknapp',\r
+       upload: 'Last opp',\r
+       urlMissing: 'Bildets adresse mangler.',\r
+       vSpace: 'VMarg',\r
+       validateBorder: 'Ramme må være et heltall.',\r
+       validateHSpace: 'HMarg må være et heltall.',\r
+       validateVSpace: 'VMarg må være et heltall.'\r
+} );\r
diff --git a/sources/plugins/image/lang/oc.js b/sources/plugins/image/lang/oc.js
new file mode 100644 (file)
index 0000000..fa595c6
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'oc', {\r
+       alt: 'Tèxte alternatiu',\r
+       border: 'Bordadura',\r
+       btnUpload: 'Mandar sul servidor',\r
+       button2Img: 'Volètz transformar lo boton amb imatge seleccionat en imatge simple ?',\r
+       hSpace: 'Espaçament orizontal',\r
+       img2Button: 'Volètz transformar l\'imatge seleccionat en boton amb imatge ?',\r
+       infoTab: 'Informacions sus l\'imatge',\r
+       linkTab: 'Ligam',\r
+       lockRatio: 'Conservar las proporcions',\r
+       menu: 'Proprietats de l\'imatge',\r
+       resetSize: 'Reïnicializar la talha',\r
+       title: 'Proprietats de l\'imatge',\r
+       titleButton: 'Proprietats del boton amb imatge',\r
+       upload: 'Mandar',\r
+       urlMissing: 'L\'URL font de l\'imatge es mancanta.',\r
+       vSpace: 'Espaçament vertical',\r
+       validateBorder: 'La bordadura deu èsser un nombre entièr.',\r
+       validateHSpace: 'L\'espaçament orizontal deu èsser un nombre entièr.',\r
+       validateVSpace: 'L\'espaçament vertical deu èsser un nombre entièr.'\r
+} );\r
diff --git a/sources/plugins/image/lang/pl.js b/sources/plugins/image/lang/pl.js
new file mode 100644 (file)
index 0000000..93afb85
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'pl', {\r
+       alt: 'Tekst zastępczy',\r
+       border: 'Obramowanie',\r
+       btnUpload: 'Wyślij',\r
+       button2Img: 'Czy chcesz przekonwertować zaznaczony przycisk graficzny do zwykłego obrazka?',\r
+       hSpace: 'Odstęp poziomy',\r
+       img2Button: 'Czy chcesz przekonwertować zaznaczony obrazek do przycisku graficznego?',\r
+       infoTab: 'Informacje o obrazku',\r
+       linkTab: 'Hiperłącze',\r
+       lockRatio: 'Zablokuj proporcje',\r
+       menu: 'Właściwości obrazka',\r
+       resetSize: 'Przywróć rozmiar',\r
+       title: 'Właściwości obrazka',\r
+       titleButton: 'Właściwości przycisku graficznego',\r
+       upload: 'Wyślij',\r
+       urlMissing: 'Podaj adres URL obrazka.',\r
+       vSpace: 'Odstęp pionowy',\r
+       validateBorder: 'Wartość obramowania musi być liczbą całkowitą.',\r
+       validateHSpace: 'Wartość odstępu poziomego musi być liczbą całkowitą.',\r
+       validateVSpace: 'Wartość odstępu pionowego musi być liczbą całkowitą.'\r
+} );\r
diff --git a/sources/plugins/image/lang/pt-br.js b/sources/plugins/image/lang/pt-br.js
new file mode 100644 (file)
index 0000000..0d13a9a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'pt-br', {\r
+       alt: 'Texto Alternativo',\r
+       border: 'Borda',\r
+       btnUpload: 'Enviar para o Servidor',\r
+       button2Img: 'Deseja transformar o botão de imagem em uma imagem comum?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Deseja transformar a imagem em um botão de imagem?',\r
+       infoTab: 'Informações da Imagem',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Travar Proporções',\r
+       menu: 'Formatar Imagem',\r
+       resetSize: 'Redefinir para o Tamanho Original',\r
+       title: 'Formatar Imagem',\r
+       titleButton: 'Formatar Botão de Imagem',\r
+       upload: 'Enviar',\r
+       urlMissing: 'URL da imagem está faltando.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'A borda deve ser um número inteiro.',\r
+       validateHSpace: 'O HSpace deve ser um número inteiro.',\r
+       validateVSpace: 'O VSpace deve ser um número inteiro.'\r
+} );\r
diff --git a/sources/plugins/image/lang/pt.js b/sources/plugins/image/lang/pt.js
new file mode 100644 (file)
index 0000000..2b8f50c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'pt', {\r
+       alt: 'Texto alternativo',\r
+       border: 'Limite',\r
+       btnUpload: 'Enviar para o servidor',\r
+       button2Img: 'Deseja transformar o botão com imagem selecionado em uma imagem?',\r
+       hSpace: 'Esp. Horiz',\r
+       img2Button: 'Deseja transformar a imagem selecionada em um botão com imagem?',\r
+       infoTab: 'Informação da imagem',\r
+       linkTab: 'Hiperligação',\r
+       lockRatio: 'Proporcional',\r
+       menu: 'Propriedades da Imagem',\r
+       resetSize: 'Tamanho original',\r
+       title: 'Propriedades da imagem',\r
+       titleButton: 'Propriedades do botão de imagem',\r
+       upload: 'Carregar',\r
+       urlMissing: 'O URL da fonte da imagem está em falta.',\r
+       vSpace: 'Esp. Vert',\r
+       validateBorder: 'A borda tem de ser um numero.',\r
+       validateHSpace: 'HSpace tem de ser um numero.',\r
+       validateVSpace: 'VSpace tem de ser um numero.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ro.js b/sources/plugins/image/lang/ro.js
new file mode 100644 (file)
index 0000000..067dee2
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ro', {\r
+       alt: 'Text alternativ',\r
+       border: 'Margine',\r
+       btnUpload: 'Trimite la server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Informaţii despre imagine',\r
+       linkTab: 'Link (Legătură web)',\r
+       lockRatio: 'Păstrează proporţiile',\r
+       menu: 'Proprietăţile imaginii',\r
+       resetSize: 'Resetează mărimea',\r
+       title: 'Proprietăţile imaginii',\r
+       titleButton: 'Proprietăţi buton imagine (Image Button)',\r
+       upload: 'Încarcă',\r
+       urlMissing: 'Sursa URL a imaginii lipsește.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Bordura trebuie să fie un număr întreg.',\r
+       validateHSpace: 'Hspace trebuie să fie un număr întreg.',\r
+       validateVSpace: 'Vspace trebuie să fie un număr întreg.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ru.js b/sources/plugins/image/lang/ru.js
new file mode 100644 (file)
index 0000000..cb937c9
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ru', {\r
+       alt: 'Альтернативный текст',\r
+       border: 'Граница',\r
+       btnUpload: 'Загрузить на сервер',\r
+       button2Img: 'Вы желаете преобразовать это изображение-кнопку в обычное изображение?',\r
+       hSpace: 'Гориз. отступ',\r
+       img2Button: 'Вы желаете преобразовать это обычное изображение в изображение-кнопку?',\r
+       infoTab: 'Данные об изображении',\r
+       linkTab: 'Ссылка',\r
+       lockRatio: 'Сохранять пропорции',\r
+       menu: 'Свойства изображения',\r
+       resetSize: 'Вернуть обычные размеры',\r
+       title: 'Свойства изображения',\r
+       titleButton: 'Свойства изображения-кнопки',\r
+       upload: 'Загрузить',\r
+       urlMissing: 'Не указана ссылка на изображение.',\r
+       vSpace: 'Вертик. отступ',\r
+       validateBorder: 'Размер границ должен быть задан числом.',\r
+       validateHSpace: 'Горизонтальный отступ должен быть задан числом.',\r
+       validateVSpace: 'Вертикальный отступ должен быть задан числом.'\r
+} );\r
diff --git a/sources/plugins/image/lang/si.js b/sources/plugins/image/lang/si.js
new file mode 100644 (file)
index 0000000..84cbace
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'si', {\r
+       alt: 'විකල්ප ',\r
+       border: 'සීමාවවල ',\r
+       btnUpload: 'සේවාදායකය වෙත යොමුකිරිම',\r
+       button2Img: 'ඔබට තෝරන ලද රුපය පරිවර්තනය කිරීමට අවශ්‍යද?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'ඔබට තෝරන ලද රුපය පරිවර්තනය කිරීමට අවශ්‍යද?',\r
+       infoTab: 'රුපයේ තොරතුරු',\r
+       linkTab: 'සබැඳිය',\r
+       lockRatio: 'නවතන අනුපාතය ',\r
+       menu: 'රුපයේ ගුණ',\r
+       resetSize: 'නැවතත් විශාලත්වය වෙනස් කිරීම',\r
+       title: 'රුපයේ ',\r
+       titleButton: 'රුප බොත්තමේ ගුණ',\r
+       upload: 'උඩුගතකිරීම',\r
+       urlMissing: 'රුප මුලාශ්‍ර URL නැත.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'මාඉම් සම්පුර්ණ සංක්‍යාවක් විය යුතුය.',\r
+       validateHSpace: 'HSpace  සම්පුර්ණ සංක්‍යාවක් විය යුතුය',\r
+       validateVSpace: 'VSpace සම්පුර්ණ සංක්‍යාවක් විය යුතුය.'\r
+} );\r
diff --git a/sources/plugins/image/lang/sk.js b/sources/plugins/image/lang/sk.js
new file mode 100644 (file)
index 0000000..38bc38a
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sk', {\r
+       alt: 'Alternatívny text',\r
+       border: 'Rám (border)',\r
+       btnUpload: 'Odoslať to na server',\r
+       button2Img: 'Chcete zmeniť vybrané obrázkové tlačidlo na jednoduchý obrázok?',\r
+       hSpace: 'H-medzera',\r
+       img2Button: 'Chcete zmeniť vybraný obrázok na obrázkové tlačidlo?',\r
+       infoTab: 'Informácie o obrázku',\r
+       linkTab: 'Odkaz',\r
+       lockRatio: 'Pomer zámky',\r
+       menu: 'Vlastnosti obrázka',\r
+       resetSize: 'Pôvodná veľkosť',\r
+       title: 'Vlastnosti obrázka',\r
+       titleButton: 'Vlastnosti obrázkového tlačidla',\r
+       upload: 'Nahrať',\r
+       urlMissing: 'Chýba URL zdroja obrázka.',\r
+       vSpace: 'V-medzera',\r
+       validateBorder: 'Rám (border) musí byť celé číslo.',\r
+       validateHSpace: 'H-medzera musí byť celé číslo.',\r
+       validateVSpace: 'V-medzera musí byť celé číslo.'\r
+} );\r
diff --git a/sources/plugins/image/lang/sl.js b/sources/plugins/image/lang/sl.js
new file mode 100644 (file)
index 0000000..29c440f
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sl', {\r
+       alt: 'Nadomestno besedilo',\r
+       border: 'Obroba',\r
+       btnUpload: 'Pošlji na strežnik',\r
+       button2Img: 'Želite pretvoriti izbrani gumb s sliko v preprosto sliko?',\r
+       hSpace: 'Vodoravni odmik',\r
+       img2Button: 'Želite pretvoriti izbrano sliko v gumb s sliko?',\r
+       infoTab: 'Podatki o sliki',\r
+       linkTab: 'Povezava',\r
+       lockRatio: 'Zakleni razmerje',\r
+       menu: 'Lastnosti slike',\r
+       resetSize: 'Ponastavi velikost',\r
+       title: 'Lastnosti slike',\r
+       titleButton: 'Lastnosti gumba s sliko',\r
+       upload: 'Naloži',\r
+       urlMissing: 'Manjka URL vira slike.',\r
+       vSpace: 'Navpični odmik',\r
+       validateBorder: 'Meja mora biti celo število.',\r
+       validateHSpace: 'Vodoravni odmik mora biti celo število.',\r
+       validateVSpace: 'VSpace mora biti celo število.'\r
+} );\r
diff --git a/sources/plugins/image/lang/sq.js b/sources/plugins/image/lang/sq.js
new file mode 100644 (file)
index 0000000..072a96d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sq', {\r
+       alt: 'Tekst Alternativ',\r
+       border: 'Korniza',\r
+       btnUpload: 'Dërgo në server',\r
+       button2Img: 'Dëshironi të e ndërroni pullën e fotos së selektuar në një foto të thjeshtë?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Dëshironi të ndryshoni foton e përzgjedhur në pullë?',\r
+       infoTab: 'Informacione mbi Fotografinë',\r
+       linkTab: 'Nyja',\r
+       lockRatio: 'Mbyll Racionin',\r
+       menu: 'Karakteristikat e Fotografisë',\r
+       resetSize: 'Rikthe Madhësinë',\r
+       title: 'Karakteristikat e Fotografisë',\r
+       titleButton: 'Karakteristikat e Pullës së Fotografisë',\r
+       upload: 'Ngarko',\r
+       urlMissing: 'Mungon URL e burimit të fotografisë.',\r
+       vSpace: 'Hapësira Vertikale',\r
+       validateBorder: 'Korniza duhet të jetë numër i plotë.',\r
+       validateHSpace: 'Hapësira horizontale duhet të jetë numër i plotë.',\r
+       validateVSpace: 'Hapësira vertikale duhet të jetë numër i plotë.'\r
+} );\r
diff --git a/sources/plugins/image/lang/sr-latn.js b/sources/plugins/image/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..b3c2a98
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sr-latn', {\r
+       alt: 'Alternativni tekst',\r
+       border: 'Okvir',\r
+       btnUpload: 'Pošalji na server',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Info slike',\r
+       linkTab: 'Link',\r
+       lockRatio: 'Zaključaj odnos',\r
+       menu: 'Osobine slika',\r
+       resetSize: 'Resetuj veličinu',\r
+       title: 'Osobine slika',\r
+       titleButton: 'Osobine dugmeta sa slikom',\r
+       upload: 'Pošalji',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/sr.js b/sources/plugins/image/lang/sr.js
new file mode 100644 (file)
index 0000000..4a269d9
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sr', {\r
+       alt: 'Алтернативни текст',\r
+       border: 'Оквир',\r
+       btnUpload: 'Пошаљи на сервер',\r
+       button2Img: 'Да ли желите да промените одабрану слику дугмета као једноставну слику?',\r
+       hSpace: 'HSpace',\r
+       img2Button: 'Да ли желите да промените одабрану слику у слику дугмета?',\r
+       infoTab: 'Инфо слике',\r
+       linkTab: 'Линк',\r
+       lockRatio: 'Закључај однос',\r
+       menu: 'Особине слика',\r
+       resetSize: 'Ресетуј величину',\r
+       title: 'Особине слика',\r
+       titleButton: 'Особине дугмета са сликом',\r
+       upload: 'Пошаљи',\r
+       urlMissing: 'Недостаје УРЛ слике.',\r
+       vSpace: 'VSpace',\r
+       validateBorder: 'Ивица треба да буде цифра.',\r
+       validateHSpace: 'HSpace треба да буде цифра.',\r
+       validateVSpace: 'VSpace треба да буде цифра.'\r
+} );\r
diff --git a/sources/plugins/image/lang/sv.js b/sources/plugins/image/lang/sv.js
new file mode 100644 (file)
index 0000000..db07c37
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'sv', {\r
+       alt: 'Alternativ text',\r
+       border: 'Kant',\r
+       btnUpload: 'Skicka till server',\r
+       button2Img: 'Vill du omvandla den valda bildknappen på en enkel bild?',\r
+       hSpace: 'Horis. marginal',\r
+       img2Button: 'Vill du omvandla den valda bildknappen på en enkel bild?',\r
+       infoTab: 'Bildinformation',\r
+       linkTab: 'Länk',\r
+       lockRatio: 'Lås höjd/bredd förhållanden',\r
+       menu: 'Bildegenskaper',\r
+       resetSize: 'Återställ storlek',\r
+       title: 'Bildegenskaper',\r
+       titleButton: 'Egenskaper för bildknapp',\r
+       upload: 'Ladda upp',\r
+       urlMissing: 'Bildkällans URL saknas.',\r
+       vSpace: 'Vert. marginal',\r
+       validateBorder: 'Kantlinje måste vara ett heltal.',\r
+       validateHSpace: 'HSpace måste vara ett heltal.',\r
+       validateVSpace: 'VSpace måste vara ett heltal.'\r
+} );\r
diff --git a/sources/plugins/image/lang/th.js b/sources/plugins/image/lang/th.js
new file mode 100644 (file)
index 0000000..0d33bb3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'th', {\r
+       alt: 'คำประกอบรูปภาพ',\r
+       border: 'ขนาดขอบรูป',\r
+       btnUpload: 'อัพโหลดไฟล์ไปเก็บไว้ที่เครื่องแม่ข่าย (เซิร์ฟเวอร์)',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'ระยะแนวนอน',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'ข้อมูลของรูปภาพ',\r
+       linkTab: 'ลิ้งค์',\r
+       lockRatio: 'กำหนดอัตราส่วน กว้าง-สูง แบบคงที่',\r
+       menu: 'คุณสมบัติของ รูปภาพ',\r
+       resetSize: 'กำหนดรูปเท่าขนาดจริง',\r
+       title: 'คุณสมบัติของ รูปภาพ',\r
+       titleButton: 'คุณสมบัติของ ปุ่มแบบรูปภาพ',\r
+       upload: 'อัพโหลดไฟล์',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'ระยะแนวตั้ง',\r
+       validateBorder: 'Border must be a whole number.', // MISSING\r
+       validateHSpace: 'HSpace must be a whole number.', // MISSING\r
+       validateVSpace: 'VSpace must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/image/lang/tr.js b/sources/plugins/image/lang/tr.js
new file mode 100644 (file)
index 0000000..2f707a1
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'tr', {\r
+       alt: 'Alternatif Yazı',\r
+       border: 'Kenar',\r
+       btnUpload: 'Sunucuya Yolla',\r
+       button2Img: 'Seçili resim butonunu basit resime çevirmek istermisiniz?',\r
+       hSpace: 'Yatay Boşluk',\r
+       img2Button: 'Seçili olan resimi, resimli butona çevirmek istermisiniz?',\r
+       infoTab: 'Resim Bilgisi',\r
+       linkTab: 'Köprü',\r
+       lockRatio: 'Oranı Kilitle',\r
+       menu: 'Resim Özellikleri',\r
+       resetSize: 'Boyutu Başa Döndür',\r
+       title: 'Resim Özellikleri',\r
+       titleButton: 'Resimli Düğme Özellikleri',\r
+       upload: 'Karşıya Yükle',\r
+       urlMissing: 'Resmin URL kaynağı eksiktir.',\r
+       vSpace: 'Dikey Boşluk',\r
+       validateBorder: 'Çerçeve tam sayı olmalıdır.',\r
+       validateHSpace: 'HSpace tam sayı olmalıdır.',\r
+       validateVSpace: 'VSpace tam sayı olmalıdır.'\r
+} );\r
diff --git a/sources/plugins/image/lang/tt.js b/sources/plugins/image/lang/tt.js
new file mode 100644 (file)
index 0000000..e659066
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'tt', {\r
+       alt: 'Альтернатив текст',\r
+       border: 'Чик',\r
+       btnUpload: 'Серверга җибәрү',\r
+       button2Img: 'Do you want to transform the selected image button on a simple image?', // MISSING\r
+       hSpace: 'Горизонталь ара',\r
+       img2Button: 'Do you want to transform the selected image on a image button?', // MISSING\r
+       infoTab: 'Рәсем тасвирламасы',\r
+       linkTab: 'Сылталама',\r
+       lockRatio: 'Lock Ratio', // MISSING\r
+       menu: 'Рәсем үзлекләре',\r
+       resetSize: 'Баштагы зурлык',\r
+       title: 'Рәсем үзлекләре',\r
+       titleButton: 'Рәсемле төймə үзлекләре',\r
+       upload: 'Йөкләү',\r
+       urlMissing: 'Image source URL is missing.', // MISSING\r
+       vSpace: 'Вертикаль ара',\r
+       validateBorder: 'Чик киңлеге сан булырга тиеш.',\r
+       validateHSpace: 'Горизонталь ара бөтен сан булырга тиеш.',\r
+       validateVSpace: 'Вертикаль ара бөтен сан булырга тиеш.'\r
+} );\r
diff --git a/sources/plugins/image/lang/ug.js b/sources/plugins/image/lang/ug.js
new file mode 100644 (file)
index 0000000..d2a28ef
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'ug', {\r
+       alt: 'تېكىست ئالماشتۇر',\r
+       border: 'گىرۋەك چوڭلۇقى',\r
+       btnUpload: 'مۇلازىمېتىرغا يۈكلە',\r
+       button2Img: 'نۆۋەتتىكى توپچىنى سۈرەتكە ئۆزگەرتەمسىز؟',\r
+       hSpace: 'توغرىسىغا ئارىلىقى',\r
+       img2Button: 'نۆۋەتتىكى سۈرەتنى توپچىغا ئۆزگەرتەمسىز؟',\r
+       infoTab: 'سۈرەت',\r
+       linkTab: 'ئۇلانما',\r
+       lockRatio: 'نىسبەتنى قۇلۇپلا',\r
+       menu: 'سۈرەت خاسلىقى',\r
+       resetSize: 'ئەسلى چوڭلۇق',\r
+       title: 'سۈرەت خاسلىقى',\r
+       titleButton: 'سۈرەت دائىرە خاسلىقى',\r
+       upload: 'يۈكلە',\r
+       urlMissing: 'سۈرەتنىڭ ئەسلى ھۆججەت ئادرېسى كەم',\r
+       vSpace: 'بويىغا ئارىلىقى',\r
+       validateBorder: 'گىرۋەك چوڭلۇقى چوقۇم سان بولىدۇ',\r
+       validateHSpace: 'توغرىسىغا ئارىلىق چوقۇم پۈتۈن سان بولىدۇ',\r
+       validateVSpace: 'بويىغا ئارىلىق چوقۇم پۈتۈن سان بولىدۇ'\r
+} );\r
diff --git a/sources/plugins/image/lang/uk.js b/sources/plugins/image/lang/uk.js
new file mode 100644 (file)
index 0000000..ace2eea
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'uk', {\r
+       alt: 'Альтернативний текст',\r
+       border: 'Рамка',\r
+       btnUpload: 'Надіслати на сервер',\r
+       button2Img: 'Бажаєте перетворити обрану кнопку-зображення на просте зображення?',\r
+       hSpace: 'Гориз. відступ',\r
+       img2Button: 'Бажаєте перетворити обране зображення на кнопку-зображення?',\r
+       infoTab: 'Інформація про зображення',\r
+       linkTab: 'Посилання',\r
+       lockRatio: 'Зберегти пропорції',\r
+       menu: 'Властивості зображення',\r
+       resetSize: 'Очистити поля розмірів',\r
+       title: 'Властивості зображення',\r
+       titleButton: 'Властивості кнопки із зображенням',\r
+       upload: 'Надіслати',\r
+       urlMissing: 'Вкажіть URL зображення.',\r
+       vSpace: 'Верт. відступ',\r
+       validateBorder: 'Ширина рамки повинна бути цілим числом.',\r
+       validateHSpace: 'Гориз. відступ повинен бути цілим числом.',\r
+       validateVSpace: 'Верт. відступ повинен бути цілим числом.'\r
+} );\r
diff --git a/sources/plugins/image/lang/vi.js b/sources/plugins/image/lang/vi.js
new file mode 100644 (file)
index 0000000..4c33fd5
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'vi', {\r
+       alt: 'Chú thích ảnh',\r
+       border: 'Đường viền',\r
+       btnUpload: 'Tải lên máy chủ',\r
+       button2Img: 'Bạn có muốn chuyển nút bấm bằng ảnh được chọn thành ảnh?',\r
+       hSpace: 'Khoảng đệm ngang',\r
+       img2Button: 'Bạn có muốn chuyển đổi ảnh được chọn thành nút bấm bằng ảnh?',\r
+       infoTab: 'Thông tin của ảnh',\r
+       linkTab: 'Tab liên kết',\r
+       lockRatio: 'Giữ nguyên tỷ lệ',\r
+       menu: 'Thuộc tính của ảnh',\r
+       resetSize: 'Kích thước gốc',\r
+       title: 'Thuộc tính của ảnh',\r
+       titleButton: 'Thuộc tính nút của ảnh',\r
+       upload: 'Tải lên',\r
+       urlMissing: 'Thiếu đường dẫn hình ảnh',\r
+       vSpace: 'Khoảng đệm dọc',\r
+       validateBorder: 'Chiều rộng của đường viền phải là một số nguyên dương',\r
+       validateHSpace: 'Khoảng đệm ngang phải là một số nguyên dương',\r
+       validateVSpace: 'Khoảng đệm dọc phải là một số nguyên dương'\r
+} );\r
diff --git a/sources/plugins/image/lang/zh-cn.js b/sources/plugins/image/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..287a362
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'zh-cn', {\r
+       alt: '替换文本',\r
+       border: '边框大小',\r
+       btnUpload: '上传到服务器',\r
+       button2Img: '确定要把当前图像按钮转换为普通图像吗?',\r
+       hSpace: '水平间距',\r
+       img2Button: '确定要把当前图像改变为图像按钮吗?',\r
+       infoTab: '图像信息',\r
+       linkTab: '链接',\r
+       lockRatio: '锁定比例',\r
+       menu: '图像属性',\r
+       resetSize: '原始尺寸',\r
+       title: '图像属性',\r
+       titleButton: '图像域属性',\r
+       upload: '上传',\r
+       urlMissing: '缺少图像源文件地址',\r
+       vSpace: '垂直间距',\r
+       validateBorder: '边框大小必须为整数格式',\r
+       validateHSpace: '水平间距必须为整数格式',\r
+       validateVSpace: '垂直间距必须为整数格式'\r
+} );\r
diff --git a/sources/plugins/image/lang/zh.js b/sources/plugins/image/lang/zh.js
new file mode 100644 (file)
index 0000000..920b554
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'image', 'zh', {\r
+       alt: '替代文字',\r
+       border: '框線',\r
+       btnUpload: '傳送到伺服器',\r
+       button2Img: '請問您確定要將「圖片按鈕」轉換成「圖片」嗎?',\r
+       hSpace: 'HSpace',\r
+       img2Button: '請問您確定要將「圖片」轉換成「圖片按鈕」嗎?',\r
+       infoTab: '影像資訊',\r
+       linkTab: '連結',\r
+       lockRatio: '固定比例',\r
+       menu: '影像屬性',\r
+       resetSize: '重設大小',\r
+       title: '影像屬性',\r
+       titleButton: '影像按鈕屬性',\r
+       upload: '上傳',\r
+       urlMissing: '遺失圖片來源之 URL ',\r
+       vSpace: 'VSpace',\r
+       validateBorder: '框線必須是整數。',\r
+       validateHSpace: 'HSpace 必須是整數。',\r
+       validateVSpace: 'VSpace 必須是整數。'\r
+} );\r
diff --git a/sources/plugins/image/plugin.js b/sources/plugins/image/plugin.js
new file mode 100644 (file)
index 0000000..1394510
--- /dev/null
@@ -0,0 +1,183 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The Image plugin.\r
+ */\r
+\r
+( function() {\r
+\r
+       CKEDITOR.plugins.add( 'image', {\r
+               requires: 'dialog',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'image', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       // Abort when Image2 is to be loaded since both plugins\r
+                       // share the same button, command, etc. names (#11222).\r
+                       if ( editor.plugins.image2 )\r
+                               return;\r
+\r
+                       var pluginName = 'image';\r
+\r
+                       // Register the dialog.\r
+                       CKEDITOR.dialog.add( pluginName, this.path + 'dialogs/image.js' );\r
+\r
+                       var allowed = 'img[alt,!src]{border-style,border-width,float,height,margin,margin-bottom,margin-left,margin-right,margin-top,width}',\r
+                               required = 'img[alt,src]';\r
+\r
+                       if ( CKEDITOR.dialog.isTabEnabled( editor, pluginName, 'advanced' ) )\r
+                               allowed = 'img[alt,dir,id,lang,longdesc,!src,title]{*}(*)';\r
+\r
+                       // Register the command.\r
+                       editor.addCommand( pluginName, new CKEDITOR.dialogCommand( pluginName, {\r
+                               allowedContent: allowed,\r
+                               requiredContent: required,\r
+                               contentTransformations: [\r
+                                       [ 'img{width}: sizeToStyle', 'img[width]: sizeToAttribute' ],\r
+                                       [ 'img{float}: alignmentToStyle', 'img[align]: alignmentToAttribute' ]\r
+                               ]\r
+                       } ) );\r
+\r
+                       // Register the toolbar button.\r
+                       editor.ui.addButton && editor.ui.addButton( 'Image', {\r
+                               label: editor.lang.common.image,\r
+                               command: pluginName,\r
+                               toolbar: 'insert,10'\r
+                       } );\r
+\r
+                       editor.on( 'doubleclick', function( evt ) {\r
+                               var element = evt.data.element;\r
+\r
+                               if ( element.is( 'img' ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() )\r
+                                       evt.data.dialog = 'image';\r
+                       } );\r
+\r
+                       // If the "menu" plugin is loaded, register the menu items.\r
+                       if ( editor.addMenuItems ) {\r
+                               editor.addMenuItems( {\r
+                                       image: {\r
+                                               label: editor.lang.image.menu,\r
+                                               command: 'image',\r
+                                               group: 'image'\r
+                                       }\r
+                               } );\r
+                       }\r
+\r
+                       // If the "contextmenu" plugin is loaded, register the listeners.\r
+                       if ( editor.contextMenu ) {\r
+                               editor.contextMenu.addListener( function( element ) {\r
+                                       if ( getSelectedImage( editor, element ) )\r
+                                               return { image: CKEDITOR.TRISTATE_OFF };\r
+                               } );\r
+                       }\r
+               },\r
+               afterInit: function( editor ) {\r
+                       // Abort when Image2 is to be loaded since both plugins\r
+                       // share the same button, command, etc. names (#11222).\r
+                       if ( editor.plugins.image2 )\r
+                               return;\r
+\r
+                       // Customize the behavior of the alignment commands. (#7430)\r
+                       setupAlignCommand( 'left' );\r
+                       setupAlignCommand( 'right' );\r
+                       setupAlignCommand( 'center' );\r
+                       setupAlignCommand( 'block' );\r
+\r
+                       function setupAlignCommand( value ) {\r
+                               var command = editor.getCommand( 'justify' + value );\r
+                               if ( command ) {\r
+                                       if ( value == 'left' || value == 'right' ) {\r
+                                               command.on( 'exec', function( evt ) {\r
+                                                       var img = getSelectedImage( editor ),\r
+                                                               align;\r
+                                                       if ( img ) {\r
+                                                               align = getImageAlignment( img );\r
+                                                               if ( align == value ) {\r
+                                                                       img.removeStyle( 'float' );\r
+\r
+                                                                       // Remove "align" attribute when necessary.\r
+                                                                       if ( value == getImageAlignment( img ) )\r
+                                                                               img.removeAttribute( 'align' );\r
+                                                               } else {\r
+                                                                       img.setStyle( 'float', value );\r
+                                                               }\r
+\r
+                                                               evt.cancel();\r
+                                                       }\r
+                                               } );\r
+                                       }\r
+\r
+                                       command.on( 'refresh', function( evt ) {\r
+                                               var img = getSelectedImage( editor ),\r
+                                                       align;\r
+                                               if ( img ) {\r
+                                                       align = getImageAlignment( img );\r
+\r
+                                                       this.setState(\r
+                                                       ( align == value ) ? CKEDITOR.TRISTATE_ON : ( value == 'right' || value == 'left' ) ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );\r
+\r
+                                                       evt.cancel();\r
+                                               }\r
+                                       } );\r
+                               }\r
+                       }\r
+               }\r
+       } );\r
+\r
+       function getSelectedImage( editor, element ) {\r
+               if ( !element ) {\r
+                       var sel = editor.getSelection();\r
+                       element = sel.getSelectedElement();\r
+               }\r
+\r
+               if ( element && element.is( 'img' ) && !element.data( 'cke-realelement' ) && !element.isReadOnly() )\r
+                       return element;\r
+       }\r
+\r
+       function getImageAlignment( element ) {\r
+               var align = element.getStyle( 'float' );\r
+\r
+               if ( align == 'inherit' || align == 'none' )\r
+                       align = 0;\r
+\r
+               if ( !align )\r
+                       align = element.getAttribute( 'align' );\r
+\r
+               return align;\r
+       }\r
+\r
+} )();\r
+\r
+/**\r
+ * Determines whether dimension inputs should be automatically filled when the image URL changes in the Image plugin dialog window.\r
+ *\r
+ *             config.image_prefillDimensions = false;\r
+ *\r
+ * @since 4.5\r
+ * @cfg {Boolean} [image_prefillDimensions=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Whether to remove links when emptying the link URL field in the Image dialog window.\r
+ *\r
+ *             config.image_removeLinkByEmptyURL = false;\r
+ *\r
+ * @cfg {Boolean} [image_removeLinkByEmptyURL=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.image_removeLinkByEmptyURL = true;\r
+\r
+/**\r
+ * Padding text to set off the image in the preview area.\r
+ *\r
+ *             config.image_previewText = CKEDITOR.tools.repeat( '___ ', 100 );\r
+ *\r
+ * @cfg {String} [image_previewText='Lorem ipsum dolor...' (placeholder text)]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/indent/dev/indent.html b/sources/plugins/indent/dev/indent.html
new file mode 100644 (file)
index 0000000..8b935ae
--- /dev/null
@@ -0,0 +1,284 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Indent DEV sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <style>\r
+               body {\r
+                       padding: 20px;\r
+                       margin: 0;\r
+               }\r
+               .editors {\r
+                       display: block;\r
+                       overflow: hidden;\r
+                       width: 100%;\r
+                       margin: 0px auto;\r
+                       list-style-type: none;\r
+                       margin: 0;\r
+                       padding: 0;\r
+\r
+                       box-sizing: content-box;\r
+\r
+                       background: #eee;\r
+               }\r
+               .editors li {\r
+                       width: 50%;\r
+                       margin: 0;\r
+                       padding: 10px;\r
+                       float: left;\r
+\r
+                       box-sizing: border-box;\r
+               }\r
+               .editors li:nth-child(2n) {\r
+                       background: #D4E59A;\r
+               }\r
+               #menu {\r
+                       position: fixed;\r
+                       top: 0;\r
+                       right: 20px;\r
+                       padding: 5px;\r
+                       border: 1px solid #aaa;\r
+                       background: #eee;\r
+               }\r
+\r
+       </style>\r
+</head>\r
+<body>\r
+       <p id="menu">\r
+               <a href="#listnblock">List &amp; Block</a>,\r
+               <a href="#classes">Classes</a>,\r
+               <a href="#list">List</a>,\r
+               <a href="#block">Block</a>,\r
+               <a href="#br">ENTER_BR</a>\r
+       </p>\r
+\r
+       <h1 class="samples">Indent DEV sample</h1>\r
+       <h2 id="listnblock">List &amp; Block</h2>\r
+       <ul class="editors">\r
+               <li>\r
+                       <textarea cols="80" id="editor1" rows="10">\r
+                               <p>xx</p>\r
+                               <ul>\r
+                                       <li>x</li>\r
+                                       <li>y</li>\r
+                               </ul>\r
+                               <p>xx</p>\r
+\r
+                               <br>\r
+\r
+                               <ul><li><ol><li>xx</li></ol></li><li>yy</li></ul>\r
+                       </textarea>\r
+               </li>\r
+               <li>\r
+                       <pre id="editor1_out"></pre>\r
+               </li>\r
+       </ul>\r
+\r
+       <h2 id="classes">Indent classes</h2>\r
+       <ul class="editors">\r
+               <li>\r
+                       <textarea cols="80" id="editor2" rows="10">\r
+                               <ul>\r
+                                       <li>a</li>\r
+                                       <li>\r
+                                               b\r
+                                               <ol>\r
+                                                       <li>inner</li>\r
+                                               </ol>\r
+                                       </li>\r
+                                       <li>c</li>\r
+                               </ul>\r
+                               <p>moo</p>\r
+                       </textarea>\r
+               </li>\r
+               <li>\r
+                       <pre id="editor2_out"></pre>\r
+               </li>\r
+       </ul>\r
+\r
+       <h2 id="list">List only</h2>\r
+       <ul class="editors">\r
+               <li>\r
+                       <textarea cols="80" id="editor3" rows="10">\r
+                               <ul>\r
+                                       <li>a</li>\r
+                                       <li>\r
+                                               b\r
+                                               <ol>\r
+                                                       <li>inner</li>\r
+                                               </ol>\r
+                                       </li>\r
+                                       <li>c</li>\r
+                               </ul>\r
+                               <p>moo</p>\r
+                       </textarea>\r
+               </li>\r
+               <li>\r
+                       <pre id="editor3_out"></pre>\r
+               </li>\r
+       </ul>\r
+\r
+       <h2 id="block">Block only</h2>\r
+       <ul class="editors">\r
+               <li>\r
+                       <textarea cols="80" id="editor4" rows="10">\r
+                               <ul>\r
+                                       <li>a</li>\r
+                                       <li>\r
+                                               b\r
+                                               <ol>\r
+                                                       <li>inner</li>\r
+                                               </ol>\r
+                                       </li>\r
+                                       <li>c</li>\r
+                               </ul>\r
+                               <p>moo</p>\r
+                       </textarea>\r
+               </li>\r
+               <li>\r
+                       <pre id="editor4_out"></pre>\r
+               </li>\r
+       </ul>\r
+\r
+       <h2 id="br">CKEDITOR.ENTER_BR</h2>\r
+       <ul class="editors">\r
+               <li>\r
+                       <textarea cols="80" id="editor5" rows="10">\r
+                               Text\r
+                               <br>\r
+                               <ul>\r
+                                       <li>a</li>\r
+                                       <li>b</li>\r
+                               </ul>\r
+                       </textarea>\r
+               </li>\r
+               <li>\r
+                       <pre id="editor5_out"></pre>\r
+               </li>\r
+       </ul>\r
+       <script>\r
+\r
+               var plugins = 'enterkey,toolbar,htmlwriter,wysiwygarea,undo,sourcearea,clipboard,list,justify,indent,indentlist,indentblock';\r
+\r
+               CKEDITOR.config.indentOffset = 10;\r
+               CKEDITOR.addCss( '\\r
+                       .i1{ margin-left: 10px}\\r
+                       .i2{ margin-left: 20px}\\r
+                       .i3{ margin-left: 30px}' );\r
+\r
+               function showData( event ) {\r
+                       CKEDITOR.document.getById( this.name + '_out' ).setText( getHtmlWithSelection( this ) );\r
+               }\r
+\r
+               function browserHtmlFix( html ) {\r
+                       if ( CKEDITOR.env.ie && ( document.documentMode || CKEDITOR.env.version ) < 9 ) {\r
+                               // Fix output base href on anchored link.\r
+                               html = html.replace( /href="(.*?)#(.*?)"/gi,\r
+                                  function( m, base, anchor ) {\r
+                                          if ( base == window.location.href.replace( window.location.hash, '' ) )\r
+                                                  return 'href="#' + anchor + '"';\r
+\r
+                                          return m;\r
+                                  } );\r
+\r
+                               // Fix output line break after HR.\r
+                               html = html.replace( /(<HR>)\r\n/gi, function( m, hr ) { return hr; } );\r
+                       }\r
+\r
+                       return html;\r
+               }\r
+\r
+               function getHtmlWithSelection( editorOrElement, root ) {\r
+                       var isEditor = editorOrElement instanceof CKEDITOR.editor,\r
+                               element =  isEditor ? editorOrElement.editable() : editorOrElement;\r
+\r
+                       root = isEditor ? element :\r
+                                  root instanceof CKEDITOR.dom.document ?\r
+                                  root.getBody() : root || CKEDITOR.document.getBody();\r
+\r
+                       function replaceWithBookmark( match, startOrEnd ) {\r
+                               var bookmark;\r
+                               switch( startOrEnd ) {\r
+                                       case 'S' :\r
+                                               bookmark = '[';\r
+                                               break;\r
+                                       case 'E' :\r
+                                               bookmark = ']';\r
+                                               break;\r
+                                       case 'C' :\r
+                                               bookmark = '^';\r
+                                               break;\r
+                               }\r
+                               return bookmark;\r
+                       }\r
+\r
+                       // Hack: force remove the filling char hack in Webkit.\r
+                       isEditor && CKEDITOR.env.webkit && editorOrElement.fire( 'beforeSetMode' );\r
+\r
+                       var sel = isEditor ? editorOrElement.getSelection()\r
+                                         : new CKEDITOR.dom.selection( root );\r
+\r
+                       var doc = sel.document;\r
+                       var ranges = sel.getRanges(),\r
+                               range;\r
+\r
+                       var bms = [];\r
+                       var iter = ranges.createIterator();\r
+                       while( range = iter.getNextRange() )\r
+                               bms.push( range.createBookmark( 1 ) );\r
+\r
+                       var html = browserHtmlFix( isEditor ? editorOrElement.getData() : element.getHtml() );\r
+                       html = html.replace( /<span\b[^>]*?id="?cke_bm_\d+(\w)"?\b[^>]*?>.*?<\/span>/gi,\r
+                                                                replaceWithBookmark );\r
+\r
+                       for ( var i = 0, bm; i < bms.length; i++ ) {\r
+                               bm = bms[ i ];\r
+                               var start = doc.getById( bm.startNode ),\r
+                                       end = doc.getById( bm.endNode );\r
+\r
+                               start && start.remove();\r
+                               end && end.remove();\r
+                       }\r
+\r
+                       return html;\r
+               }\r
+\r
+               CKEDITOR.on( 'instanceReady', function ( event ) {\r
+                       var editor = event.editor;\r
+\r
+                       showData.call( editor );\r
+\r
+                       editor.on( 'afterCommandExec', showData, editor );\r
+               });\r
+\r
+               CKEDITOR.replace( 'editor1', {\r
+                       plugins: plugins\r
+               } );\r
+\r
+               CKEDITOR.replace( 'editor2', {\r
+                       plugins: plugins,\r
+                       indentClasses: [ 'i1', 'i2', 'i3' ]\r
+               } );\r
+\r
+               CKEDITOR.replace( 'editor3', {\r
+                       plugins: plugins,\r
+                       removePlugins: 'indentblock'\r
+               } );\r
+\r
+               CKEDITOR.replace( 'editor4', {\r
+                       plugins: plugins,\r
+                       removePlugins: 'indentlist'\r
+               } );\r
+\r
+               CKEDITOR.replace( 'editor5', {\r
+                       plugins: plugins,\r
+                       enterMode: CKEDITOR.ENTER_BR\r
+               } );\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/indent/icons/hidpi/indent-rtl.png b/sources/plugins/indent/icons/hidpi/indent-rtl.png
new file mode 100644 (file)
index 0000000..72bf567
Binary files /dev/null and b/sources/plugins/indent/icons/hidpi/indent-rtl.png differ
diff --git a/sources/plugins/indent/icons/hidpi/indent.png b/sources/plugins/indent/icons/hidpi/indent.png
new file mode 100644 (file)
index 0000000..6381b23
Binary files /dev/null and b/sources/plugins/indent/icons/hidpi/indent.png differ
diff --git a/sources/plugins/indent/icons/hidpi/outdent-rtl.png b/sources/plugins/indent/icons/hidpi/outdent-rtl.png
new file mode 100644 (file)
index 0000000..441e204
Binary files /dev/null and b/sources/plugins/indent/icons/hidpi/outdent-rtl.png differ
diff --git a/sources/plugins/indent/icons/hidpi/outdent.png b/sources/plugins/indent/icons/hidpi/outdent.png
new file mode 100644 (file)
index 0000000..8fa4e5e
Binary files /dev/null and b/sources/plugins/indent/icons/hidpi/outdent.png differ
diff --git a/sources/plugins/indent/icons/indent-rtl.png b/sources/plugins/indent/icons/indent-rtl.png
new file mode 100644 (file)
index 0000000..0327578
Binary files /dev/null and b/sources/plugins/indent/icons/indent-rtl.png differ
diff --git a/sources/plugins/indent/icons/indent.png b/sources/plugins/indent/icons/indent.png
new file mode 100644 (file)
index 0000000..0a5d293
Binary files /dev/null and b/sources/plugins/indent/icons/indent.png differ
diff --git a/sources/plugins/indent/icons/outdent-rtl.png b/sources/plugins/indent/icons/outdent-rtl.png
new file mode 100644 (file)
index 0000000..ce9ce08
Binary files /dev/null and b/sources/plugins/indent/icons/outdent-rtl.png differ
diff --git a/sources/plugins/indent/icons/outdent.png b/sources/plugins/indent/icons/outdent.png
new file mode 100644 (file)
index 0000000..351f05d
Binary files /dev/null and b/sources/plugins/indent/icons/outdent.png differ
diff --git a/sources/plugins/indent/lang/af.js b/sources/plugins/indent/lang/af.js
new file mode 100644 (file)
index 0000000..14fff63
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'af', {\r
+       indent: 'Vergroot inspring',\r
+       outdent: 'Verklein inspring'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ar.js b/sources/plugins/indent/lang/ar.js
new file mode 100644 (file)
index 0000000..fe078cb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ar', {\r
+       indent: 'زيادة المسافة البادئة',\r
+       outdent: 'إنقاص المسافة البادئة'\r
+} );\r
diff --git a/sources/plugins/indent/lang/az.js b/sources/plugins/indent/lang/az.js
new file mode 100644 (file)
index 0000000..389d1d9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'az', {\r
+       indent: 'Sol boşluqu artır',\r
+       outdent: 'Sol boşluqu azalt'\r
+} );\r
diff --git a/sources/plugins/indent/lang/bg.js b/sources/plugins/indent/lang/bg.js
new file mode 100644 (file)
index 0000000..f4e0163
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'bg', {\r
+       indent: 'Увеличаване на отстъпа',\r
+       outdent: 'Намаляване на отстъпа'\r
+} );\r
diff --git a/sources/plugins/indent/lang/bn.js b/sources/plugins/indent/lang/bn.js
new file mode 100644 (file)
index 0000000..88a3393
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'bn', {\r
+       indent: 'ইনডেন্ট বাড়াই',\r
+       outdent: 'ইনডেন্ট কমাও'\r
+} );\r
diff --git a/sources/plugins/indent/lang/bs.js b/sources/plugins/indent/lang/bs.js
new file mode 100644 (file)
index 0000000..62df508
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'bs', {\r
+       indent: 'Poveæaj uvod',\r
+       outdent: 'Smanji uvod'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ca.js b/sources/plugins/indent/lang/ca.js
new file mode 100644 (file)
index 0000000..38f299a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ca', {\r
+       indent: 'Augmenta el sagnat',\r
+       outdent: 'Redueix el sagnat'\r
+} );\r
diff --git a/sources/plugins/indent/lang/cs.js b/sources/plugins/indent/lang/cs.js
new file mode 100644 (file)
index 0000000..854aac8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'cs', {\r
+       indent: 'Zvětšit odsazení',\r
+       outdent: 'Zmenšit odsazení'\r
+} );\r
diff --git a/sources/plugins/indent/lang/cy.js b/sources/plugins/indent/lang/cy.js
new file mode 100644 (file)
index 0000000..d1df873
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'cy', {\r
+       indent: 'Cynyddu\'r Mewnoliad',\r
+       outdent: 'Lleihau\'r Mewnoliad'\r
+} );\r
diff --git a/sources/plugins/indent/lang/da.js b/sources/plugins/indent/lang/da.js
new file mode 100644 (file)
index 0000000..27e5731
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'da', {\r
+       indent: 'Forøg indrykning',\r
+       outdent: 'Formindsk indrykning'\r
+} );\r
diff --git a/sources/plugins/indent/lang/de-ch.js b/sources/plugins/indent/lang/de-ch.js
new file mode 100644 (file)
index 0000000..0696275
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'de-ch', {\r
+       indent: 'Einzug erhöhen',\r
+       outdent: 'Einzug verringern'\r
+} );\r
diff --git a/sources/plugins/indent/lang/de.js b/sources/plugins/indent/lang/de.js
new file mode 100644 (file)
index 0000000..3f7a53c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'de', {\r
+       indent: 'Einzug erhöhen',\r
+       outdent: 'Einzug verringern'\r
+} );\r
diff --git a/sources/plugins/indent/lang/el.js b/sources/plugins/indent/lang/el.js
new file mode 100644 (file)
index 0000000..57ac0f5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'el', {\r
+       indent: 'Αύξηση Εσοχής',\r
+       outdent: 'Μείωση Εσοχής'\r
+} );\r
diff --git a/sources/plugins/indent/lang/en-au.js b/sources/plugins/indent/lang/en-au.js
new file mode 100644 (file)
index 0000000..6fd80ea
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'en-au', {\r
+       indent: 'Increase Indent',\r
+       outdent: 'Decrease Indent'\r
+} );\r
diff --git a/sources/plugins/indent/lang/en-ca.js b/sources/plugins/indent/lang/en-ca.js
new file mode 100644 (file)
index 0000000..b103510
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'en-ca', {\r
+       indent: 'Increase Indent',\r
+       outdent: 'Decrease Indent'\r
+} );\r
diff --git a/sources/plugins/indent/lang/en-gb.js b/sources/plugins/indent/lang/en-gb.js
new file mode 100644 (file)
index 0000000..0d2edf3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'en-gb', {\r
+       indent: 'Increase Indent',\r
+       outdent: 'Decrease Indent'\r
+} );\r
diff --git a/sources/plugins/indent/lang/en.js b/sources/plugins/indent/lang/en.js
new file mode 100644 (file)
index 0000000..c5dba75
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'en', {\r
+       indent: 'Increase Indent',\r
+       outdent: 'Decrease Indent'\r
+} );\r
diff --git a/sources/plugins/indent/lang/eo.js b/sources/plugins/indent/lang/eo.js
new file mode 100644 (file)
index 0000000..eb8b8ea
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'eo', {\r
+       indent: 'Pligrandigi Krommarĝenon',\r
+       outdent: 'Malpligrandigi Krommarĝenon'\r
+} );\r
diff --git a/sources/plugins/indent/lang/es.js b/sources/plugins/indent/lang/es.js
new file mode 100644 (file)
index 0000000..d7b01c6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'es', {\r
+       indent: 'Aumentar Sangría',\r
+       outdent: 'Disminuir Sangría'\r
+} );\r
diff --git a/sources/plugins/indent/lang/et.js b/sources/plugins/indent/lang/et.js
new file mode 100644 (file)
index 0000000..ce10b13
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'et', {\r
+       indent: 'Taande suurendamine',\r
+       outdent: 'Taande vähendamine'\r
+} );\r
diff --git a/sources/plugins/indent/lang/eu.js b/sources/plugins/indent/lang/eu.js
new file mode 100644 (file)
index 0000000..7934a48
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'eu', {\r
+       indent: 'Handitu koska',\r
+       outdent: 'Txikitu koska'\r
+} );\r
diff --git a/sources/plugins/indent/lang/fa.js b/sources/plugins/indent/lang/fa.js
new file mode 100644 (file)
index 0000000..932734a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'fa', {\r
+       indent: 'افزایش تورفتگی',\r
+       outdent: 'کاهش تورفتگی'\r
+} );\r
diff --git a/sources/plugins/indent/lang/fi.js b/sources/plugins/indent/lang/fi.js
new file mode 100644 (file)
index 0000000..c6a5b21
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'fi', {\r
+       indent: 'Suurenna sisennystä',\r
+       outdent: 'Pienennä sisennystä'\r
+} );\r
diff --git a/sources/plugins/indent/lang/fo.js b/sources/plugins/indent/lang/fo.js
new file mode 100644 (file)
index 0000000..f6e6671
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'fo', {\r
+       indent: 'Økja reglubrotarinntriv',\r
+       outdent: 'Minka reglubrotarinntriv'\r
+} );\r
diff --git a/sources/plugins/indent/lang/fr-ca.js b/sources/plugins/indent/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..74bbed5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'fr-ca', {\r
+       indent: 'Augmenter le retrait',\r
+       outdent: 'Diminuer le retrait'\r
+} );\r
diff --git a/sources/plugins/indent/lang/fr.js b/sources/plugins/indent/lang/fr.js
new file mode 100644 (file)
index 0000000..0fb1347
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'fr', {\r
+       indent: 'Augmenter le retrait',\r
+       outdent: 'Diminuer le retrait'\r
+} );\r
diff --git a/sources/plugins/indent/lang/gl.js b/sources/plugins/indent/lang/gl.js
new file mode 100644 (file)
index 0000000..832b0ad
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'gl', {\r
+       indent: 'Aumentar a sangría',\r
+       outdent: 'Reducir a sangría'\r
+} );\r
diff --git a/sources/plugins/indent/lang/gu.js b/sources/plugins/indent/lang/gu.js
new file mode 100644 (file)
index 0000000..e69a3ce
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'gu', {\r
+       indent: 'ઇન્ડેન્ટ, લીટીના આરંભમાં જગ્યા વધારવી',\r
+       outdent: 'ઇન્ડેન્ટ લીટીના આરંભમાં જગ્યા ઘટાડવી'\r
+} );\r
diff --git a/sources/plugins/indent/lang/he.js b/sources/plugins/indent/lang/he.js
new file mode 100644 (file)
index 0000000..6fa5ed7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'he', {\r
+       indent: 'הגדלת הזחה',\r
+       outdent: 'הקטנת הזחה'\r
+} );\r
diff --git a/sources/plugins/indent/lang/hi.js b/sources/plugins/indent/lang/hi.js
new file mode 100644 (file)
index 0000000..a3c39d8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'hi', {\r
+       indent: 'इन्डॅन्ट बढ़ायें',\r
+       outdent: 'इन्डॅन्ट कम करें'\r
+} );\r
diff --git a/sources/plugins/indent/lang/hr.js b/sources/plugins/indent/lang/hr.js
new file mode 100644 (file)
index 0000000..dfa90d4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'hr', {\r
+       indent: 'Pomakni udesno',\r
+       outdent: 'Pomakni ulijevo'\r
+} );\r
diff --git a/sources/plugins/indent/lang/hu.js b/sources/plugins/indent/lang/hu.js
new file mode 100644 (file)
index 0000000..22cd8e0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'hu', {\r
+       indent: 'Behúzás növelése',\r
+       outdent: 'Behúzás csökkentése'\r
+} );\r
diff --git a/sources/plugins/indent/lang/id.js b/sources/plugins/indent/lang/id.js
new file mode 100644 (file)
index 0000000..2c66b70
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'id', {\r
+       indent: 'Tingkatkan Lekuk',\r
+       outdent: 'Kurangi Lekuk'\r
+} );\r
diff --git a/sources/plugins/indent/lang/is.js b/sources/plugins/indent/lang/is.js
new file mode 100644 (file)
index 0000000..71f80b1
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'is', {\r
+       indent: 'Minnka inndrátt',\r
+       outdent: 'Auka inndrátt'\r
+} );\r
diff --git a/sources/plugins/indent/lang/it.js b/sources/plugins/indent/lang/it.js
new file mode 100644 (file)
index 0000000..36e0922
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'it', {\r
+       indent: 'Aumenta rientro',\r
+       outdent: 'Riduci rientro'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ja.js b/sources/plugins/indent/lang/ja.js
new file mode 100644 (file)
index 0000000..838f4cb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ja', {\r
+       indent: 'インデント',\r
+       outdent: 'インデント解除'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ka.js b/sources/plugins/indent/lang/ka.js
new file mode 100644 (file)
index 0000000..a0ce0e8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ka', {\r
+       indent: 'მეტად შეწევა',\r
+       outdent: 'ნაკლებად შეწევა'\r
+} );\r
diff --git a/sources/plugins/indent/lang/km.js b/sources/plugins/indent/lang/km.js
new file mode 100644 (file)
index 0000000..514fba2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'km', {\r
+       indent: 'បន្ថែមការចូលបន្ទាត់',\r
+       outdent: 'បន្ថយការចូលបន្ទាត់'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ko.js b/sources/plugins/indent/lang/ko.js
new file mode 100644 (file)
index 0000000..c77afbd
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ko', {\r
+       indent: '들여쓰기',\r
+       outdent: '내어쓰기'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ku.js b/sources/plugins/indent/lang/ku.js
new file mode 100644 (file)
index 0000000..728bfe3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ku', {\r
+       indent: 'زیادکردنی بۆشایی',\r
+       outdent: 'کەمکردنەوەی بۆشایی'\r
+} );\r
diff --git a/sources/plugins/indent/lang/lt.js b/sources/plugins/indent/lang/lt.js
new file mode 100644 (file)
index 0000000..4458598
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'lt', {\r
+       indent: 'Padidinti įtrauką',\r
+       outdent: 'Sumažinti įtrauką'\r
+} );\r
diff --git a/sources/plugins/indent/lang/lv.js b/sources/plugins/indent/lang/lv.js
new file mode 100644 (file)
index 0000000..74d36a4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'lv', {\r
+       indent: 'Palielināt atkāpi',\r
+       outdent: 'Samazināt atkāpi'\r
+} );\r
diff --git a/sources/plugins/indent/lang/mk.js b/sources/plugins/indent/lang/mk.js
new file mode 100644 (file)
index 0000000..440995e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'mk', {\r
+       indent: 'Increase Indent', // MISSING\r
+       outdent: 'Decrease Indent' // MISSING\r
+} );\r
diff --git a/sources/plugins/indent/lang/mn.js b/sources/plugins/indent/lang/mn.js
new file mode 100644 (file)
index 0000000..d9c74ba
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'mn', {\r
+       indent: 'Догол мөр хасах',\r
+       outdent: 'Догол мөр нэмэх'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ms.js b/sources/plugins/indent/lang/ms.js
new file mode 100644 (file)
index 0000000..5fd53e2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ms', {\r
+       indent: 'Tambahkan Inden',\r
+       outdent: 'Kurangkan Inden'\r
+} );\r
diff --git a/sources/plugins/indent/lang/nb.js b/sources/plugins/indent/lang/nb.js
new file mode 100644 (file)
index 0000000..e69a947
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'nb', {\r
+       indent: 'Øk innrykk',\r
+       outdent: 'Reduser innrykk'\r
+} );\r
diff --git a/sources/plugins/indent/lang/nl.js b/sources/plugins/indent/lang/nl.js
new file mode 100644 (file)
index 0000000..8979f8f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'nl', {\r
+       indent: 'Inspringing vergroten',\r
+       outdent: 'Inspringing verkleinen'\r
+} );\r
diff --git a/sources/plugins/indent/lang/no.js b/sources/plugins/indent/lang/no.js
new file mode 100644 (file)
index 0000000..a01c1bb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'no', {\r
+       indent: 'Øk innrykk',\r
+       outdent: 'Reduser innrykk'\r
+} );\r
diff --git a/sources/plugins/indent/lang/oc.js b/sources/plugins/indent/lang/oc.js
new file mode 100644 (file)
index 0000000..00e9cf9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'oc', {\r
+       indent: 'Aumentar l\'alinèa',\r
+       outdent: 'Dmesir l\'alinèa'\r
+} );\r
diff --git a/sources/plugins/indent/lang/pl.js b/sources/plugins/indent/lang/pl.js
new file mode 100644 (file)
index 0000000..ef78a2e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'pl', {\r
+       indent: 'Zwiększ wcięcie',\r
+       outdent: 'Zmniejsz wcięcie'\r
+} );\r
diff --git a/sources/plugins/indent/lang/pt-br.js b/sources/plugins/indent/lang/pt-br.js
new file mode 100644 (file)
index 0000000..45ae5e6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'pt-br', {\r
+       indent: 'Aumentar Recuo',\r
+       outdent: 'Diminuir Recuo'\r
+} );\r
diff --git a/sources/plugins/indent/lang/pt.js b/sources/plugins/indent/lang/pt.js
new file mode 100644 (file)
index 0000000..6d26cb2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'pt', {\r
+       indent: 'Aumentar avanço',\r
+       outdent: 'Diminuir avanço'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ro.js b/sources/plugins/indent/lang/ro.js
new file mode 100644 (file)
index 0000000..708b09d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ro', {\r
+       indent: 'Creşte indentarea',\r
+       outdent: 'Scade indentarea'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ru.js b/sources/plugins/indent/lang/ru.js
new file mode 100644 (file)
index 0000000..aa21b7a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ru', {\r
+       indent: 'Увеличить отступ',\r
+       outdent: 'Уменьшить отступ'\r
+} );\r
diff --git a/sources/plugins/indent/lang/si.js b/sources/plugins/indent/lang/si.js
new file mode 100644 (file)
index 0000000..98b8dd3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'si', {\r
+       indent: 'අතර පරතරය වැඩිකරන්න',\r
+       outdent: 'අතර පරතරය අඩුකරන්න'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sk.js b/sources/plugins/indent/lang/sk.js
new file mode 100644 (file)
index 0000000..3135f4f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sk', {\r
+       indent: 'Zväčšiť odsadenie',\r
+       outdent: 'Zmenšiť odsadenie'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sl.js b/sources/plugins/indent/lang/sl.js
new file mode 100644 (file)
index 0000000..15be2f7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sl', {\r
+       indent: 'Povečaj zamik',\r
+       outdent: 'Zmanjšaj zamik'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sq.js b/sources/plugins/indent/lang/sq.js
new file mode 100644 (file)
index 0000000..9a2dd63
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sq', {\r
+       indent: 'Rrite Identin',\r
+       outdent: 'Zvogëlo Identin'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sr-latn.js b/sources/plugins/indent/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..ca5a140
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sr-latn', {\r
+       indent: 'Uvećaj levu marginu',\r
+       outdent: 'Smanji levu marginu'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sr.js b/sources/plugins/indent/lang/sr.js
new file mode 100644 (file)
index 0000000..f7498be
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sr', {\r
+       indent: 'Увећај леву маргину',\r
+       outdent: 'Смањи леву маргину'\r
+} );\r
diff --git a/sources/plugins/indent/lang/sv.js b/sources/plugins/indent/lang/sv.js
new file mode 100644 (file)
index 0000000..46b0692
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'sv', {\r
+       indent: 'Öka indrag',\r
+       outdent: 'Minska indrag'\r
+} );\r
diff --git a/sources/plugins/indent/lang/th.js b/sources/plugins/indent/lang/th.js
new file mode 100644 (file)
index 0000000..2f60e53
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'th', {\r
+       indent: 'เพิ่มระยะย่อหน้า',\r
+       outdent: 'ลดระยะย่อหน้า'\r
+} );\r
diff --git a/sources/plugins/indent/lang/tr.js b/sources/plugins/indent/lang/tr.js
new file mode 100644 (file)
index 0000000..21520b6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'tr', {\r
+       indent: 'Sekme Arttır',\r
+       outdent: 'Sekme Azalt'\r
+} );\r
diff --git a/sources/plugins/indent/lang/tt.js b/sources/plugins/indent/lang/tt.js
new file mode 100644 (file)
index 0000000..604bbba
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'tt', {\r
+       indent: 'Отступны арттыру',\r
+       outdent: 'Отступны кечерәйтү'\r
+} );\r
diff --git a/sources/plugins/indent/lang/ug.js b/sources/plugins/indent/lang/ug.js
new file mode 100644 (file)
index 0000000..6fec573
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'ug', {\r
+       indent: 'تارايت',\r
+       outdent: 'كەڭەيت'\r
+} );\r
diff --git a/sources/plugins/indent/lang/uk.js b/sources/plugins/indent/lang/uk.js
new file mode 100644 (file)
index 0000000..c68ca96
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'uk', {\r
+       indent: 'Збільшити відступ',\r
+       outdent: 'Зменшити відступ'\r
+} );\r
diff --git a/sources/plugins/indent/lang/vi.js b/sources/plugins/indent/lang/vi.js
new file mode 100644 (file)
index 0000000..7f44c5d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'vi', {\r
+       indent: 'Dịch vào trong',\r
+       outdent: 'Dịch ra ngoài'\r
+} );\r
diff --git a/sources/plugins/indent/lang/zh-cn.js b/sources/plugins/indent/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..2c9c383
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'zh-cn', {\r
+       indent: '增加缩进量',\r
+       outdent: '减少缩进量'\r
+} );\r
diff --git a/sources/plugins/indent/lang/zh.js b/sources/plugins/indent/lang/zh.js
new file mode 100644 (file)
index 0000000..ee681cb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'indent', 'zh', {\r
+       indent: '增加縮排',\r
+       outdent: '減少縮排'\r
+} );\r
diff --git a/sources/plugins/indent/plugin.js b/sources/plugins/indent/plugin.js
new file mode 100644 (file)
index 0000000..0e887cf
--- /dev/null
@@ -0,0 +1,461 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Increase and Decrease Indent commands.\r
+ */\r
+\r
+( function() {\r
+       'use strict';\r
+\r
+       var TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED,\r
+               TRISTATE_OFF = CKEDITOR.TRISTATE_OFF;\r
+\r
+       CKEDITOR.plugins.add( 'indent', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'indent,indent-rtl,outdent,outdent-rtl', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+\r
+               init: function( editor ) {\r
+                       var genericDefinition = CKEDITOR.plugins.indent.genericDefinition;\r
+\r
+                       // Register generic commands.\r
+                       setupGenericListeners( editor, editor.addCommand( 'indent', new genericDefinition( true ) ) );\r
+                       setupGenericListeners( editor, editor.addCommand( 'outdent', new genericDefinition() ) );\r
+\r
+                       // Create and register toolbar button if possible.\r
+                       if ( editor.ui.addButton ) {\r
+                               editor.ui.addButton( 'Indent', {\r
+                                       label: editor.lang.indent.indent,\r
+                                       command: 'indent',\r
+                                       directional: true,\r
+                                       toolbar: 'indent,20'\r
+                               } );\r
+\r
+                               editor.ui.addButton( 'Outdent', {\r
+                                       label: editor.lang.indent.outdent,\r
+                                       command: 'outdent',\r
+                                       directional: true,\r
+                                       toolbar: 'indent,10'\r
+                               } );\r
+                       }\r
+\r
+                       // Register dirChanged listener.\r
+                       editor.on( 'dirChanged', function( evt ) {\r
+                               var range = editor.createRange(),\r
+                                       dataNode = evt.data.node;\r
+\r
+                               range.setStartBefore( dataNode );\r
+                               range.setEndAfter( dataNode );\r
+\r
+                               var walker = new CKEDITOR.dom.walker( range ),\r
+                                       node;\r
+\r
+                               while ( ( node = walker.next() ) ) {\r
+                                       if ( node.type == CKEDITOR.NODE_ELEMENT ) {\r
+                                               // A child with the defined dir is to be ignored.\r
+                                               if ( !node.equals( dataNode ) && node.getDirection() ) {\r
+                                                       range.setStartAfter( node );\r
+                                                       walker = new CKEDITOR.dom.walker( range );\r
+                                                       continue;\r
+                                               }\r
+\r
+                                               // Switch alignment classes.\r
+                                               var classes = editor.config.indentClasses;\r
+                                               if ( classes ) {\r
+                                                       var suffix = ( evt.data.dir == 'ltr' ) ? [ '_rtl', '' ] : [ '', '_rtl' ];\r
+                                                       for ( var i = 0; i < classes.length; i++ ) {\r
+                                                               if ( node.hasClass( classes[ i ] + suffix[ 0 ] ) ) {\r
+                                                                       node.removeClass( classes[ i ] + suffix[ 0 ] );\r
+                                                                       node.addClass( classes[ i ] + suffix[ 1 ] );\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+\r
+                                               // Switch the margins.\r
+                                               var marginLeft = node.getStyle( 'margin-right' ),\r
+                                                       marginRight = node.getStyle( 'margin-left' );\r
+\r
+                                               marginLeft ? node.setStyle( 'margin-left', marginLeft ) : node.removeStyle( 'margin-left' );\r
+                                               marginRight ? node.setStyle( 'margin-right', marginRight ) : node.removeStyle( 'margin-right' );\r
+                                       }\r
+                               }\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * Global command class definitions and global helpers.\r
+        *\r
+        * @class\r
+        * @singleton\r
+        */\r
+       CKEDITOR.plugins.indent = {\r
+               /**\r
+                * A base class for a generic command definition, responsible mainly for creating\r
+                * Increase Indent and Decrease Indent toolbar buttons as well as for refreshing\r
+                * UI states.\r
+                *\r
+                * Commands of this class do not perform any indentation by themselves. They\r
+                * delegate this job to content-specific indentation commands (i.e. indentlist).\r
+                *\r
+                * @class CKEDITOR.plugins.indent.genericDefinition\r
+                * @extends CKEDITOR.commandDefinition\r
+                * @param {CKEDITOR.editor} editor The editor instance this command will be\r
+                * applied to.\r
+                * @param {String} name The name of the command.\r
+                * @param {Boolean} [isIndent] Defines the command as indenting or outdenting.\r
+                */\r
+               genericDefinition: function( isIndent ) {\r
+                       /**\r
+                        * Determines whether the command belongs to the indentation family.\r
+                        * Otherwise it is assumed to be an outdenting command.\r
+                        *\r
+                        * @readonly\r
+                        * @property {Boolean} [=false]\r
+                        */\r
+                       this.isIndent = !!isIndent;\r
+\r
+                       // Mimic naive startDisabled behavior for outdent.\r
+                       this.startDisabled = !this.isIndent;\r
+               },\r
+\r
+               /**\r
+                * A base class for specific indentation command definitions responsible for\r
+                * handling a pre-defined set of elements i.e. indentlist for lists or\r
+                * indentblock for text block elements.\r
+                *\r
+                * Commands of this class perform indentation operations and modify the DOM structure.\r
+                * They listen for events fired by {@link CKEDITOR.plugins.indent.genericDefinition}\r
+                * and execute defined actions.\r
+                *\r
+                * **NOTE**: This is not an {@link CKEDITOR.command editor command}.\r
+                * Context-specific commands are internal, for indentation system only.\r
+                *\r
+                * @class CKEDITOR.plugins.indent.specificDefinition\r
+                * @param {CKEDITOR.editor} editor The editor instance this command will be\r
+                * applied to.\r
+                * @param {String} name The name of the command.\r
+                * @param {Boolean} [isIndent] Defines the command as indenting or outdenting.\r
+                */\r
+               specificDefinition: function( editor, name, isIndent ) {\r
+                       this.name = name;\r
+                       this.editor = editor;\r
+\r
+                       /**\r
+                        * An object of jobs handled by the command. Each job consists\r
+                        * of two functions: `refresh` and `exec` as well as the execution priority.\r
+                        *\r
+                        *      * The `refresh` function determines whether a job is doable for\r
+                        *        a particular context. These functions are executed in the\r
+                        *        order of priorities, one by one, for all plugins that registered\r
+                        *        jobs. As jobs are related to generic commands, refreshing\r
+                        *        occurs when the global command is firing the `refresh` event.\r
+                        *\r
+                        *        **Note**: This function must return either {@link CKEDITOR#TRISTATE_DISABLED}\r
+                        *        or {@link CKEDITOR#TRISTATE_OFF}.\r
+                        *\r
+                        *      * The `exec` function modifies the DOM if possible. Just like\r
+                        *        `refresh`, `exec` functions are executed in the order of priorities\r
+                        *        while the generic command is executed. This function is not executed\r
+                        *        if `refresh` for this job returned {@link CKEDITOR#TRISTATE_DISABLED}.\r
+                        *\r
+                        *        **Note**: This function must return a Boolean value, indicating whether it\r
+                        *        was successful. If a job was successful, then no other jobs are being executed.\r
+                        *\r
+                        * Sample definition:\r
+                        *\r
+                        *              command.jobs = {\r
+                        *                      // Priority = 20.\r
+                        *                      '20': {\r
+                        *                              refresh( editor, path ) {\r
+                        *                                      if ( condition )\r
+                        *                                              return CKEDITOR.TRISTATE_OFF;\r
+                        *                                      else\r
+                        *                                              return CKEDITOR.TRISTATE_DISABLED;\r
+                        *                              },\r
+                        *                              exec( editor ) {\r
+                        *                                      // DOM modified! This was OK.\r
+                        *                                      return true;\r
+                        *                              }\r
+                        *                      },\r
+                        *                      // Priority = 60. This job is done later.\r
+                        *                      '60': {\r
+                        *                              // Another job.\r
+                        *                      }\r
+                        *              };\r
+                        *\r
+                        * For additional information, please check comments for\r
+                        * the `setupGenericListeners` function.\r
+                        *\r
+                        * @readonly\r
+                        * @property {Object} [={}]\r
+                        */\r
+                       this.jobs = {};\r
+\r
+                       /**\r
+                        * Determines whether the editor that the command belongs to has\r
+                        * {@link CKEDITOR.config#enterMode config.enterMode} set to {@link CKEDITOR#ENTER_BR}.\r
+                        *\r
+                        * @readonly\r
+                        * @see CKEDITOR.config#enterMode\r
+                        * @property {Boolean} [=false]\r
+                        */\r
+                       this.enterBr = editor.config.enterMode == CKEDITOR.ENTER_BR;\r
+\r
+                       /**\r
+                        * Determines whether the command belongs to the indentation family.\r
+                        * Otherwise it is assumed to be an outdenting command.\r
+                        *\r
+                        * @readonly\r
+                        * @property {Boolean} [=false]\r
+                        */\r
+                       this.isIndent = !!isIndent;\r
+\r
+                       /**\r
+                        * The name of the global command related to this one.\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       this.relatedGlobal = isIndent ? 'indent' : 'outdent';\r
+\r
+                       /**\r
+                        * A keystroke associated with this command (*Tab* or *Shift+Tab*).\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       this.indentKey = isIndent ? 9 : CKEDITOR.SHIFT + 9;\r
+\r
+                       /**\r
+                        * Stores created markers for the command so they can eventually be\r
+                        * purged after the `exec` function is run.\r
+                        */\r
+                       this.database = {};\r
+               },\r
+\r
+               /**\r
+                * Registers content-specific commands as a part of the indentation system\r
+                * directed by generic commands. Once a command is registered,\r
+                * it listens for events of a related generic command.\r
+                *\r
+                *              CKEDITOR.plugins.indent.registerCommands( editor, {\r
+                *                      'indentlist': new indentListCommand( editor, 'indentlist' ),\r
+                *                      'outdentlist': new indentListCommand( editor, 'outdentlist' )\r
+                *              } );\r
+                *\r
+                * Content-specific commands listen for the generic command's `exec` and\r
+                * try to execute their own jobs, one after another. If some execution is\r
+                * successful, `evt.data.done` is set so no more jobs (commands) are involved.\r
+                *\r
+                * Content-specific commands also listen for the generic command's `refresh`\r
+                * and fill the `evt.data.states` object with states of jobs. A generic command\r
+                * uses this data to determine its own state and to update the UI.\r
+                *\r
+                * @member CKEDITOR.plugins.indent\r
+                * @param {CKEDITOR.editor} editor The editor instance this command is\r
+                * applied to.\r
+                * @param {Object} commands An object of {@link CKEDITOR.command}.\r
+                */\r
+               registerCommands: function( editor, commands ) {\r
+                       editor.on( 'pluginsLoaded', function() {\r
+                               for ( var name in commands ) {\r
+                                       ( function( editor, command ) {\r
+                                               var relatedGlobal = editor.getCommand( command.relatedGlobal );\r
+\r
+                                               for ( var priority in command.jobs ) {\r
+                                                       // Observe generic exec event and execute command when necessary.\r
+                                                       // If the command was successfully handled by the command and\r
+                                                       // DOM has been modified, stop event propagation so no other plugin\r
+                                                       // will bother. Job is done.\r
+                                                       relatedGlobal.on( 'exec', function( evt ) {\r
+                                                               if ( evt.data.done )\r
+                                                                       return;\r
+\r
+                                                               // Make sure that anything this command will do is invisible\r
+                                                               // for undoManager. What undoManager only can see and\r
+                                                               // remember is the execution of the global command (relatedGlobal).\r
+                                                               editor.fire( 'lockSnapshot' );\r
+\r
+                                                               if ( command.execJob( editor, priority ) )\r
+                                                                       evt.data.done = true;\r
+\r
+                                                               editor.fire( 'unlockSnapshot' );\r
+\r
+                                                               // Clean up the markers.\r
+                                                               CKEDITOR.dom.element.clearAllMarkers( command.database );\r
+                                                       }, this, null, priority );\r
+\r
+                                                       // Observe generic refresh event and force command refresh.\r
+                                                       // Once refreshed, save command state in event data\r
+                                                       // so generic command plugin can update its own state and UI.\r
+                                                       relatedGlobal.on( 'refresh', function( evt ) {\r
+                                                               if ( !evt.data.states )\r
+                                                                       evt.data.states = {};\r
+\r
+                                                               evt.data.states[ command.name + '@' + priority ] =\r
+                                                                       command.refreshJob( editor, priority, evt.data.path );\r
+                                                       }, this, null, priority );\r
+                                               }\r
+\r
+                                               // Since specific indent commands have no UI elements,\r
+                                               // they need to be manually registered as a editor feature.\r
+                                               editor.addFeature( command );\r
+                                       } )( this, commands[ name ] );\r
+                               }\r
+                       } );\r
+               }\r
+       };\r
+\r
+       CKEDITOR.plugins.indent.genericDefinition.prototype = {\r
+               context: 'p',\r
+\r
+               exec: function() {}\r
+       };\r
+\r
+       CKEDITOR.plugins.indent.specificDefinition.prototype = {\r
+               /**\r
+                * Executes the content-specific procedure if the context is correct.\r
+                * It calls the `exec` function of a job of the given `priority`\r
+                * that modifies the DOM.\r
+                *\r
+                * @param {CKEDITOR.editor} editor The editor instance this command\r
+                * will be applied to.\r
+                * @param {Number} priority The priority of the job to be executed.\r
+                * @returns {Boolean} Indicates whether the job was successful.\r
+                */\r
+               execJob: function( editor, priority ) {\r
+                       var job = this.jobs[ priority ];\r
+\r
+                       if ( job.state != TRISTATE_DISABLED )\r
+                               return job.exec.call( this, editor );\r
+               },\r
+\r
+               /**\r
+                * Calls the `refresh` function of a job of the given `priority`.\r
+                * The function returns the state of the job which can be either\r
+                * {@link CKEDITOR#TRISTATE_DISABLED} or {@link CKEDITOR#TRISTATE_OFF}.\r
+                *\r
+                * @param {CKEDITOR.editor} editor The editor instance this command\r
+                * will be applied to.\r
+                * @param {Number} priority The priority of the job to be executed.\r
+                * @returns {Number} The state of the job.\r
+                */\r
+               refreshJob: function( editor, priority, path ) {\r
+                       var job = this.jobs[ priority ];\r
+\r
+                       if ( !editor.activeFilter.checkFeature( this ) )\r
+                               job.state = TRISTATE_DISABLED;\r
+                       else\r
+                               job.state = job.refresh.call( this, editor, path );\r
+\r
+                       return job.state;\r
+               },\r
+\r
+               /**\r
+                * Checks if the element path contains the element handled\r
+                * by this indentation command.\r
+                *\r
+                * @param {CKEDITOR.dom.elementPath} node A path to be checked.\r
+                * @returns {CKEDITOR.dom.element}\r
+                */\r
+               getContext: function( path ) {\r
+                       return path.contains( this.context );\r
+               }\r
+       };\r
+\r
+       /**\r
+        * Attaches event listeners for this generic command. Since the indentation\r
+        * system is event-oriented, generic commands communicate with\r
+        * content-specific commands using the `exec` and `refresh` events.\r
+        *\r
+        * Listener priorities are crucial. Different indentation phases\r
+        * are executed with different priorities.\r
+        *\r
+        * For the `exec` event:\r
+        *\r
+        *      * 0: Selection and bookmarks are saved by the generic command.\r
+        *      * 1-99: Content-specific commands try to indent the code by executing\r
+        *        their own jobs ({@link CKEDITOR.plugins.indent.specificDefinition#jobs}).\r
+        *      * 100: Bookmarks are re-selected by the generic command.\r
+        *\r
+        * The visual interpretation looks as follows:\r
+        *\r
+        *                +------------------+\r
+        *                | Exec event fired |\r
+        *                +------ + ---------+\r
+        *                        |\r
+        *                      0 -<----------+ Selection and bookmarks saved.\r
+        *                        |\r
+        *                        |\r
+        *                     25 -<---+ Exec 1st job of plugin#1 (return false, continuing...).\r
+        *                        |\r
+        *                        |\r
+        *                     50 -<---+ Exec 1st job of plugin#2 (return false, continuing...).\r
+        *                        |\r
+        *                        |\r
+        *                     75 -<---+ Exec 2nd job of plugin#1 (only if plugin#2 failed).\r
+        *                        |\r
+        *                        |\r
+        *                    100 -<-----------+ Re-select bookmarks, clean-up.\r
+        *                        |\r
+        *              +-------- v ----------+\r
+        *              | Exec event finished |\r
+        *              +---------------------+\r
+        *\r
+        * For the `refresh` event:\r
+        *\r
+        *      * <100: Content-specific commands refresh their job states according\r
+        *        to the given path. Jobs save their states in the `evt.data.states` object\r
+        *        passed along with the event. This can be either {@link CKEDITOR#TRISTATE_DISABLED}\r
+        *        or {@link CKEDITOR#TRISTATE_OFF}.\r
+        *      * 100: Command state is determined according to what states\r
+        *        have been returned by content-specific jobs (`evt.data.states`).\r
+        *        UI elements are updated at this stage.\r
+        *\r
+        *        **Note**: If there is at least one job with the {@link CKEDITOR#TRISTATE_OFF} state,\r
+        *        then the generic command state is also {@link CKEDITOR#TRISTATE_OFF}. Otherwise,\r
+        *        the command state is {@link CKEDITOR#TRISTATE_DISABLED}.\r
+        *\r
+        * @param {CKEDITOR.command} command The command to be set up.\r
+        * @private\r
+        */\r
+       function setupGenericListeners( editor, command ) {\r
+               var selection, bookmarks;\r
+\r
+               // Set the command state according to content-specific\r
+               // command states.\r
+               command.on( 'refresh', function( evt ) {\r
+                       // If no state comes with event data, disable command.\r
+                       var states = [ TRISTATE_DISABLED ];\r
+\r
+                       for ( var s in evt.data.states )\r
+                               states.push( evt.data.states[ s ] );\r
+\r
+                       this.setState( CKEDITOR.tools.search( states, TRISTATE_OFF ) ? TRISTATE_OFF : TRISTATE_DISABLED );\r
+               }, command, null, 100 );\r
+\r
+               // Initialization. Save bookmarks and mark event as not handled\r
+               // by any plugin (command) yet.\r
+               command.on( 'exec', function( evt ) {\r
+                       selection = editor.getSelection();\r
+                       bookmarks = selection.createBookmarks( 1 );\r
+\r
+                       // Mark execution as not handled yet.\r
+                       if ( !evt.data )\r
+                               evt.data = {};\r
+\r
+                       evt.data.done = false;\r
+               }, command, null, 0 );\r
+\r
+               // Housekeeping. Make sure selectionChange will be called.\r
+               // Also re-select previously saved bookmarks.\r
+               command.on( 'exec', function() {\r
+                       editor.forceNextSelectionCheck();\r
+                       selection.selectBookmarks( bookmarks );\r
+               }, command, null, 100 );\r
+       }\r
+} )();\r
diff --git a/sources/plugins/indentblock/plugin.js b/sources/plugins/indentblock/plugin.js
new file mode 100644 (file)
index 0000000..b39fd73
--- /dev/null
@@ -0,0 +1,312 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Handles the indentation of block elements.\r
+ */\r
+\r
+( function() {\r
+       'use strict';\r
+\r
+       var $listItem = CKEDITOR.dtd.$listItem,\r
+               $list = CKEDITOR.dtd.$list,\r
+               TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED,\r
+               TRISTATE_OFF = CKEDITOR.TRISTATE_OFF;\r
+\r
+       CKEDITOR.plugins.add( 'indentblock', {\r
+               requires: 'indent',\r
+               init: function( editor ) {\r
+                       var globalHelpers = CKEDITOR.plugins.indent,\r
+                               classes = editor.config.indentClasses;\r
+\r
+                       // Register commands.\r
+                       globalHelpers.registerCommands( editor, {\r
+                               indentblock: new commandDefinition( editor, 'indentblock', true ),\r
+                               outdentblock: new commandDefinition( editor, 'outdentblock' )\r
+                       } );\r
+\r
+                       function commandDefinition() {\r
+                               globalHelpers.specificDefinition.apply( this, arguments );\r
+\r
+                               this.allowedContent = {\r
+                                       'div h1 h2 h3 h4 h5 h6 ol p pre ul': {\r
+                                               // Do not add elements, but only text-align style if element is validated by other rule.\r
+                                               propertiesOnly: true,\r
+                                               styles: !classes ? 'margin-left,margin-right' : null,\r
+                                               classes: classes || null\r
+                                       }\r
+                               };\r
+\r
+                               this.contentTransformations = [\r
+                                       [ 'div: splitMarginShorthand' ],\r
+                                       [ 'h1: splitMarginShorthand' ],\r
+                                       [ 'h2: splitMarginShorthand' ],\r
+                                       [ 'h3: splitMarginShorthand' ],\r
+                                       [ 'h4: splitMarginShorthand' ],\r
+                                       [ 'h5: splitMarginShorthand' ],\r
+                                       [ 'h6: splitMarginShorthand' ],\r
+                                       [ 'ol: splitMarginShorthand' ],\r
+                                       [ 'p: splitMarginShorthand' ],\r
+                                       [ 'pre: splitMarginShorthand' ],\r
+                                       [ 'ul: splitMarginShorthand' ]\r
+                               ];\r
+\r
+                               if ( this.enterBr )\r
+                                       this.allowedContent.div = true;\r
+\r
+                               this.requiredContent = ( this.enterBr ? 'div' : 'p' ) +\r
+                                       ( classes ? '(' + classes.join( ',' ) + ')' : '{margin-left}' );\r
+\r
+                               this.jobs = {\r
+                                       '20': {\r
+                                               refresh: function( editor, path ) {\r
+                                                       var firstBlock = path.block || path.blockLimit;\r
+\r
+                                                       // Switch context from somewhere inside list item to list item,\r
+                                                       // if not found just assign self (doing nothing).\r
+                                                       if ( !firstBlock.is( $listItem ) ) {\r
+                                                               var ascendant = firstBlock.getAscendant( $listItem );\r
+\r
+                                                               firstBlock = ( ascendant && path.contains( ascendant ) ) || firstBlock;\r
+                                                       }\r
+\r
+                                                       // Switch context from list item to list\r
+                                                       // because indentblock can indent entire list\r
+                                                       // but not a single list element.\r
+\r
+                                                       if ( firstBlock.is( $listItem ) )\r
+                                                               firstBlock = firstBlock.getParent();\r
+\r
+                                                       //      [-] Context in the path or ENTER_BR\r
+                                                       //\r
+                                                       //              Don't try to indent if the element is out of\r
+                                                       //              this plugin's scope. This assertion is omitted\r
+                                                       //              if ENTER_BR is in use since there may be no block\r
+                                                       //              in the path.\r
+\r
+                                                       if ( !this.enterBr && !this.getContext( path ) )\r
+                                                               return TRISTATE_DISABLED;\r
+\r
+                                                       else if ( classes ) {\r
+\r
+                                                               //      [+] Context in the path or ENTER_BR\r
+                                                               //      [+] IndentClasses\r
+                                                               //\r
+                                                               //              If there are indentation classes, check if reached\r
+                                                               //              the highest level of indentation. If so, disable\r
+                                                               //              the command.\r
+\r
+                                                               if ( indentClassLeft.call( this, firstBlock, classes ) )\r
+                                                                       return TRISTATE_OFF;\r
+                                                               else\r
+                                                                       return TRISTATE_DISABLED;\r
+                                                       } else {\r
+\r
+                                                               //      [+] Context in the path or ENTER_BR\r
+                                                               //      [-] IndentClasses\r
+                                                               //      [+] Indenting\r
+                                                               //\r
+                                                               //              No indent-level limitations due to indent classes.\r
+                                                               //              Indent-like command can always be executed.\r
+\r
+                                                               if ( this.isIndent )\r
+                                                                       return TRISTATE_OFF;\r
+\r
+                                                               //      [+] Context in the path or ENTER_BR\r
+                                                               //      [-] IndentClasses\r
+                                                               //      [-] Indenting\r
+                                                               //      [-] Block in the path\r
+                                                               //\r
+                                                               //              No block in path. There's no element to apply indentation\r
+                                                               //              so disable the command.\r
+\r
+                                                               else if ( !firstBlock )\r
+                                                                       return TRISTATE_DISABLED;\r
+\r
+                                                               //      [+] Context in the path or ENTER_BR\r
+                                                               //      [-] IndentClasses\r
+                                                               //      [-] Indenting\r
+                                                               //      [+] Block in path.\r
+                                                               //\r
+                                                               //              Not using indentClasses but there is firstBlock.\r
+                                                               //              We can calculate current indentation level and\r
+                                                               //              try to increase/decrease it.\r
+\r
+                                                               else {\r
+                                                                       return CKEDITOR[\r
+                                                                               ( getIndent( firstBlock ) || 0 ) <= 0 ? 'TRISTATE_DISABLED' : 'TRISTATE_OFF'\r
+                                                                       ];\r
+                                                               }\r
+                                                       }\r
+                                               },\r
+\r
+                                               exec: function( editor ) {\r
+                                                       var selection = editor.getSelection(),\r
+                                                               range = selection && selection.getRanges()[ 0 ],\r
+                                                               nearestListBlock;\r
+\r
+                                                       // If there's some list in the path, then it will be\r
+                                                       // a full-list indent by increasing or decreasing margin property.\r
+                                                       if ( ( nearestListBlock = editor.elementPath().contains( $list ) ) )\r
+                                                               indentElement.call( this, nearestListBlock, classes );\r
+\r
+                                                       // If no list in the path, use iterator to indent all the possible\r
+                                                       // paragraphs in the range, creating them if necessary.\r
+                                                       else {\r
+                                                               var iterator = range.createIterator(),\r
+                                                                       enterMode = editor.config.enterMode,\r
+                                                                       block;\r
+\r
+                                                               iterator.enforceRealBlocks = true;\r
+                                                               iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;\r
+\r
+                                                               while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) {\r
+                                                                       if ( !block.isReadOnly() )\r
+                                                                               indentElement.call( this, block, classes );\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       return true;\r
+                                               }\r
+                                       }\r
+                               };\r
+                       }\r
+\r
+                       CKEDITOR.tools.extend( commandDefinition.prototype, globalHelpers.specificDefinition.prototype, {\r
+                               // Elements that, if in an elementpath, will be handled by this\r
+                               // command. They restrict the scope of the plugin.\r
+                               context: { div: 1, dl: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, ul: 1, ol: 1, p: 1, pre: 1, table: 1 },\r
+\r
+                               // A regex built on config#indentClasses to detect whether an\r
+                               // element has some indentClass or not.\r
+                               classNameRegex: classes ? new RegExp( '(?:^|\\s+)(' + classes.join( '|' ) + ')(?=$|\\s)' ) : null\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       // Generic indentation procedure for indentation of any element\r
+       // either with margin property or config#indentClass.\r
+       function indentElement( element, classes, dir ) {\r
+               if ( element.getCustomData( 'indent_processed' ) )\r
+                       return;\r
+\r
+               var editor = this.editor,\r
+                       isIndent = this.isIndent;\r
+\r
+               if ( classes ) {\r
+                       // Transform current class f to indent step index.\r
+                       var indentClass = element.$.className.match( this.classNameRegex ),\r
+                               indentStep = 0;\r
+\r
+                       if ( indentClass ) {\r
+                               indentClass = indentClass[ 1 ];\r
+                               indentStep = CKEDITOR.tools.indexOf( classes, indentClass ) + 1;\r
+                       }\r
+\r
+                       // Operate on indent step index, transform indent step index\r
+                       // back to class name.\r
+                       if ( ( indentStep += isIndent ? 1 : -1 ) < 0 )\r
+                               return;\r
+\r
+                       indentStep = Math.min( indentStep, classes.length );\r
+                       indentStep = Math.max( indentStep, 0 );\r
+                       element.$.className = CKEDITOR.tools.ltrim( element.$.className.replace( this.classNameRegex, '' ) );\r
+\r
+                       if ( indentStep > 0 )\r
+                               element.addClass( classes[ indentStep - 1 ] );\r
+               } else {\r
+                       var indentCssProperty = getIndentCss( element, dir ),\r
+                               currentOffset = parseInt( element.getStyle( indentCssProperty ), 10 ),\r
+                               indentOffset = editor.config.indentOffset || 40;\r
+\r
+                       if ( isNaN( currentOffset ) )\r
+                               currentOffset = 0;\r
+\r
+                       currentOffset += ( isIndent ? 1 : -1 ) * indentOffset;\r
+\r
+                       if ( currentOffset < 0 )\r
+                               return;\r
+\r
+                       currentOffset = Math.max( currentOffset, 0 );\r
+                       currentOffset = Math.ceil( currentOffset / indentOffset ) * indentOffset;\r
+\r
+                       element.setStyle(\r
+                               indentCssProperty,\r
+                               currentOffset ? currentOffset + ( editor.config.indentUnit || 'px' ) : ''\r
+                       );\r
+\r
+                       if ( element.getAttribute( 'style' ) === '' )\r
+                               element.removeAttribute( 'style' );\r
+               }\r
+\r
+               CKEDITOR.dom.element.setMarker( this.database, element, 'indent_processed', 1 );\r
+\r
+               return;\r
+       }\r
+\r
+       // Method that checks if current indentation level for an element\r
+       // reached the limit determined by config#indentClasses.\r
+       function indentClassLeft( node, classes ) {\r
+               var indentClass = node.$.className.match( this.classNameRegex ),\r
+                       isIndent = this.isIndent;\r
+\r
+               // If node has one of the indentClasses:\r
+               //      * If it holds the topmost indentClass, then\r
+               //        no more classes have left.\r
+               //      * If it holds any other indentClass, it can use the next one\r
+               //        or the previous one.\r
+               //      * Outdent is always possible. We can remove indentClass.\r
+               if ( indentClass )\r
+                       return isIndent ? indentClass[ 1 ] != classes.slice( -1 ) : true;\r
+\r
+               // If node has no class which belongs to indentClasses,\r
+               // then it is at 0-level. It can be indented but not outdented.\r
+               else\r
+                       return isIndent;\r
+       }\r
+\r
+       // Determines indent CSS property for an element according to\r
+       // what is the direction of such element. It can be either `margin-left`\r
+       // or `margin-right`.\r
+       function getIndentCss( element, dir ) {\r
+               return ( dir || element.getComputedStyle( 'direction' ) ) == 'ltr' ? 'margin-left' : 'margin-right';\r
+       }\r
+\r
+       // Return the numerical indent value of margin-left|right of an element,\r
+       // considering element's direction. If element has no margin specified,\r
+       // NaN is returned.\r
+       function getIndent( element ) {\r
+               return parseInt( element.getStyle( getIndentCss( element ) ), 10 );\r
+       }\r
+} )();\r
+\r
+/**\r
+ * A list of classes to use for indenting the contents. If set to `null`, no classes will be used\r
+ * and instead the {@link #indentUnit} and {@link #indentOffset} properties will be used.\r
+ *\r
+ *             // Use the 'Indent1', 'Indent2', 'Indent3' classes.\r
+ *             config.indentClasses = ['Indent1', 'Indent2', 'Indent3'];\r
+ *\r
+ * @cfg {Array} [indentClasses=null]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The size in {@link CKEDITOR.config#indentUnit indentation units} of each indentation step.\r
+ *\r
+ *             config.indentOffset = 4;\r
+ *\r
+ * @cfg {Number} [indentOffset=40]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The unit used for {@link CKEDITOR.config#indentOffset indentation offset}.\r
+ *\r
+ *             config.indentUnit = 'em';\r
+ *\r
+ * @cfg {String} [indentUnit='px']\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/indentlist/plugin.js b/sources/plugins/indentlist/plugin.js
new file mode 100644 (file)
index 0000000..15c661f
--- /dev/null
@@ -0,0 +1,318 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Handles the indentation of lists.\r
+ */\r
+\r
+( function() {\r
+       'use strict';\r
+\r
+       var isNotWhitespaces = CKEDITOR.dom.walker.whitespaces( true ),\r
+               isNotBookmark = CKEDITOR.dom.walker.bookmark( false, true ),\r
+               TRISTATE_DISABLED = CKEDITOR.TRISTATE_DISABLED,\r
+               TRISTATE_OFF = CKEDITOR.TRISTATE_OFF;\r
+\r
+       CKEDITOR.plugins.add( 'indentlist', {\r
+               requires: 'indent',\r
+               init: function( editor ) {\r
+                       var globalHelpers = CKEDITOR.plugins.indent;\r
+\r
+                       // Register commands.\r
+                       globalHelpers.registerCommands( editor, {\r
+                               indentlist: new commandDefinition( editor, 'indentlist', true ),\r
+                               outdentlist: new commandDefinition( editor, 'outdentlist' )\r
+                       } );\r
+\r
+                       function commandDefinition( editor ) {\r
+                               globalHelpers.specificDefinition.apply( this, arguments );\r
+\r
+                               // Require ul OR ol list.\r
+                               this.requiredContent = [ 'ul', 'ol' ];\r
+\r
+                               // Indent and outdent lists with TAB/SHIFT+TAB key. Indenting can\r
+                               // be done for any list item that isn't the first child of the parent.\r
+                               editor.on( 'key', function( evt ) {\r
+                                       if ( editor.mode != 'wysiwyg' )\r
+                                               return;\r
+\r
+                                       if ( evt.data.keyCode == this.indentKey ) {\r
+                                               var list = this.getContext( editor.elementPath() );\r
+\r
+                                               if ( list ) {\r
+                                                       // Don't indent if in first list item of the parent.\r
+                                                       // Outdent, however, can always be done to collapse\r
+                                                       // the list into a paragraph (div).\r
+                                                       if ( this.isIndent && CKEDITOR.plugins.indentList.firstItemInPath( this.context, editor.elementPath(), list ) )\r
+                                                               return;\r
+\r
+                                                       // Exec related global indentation command. Global\r
+                                                       // commands take care of bookmarks and selection,\r
+                                                       // so it's much easier to use them instead of\r
+                                                       // content-specific commands.\r
+                                                       editor.execCommand( this.relatedGlobal );\r
+\r
+                                                       // Cancel the key event so editor doesn't lose focus.\r
+                                                       evt.cancel();\r
+                                               }\r
+                                       }\r
+                               }, this );\r
+\r
+                               // There are two different jobs for this plugin:\r
+                               //\r
+                               //      * Indent job (priority=10), before indentblock.\r
+                               //\r
+                               //        This job is before indentblock because, if this plugin is\r
+                               //        loaded it has higher priority over indentblock. It means that,\r
+                               //        if possible, nesting is performed, and then block manipulation,\r
+                               //        if necessary.\r
+                               //\r
+                               //      * Outdent job (priority=30), after outdentblock.\r
+                               //\r
+                               //        This job got to be after outdentblock because in some cases\r
+                               //        (margin, config#indentClass on list) outdent must be done on\r
+                               //        block-level.\r
+\r
+                               this.jobs[ this.isIndent ? 10 : 30 ] = {\r
+                                       refresh: this.isIndent ?\r
+                                               function( editor, path ) {\r
+                                                       var list = this.getContext( path ),\r
+                                                               inFirstListItem = CKEDITOR.plugins.indentList.firstItemInPath( this.context, path, list );\r
+\r
+                                                       if ( !list || !this.isIndent || inFirstListItem )\r
+                                                               return TRISTATE_DISABLED;\r
+\r
+                                                       return TRISTATE_OFF;\r
+                                               } : function( editor, path ) {\r
+                                                       var list = this.getContext( path );\r
+\r
+                                                       if ( !list || this.isIndent )\r
+                                                               return TRISTATE_DISABLED;\r
+\r
+                                                       return TRISTATE_OFF;\r
+                                               },\r
+\r
+                                       exec: CKEDITOR.tools.bind( indentList, this )\r
+                               };\r
+                       }\r
+\r
+                       CKEDITOR.tools.extend( commandDefinition.prototype, globalHelpers.specificDefinition.prototype, {\r
+                               // Elements that, if in an elementpath, will be handled by this\r
+                               // command. They restrict the scope of the plugin.\r
+                               context: { ol: 1, ul: 1 }\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       function indentList( editor ) {\r
+               var that = this,\r
+                       database = this.database,\r
+                       context = this.context;\r
+\r
+               function indent( listNode ) {\r
+                       // Our starting and ending points of the range might be inside some blocks under a list item...\r
+                       // So before playing with the iterator, we need to expand the block to include the list items.\r
+                       var startContainer = range.startContainer,\r
+                               endContainer = range.endContainer;\r
+                       while ( startContainer && !startContainer.getParent().equals( listNode ) )\r
+                               startContainer = startContainer.getParent();\r
+                       while ( endContainer && !endContainer.getParent().equals( listNode ) )\r
+                               endContainer = endContainer.getParent();\r
+\r
+                       if ( !startContainer || !endContainer )\r
+                               return false;\r
+\r
+                       // Now we can iterate over the individual items on the same tree depth.\r
+                       var block = startContainer,\r
+                               itemsToMove = [],\r
+                               stopFlag = false;\r
+\r
+                       while ( !stopFlag ) {\r
+                               if ( block.equals( endContainer ) )\r
+                                       stopFlag = true;\r
+\r
+                               itemsToMove.push( block );\r
+                               block = block.getNext();\r
+                       }\r
+\r
+                       if ( itemsToMove.length < 1 )\r
+                               return false;\r
+\r
+                       // Do indent or outdent operations on the array model of the list, not the\r
+                       // list's DOM tree itself. The array model demands that it knows as much as\r
+                       // possible about the surrounding lists, we need to feed it the further\r
+                       // ancestor node that is still a list.\r
+                       var listParents = listNode.getParents( true );\r
+                       for ( var i = 0; i < listParents.length; i++ ) {\r
+                               if ( listParents[ i ].getName && context[ listParents[ i ].getName() ] ) {\r
+                                       listNode = listParents[ i ];\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       var indentOffset = that.isIndent ? 1 : -1,\r
+                               startItem = itemsToMove[ 0 ],\r
+                               lastItem = itemsToMove[ itemsToMove.length - 1 ],\r
+\r
+                               // Convert the list DOM tree into a one dimensional array.\r
+                               listArray = CKEDITOR.plugins.list.listToArray( listNode, database ),\r
+\r
+                               // Apply indenting or outdenting on the array.\r
+                               baseIndent = listArray[ lastItem.getCustomData( 'listarray_index' ) ].indent;\r
+\r
+                       for ( i = startItem.getCustomData( 'listarray_index' ); i <= lastItem.getCustomData( 'listarray_index' ); i++ ) {\r
+                               listArray[ i ].indent += indentOffset;\r
+                               // Make sure the newly created sublist get a brand-new element of the same type. (#5372)\r
+                               if ( indentOffset > 0 ) {\r
+                                       var listRoot = listArray[ i ].parent;\r
+                                       listArray[ i ].parent = new CKEDITOR.dom.element( listRoot.getName(), listRoot.getDocument() );\r
+                               }\r
+                       }\r
+\r
+                       for ( i = lastItem.getCustomData( 'listarray_index' ) + 1; i < listArray.length && listArray[ i ].indent > baseIndent; i++ )\r
+                               listArray[ i ].indent += indentOffset;\r
+\r
+                       // Convert the array back to a DOM forest (yes we might have a few subtrees now).\r
+                       // And replace the old list with the new forest.\r
+                       var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, listNode.getDirection() );\r
+\r
+                       // Avoid nested <li> after outdent even they're visually same,\r
+                       // recording them for later refactoring.(#3982)\r
+                       if ( !that.isIndent ) {\r
+                               var parentLiElement;\r
+                               if ( ( parentLiElement = listNode.getParent() ) && parentLiElement.is( 'li' ) ) {\r
+                                       var children = newList.listNode.getChildren(),\r
+                                               pendingLis = [],\r
+                                               count = children.count(),\r
+                                               child;\r
+\r
+                                       for ( i = count - 1; i >= 0; i-- ) {\r
+                                               if ( ( child = children.getItem( i ) ) && child.is && child.is( 'li' ) )\r
+                                                       pendingLis.push( child );\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       if ( newList )\r
+                               newList.listNode.replace( listNode );\r
+\r
+                       // Move the nested <li> to be appeared after the parent.\r
+                       if ( pendingLis && pendingLis.length ) {\r
+                               for ( i = 0; i < pendingLis.length; i++ ) {\r
+                                       var li = pendingLis[ i ],\r
+                                               followingList = li;\r
+\r
+                                       // Nest preceding <ul>/<ol> inside current <li> if any.\r
+                                       while ( ( followingList = followingList.getNext() ) && followingList.is && followingList.getName() in context ) {\r
+                                               // IE requires a filler NBSP for nested list inside empty list item,\r
+                                               // otherwise the list item will be inaccessiable. (#4476)\r
+                                               if ( CKEDITOR.env.needsNbspFiller && !li.getFirst( neitherWhitespacesNorBookmark ) )\r
+                                                       li.append( range.document.createText( '\u00a0' ) );\r
+\r
+                                               li.append( followingList );\r
+                                       }\r
+\r
+                                       li.insertAfter( parentLiElement );\r
+                               }\r
+                       }\r
+\r
+                       if ( newList )\r
+                               editor.fire( 'contentDomInvalidated' );\r
+\r
+                       return true;\r
+               }\r
+\r
+               var selection = editor.getSelection(),\r
+                       ranges = selection && selection.getRanges(),\r
+                       iterator = ranges.createIterator(),\r
+                       range;\r
+\r
+               while ( ( range = iterator.getNextRange() ) ) {\r
+                       var nearestListBlock = range.getCommonAncestor();\r
+\r
+                       while ( nearestListBlock && !( nearestListBlock.type == CKEDITOR.NODE_ELEMENT && context[ nearestListBlock.getName() ] ) ) {\r
+                               // Avoid having plugin propagate to parent of editor in inline mode by canceling the indentation. (#12796)\r
+                               if ( editor.editable().equals( nearestListBlock ) ) {\r
+                                       nearestListBlock = false;\r
+                                       break;\r
+                               }\r
+                               nearestListBlock = nearestListBlock.getParent();\r
+                       }\r
+\r
+                       // Avoid having selection boundaries out of the list.\r
+                       // <ul><li>[...</li></ul><p>...]</p> => <ul><li>[...]</li></ul><p>...</p>\r
+                       if ( !nearestListBlock ) {\r
+                               if ( ( nearestListBlock = range.startPath().contains( context ) ) )\r
+                                       range.setEndAt( nearestListBlock, CKEDITOR.POSITION_BEFORE_END );\r
+                       }\r
+\r
+                       // Avoid having selection enclose the entire list. (#6138)\r
+                       // [<ul><li>...</li></ul>] =><ul><li>[...]</li></ul>\r
+                       if ( !nearestListBlock ) {\r
+                               var selectedNode = range.getEnclosedNode();\r
+                               if ( selectedNode && selectedNode.type == CKEDITOR.NODE_ELEMENT && selectedNode.getName() in context ) {\r
+                                       range.setStartAt( selectedNode, CKEDITOR.POSITION_AFTER_START );\r
+                                       range.setEndAt( selectedNode, CKEDITOR.POSITION_BEFORE_END );\r
+                                       nearestListBlock = selectedNode;\r
+                               }\r
+                       }\r
+\r
+                       // Avoid selection anchors under list root.\r
+                       // <ul>[<li>...</li>]</ul> =>   <ul><li>[...]</li></ul>\r
+                       if ( nearestListBlock && range.startContainer.type == CKEDITOR.NODE_ELEMENT && range.startContainer.getName() in context ) {\r
+                               var walker = new CKEDITOR.dom.walker( range );\r
+                               walker.evaluator = listItem;\r
+                               range.startContainer = walker.next();\r
+                       }\r
+\r
+                       if ( nearestListBlock && range.endContainer.type == CKEDITOR.NODE_ELEMENT && range.endContainer.getName() in context ) {\r
+                               walker = new CKEDITOR.dom.walker( range );\r
+                               walker.evaluator = listItem;\r
+                               range.endContainer = walker.previous();\r
+                       }\r
+\r
+                       if ( nearestListBlock )\r
+                               return indent( nearestListBlock );\r
+               }\r
+               return 0;\r
+       }\r
+\r
+       // Determines whether a node is a list <li> element.\r
+       function listItem( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' );\r
+       }\r
+\r
+       function neitherWhitespacesNorBookmark( node ) {\r
+               return isNotWhitespaces( node ) && isNotBookmark( node );\r
+       }\r
+\r
+       /**\r
+        * Global namespace for methods exposed by the Indent List plugin.\r
+        *\r
+        * @singleton\r
+        * @class\r
+        */\r
+       CKEDITOR.plugins.indentList = {};\r
+\r
+       /**\r
+        * Checks whether the first child of the list is in the path.\r
+        * The list can be extracted from the path or given explicitly\r
+        * e.g. for better performance if cached.\r
+        *\r
+        * @since 4.4.6\r
+        * @param {Object} query See the {@link CKEDITOR.dom.elementPath#contains} method arguments.\r
+        * @param {CKEDITOR.dom.elementPath} path\r
+        * @param {CKEDITOR.dom.element} [list]\r
+        * @returns {Boolean}\r
+        * @member CKEDITOR.plugins.indentList\r
+        */\r
+       CKEDITOR.plugins.indentList.firstItemInPath = function( query, path, list ) {\r
+               var firstListItemInPath = path.contains( listItem );\r
+               if ( !list )\r
+                       list = path.contains( query );\r
+\r
+               return list && firstListItemInPath && firstListItemInPath.equals( list.getFirst( listItem ) );\r
+       };\r
+} )();\r
diff --git a/sources/plugins/justify/icons/hidpi/justifyblock.png b/sources/plugins/justify/icons/hidpi/justifyblock.png
new file mode 100644 (file)
index 0000000..5c0cf43
Binary files /dev/null and b/sources/plugins/justify/icons/hidpi/justifyblock.png differ
diff --git a/sources/plugins/justify/icons/hidpi/justifycenter.png b/sources/plugins/justify/icons/hidpi/justifycenter.png
new file mode 100644 (file)
index 0000000..fd751be
Binary files /dev/null and b/sources/plugins/justify/icons/hidpi/justifycenter.png differ
diff --git a/sources/plugins/justify/icons/hidpi/justifyleft.png b/sources/plugins/justify/icons/hidpi/justifyleft.png
new file mode 100644 (file)
index 0000000..a109ad3
Binary files /dev/null and b/sources/plugins/justify/icons/hidpi/justifyleft.png differ
diff --git a/sources/plugins/justify/icons/hidpi/justifyright.png b/sources/plugins/justify/icons/hidpi/justifyright.png
new file mode 100644 (file)
index 0000000..5125d56
Binary files /dev/null and b/sources/plugins/justify/icons/hidpi/justifyright.png differ
diff --git a/sources/plugins/justify/icons/justifyblock.png b/sources/plugins/justify/icons/justifyblock.png
new file mode 100644 (file)
index 0000000..ffe0620
Binary files /dev/null and b/sources/plugins/justify/icons/justifyblock.png differ
diff --git a/sources/plugins/justify/icons/justifycenter.png b/sources/plugins/justify/icons/justifycenter.png
new file mode 100644 (file)
index 0000000..8b5b40f
Binary files /dev/null and b/sources/plugins/justify/icons/justifycenter.png differ
diff --git a/sources/plugins/justify/icons/justifyleft.png b/sources/plugins/justify/icons/justifyleft.png
new file mode 100644 (file)
index 0000000..a60d079
Binary files /dev/null and b/sources/plugins/justify/icons/justifyleft.png differ
diff --git a/sources/plugins/justify/icons/justifyright.png b/sources/plugins/justify/icons/justifyright.png
new file mode 100644 (file)
index 0000000..21de814
Binary files /dev/null and b/sources/plugins/justify/icons/justifyright.png differ
diff --git a/sources/plugins/justify/lang/af.js b/sources/plugins/justify/lang/af.js
new file mode 100644 (file)
index 0000000..9f5c303
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'af', {\r
+       block: 'Uitvul',\r
+       center: 'Sentreer',\r
+       left: 'Links oplyn',\r
+       right: 'Regs oplyn'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ar.js b/sources/plugins/justify/lang/ar.js
new file mode 100644 (file)
index 0000000..6c414be
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ar', {\r
+       block: 'ضبط',\r
+       center: 'توسيط',\r
+       left: 'محاذاة إلى اليسار',\r
+       right: 'محاذاة إلى اليمين'\r
+} );\r
diff --git a/sources/plugins/justify/lang/az.js b/sources/plugins/justify/lang/az.js
new file mode 100644 (file)
index 0000000..9360568
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'az', {\r
+       block: 'Eninə görə',\r
+       center: 'Mərkəz',\r
+       left: 'Soldan düzləndir',\r
+       right: 'Sağdan düzləndir'\r
+} );\r
diff --git a/sources/plugins/justify/lang/bg.js b/sources/plugins/justify/lang/bg.js
new file mode 100644 (file)
index 0000000..1724947
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'bg', {\r
+       block: 'Двустранно подравняване',\r
+       center: 'Център',\r
+       left: 'Подравни в ляво',\r
+       right: 'Подравни в дясно'\r
+} );\r
diff --git a/sources/plugins/justify/lang/bn.js b/sources/plugins/justify/lang/bn.js
new file mode 100644 (file)
index 0000000..002a633
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'bn', {\r
+       block: 'যাচাই করি',\r
+       center: 'মাঝ বরাবর ঘেষা',\r
+       left: 'বা দিকে ঘেঁষা',\r
+       right: 'ডান দিকে ঘেঁষা'\r
+} );\r
diff --git a/sources/plugins/justify/lang/bs.js b/sources/plugins/justify/lang/bs.js
new file mode 100644 (file)
index 0000000..0fbedfc
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'bs', {\r
+       block: 'Puno poravnanje',\r
+       center: 'Centralno poravnanje',\r
+       left: 'Lijevo poravnanje',\r
+       right: 'Desno poravnanje'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ca.js b/sources/plugins/justify/lang/ca.js
new file mode 100644 (file)
index 0000000..afb7adb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ca', {\r
+       block: 'Justificat',\r
+       center: 'Centrat',\r
+       left: 'Alinea a l\'esquerra',\r
+       right: 'Alinea a la dreta'\r
+} );\r
diff --git a/sources/plugins/justify/lang/cs.js b/sources/plugins/justify/lang/cs.js
new file mode 100644 (file)
index 0000000..467ae6f
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'cs', {\r
+       block: 'Zarovnat do bloku',\r
+       center: 'Zarovnat na střed',\r
+       left: 'Zarovnat vlevo',\r
+       right: 'Zarovnat vpravo'\r
+} );\r
diff --git a/sources/plugins/justify/lang/cy.js b/sources/plugins/justify/lang/cy.js
new file mode 100644 (file)
index 0000000..6b39beb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'cy', {\r
+       block: 'Unioni',\r
+       center: 'Alinio i\'r Canol',\r
+       left: 'Alinio i\'r Chwith',\r
+       right: 'Alinio i\'r Dde'\r
+} );\r
diff --git a/sources/plugins/justify/lang/da.js b/sources/plugins/justify/lang/da.js
new file mode 100644 (file)
index 0000000..ac8ee29
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'da', {\r
+       block: 'Lige margener',\r
+       center: 'Centreret',\r
+       left: 'Venstrestillet',\r
+       right: 'Højrestillet'\r
+} );\r
diff --git a/sources/plugins/justify/lang/de-ch.js b/sources/plugins/justify/lang/de-ch.js
new file mode 100644 (file)
index 0000000..a2c24eb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'de-ch', {\r
+       block: 'Blocksatz',\r
+       center: 'Zentriert',\r
+       left: 'Linksbündig',\r
+       right: 'Rechtsbündig'\r
+} );\r
diff --git a/sources/plugins/justify/lang/de.js b/sources/plugins/justify/lang/de.js
new file mode 100644 (file)
index 0000000..4db8725
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'de', {\r
+       block: 'Blocksatz',\r
+       center: 'Zentriert',\r
+       left: 'Linksbündig',\r
+       right: 'Rechtsbündig'\r
+} );\r
diff --git a/sources/plugins/justify/lang/el.js b/sources/plugins/justify/lang/el.js
new file mode 100644 (file)
index 0000000..1bdc64f
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'el', {\r
+       block: 'Πλήρης Στοίχιση',\r
+       center: 'Στο Κέντρο',\r
+       left: 'Στοίχιση Αριστερά',\r
+       right: 'Στοίχιση Δεξιά'\r
+} );\r
diff --git a/sources/plugins/justify/lang/en-au.js b/sources/plugins/justify/lang/en-au.js
new file mode 100644 (file)
index 0000000..68eb09c
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'en-au', {\r
+       block: 'Justify',\r
+       center: 'Centre',\r
+       left: 'Align Left',\r
+       right: 'Align Right'\r
+} );\r
diff --git a/sources/plugins/justify/lang/en-ca.js b/sources/plugins/justify/lang/en-ca.js
new file mode 100644 (file)
index 0000000..27718a2
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'en-ca', {\r
+       block: 'Justify',\r
+       center: 'Centre',\r
+       left: 'Align Left',\r
+       right: 'Align Right'\r
+} );\r
diff --git a/sources/plugins/justify/lang/en-gb.js b/sources/plugins/justify/lang/en-gb.js
new file mode 100644 (file)
index 0000000..d6db4ff
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'en-gb', {\r
+       block: 'Justify',\r
+       center: 'Centre',\r
+       left: 'Align Left',\r
+       right: 'Align Right'\r
+} );\r
diff --git a/sources/plugins/justify/lang/en.js b/sources/plugins/justify/lang/en.js
new file mode 100644 (file)
index 0000000..8a72e85
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'en', {\r
+       block: 'Justify',\r
+       center: 'Center',\r
+       left: 'Align Left',\r
+       right: 'Align Right'\r
+} );\r
diff --git a/sources/plugins/justify/lang/eo.js b/sources/plugins/justify/lang/eo.js
new file mode 100644 (file)
index 0000000..7531dde
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'eo', {\r
+       block: 'Ĝisrandigi Ambaŭflanke',\r
+       center: 'Centrigi',\r
+       left: 'Ĝisrandigi maldekstren',\r
+       right: 'Ĝisrandigi dekstren'\r
+} );\r
diff --git a/sources/plugins/justify/lang/es.js b/sources/plugins/justify/lang/es.js
new file mode 100644 (file)
index 0000000..2e89bc0
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'es', {\r
+       block: 'Justificado',\r
+       center: 'Centrar',\r
+       left: 'Alinear a Izquierda',\r
+       right: 'Alinear a Derecha'\r
+} );\r
diff --git a/sources/plugins/justify/lang/et.js b/sources/plugins/justify/lang/et.js
new file mode 100644 (file)
index 0000000..0fc4915
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'et', {\r
+       block: 'Rööpjoondus',\r
+       center: 'Keskjoondus',\r
+       left: 'Vasakjoondus',\r
+       right: 'Paremjoondus'\r
+} );\r
diff --git a/sources/plugins/justify/lang/eu.js b/sources/plugins/justify/lang/eu.js
new file mode 100644 (file)
index 0000000..f7d291e
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'eu', {\r
+       block: 'Justifikatu',\r
+       center: 'Erdian',\r
+       left: 'Lerrokatu ezkerrean',\r
+       right: 'Lerrokatu eskuinean'\r
+} );\r
diff --git a/sources/plugins/justify/lang/fa.js b/sources/plugins/justify/lang/fa.js
new file mode 100644 (file)
index 0000000..03c3c6b
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'fa', {\r
+       block: 'بلوک چین',\r
+       center: 'میان چین',\r
+       left: 'چپ چین',\r
+       right: 'راست چین'\r
+} );\r
diff --git a/sources/plugins/justify/lang/fi.js b/sources/plugins/justify/lang/fi.js
new file mode 100644 (file)
index 0000000..6993f10
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'fi', {\r
+       block: 'Tasaa molemmat reunat',\r
+       center: 'Keskitä',\r
+       left: 'Tasaa vasemmat reunat',\r
+       right: 'Tasaa oikeat reunat'\r
+} );\r
diff --git a/sources/plugins/justify/lang/fo.js b/sources/plugins/justify/lang/fo.js
new file mode 100644 (file)
index 0000000..f11a575
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'fo', {\r
+       block: 'Javnir tekstkantar',\r
+       center: 'Miðsett',\r
+       left: 'Vinstrasett',\r
+       right: 'Høgrasett'\r
+} );\r
diff --git a/sources/plugins/justify/lang/fr-ca.js b/sources/plugins/justify/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..8d59e5e
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'fr-ca', {\r
+       block: 'Justifié',\r
+       center: 'Centré',\r
+       left: 'Aligner à gauche',\r
+       right: 'Aligner à Droite'\r
+} );\r
diff --git a/sources/plugins/justify/lang/fr.js b/sources/plugins/justify/lang/fr.js
new file mode 100644 (file)
index 0000000..e44df52
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'fr', {\r
+       block: 'Justifier',\r
+       center: 'Centrer',\r
+       left: 'Aligner à gauche',\r
+       right: 'Aligner à droite'\r
+} );\r
diff --git a/sources/plugins/justify/lang/gl.js b/sources/plugins/justify/lang/gl.js
new file mode 100644 (file)
index 0000000..1995e8c
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'gl', {\r
+       block: 'Xustificado',\r
+       center: 'Centrado',\r
+       left: 'Aliñar á esquerda',\r
+       right: 'Aliñar á dereita'\r
+} );\r
diff --git a/sources/plugins/justify/lang/gu.js b/sources/plugins/justify/lang/gu.js
new file mode 100644 (file)
index 0000000..d491684
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'gu', {\r
+       block: 'બ્લૉક, અંતરાય જસ્ટિફાઇ',\r
+       center: 'સંકેંદ્રણ/સેંટરિંગ',\r
+       left: 'ડાબી બાજુએ/બાજુ તરફ',\r
+       right: 'જમણી બાજુએ/બાજુ તરફ'\r
+} );\r
diff --git a/sources/plugins/justify/lang/he.js b/sources/plugins/justify/lang/he.js
new file mode 100644 (file)
index 0000000..ab5c759
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'he', {\r
+       block: 'יישור לשוליים',\r
+       center: 'מרכוז',\r
+       left: 'יישור לשמאל',\r
+       right: 'יישור לימין'\r
+} );\r
diff --git a/sources/plugins/justify/lang/hi.js b/sources/plugins/justify/lang/hi.js
new file mode 100644 (file)
index 0000000..6a4fae8
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'hi', {\r
+       block: 'ब्लॉक जस्टीफ़ाई',\r
+       center: 'बीच में',\r
+       left: 'बायीं तरफ',\r
+       right: 'दायीं तरफ'\r
+} );\r
diff --git a/sources/plugins/justify/lang/hr.js b/sources/plugins/justify/lang/hr.js
new file mode 100644 (file)
index 0000000..852c686
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'hr', {\r
+       block: 'Blok poravnanje',\r
+       center: 'Središnje poravnanje',\r
+       left: 'Lijevo poravnanje',\r
+       right: 'Desno poravnanje'\r
+} );\r
diff --git a/sources/plugins/justify/lang/hu.js b/sources/plugins/justify/lang/hu.js
new file mode 100644 (file)
index 0000000..c7b8dad
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'hu', {\r
+       block: 'Sorkizárt',\r
+       center: 'Középre',\r
+       left: 'Balra',\r
+       right: 'Jobbra'\r
+} );\r
diff --git a/sources/plugins/justify/lang/id.js b/sources/plugins/justify/lang/id.js
new file mode 100644 (file)
index 0000000..d67247c
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'id', {\r
+       block: 'Rata kiri-kanan',\r
+       center: 'Pusat',\r
+       left: 'Align Left', // MISSING\r
+       right: 'Align Right' // MISSING\r
+} );\r
diff --git a/sources/plugins/justify/lang/is.js b/sources/plugins/justify/lang/is.js
new file mode 100644 (file)
index 0000000..d01a43a
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'is', {\r
+       block: 'Jafna báðum megin',\r
+       center: 'Miðja texta',\r
+       left: 'Vinstrijöfnun',\r
+       right: 'Hægrijöfnun'\r
+} );\r
diff --git a/sources/plugins/justify/lang/it.js b/sources/plugins/justify/lang/it.js
new file mode 100644 (file)
index 0000000..fd4ae51
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'it', {\r
+       block: 'Giustifica',\r
+       center: 'Centra',\r
+       left: 'Allinea a sinistra',\r
+       right: 'Allinea a destra'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ja.js b/sources/plugins/justify/lang/ja.js
new file mode 100644 (file)
index 0000000..6c71c86
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ja', {\r
+       block: '両端揃え',\r
+       center: '中央揃え',\r
+       left: '左揃え',\r
+       right: '右揃え'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ka.js b/sources/plugins/justify/lang/ka.js
new file mode 100644 (file)
index 0000000..4ba0bcb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ka', {\r
+       block: 'გადასწორება',\r
+       center: 'შუაში სწორება',\r
+       left: 'მარცხნივ სწორება',\r
+       right: 'მარჯვნივ სწორება'\r
+} );\r
diff --git a/sources/plugins/justify/lang/km.js b/sources/plugins/justify/lang/km.js
new file mode 100644 (file)
index 0000000..a7546c3
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'km', {\r
+       block: 'តម្រឹម​ពេញ',\r
+       center: 'កណ្ដាល',\r
+       left: 'តម្រឹម​ឆ្វេង',\r
+       right: 'តម្រឹម​ស្ដាំ'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ko.js b/sources/plugins/justify/lang/ko.js
new file mode 100644 (file)
index 0000000..346405d
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ko', {\r
+       block: '양쪽 맞춤',\r
+       center: '가운데 정렬',\r
+       left: '왼쪽 정렬',\r
+       right: '오른쪽 정렬'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ku.js b/sources/plugins/justify/lang/ku.js
new file mode 100644 (file)
index 0000000..24ed914
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ku', {\r
+       block: 'هاوستوونی',\r
+       center: 'ناوەڕاست',\r
+       left: 'بەهێڵ کردنی چەپ',\r
+       right: 'بەهێڵ کردنی ڕاست'\r
+} );\r
diff --git a/sources/plugins/justify/lang/lt.js b/sources/plugins/justify/lang/lt.js
new file mode 100644 (file)
index 0000000..08202cb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'lt', {\r
+       block: 'Lygiuoti abi puses',\r
+       center: 'Centruoti',\r
+       left: 'Lygiuoti kairę',\r
+       right: 'Lygiuoti dešinę'\r
+} );\r
diff --git a/sources/plugins/justify/lang/lv.js b/sources/plugins/justify/lang/lv.js
new file mode 100644 (file)
index 0000000..8c729c9
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'lv', {\r
+       block: 'Izlīdzināt malas',\r
+       center: 'Izlīdzināt pret centru',\r
+       left: 'Izlīdzināt pa kreisi',\r
+       right: 'Izlīdzināt pa labi'\r
+} );\r
diff --git a/sources/plugins/justify/lang/mk.js b/sources/plugins/justify/lang/mk.js
new file mode 100644 (file)
index 0000000..f45fb19
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'mk', {\r
+       block: 'Justify', // MISSING\r
+       center: 'Во средина',\r
+       left: 'Align Left', // MISSING\r
+       right: 'Align Right' // MISSING\r
+} );\r
diff --git a/sources/plugins/justify/lang/mn.js b/sources/plugins/justify/lang/mn.js
new file mode 100644 (file)
index 0000000..850e474
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'mn', {\r
+       block: 'Тэгшлэх',\r
+       center: 'Голлуулах',\r
+       left: 'Зүүн талд тулгах',\r
+       right: 'Баруун талд тулгах'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ms.js b/sources/plugins/justify/lang/ms.js
new file mode 100644 (file)
index 0000000..323f8e9
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ms', {\r
+       block: 'Jajaran Blok',\r
+       center: 'Jajaran Tengah',\r
+       left: 'Jajaran Kiri',\r
+       right: 'Jajaran Kanan'\r
+} );\r
diff --git a/sources/plugins/justify/lang/nb.js b/sources/plugins/justify/lang/nb.js
new file mode 100644 (file)
index 0000000..98a3c44
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'nb', {\r
+       block: 'Blokkjuster',\r
+       center: 'Midtstill',\r
+       left: 'Venstrejuster',\r
+       right: 'Høyrejuster'\r
+} );\r
diff --git a/sources/plugins/justify/lang/nl.js b/sources/plugins/justify/lang/nl.js
new file mode 100644 (file)
index 0000000..972bf82
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'nl', {\r
+       block: 'Uitvullen',\r
+       center: 'Centreren',\r
+       left: 'Links uitlijnen',\r
+       right: 'Rechts uitlijnen'\r
+} );\r
diff --git a/sources/plugins/justify/lang/no.js b/sources/plugins/justify/lang/no.js
new file mode 100644 (file)
index 0000000..cfcd72a
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'no', {\r
+       block: 'Blokkjuster',\r
+       center: 'Midtstill',\r
+       left: 'Venstrejuster',\r
+       right: 'Høyrejuster'\r
+} );\r
diff --git a/sources/plugins/justify/lang/oc.js b/sources/plugins/justify/lang/oc.js
new file mode 100644 (file)
index 0000000..a13e528
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'oc', {\r
+       block: 'Justificar',\r
+       center: 'Centrar',\r
+       left: 'Alinhar a esquèrra',\r
+       right: 'Alinhar a dreita'\r
+} );\r
diff --git a/sources/plugins/justify/lang/pl.js b/sources/plugins/justify/lang/pl.js
new file mode 100644 (file)
index 0000000..60922b9
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'pl', {\r
+       block: 'Wyjustuj',\r
+       center: 'Wyśrodkuj',\r
+       left: 'Wyrównaj do lewej',\r
+       right: 'Wyrównaj do prawej'\r
+} );\r
diff --git a/sources/plugins/justify/lang/pt-br.js b/sources/plugins/justify/lang/pt-br.js
new file mode 100644 (file)
index 0000000..cf40ad0
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'pt-br', {\r
+       block: 'Justificado',\r
+       center: 'Centralizar',\r
+       left: 'Alinhar Esquerda',\r
+       right: 'Alinhar Direita'\r
+} );\r
diff --git a/sources/plugins/justify/lang/pt.js b/sources/plugins/justify/lang/pt.js
new file mode 100644 (file)
index 0000000..46ac43b
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'pt', {\r
+       block: 'Justificado',\r
+       center: 'Alinhar ao centro',\r
+       left: 'Alinhar à esquerda',\r
+       right: 'Alinhar à direita'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ro.js b/sources/plugins/justify/lang/ro.js
new file mode 100644 (file)
index 0000000..21caeca
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ro', {\r
+       block: 'Aliniere în bloc (Block Justify)',\r
+       center: 'Aliniere centrală',\r
+       left: 'Aliniere la stânga',\r
+       right: 'Aliniere la dreapta'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ru.js b/sources/plugins/justify/lang/ru.js
new file mode 100644 (file)
index 0000000..47c98bb
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ru', {\r
+       block: 'По ширине',\r
+       center: 'По центру',\r
+       left: 'По левому краю',\r
+       right: 'По правому краю'\r
+} );\r
diff --git a/sources/plugins/justify/lang/si.js b/sources/plugins/justify/lang/si.js
new file mode 100644 (file)
index 0000000..6d9f373
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'si', {\r
+       block: 'Justify', // MISSING\r
+       center: 'මධ්‍ය',\r
+       left: 'Align Left', // MISSING\r
+       right: 'Align Right' // MISSING\r
+} );\r
diff --git a/sources/plugins/justify/lang/sk.js b/sources/plugins/justify/lang/sk.js
new file mode 100644 (file)
index 0000000..08c3991
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sk', {\r
+       block: 'Zarovnať do bloku',\r
+       center: 'Zarovnať na stred',\r
+       left: 'Zarovnať vľavo',\r
+       right: 'Zarovnať vpravo'\r
+} );\r
diff --git a/sources/plugins/justify/lang/sl.js b/sources/plugins/justify/lang/sl.js
new file mode 100644 (file)
index 0000000..d776354
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sl', {\r
+       block: 'Obojestranska poravnava',\r
+       center: 'Sredinska poravnava',\r
+       left: 'Leva poravnava',\r
+       right: 'Desna poravnava'\r
+} );\r
diff --git a/sources/plugins/justify/lang/sq.js b/sources/plugins/justify/lang/sq.js
new file mode 100644 (file)
index 0000000..1ed002c
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sq', {\r
+       block: 'Zgjero',\r
+       center: 'Qendër',\r
+       left: 'Rreshto majtas',\r
+       right: 'Rreshto Djathtas'\r
+} );\r
diff --git a/sources/plugins/justify/lang/sr-latn.js b/sources/plugins/justify/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..7fdba23
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sr-latn', {\r
+       block: 'Obostrano ravnanje',\r
+       center: 'Centriran tekst',\r
+       left: 'Levo ravnanje',\r
+       right: 'Desno ravnanje'\r
+} );\r
diff --git a/sources/plugins/justify/lang/sr.js b/sources/plugins/justify/lang/sr.js
new file mode 100644 (file)
index 0000000..2314a96
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sr', {\r
+       block: 'Обострано равнање',\r
+       center: 'Центриран текст',\r
+       left: 'Лево равнање',\r
+       right: 'Десно равнање'\r
+} );\r
diff --git a/sources/plugins/justify/lang/sv.js b/sources/plugins/justify/lang/sv.js
new file mode 100644 (file)
index 0000000..cac94c0
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'sv', {\r
+       block: 'Justera till marginaler',\r
+       center: 'Centrera',\r
+       left: 'Vänsterjustera',\r
+       right: 'Högerjustera'\r
+} );\r
diff --git a/sources/plugins/justify/lang/th.js b/sources/plugins/justify/lang/th.js
new file mode 100644 (file)
index 0000000..4a9d4f9
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'th', {\r
+       block: 'จัดพอดีหน้ากระดาษ',\r
+       center: 'จัดกึ่งกลาง',\r
+       left: 'จัดชิดซ้าย',\r
+       right: 'จัดชิดขวา'\r
+} );\r
diff --git a/sources/plugins/justify/lang/tr.js b/sources/plugins/justify/lang/tr.js
new file mode 100644 (file)
index 0000000..fbc512f
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'tr', {\r
+       block: 'İki Kenara Yaslanmış',\r
+       center: 'Ortalanmış',\r
+       left: 'Sola Dayalı',\r
+       right: 'Sağa Dayalı'\r
+} );\r
diff --git a/sources/plugins/justify/lang/tt.js b/sources/plugins/justify/lang/tt.js
new file mode 100644 (file)
index 0000000..b36f69c
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'tt', {\r
+       block: 'Киңлеккә карап тигезләү',\r
+       center: 'Үзәккә тигезләү',\r
+       left: 'Сул як кырыйдан тигезләү',\r
+       right: 'Уң як кырыйдан тигезләү'\r
+} );\r
diff --git a/sources/plugins/justify/lang/ug.js b/sources/plugins/justify/lang/ug.js
new file mode 100644 (file)
index 0000000..e5861f5
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'ug', {\r
+       block: 'ئىككى تەرەپتىن توغرىلا',\r
+       center: 'ئوتتۇرىغا توغرىلا',\r
+       left: 'سولغا توغرىلا',\r
+       right: 'ئوڭغا توغرىلا'\r
+} );\r
diff --git a/sources/plugins/justify/lang/uk.js b/sources/plugins/justify/lang/uk.js
new file mode 100644 (file)
index 0000000..5807f25
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'uk', {\r
+       block: 'По ширині',\r
+       center: 'По центру',\r
+       left: 'По лівому краю',\r
+       right: 'По правому краю'\r
+} );\r
diff --git a/sources/plugins/justify/lang/vi.js b/sources/plugins/justify/lang/vi.js
new file mode 100644 (file)
index 0000000..de0c170
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'vi', {\r
+       block: 'Canh đều',\r
+       center: 'Canh giữa',\r
+       left: 'Canh trái',\r
+       right: 'Canh phải'\r
+} );\r
diff --git a/sources/plugins/justify/lang/zh-cn.js b/sources/plugins/justify/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..4c19627
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'zh-cn', {\r
+       block: '两端对齐',\r
+       center: '居中',\r
+       left: '左对齐',\r
+       right: '右对齐'\r
+} );\r
diff --git a/sources/plugins/justify/lang/zh.js b/sources/plugins/justify/lang/zh.js
new file mode 100644 (file)
index 0000000..0865d51
--- /dev/null
@@ -0,0 +1,10 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'justify', 'zh', {\r
+       block: '左右對齊',\r
+       center: '置中',\r
+       left: '靠左對齊',\r
+       right: '靠右對齊'\r
+} );\r
diff --git a/sources/plugins/justify/plugin.js b/sources/plugins/justify/plugin.js
new file mode 100644 (file)
index 0000000..ce5cab3
--- /dev/null
@@ -0,0 +1,245 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Justify commands.\r
+ */\r
+\r
+( function() {\r
+       function getAlignment( element, useComputedState ) {\r
+               useComputedState = useComputedState === undefined || useComputedState;\r
+\r
+               var align;\r
+               if ( useComputedState )\r
+                       align = element.getComputedStyle( 'text-align' );\r
+               else {\r
+                       while ( !element.hasAttribute || !( element.hasAttribute( 'align' ) || element.getStyle( 'text-align' ) ) ) {\r
+                               var parent = element.getParent();\r
+                               if ( !parent )\r
+                                       break;\r
+                               element = parent;\r
+                       }\r
+                       align = element.getStyle( 'text-align' ) || element.getAttribute( 'align' ) || '';\r
+               }\r
+\r
+               // Sometimes computed values doesn't tell.\r
+               align && ( align = align.replace( /(?:-(?:moz|webkit)-)?(?:start|auto)/i, '' ) );\r
+\r
+               !align && useComputedState && ( align = element.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' );\r
+\r
+               return align;\r
+       }\r
+\r
+       function justifyCommand( editor, name, value ) {\r
+               this.editor = editor;\r
+               this.name = name;\r
+               this.value = value;\r
+               this.context = 'p';\r
+\r
+               var classes = editor.config.justifyClasses,\r
+                       blockTag = editor.config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div';\r
+\r
+               if ( classes ) {\r
+                       switch ( value ) {\r
+                               case 'left':\r
+                                       this.cssClassName = classes[ 0 ];\r
+                                       break;\r
+                               case 'center':\r
+                                       this.cssClassName = classes[ 1 ];\r
+                                       break;\r
+                               case 'right':\r
+                                       this.cssClassName = classes[ 2 ];\r
+                                       break;\r
+                               case 'justify':\r
+                                       this.cssClassName = classes[ 3 ];\r
+                                       break;\r
+                       }\r
+\r
+                       this.cssClassRegex = new RegExp( '(?:^|\\s+)(?:' + classes.join( '|' ) + ')(?=$|\\s)' );\r
+                       this.requiredContent = blockTag + '(' + this.cssClassName + ')';\r
+               }\r
+               else {\r
+                       this.requiredContent = blockTag + '{text-align}';\r
+               }\r
+\r
+               this.allowedContent = {\r
+                       'caption div h1 h2 h3 h4 h5 h6 p pre td th li': {\r
+                               // Do not add elements, but only text-align style if element is validated by other rule.\r
+                               propertiesOnly: true,\r
+                               styles: this.cssClassName ? null : 'text-align',\r
+                               classes: this.cssClassName || null\r
+                       }\r
+               };\r
+\r
+               // In enter mode BR we need to allow here for div, because when non other\r
+               // feature allows div justify is the only plugin that uses it.\r
+               if ( editor.config.enterMode == CKEDITOR.ENTER_BR )\r
+                       this.allowedContent.div = true;\r
+       }\r
+\r
+       function onDirChanged( e ) {\r
+               var editor = e.editor;\r
+\r
+               var range = editor.createRange();\r
+               range.setStartBefore( e.data.node );\r
+               range.setEndAfter( e.data.node );\r
+\r
+               var walker = new CKEDITOR.dom.walker( range ),\r
+                       node;\r
+\r
+               while ( ( node = walker.next() ) ) {\r
+                       if ( node.type == CKEDITOR.NODE_ELEMENT ) {\r
+                               // A child with the defined dir is to be ignored.\r
+                               if ( !node.equals( e.data.node ) && node.getDirection() ) {\r
+                                       range.setStartAfter( node );\r
+                                       walker = new CKEDITOR.dom.walker( range );\r
+                                       continue;\r
+                               }\r
+\r
+                               // Switch the alignment.\r
+                               var classes = editor.config.justifyClasses;\r
+                               if ( classes ) {\r
+                                       // The left align class.\r
+                                       if ( node.hasClass( classes[ 0 ] ) ) {\r
+                                               node.removeClass( classes[ 0 ] );\r
+                                               node.addClass( classes[ 2 ] );\r
+                                       }\r
+                                       // The right align class.\r
+                                       else if ( node.hasClass( classes[ 2 ] ) ) {\r
+                                               node.removeClass( classes[ 2 ] );\r
+                                               node.addClass( classes[ 0 ] );\r
+                                       }\r
+                               }\r
+\r
+                               // Always switch CSS margins.\r
+                               var style = 'text-align';\r
+                               var align = node.getStyle( style );\r
+\r
+                               if ( align == 'left' )\r
+                                       node.setStyle( style, 'right' );\r
+                               else if ( align == 'right' )\r
+                                       node.setStyle( style, 'left' );\r
+                       }\r
+               }\r
+       }\r
+\r
+       justifyCommand.prototype = {\r
+               exec: function( editor ) {\r
+                       var selection = editor.getSelection(),\r
+                               enterMode = editor.config.enterMode;\r
+\r
+                       if ( !selection )\r
+                               return;\r
+\r
+                       var bookmarks = selection.createBookmarks(),\r
+                               ranges = selection.getRanges();\r
+\r
+                       var cssClassName = this.cssClassName,\r
+                               iterator, block;\r
+\r
+                       var useComputedState = editor.config.useComputedState;\r
+                       useComputedState = useComputedState === undefined || useComputedState;\r
+\r
+                       for ( var i = ranges.length - 1; i >= 0; i-- ) {\r
+                               iterator = ranges[ i ].createIterator();\r
+                               iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;\r
+\r
+                               while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) ) {\r
+                                       if ( block.isReadOnly() )\r
+                                               continue;\r
+\r
+                                       block.removeAttribute( 'align' );\r
+                                       block.removeStyle( 'text-align' );\r
+\r
+                                       // Remove any of the alignment classes from the className.\r
+                                       var className = cssClassName && ( block.$.className = CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) ) );\r
+\r
+                                       var apply = ( this.state == CKEDITOR.TRISTATE_OFF ) && ( !useComputedState || ( getAlignment( block, true ) != this.value ) );\r
+\r
+                                       if ( cssClassName ) {\r
+                                               // Append the desired class name.\r
+                                               if ( apply )\r
+                                                       block.addClass( cssClassName );\r
+                                               else if ( !className )\r
+                                                       block.removeAttribute( 'class' );\r
+                                       } else if ( apply ) {\r
+                                               block.setStyle( 'text-align', this.value );\r
+                                       }\r
+                               }\r
+\r
+                       }\r
+\r
+                       editor.focus();\r
+                       editor.forceNextSelectionCheck();\r
+                       selection.selectBookmarks( bookmarks );\r
+               },\r
+\r
+               refresh: function( editor, path ) {\r
+                       var firstBlock = path.block || path.blockLimit;\r
+\r
+                       this.setState( firstBlock.getName() != 'body' && getAlignment( firstBlock, this.editor.config.useComputedState ) == this.value ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
+               }\r
+       };\r
+\r
+       CKEDITOR.plugins.add( 'justify', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'justifyblock,justifycenter,justifyleft,justifyright', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       if ( editor.blockless )\r
+                               return;\r
+\r
+                       var left = new justifyCommand( editor, 'justifyleft', 'left' ),\r
+                               center = new justifyCommand( editor, 'justifycenter', 'center' ),\r
+                               right = new justifyCommand( editor, 'justifyright', 'right' ),\r
+                               justify = new justifyCommand( editor, 'justifyblock', 'justify' );\r
+\r
+                       editor.addCommand( 'justifyleft', left );\r
+                       editor.addCommand( 'justifycenter', center );\r
+                       editor.addCommand( 'justifyright', right );\r
+                       editor.addCommand( 'justifyblock', justify );\r
+\r
+                       if ( editor.ui.addButton ) {\r
+                               editor.ui.addButton( 'JustifyLeft', {\r
+                                       label: editor.lang.justify.left,\r
+                                       command: 'justifyleft',\r
+                                       toolbar: 'align,10'\r
+                               } );\r
+                               editor.ui.addButton( 'JustifyCenter', {\r
+                                       label: editor.lang.justify.center,\r
+                                       command: 'justifycenter',\r
+                                       toolbar: 'align,20'\r
+                               } );\r
+                               editor.ui.addButton( 'JustifyRight', {\r
+                                       label: editor.lang.justify.right,\r
+                                       command: 'justifyright',\r
+                                       toolbar: 'align,30'\r
+                               } );\r
+                               editor.ui.addButton( 'JustifyBlock', {\r
+                                       label: editor.lang.justify.block,\r
+                                       command: 'justifyblock',\r
+                                       toolbar: 'align,40'\r
+                               } );\r
+                       }\r
+\r
+                       editor.on( 'dirChanged', onDirChanged );\r
+               }\r
+       } );\r
+} )();\r
+\r
+/**\r
+ * List of classes to use for aligning the contents. If it's `null`, no classes will be used\r
+ * and instead the corresponding CSS values will be used.\r
+ *\r
+ * The array should contain 4 members, in the following order: left, center, right, justify.\r
+ *\r
+ *             // Use the classes 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify'\r
+ *             config.justifyClasses = [ 'AlignLeft', 'AlignCenter', 'AlignRight', 'AlignJustify' ];\r
+ *\r
+ * @cfg {Array} [justifyClasses=null]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/lineutils/dev/dnd.html b/sources/plugins/lineutils/dev/dnd.html
new file mode 100644 (file)
index 0000000..7293daa
--- /dev/null
@@ -0,0 +1,172 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Widget Drag &amp; Drop with Lineutils &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script>\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+                       CKEDITOR.tools.enableHtml5Elements( document );\r
+       </script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <link href="../../image2/samples/contents.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Widget Drag &amp; Drop with Lineutils\r
+       </h1>\r
+\r
+       <h3>Classic (iframe-based) Editor</h3>\r
+\r
+       <textarea id="editor1" cols="10" rows="10">\r
+               <h1>Apollo 11</h1>\r
+\r
+               <figure class="caption" style="float:right"><img alt="Saturn V" src="../../image2/samples/assets/image1.jpg" width="200" />\r
+               <figcaption>Roll out of Saturn V on launch pad</figcaption>\r
+               </figure>\r
+\r
+               <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>\r
+\r
+               <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>\r
+\r
+               <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>\r
+\r
+               <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+\r
+               <blockquote>\r
+               <p>One small step for [a] man, one giant leap for mankind.</p>\r
+               </blockquote>\r
+\r
+               <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>\r
+\r
+               <div style="text-align:center">\r
+               <figure class="caption" style="display:inline-block"><img alt="The Eagle" height="123" src="../../image2/samples/assets/image2.jpg" width="136" />\r
+               <figcaption>The Eagle in lunar orbit</figcaption>\r
+               </figure>\r
+               </div>\r
+\r
+               <blockquote>\r
+               <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>\r
+               </blockquote>\r
+\r
+               <figure class="caption" style="float:right"><img alt="The Eagle" src="../../image2/samples/assets/image2.jpg" width="200" />\r
+               <figcaption>The Eagle in lunar orbit</figcaption>\r
+               </figure>\r
+\r
+               <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>\r
+\r
+               <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>\r
+\r
+               <ol>\r
+                       <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>\r
+                       <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>\r
+                       <li><strong>Lunar Module</strong> for landing on the Moon.</li>\r
+               </ol>\r
+\r
+               <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>\r
+\r
+               <figure class="caption"><img alt="Saturn V" height="129" src="../../image2/samples/assets/image1.jpg" width="101" />\r
+               <figcaption>Roll out of Saturn V on launch pad</figcaption>\r
+               </figure>\r
+\r
+               <hr />\r
+               <p style="text-align:right"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p>\r
+\r
+       </textarea>\r
+\r
+       <h3>Inline Editor</h3>\r
+\r
+       <div id="editor2" contenteditable="true" style="outline: 2px solid #ccc">\r
+               <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>This table</td>\r
+                                       <td>is the</td>\r
+                                       <td>very first</td>\r
+                                       <td>element of the document.</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>We are still</td>\r
+                                       <td>able to acces</td>\r
+                                       <td>the space before it.</td>\r
+                                       <td style="padding: 25px">\r
+                                       <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                                               <tbody>\r
+                                                       <tr>\r
+                                                               <td>This table is inside of a cell of another table.</td>\r
+                                                       </tr>\r
+                                                       <tr>\r
+                                                               <td>We can type&nbsp;either before or after it though.</td>\r
+                                                       </tr>\r
+                                               </tbody>\r
+                                       </table>\r
+                                       </td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+\r
+               <hr />\r
+               <hr />\r
+               <ol style="width: 300px">\r
+                       <li>This numbered list...</li>\r
+                       <li>...is a neighbour of a horizontal line...</li>\r
+                       <li style="padding: 20px;">\r
+                               <ol>\r
+                                       <li>Nested list!</li>\r
+                               </ol>\r
+                       </li>\r
+               </ol>\r
+\r
+               <figure class="caption"><img alt="Saturn V" src="../../image2/samples/assets/image1.jpg" width="100" />\r
+                       <figcaption>Roll out of Saturn V on launch pad</figcaption>\r
+               </figure>\r
+\r
+               <ul style="width: 450px">\r
+                       <li>We can type between the lists...</li>\r
+                       <li>...thanks to <strong>Magicline</strong>.</li>\r
+               </ul>\r
+\r
+               <p>Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.</p>\r
+\r
+               <p>Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.</p>\r
+\r
+               <p>Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.</p>\r
+\r
+               <div id="last" style="padding: 10px; text-align: center;">\r
+                       <p>This text is wrapped in a&nbsp;<tt>DIV</tt>&nbsp;element. We can type after this element though.</p>\r
+               </div>\r
+       </div>\r
+\r
+       <script>\r
+\r
+               CKEDITOR.replace( 'editor1', {\r
+                       extraPlugins: 'image2',\r
+                       height: 450,\r
+                       removePlugins: 'image,forms',\r
+                       contentsCss: [ '../../../contents.css', '../../image2/samples/contents.css' ]\r
+               } );\r
+\r
+               CKEDITOR.inline( 'editor2', {\r
+                       extraPlugins: 'image2',\r
+                       height: 450,\r
+                       removePlugins: 'image,forms'\r
+               } );\r
+\r
+       </script>\r
+\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/lineutils/dev/magicfinger.html b/sources/plugins/lineutils/dev/magicfinger.html
new file mode 100644 (file)
index 0000000..3172d22
--- /dev/null
@@ -0,0 +1,285 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Lineutils &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Lineutils\r
+       </h1>\r
+\r
+       <h3>Classic (iframe-based) Editor</h3>\r
+\r
+       <textarea id="editor1" cols="10" rows="10">\r
+               <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>This table</td>\r
+                                       <td>is the</td>\r
+                                       <td>very first</td>\r
+                                       <td>element of the document.</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>We are still</td>\r
+                                       <td>able to acces</td>\r
+                                       <td>the space before it.</td>\r
+                                       <td style="padding: 25px">\r
+                                       <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                                               <tbody>\r
+                                                       <tr>\r
+                                                               <td>This table is inside of a cell of another table.</td>\r
+                                                       </tr>\r
+                                                       <tr>\r
+                                                               <td>We can type&nbsp;either before or after it though.</td>\r
+                                                       </tr>\r
+                                               </tbody>\r
+                                       </table>\r
+                                       </td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+\r
+               <p>Two succesive horizontal lines (<tt>HR</tt> tags). We can access the space in between:</p>\r
+\r
+               <hr />\r
+               <hr />\r
+               <ol style="width: 300px">\r
+                       <li>This numbered list...</li>\r
+                       <li>...is a neighbour of a horizontal line...</li>\r
+                       <li style="padding: 20px;">\r
+                               <ol>\r
+                                       <li>Nested list!</li>\r
+                               </ol>\r
+                       </li>\r
+               </ol>\r
+\r
+               <ul style="width: 450px">\r
+                       <li>We can type between the lists...</li>\r
+                       <li>...thanks to <strong>Magicline</strong>.</li>\r
+               </ul>\r
+\r
+               <p>Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.</p>\r
+\r
+               <p>Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.</p>\r
+\r
+               <p>Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.</p>\r
+\r
+               <div id="last" style="padding: 10px; text-align: center;">\r
+               <p>This text is wrapped in a&nbsp;<tt>DIV</tt>&nbsp;element. We can type after this element though.</p>\r
+               </div>\r
+       </textarea>\r
+\r
+       <h3>Inline Editor</h3>\r
+\r
+       <div id="editor2" contenteditable="true" style="outline: 2px solid #ccc">\r
+               <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>This table</td>\r
+                                       <td>is the</td>\r
+                                       <td>very first</td>\r
+                                       <td>element of the document.</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>We are still</td>\r
+                                       <td>able to acces</td>\r
+                                       <td>the space before it.</td>\r
+                                       <td style="padding: 25px">\r
+                                       <table border="0" cellpadding="1" cellspacing="1" style="width: 100%; ">\r
+                                               <tbody>\r
+                                                       <tr>\r
+                                                               <td>This table is inside of a cell of another table.</td>\r
+                                                       </tr>\r
+                                                       <tr>\r
+                                                               <td>We can type&nbsp;either before or after it though.</td>\r
+                                                       </tr>\r
+                                               </tbody>\r
+                                       </table>\r
+                                       </td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+\r
+               <p>Two succesive horizontal lines (<tt>HR</tt> tags). We can access the space in between:</p>\r
+\r
+               <hr />\r
+               <hr />\r
+               <ol style="width: 300px">\r
+                       <li>This numbered list...</li>\r
+                       <li>...is a neighbour of a horizontal line...</li>\r
+                       <li style="padding: 20px;">\r
+                               <ol>\r
+                                       <li>Nested list!</li>\r
+                               </ol>\r
+                       </li>\r
+               </ol>\r
+\r
+               <ul style="width: 450px">\r
+                       <li>We can type between the lists...</li>\r
+                       <li>...thanks to <strong>Magicline</strong>.</li>\r
+               </ul>\r
+\r
+               <p>Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.</p>\r
+\r
+               <p>Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.</p>\r
+\r
+               <p>Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.</p>\r
+\r
+               <div id="last" style="padding: 10px; text-align: center;">\r
+                       <p>This text is wrapped in a&nbsp;<tt>DIV</tt>&nbsp;element. We can type after this element though.</p>\r
+               </div>\r
+       </div>\r
+\r
+       <h3>Extreme inline</h3>\r
+\r
+       <div id="editor3" contenteditable="true" style="left: 123px; outline: 1px solid red; border: 15px solid green; position: relative; top: 30; left: 30px;">\r
+               <div style="padding: 20px; background: gray; width: 300px" class="1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim.</div>\r
+               <div style="background: violet; padding: 30px;" class="static">\r
+                       Position static\r
+                       <div style="background: green; padding: 30px;  border: 14px solid orange">foo</div>\r
+               </div>\r
+               <dl class="2">\r
+                       <dt>Key</dt><dd>Value</dd>\r
+               </dl>\r
+               <div>Whatever</div>\r
+               <hr id="hr">\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <hr>\r
+               <hr>\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <div style="background: green; padding: 30px; width: 200px">foo</div>\r
+       </div>\r
+\r
+       <h3>Classic (iframe-based) Editor, H-scroll</h3>\r
+\r
+       <textarea id="editor4" cols="10" rows="10">\r
+               <hr />\r
+               <hr />\r
+               <ol style="width: 1500px">\r
+                       <li>This numbered list...</li>\r
+                       <li>...is a neighbour of a horizontal line...</li>\r
+                       <li style="padding: 20px;">\r
+                               <ol>\r
+                                       <li>Nested list!</li>\r
+                               </ol>\r
+                       </li>\r
+               </ol>\r
+\r
+               <ul style="width: 450px">\r
+                       <li>We can type between the lists...</li>\r
+                       <li>...thanks to <strong>Magicline</strong>.</li>\r
+               </ul>\r
+\r
+               <p>Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.</p>\r
+\r
+               <p>Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.</p>\r
+\r
+               <p>Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.</p>\r
+\r
+               <div id="last" style="padding: 10px; text-align: center;">\r
+               <p>This text is wrapped in a&nbsp;<tt>DIV</tt>&nbsp;element. We can type after this element though.</p>\r
+               </div>\r
+       </textarea>\r
+\r
+       <script>\r
+\r
+               CKEDITOR.addCss(\r
+                       '.cke_editable * { outline: 1px solid #BCEBFF }'\r
+               );\r
+\r
+               function callback() {\r
+                       var helpers = CKEDITOR.plugins.lineutils;\r
+                       var liner = new helpers.liner( this );\r
+                       var locator = new helpers.locator( this );\r
+                       var finder = new helpers.finder( this, {\r
+                               lookups: {\r
+                                       'is block and first child': function( el ) {\r
+                                               if ( el.is( CKEDITOR.dtd.$listItem ) )\r
+                                                       return;\r
+\r
+                                               if ( el.is( CKEDITOR.dtd.$block ) )\r
+                                                       return CKEDITOR.LINEUTILS_BEFORE | CKEDITOR.LINEUTILS_AFTER;\r
+                                       }\r
+                               }\r
+                       } ).start( function( relations, x, y ) {\r
+                               locator.locate( relations );\r
+\r
+                               var locations = locator.locations,\r
+                                       uid, type;\r
+\r
+                               liner.prepare( relations, locations );\r
+\r
+                               for ( uid in locations ) {\r
+                                       for ( type in locations[ uid ] )\r
+                                               liner.placeLine( { uid: uid, type: type } );\r
+                               }\r
+\r
+                               liner.cleanup();\r
+                       } );\r
+               }\r
+\r
+               CKEDITOR.disableAutoInline = true;\r
+\r
+               CKEDITOR.replace( 'editor1', {\r
+                       extraPlugins: 'lineutils',\r
+                       height: 450,\r
+                       removePlugins: 'magicline',\r
+                       allowedContent: true,\r
+                       contentsCss: [ '../../../contents.css' ],\r
+                       on: {\r
+                               contentDom: callback\r
+                       }\r
+               } );\r
+\r
+               CKEDITOR.inline( 'editor2', {\r
+                       extraPlugins: 'lineutils',\r
+                       removePlugins: 'magicline',\r
+                       allowedContent: true,\r
+                       contentsCss: [ '../../../contents.css' ],\r
+                       on: {\r
+                               contentDom: callback\r
+                       }\r
+               } );\r
+\r
+               CKEDITOR.inline( 'editor3', {\r
+                       extraPlugins: 'lineutils',\r
+                       removePlugins: 'magicline',\r
+                       allowedContent: true,\r
+                       contentsCss: [ '../../../contents.css' ],\r
+                       on: {\r
+                               contentDom: callback\r
+                       }\r
+               } );\r
+\r
+               CKEDITOR.replace( 'editor4', {\r
+                       extraPlugins: 'lineutils',\r
+                       removePlugins: 'magicline',\r
+                       allowedContent: true,\r
+                       contentsCss: [ '../../../contents.css' ],\r
+                       on: {\r
+                               contentDom: callback\r
+                       }\r
+               } );\r
+\r
+\r
+       </script>\r
+\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/lineutils/plugin.js b/sources/plugins/lineutils/plugin.js
new file mode 100644 (file)
index 0000000..e0473ee
--- /dev/null
@@ -0,0 +1,1018 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+ /**\r
+ * @fileOverview A set of utilities to find and create horizontal spaces in edited content.\r
+ */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+\r
+       CKEDITOR.plugins.add( 'lineutils' );\r
+\r
+       /**\r
+        * Determines a position relative to an element in DOM (before).\r
+        *\r
+        * @readonly\r
+        * @property {Number} [=0]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.LINEUTILS_BEFORE = 1;\r
+\r
+       /**\r
+        * Determines a position relative to an element in DOM (after).\r
+        *\r
+        * @readonly\r
+        * @property {Number} [=2]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.LINEUTILS_AFTER = 2;\r
+\r
+       /**\r
+        * Determines a position relative to an element in DOM (inside).\r
+        *\r
+        * @readonly\r
+        * @property {Number} [=4]\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.LINEUTILS_INSIDE = 4;\r
+\r
+       /**\r
+        * A utility that traverses the DOM tree and discovers elements\r
+        * (relations) matching user-defined lookups.\r
+        *\r
+        * @private\r
+        * @class CKEDITOR.plugins.lineutils.finder\r
+        * @constructor Creates a Finder class instance.\r
+        * @param {CKEDITOR.editor} editor Editor instance that the Finder belongs to.\r
+        * @param {Object} def Finder's definition.\r
+        * @since 4.3\r
+        */\r
+       function Finder( editor, def ) {\r
+               CKEDITOR.tools.extend( this, {\r
+                       editor: editor,\r
+                       editable: editor.editable(),\r
+                       doc: editor.document,\r
+                       win: editor.window\r
+               }, def, true );\r
+\r
+               this.inline = this.editable.isInline();\r
+\r
+               if ( !this.inline ) {\r
+                       this.frame = this.win.getFrame();\r
+               }\r
+\r
+               this.target = this[ this.inline ? 'editable' : 'doc' ];\r
+       }\r
+\r
+       Finder.prototype = {\r
+               /**\r
+                * Initializes searching for elements with every mousemove event fired.\r
+                * To stop searching use {@link #stop}.\r
+                *\r
+                * @param {Function} [callback] Function executed on every iteration.\r
+                */\r
+               start: function( callback ) {\r
+                       var that = this,\r
+                               editor = this.editor,\r
+                               doc = this.doc,\r
+                               el, elfp, x, y;\r
+\r
+                       var moveBuffer = CKEDITOR.tools.eventsBuffer( 50, function() {\r
+                                       if ( editor.readOnly || editor.mode != 'wysiwyg' )\r
+                                               return;\r
+\r
+                                       that.relations = {};\r
+\r
+                                       // Sometimes it happens that elementFromPoint returns null (especially on IE).\r
+                                       // Any further traversal makes no sense if there's no start point. Abort.\r
+                                       // Note: In IE8 elementFromPoint may return zombie nodes of undefined nodeType,\r
+                                       // so rejecting those as well.\r
+                                       if ( !( elfp = doc.$.elementFromPoint( x, y ) ) || !elfp.nodeType ) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       el = new CKEDITOR.dom.element( elfp );\r
+\r
+                                       that.traverseSearch( el );\r
+\r
+                                       if ( !isNaN( x + y ) ) {\r
+                                               that.pixelSearch( el, x, y );\r
+                                       }\r
+\r
+                                       callback && callback( that.relations, x, y );\r
+                               } );\r
+\r
+                       // Searching starting from element from point on mousemove.\r
+                       this.listener = this.editable.attachListener( this.target, 'mousemove', function( evt ) {\r
+                               x = evt.data.$.clientX;\r
+                               y = evt.data.$.clientY;\r
+\r
+                               moveBuffer.input();\r
+                       } );\r
+\r
+                       this.editable.attachListener( this.inline ? this.editable : this.frame, 'mouseout', function() {\r
+                               moveBuffer.reset();\r
+                       } );\r
+               },\r
+\r
+               /**\r
+                * Stops observing mouse events attached by {@link #start}.\r
+                */\r
+               stop: function() {\r
+                       if ( this.listener ) {\r
+                               this.listener.removeListener();\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Returns a range representing the relation, according to its element\r
+                * and type.\r
+                *\r
+                * @param {Object} location Location containing a unique identifier and type.\r
+                * @returns {CKEDITOR.dom.range} Range representing the relation.\r
+                */\r
+               getRange: ( function() {\r
+                       var where = {};\r
+\r
+                       where[ CKEDITOR.LINEUTILS_BEFORE ] = CKEDITOR.POSITION_BEFORE_START;\r
+                       where[ CKEDITOR.LINEUTILS_AFTER ] = CKEDITOR.POSITION_AFTER_END;\r
+                       where[ CKEDITOR.LINEUTILS_INSIDE ] = CKEDITOR.POSITION_AFTER_START;\r
+\r
+                       return function( location ) {\r
+                               var range = this.editor.createRange();\r
+\r
+                               range.moveToPosition( this.relations[ location.uid ].element, where[ location.type ] );\r
+\r
+                               return range;\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Stores given relation in a {@link #relations} object. Processes the relation\r
+                * to normalize and avoid duplicates.\r
+                *\r
+                * @param {CKEDITOR.dom.element} el Element of the relation.\r
+                * @param {Number} type Relation, one of `CKEDITOR.LINEUTILS_AFTER`, `CKEDITOR.LINEUTILS_BEFORE`, `CKEDITOR.LINEUTILS_INSIDE`.\r
+                */\r
+               store: ( function() {\r
+                       function merge( el, type, relations ) {\r
+                               var uid = el.getUniqueId();\r
+\r
+                               if ( uid in relations ) {\r
+                                       relations[ uid ].type |= type;\r
+                               } else {\r
+                                       relations[ uid ] = { element: el, type: type };\r
+                               }\r
+                       }\r
+\r
+                       return function( el, type ) {\r
+                               var alt;\r
+\r
+                               // Normalization to avoid duplicates:\r
+                               // CKEDITOR.LINEUTILS_AFTER becomes CKEDITOR.LINEUTILS_BEFORE of el.getNext().\r
+                               if ( is( type, CKEDITOR.LINEUTILS_AFTER ) && isStatic( alt = el.getNext() ) && alt.isVisible() ) {\r
+                                       merge( alt, CKEDITOR.LINEUTILS_BEFORE, this.relations );\r
+                                       type ^= CKEDITOR.LINEUTILS_AFTER;\r
+                               }\r
+\r
+                               // Normalization to avoid duplicates:\r
+                               // CKEDITOR.LINEUTILS_INSIDE becomes CKEDITOR.LINEUTILS_BEFORE of el.getFirst().\r
+                               if ( is( type, CKEDITOR.LINEUTILS_INSIDE ) && isStatic( alt = el.getFirst() ) && alt.isVisible() ) {\r
+                                       merge( alt, CKEDITOR.LINEUTILS_BEFORE, this.relations );\r
+                                       type ^= CKEDITOR.LINEUTILS_INSIDE;\r
+                               }\r
+\r
+                               merge( el, type, this.relations );\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Traverses the DOM tree towards root, checking all ancestors\r
+                * with lookup rules, avoiding duplicates. Stores positive relations\r
+                * in the {@link #relations} object.\r
+                *\r
+                * @param {CKEDITOR.dom.element} el Element which is the starting point.\r
+                */\r
+               traverseSearch: function( el ) {\r
+                       var l, type, uid;\r
+\r
+                       // Go down DOM towards root (or limit).\r
+                       do {\r
+                               uid = el.$[ 'data-cke-expando' ];\r
+\r
+                               // This element was already visited and checked.\r
+                               if ( uid && uid in this.relations ) {\r
+                                       continue;\r
+                               }\r
+\r
+                               if ( el.equals( this.editable ) ) {\r
+                                       return;\r
+                               }\r
+\r
+                               if ( isStatic( el ) ) {\r
+                                       // Collect all addresses yielded by lookups for that element.\r
+                                       for ( l in this.lookups ) {\r
+\r
+                                               if ( ( type = this.lookups[ l ]( el ) ) ) {\r
+                                                       this.store( el, type );\r
+                                               }\r
+                                       }\r
+                               }\r
+                       } while ( !isLimit( el ) && ( el = el.getParent() ) );\r
+               },\r
+\r
+               /**\r
+                * Iterates vertically pixel-by-pixel within a given element starting\r
+                * from given coordinates, searching for elements in the neighborhood.\r
+                * Once an element is found it is processed by {@link #traverseSearch}.\r
+                *\r
+                * @param {CKEDITOR.dom.element} el Element which is the starting point.\r
+                * @param {Number} [x] Horizontal mouse coordinate relative to the viewport.\r
+                * @param {Number} [y] Vertical mouse coordinate relative to the viewport.\r
+                */\r
+               pixelSearch: ( function() {\r
+                       var contains = CKEDITOR.env.ie || CKEDITOR.env.webkit ?\r
+                               function( el, found ) {\r
+                                       return el.contains( found );\r
+                               } : function( el, found ) {\r
+                                       return !!( el.compareDocumentPosition( found ) & 16 );\r
+                               };\r
+\r
+                       // Iterates pixel-by-pixel from starting coordinates, moving by defined\r
+                       // step and getting elementFromPoint in every iteration. Iteration stops when:\r
+                       //  * A valid element is found.\r
+                       //  * Condition function returns `false` (i.e. reached boundaries of viewport).\r
+                       //  * No element is found (i.e. coordinates out of viewport).\r
+                       //  * Element found is ascendant of starting element.\r
+                       //\r
+                       // @param {Object} doc Native DOM document.\r
+                       // @param {Object} el Native DOM element.\r
+                       // @param {Number} xStart Horizontal starting coordinate to use.\r
+                       // @param {Number} yStart Vertical starting coordinate to use.\r
+                       // @param {Number} step Step of the algorithm.\r
+                       // @param {Function} condition A condition relative to current vertical coordinate.\r
+                       function iterate( el, xStart, yStart, step, condition ) {\r
+                               var y = yStart,\r
+                                       tryouts = 0,\r
+                                       found;\r
+\r
+                               while ( condition( y ) ) {\r
+                                       y += step;\r
+\r
+                                       // If we try and we try, and still nothing's found, let's end\r
+                                       // that party.\r
+                                       if ( ++tryouts == 25 ) {\r
+                                               return;\r
+                                       }\r
+\r
+                                       found = this.doc.$.elementFromPoint( xStart, y );\r
+\r
+                                       // Nothing found. This is crazy... but...\r
+                                       // It might be that a line, which is in different document,\r
+                                       // covers that pixel (elementFromPoint is doc-sensitive).\r
+                                       // Better let's have another try.\r
+                                       if ( !found ) {\r
+                                               continue;\r
+                                       }\r
+\r
+                                       // Still in the same element.\r
+                                       else if ( found == el ) {\r
+                                               tryouts = 0;\r
+                                               continue;\r
+                                       }\r
+\r
+                                       // Reached the edge of an element and found an ancestor or...\r
+                                       // A line, that covers that pixel. Better let's have another try.\r
+                                       else if ( !contains( el, found ) ) {\r
+                                               continue;\r
+                                       }\r
+\r
+                                       tryouts = 0;\r
+\r
+                                       // Found a valid element. Stop iterating.\r
+                                       if ( isStatic( ( found = new CKEDITOR.dom.element( found ) ) ) ) {\r
+                                               return found;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       return function( el, x, y ) {\r
+                               var paneHeight = this.win.getViewPaneSize().height,\r
+\r
+                                       // Try to find an element iterating *up* from the starting point.\r
+                                       neg = iterate.call( this, el.$, x, y, -1, function( y ) {\r
+                                               return y > 0;\r
+                                       } ),\r
+\r
+                                       // Try to find an element iterating *down* from the starting point.\r
+                                       pos = iterate.call( this, el.$, x, y, 1, function( y ) {\r
+                                               return y < paneHeight;\r
+                                       } );\r
+\r
+                               if ( neg ) {\r
+                                       this.traverseSearch( neg );\r
+\r
+                                       // Iterate towards DOM root until neg is a direct child of el.\r
+                                       while ( !neg.getParent().equals( el ) ) {\r
+                                               neg = neg.getParent();\r
+                                       }\r
+                               }\r
+\r
+                               if ( pos ) {\r
+                                       this.traverseSearch( pos );\r
+\r
+                                       // Iterate towards DOM root until pos is a direct child of el.\r
+                                       while ( !pos.getParent().equals( el ) ) {\r
+                                               pos = pos.getParent();\r
+                                       }\r
+                               }\r
+\r
+                               // Iterate forwards starting from neg and backwards from\r
+                               // pos to harvest all children of el between those elements.\r
+                               // Stop when neg and pos meet each other or there's none of them.\r
+                               // TODO (?) reduce number of hops forwards/backwards.\r
+                               while ( neg || pos ) {\r
+                                       if ( neg ) {\r
+                                               neg = neg.getNext( isStatic );\r
+                                       }\r
+\r
+                                       if ( !neg || neg.equals( pos ) ) {\r
+                                               break;\r
+                                       }\r
+\r
+                                       this.traverseSearch( neg );\r
+\r
+                                       if ( pos ) {\r
+                                               pos = pos.getPrevious( isStatic );\r
+                                       }\r
+\r
+                                       if ( !pos || pos.equals( neg ) ) {\r
+                                               break;\r
+                                       }\r
+\r
+                                       this.traverseSearch( pos );\r
+                               }\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Unlike {@link #traverseSearch}, it collects **all** elements from editable's DOM tree\r
+                * and runs lookups for every one of them, collecting relations.\r
+                *\r
+                * @returns {Object} {@link #relations}.\r
+                */\r
+               greedySearch: function() {\r
+                       this.relations = {};\r
+\r
+                       var all = this.editable.getElementsByTag( '*' ),\r
+                               i = 0,\r
+                               el, type, l;\r
+\r
+                       while ( ( el = all.getItem( i++ ) ) ) {\r
+                               // Don't consider editable, as it might be inline,\r
+                               // and i.e. checking it's siblings is pointless.\r
+                               if ( el.equals( this.editable ) ) {\r
+                                       continue;\r
+                               }\r
+\r
+                               // On IE8 element.getElementsByTagName returns comments... sic! (#13176)\r
+                               if ( el.type != CKEDITOR.NODE_ELEMENT ) {\r
+                                       continue;\r
+                               }\r
+\r
+                               // Don't visit non-editable internals, for example widget's\r
+                               // guts (above wrapper, below nested). Still check editable limits,\r
+                               // as they are siblings with editable contents.\r
+                               if ( !el.hasAttribute( 'contenteditable' ) && el.isReadOnly() ) {\r
+                                       continue;\r
+                               }\r
+\r
+                               if ( isStatic( el ) && el.isVisible() ) {\r
+                                       // Collect all addresses yielded by lookups for that element.\r
+                                       for ( l in this.lookups ) {\r
+                                               if ( ( type = this.lookups[ l ]( el ) ) ) {\r
+                                                       this.store( el, type );\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       return this.relations;\r
+               }\r
+\r
+               /**\r
+                * Relations express elements in DOM that match user-defined {@link #lookups}.\r
+                * Every relation has its own `type` that determines whether\r
+                * it refers to the space before, after or inside the `element`.\r
+                * This object stores relations found by {@link #traverseSearch} or {@link #greedySearch}, structured\r
+                * in the following way:\r
+                *\r
+                *              relations: {\r
+                *                      // Unique identifier of the element.\r
+                *                      Number: {\r
+                *                              // Element of this relation.\r
+                *                              element: {@link CKEDITOR.dom.element}\r
+                *                              // Conjunction of CKEDITOR.LINEUTILS_BEFORE, CKEDITOR.LINEUTILS_AFTER and CKEDITOR.LINEUTILS_INSIDE.\r
+                *                              type: Number\r
+                *                      },\r
+                *                      ...\r
+                *              }\r
+                *\r
+                * @property {Object} relations\r
+                * @readonly\r
+                */\r
+\r
+               /**\r
+                * A set of user-defined functions used by Finder to check if an element\r
+                * is a valid relation, belonging to {@link #relations}.\r
+                * When the criterion is met, lookup returns a logical conjunction of `CKEDITOR.LINEUTILS_BEFORE`,\r
+                * `CKEDITOR.LINEUTILS_AFTER` or `CKEDITOR.LINEUTILS_INSIDE`.\r
+                *\r
+                * Lookups are passed along with Finder's definition.\r
+                *\r
+                *              lookups: {\r
+                *                      'some lookup': function( el ) {\r
+                *                              if ( someCondition )\r
+                *                                      return CKEDITOR.LINEUTILS_BEFORE;\r
+                *                      },\r
+                *                      ...\r
+                *              }\r
+                *\r
+                * @property {Object} lookups\r
+                */\r
+       };\r
+\r
+\r
+       /**\r
+        * A utility that analyses relations found by\r
+        * CKEDITOR.plugins.lineutils.finder and locates them\r
+        * in the viewport as horizontal lines of specific coordinates.\r
+        *\r
+        * @private\r
+        * @class CKEDITOR.plugins.lineutils.locator\r
+        * @constructor Creates a Locator class instance.\r
+        * @param {CKEDITOR.editor} editor Editor instance that Locator belongs to.\r
+        * @since 4.3\r
+        */\r
+       function Locator( editor, def ) {\r
+               CKEDITOR.tools.extend( this, def, {\r
+                       editor: editor\r
+               }, true );\r
+       }\r
+\r
+       Locator.prototype = {\r
+               /**\r
+                * Locates the Y coordinate for all types of every single relation and stores\r
+                * them in an object.\r
+                *\r
+                * @param {Object} relations {@link CKEDITOR.plugins.lineutils.finder#relations}.\r
+                * @returns {Object} {@link #locations}.\r
+                */\r
+               locate: ( function() {\r
+                       function locateSibling( rel, type ) {\r
+                               var sib = rel.element[ type === CKEDITOR.LINEUTILS_BEFORE ? 'getPrevious' : 'getNext' ]();\r
+\r
+                               // Return the middle point between siblings.\r
+                               if ( sib && isStatic( sib ) ) {\r
+                                       rel.siblingRect = sib.getClientRect();\r
+\r
+                                       if ( type == CKEDITOR.LINEUTILS_BEFORE ) {\r
+                                               return ( rel.siblingRect.bottom + rel.elementRect.top ) / 2;\r
+                                       } else {\r
+                                               return ( rel.elementRect.bottom + rel.siblingRect.top ) / 2;\r
+                                       }\r
+                               }\r
+\r
+                               // If there's no sibling, use the edge of an element.\r
+                               else {\r
+                                       if ( type == CKEDITOR.LINEUTILS_BEFORE ) {\r
+                                               return rel.elementRect.top;\r
+                                       } else {\r
+                                               return rel.elementRect.bottom;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       return function( relations ) {\r
+                               var rel;\r
+\r
+                               this.locations = {};\r
+\r
+                               for ( var uid in relations ) {\r
+                                       rel = relations[ uid ];\r
+                                       rel.elementRect = rel.element.getClientRect();\r
+\r
+                                       if ( is( rel.type, CKEDITOR.LINEUTILS_BEFORE ) ) {\r
+                                               this.store( uid, CKEDITOR.LINEUTILS_BEFORE, locateSibling( rel, CKEDITOR.LINEUTILS_BEFORE ) );\r
+                                       }\r
+\r
+                                       if ( is( rel.type, CKEDITOR.LINEUTILS_AFTER ) ) {\r
+                                               this.store( uid, CKEDITOR.LINEUTILS_AFTER, locateSibling( rel, CKEDITOR.LINEUTILS_AFTER ) );\r
+                                       }\r
+\r
+                                       // The middle point of the element.\r
+                                       if ( is( rel.type, CKEDITOR.LINEUTILS_INSIDE ) ) {\r
+                                               this.store( uid, CKEDITOR.LINEUTILS_INSIDE, ( rel.elementRect.top + rel.elementRect.bottom ) / 2 );\r
+                                       }\r
+                               }\r
+\r
+                               return this.locations;\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Calculates distances from every location to given vertical coordinate\r
+                * and sorts locations according to that distance.\r
+                *\r
+                * @param {Number} y The vertical coordinate used for sorting, used as a reference.\r
+                * @param {Number} [howMany] Determines the number of "closest locations" to be returned.\r
+                * @returns {Array} Sorted, array representation of {@link #locations}.\r
+                */\r
+               sort: ( function() {\r
+                       var locations, sorted,\r
+                               dist, i;\r
+\r
+                       function distance( y, uid, type ) {\r
+                               return Math.abs( y - locations[ uid ][ type ] );\r
+                       }\r
+\r
+                       return function( y, howMany ) {\r
+                               locations = this.locations;\r
+                               sorted = [];\r
+\r
+                               for ( var uid in locations ) {\r
+                                       for ( var type in locations[ uid ] ) {\r
+                                               dist = distance( y, uid, type );\r
+\r
+                                               // An array is empty.\r
+                                               if ( !sorted.length ) {\r
+                                                       sorted.push( { uid: +uid, type: type, dist: dist } );\r
+                                               } else {\r
+                                                       // Sort the array on fly when it's populated.\r
+                                                       for ( i = 0; i < sorted.length; i++ ) {\r
+                                                               if ( dist < sorted[ i ].dist ) {\r
+                                                                       sorted.splice( i, 0, { uid: +uid, type: type, dist: dist } );\r
+                                                                       break;\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       // Nothing was inserted, so the distance is bigger than\r
+                                                       // any of already calculated: push to the end.\r
+                                                       if ( i == sorted.length ) {\r
+                                                               sorted.push( { uid: +uid, type: type, dist: dist } );\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               if ( typeof howMany != 'undefined' ) {\r
+                                       return sorted.slice( 0, howMany );\r
+                               } else {\r
+                                       return sorted;\r
+                               }\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Stores the location in a collection.\r
+                *\r
+                * @param {Number} uid Unique identifier of the relation.\r
+                * @param {Number} type One of `CKEDITOR.LINEUTILS_BEFORE`, `CKEDITOR.LINEUTILS_AFTER` and `CKEDITOR.LINEUTILS_INSIDE`.\r
+                * @param {Number} y Vertical position of the relation.\r
+                */\r
+               store: function( uid, type, y ) {\r
+                       if ( !this.locations[ uid ] ) {\r
+                               this.locations[ uid ] = {};\r
+                       }\r
+\r
+                       this.locations[ uid ][ type ] = y;\r
+               }\r
+\r
+               /**\r
+                * @readonly\r
+                * @property {Object} locations\r
+                */\r
+       };\r
+\r
+       var tipCss = {\r
+                       display: 'block',\r
+                       width: '0px',\r
+                       height: '0px',\r
+                       'border-color': 'transparent',\r
+                       'border-style': 'solid',\r
+                       position: 'absolute',\r
+                       top: '-6px'\r
+               },\r
+\r
+               lineStyle = {\r
+                       height: '0px',\r
+                       'border-top': '1px dashed red',\r
+                       position: 'absolute',\r
+                       'z-index': 9999\r
+               },\r
+\r
+               lineTpl =\r
+                       '<div data-cke-lineutils-line="1" class="cke_reset_all" style="{lineStyle}">' +\r
+                               '<span style="{tipLeftStyle}">&nbsp;</span>' +\r
+                               '<span style="{tipRightStyle}">&nbsp;</span>' +\r
+                       '</div>';\r
+\r
+       /**\r
+        * A utility that draws horizontal lines in DOM according to locations\r
+        * returned by CKEDITOR.plugins.lineutils.locator.\r
+        *\r
+        * @private\r
+        * @class CKEDITOR.plugins.lineutils.liner\r
+        * @constructor Creates a Liner class instance.\r
+        * @param {CKEDITOR.editor} editor Editor instance that Liner belongs to.\r
+        * @param {Object} def Liner's definition.\r
+        * @since 4.3\r
+        */\r
+       function Liner( editor, def ) {\r
+               var editable = editor.editable();\r
+\r
+               CKEDITOR.tools.extend( this, {\r
+                       editor: editor,\r
+                       editable: editable,\r
+                       inline: editable.isInline(),\r
+                       doc: editor.document,\r
+                       win: editor.window,\r
+                       container: CKEDITOR.document.getBody(),\r
+                       winTop: CKEDITOR.document.getWindow()\r
+               }, def, true );\r
+\r
+               this.hidden = {};\r
+               this.visible = {};\r
+\r
+               if ( !this.inline ) {\r
+                       this.frame = this.win.getFrame();\r
+               }\r
+\r
+               this.queryViewport();\r
+\r
+               // Callbacks must be wrapped. Otherwise they're not attached\r
+               // to global DOM objects (i.e. topmost window) for every editor\r
+               // because they're treated as duplicates. They belong to the\r
+               // same prototype shared among Liner instances.\r
+               var queryViewport = CKEDITOR.tools.bind( this.queryViewport, this ),\r
+                       hideVisible = CKEDITOR.tools.bind( this.hideVisible, this ),\r
+                       removeAll = CKEDITOR.tools.bind( this.removeAll, this );\r
+\r
+               editable.attachListener( this.winTop, 'resize', queryViewport );\r
+               editable.attachListener( this.winTop, 'scroll', queryViewport );\r
+\r
+               editable.attachListener( this.winTop, 'resize', hideVisible );\r
+               editable.attachListener( this.win, 'scroll', hideVisible );\r
+\r
+               editable.attachListener( this.inline ? editable : this.frame, 'mouseout', function( evt ) {\r
+                       var x = evt.data.$.clientX,\r
+                               y = evt.data.$.clientY;\r
+\r
+                       this.queryViewport();\r
+\r
+                       // Check if mouse is out of the element (iframe/editable).\r
+                       if ( x <= this.rect.left || x >= this.rect.right || y <= this.rect.top || y >= this.rect.bottom ) {\r
+                               this.hideVisible();\r
+                       }\r
+\r
+                       // Check if mouse is out of the top-window vieport.\r
+                       if ( x <= 0 || x >= this.winTopPane.width || y <= 0 || y >= this.winTopPane.height ) {\r
+                               this.hideVisible();\r
+                       }\r
+               }, this );\r
+\r
+               editable.attachListener( editor, 'resize', queryViewport );\r
+               editable.attachListener( editor, 'mode', removeAll );\r
+               editor.on( 'destroy', removeAll );\r
+\r
+               this.lineTpl = new CKEDITOR.template( lineTpl ).output( {\r
+                       lineStyle: CKEDITOR.tools.writeCssText(\r
+                               CKEDITOR.tools.extend( {}, lineStyle, this.lineStyle, true )\r
+                       ),\r
+                       tipLeftStyle: CKEDITOR.tools.writeCssText(\r
+                               CKEDITOR.tools.extend( {}, tipCss, {\r
+                                       left: '0px',\r
+                                       'border-left-color': 'red',\r
+                                       'border-width': '6px 0 6px 6px'\r
+                               }, this.tipCss, this.tipLeftStyle, true )\r
+                       ),\r
+                       tipRightStyle: CKEDITOR.tools.writeCssText(\r
+                               CKEDITOR.tools.extend( {}, tipCss, {\r
+                                       right: '0px',\r
+                                       'border-right-color': 'red',\r
+                                       'border-width': '6px 6px 6px 0'\r
+                               }, this.tipCss, this.tipRightStyle, true )\r
+                       )\r
+               } );\r
+       }\r
+\r
+       Liner.prototype = {\r
+               /**\r
+                * Permanently removes all lines (both hidden and visible) from DOM.\r
+                */\r
+               removeAll: function() {\r
+                       var l;\r
+\r
+                       for ( l in this.hidden ) {\r
+                               this.hidden[ l ].remove();\r
+                               delete this.hidden[ l ];\r
+                       }\r
+\r
+                       for ( l in this.visible ) {\r
+                               this.visible[ l ].remove();\r
+                               delete this.visible[ l ];\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Hides a given line.\r
+                *\r
+                * @param {CKEDITOR.dom.element} line The line to be hidden.\r
+                */\r
+               hideLine: function( line ) {\r
+                       var uid = line.getUniqueId();\r
+\r
+                       line.hide();\r
+\r
+                       this.hidden[ uid ] = line;\r
+                       delete this.visible[ uid ];\r
+               },\r
+\r
+               /**\r
+                * Shows a given line.\r
+                *\r
+                * @param {CKEDITOR.dom.element} line The line to be shown.\r
+                */\r
+               showLine: function( line ) {\r
+                       var uid = line.getUniqueId();\r
+\r
+                       line.show();\r
+\r
+                       this.visible[ uid ] = line;\r
+                       delete this.hidden[ uid ];\r
+               },\r
+\r
+               /**\r
+                * Hides all visible lines.\r
+                */\r
+               hideVisible: function() {\r
+                       for ( var l in this.visible ) {\r
+                               this.hideLine( this.visible[ l ] );\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Shows a line at given location.\r
+                *\r
+                * @param {Object} location Location object containing the unique identifier of the relation\r
+                * and its type. Usually returned by {@link CKEDITOR.plugins.lineutils.locator#sort}.\r
+                * @param {Function} [callback] A callback to be called once the line is shown.\r
+                */\r
+               placeLine: function( location, callback ) {\r
+                       var styles, line, l;\r
+\r
+                       // No style means that line would be out of viewport.\r
+                       if ( !( styles = this.getStyle( location.uid, location.type ) ) ) {\r
+                               return;\r
+                       }\r
+\r
+                       // Search for any visible line of a different hash first.\r
+                       // It's faster to re-position visible line than to show it.\r
+                       for ( l in this.visible ) {\r
+                               if ( this.visible[ l ].getCustomData( 'hash' ) !== this.hash ) {\r
+                                       line = this.visible[ l ];\r
+                                       break;\r
+                               }\r
+                       }\r
+\r
+                       // Search for any hidden line of a different hash.\r
+                       if ( !line ) {\r
+                               for ( l in this.hidden ) {\r
+                                       if ( this.hidden[ l ].getCustomData( 'hash' ) !== this.hash ) {\r
+                                               this.showLine( ( line = this.hidden[ l ] ) );\r
+                                               break;\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       // If no line available, add the new one.\r
+                       if ( !line ) {\r
+                               this.showLine( ( line = this.addLine() ) );\r
+                       }\r
+\r
+                       // Mark the line with current hash.\r
+                       line.setCustomData( 'hash', this.hash );\r
+\r
+                       // Mark the line as visible.\r
+                       this.visible[ line.getUniqueId() ] = line;\r
+\r
+                       line.setStyles( styles );\r
+\r
+                       callback && callback( line );\r
+               },\r
+\r
+               /**\r
+                * Creates a style set to be used by the line, representing a particular\r
+                * relation (location).\r
+                *\r
+                * @param {Number} uid Unique identifier of the relation.\r
+                * @param {Number} type Type of the relation.\r
+                * @returns {Object} An object containing styles.\r
+                */\r
+               getStyle: function( uid, type ) {\r
+                       var rel = this.relations[ uid ],\r
+                               loc = this.locations[ uid ][ type ],\r
+                               styles = {},\r
+                               hdiff;\r
+\r
+                       // Line should be between two elements.\r
+                       if ( rel.siblingRect ) {\r
+                               styles.width = Math.max( rel.siblingRect.width, rel.elementRect.width );\r
+                       }\r
+                       // Line is relative to a single element.\r
+                       else {\r
+                               styles.width = rel.elementRect.width;\r
+                       }\r
+\r
+                       // Let's calculate the vertical position of the line.\r
+                       if ( this.inline ) {\r
+                               // (#13155)\r
+                               styles.top = loc + this.winTopScroll.y - this.rect.relativeY;\r
+                       } else {\r
+                               styles.top = this.rect.top + this.winTopScroll.y + loc;\r
+                       }\r
+\r
+                       // Check if line would be vertically out of the viewport.\r
+                       if ( styles.top - this.winTopScroll.y < this.rect.top || styles.top - this.winTopScroll.y > this.rect.bottom ) {\r
+                               return false;\r
+                       }\r
+\r
+                       // Now let's calculate the horizontal alignment (left and width).\r
+                       if ( this.inline ) {\r
+                               // (#13155)\r
+                               styles.left = rel.elementRect.left - this.rect.relativeX;\r
+                       } else {\r
+                               if ( rel.elementRect.left > 0 )\r
+                                       styles.left = this.rect.left + rel.elementRect.left;\r
+\r
+                               // H-scroll case. Left edge of element may be out of viewport.\r
+                               else {\r
+                                       styles.width += rel.elementRect.left;\r
+                                       styles.left = this.rect.left;\r
+                               }\r
+\r
+                               // H-scroll case. Right edge of element may be out of viewport.\r
+                               if ( ( hdiff = styles.left + styles.width - ( this.rect.left + this.winPane.width ) ) > 0 ) {\r
+                                       styles.width -= hdiff;\r
+                               }\r
+                       }\r
+\r
+                       // Finally include horizontal scroll of the global window.\r
+                       styles.left += this.winTopScroll.x;\r
+\r
+                       // Append 'px' to style values.\r
+                       for ( var style in styles ) {\r
+                               styles[ style ] = CKEDITOR.tools.cssLength( styles[ style ] );\r
+                       }\r
+\r
+                       return styles;\r
+               },\r
+\r
+               /**\r
+                * Adds a new line to DOM.\r
+                *\r
+                * @returns {CKEDITOR.dom.element} A brand-new line.\r
+                */\r
+               addLine: function() {\r
+                       var line = CKEDITOR.dom.element.createFromHtml( this.lineTpl );\r
+\r
+                       line.appendTo( this.container );\r
+\r
+                       return line;\r
+               },\r
+\r
+               /**\r
+                * Assigns a unique hash to the instance that is later used\r
+                * to tell unwanted lines from new ones. This method **must** be called\r
+                * before a new set of relations is to be visualized so {@link #cleanup}\r
+                * eventually hides obsolete lines. This is because lines\r
+                * are re-used between {@link #placeLine} calls and the number of\r
+                * necessary ones may vary depending on the number of relations.\r
+                *\r
+                * @param {Object} relations {@link CKEDITOR.plugins.lineutils.finder#relations}.\r
+                * @param {Object} locations {@link CKEDITOR.plugins.lineutils.locator#locations}.\r
+                */\r
+               prepare: function( relations, locations ) {\r
+                       this.relations = relations;\r
+                       this.locations = locations;\r
+                       this.hash = Math.random();\r
+               },\r
+\r
+               /**\r
+                * Hides all visible lines that do not belong to current hash\r
+                * and no longer represent relations (locations).\r
+                *\r
+                * See also: {@link #prepare}.\r
+                */\r
+               cleanup: function() {\r
+                       var line;\r
+\r
+                       for ( var l in this.visible ) {\r
+                               line = this.visible[ l ];\r
+\r
+                               if ( line.getCustomData( 'hash' ) !== this.hash ) {\r
+                                       this.hideLine( line );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Queries dimensions of the viewport, editable, frame etc.\r
+                * that are used for correct positioning of the line.\r
+                */\r
+               queryViewport: function() {\r
+                       this.winPane = this.win.getViewPaneSize();\r
+                       this.winTopScroll = this.winTop.getScrollPosition();\r
+                       this.winTopPane = this.winTop.getViewPaneSize();\r
+\r
+                       // (#13155)\r
+                       this.rect = this.getClientRect( this.inline ? this.editable : this.frame );\r
+               },\r
+\r
+               /**\r
+                * Returns `boundingClientRect` of an element, shifted by the position\r
+                * of `container` when the container is not `static` (#13155).\r
+                *\r
+                * See also: {@link CKEDITOR.dom.element#getClientRect}.\r
+                *\r
+                * @param {CKEDITOR.dom.element} el A DOM element.\r
+                * @returns {Object} A shifted rect, extended by `relativeY` and `relativeX` properties.\r
+                */\r
+               getClientRect: function( el ) {\r
+                       var rect = el.getClientRect(),\r
+                               relativeContainerDocPosition = this.container.getDocumentPosition(),\r
+                               relativeContainerComputedPosition = this.container.getComputedStyle( 'position' );\r
+\r
+                       // Static or not, those values are used to offset the position of the line so they cannot be undefined.\r
+                       rect.relativeX = rect.relativeY = 0;\r
+\r
+                       if ( relativeContainerComputedPosition != 'static' ) {\r
+                               // Remember the offset used to shift the clientRect.\r
+                               rect.relativeY = relativeContainerDocPosition.y;\r
+                               rect.relativeX = relativeContainerDocPosition.x;\r
+\r
+                               rect.top -= rect.relativeY;\r
+                               rect.bottom -= rect.relativeY;\r
+                               rect.left -= rect.relativeX;\r
+                               rect.right -= rect.relativeX;\r
+                       }\r
+\r
+                       return rect;\r
+               }\r
+       };\r
+\r
+       function is( type, flag ) {\r
+               return type & flag;\r
+       }\r
+\r
+       var floats = { left: 1, right: 1, center: 1 },\r
+               positions = { absolute: 1, fixed: 1 };\r
+\r
+       function isElement( node ) {\r
+               return node && node.type == CKEDITOR.NODE_ELEMENT;\r
+       }\r
+\r
+       function isFloated( el ) {\r
+               return !!( floats[ el.getComputedStyle( 'float' ) ] || floats[ el.getAttribute( 'align' ) ] );\r
+       }\r
+\r
+       function isPositioned( el ) {\r
+               return !!positions[ el.getComputedStyle( 'position' ) ];\r
+       }\r
+\r
+       function isLimit( node ) {\r
+               return isElement( node ) && node.getAttribute( 'contenteditable' ) == 'true';\r
+       }\r
+\r
+       function isStatic( node ) {\r
+               return isElement( node ) && !isFloated( node ) && !isPositioned( node );\r
+       }\r
+\r
+       /**\r
+        * Global namespace storing definitions and global helpers for the Line Utilities plugin.\r
+        *\r
+        * @private\r
+        * @class\r
+        * @singleton\r
+        * @since 4.3\r
+        */\r
+       CKEDITOR.plugins.lineutils = {\r
+               finder: Finder,\r
+               locator: Locator,\r
+               liner: Liner\r
+       };\r
+} )();\r
diff --git a/sources/plugins/link/dialogs/anchor.js b/sources/plugins/link/dialogs/anchor.js
new file mode 100644 (file)
index 0000000..2b32b71
--- /dev/null
@@ -0,0 +1,105 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.dialog.add( 'anchor', function( editor ) {\r
+       // Function called in onShow to load selected element.\r
+       var loadElements = function( element ) {\r
+                       this._.selectedElement = element;\r
+\r
+                       var attributeValue = element.data( 'cke-saved-name' );\r
+                       this.setValueOf( 'info', 'txtName', attributeValue || '' );\r
+               };\r
+\r
+       function createFakeAnchor( editor, attributes ) {\r
+               return editor.createFakeElement( editor.document.createElement( 'a', {\r
+                       attributes: attributes\r
+               } ), 'cke_anchor', 'anchor' );\r
+       }\r
+\r
+       return {\r
+               title: editor.lang.link.anchor.title,\r
+               minWidth: 300,\r
+               minHeight: 60,\r
+               onOk: function() {\r
+                       var name = CKEDITOR.tools.trim( this.getValueOf( 'info', 'txtName' ) );\r
+                       var attributes = {\r
+                               id: name,\r
+                               name: name,\r
+                               'data-cke-saved-name': name\r
+                       };\r
+\r
+                       if ( this._.selectedElement ) {\r
+                               if ( this._.selectedElement.data( 'cke-realelement' ) ) {\r
+                                       var newFake = createFakeAnchor( editor, attributes );\r
+                                       newFake.replace( this._.selectedElement );\r
+\r
+                                       // Selecting fake element for IE. (#11377)\r
+                                       if ( CKEDITOR.env.ie )\r
+                                               editor.getSelection().selectElement( newFake );\r
+                               } else {\r
+                                       this._.selectedElement.setAttributes( attributes );\r
+                               }\r
+                       } else {\r
+                               var sel = editor.getSelection(),\r
+                                       range = sel && sel.getRanges()[ 0 ];\r
+\r
+                               // Empty anchor\r
+                               if ( range.collapsed ) {\r
+                                       var anchor = createFakeAnchor( editor, attributes );\r
+                                       range.insertNode( anchor );\r
+                               } else {\r
+                                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+                                               attributes[ 'class' ] = 'cke_anchor';\r
+\r
+                                       // Apply style.\r
+                                       var style = new CKEDITOR.style( { element: 'a', attributes: attributes } );\r
+                                       style.type = CKEDITOR.STYLE_INLINE;\r
+                                       editor.applyStyle( style );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               onHide: function() {\r
+                       delete this._.selectedElement;\r
+               },\r
+\r
+               onShow: function() {\r
+                       var sel = editor.getSelection(),\r
+                               fullySelected = sel.getSelectedElement(),\r
+                               fakeSelected = fullySelected && fullySelected.data( 'cke-realelement' ),\r
+                               linkElement = fakeSelected ?\r
+                                       CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, fullySelected ) :\r
+                                       CKEDITOR.plugins.link.getSelectedLink( editor );\r
+\r
+                       if ( linkElement ) {\r
+                               loadElements.call( this, linkElement );\r
+                               !fakeSelected && sel.selectElement( linkElement );\r
+\r
+                               if ( fullySelected )\r
+                                       this._.selectedElement = fullySelected;\r
+                       }\r
+\r
+                       this.getContentElement( 'info', 'txtName' ).focus();\r
+               },\r
+               contents: [ {\r
+                       id: 'info',\r
+                       label: editor.lang.link.anchor.title,\r
+                       accessKey: 'I',\r
+                       elements: [ {\r
+                               type: 'text',\r
+                               id: 'txtName',\r
+                               label: editor.lang.link.anchor.name,\r
+                               required: true,\r
+                               validate: function() {\r
+                                       if ( !this.getValue() ) {\r
+                                               alert( editor.lang.link.anchor.errorName ); // jshint ignore:line\r
+                                               return false;\r
+                                       }\r
+                                       return true;\r
+                               }\r
+                       } ]\r
+               } ]\r
+       };\r
+} );\r
diff --git a/sources/plugins/link/dialogs/link.js b/sources/plugins/link/dialogs/link.js
new file mode 100644 (file)
index 0000000..914471f
--- /dev/null
@@ -0,0 +1,979 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       CKEDITOR.dialog.add( 'link', function( editor ) {\r
+               var plugin = CKEDITOR.plugins.link,\r
+                       initialLinkText;\r
+\r
+               // Handles the event when the "Target" selection box is changed.\r
+               var targetChanged = function() {\r
+                               var dialog = this.getDialog(),\r
+                                       popupFeatures = dialog.getContentElement( 'target', 'popupFeatures' ),\r
+                                       targetName = dialog.getContentElement( 'target', 'linkTargetName' ),\r
+                                       value = this.getValue();\r
+\r
+                               if ( !popupFeatures || !targetName )\r
+                                       return;\r
+\r
+                               popupFeatures = popupFeatures.getElement();\r
+                               popupFeatures.hide();\r
+                               targetName.setValue( '' );\r
+\r
+                               switch ( value ) {\r
+                                       case 'frame':\r
+                                               targetName.setLabel( editor.lang.link.targetFrameName );\r
+                                               targetName.getElement().show();\r
+                                               break;\r
+                                       case 'popup':\r
+                                               popupFeatures.show();\r
+                                               targetName.setLabel( editor.lang.link.targetPopupName );\r
+                                               targetName.getElement().show();\r
+                                               break;\r
+                                       default:\r
+                                               targetName.setValue( value );\r
+                                               targetName.getElement().hide();\r
+                                               break;\r
+                               }\r
+\r
+                       };\r
+\r
+               // Handles the event when the "Type" selection box is changed.\r
+               var linkTypeChanged = function() {\r
+                               var dialog = this.getDialog(),\r
+                                       partIds = [ 'urlOptions', 'anchorOptions', 'emailOptions' ],\r
+                                       typeValue = this.getValue(),\r
+                                       uploadTab = dialog.definition.getContents( 'upload' ),\r
+                                       uploadInitiallyHidden = uploadTab && uploadTab.hidden;\r
+\r
+                               if ( typeValue == 'url' ) {\r
+                                       if ( editor.config.linkShowTargetTab )\r
+                                               dialog.showPage( 'target' );\r
+                                       if ( !uploadInitiallyHidden )\r
+                                               dialog.showPage( 'upload' );\r
+                               } else {\r
+                                       dialog.hidePage( 'target' );\r
+                                       if ( !uploadInitiallyHidden )\r
+                                               dialog.hidePage( 'upload' );\r
+                               }\r
+\r
+                               for ( var i = 0; i < partIds.length; i++ ) {\r
+                                       var element = dialog.getContentElement( 'info', partIds[ i ] );\r
+                                       if ( !element )\r
+                                               continue;\r
+\r
+                                       element = element.getElement().getParent().getParent();\r
+                                       if ( partIds[ i ] == typeValue + 'Options' )\r
+                                               element.show();\r
+                                       else\r
+                                               element.hide();\r
+                               }\r
+\r
+                               dialog.layout();\r
+                       };\r
+\r
+               var setupParams = function( page, data ) {\r
+                               if ( data[ page ] )\r
+                                       this.setValue( data[ page ][ this.id ] || '' );\r
+                       };\r
+\r
+               var setupPopupParams = function( data ) {\r
+                               return setupParams.call( this, 'target', data );\r
+                       };\r
+\r
+               var setupAdvParams = function( data ) {\r
+                               return setupParams.call( this, 'advanced', data );\r
+                       };\r
+\r
+               var commitParams = function( page, data ) {\r
+                               if ( !data[ page ] )\r
+                                       data[ page ] = {};\r
+\r
+                               data[ page ][ this.id ] = this.getValue() || '';\r
+                       };\r
+\r
+               var commitPopupParams = function( data ) {\r
+                               return commitParams.call( this, 'target', data );\r
+                       };\r
+\r
+               var commitAdvParams = function( data ) {\r
+                               return commitParams.call( this, 'advanced', data );\r
+                       };\r
+\r
+               var commonLang = editor.lang.common,\r
+                       linkLang = editor.lang.link,\r
+                       anchors;\r
+\r
+               return {\r
+                       title: linkLang.title,\r
+                       minWidth: ( CKEDITOR.skinName || editor.config.skin ) == 'moono-lisa' ? 450 : 350,\r
+                       minHeight: 240,\r
+                       contents: [ {\r
+                               id: 'info',\r
+                               label: linkLang.info,\r
+                               title: linkLang.info,\r
+                               elements: [ {\r
+                                       type: 'text',\r
+                                       id: 'linkDisplayText',\r
+                                       label: linkLang.displayText,\r
+                                       setup: function() {\r
+                                               this.enable();\r
+\r
+                                               this.setValue( editor.getSelection().getSelectedText() );\r
+\r
+                                               // Keep inner text so that it can be compared in commit function. By obtaining value from getData()\r
+                                               // we get value stripped from new line chars which is important when comparing the value later on.\r
+                                               initialLinkText = this.getValue();\r
+                                       },\r
+                                       commit: function( data ) {\r
+                                               data.linkText = this.isEnabled() ? this.getValue() : '';\r
+                                       }\r
+                               },\r
+                               {\r
+                                       id: 'linkType',\r
+                                       type: 'select',\r
+                                       label: linkLang.type,\r
+                                       'default': 'url',\r
+                                       items: [\r
+                                               [ linkLang.toUrl, 'url' ],\r
+                                               [ linkLang.toAnchor, 'anchor' ],\r
+                                               [ linkLang.toEmail, 'email' ]\r
+                                       ],\r
+                                       onChange: linkTypeChanged,\r
+                                       setup: function( data ) {\r
+                                               this.setValue( data.type || 'url' );\r
+                                       },\r
+                                       commit: function( data ) {\r
+                                               data.type = this.getValue();\r
+                                       }\r
+                               },\r
+                               {\r
+                                       type: 'vbox',\r
+                                       id: 'urlOptions',\r
+                                       children: [ {\r
+                                               type: 'hbox',\r
+                                               widths: [ '25%', '75%' ],\r
+                                               children: [ {\r
+                                                       id: 'protocol',\r
+                                                       type: 'select',\r
+                                                       label: commonLang.protocol,\r
+                                                       'default': 'http://',\r
+                                                       items: [\r
+                                                               // Force 'ltr' for protocol names in BIDI. (#5433)\r
+                                                               [ 'http://\u200E', 'http://' ],\r
+                                                               [ 'https://\u200E', 'https://' ],\r
+                                                               [ 'ftp://\u200E', 'ftp://' ],\r
+                                                               [ 'news://\u200E', 'news://' ],\r
+                                                               [ linkLang.other, '' ]\r
+                                                       ],\r
+                                                       setup: function( data ) {\r
+                                                               if ( data.url )\r
+                                                                       this.setValue( data.url.protocol || '' );\r
+                                                       },\r
+                                                       commit: function( data ) {\r
+                                                               if ( !data.url )\r
+                                                                       data.url = {};\r
+\r
+                                                               data.url.protocol = this.getValue();\r
+                                                       }\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       id: 'url',\r
+                                                       label: commonLang.url,\r
+                                                       required: true,\r
+                                                       onLoad: function() {\r
+                                                               this.allowOnChange = true;\r
+                                                       },\r
+                                                       onKeyUp: function() {\r
+                                                               this.allowOnChange = false;\r
+                                                               var protocolCmb = this.getDialog().getContentElement( 'info', 'protocol' ),\r
+                                                                       url = this.getValue(),\r
+                                                                       urlOnChangeProtocol = /^(http|https|ftp|news):\/\/(?=.)/i,\r
+                                                                       urlOnChangeTestOther = /^((javascript:)|[#\/\.\?])/i;\r
+\r
+                                                               var protocol = urlOnChangeProtocol.exec( url );\r
+                                                               if ( protocol ) {\r
+                                                                       this.setValue( url.substr( protocol[ 0 ].length ) );\r
+                                                                       protocolCmb.setValue( protocol[ 0 ].toLowerCase() );\r
+                                                               } else if ( urlOnChangeTestOther.test( url ) ) {\r
+                                                                       protocolCmb.setValue( '' );\r
+                                                               }\r
+\r
+                                                               this.allowOnChange = true;\r
+                                                       },\r
+                                                       onChange: function() {\r
+                                                               if ( this.allowOnChange ) // Dont't call on dialog load.\r
+                                                               this.onKeyUp();\r
+                                                       },\r
+                                                       validate: function() {\r
+                                                               var dialog = this.getDialog();\r
+\r
+                                                               if ( dialog.getContentElement( 'info', 'linkType' ) && dialog.getValueOf( 'info', 'linkType' ) != 'url' )\r
+                                                                       return true;\r
+\r
+                                                               if ( !editor.config.linkJavaScriptLinksAllowed && ( /javascript\:/ ).test( this.getValue() ) ) {\r
+                                                                       alert( commonLang.invalidValue ); // jshint ignore:line\r
+                                                                       return false;\r
+                                                               }\r
+\r
+                                                               if ( this.getDialog().fakeObj ) // Edit Anchor.\r
+                                                               return true;\r
+\r
+                                                               var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noUrl );\r
+                                                               return func.apply( this );\r
+                                                       },\r
+                                                       setup: function( data ) {\r
+                                                               this.allowOnChange = false;\r
+                                                               if ( data.url )\r
+                                                                       this.setValue( data.url.url );\r
+                                                               this.allowOnChange = true;\r
+\r
+                                                       },\r
+                                                       commit: function( data ) {\r
+                                                               // IE will not trigger the onChange event if the mouse has been used\r
+                                                               // to carry all the operations #4724\r
+                                                               this.onChange();\r
+\r
+                                                               if ( !data.url )\r
+                                                                       data.url = {};\r
+\r
+                                                               data.url.url = this.getValue();\r
+                                                               this.allowOnChange = false;\r
+                                                       }\r
+                                               } ],\r
+                                               setup: function() {\r
+                                                       if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
+                                                               this.getElement().show();\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'button',\r
+                                               id: 'browse',\r
+                                               hidden: 'true',\r
+                                               filebrowser: 'info:url',\r
+                                               label: commonLang.browseServer\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'vbox',\r
+                                       id: 'anchorOptions',\r
+                                       width: 260,\r
+                                       align: 'center',\r
+                                       padding: 0,\r
+                                       children: [ {\r
+                                               type: 'fieldset',\r
+                                               id: 'selectAnchorText',\r
+                                               label: linkLang.selectAnchor,\r
+                                               setup: function() {\r
+                                                       anchors = plugin.getEditorAnchors( editor );\r
+\r
+                                                       this.getElement()[ anchors && anchors.length ? 'show' : 'hide' ]();\r
+                                               },\r
+                                               children: [ {\r
+                                                       type: 'hbox',\r
+                                                       id: 'selectAnchor',\r
+                                                       children: [ {\r
+                                                               type: 'select',\r
+                                                               id: 'anchorName',\r
+                                                               'default': '',\r
+                                                               label: linkLang.anchorName,\r
+                                                               style: 'width: 100%;',\r
+                                                               items: [\r
+                                                                       [ '' ]\r
+                                                               ],\r
+                                                               setup: function( data ) {\r
+                                                                       this.clear();\r
+                                                                       this.add( '' );\r
+\r
+                                                                       if ( anchors ) {\r
+                                                                               for ( var i = 0; i < anchors.length; i++ ) {\r
+                                                                                       if ( anchors[ i ].name )\r
+                                                                                               this.add( anchors[ i ].name );\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       if ( data.anchor )\r
+                                                                               this.setValue( data.anchor.name );\r
+\r
+                                                                       var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
+                                                                       if ( linkType && linkType.getValue() == 'email' )\r
+                                                                               this.focus();\r
+                                                               },\r
+                                                               commit: function( data ) {\r
+                                                                       if ( !data.anchor )\r
+                                                                               data.anchor = {};\r
+\r
+                                                                       data.anchor.name = this.getValue();\r
+                                                               }\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'select',\r
+                                                               id: 'anchorId',\r
+                                                               'default': '',\r
+                                                               label: linkLang.anchorId,\r
+                                                               style: 'width: 100%;',\r
+                                                               items: [\r
+                                                                       [ '' ]\r
+                                                               ],\r
+                                                               setup: function( data ) {\r
+                                                                       this.clear();\r
+                                                                       this.add( '' );\r
+\r
+                                                                       if ( anchors ) {\r
+                                                                               for ( var i = 0; i < anchors.length; i++ ) {\r
+                                                                                       if ( anchors[ i ].id )\r
+                                                                                               this.add( anchors[ i ].id );\r
+                                                                               }\r
+                                                                       }\r
+\r
+                                                                       if ( data.anchor )\r
+                                                                               this.setValue( data.anchor.id );\r
+                                                               },\r
+                                                               commit: function( data ) {\r
+                                                                       if ( !data.anchor )\r
+                                                                               data.anchor = {};\r
+\r
+                                                                       data.anchor.id = this.getValue();\r
+                                                               }\r
+                                                       } ],\r
+                                                       setup: function() {\r
+                                                               this.getElement()[ anchors && anchors.length ? 'show' : 'hide' ]();\r
+                                                       }\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'html',\r
+                                               id: 'noAnchors',\r
+                                               style: 'text-align: center;',\r
+                                               html: '<div role="note" tabIndex="-1">' + CKEDITOR.tools.htmlEncode( linkLang.noAnchors ) + '</div>',\r
+                                               // Focus the first element defined in above html.\r
+                                               focus: true,\r
+                                               setup: function() {\r
+                                                       this.getElement()[ anchors && anchors.length ? 'hide' : 'show' ]();\r
+                                               }\r
+                                       } ],\r
+                                       setup: function() {\r
+                                               if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
+                                                       this.getElement().hide();\r
+                                       }\r
+                               },\r
+                               {\r
+                                       type: 'vbox',\r
+                                       id: 'emailOptions',\r
+                                       padding: 1,\r
+                                       children: [ {\r
+                                               type: 'text',\r
+                                               id: 'emailAddress',\r
+                                               label: linkLang.emailAddress,\r
+                                               required: true,\r
+                                               validate: function() {\r
+                                                       var dialog = this.getDialog();\r
+\r
+                                                       if ( !dialog.getContentElement( 'info', 'linkType' ) || dialog.getValueOf( 'info', 'linkType' ) != 'email' )\r
+                                                               return true;\r
+\r
+                                                       var func = CKEDITOR.dialog.validate.notEmpty( linkLang.noEmail );\r
+                                                       return func.apply( this );\r
+                                               },\r
+                                               setup: function( data ) {\r
+                                                       if ( data.email )\r
+                                                               this.setValue( data.email.address );\r
+\r
+                                                       var linkType = this.getDialog().getContentElement( 'info', 'linkType' );\r
+                                                       if ( linkType && linkType.getValue() == 'email' )\r
+                                                               this.select();\r
+                                               },\r
+                                               commit: function( data ) {\r
+                                                       if ( !data.email )\r
+                                                               data.email = {};\r
+\r
+                                                       data.email.address = this.getValue();\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'text',\r
+                                               id: 'emailSubject',\r
+                                               label: linkLang.emailSubject,\r
+                                               setup: function( data ) {\r
+                                                       if ( data.email )\r
+                                                               this.setValue( data.email.subject );\r
+                                               },\r
+                                               commit: function( data ) {\r
+                                                       if ( !data.email )\r
+                                                               data.email = {};\r
+\r
+                                                       data.email.subject = this.getValue();\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'textarea',\r
+                                               id: 'emailBody',\r
+                                               label: linkLang.emailBody,\r
+                                               rows: 3,\r
+                                               'default': '',\r
+                                               setup: function( data ) {\r
+                                                       if ( data.email )\r
+                                                               this.setValue( data.email.body );\r
+                                               },\r
+                                               commit: function( data ) {\r
+                                                       if ( !data.email )\r
+                                                               data.email = {};\r
+\r
+                                                       data.email.body = this.getValue();\r
+                                               }\r
+                                       } ],\r
+                                       setup: function() {\r
+                                               if ( !this.getDialog().getContentElement( 'info', 'linkType' ) )\r
+                                                       this.getElement().hide();\r
+                                       }\r
+                               } ]\r
+                       },\r
+                       {\r
+                               id: 'target',\r
+                               requiredContent: 'a[target]', // This is not fully correct, because some target option requires JS.\r
+                               label: linkLang.target,\r
+                               title: linkLang.target,\r
+                               elements: [ {\r
+                                       type: 'hbox',\r
+                                       widths: [ '50%', '50%' ],\r
+                                       children: [ {\r
+                                               type: 'select',\r
+                                               id: 'linkTargetType',\r
+                                               label: commonLang.target,\r
+                                               'default': 'notSet',\r
+                                               style: 'width : 100%;',\r
+                                               'items': [\r
+                                                       [ commonLang.notSet, 'notSet' ],\r
+                                                       [ linkLang.targetFrame, 'frame' ],\r
+                                                       [ linkLang.targetPopup, 'popup' ],\r
+                                                       [ commonLang.targetNew, '_blank' ],\r
+                                                       [ commonLang.targetTop, '_top' ],\r
+                                                       [ commonLang.targetSelf, '_self' ],\r
+                                                       [ commonLang.targetParent, '_parent' ]\r
+                                               ],\r
+                                               onChange: targetChanged,\r
+                                               setup: function( data ) {\r
+                                                       if ( data.target )\r
+                                                               this.setValue( data.target.type || 'notSet' );\r
+                                                       targetChanged.call( this );\r
+                                               },\r
+                                               commit: function( data ) {\r
+                                                       if ( !data.target )\r
+                                                               data.target = {};\r
+\r
+                                                       data.target.type = this.getValue();\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               type: 'text',\r
+                                               id: 'linkTargetName',\r
+                                               label: linkLang.targetFrameName,\r
+                                               'default': '',\r
+                                               setup: function( data ) {\r
+                                                       if ( data.target )\r
+                                                               this.setValue( data.target.name );\r
+                                               },\r
+                                               commit: function( data ) {\r
+                                                       if ( !data.target )\r
+                                                               data.target = {};\r
+\r
+                                                       data.target.name = this.getValue().replace( /([^\x00-\x7F]|\s)/gi, '' );\r
+                                               }\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'vbox',\r
+                                       width: '100%',\r
+                                       align: 'center',\r
+                                       padding: 2,\r
+                                       id: 'popupFeatures',\r
+                                       children: [ {\r
+                                               type: 'fieldset',\r
+                                               label: linkLang.popupFeatures,\r
+                                               children: [ {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'resizable',\r
+                                                               label: linkLang.popupResizable,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'status',\r
+                                                               label: linkLang.popupStatusBar,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'location',\r
+                                                               label: linkLang.popupLocationBar,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'toolbar',\r
+                                                               label: linkLang.popupToolbar,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'menubar',\r
+                                                               label: linkLang.popupMenuBar,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'fullscreen',\r
+                                                               label: linkLang.popupFullScreen,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'scrollbars',\r
+                                                               label: linkLang.popupScrollBars,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'checkbox',\r
+                                                               id: 'dependent',\r
+                                                               label: linkLang.popupDependent,\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'text',\r
+                                                               widths: [ '50%', '50%' ],\r
+                                                               labelLayout: 'horizontal',\r
+                                                               label: commonLang.width,\r
+                                                               id: 'width',\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'text',\r
+                                                               labelLayout: 'horizontal',\r
+                                                               widths: [ '50%', '50%' ],\r
+                                                               label: linkLang.popupLeft,\r
+                                                               id: 'left',\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               },\r
+                                               {\r
+                                                       type: 'hbox',\r
+                                                       children: [ {\r
+                                                               type: 'text',\r
+                                                               labelLayout: 'horizontal',\r
+                                                               widths: [ '50%', '50%' ],\r
+                                                               label: commonLang.height,\r
+                                                               id: 'height',\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       },\r
+                                                       {\r
+                                                               type: 'text',\r
+                                                               labelLayout: 'horizontal',\r
+                                                               label: linkLang.popupTop,\r
+                                                               widths: [ '50%', '50%' ],\r
+                                                               id: 'top',\r
+                                                               setup: setupPopupParams,\r
+                                                               commit: commitPopupParams\r
+\r
+                                                       } ]\r
+                                               } ]\r
+                                       } ]\r
+                               } ]\r
+                       },\r
+                       {\r
+                               id: 'upload',\r
+                               label: linkLang.upload,\r
+                               title: linkLang.upload,\r
+                               hidden: true,\r
+                               filebrowser: 'uploadButton',\r
+                               elements: [ {\r
+                                       type: 'file',\r
+                                       id: 'upload',\r
+                                       label: commonLang.upload,\r
+                                       style: 'height:40px',\r
+                                       size: 29\r
+                               },\r
+                               {\r
+                                       type: 'fileButton',\r
+                                       id: 'uploadButton',\r
+                                       label: commonLang.uploadSubmit,\r
+                                       filebrowser: 'info:url',\r
+                                       'for': [ 'upload', 'upload' ]\r
+                               } ]\r
+                       },\r
+                       {\r
+                               id: 'advanced',\r
+                               label: linkLang.advanced,\r
+                               title: linkLang.advanced,\r
+                               elements: [ {\r
+                                       type: 'vbox',\r
+                                       padding: 1,\r
+                                       children: [ {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '35%', '20%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       id: 'advId',\r
+                                                       requiredContent: 'a[id]',\r
+                                                       label: linkLang.id,\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+                                               },\r
+                                               {\r
+                                                       type: 'select',\r
+                                                       id: 'advLangDir',\r
+                                                       requiredContent: 'a[dir]',\r
+                                                       label: linkLang.langDir,\r
+                                                       'default': '',\r
+                                                       style: 'width:110px',\r
+                                                       items: [\r
+                                                               [ commonLang.notSet, '' ],\r
+                                                               [ linkLang.langDirLTR, 'ltr' ],\r
+                                                               [ linkLang.langDirRTL, 'rtl' ]\r
+                                                       ],\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       id: 'advAccessKey',\r
+                                                       requiredContent: 'a[accesskey]',\r
+                                                       width: '80px',\r
+                                                       label: linkLang.acccessKey,\r
+                                                       maxLength: 1,\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '35%', '20%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.name,\r
+                                                       id: 'advName',\r
+                                                       requiredContent: 'a[name]',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.langCode,\r
+                                                       id: 'advLangCode',\r
+                                                       requiredContent: 'a[lang]',\r
+                                                       width: '110px',\r
+                                                       'default': '',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.tabIndex,\r
+                                                       id: 'advTabIndex',\r
+                                                       requiredContent: 'a[tabindex]',\r
+                                                       width: '80px',\r
+                                                       maxLength: 5,\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               } ]\r
+                                       } ]\r
+                               },\r
+                               {\r
+                                       type: 'vbox',\r
+                                       padding: 1,\r
+                                       children: [ {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '55%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.advisoryTitle,\r
+                                                       requiredContent: 'a[title]',\r
+                                                       'default': '',\r
+                                                       id: 'advTitle',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.advisoryContentType,\r
+                                                       requiredContent: 'a[type]',\r
+                                                       'default': '',\r
+                                                       id: 'advContentType',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '55%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.cssClasses,\r
+                                                       requiredContent: 'a(cke-xyz)', // Random text like 'xyz' will check if all are allowed.\r
+                                                       'default': '',\r
+                                                       id: 'advCSSClasses',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.charset,\r
+                                                       requiredContent: 'a[charset]',\r
+                                                       'default': '',\r
+                                                       id: 'advCharset',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '55%' ],\r
+                                               children: [ {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.rel,\r
+                                                       requiredContent: 'a[rel]',\r
+                                                       'default': '',\r
+                                                       id: 'advRel',\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+                                               },\r
+                                               {\r
+                                                       type: 'text',\r
+                                                       label: linkLang.styles,\r
+                                                       requiredContent: 'a{cke-xyz}', // Random text like 'xyz' will check if all are allowed.\r
+                                                       'default': '',\r
+                                                       id: 'advStyles',\r
+                                                       validate: CKEDITOR.dialog.validate.inlineStyle( editor.lang.common.invalidInlineStyle ),\r
+                                                       setup: setupAdvParams,\r
+                                                       commit: commitAdvParams\r
+                                               } ]\r
+                                       },\r
+                                       {\r
+                                               type: 'hbox',\r
+                                               widths: [ '45%', '55%' ],\r
+                                               children: [ {\r
+                                                       type: 'checkbox',\r
+                                                       id: 'download',\r
+                                                       requiredContent: 'a[download]',\r
+                                                       label: linkLang.download,\r
+                                                       setup: function( data ) {\r
+                                                               if ( data.download !== undefined )\r
+                                                                       this.setValue( 'checked', 'checked' );\r
+                                                       },\r
+                                                       commit: function( data ) {\r
+                                                               if ( this.getValue() ) {\r
+                                                                       data.download = this.getValue();\r
+                                                               }\r
+                                                       }\r
+                                               } ]\r
+                                       } ]\r
+                               } ]\r
+                       } ],\r
+                       onShow: function() {\r
+                               var editor = this.getParentEditor(),\r
+                                       selection = editor.getSelection(),\r
+                                       selectedElement = selection.getSelectedElement(),\r
+                                       displayTextField = this.getContentElement( 'info', 'linkDisplayText' ).getElement().getParent().getParent(),\r
+                                       element = null;\r
+\r
+                               // Fill in all the relevant fields if there's already one link selected.\r
+                               if ( ( element = plugin.getSelectedLink( editor ) ) && element.hasAttribute( 'href' ) ) {\r
+                                       // Don't change selection if some element is already selected.\r
+                                       // For example - don't destroy fake selection.\r
+                                       if ( !selectedElement ) {\r
+                                               selection.selectElement( element );\r
+                                               selectedElement = element;\r
+                                       }\r
+                               } else {\r
+                                       element = null;\r
+                               }\r
+\r
+                               // Here we'll decide whether or not we want to show Display Text field.\r
+                               if ( plugin.showDisplayTextForElement( selectedElement, editor ) ) {\r
+                                       displayTextField.show();\r
+                               } else {\r
+                                       displayTextField.hide();\r
+                               }\r
+\r
+                               var data = plugin.parseLinkAttributes( editor, element );\r
+\r
+                               // Record down the selected element in the dialog.\r
+                               this._.selectedElement = element;\r
+\r
+                               this.setupContent( data );\r
+                       },\r
+                       onOk: function() {\r
+                               var data = {};\r
+\r
+                               // Collect data from fields.\r
+                               this.commitContent( data );\r
+\r
+                               var selection = editor.getSelection(),\r
+                                       attributes = plugin.getLinkAttributes( editor, data ),\r
+                                       bm,\r
+                                       nestedLinks;\r
+\r
+                               if ( !this._.selectedElement ) {\r
+                                       var range = selection.getRanges()[ 0 ],\r
+                                               text;\r
+\r
+                                       // Use link URL as text with a collapsed cursor.\r
+                                       if ( range.collapsed ) {\r
+                                               // Short mailto link text view (#5736).\r
+                                               text = new CKEDITOR.dom.text( data.linkText || ( data.type == 'email' ?\r
+                                                       data.email.address : attributes.set[ 'data-cke-saved-href' ] ), editor.document );\r
+                                               range.insertNode( text );\r
+                                               range.selectNodeContents( text );\r
+                                       } else if ( initialLinkText !== data.linkText ) {\r
+                                               text = new CKEDITOR.dom.text( data.linkText, editor.document );\r
+\r
+                                               // Shrink range to preserve block element.\r
+                                               range.shrink( CKEDITOR.SHRINK_TEXT );\r
+\r
+                                               // Use extractHtmlFromRange to remove markup within the selection. Also this method is a little\r
+                                               // smarter than range#deleteContents as it plays better e.g. with table cells.\r
+                                               editor.editable().extractHtmlFromRange( range );\r
+\r
+                                               range.insertNode( text );\r
+                                       }\r
+\r
+                                       // Editable links nested within current range should be removed, so that the link is applied to whole selection.\r
+                                       nestedLinks = range._find( 'a' );\r
+\r
+                                       for     ( var i = 0; i < nestedLinks.length; i++ ) {\r
+                                               nestedLinks[ i ].remove( true );\r
+                                       }\r
+\r
+                                       // Apply style.\r
+                                       var style = new CKEDITOR.style( {\r
+                                               element: 'a',\r
+                                               attributes: attributes.set\r
+                                       } );\r
+\r
+                                       style.type = CKEDITOR.STYLE_INLINE; // need to override... dunno why.\r
+                                       style.applyToRange( range, editor );\r
+                                       range.select();\r
+                               } else {\r
+                                       // We're only editing an existing link, so just overwrite the attributes.\r
+                                       var element = this._.selectedElement,\r
+                                               href = element.data( 'cke-saved-href' ),\r
+                                               textView = element.getHtml(),\r
+                                               newText;\r
+\r
+                                       element.setAttributes( attributes.set );\r
+                                       element.removeAttributes( attributes.removed );\r
+\r
+                                       if ( data.linkText && initialLinkText != data.linkText ) {\r
+                                               // Display text has been changed.\r
+                                               newText = data.linkText;\r
+                                       } else if ( href == textView || data.type == 'email' && textView.indexOf( '@' ) != -1 ) {\r
+                                               // Update text view when user changes protocol (#4612).\r
+                                               // Short mailto link text view (#5736).\r
+                                               newText = data.type == 'email' ? data.email.address : attributes.set[ 'data-cke-saved-href' ];\r
+                                       }\r
+\r
+                                       if ( newText ) {\r
+                                               element.setText( newText );\r
+                                               // We changed the content, so need to select it again.\r
+                                               selection.selectElement( element );\r
+                                       }\r
+\r
+                                       delete this._.selectedElement;\r
+                               }\r
+                       },\r
+                       onLoad: function() {\r
+                               if ( !editor.config.linkShowAdvancedTab )\r
+                                       this.hidePage( 'advanced' ); //Hide Advanded tab.\r
+\r
+                               if ( !editor.config.linkShowTargetTab )\r
+                                       this.hidePage( 'target' ); //Hide Target tab.\r
+                       },\r
+                       // Inital focus on 'url' field if link is of type URL.\r
+                       onFocus: function() {\r
+                               var linkType = this.getContentElement( 'info', 'linkType' ),\r
+                                       urlField;\r
+\r
+                               if ( linkType && linkType.getValue() == 'url' ) {\r
+                                       urlField = this.getContentElement( 'info', 'url' );\r
+                                       urlField.select();\r
+                               }\r
+                       }\r
+               };\r
+       } );\r
+} )();\r
+// jscs:disable maximumLineLength\r
+/**\r
+ * The e-mail address anti-spam protection option. The protection will be\r
+ * applied when creating or modifying e-mail links through the editor interface.\r
+ *\r
+ * Two methods of protection can be chosen:\r
+ *\r
+ * 1. The e-mail parts (name, domain, and any other query string) are\r
+ *     assembled into a function call pattern. Such function must be\r
+ *     provided by the developer in the pages that will use the contents.\r
+ * 2. Only the e-mail address is obfuscated into a special string that\r
+ *     has no meaning for humans or spam bots, but which is properly\r
+ *     rendered and accepted by the browser.\r
+ *\r
+ * Both approaches require JavaScript to be enabled.\r
+ *\r
+ *             // href="mailto:tester@ckeditor.com?subject=subject&body=body"\r
+ *             config.emailProtection = '';\r
+ *\r
+ *             // href="<a href=\"javascript:void(location.href=\'mailto:\'+String.fromCharCode(116,101,115,116,101,114,64,99,107,101,100,105,116,111,114,46,99,111,109)+\'?subject=subject&body=body\')\">e-mail</a>"\r
+ *             config.emailProtection = 'encode';\r
+ *\r
+ *             // href="javascript:mt('tester','ckeditor.com','subject','body')"\r
+ *             config.emailProtection = 'mt(NAME,DOMAIN,SUBJECT,BODY)';\r
+ *\r
+ * @since 3.1\r
+ * @cfg {String} [emailProtection='' (empty string = disabled)]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/link/icons/anchor-rtl.png b/sources/plugins/link/icons/anchor-rtl.png
new file mode 100644 (file)
index 0000000..b068855
Binary files /dev/null and b/sources/plugins/link/icons/anchor-rtl.png differ
diff --git a/sources/plugins/link/icons/anchor.png b/sources/plugins/link/icons/anchor.png
new file mode 100644 (file)
index 0000000..e50d6cd
Binary files /dev/null and b/sources/plugins/link/icons/anchor.png differ
diff --git a/sources/plugins/link/icons/hidpi/anchor-rtl.png b/sources/plugins/link/icons/hidpi/anchor-rtl.png
new file mode 100644 (file)
index 0000000..3533c38
Binary files /dev/null and b/sources/plugins/link/icons/hidpi/anchor-rtl.png differ
diff --git a/sources/plugins/link/icons/hidpi/anchor.png b/sources/plugins/link/icons/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..99eeadd
Binary files /dev/null and b/sources/plugins/link/icons/hidpi/anchor.png differ
diff --git a/sources/plugins/link/icons/hidpi/link.png b/sources/plugins/link/icons/hidpi/link.png
new file mode 100644 (file)
index 0000000..43ce99e
Binary files /dev/null and b/sources/plugins/link/icons/hidpi/link.png differ
diff --git a/sources/plugins/link/icons/hidpi/unlink.png b/sources/plugins/link/icons/hidpi/unlink.png
new file mode 100644 (file)
index 0000000..8ace29d
Binary files /dev/null and b/sources/plugins/link/icons/hidpi/unlink.png differ
diff --git a/sources/plugins/link/icons/link.png b/sources/plugins/link/icons/link.png
new file mode 100644 (file)
index 0000000..c2c450f
Binary files /dev/null and b/sources/plugins/link/icons/link.png differ
diff --git a/sources/plugins/link/icons/unlink.png b/sources/plugins/link/icons/unlink.png
new file mode 100644 (file)
index 0000000..c2f3f64
Binary files /dev/null and b/sources/plugins/link/icons/unlink.png differ
diff --git a/sources/plugins/link/images/anchor.png b/sources/plugins/link/images/anchor.png
new file mode 100644 (file)
index 0000000..d94adb4
Binary files /dev/null and b/sources/plugins/link/images/anchor.png differ
diff --git a/sources/plugins/link/images/hidpi/anchor.png b/sources/plugins/link/images/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..186c3e9
Binary files /dev/null and b/sources/plugins/link/images/hidpi/anchor.png differ
diff --git a/sources/plugins/link/lang/af.js b/sources/plugins/link/lang/af.js
new file mode 100644 (file)
index 0000000..3032beb
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'af', {\r
+       acccessKey: 'Toegangsleutel',\r
+       advanced: 'Gevorderd',\r
+       advisoryContentType: 'Aanbevole inhoudstipe',\r
+       advisoryTitle: 'Aanbevole titel',\r
+       anchor: {\r
+               toolbar: 'Anker byvoeg/verander',\r
+               menu: 'Anker-eienskappe',\r
+               title: 'Anker-eienskappe',\r
+               name: 'Ankernaam',\r
+               errorName: 'Voltooi die ankernaam asseblief',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'Op element Id',\r
+       anchorName: 'Op ankernaam',\r
+       charset: 'Karakterstel van geskakelde bron',\r
+       cssClasses: 'CSS klasse',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-posadres',\r
+       emailBody: 'Berig-inhoud',\r
+       emailSubject: 'Berig-onderwerp',\r
+       id: 'Id',\r
+       info: 'Skakel informasie',\r
+       langCode: 'Taalkode',\r
+       langDir: 'Skryfrigting',\r
+       langDirLTR: 'Links na regs (LTR)',\r
+       langDirRTL: 'Regs na links (RTL)',\r
+       menu: 'Wysig skakel',\r
+       name: 'Naam',\r
+       noAnchors: '(Geen ankers beskikbaar in dokument)',\r
+       noEmail: 'Gee die e-posadres',\r
+       noUrl: 'Gee die skakel se URL',\r
+       other: '<ander>',\r
+       popupDependent: 'Afhanklik (Netscape)',\r
+       popupFeatures: 'Eienskappe van opspringvenster',\r
+       popupFullScreen: 'Volskerm (IE)',\r
+       popupLeft: 'Posisie links',\r
+       popupLocationBar: 'Adresbalk',\r
+       popupMenuBar: 'Spyskaartbalk',\r
+       popupResizable: 'Herskaalbaar',\r
+       popupScrollBars: 'Skuifbalke',\r
+       popupStatusBar: 'Statusbalk',\r
+       popupToolbar: 'Werkbalk',\r
+       popupTop: 'Posisie bo',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Kies \'n anker',\r
+       styles: 'Styl',\r
+       tabIndex: 'Tab indeks',\r
+       target: 'Doel',\r
+       targetFrame: '<raam>',\r
+       targetFrameName: 'Naam van doelraam',\r
+       targetPopup: '<opspringvenster>',\r
+       targetPopupName: 'Naam van opspringvenster',\r
+       title: 'Skakel',\r
+       toAnchor: 'Anker in bladsy',\r
+       toEmail: 'E-pos',\r
+       toUrl: 'URL',\r
+       toolbar: 'Skakel invoeg/wysig',\r
+       type: 'Skakelsoort',\r
+       unlink: 'Verwyder skakel',\r
+       upload: 'Oplaai'\r
+} );\r
diff --git a/sources/plugins/link/lang/ar.js b/sources/plugins/link/lang/ar.js
new file mode 100644 (file)
index 0000000..e0dd0d9
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ar', {\r
+       acccessKey: 'مفاتيح الإختصار',\r
+       advanced: 'متقدم',\r
+       advisoryContentType: 'نوع التقرير',\r
+       advisoryTitle: 'عنوان التقرير',\r
+       anchor: {\r
+               toolbar: 'إشارة مرجعية',\r
+               menu: 'تحرير الإشارة المرجعية',\r
+               title: 'خصائص الإشارة المرجعية',\r
+               name: 'اسم الإشارة المرجعية',\r
+               errorName: 'الرجاء كتابة اسم الإشارة المرجعية',\r
+               remove: 'إزالة الإشارة المرجعية'\r
+       },\r
+       anchorId: 'حسب رقم العنصر',\r
+       anchorName: 'حسب إسم الإشارة المرجعية',\r
+       charset: 'ترميز المادة المطلوبة',\r
+       cssClasses: 'فئات التنسيق',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'البريد الإلكتروني',\r
+       emailBody: 'محتوى الرسالة',\r
+       emailSubject: 'موضوع الرسالة',\r
+       id: 'هوية',\r
+       info: 'معلومات الرابط',\r
+       langCode: 'رمز اللغة',\r
+       langDir: 'إتجاه نص اللغة',\r
+       langDirLTR: 'اليسار لليمين (LTR)',\r
+       langDirRTL: 'اليمين لليسار (RTL)',\r
+       menu: 'تحرير الرابط',\r
+       name: 'إسم',\r
+       noAnchors: '(لا توجد علامات مرجعية في هذا المستند)',\r
+       noEmail: 'الرجاء كتابة الريد الإلكتروني',\r
+       noUrl: 'الرجاء كتابة رابط الموقع',\r
+       other: '<أخرى>',\r
+       popupDependent: 'تابع (Netscape)',\r
+       popupFeatures: 'خصائص النافذة المنبثقة',\r
+       popupFullScreen: 'ملئ الشاشة (IE)',\r
+       popupLeft: 'التمركز لليسار',\r
+       popupLocationBar: 'شريط العنوان',\r
+       popupMenuBar: 'القوائم الرئيسية',\r
+       popupResizable: 'قابلة التشكيل',\r
+       popupScrollBars: 'أشرطة التمرير',\r
+       popupStatusBar: 'شريط الحالة',\r
+       popupToolbar: 'شريط الأدوات',\r
+       popupTop: 'التمركز للأعلى',\r
+       rel: 'العلاقة',\r
+       selectAnchor: 'اختر علامة مرجعية',\r
+       styles: 'نمط',\r
+       tabIndex: 'الترتيب',\r
+       target: 'هدف الرابط',\r
+       targetFrame: '<إطار>',\r
+       targetFrameName: 'اسم الإطار المستهدف',\r
+       targetPopup: '<نافذة منبثقة>',\r
+       targetPopupName: 'اسم النافذة المنبثقة',\r
+       title: 'رابط',\r
+       toAnchor: 'مكان في هذا المستند',\r
+       toEmail: 'بريد إلكتروني',\r
+       toUrl: 'الرابط',\r
+       toolbar: 'رابط',\r
+       type: 'نوع الربط',\r
+       unlink: 'إزالة رابط',\r
+       upload: 'رفع'\r
+} );\r
diff --git a/sources/plugins/link/lang/az.js b/sources/plugins/link/lang/az.js
new file mode 100644 (file)
index 0000000..33588fe
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'az', {\r
+       acccessKey: 'Qısayol düyməsi',\r
+       advanced: 'Geniş seçimləri',\r
+       advisoryContentType: 'Məsləhətli məzmunun növü',\r
+       advisoryTitle: 'Məsləhətli başlıq',\r
+       anchor: {\r
+               toolbar: 'Xeş',\r
+               menu: 'Xeşi redaktə et',\r
+               title: 'Xeşin seçimləri',\r
+               name: 'Xeşin adı',\r
+               errorName: 'Xeşin adı yanlışdır',\r
+               remove: 'Xeşin adı sil'\r
+       },\r
+       anchorId: 'ID görə',\r
+       anchorName: 'Xeşin adına görə',\r
+       charset: 'Hədəfin kodlaşdırması',\r
+       cssClasses: 'Üslub klası',\r
+       download: 'Məcburi yükləmə',\r
+       displayText: 'Göstərilən mətn',\r
+       emailAddress: 'E-poçt ünvanı',\r
+       emailBody: 'Mesajın məzmunu',\r
+       emailSubject: 'Mesajın başlığı',\r
+       id: 'ID',\r
+       info: 'Linkin xüsusiyyətləri',\r
+       langCode: 'Dilin kodu',\r
+       langDir: 'Yaziların istiqaməti',\r
+       langDirLTR: 'Soldan sağa (LTR)',\r
+       langDirRTL: 'Sağdan sola (RTL)',\r
+       menu: 'Linki redaktə et',\r
+       name: 'Ad',\r
+       noAnchors: '(heç bir xeş tapılmayıb)',\r
+       noEmail: 'E-poçt ünvanı daxil edin',\r
+       noUrl: 'Linkin URL-ı daxil edin',\r
+       other: '<digər>',\r
+       popupDependent: 'Asılı (Netscape)',\r
+       popupFeatures: 'Pəncərənin xüsusiyyətləri',\r
+       popupFullScreen: 'Tam ekran rejimi (IE)',\r
+       popupLeft: 'Solda',\r
+       popupLocationBar: 'Ünvan paneli',\r
+       popupMenuBar: 'Menyu paneli',\r
+       popupResizable: 'Olçülər dəyişilir',\r
+       popupScrollBars: 'Sürüşdürmələr göstər',\r
+       popupStatusBar: 'Bildirişlərin paneli',\r
+       popupToolbar: 'Alətlərin paneli',\r
+       popupTop: 'Yuxarıda',\r
+       rel: 'Münasibət',\r
+       selectAnchor: 'Xeşi seçin',\r
+       styles: 'Üslub',\r
+       tabIndex: 'Tabın nömrəsi',\r
+       target: 'Hədəf çərçivə',\r
+       targetFrame: '<freym>',\r
+       targetFrameName: 'Freymin adı',\r
+       targetPopup: '<yeni pəncərə>',\r
+       targetPopupName: 'Pəncərənin adı',\r
+       title: 'Link',\r
+       toAnchor: 'Xeş',\r
+       toEmail: 'E-poçt',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link',\r
+       type: 'Linkin növü',\r
+       unlink: 'Linki sil',\r
+       upload: 'Serverə yüklə'\r
+} );\r
diff --git a/sources/plugins/link/lang/bg.js b/sources/plugins/link/lang/bg.js
new file mode 100644 (file)
index 0000000..ad32915
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'bg', {\r
+       acccessKey: 'Ключ за достъп',\r
+       advanced: 'Разширено',\r
+       advisoryContentType: 'Препоръчителен тип на съдържанието',\r
+       advisoryTitle: 'Препоръчително заглавие',\r
+       anchor: {\r
+               toolbar: 'Котва',\r
+               menu: 'Промяна на котва',\r
+               title: 'Настройки на котва',\r
+               name: 'Име на котва',\r
+               errorName: 'Моля въведете име на котвата',\r
+               remove: 'Премахване на котва'\r
+       },\r
+       anchorId: 'По ID на елемент',\r
+       anchorName: 'По име на котва',\r
+       charset: 'Тип на свързания ресурс',\r
+       cssClasses: 'Класове за CSS',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-mail aдрес',\r
+       emailBody: 'Съдържание',\r
+       emailSubject: 'Тема',\r
+       id: 'ID',\r
+       info: 'Инфо за връзката',\r
+       langCode: 'Код за езика',\r
+       langDir: 'Посока на езика',\r
+       langDirLTR: 'Ляво на Дясно (ЛнД)',\r
+       langDirRTL: 'Дясно на Ляво (ДнЛ)',\r
+       menu: 'Промяна на връзка',\r
+       name: 'Име',\r
+       noAnchors: '(Няма котви в текущия документ)',\r
+       noEmail: 'Моля въведете e-mail aдрес',\r
+       noUrl: 'Моля въведете URL адреса',\r
+       other: '<друго>',\r
+       popupDependent: 'Зависимост (Netscape)',\r
+       popupFeatures: 'Функции на изкачащ прозорец',\r
+       popupFullScreen: 'Цял екран (IE)',\r
+       popupLeft: 'Лява позиция',\r
+       popupLocationBar: 'Лента с локацията',\r
+       popupMenuBar: 'Лента за меню',\r
+       popupResizable: 'Оразмеряем',\r
+       popupScrollBars: 'Скролери',\r
+       popupStatusBar: 'Статусна лента',\r
+       popupToolbar: 'Лента с инструменти',\r
+       popupTop: 'Горна позиция',\r
+       rel: 'Връзка',\r
+       selectAnchor: 'Изберете котва',\r
+       styles: 'Стил',\r
+       tabIndex: 'Ред на достъп',\r
+       target: 'Цел',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Име на целевият прозорец',\r
+       targetPopup: '<изкачащ прозорец>',\r
+       targetPopupName: 'Име на изкачащ прозорец',\r
+       title: 'Връзка',\r
+       toAnchor: 'Връзка към котва в текста',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'Уеб адрес',\r
+       toolbar: 'Връзка',\r
+       type: 'Тип на връзката',\r
+       unlink: 'Премахни връзката',\r
+       upload: 'Качване'\r
+} );\r
diff --git a/sources/plugins/link/lang/bn.js b/sources/plugins/link/lang/bn.js
new file mode 100644 (file)
index 0000000..c071821
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'bn', {\r
+       acccessKey: 'প্রবেশ কী',\r
+       advanced: 'এডভান্সড',\r
+       advisoryContentType: 'পরামর্শ কন্টেন্টের প্রকার',\r
+       advisoryTitle: 'পরামর্শ শীর্ষক',\r
+       anchor: {\r
+               toolbar: 'নোঙ্গর',\r
+               menu: 'নোঙর প্রোপার্টি',\r
+               title: 'নোঙর প্রোপার্টি',\r
+               name: 'নোঙরের নাম',\r
+               errorName: 'নোঙরের নাম টাইপ করুন',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'নোঙরের আইডি দিয়ে',\r
+       anchorName: 'নোঙরের নাম দিয়ে',\r
+       charset: 'লিংক রিসোর্স ক্যারেক্টর সেট',\r
+       cssClasses: 'স্টাইল-শীট ক্লাস',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ইমেইল ঠিকানা',\r
+       emailBody: 'মেসেজের দেহ',\r
+       emailSubject: 'মেসেজের বিষয়',\r
+       id: 'আইডি',\r
+       info: 'লিংক তথ্য',\r
+       langCode: 'ভাষা লেখার দিক',\r
+       langDir: 'ভাষা লেখার দিক',\r
+       langDirLTR: 'বাম থেকে ডান (LTR)',\r
+       langDirRTL: 'ডান থেকে বাম (RTL)',\r
+       menu: 'লিংক সম্পাদন',\r
+       name: 'নাম',\r
+       noAnchors: '(No anchors available in the document)', // MISSING\r
+       noEmail: 'অনুগ্রহ করে ইমেইল এড্রেস টাইপ করুন',\r
+       noUrl: 'অনুগ্রহ করে URL লিংক টাইপ করুন',\r
+       other: '<other>', // MISSING\r
+       popupDependent: 'ডিপেন্ডেন্ট (Netscape)',\r
+       popupFeatures: 'পপআপ উইন্ডো ফীচার সমূহ',\r
+       popupFullScreen: 'পূর্ণ পর্দা জুড়ে (IE)',\r
+       popupLeft: 'বামের পজিশন',\r
+       popupLocationBar: 'লোকেশন বার',\r
+       popupMenuBar: 'মেন্যু বার',\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'স্ক্রল বার',\r
+       popupStatusBar: 'স্ট্যাটাস বার',\r
+       popupToolbar: 'টুল বার',\r
+       popupTop: 'ডানের পজিশন',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'নোঙর বাছাই',\r
+       styles: 'স্টাইল',\r
+       tabIndex: 'ট্যাব ইন্ডেক্স',\r
+       target: 'টার্গেট',\r
+       targetFrame: '<ফ্রেম>',\r
+       targetFrameName: 'টার্গেট ফ্রেমের নাম',\r
+       targetPopup: '<পপআপ উইন্ডো>',\r
+       targetPopupName: 'পপআপ উইন্ডোর নাম',\r
+       title: 'লিংক',\r
+       toAnchor: 'এই পেজে নোঙর কর',\r
+       toEmail: 'ইমেইল',\r
+       toUrl: 'URL',\r
+       toolbar: 'লিংক যুক্ত কর',\r
+       type: 'লিংক প্রকার',\r
+       unlink: 'লিংক সরাও',\r
+       upload: 'আপলোড'\r
+} );\r
diff --git a/sources/plugins/link/lang/bs.js b/sources/plugins/link/lang/bs.js
new file mode 100644 (file)
index 0000000..d23ae35
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'bs', {\r
+       acccessKey: 'Pristupna tipka',\r
+       advanced: 'Naprednije',\r
+       advisoryContentType: 'Advisory vrsta sadržaja',\r
+       advisoryTitle: 'Advisory title',\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'Po Id-u elementa',\r
+       anchorName: 'Po nazivu sidra',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Klase CSS stilova',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Adresa',\r
+       emailBody: 'Poruka',\r
+       emailSubject: 'Subjekt poruke',\r
+       id: 'Id',\r
+       info: 'Link info',\r
+       langCode: 'Smjer pisanja',\r
+       langDir: 'Smjer pisanja',\r
+       langDirLTR: 'S lijeva na desno (LTR)',\r
+       langDirRTL: 'S desna na lijevo (RTL)',\r
+       menu: 'Izmjeni link',\r
+       name: 'Naziv',\r
+       noAnchors: '(Nema dostupnih sidra na stranici)',\r
+       noEmail: 'Molimo ukucajte e-mail adresu',\r
+       noUrl: 'Molimo ukucajte URL link',\r
+       other: '<other>', // MISSING\r
+       popupDependent: 'Ovisno (Netscape)',\r
+       popupFeatures: 'Moguænosti popup prozora',\r
+       popupFullScreen: 'Cijeli ekran (IE)',\r
+       popupLeft: 'Lijeva pozicija',\r
+       popupLocationBar: 'Traka za lokaciju',\r
+       popupMenuBar: 'Izborna traka',\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Scroll traka',\r
+       popupStatusBar: 'Statusna traka',\r
+       popupToolbar: 'Traka sa alatima',\r
+       popupTop: 'Gornja pozicija',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Izaberi sidro',\r
+       styles: 'Stil',\r
+       tabIndex: 'Tab indeks',\r
+       target: 'Prozor',\r
+       targetFrame: '<frejm>',\r
+       targetFrameName: 'Target Frame Name', // MISSING\r
+       targetPopup: '<popup prozor>',\r
+       targetPopupName: 'Naziv popup prozora',\r
+       title: 'Link',\r
+       toAnchor: 'Sidro na ovoj stranici',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Ubaci/Izmjeni link',\r
+       type: 'Tip linka',\r
+       unlink: 'Izbriši link',\r
+       upload: 'Šalji'\r
+} );\r
diff --git a/sources/plugins/link/lang/ca.js b/sources/plugins/link/lang/ca.js
new file mode 100644 (file)
index 0000000..44a9ebd
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ca', {\r
+       acccessKey: 'Clau d\'accés',\r
+       advanced: 'Avançat',\r
+       advisoryContentType: 'Tipus de contingut consultiu',\r
+       advisoryTitle: 'Títol consultiu',\r
+       anchor: {\r
+               toolbar: 'Insereix/Edita àncora',\r
+               menu: 'Propietats de l\'àncora',\r
+               title: 'Propietats de l\'àncora',\r
+               name: 'Nom de l\'àncora',\r
+               errorName: 'Si us plau, escriviu el nom de l\'ancora',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'Per Id d\'element',\r
+       anchorName: 'Per nom d\'àncora',\r
+       charset: 'Conjunt de caràcters font enllaçat',\r
+       cssClasses: 'Classes del full d\'estil',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Text a mostrar',\r
+       emailAddress: 'Adreça de correu electrònic',\r
+       emailBody: 'Cos del missatge',\r
+       emailSubject: 'Assumpte del missatge',\r
+       id: 'Id',\r
+       info: 'Informació de l\'enllaç',\r
+       langCode: 'Direcció de l\'idioma',\r
+       langDir: 'Direcció de l\'idioma',\r
+       langDirLTR: 'D\'esquerra a dreta (LTR)',\r
+       langDirRTL: 'De dreta a esquerra (RTL)',\r
+       menu: 'Edita l\'enllaç',\r
+       name: 'Nom',\r
+       noAnchors: '(No hi ha àncores disponibles en aquest document)',\r
+       noEmail: 'Si us plau, escrigui l\'adreça correu electrònic',\r
+       noUrl: 'Si us plau, escrigui l\'enllaç URL',\r
+       other: '<altre>',\r
+       popupDependent: 'Depenent (Netscape)',\r
+       popupFeatures: 'Característiques finestra popup',\r
+       popupFullScreen: 'Pantalla completa (IE)',\r
+       popupLeft: 'Posició esquerra',\r
+       popupLocationBar: 'Barra d\'adreça',\r
+       popupMenuBar: 'Barra de menú',\r
+       popupResizable: 'Redimensionable',\r
+       popupScrollBars: 'Barres d\'scroll',\r
+       popupStatusBar: 'Barra d\'estat',\r
+       popupToolbar: 'Barra d\'eines',\r
+       popupTop: 'Posició dalt',\r
+       rel: 'Relació',\r
+       selectAnchor: 'Selecciona una àncora',\r
+       styles: 'Estil',\r
+       tabIndex: 'Index de Tab',\r
+       target: 'Destí',\r
+       targetFrame: '<marc>',\r
+       targetFrameName: 'Nom del marc de destí',\r
+       targetPopup: '<finestra emergent>',\r
+       targetPopupName: 'Nom finestra popup',\r
+       title: 'Enllaç',\r
+       toAnchor: 'Àncora en aquesta pàgina',\r
+       toEmail: 'Correu electrònic',\r
+       toUrl: 'URL',\r
+       toolbar: 'Insereix/Edita enllaç',\r
+       type: 'Tipus d\'enllaç',\r
+       unlink: 'Elimina l\'enllaç',\r
+       upload: 'Puja'\r
+} );\r
diff --git a/sources/plugins/link/lang/cs.js b/sources/plugins/link/lang/cs.js
new file mode 100644 (file)
index 0000000..508c133
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'cs', {\r
+       acccessKey: 'Přístupový klíč',\r
+       advanced: 'Rozšířené',\r
+       advisoryContentType: 'Pomocný typ obsahu',\r
+       advisoryTitle: 'Pomocný titulek',\r
+       anchor: {\r
+               toolbar: 'Záložka',\r
+               menu: 'Vlastnosti záložky',\r
+               title: 'Vlastnosti záložky',\r
+               name: 'Název záložky',\r
+               errorName: 'Zadejte prosím název záložky',\r
+               remove: 'Odstranit záložku'\r
+       },\r
+       anchorId: 'Podle Id objektu',\r
+       anchorName: 'Podle jména kotvy',\r
+       charset: 'Přiřazená znaková sada',\r
+       cssClasses: 'Třída stylu',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Zobrazit text',\r
+       emailAddress: 'E-mailová adresa',\r
+       emailBody: 'Tělo zprávy',\r
+       emailSubject: 'Předmět zprávy',\r
+       id: 'Id',\r
+       info: 'Informace o odkazu',\r
+       langCode: 'Kód jazyka',\r
+       langDir: 'Směr jazyka',\r
+       langDirLTR: 'Zleva doprava (LTR)',\r
+       langDirRTL: 'Zprava doleva (RTL)',\r
+       menu: 'Změnit odkaz',\r
+       name: 'Jméno',\r
+       noAnchors: '(Ve stránce není definována žádná kotva!)',\r
+       noEmail: 'Zadejte prosím e-mailovou adresu',\r
+       noUrl: 'Zadejte prosím URL odkazu',\r
+       other: '<jiný>',\r
+       popupDependent: 'Závislost (Netscape)',\r
+       popupFeatures: 'Vlastnosti vyskakovacího okna',\r
+       popupFullScreen: 'Celá obrazovka (IE)',\r
+       popupLeft: 'Levý okraj',\r
+       popupLocationBar: 'Panel umístění',\r
+       popupMenuBar: 'Panel nabídky',\r
+       popupResizable: 'Umožňující měnit velikost',\r
+       popupScrollBars: 'Posuvníky',\r
+       popupStatusBar: 'Stavový řádek',\r
+       popupToolbar: 'Panel nástrojů',\r
+       popupTop: 'Horní okraj',\r
+       rel: 'Vztah',\r
+       selectAnchor: 'Vybrat kotvu',\r
+       styles: 'Styl',\r
+       tabIndex: 'Pořadí prvku',\r
+       target: 'Cíl',\r
+       targetFrame: '<rámec>',\r
+       targetFrameName: 'Název cílového rámu',\r
+       targetPopup: '<vyskakovací okno>',\r
+       targetPopupName: 'Název vyskakovacího okna',\r
+       title: 'Odkaz',\r
+       toAnchor: 'Kotva v této stránce',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Odkaz',\r
+       type: 'Typ odkazu',\r
+       unlink: 'Odstranit odkaz',\r
+       upload: 'Odeslat'\r
+} );\r
diff --git a/sources/plugins/link/lang/cy.js b/sources/plugins/link/lang/cy.js
new file mode 100644 (file)
index 0000000..024b669
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'cy', {\r
+       acccessKey: 'Allwedd Mynediad',\r
+       advanced: 'Uwch',\r
+       advisoryContentType: 'Math y Cynnwys Cynghorol',\r
+       advisoryTitle: 'Teitl Cynghorol',\r
+       anchor: {\r
+               toolbar: 'Angor',\r
+               menu: 'Golygu\'r Angor',\r
+               title: 'Priodweddau\'r Angor',\r
+               name: 'Enw\'r Angor',\r
+               errorName: 'Teipiwch enw\'r angor',\r
+               remove: 'Tynnwch yr Angor'\r
+       },\r
+       anchorId: 'Gan Id yr Elfen',\r
+       anchorName: 'Gan Enw\'r Angor',\r
+       charset: 'Set Nodau\'r Adnodd Cysylltiedig',\r
+       cssClasses: 'Dosbarthiadau Dalen Arddull',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Cyfeiriad E-Bost',\r
+       emailBody: 'Corff y Neges',\r
+       emailSubject: 'Testun y Neges',\r
+       id: 'Id',\r
+       info: 'Gwyb y Ddolen',\r
+       langCode: 'Cod Iaith',\r
+       langDir: 'Cyfeiriad Iaith',\r
+       langDirLTR: 'Chwith i\'r Dde (LTR)',\r
+       langDirRTL: 'Dde i\'r Chwith (RTL)',\r
+       menu: 'Golygu Dolen',\r
+       name: 'Enw',\r
+       noAnchors: '(Dim angorau ar gael yn y ddogfen)',\r
+       noEmail: 'Teipiwch gyfeiriad yr e-bost',\r
+       noUrl: 'Teipiwch URL y ddolen',\r
+       other: '<eraill>',\r
+       popupDependent: 'Dibynnol (Netscape)',\r
+       popupFeatures: 'Nodweddion Ffenestr Bop',\r
+       popupFullScreen: 'Sgrin Llawn (IE)',\r
+       popupLeft: 'Safle Chwith',\r
+       popupLocationBar: 'Bar Safle',\r
+       popupMenuBar: 'Dewislen',\r
+       popupResizable: 'Ailfeintiol',\r
+       popupScrollBars: 'Barrau Sgrolio',\r
+       popupStatusBar: 'Bar Statws',\r
+       popupToolbar: 'Bar Offer',\r
+       popupTop: 'Safle Top',\r
+       rel: 'Perthynas',\r
+       selectAnchor: 'Dewiswch Angor',\r
+       styles: 'Arddull',\r
+       tabIndex: 'Indecs Tab',\r
+       target: 'Targed',\r
+       targetFrame: '<ffrâm>',\r
+       targetFrameName: 'Enw Ffrâm y Targed',\r
+       targetPopup: '<ffenestr bop>',\r
+       targetPopupName: 'Enw Ffenestr Bop',\r
+       title: 'Dolen',\r
+       toAnchor: 'Dolen at angor yn y testun',\r
+       toEmail: 'E-bost',\r
+       toUrl: 'URL',\r
+       toolbar: 'Dolen',\r
+       type: 'Math y Ddolen',\r
+       unlink: 'Datgysylltu',\r
+       upload: 'Lanlwytho'\r
+} );\r
diff --git a/sources/plugins/link/lang/da.js b/sources/plugins/link/lang/da.js
new file mode 100644 (file)
index 0000000..47adf58
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'da', {\r
+       acccessKey: 'Genvejstast',\r
+       advanced: 'Avanceret',\r
+       advisoryContentType: 'Indholdstype',\r
+       advisoryTitle: 'Titel',\r
+       anchor: {\r
+               toolbar: 'Indsæt/redigér bogmærke',\r
+               menu: 'Egenskaber for bogmærke',\r
+               title: 'Egenskaber for bogmærke',\r
+               name: 'Bogmærkenavn',\r
+               errorName: 'Indtast bogmærkenavn',\r
+               remove: 'Fjern bogmærke'\r
+       },\r
+       anchorId: 'Efter element-Id',\r
+       anchorName: 'Efter ankernavn',\r
+       charset: 'Tegnsæt',\r
+       cssClasses: 'Typografiark',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-mailadresse',\r
+       emailBody: 'Besked',\r
+       emailSubject: 'Emne',\r
+       id: 'Id',\r
+       info: 'Generelt',\r
+       langCode: 'Tekstretning',\r
+       langDir: 'Tekstretning',\r
+       langDirLTR: 'Fra venstre mod højre (LTR)',\r
+       langDirRTL: 'Fra højre mod venstre (RTL)',\r
+       menu: 'Redigér hyperlink',\r
+       name: 'Navn',\r
+       noAnchors: '(Ingen bogmærker i dokumentet)',\r
+       noEmail: 'Indtast e-mailadresse!',\r
+       noUrl: 'Indtast hyperlink-URL!',\r
+       other: '<anden>',\r
+       popupDependent: 'Koblet/dependent (Netscape)',\r
+       popupFeatures: 'Egenskaber for popup',\r
+       popupFullScreen: 'Fuld skærm (IE)',\r
+       popupLeft: 'Position fra venstre',\r
+       popupLocationBar: 'Adresselinje',\r
+       popupMenuBar: 'Menulinje',\r
+       popupResizable: 'Justérbar',\r
+       popupScrollBars: 'Scrollbar',\r
+       popupStatusBar: 'Statuslinje',\r
+       popupToolbar: 'Værktøjslinje',\r
+       popupTop: 'Position fra toppen',\r
+       rel: 'Relation',\r
+       selectAnchor: 'Vælg et anker',\r
+       styles: 'Typografi',\r
+       tabIndex: 'Tabulatorindeks',\r
+       target: 'Mål',\r
+       targetFrame: '<ramme>',\r
+       targetFrameName: 'Destinationsvinduets navn',\r
+       targetPopup: '<popup vindue>',\r
+       targetPopupName: 'Popupvinduets navn',\r
+       title: 'Egenskaber for hyperlink',\r
+       toAnchor: 'Bogmærke på denne side',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Indsæt/redigér hyperlink',\r
+       type: 'Type',\r
+       unlink: 'Fjern hyperlink',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/de-ch.js b/sources/plugins/link/lang/de-ch.js
new file mode 100644 (file)
index 0000000..eba8c7e
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'de-ch', {\r
+       acccessKey: 'Zugriffstaste',\r
+       advanced: 'Erweitert',\r
+       advisoryContentType: 'Inhaltstyp',\r
+       advisoryTitle: 'Titel Beschreibung',\r
+       anchor: {\r
+               toolbar: 'Anker',\r
+               menu: 'Anker bearbeiten',\r
+               title: 'Ankereigenschaften',\r
+               name: 'Ankername',\r
+               errorName: 'Bitte geben Sie den Namen des Ankers ein',\r
+               remove: 'Anker entfernen'\r
+       },\r
+       anchorId: 'Nach Elementkennung',\r
+       anchorName: 'Nach Ankername',\r
+       charset: 'Verknüpfter Ressourcenzeichensatz',\r
+       cssClasses: 'Formatvorlagenklasse',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail-Adresse',\r
+       emailBody: 'Nachrichtentext',\r
+       emailSubject: 'Betreffzeile',\r
+       id: 'Kennung',\r
+       info: 'Linkinfo',\r
+       langCode: 'Sprachcode',\r
+       langDir: 'Schreibrichtung',\r
+       langDirLTR: 'Links nach Rechts (LTR)',\r
+       langDirRTL: 'Rechts nach Links (RTL)',\r
+       menu: 'Link bearbeiten',\r
+       name: 'Name',\r
+       noAnchors: '(Keine Anker im Dokument vorhanden)',\r
+       noEmail: 'Bitte geben Sie E-Mail-Adresse an',\r
+       noUrl: 'Bitte geben Sie die Link-URL an',\r
+       other: '<andere>',\r
+       popupDependent: 'Abhängig (Netscape)',\r
+       popupFeatures: 'Pop-up Fenstereigenschaften',\r
+       popupFullScreen: 'Vollbild (IE)',\r
+       popupLeft: 'Linke Position',\r
+       popupLocationBar: 'Adressleiste',\r
+       popupMenuBar: 'Menüleiste',\r
+       popupResizable: 'Grösse änderbar',\r
+       popupScrollBars: 'Rollbalken',\r
+       popupStatusBar: 'Statusleiste',\r
+       popupToolbar: 'Werkzeugleiste',\r
+       popupTop: 'Obere Position',\r
+       rel: 'Beziehung',\r
+       selectAnchor: 'Anker auswählen',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab-Index',\r
+       target: 'Zielseite',\r
+       targetFrame: '<Frame>',\r
+       targetFrameName: 'Ziel-Fenster-Name',\r
+       targetPopup: '<Pop-up Fenster>',\r
+       targetPopupName: 'Pop-up Fenster-Name',\r
+       title: 'Link',\r
+       toAnchor: 'Anker in dieser Seite',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link einfügen/editieren',\r
+       type: 'Link-Typ',\r
+       unlink: 'Link entfernen',\r
+       upload: 'Hochladen'\r
+} );\r
diff --git a/sources/plugins/link/lang/de.js b/sources/plugins/link/lang/de.js
new file mode 100644 (file)
index 0000000..e73093f
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'de', {\r
+       acccessKey: 'Zugriffstaste',\r
+       advanced: 'Erweitert',\r
+       advisoryContentType: 'Inhaltstyp',\r
+       advisoryTitle: 'Titel Beschreibung',\r
+       anchor: {\r
+               toolbar: 'Anker',\r
+               menu: 'Anker bearbeiten',\r
+               title: 'Ankereigenschaften',\r
+               name: 'Ankername',\r
+               errorName: 'Bitte geben Sie den Namen des Ankers ein',\r
+               remove: 'Anker entfernen'\r
+       },\r
+       anchorId: 'Nach Elementkennung',\r
+       anchorName: 'Nach Ankername',\r
+       charset: 'Verknüpfter Ressourcenzeichensatz',\r
+       cssClasses: 'Formatvorlagenklasse',\r
+       download: 'Herunterladen erzwingen',\r
+       displayText: 'Anzeigetext',\r
+       emailAddress: 'E-Mail-Adresse',\r
+       emailBody: 'Nachrichtentext',\r
+       emailSubject: 'Betreffzeile',\r
+       id: 'Kennung',\r
+       info: 'Linkinfo',\r
+       langCode: 'Sprachcode',\r
+       langDir: 'Schreibrichtung',\r
+       langDirLTR: 'Links nach Rechts (LTR)',\r
+       langDirRTL: 'Rechts nach Links (RTL)',\r
+       menu: 'Link bearbeiten',\r
+       name: 'Name',\r
+       noAnchors: '(Keine Anker im Dokument vorhanden)',\r
+       noEmail: 'Bitte geben Sie E-Mail-Adresse an',\r
+       noUrl: 'Bitte geben Sie die Link-URL an',\r
+       other: '<andere>',\r
+       popupDependent: 'Abhängig (Netscape)',\r
+       popupFeatures: 'Pop-up Fenstereigenschaften',\r
+       popupFullScreen: 'Vollbild (IE)',\r
+       popupLeft: 'Linke Position',\r
+       popupLocationBar: 'Adressleiste',\r
+       popupMenuBar: 'Menüleiste',\r
+       popupResizable: 'Größe änderbar',\r
+       popupScrollBars: 'Rollbalken',\r
+       popupStatusBar: 'Statusleiste',\r
+       popupToolbar: 'Werkzeugleiste',\r
+       popupTop: 'Obere Position',\r
+       rel: 'Beziehung',\r
+       selectAnchor: 'Anker auswählen',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab-Index',\r
+       target: 'Zielseite',\r
+       targetFrame: '<Frame>',\r
+       targetFrameName: 'Ziel-Fenster-Name',\r
+       targetPopup: '<Pop-up Fenster>',\r
+       targetPopupName: 'Pop-up Fenster-Name',\r
+       title: 'Link',\r
+       toAnchor: 'Anker in dieser Seite',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link einfügen/editieren',\r
+       type: 'Link-Typ',\r
+       unlink: 'Link entfernen',\r
+       upload: 'Hochladen'\r
+} );\r
diff --git a/sources/plugins/link/lang/el.js b/sources/plugins/link/lang/el.js
new file mode 100644 (file)
index 0000000..bf0fbb9
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'el', {\r
+       acccessKey: 'Συντόμευση',\r
+       advanced: 'Για Προχωρημένους',\r
+       advisoryContentType: 'Ενδεικτικός Τύπος Περιεχομένου',\r
+       advisoryTitle: 'Ενδεικτικός Τίτλος',\r
+       anchor: {\r
+               toolbar: 'Εισαγωγή/επεξεργασία Άγκυρας',\r
+               menu: 'Ιδιότητες άγκυρας',\r
+               title: 'Ιδιότητες άγκυρας',\r
+               name: 'Όνομα άγκυρας',\r
+               errorName: 'Παρακαλούμε εισάγετε όνομα άγκυρας',\r
+               remove: 'Αφαίρεση Άγκυρας'\r
+       },\r
+       anchorId: 'Βάσει του Element Id',\r
+       anchorName: 'Βάσει του Ονόματος Άγκυρας',\r
+       charset: 'Κωδικοποίηση Χαρακτήρων Προσαρτημένης Πηγής',\r
+       cssClasses: 'Κλάσεις Φύλλων Στυλ',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Διεύθυνση E-mail',\r
+       emailBody: 'Κείμενο Μηνύματος',\r
+       emailSubject: 'Θέμα Μηνύματος',\r
+       id: 'Id',\r
+       info: 'Πληροφορίες Συνδέσμου',\r
+       langCode: 'Κατεύθυνση Κειμένου',\r
+       langDir: 'Κατεύθυνση Κειμένου',\r
+       langDirLTR: 'Αριστερά προς Δεξιά (LTR)',\r
+       langDirRTL: 'Δεξιά προς Αριστερά (RTL)',\r
+       menu: 'Επεξεργασία Συνδέσμου',\r
+       name: 'Όνομα',\r
+       noAnchors: '(Δεν υπάρχουν άγκυρες στο κείμενο)',\r
+       noEmail: 'Εισάγετε τη διεύθυνση ηλεκτρονικού ταχυδρομείου',\r
+       noUrl: 'Εισάγετε την τοποθεσία (URL) του συνδέσμου',\r
+       other: '<άλλο>',\r
+       popupDependent: 'Εξαρτημένο (Netscape)',\r
+       popupFeatures: 'Επιλογές Αναδυόμενου Παραθύρου',\r
+       popupFullScreen: 'Πλήρης Οθόνη (IE)',\r
+       popupLeft: 'Θέση Αριστερά',\r
+       popupLocationBar: 'Γραμμή Τοποθεσίας',\r
+       popupMenuBar: 'Γραμμή Επιλογών',\r
+       popupResizable: 'Προσαρμοζόμενο Μέγεθος',\r
+       popupScrollBars: 'Μπάρες Κύλισης',\r
+       popupStatusBar: 'Γραμμή Κατάστασης',\r
+       popupToolbar: 'Εργαλειοθήκη',\r
+       popupTop: 'Θέση Πάνω',\r
+       rel: 'Σχέση',\r
+       selectAnchor: 'Επιλέξτε μια Άγκυρα',\r
+       styles: 'Μορφή',\r
+       tabIndex: 'Σειρά Μεταπήδησης',\r
+       target: 'Παράθυρο Προορισμού',\r
+       targetFrame: '<πλαίσιο>',\r
+       targetFrameName: 'Όνομα Πλαισίου Προορισμού',\r
+       targetPopup: '<αναδυόμενο παράθυρο>',\r
+       targetPopupName: 'Όνομα Αναδυόμενου Παραθύρου',\r
+       title: 'Σύνδεσμος',\r
+       toAnchor: 'Άγκυρα σε αυτήν τη σελίδα',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Σύνδεσμος',\r
+       type: 'Τύπος Συνδέσμου',\r
+       unlink: 'Αφαίρεση Συνδέσμου',\r
+       upload: 'Αποστολή'\r
+} );\r
diff --git a/sources/plugins/link/lang/en-au.js b/sources/plugins/link/lang/en-au.js
new file mode 100644 (file)
index 0000000..f67a6f7
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'en-au', {\r
+       acccessKey: 'Access Key',\r
+       advanced: 'Advanced',\r
+       advisoryContentType: 'Advisory Content Type',\r
+       advisoryTitle: 'Advisory Title',\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'By Element Id',\r
+       anchorName: 'By Anchor Name',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet Classes',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Address',\r
+       emailBody: 'Message Body',\r
+       emailSubject: 'Message Subject',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Language Code',\r
+       langDir: 'Language Direction',\r
+       langDirLTR: 'Left to Right (LTR)',\r
+       langDirRTL: 'Right to Left (RTL)',\r
+       menu: 'Edit Link',\r
+       name: 'Name',\r
+       noAnchors: '(No anchors available in the document)',\r
+       noEmail: 'Please type the e-mail address',\r
+       noUrl: 'Please type the link URL',\r
+       other: '<other>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'Popup Window Features',\r
+       popupFullScreen: 'Full Screen (IE)',\r
+       popupLeft: 'Left Position',\r
+       popupLocationBar: 'Location Bar',\r
+       popupMenuBar: 'Menu Bar',\r
+       popupResizable: 'Resizable',\r
+       popupScrollBars: 'Scroll Bars',\r
+       popupStatusBar: 'Status Bar',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Top Position',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Select an Anchor',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab Index',\r
+       target: 'Target',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Target Frame Name',\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Popup Window Name',\r
+       title: 'Link',\r
+       toAnchor: 'Link to anchor in the text',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link',\r
+       type: 'Link Type',\r
+       unlink: 'Unlink',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/en-ca.js b/sources/plugins/link/lang/en-ca.js
new file mode 100644 (file)
index 0000000..636ee5c
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'en-ca', {\r
+       acccessKey: 'Access Key',\r
+       advanced: 'Advanced',\r
+       advisoryContentType: 'Advisory Content Type',\r
+       advisoryTitle: 'Advisory Title',\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'By Element Id',\r
+       anchorName: 'By Anchor Name',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet Classes',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Address',\r
+       emailBody: 'Message Body',\r
+       emailSubject: 'Message Subject',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Language Code',\r
+       langDir: 'Language Direction',\r
+       langDirLTR: 'Left to Right (LTR)',\r
+       langDirRTL: 'Right to Left (RTL)',\r
+       menu: 'Edit Link',\r
+       name: 'Name',\r
+       noAnchors: '(No anchors available in the document)',\r
+       noEmail: 'Please type the e-mail address',\r
+       noUrl: 'Please type the link URL',\r
+       other: '<other>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'Popup Window Features',\r
+       popupFullScreen: 'Full Screen (IE)',\r
+       popupLeft: 'Left Position',\r
+       popupLocationBar: 'Location Bar',\r
+       popupMenuBar: 'Menu Bar',\r
+       popupResizable: 'Resizable',\r
+       popupScrollBars: 'Scroll Bars',\r
+       popupStatusBar: 'Status Bar',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Top Position',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Select an Anchor',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab Index',\r
+       target: 'Target',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Target Frame Name',\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Popup Window Name',\r
+       title: 'Link',\r
+       toAnchor: 'Link to anchor in the text',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link',\r
+       type: 'Link Type',\r
+       unlink: 'Unlink',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/en-gb.js b/sources/plugins/link/lang/en-gb.js
new file mode 100644 (file)
index 0000000..f0f3506
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'en-gb', {\r
+       acccessKey: 'Access Key',\r
+       advanced: 'Advanced',\r
+       advisoryContentType: 'Advisory Content Type',\r
+       advisoryTitle: 'Advisory Title',\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'By Element Id',\r
+       anchorName: 'By Anchor Name',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet Classes',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Address',\r
+       emailBody: 'Message Body',\r
+       emailSubject: 'Message Subject',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Language Code',\r
+       langDir: 'Language Direction',\r
+       langDirLTR: 'Left to Right (LTR)',\r
+       langDirRTL: 'Right to Left (RTL)',\r
+       menu: 'Edit Link',\r
+       name: 'Name',\r
+       noAnchors: '(No anchors available in the document)',\r
+       noEmail: 'Please type the e-mail address',\r
+       noUrl: 'Please type the link URL',\r
+       other: '<other>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'Popup Window Features',\r
+       popupFullScreen: 'Full Screen (IE)',\r
+       popupLeft: 'Left Position',\r
+       popupLocationBar: 'Location Bar',\r
+       popupMenuBar: 'Menu Bar',\r
+       popupResizable: 'Resizable',\r
+       popupScrollBars: 'Scroll Bars',\r
+       popupStatusBar: 'Status Bar',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Top Position',\r
+       rel: 'Relationship',\r
+       selectAnchor: 'Select an Anchor',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab Index',\r
+       target: 'Target',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Target Frame Name',\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Popup Window Name',\r
+       title: 'Link',\r
+       toAnchor: 'Link to anchor in the text',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link',\r
+       type: 'Link Type',\r
+       unlink: 'Unlink',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/en.js b/sources/plugins/link/lang/en.js
new file mode 100644 (file)
index 0000000..8f613de
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'en', {\r
+       acccessKey: 'Access Key',\r
+       advanced: 'Advanced',\r
+       advisoryContentType: 'Advisory Content Type',\r
+       advisoryTitle: 'Advisory Title',\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'By Element Id',\r
+       anchorName: 'By Anchor Name',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet Classes',\r
+       download: 'Force Download',\r
+       displayText: 'Display Text',\r
+       emailAddress: 'E-Mail Address',\r
+       emailBody: 'Message Body',\r
+       emailSubject: 'Message Subject',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Language Code',\r
+       langDir: 'Language Direction',\r
+       langDirLTR: 'Left to Right (LTR)',\r
+       langDirRTL: 'Right to Left (RTL)',\r
+       menu: 'Edit Link',\r
+       name: 'Name',\r
+       noAnchors: '(No anchors available in the document)',\r
+       noEmail: 'Please type the e-mail address',\r
+       noUrl: 'Please type the link URL',\r
+       other: '<other>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'Popup Window Features',\r
+       popupFullScreen: 'Full Screen (IE)',\r
+       popupLeft: 'Left Position',\r
+       popupLocationBar: 'Location Bar',\r
+       popupMenuBar: 'Menu Bar',\r
+       popupResizable: 'Resizable',\r
+       popupScrollBars: 'Scroll Bars',\r
+       popupStatusBar: 'Status Bar',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Top Position',\r
+       rel: 'Relationship',\r
+       selectAnchor: 'Select an Anchor',\r
+       styles: 'Style',\r
+       tabIndex: 'Tab Index',\r
+       target: 'Target',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Target Frame Name',\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Popup Window Name',\r
+       title: 'Link',\r
+       toAnchor: 'Link to anchor in the text',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link',\r
+       type: 'Link Type',\r
+       unlink: 'Unlink',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/eo.js b/sources/plugins/link/lang/eo.js
new file mode 100644 (file)
index 0000000..7991231
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'eo', {\r
+       acccessKey: 'Fulmoklavo',\r
+       advanced: 'Speciala',\r
+       advisoryContentType: 'Enhavotipo',\r
+       advisoryTitle: 'Priskriba Titolo',\r
+       anchor: {\r
+               toolbar: 'Ankro',\r
+               menu: 'Enmeti/Ŝanĝi Ankron',\r
+               title: 'Ankraj Atributoj',\r
+               name: 'Ankra Nomo',\r
+               errorName: 'Bv entajpi la ankran nomon',\r
+               remove: 'Forigi Ankron'\r
+       },\r
+       anchorId: 'Per Elementidentigilo',\r
+       anchorName: 'Per Ankronomo',\r
+       charset: 'Signaro de la Ligita Rimedo',\r
+       cssClasses: 'Klasoj de Stilfolioj',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Retpoŝto',\r
+       emailBody: 'Mesaĝa korpo',\r
+       emailSubject: 'Mesaĝa Temo',\r
+       id: 'Id',\r
+       info: 'Informoj pri la Ligilo',\r
+       langCode: 'Lingva Kodo',\r
+       langDir: 'Skribdirekto',\r
+       langDirLTR: 'De maldekstro dekstren (LTR)',\r
+       langDirRTL: 'De dekstro maldekstren (RTL)',\r
+       menu: 'Ŝanĝi Ligilon',\r
+       name: 'Nomo',\r
+       noAnchors: '<Ne disponeblas ankroj en la dokumento>',\r
+       noEmail: 'Bonvolu entajpi la retpoŝtadreson',\r
+       noUrl: 'Bonvolu entajpi la URL-on',\r
+       other: '<alia>',\r
+       popupDependent: 'Dependa (Netscape)',\r
+       popupFeatures: 'Atributoj de la Ŝprucfenestro',\r
+       popupFullScreen: 'Tutekrane (IE)',\r
+       popupLeft: 'Maldekstra Pozicio',\r
+       popupLocationBar: 'Adresobreto',\r
+       popupMenuBar: 'Menubreto',\r
+       popupResizable: 'Dimensiŝanĝebla',\r
+       popupScrollBars: 'Rulumskaloj',\r
+       popupStatusBar: 'Statobreto',\r
+       popupToolbar: 'Ilobreto',\r
+       popupTop: 'Supra Pozicio',\r
+       rel: 'Rilato',\r
+       selectAnchor: 'Elekti Ankron',\r
+       styles: 'Stilo',\r
+       tabIndex: 'Taba Indekso',\r
+       target: 'Celo',\r
+       targetFrame: '<kadro>',\r
+       targetFrameName: 'Nomo de CelKadro',\r
+       targetPopup: '<ŝprucfenestro>',\r
+       targetPopupName: 'Nomo de Ŝprucfenestro',\r
+       title: 'Ligilo',\r
+       toAnchor: 'Ankri en tiu ĉi paĝo',\r
+       toEmail: 'Retpoŝto',\r
+       toUrl: 'URL',\r
+       toolbar: 'Enmeti/Ŝanĝi Ligilon',\r
+       type: 'Tipo de Ligilo',\r
+       unlink: 'Forigi Ligilon',\r
+       upload: 'Alŝuti'\r
+} );\r
diff --git a/sources/plugins/link/lang/es.js b/sources/plugins/link/lang/es.js
new file mode 100644 (file)
index 0000000..700ad86
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'es', {\r
+       acccessKey: 'Tecla de Acceso',\r
+       advanced: 'Avanzado',\r
+       advisoryContentType: 'Tipo de Contenido',\r
+       advisoryTitle: 'Título',\r
+       anchor: {\r
+               toolbar: 'Referencia',\r
+               menu: 'Propiedades de Referencia',\r
+               title: 'Propiedades de Referencia',\r
+               name: 'Nombre de la Referencia',\r
+               errorName: 'Por favor, complete el nombre de la Referencia',\r
+               remove: 'Quitar Referencia'\r
+       },\r
+       anchorId: 'Por ID de elemento',\r
+       anchorName: 'Por Nombre de Referencia',\r
+       charset: 'Fuente de caracteres vinculado',\r
+       cssClasses: 'Clases de hojas de estilo',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Dirección de E-Mail',\r
+       emailBody: 'Cuerpo del Mensaje',\r
+       emailSubject: 'Título del Mensaje',\r
+       id: 'Id',\r
+       info: 'Información de Vínculo',\r
+       langCode: 'Código idioma',\r
+       langDir: 'Orientación',\r
+       langDirLTR: 'Izquierda a Derecha (LTR)',\r
+       langDirRTL: 'Derecha a Izquierda (RTL)',\r
+       menu: 'Editar Vínculo',\r
+       name: 'Nombre',\r
+       noAnchors: '(No hay referencias disponibles en el documento)',\r
+       noEmail: 'Por favor escriba la dirección de e-mail',\r
+       noUrl: 'Por favor escriba el vínculo URL',\r
+       other: '<otro>',\r
+       popupDependent: 'Dependiente (Netscape)',\r
+       popupFeatures: 'Características de Ventana Emergente',\r
+       popupFullScreen: 'Pantalla Completa (IE)',\r
+       popupLeft: 'Posición Izquierda',\r
+       popupLocationBar: 'Barra de ubicación',\r
+       popupMenuBar: 'Barra de Menú',\r
+       popupResizable: 'Redimensionable',\r
+       popupScrollBars: 'Barras de desplazamiento',\r
+       popupStatusBar: 'Barra de Estado',\r
+       popupToolbar: 'Barra de Herramientas',\r
+       popupTop: 'Posición Derecha',\r
+       rel: 'Relación',\r
+       selectAnchor: 'Seleccionar una referencia',\r
+       styles: 'Estilo',\r
+       tabIndex: 'Indice de tabulación',\r
+       target: 'Destino',\r
+       targetFrame: '<marco>',\r
+       targetFrameName: 'Nombre del Marco Destino',\r
+       targetPopup: '<ventana emergente>',\r
+       targetPopupName: 'Nombre de Ventana Emergente',\r
+       title: 'Vínculo',\r
+       toAnchor: 'Referencia en esta página',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Insertar/Editar Vínculo',\r
+       type: 'Tipo de vínculo',\r
+       unlink: 'Eliminar Vínculo',\r
+       upload: 'Cargar'\r
+} );\r
diff --git a/sources/plugins/link/lang/et.js b/sources/plugins/link/lang/et.js
new file mode 100644 (file)
index 0000000..7e31aa6
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'et', {\r
+       acccessKey: 'Juurdepääsu võti',\r
+       advanced: 'Täpsemalt',\r
+       advisoryContentType: 'Juhendava sisu tüüp',\r
+       advisoryTitle: 'Juhendav tiitel',\r
+       anchor: {\r
+               toolbar: 'Ankru sisestamine/muutmine',\r
+               menu: 'Ankru omadused',\r
+               title: 'Ankru omadused',\r
+               name: 'Ankru nimi',\r
+               errorName: 'Palun sisesta ankru nimi',\r
+               remove: 'Eemalda ankur'\r
+       },\r
+       anchorId: 'Elemendi id järgi',\r
+       anchorName: 'Ankru nime järgi',\r
+       charset: 'Lingitud ressursi märgistik',\r
+       cssClasses: 'Stiilistiku klassid',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-posti aadress',\r
+       emailBody: 'Sõnumi tekst',\r
+       emailSubject: 'Sõnumi teema',\r
+       id: 'ID',\r
+       info: 'Lingi info',\r
+       langCode: 'Keele suund',\r
+       langDir: 'Keele suund',\r
+       langDirLTR: 'Vasakult paremale (LTR)',\r
+       langDirRTL: 'Paremalt vasakule (RTL)',\r
+       menu: 'Muuda linki',\r
+       name: 'Nimi',\r
+       noAnchors: '(Selles dokumendis pole ankruid)',\r
+       noEmail: 'Palun kirjuta e-posti aadress',\r
+       noUrl: 'Palun kirjuta lingi URL',\r
+       other: '<muu>',\r
+       popupDependent: 'Sõltuv (Netscape)',\r
+       popupFeatures: 'Hüpikakna omadused',\r
+       popupFullScreen: 'Täisekraan (IE)',\r
+       popupLeft: 'Vasak asukoht',\r
+       popupLocationBar: 'Aadressiriba',\r
+       popupMenuBar: 'Menüüriba',\r
+       popupResizable: 'Suurust saab muuta',\r
+       popupScrollBars: 'Kerimisribad',\r
+       popupStatusBar: 'Olekuriba',\r
+       popupToolbar: 'Tööriistariba',\r
+       popupTop: 'Ülemine asukoht',\r
+       rel: 'Suhe',\r
+       selectAnchor: 'Vali ankur',\r
+       styles: 'Laad',\r
+       tabIndex: 'Tab indeks',\r
+       target: 'Sihtkoht',\r
+       targetFrame: '<raam>',\r
+       targetFrameName: 'Sihtmärk raami nimi',\r
+       targetPopup: '<hüpikaken>',\r
+       targetPopupName: 'Hüpikakna nimi',\r
+       title: 'Link',\r
+       toAnchor: 'Ankur sellel lehel',\r
+       toEmail: 'E-post',\r
+       toUrl: 'URL',\r
+       toolbar: 'Lingi lisamine/muutmine',\r
+       type: 'Lingi liik',\r
+       unlink: 'Lingi eemaldamine',\r
+       upload: 'Lae üles'\r
+} );\r
diff --git a/sources/plugins/link/lang/eu.js b/sources/plugins/link/lang/eu.js
new file mode 100644 (file)
index 0000000..7a2727e
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'eu', {\r
+       acccessKey: 'Sarbide-tekla',\r
+       advanced: 'Aurreratua',\r
+       advisoryContentType: 'Aholkatutako eduki-mota',\r
+       advisoryTitle: 'Aholkatutako izenburua',\r
+       anchor: {\r
+               toolbar: 'Aingura',\r
+               menu: 'Editatu aingura',\r
+               title: 'Ainguraren propietateak',\r
+               name: 'Ainguraren izena',\r
+               errorName: 'Idatzi ainguraren izena',\r
+               remove: 'Kendu aingura'\r
+       },\r
+       anchorId: 'Elementuaren Id-aren arabera',\r
+       anchorName: 'Aingura-izenaren arabera',\r
+       charset: 'Estekatutako baliabide karaktere-jokoa',\r
+       cssClasses: 'Estilo-orriko klaseak',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Bistaratu testua',\r
+       emailAddress: 'E-posta helbidea',\r
+       emailBody: 'Mezuaren gorputza',\r
+       emailSubject: 'Mezuaren gaia',\r
+       id: 'Id',\r
+       info: 'Estekaren informazioa',\r
+       langCode: 'Hizkuntzaren kodea',\r
+       langDir: 'Hizkuntzaren norabidea',\r
+       langDirLTR: 'Ezkerretik eskuinera (LTR)',\r
+       langDirRTL: 'Eskuinetik ezkerrera (RTL)',\r
+       menu: 'Editatu esteka',\r
+       name: 'Izena',\r
+       noAnchors: '(Ez dago aingurarik erabilgarri dokumentuan)',\r
+       noEmail: 'Mesedez idatzi e-posta helbidea',\r
+       noUrl: 'Mesedez idatzi estekaren URLa',\r
+       other: '<bestelakoa>',\r
+       popupDependent: 'Menpekoa (Netscape)',\r
+       popupFeatures: 'Laster-leihoaren ezaugarriak',\r
+       popupFullScreen: 'Pantaila osoa (IE)',\r
+       popupLeft: 'Ezkerreko posizioa',\r
+       popupLocationBar: 'Kokaleku-barra',\r
+       popupMenuBar: 'Menu-barra',\r
+       popupResizable: 'Tamaina aldakorra',\r
+       popupScrollBars: 'Korritze-barrak',\r
+       popupStatusBar: 'Egoera-barra',\r
+       popupToolbar: 'Tresna-barra',\r
+       popupTop: 'Goiko posizioa',\r
+       rel: 'Erlazioa',\r
+       selectAnchor: 'Hautatu aingura',\r
+       styles: 'Estiloa',\r
+       tabIndex: 'Tabulazio indizea',\r
+       target: 'Helburua',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Helburuko markoaren izena',\r
+       targetPopup: '<laster-leihoa>',\r
+       targetPopupName: 'Laster-leihoaren izena',\r
+       title: 'Esteka',\r
+       toAnchor: 'Estekatu testuko aingurara',\r
+       toEmail: 'E-posta',\r
+       toUrl: 'URLa',\r
+       toolbar: 'Esteka',\r
+       type: 'Esteka-mota',\r
+       unlink: 'Kendu esteka',\r
+       upload: 'Kargatu'\r
+} );\r
diff --git a/sources/plugins/link/lang/fa.js b/sources/plugins/link/lang/fa.js
new file mode 100644 (file)
index 0000000..525d899
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'fa', {\r
+       acccessKey: 'کلید دستیابی',\r
+       advanced: 'پیشرفته',\r
+       advisoryContentType: 'نوع محتوای کمکی',\r
+       advisoryTitle: 'عنوان کمکی',\r
+       anchor: {\r
+               toolbar: 'گنجاندن/ویرایش لنگر',\r
+               menu: 'ویژگی​های لنگر',\r
+               title: 'ویژگی​های لنگر',\r
+               name: 'نام لنگر',\r
+               errorName: 'لطفا نام لنگر را بنویسید',\r
+               remove: 'حذف لنگر'\r
+       },\r
+       anchorId: 'با شناسهٴ المان',\r
+       anchorName: 'با نام لنگر',\r
+       charset: 'نویسه​گان منبع پیوند شده',\r
+       cssClasses: 'کلاس​های شیوه​نامه(Stylesheet)',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'نشانی پست الکترونیکی',\r
+       emailBody: 'متن پیام',\r
+       emailSubject: 'موضوع پیام',\r
+       id: 'شناسه',\r
+       info: 'اطلاعات پیوند',\r
+       langCode: 'جهت​نمای زبان',\r
+       langDir: 'جهت​نمای زبان',\r
+       langDirLTR: 'چپ به راست (LTR)',\r
+       langDirRTL: 'راست به چپ (RTL)',\r
+       menu: 'ویرایش پیوند',\r
+       name: 'نام',\r
+       noAnchors: '(در این سند لنگری دردسترس نیست)',\r
+       noEmail: 'لطفا نشانی پست الکترونیکی را بنویسید',\r
+       noUrl: 'لطفا URL پیوند را بنویسید',\r
+       other: '<سایر>',\r
+       popupDependent: 'وابسته (Netscape)',\r
+       popupFeatures: 'ویژگی​های پنجرهٴ پاپاپ',\r
+       popupFullScreen: 'تمام صفحه (IE)',\r
+       popupLeft: 'موقعیت چپ',\r
+       popupLocationBar: 'نوار موقعیت',\r
+       popupMenuBar: 'نوار منو',\r
+       popupResizable: 'قابل تغییر اندازه',\r
+       popupScrollBars: 'میله​های پیمایش',\r
+       popupStatusBar: 'نوار وضعیت',\r
+       popupToolbar: 'نوار ابزار',\r
+       popupTop: 'موقعیت بالا',\r
+       rel: 'وابستگی',\r
+       selectAnchor: 'یک لنگر برگزینید',\r
+       styles: 'شیوه (style)',\r
+       tabIndex: 'نمایهٴ دسترسی با برگه',\r
+       target: 'مقصد',\r
+       targetFrame: '<فریم>',\r
+       targetFrameName: 'نام فریم مقصد',\r
+       targetPopup: '<پنجرهٴ پاپاپ>',\r
+       targetPopupName: 'نام پنجرهٴ پاپاپ',\r
+       title: 'پیوند',\r
+       toAnchor: 'لنگر در همین صفحه',\r
+       toEmail: 'پست الکترونیکی',\r
+       toUrl: 'URL',\r
+       toolbar: 'گنجاندن/ویرایش پیوند',\r
+       type: 'نوع پیوند',\r
+       unlink: 'برداشتن پیوند',\r
+       upload: 'انتقال به سرور'\r
+} );\r
diff --git a/sources/plugins/link/lang/fi.js b/sources/plugins/link/lang/fi.js
new file mode 100644 (file)
index 0000000..9ab5224
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'fi', {\r
+       acccessKey: 'Pikanäppäin',\r
+       advanced: 'Lisäominaisuudet',\r
+       advisoryContentType: 'Avustava sisällön tyyppi',\r
+       advisoryTitle: 'Avustava otsikko',\r
+       anchor: {\r
+               toolbar: 'Lisää ankkuri/muokkaa ankkuria',\r
+               menu: 'Ankkurin ominaisuudet',\r
+               title: 'Ankkurin ominaisuudet',\r
+               name: 'Nimi',\r
+               errorName: 'Ankkurille on kirjoitettava nimi',\r
+               remove: 'Poista ankkuri'\r
+       },\r
+       anchorId: 'Ankkurin ID:n mukaan',\r
+       anchorName: 'Ankkurin nimen mukaan',\r
+       charset: 'Linkitetty kirjaimisto',\r
+       cssClasses: 'Tyyliluokat',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Sähköpostiosoite',\r
+       emailBody: 'Viesti',\r
+       emailSubject: 'Aihe',\r
+       id: 'Tunniste',\r
+       info: 'Linkin tiedot',\r
+       langCode: 'Kielen suunta',\r
+       langDir: 'Kielen suunta',\r
+       langDirLTR: 'Vasemmalta oikealle (LTR)',\r
+       langDirRTL: 'Oikealta vasemmalle (RTL)',\r
+       menu: 'Muokkaa linkkiä',\r
+       name: 'Nimi',\r
+       noAnchors: '(Ei ankkureita tässä dokumentissa)',\r
+       noEmail: 'Kirjoita sähköpostiosoite',\r
+       noUrl: 'Linkille on kirjoitettava URL',\r
+       other: '<muu>',\r
+       popupDependent: 'Riippuva (Netscape)',\r
+       popupFeatures: 'Popup ikkunan ominaisuudet',\r
+       popupFullScreen: 'Täysi ikkuna (IE)',\r
+       popupLeft: 'Vasemmalta (px)',\r
+       popupLocationBar: 'Osoiterivi',\r
+       popupMenuBar: 'Valikkorivi',\r
+       popupResizable: 'Venytettävä',\r
+       popupScrollBars: 'Vierityspalkit',\r
+       popupStatusBar: 'Tilarivi',\r
+       popupToolbar: 'Vakiopainikkeet',\r
+       popupTop: 'Ylhäältä (px)',\r
+       rel: 'Suhde',\r
+       selectAnchor: 'Valitse ankkuri',\r
+       styles: 'Tyyli',\r
+       tabIndex: 'Tabulaattori indeksi',\r
+       target: 'Kohde',\r
+       targetFrame: '<kehys>',\r
+       targetFrameName: 'Kohdekehyksen nimi',\r
+       targetPopup: '<popup ikkuna>',\r
+       targetPopupName: 'Popup ikkunan nimi',\r
+       title: 'Linkki',\r
+       toAnchor: 'Ankkuri tässä sivussa',\r
+       toEmail: 'Sähköposti',\r
+       toUrl: 'Osoite',\r
+       toolbar: 'Lisää linkki/muokkaa linkkiä',\r
+       type: 'Linkkityyppi',\r
+       unlink: 'Poista linkki',\r
+       upload: 'Lisää tiedosto'\r
+} );\r
diff --git a/sources/plugins/link/lang/fo.js b/sources/plugins/link/lang/fo.js
new file mode 100644 (file)
index 0000000..90ab1ed
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'fo', {\r
+       acccessKey: 'Snarvegisknöttur',\r
+       advanced: 'Fjølbroytt',\r
+       advisoryContentType: 'Vegleiðandi innihaldsslag',\r
+       advisoryTitle: 'Vegleiðandi heiti',\r
+       anchor: {\r
+               toolbar: 'Ger/broyt marknastein',\r
+               menu: 'Eginleikar fyri marknastein',\r
+               title: 'Eginleikar fyri marknastein',\r
+               name: 'Heiti marknasteinsins',\r
+               errorName: 'Vinarliga rita marknasteinsins heiti',\r
+               remove: 'Strika marknastein'\r
+       },\r
+       anchorId: 'Eftir element Id',\r
+       anchorName: 'Eftir navni á marknasteini',\r
+       charset: 'Atknýtt teknsett',\r
+       cssClasses: 'Typografi klassar',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Teldupost-adressa',\r
+       emailBody: 'Breyðtekstur',\r
+       emailSubject: 'Evni',\r
+       id: 'Id',\r
+       info: 'Tilknýtis upplýsingar',\r
+       langCode: 'Tekstkós',\r
+       langDir: 'Tekstkós',\r
+       langDirLTR: 'Frá vinstru til høgru (LTR)',\r
+       langDirRTL: 'Frá høgru til vinstru (RTL)',\r
+       menu: 'Broyt tilknýti',\r
+       name: 'Navn',\r
+       noAnchors: '(Eingir marknasteinar eru í hesum dokumentið)',\r
+       noEmail: 'Vinarliga skriva teldupost-adressu',\r
+       noUrl: 'Vinarliga skriva tilknýti (URL)',\r
+       other: '<annað>',\r
+       popupDependent: 'Bundið (Netscape)',\r
+       popupFeatures: 'Popup vindeygans víðkaðu eginleikar',\r
+       popupFullScreen: 'Fullur skermur (IE)',\r
+       popupLeft: 'Frástøða frá vinstru',\r
+       popupLocationBar: 'Adressulinja',\r
+       popupMenuBar: 'Skrábjálki',\r
+       popupResizable: 'Stødd kann broytast',\r
+       popupScrollBars: 'Rullibjálki',\r
+       popupStatusBar: 'Støðufrágreiðingarbjálki',\r
+       popupToolbar: 'Amboðsbjálki',\r
+       popupTop: 'Frástøða frá íerva',\r
+       rel: 'Relatión',\r
+       selectAnchor: 'Vel ein marknastein',\r
+       styles: 'Typografi',\r
+       tabIndex: 'Tabulator indeks',\r
+       target: 'Target',\r
+       targetFrame: '<ramma>',\r
+       targetFrameName: 'Vís navn vindeygans',\r
+       targetPopup: '<popup vindeyga>',\r
+       targetPopupName: 'Popup vindeygans navn',\r
+       title: 'Tilknýti',\r
+       toAnchor: 'Tilknýti til marknastein í tekstinum',\r
+       toEmail: 'Teldupostur',\r
+       toUrl: 'URL',\r
+       toolbar: 'Ger/broyt tilknýti',\r
+       type: 'Tilknýtisslag',\r
+       unlink: 'Strika tilknýti',\r
+       upload: 'Send til ambætaran'\r
+} );\r
diff --git a/sources/plugins/link/lang/fr-ca.js b/sources/plugins/link/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..ddf2dde
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'fr-ca', {\r
+       acccessKey: 'Touche d\'accessibilité',\r
+       advanced: 'Avancé',\r
+       advisoryContentType: 'Type de contenu',\r
+       advisoryTitle: 'Description',\r
+       anchor: {\r
+               toolbar: 'Ancre',\r
+               menu: 'Modifier l\'ancre',\r
+               title: 'Propriétés de l\'ancre',\r
+               name: 'Nom de l\'ancre',\r
+               errorName: 'Veuillez saisir le nom de l\'ancre',\r
+               remove: 'Supprimer l\'ancre'\r
+       },\r
+       anchorId: 'Par ID',\r
+       anchorName: 'Par nom',\r
+       charset: 'Encodage de la cible',\r
+       cssClasses: 'Classes CSS',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Courriel',\r
+       emailBody: 'Corps du message',\r
+       emailSubject: 'Objet du message',\r
+       id: 'ID',\r
+       info: 'Informations sur le lien',\r
+       langCode: 'Code de langue',\r
+       langDir: 'Sens d\'écriture',\r
+       langDirLTR: 'De gauche à droite (LTR)',\r
+       langDirRTL: 'De droite à gauche (RTL)',\r
+       menu: 'Modifier le lien',\r
+       name: 'Nom',\r
+       noAnchors: '(Pas d\'ancre disponible dans le document)',\r
+       noEmail: 'Veuillez saisir le courriel',\r
+       noUrl: 'Veuillez saisir l\'URL',\r
+       other: '<autre>',\r
+       popupDependent: 'Dépendante (Netscape)',\r
+       popupFeatures: 'Caractéristiques de la fenêtre popup',\r
+       popupFullScreen: 'Plein écran (IE)',\r
+       popupLeft: 'Position de la gauche',\r
+       popupLocationBar: 'Barre d\'adresse',\r
+       popupMenuBar: 'Barre de menu',\r
+       popupResizable: 'Redimensionnable',\r
+       popupScrollBars: 'Barres de défilement',\r
+       popupStatusBar: 'Barre d\'état',\r
+       popupToolbar: 'Barre d\'outils',\r
+       popupTop: 'Position à partir du haut',\r
+       rel: 'Relation',\r
+       selectAnchor: 'Sélectionner une ancre',\r
+       styles: 'Style',\r
+       tabIndex: 'Ordre de tabulation',\r
+       target: 'Destination',\r
+       targetFrame: '<Cadre>',\r
+       targetFrameName: 'Nom du cadre de destination',\r
+       targetPopup: '<fenêtre popup>',\r
+       targetPopupName: 'Nom de la fenêtre popup',\r
+       title: 'Lien',\r
+       toAnchor: 'Ancre dans cette page',\r
+       toEmail: 'Courriel',\r
+       toUrl: 'URL',\r
+       toolbar: 'Lien',\r
+       type: 'Type de lien',\r
+       unlink: 'Supprimer le lien',\r
+       upload: 'Téléverser'\r
+} );\r
diff --git a/sources/plugins/link/lang/fr.js b/sources/plugins/link/lang/fr.js
new file mode 100644 (file)
index 0000000..a4561cb
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'fr', {\r
+       acccessKey: 'Touche d\'accessibilité',\r
+       advanced: 'Avancé',\r
+       advisoryContentType: 'Type de contenu (indicatif)',\r
+       advisoryTitle: 'Infobulle',\r
+       anchor: {\r
+               toolbar: 'Ancre',\r
+               menu: 'Modifier l\'ancre',\r
+               title: 'Propriétés de l\'ancre',\r
+               name: 'Nom de l\'ancre',\r
+               errorName: 'Veuillez entrer le nom de l\'ancre.',\r
+               remove: 'Supprimer l\'ancre'\r
+       },\r
+       anchorId: 'Par ID d\'élément',\r
+       anchorName: 'Par nom d\'ancre',\r
+       charset: 'Encodage de la ressource liée',\r
+       cssClasses: 'Classes de style',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Adresse électronique',\r
+       emailBody: 'Corps du message',\r
+       emailSubject: 'Sujet du message',\r
+       id: 'ID',\r
+       info: 'Informations sur le lien',\r
+       langCode: 'Code de langue',\r
+       langDir: 'Sens d\'écriture',\r
+       langDirLTR: 'Gauche à droite',\r
+       langDirRTL: 'Droite à gauche (RTL)',\r
+       menu: 'Modifier le lien',\r
+       name: 'Nom',\r
+       noAnchors: '(Aucune ancre disponible dans ce document)',\r
+       noEmail: 'Veuillez entrer l\'adresse électronique',\r
+       noUrl: 'Veuillez entrer l\'URL du lien',\r
+       other: '<autre>',\r
+       popupDependent: 'Dépendante (Netscape)',\r
+       popupFeatures: 'Caractéristiques de la fenêtre surgissante',\r
+       popupFullScreen: 'Plein écran (IE)',\r
+       popupLeft: 'À gauche',\r
+       popupLocationBar: 'Barre d\'adresse',\r
+       popupMenuBar: 'Barre de menu',\r
+       popupResizable: 'Redimensionnable',\r
+       popupScrollBars: 'Barres de défilement',\r
+       popupStatusBar: 'Barre d\'état',\r
+       popupToolbar: 'Barre d\'outils',\r
+       popupTop: 'En haut',\r
+       rel: 'Relation',\r
+       selectAnchor: 'Sélectionner une ancre',\r
+       styles: 'Style',\r
+       tabIndex: 'Indice de tabulation',\r
+       target: 'Cible',\r
+       targetFrame: '<cadre>',\r
+       targetFrameName: 'Nom du cadre affecté',\r
+       targetPopup: '<fenêtre surgissante>',\r
+       targetPopupName: 'Nom de la fenêtre surgissante',\r
+       title: 'Lien',\r
+       toAnchor: 'Ancre',\r
+       toEmail: 'Courriel',\r
+       toUrl: 'URL',\r
+       toolbar: 'Lien',\r
+       type: 'Type de lien',\r
+       unlink: 'Supprimer le lien',\r
+       upload: 'Téléverser'\r
+} );\r
diff --git a/sources/plugins/link/lang/gl.js b/sources/plugins/link/lang/gl.js
new file mode 100644 (file)
index 0000000..45ced42
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'gl', {\r
+       acccessKey: 'Chave de acceso',\r
+       advanced: 'Avanzado',\r
+       advisoryContentType: 'Tipo de contido informativo',\r
+       advisoryTitle: 'Título',\r
+       anchor: {\r
+               toolbar: 'Ancoraxe',\r
+               menu: 'Editar a ancoraxe',\r
+               title: 'Propiedades da ancoraxe',\r
+               name: 'Nome da ancoraxe',\r
+               errorName: 'Escriba o nome da ancoraxe',\r
+               remove: 'Retirar a ancoraxe'\r
+       },\r
+       anchorId: 'Polo ID do elemento',\r
+       anchorName: 'Polo nome da ancoraxe',\r
+       charset: 'Codificación do recurso ligado',\r
+       cssClasses: 'Clases da folla de estilos',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Enderezo de correo',\r
+       emailBody: 'Corpo da mensaxe',\r
+       emailSubject: 'Asunto da mensaxe',\r
+       id: 'ID',\r
+       info: 'Información da ligazón',\r
+       langCode: 'Código do idioma',\r
+       langDir: 'Dirección de escritura do idioma',\r
+       langDirLTR: 'Esquerda a dereita (LTR)',\r
+       langDirRTL: 'Dereita a esquerda (RTL)',\r
+       menu: 'Editar a ligazón',\r
+       name: 'Nome',\r
+       noAnchors: '(Non hai ancoraxes dispoñíbeis no documento)',\r
+       noEmail: 'Escriba o enderezo de correo',\r
+       noUrl: 'Escriba a ligazón URL',\r
+       other: '<outro>',\r
+       popupDependent: 'Dependente (Netscape)',\r
+       popupFeatures: 'Características da xanela emerxente',\r
+       popupFullScreen: 'Pantalla completa (IE)',\r
+       popupLeft: 'Posición esquerda',\r
+       popupLocationBar: 'Barra de localización',\r
+       popupMenuBar: 'Barra do menú',\r
+       popupResizable: 'Redimensionábel',\r
+       popupScrollBars: 'Barras de desprazamento',\r
+       popupStatusBar: 'Barra de estado',\r
+       popupToolbar: 'Barra de ferramentas',\r
+       popupTop: 'Posición superior',\r
+       rel: 'Relación',\r
+       selectAnchor: 'Seleccionar unha ancoraxe',\r
+       styles: 'Estilo',\r
+       tabIndex: 'Índice de tabulación',\r
+       target: 'Destino',\r
+       targetFrame: '<marco>',\r
+       targetFrameName: 'Nome do marco de destino',\r
+       targetPopup: '<xanela emerxente>',\r
+       targetPopupName: 'Nome da xanela emerxente',\r
+       title: 'Ligazón',\r
+       toAnchor: 'Ligar coa ancoraxe no testo',\r
+       toEmail: 'Correo',\r
+       toUrl: 'URL',\r
+       toolbar: 'Ligazón',\r
+       type: 'Tipo de ligazón',\r
+       unlink: 'Eliminar a ligazón',\r
+       upload: 'Enviar'\r
+} );\r
diff --git a/sources/plugins/link/lang/gu.js b/sources/plugins/link/lang/gu.js
new file mode 100644 (file)
index 0000000..2bbf577
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'gu', {\r
+       acccessKey: 'ઍક્સેસ કી',\r
+       advanced: 'અડ્વાન્સડ',\r
+       advisoryContentType: 'મુખ્ય કન્ટેન્ટ પ્રકાર',\r
+       advisoryTitle: 'મુખ્ય મથાળું',\r
+       anchor: {\r
+               toolbar: 'ઍંકર ઇન્સર્ટ/દાખલ કરવી',\r
+               menu: 'ઍંકરના ગુણ',\r
+               title: 'ઍંકરના ગુણ',\r
+               name: 'ઍંકરનું નામ',\r
+               errorName: 'ઍંકરનું નામ ટાઈપ કરો',\r
+               remove: 'સ્થિર નકરવું'\r
+       },\r
+       anchorId: 'ઍંકર એલિમન્ટ Id થી પસંદ કરો',\r
+       anchorName: 'ઍંકર નામથી પસંદ કરો',\r
+       charset: 'લિંક રિસૉર્સ કૅરિક્ટર સેટ',\r
+       cssClasses: 'સ્ટાઇલ-શીટ ક્લાસ',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ઈ-મેલ સરનામું',\r
+       emailBody: 'સંદેશ',\r
+       emailSubject: 'ઈ-મેલ વિષય',\r
+       id: 'Id',\r
+       info: 'લિંક ઇન્ફૉ ટૅબ',\r
+       langCode: 'ભાષા લેખવાની પદ્ધતિ',\r
+       langDir: 'ભાષા લેખવાની પદ્ધતિ',\r
+       langDirLTR: 'ડાબે થી જમણે (LTR)',\r
+       langDirRTL: 'જમણે થી ડાબે (RTL)',\r
+       menu: ' લિંક એડિટ/માં ફેરફાર કરવો',\r
+       name: 'નામ',\r
+       noAnchors: '(ડૉક્યુમન્ટમાં ઍંકરની સંખ્યા)',\r
+       noEmail: 'ઈ-મેલ સરનામું ટાઇપ કરો',\r
+       noUrl: 'લિંક  URL ટાઇપ કરો',\r
+       other: '<other> <અન્ય>',\r
+       popupDependent: 'ડિપેન્ડન્ટ (Netscape)',\r
+       popupFeatures: 'પૉપ-અપ વિન્ડો ફીચરસૅ',\r
+       popupFullScreen: 'ફુલ સ્ક્રીન (IE)',\r
+       popupLeft: 'ડાબી બાજુ',\r
+       popupLocationBar: 'લોકેશન બાર',\r
+       popupMenuBar: 'મેન્યૂ બાર',\r
+       popupResizable: 'રીસાઈઝએબલ',\r
+       popupScrollBars: 'સ્ક્રોલ બાર',\r
+       popupStatusBar: 'સ્ટૅટસ બાર',\r
+       popupToolbar: 'ટૂલ બાર',\r
+       popupTop: 'જમણી બાજુ',\r
+       rel: 'સંબંધની સ્થિતિ',\r
+       selectAnchor: 'ઍંકર પસંદ કરો',\r
+       styles: 'સ્ટાઇલ',\r
+       tabIndex: 'ટૅબ ઇન્ડેક્સ',\r
+       target: 'ટાર્ગેટ/લક્ષ્ય',\r
+       targetFrame: '<ફ્રેમ>',\r
+       targetFrameName: 'ટાર્ગેટ ફ્રેમ નું નામ',\r
+       targetPopup: '<પૉપ-અપ વિન્ડો>',\r
+       targetPopupName: 'પૉપ-અપ વિન્ડો નું નામ',\r
+       title: 'લિંક',\r
+       toAnchor: 'આ પેજનો ઍંકર',\r
+       toEmail: 'ઈ-મેલ',\r
+       toUrl: 'URL',\r
+       toolbar: 'લિંક ઇન્સર્ટ/દાખલ કરવી',\r
+       type: 'લિંક પ્રકાર',\r
+       unlink: 'લિંક કાઢવી',\r
+       upload: 'અપલોડ'\r
+} );\r
diff --git a/sources/plugins/link/lang/he.js b/sources/plugins/link/lang/he.js
new file mode 100644 (file)
index 0000000..a00f60a
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'he', {\r
+       acccessKey: 'מקש גישה',\r
+       advanced: 'אפשרויות מתקדמות',\r
+       advisoryContentType: 'Content Type מוצע',\r
+       advisoryTitle: 'כותרת מוצעת',\r
+       anchor: {\r
+               toolbar: 'הוספת/עריכת נקודת עיגון',\r
+               menu: 'מאפייני נקודת עיגון',\r
+               title: 'מאפייני נקודת עיגון',\r
+               name: 'שם לנקודת עיגון',\r
+               errorName: 'יש להקליד שם לנקודת עיגון',\r
+               remove: 'מחיקת נקודת עיגון'\r
+       },\r
+       anchorId: 'עפ"י זיהוי (ID) האלמנט',\r
+       anchorName: 'עפ"י שם העוגן',\r
+       charset: 'קידוד המשאב המקושר',\r
+       cssClasses: 'גיליונות עיצוב קבוצות',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'כתובת הדוא"ל',\r
+       emailBody: 'גוף ההודעה',\r
+       emailSubject: 'נושא ההודעה',\r
+       id: 'זיהוי (ID)',\r
+       info: 'מידע על הקישור',\r
+       langCode: 'קוד שפה',\r
+       langDir: 'כיוון שפה',\r
+       langDirLTR: 'שמאל לימין (LTR)',\r
+       langDirRTL: 'ימין לשמאל (RTL)',\r
+       menu: 'מאפייני קישור',\r
+       name: 'שם',\r
+       noAnchors: '(אין עוגנים זמינים בדף)',\r
+       noEmail: 'יש להקליד את כתובת הדוא"ל',\r
+       noUrl: 'יש להקליד את כתובת הקישור (URL)',\r
+       other: '<אחר>',\r
+       popupDependent: 'תלוי (Netscape)',\r
+       popupFeatures: 'תכונות החלון הקופץ',\r
+       popupFullScreen: 'מסך מלא (IE)',\r
+       popupLeft: 'מיקום צד שמאל',\r
+       popupLocationBar: 'סרגל כתובת',\r
+       popupMenuBar: 'סרגל תפריט',\r
+       popupResizable: 'שינוי גודל',\r
+       popupScrollBars: 'ניתן לגלילה',\r
+       popupStatusBar: 'סרגל חיווי',\r
+       popupToolbar: 'סרגל הכלים',\r
+       popupTop: 'מיקום צד עליון',\r
+       rel: 'קשר גומלין',\r
+       selectAnchor: 'בחירת עוגן',\r
+       styles: 'סגנון',\r
+       tabIndex: 'מספר טאב',\r
+       target: 'מטרה',\r
+       targetFrame: '<מסגרת>',\r
+       targetFrameName: 'שם מסגרת היעד',\r
+       targetPopup: '<חלון קופץ>',\r
+       targetPopupName: 'שם החלון הקופץ',\r
+       title: 'קישור',\r
+       toAnchor: 'עוגן בעמוד זה',\r
+       toEmail: 'דוא"ל',\r
+       toUrl: 'כתובת (URL)',\r
+       toolbar: 'הוספת/עריכת קישור',\r
+       type: 'סוג קישור',\r
+       unlink: 'הסרת הקישור',\r
+       upload: 'העלאה'\r
+} );\r
diff --git a/sources/plugins/link/lang/hi.js b/sources/plugins/link/lang/hi.js
new file mode 100644 (file)
index 0000000..88b7df9
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'hi', {\r
+       acccessKey: 'ऍक्सॅस की',\r
+       advanced: 'ऍड्वान्स्ड',\r
+       advisoryContentType: 'परामर्श कन्टॅन्ट प्रकार',\r
+       advisoryTitle: 'परामर्श शीर्शक',\r
+       anchor: {\r
+               toolbar: 'ऐंकर इन्सर्ट/संपादन',\r
+               menu: 'ऐंकर प्रॉपर्टीज़',\r
+               title: 'ऐंकर प्रॉपर्टीज़',\r
+               name: 'ऐंकर का नाम',\r
+               errorName: 'ऐंकर का नाम टाइप करें',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'ऍलीमॅन्ट Id से',\r
+       anchorName: 'ऐंकर नाम से',\r
+       charset: 'लिंक रिसोर्स करॅक्टर सॅट',\r
+       cssClasses: 'स्टाइल-शीट क्लास',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ई-मेल पता',\r
+       emailBody: 'संदेश',\r
+       emailSubject: 'संदेश विषय',\r
+       id: 'Id',\r
+       info: 'लिंक  ',\r
+       langCode: 'भाषा लिखने की दिशा',\r
+       langDir: 'भाषा लिखने की दिशा',\r
+       langDirLTR: 'बायें से दायें (LTR)',\r
+       langDirRTL: 'दायें से बायें (RTL)',\r
+       menu: 'लिंक संपादन',\r
+       name: 'नाम',\r
+       noAnchors: '(डॉक्यूमॅन्ट में ऐंकर्स की संख्या)',\r
+       noEmail: 'ई-मेल पता टाइप करें',\r
+       noUrl: 'लिंक URL टाइप करें',\r
+       other: '<अन्य>',\r
+       popupDependent: 'डिपेन्डॅन्ट (Netscape)',\r
+       popupFeatures: 'पॉप-अप विन्डो फ़ीचर्स',\r
+       popupFullScreen: 'फ़ुल स्क्रीन (IE)',\r
+       popupLeft: 'बायीं तरफ',\r
+       popupLocationBar: 'लोकेशन बार',\r
+       popupMenuBar: 'मॅन्यू बार',\r
+       popupResizable: 'आकार बदलने लायक',\r
+       popupScrollBars: 'स्क्रॉल बार',\r
+       popupStatusBar: 'स्टेटस बार',\r
+       popupToolbar: 'टूल बार',\r
+       popupTop: 'दायीं तरफ',\r
+       rel: 'संबंध',\r
+       selectAnchor: 'ऐंकर चुनें',\r
+       styles: 'स्टाइल',\r
+       tabIndex: 'टैब इन्डॅक्स',\r
+       target: 'टार्गेट',\r
+       targetFrame: '<फ़्रेम>',\r
+       targetFrameName: 'टार्गेट फ़्रेम का नाम',\r
+       targetPopup: '<पॉप-अप विन्डो>',\r
+       targetPopupName: 'पॉप-अप विन्डो का नाम',\r
+       title: 'लिंक',\r
+       toAnchor: 'इस पेज का ऐंकर',\r
+       toEmail: 'ई-मेल',\r
+       toUrl: 'URL',\r
+       toolbar: 'लिंक इन्सर्ट/संपादन',\r
+       type: 'लिंक प्रकार',\r
+       unlink: 'लिंक हटायें',\r
+       upload: 'अपलोड'\r
+} );\r
diff --git a/sources/plugins/link/lang/hr.js b/sources/plugins/link/lang/hr.js
new file mode 100644 (file)
index 0000000..898b18b
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'hr', {\r
+       acccessKey: 'Pristupna tipka',\r
+       advanced: 'Napredno',\r
+       advisoryContentType: 'Advisory vrsta sadržaja',\r
+       advisoryTitle: 'Advisory naslov',\r
+       anchor: {\r
+               toolbar: 'Ubaci/promijeni sidro',\r
+               menu: 'Svojstva sidra',\r
+               title: 'Svojstva sidra',\r
+               name: 'Ime sidra',\r
+               errorName: 'Molimo unesite ime sidra',\r
+               remove: 'Ukloni sidro'\r
+       },\r
+       anchorId: 'Po Id elementa',\r
+       anchorName: 'Po nazivu sidra',\r
+       charset: 'Kodna stranica povezanih resursa',\r
+       cssClasses: 'Stylesheet klase',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail adresa',\r
+       emailBody: 'Sadržaj poruke',\r
+       emailSubject: 'Naslov',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Smjer jezika',\r
+       langDir: 'Smjer jezika',\r
+       langDirLTR: 'S lijeva na desno (LTR)',\r
+       langDirRTL: 'S desna na lijevo (RTL)',\r
+       menu: 'Promijeni link',\r
+       name: 'Naziv',\r
+       noAnchors: '(Nema dostupnih sidra)',\r
+       noEmail: 'Molimo upišite e-mail adresu',\r
+       noUrl: 'Molimo upišite URL link',\r
+       other: '<drugi>',\r
+       popupDependent: 'Ovisno (Netscape)',\r
+       popupFeatures: 'Mogućnosti popup prozora',\r
+       popupFullScreen: 'Cijeli ekran (IE)',\r
+       popupLeft: 'Lijeva pozicija',\r
+       popupLocationBar: 'Traka za lokaciju',\r
+       popupMenuBar: 'Izborna traka',\r
+       popupResizable: 'Promjenjiva veličina',\r
+       popupScrollBars: 'Scroll traka',\r
+       popupStatusBar: 'Statusna traka',\r
+       popupToolbar: 'Traka s alatima',\r
+       popupTop: 'Gornja pozicija',\r
+       rel: 'Veza',\r
+       selectAnchor: 'Odaberi sidro',\r
+       styles: 'Stil',\r
+       tabIndex: 'Tab Indeks',\r
+       target: 'Meta',\r
+       targetFrame: '<okvir>',\r
+       targetFrameName: 'Ime ciljnog okvira',\r
+       targetPopup: '<popup prozor>',\r
+       targetPopupName: 'Naziv popup prozora',\r
+       title: 'Link',\r
+       toAnchor: 'Sidro na ovoj stranici',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Ubaci/promijeni link',\r
+       type: 'Link vrsta',\r
+       unlink: 'Ukloni link',\r
+       upload: 'Pošalji'\r
+} );\r
diff --git a/sources/plugins/link/lang/hu.js b/sources/plugins/link/lang/hu.js
new file mode 100644 (file)
index 0000000..52c09a8
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'hu', {\r
+       acccessKey: 'Billentyűkombináció',\r
+       advanced: 'További opciók',\r
+       advisoryContentType: 'Súgó tartalomtípusa',\r
+       advisoryTitle: 'Súgócimke',\r
+       anchor: {\r
+               toolbar: 'Horgony beillesztése/szerkesztése',\r
+               menu: 'Horgony tulajdonságai',\r
+               title: 'Horgony tulajdonságai',\r
+               name: 'Horgony neve',\r
+               errorName: 'Kérem adja meg a horgony nevét',\r
+               remove: 'Horgony eltávolítása'\r
+       },\r
+       anchorId: 'Azonosító szerint',\r
+       anchorName: 'Horgony név szerint',\r
+       charset: 'Hivatkozott tartalom kódlapja',\r
+       cssClasses: 'Stíluskészlet',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail cím',\r
+       emailBody: 'Üzenet',\r
+       emailSubject: 'Üzenet tárgya',\r
+       id: 'Id',\r
+       info: 'Alaptulajdonságok',\r
+       langCode: 'Írás iránya',\r
+       langDir: 'Írás iránya',\r
+       langDirLTR: 'Balról jobbra',\r
+       langDirRTL: 'Jobbról balra',\r
+       menu: 'Hivatkozás módosítása',\r
+       name: 'Név',\r
+       noAnchors: '(Nincs horgony a dokumentumban)',\r
+       noEmail: 'Adja meg az E-Mail címet',\r
+       noUrl: 'Adja meg a hivatkozás webcímét',\r
+       other: '<más>',\r
+       popupDependent: 'Szülőhöz kapcsolt (csak Netscape)',\r
+       popupFeatures: 'Felugró ablak jellemzői',\r
+       popupFullScreen: 'Teljes képernyő (csak IE)',\r
+       popupLeft: 'Bal pozíció',\r
+       popupLocationBar: 'Címsor',\r
+       popupMenuBar: 'Menü sor',\r
+       popupResizable: 'Átméretezés',\r
+       popupScrollBars: 'Gördítősáv',\r
+       popupStatusBar: 'Állapotsor',\r
+       popupToolbar: 'Eszköztár',\r
+       popupTop: 'Felső pozíció',\r
+       rel: 'Kapcsolat típusa',\r
+       selectAnchor: 'Horgony választása',\r
+       styles: 'Stílus',\r
+       tabIndex: 'Tabulátor index',\r
+       target: 'Tartalom megjelenítése',\r
+       targetFrame: '<keretben>',\r
+       targetFrameName: 'Keret neve',\r
+       targetPopup: '<felugró ablakban>',\r
+       targetPopupName: 'Felugró ablak neve',\r
+       title: 'Hivatkozás tulajdonságai',\r
+       toAnchor: 'Horgony az oldalon',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Hivatkozás beillesztése/módosítása',\r
+       type: 'Hivatkozás típusa',\r
+       unlink: 'Hivatkozás törlése',\r
+       upload: 'Feltöltés'\r
+} );\r
diff --git a/sources/plugins/link/lang/id.js b/sources/plugins/link/lang/id.js
new file mode 100644 (file)
index 0000000..e255eb5
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'id', {\r
+       acccessKey: 'Access Key', // MISSING\r
+       advanced: 'Advanced', // MISSING\r
+       advisoryContentType: 'Advisory Content Type', // MISSING\r
+       advisoryTitle: 'Penasehat Judul',\r
+       anchor: {\r
+               toolbar: 'Anchor', // MISSING\r
+               menu: 'Edit Anchor', // MISSING\r
+               title: 'Anchor Properties', // MISSING\r
+               name: 'Anchor Name', // MISSING\r
+               errorName: 'Please type the anchor name', // MISSING\r
+               remove: 'Remove Anchor' // MISSING\r
+       },\r
+       anchorId: 'By Element Id', // MISSING\r
+       anchorName: 'By Anchor Name', // MISSING\r
+       charset: 'Linked Resource Charset', // MISSING\r
+       cssClasses: 'Kelas Stylesheet',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Alamat E-mail',\r
+       emailBody: 'Message Body', // MISSING\r
+       emailSubject: 'Judul Pesan',\r
+       id: 'Id',\r
+       info: 'Link Info', // MISSING\r
+       langCode: 'Kode Bahasa',\r
+       langDir: 'Arah Bahasa',\r
+       langDirLTR: 'Kiri ke Kanan (LTR)',\r
+       langDirRTL: 'Kanan ke Kiri (RTL)',\r
+       menu: 'Sunting Tautan',\r
+       name: 'Nama',\r
+       noAnchors: '(No anchors available in the document)', // MISSING\r
+       noEmail: 'Silahkan ketikkan alamat e-mail',\r
+       noUrl: 'Silahkan ketik URL tautan',\r
+       other: '<lainnya>',\r
+       popupDependent: 'Dependent (Netscape)', // MISSING\r
+       popupFeatures: 'Popup Window Features', // MISSING\r
+       popupFullScreen: 'Full Screen (IE)', // MISSING\r
+       popupLeft: 'Left Position', // MISSING\r
+       popupLocationBar: 'Location Bar', // MISSING\r
+       popupMenuBar: 'Menu Bar', // MISSING\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Scroll Bars', // MISSING\r
+       popupStatusBar: 'Status Bar', // MISSING\r
+       popupToolbar: 'Toolbar', // MISSING\r
+       popupTop: 'Top Position', // MISSING\r
+       rel: 'Hubungan',\r
+       selectAnchor: 'Select an Anchor', // MISSING\r
+       styles: 'Gaya',\r
+       tabIndex: 'Tab Index', // MISSING\r
+       target: 'Sasaran',\r
+       targetFrame: '<frame>', // MISSING\r
+       targetFrameName: 'Target Frame Name', // MISSING\r
+       targetPopup: '<popup window>', // MISSING\r
+       targetPopupName: 'Popup Window Name', // MISSING\r
+       title: 'Tautan',\r
+       toAnchor: 'Link to anchor in the text', // MISSING\r
+       toEmail: 'E-mail', // MISSING\r
+       toUrl: 'URL',\r
+       toolbar: 'Tautan',\r
+       type: 'Link Type', // MISSING\r
+       unlink: 'Unlink', // MISSING\r
+       upload: 'Unggah'\r
+} );\r
diff --git a/sources/plugins/link/lang/is.js b/sources/plugins/link/lang/is.js
new file mode 100644 (file)
index 0000000..ccdea0a
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'is', {\r
+       acccessKey: 'Skammvalshnappur',\r
+       advanced: 'Tæknilegt',\r
+       advisoryContentType: 'Tegund innihalds',\r
+       advisoryTitle: 'Titill',\r
+       anchor: {\r
+               toolbar: 'Stofna/breyta kaflamerki',\r
+               menu: 'Eigindi kaflamerkis',\r
+               title: 'Eigindi kaflamerkis',\r
+               name: 'Nafn bókamerkis',\r
+               errorName: 'Sláðu inn nafn bókamerkis!',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'Eftir auðkenni einingar',\r
+       anchorName: 'Eftir akkerisnafni',\r
+       charset: 'Táknróf',\r
+       cssClasses: 'Stílsniðsflokkur',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Netfang',\r
+       emailBody: 'Meginmál',\r
+       emailSubject: 'Efni',\r
+       id: 'Auðkenni',\r
+       info: 'Almennt',\r
+       langCode: 'Lesstefna',\r
+       langDir: 'Lesstefna',\r
+       langDirLTR: 'Frá vinstri til hægri (LTR)',\r
+       langDirRTL: 'Frá hægri til vinstri (RTL)',\r
+       menu: 'Breyta stiklu',\r
+       name: 'Nafn',\r
+       noAnchors: '<Engin bókamerki á skrá>',\r
+       noEmail: 'Sláðu inn netfang!',\r
+       noUrl: 'Sláðu inn veffang stiklunnar!',\r
+       other: '<annar>',\r
+       popupDependent: 'Háð venslum (Netscape)',\r
+       popupFeatures: 'Eigindi sprettiglugga',\r
+       popupFullScreen: 'Heilskjár (IE)',\r
+       popupLeft: 'Fjarlægð frá vinstri',\r
+       popupLocationBar: 'Fanglína',\r
+       popupMenuBar: 'Vallína',\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Skrunstikur',\r
+       popupStatusBar: 'Stöðustika',\r
+       popupToolbar: 'Verkfærastika',\r
+       popupTop: 'Fjarlægð frá efri brún',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Veldu akkeri',\r
+       styles: 'Stíll',\r
+       tabIndex: 'Raðnúmer innsláttarreits',\r
+       target: 'Mark',\r
+       targetFrame: '<rammi>',\r
+       targetFrameName: 'Nafn markglugga',\r
+       targetPopup: '<sprettigluggi>',\r
+       targetPopupName: 'Nafn sprettiglugga',\r
+       title: 'Stikla',\r
+       toAnchor: 'Bókamerki á þessari síðu',\r
+       toEmail: 'Netfang',\r
+       toUrl: 'Vefslóð',\r
+       toolbar: 'Stofna/breyta stiklu',\r
+       type: 'Stikluflokkur',\r
+       unlink: 'Fjarlægja stiklu',\r
+       upload: 'Senda upp'\r
+} );\r
diff --git a/sources/plugins/link/lang/it.js b/sources/plugins/link/lang/it.js
new file mode 100644 (file)
index 0000000..b6b93bf
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'it', {\r
+       acccessKey: 'Scorciatoia da tastiera',\r
+       advanced: 'Avanzate',\r
+       advisoryContentType: 'Tipo della risorsa collegata',\r
+       advisoryTitle: 'Titolo',\r
+       anchor: {\r
+               toolbar: 'Inserisci/Modifica Ancora',\r
+               menu: 'Proprietà ancora',\r
+               title: 'Proprietà ancora',\r
+               name: 'Nome ancora',\r
+               errorName: 'Inserici il nome dell\'ancora',\r
+               remove: 'Rimuovi l\'ancora'\r
+       },\r
+       anchorId: 'Per id elemento',\r
+       anchorName: 'Per Nome',\r
+       charset: 'Set di caretteri della risorsa collegata',\r
+       cssClasses: 'Nome classe CSS',\r
+       download: 'Forza scaricamento',\r
+       displayText: 'Mostra testo',\r
+       emailAddress: 'Indirizzo E-Mail',\r
+       emailBody: 'Corpo del messaggio',\r
+       emailSubject: 'Oggetto del messaggio',\r
+       id: 'Id',\r
+       info: 'Informazioni collegamento',\r
+       langCode: 'Direzione scrittura',\r
+       langDir: 'Direzione scrittura',\r
+       langDirLTR: 'Da Sinistra a Destra (LTR)',\r
+       langDirRTL: 'Da Destra a Sinistra (RTL)',\r
+       menu: 'Modifica collegamento',\r
+       name: 'Nome',\r
+       noAnchors: '(Nessuna ancora disponibile nel documento)',\r
+       noEmail: 'Devi inserire un\'indirizzo e-mail',\r
+       noUrl: 'Devi inserire l\'URL del collegamento',\r
+       other: '<altro>',\r
+       popupDependent: 'Dipendente (Netscape)',\r
+       popupFeatures: 'Caratteristiche finestra popup',\r
+       popupFullScreen: 'A tutto schermo (IE)',\r
+       popupLeft: 'Posizione da sinistra',\r
+       popupLocationBar: 'Barra degli indirizzi',\r
+       popupMenuBar: 'Barra del menu',\r
+       popupResizable: 'Ridimensionabile',\r
+       popupScrollBars: 'Barre di scorrimento',\r
+       popupStatusBar: 'Barra di stato',\r
+       popupToolbar: 'Barra degli strumenti',\r
+       popupTop: 'Posizione dall\'alto',\r
+       rel: 'Relazioni',\r
+       selectAnchor: 'Scegli Ancora',\r
+       styles: 'Stile',\r
+       tabIndex: 'Ordine di tabulazione',\r
+       target: 'Destinazione',\r
+       targetFrame: '<riquadro>',\r
+       targetFrameName: 'Nome del riquadro di destinazione',\r
+       targetPopup: '<finestra popup>',\r
+       targetPopupName: 'Nome finestra popup',\r
+       title: 'Collegamento',\r
+       toAnchor: 'Ancora nel testo',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Collegamento',\r
+       type: 'Tipo di Collegamento',\r
+       unlink: 'Elimina collegamento',\r
+       upload: 'Carica'\r
+} );\r
diff --git a/sources/plugins/link/lang/ja.js b/sources/plugins/link/lang/ja.js
new file mode 100644 (file)
index 0000000..94108b5
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ja', {\r
+       acccessKey: 'アクセスキー',\r
+       advanced: '高度な設定',\r
+       advisoryContentType: 'Content Type属性',\r
+       advisoryTitle: 'Title属性',\r
+       anchor: {\r
+               toolbar: 'アンカー挿入/編集',\r
+               menu: 'アンカーの編集',\r
+               title: 'アンカーのプロパティ',\r
+               name: 'アンカー名',\r
+               errorName: 'アンカー名を入力してください。',\r
+               remove: 'アンカーを削除'\r
+       },\r
+       anchorId: 'エレメントID',\r
+       anchorName: 'アンカー名',\r
+       charset: 'リンク先のcharset',\r
+       cssClasses: 'スタイルシートクラス',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail アドレス',\r
+       emailBody: '本文',\r
+       emailSubject: '件名',\r
+       id: 'Id',\r
+       info: 'ハイパーリンク情報',\r
+       langCode: '言語コード',\r
+       langDir: '文字表記の方向',\r
+       langDirLTR: '左から右 (LTR)',\r
+       langDirRTL: '右から左 (RTL)',\r
+       menu: 'リンクを編集',\r
+       name: 'Name属性',\r
+       noAnchors: '(このドキュメント内にアンカーはありません)',\r
+       noEmail: 'メールアドレスを入力してください。',\r
+       noUrl: 'リンクURLを入力してください。',\r
+       other: '<その他の>',\r
+       popupDependent: '開いたウィンドウに連動して閉じる (Netscape)',\r
+       popupFeatures: 'ポップアップウィンドウ特徴',\r
+       popupFullScreen: '全画面モード(IE)',\r
+       popupLeft: '左端からの座標で指定',\r
+       popupLocationBar: 'ロケーションバー',\r
+       popupMenuBar: 'メニューバー',\r
+       popupResizable: 'サイズ可変',\r
+       popupScrollBars: 'スクロールバー',\r
+       popupStatusBar: 'ステータスバー',\r
+       popupToolbar: 'ツールバー',\r
+       popupTop: '上端からの座標で指定',\r
+       rel: '関連リンク',\r
+       selectAnchor: 'アンカーを選択',\r
+       styles: 'スタイルシート',\r
+       tabIndex: 'タブインデックス',\r
+       target: 'ターゲット',\r
+       targetFrame: '<フレーム>',\r
+       targetFrameName: 'ターゲットのフレーム名',\r
+       targetPopup: '<ポップアップウィンドウ>',\r
+       targetPopupName: 'ポップアップウィンドウ名',\r
+       title: 'ハイパーリンク',\r
+       toAnchor: 'ページ内のアンカー',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'リンク挿入/編集',\r
+       type: 'リンクタイプ',\r
+       unlink: 'リンクを削除',\r
+       upload: 'アップロード'\r
+} );\r
diff --git a/sources/plugins/link/lang/ka.js b/sources/plugins/link/lang/ka.js
new file mode 100644 (file)
index 0000000..439c43d
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ka', {\r
+       acccessKey: 'წვდომის ღილაკი',\r
+       advanced: 'დაწვრილებით',\r
+       advisoryContentType: 'შიგთავსის ტიპი',\r
+       advisoryTitle: 'სათაური',\r
+       anchor: {\r
+               toolbar: 'ღუზა',\r
+               menu: 'ღუზის რედაქტირება',\r
+               title: 'ღუზის პარამეტრები',\r
+               name: 'ღუზუს სახელი',\r
+               errorName: 'აკრიფეთ ღუზის სახელი',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'ელემენტის Id-თ',\r
+       anchorName: 'ღუზის სახელით',\r
+       charset: 'კოდირება',\r
+       cssClasses: 'CSS კლასი',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ელფოსტის მისამართები',\r
+       emailBody: 'წერილის ტექსტი',\r
+       emailSubject: 'წერილის სათაური',\r
+       id: 'Id',\r
+       info: 'ბმულის ინფორმაცია',\r
+       langCode: 'ენის კოდი',\r
+       langDir: 'ენის მიმართულება',\r
+       langDirLTR: 'მარცხნიდან მარჯვნივ (LTR)',\r
+       langDirRTL: 'მარჯვნიდან მარცხნივ (RTL)',\r
+       menu: 'ბმულის რედაქტირება',\r
+       name: 'სახელი',\r
+       noAnchors: '(ამ დოკუმენტში ღუზა არაა)',\r
+       noEmail: 'აკრიფეთ ელფოსტის მისამართი',\r
+       noUrl: 'აკრიფეთ ბმულის URL',\r
+       other: '<სხვა>',\r
+       popupDependent: 'დამოკიდებული (Netscape)',\r
+       popupFeatures: 'Popup ფანჯრის პარამეტრები',\r
+       popupFullScreen: 'მთელი ეკრანი (IE)',\r
+       popupLeft: 'მარცხენა პოზიცია',\r
+       popupLocationBar: 'ნავიგაციის ზოლი',\r
+       popupMenuBar: 'მენიუს ზოლი',\r
+       popupResizable: 'ცვალებადი ზომით',\r
+       popupScrollBars: 'გადახვევის ზოლები',\r
+       popupStatusBar: 'სტატუსის ზოლი',\r
+       popupToolbar: 'ხელსაწყოთა ზოლი',\r
+       popupTop: 'ზედა პოზიცია',\r
+       rel: 'კავშირი',\r
+       selectAnchor: 'აირჩიეთ ღუზა',\r
+       styles: 'CSS სტილი',\r
+       tabIndex: 'Tab-ის ინდექსი',\r
+       target: 'გახსნის ადგილი',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Frame-ის სახელი',\r
+       targetPopup: '<popup ფანჯარა>',\r
+       targetPopupName: 'Popup ფანჯრის სახელი',\r
+       title: 'ბმული',\r
+       toAnchor: 'ბმული ტექსტში ღუზაზე',\r
+       toEmail: 'ელფოსტა',\r
+       toUrl: 'URL',\r
+       toolbar: 'ბმული',\r
+       type: 'ბმულის ტიპი',\r
+       unlink: 'ბმულის მოხსნა',\r
+       upload: 'აქაჩვა'\r
+} );\r
diff --git a/sources/plugins/link/lang/km.js b/sources/plugins/link/lang/km.js
new file mode 100644 (file)
index 0000000..5d0be03
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'km', {\r
+       acccessKey: 'សោរ​ចូល',\r
+       advanced: 'កម្រិត​ខ្ពស់',\r
+       advisoryContentType: 'ប្រភេទអត្ថបទ​ប្រឹក្សា',\r
+       advisoryTitle: 'ចំណងជើង​ប្រឹក្សា',\r
+       anchor: {\r
+               toolbar: 'យុថ្កា',\r
+               menu: 'កែ​យុថ្កា',\r
+               title: 'លក្ខណៈ​យុថ្កា',\r
+               name: 'ឈ្មោះ​យុថ្កា',\r
+               errorName: 'សូម​បញ្ចូល​ឈ្មោះ​យុថ្កា',\r
+               remove: 'ដក​យុថ្កា​ចេញ'\r
+       },\r
+       anchorId: 'តាម ID ធាតុ',\r
+       anchorName: 'តាម​ឈ្មោះ​យុថ្កា',\r
+       charset: 'លេខកូតអក្សររបស់ឈ្នាប់',\r
+       cssClasses: 'Stylesheet Classes',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'អាសយដ្ឋាន​អ៊ីមែល',\r
+       emailBody: 'តួ​អត្ថបទ',\r
+       emailSubject: 'ប្រធានបទ​សារ',\r
+       id: 'Id',\r
+       info: 'ព័ត៌មាន​ពី​តំណ',\r
+       langCode: 'កូដ​ភាសា',\r
+       langDir: 'ទិសដៅភាសា',\r
+       langDirLTR: 'ពីឆ្វេងទៅស្តាំ(LTR)',\r
+       langDirRTL: 'ពីស្តាំទៅឆ្វេង(RTL)',\r
+       menu: 'កែ​តំណ',\r
+       name: 'ឈ្មោះ',\r
+       noAnchors: '(មិន​មាន​យុថ្កា​នៅ​ក្នុង​ឯកសារ​អត្ថថបទ​ទេ)',\r
+       noEmail: 'សូម​បញ្ចូល​អាសយដ្ឋាន​អ៊ីមែល',\r
+       noUrl: 'សូម​បញ្ចូល​តំណ URL',\r
+       other: '<ផ្សេង​ទៀត>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'មុខ​ងារ​ផុស​ផ្ទាំង​វីនដូ​ឡើង',\r
+       popupFullScreen: 'ពេញ​អេក្រង់ (IE)',\r
+       popupLeft: 'ទីតាំងខាងឆ្វេង',\r
+       popupLocationBar: 'របារ​ទីតាំង',\r
+       popupMenuBar: 'របារ​ម៉ឺនុយ',\r
+       popupResizable: 'អាច​ប្ដូរ​ទំហំ',\r
+       popupScrollBars: 'របារ​រំកិល',\r
+       popupStatusBar: 'របារ​ស្ថានភាព',\r
+       popupToolbar: 'របារ​ឧបករណ៍',\r
+       popupTop: 'ទីតាំង​កំពូល',\r
+       rel: 'សម្ពន្ធ​ភាព',\r
+       selectAnchor: 'រើស​យក​យុថ្កា​មួយ',\r
+       styles: 'ស្ទីល',\r
+       tabIndex: 'លេខ Tab',\r
+       target: 'គោលដៅ',\r
+       targetFrame: '<ស៊ុម>',\r
+       targetFrameName: 'ឈ្មោះ​ស៊ុម​ជា​គោល​ដៅ',\r
+       targetPopup: '<វីនដូ​ផុស​ឡើង>',\r
+       targetPopupName: 'ឈ្មោះ​វីនដូត​ផុស​ឡើង',\r
+       title: 'តំណ',\r
+       toAnchor: 'ត​ភ្ជាប់​ទៅ​យុថ្កា​ក្នុង​អត្ថបទ',\r
+       toEmail: 'អ៊ីមែល',\r
+       toUrl: 'URL',\r
+       toolbar: 'តំណ',\r
+       type: 'ប្រភេទ​តំណ',\r
+       unlink: 'ផ្ដាច់​តំណ',\r
+       upload: 'ផ្ទុក​ឡើង'\r
+} );\r
diff --git a/sources/plugins/link/lang/ko.js b/sources/plugins/link/lang/ko.js
new file mode 100644 (file)
index 0000000..86a797d
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ko', {\r
+       acccessKey: '액세스 키',\r
+       advanced: '고급',\r
+       advisoryContentType: '보조 콘텐츠 유형',\r
+       advisoryTitle: '보조 제목',\r
+       anchor: {\r
+               toolbar: '책갈피',\r
+               menu: '책갈피 편집',\r
+               title: '책갈피 속성',\r
+               name: '책갈피 이름',\r
+               errorName: '책갈피 이름을 입력하십시오',\r
+               remove: '책갈피 제거'\r
+       },\r
+       anchorId: '책갈피 ID',\r
+       anchorName: '책갈피 이름',\r
+       charset: '링크된 자료 문자열 인코딩',\r
+       cssClasses: '스타일시트 클래스',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: '이메일 주소',\r
+       emailBody: '메시지 내용',\r
+       emailSubject: '메시지 제목',\r
+       id: 'ID',\r
+       info: '링크 정보',\r
+       langCode: '언어 코드',\r
+       langDir: '언어 방향',\r
+       langDirLTR: '왼쪽에서 오른쪽 (LTR)',\r
+       langDirRTL: '오른쪽에서 왼쪽 (RTL)',\r
+       menu: '링크 수정',\r
+       name: '이름',\r
+       noAnchors: '(문서에 책갈피가 없습니다.)',\r
+       noEmail: '이메일 주소를 입력하십시오',\r
+       noUrl: '링크 주소(URL)를 입력하십시오',\r
+       other: '<기타>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: '팝업창 속성',\r
+       popupFullScreen: '전체화면 (IE)',\r
+       popupLeft: '왼쪽 위치',\r
+       popupLocationBar: '주소 표시줄',\r
+       popupMenuBar: '메뉴 바',\r
+       popupResizable: '크기 조절 가능',\r
+       popupScrollBars: '스크롤 바',\r
+       popupStatusBar: '상태 바',\r
+       popupToolbar: '툴바',\r
+       popupTop: '위쪽 위치',\r
+       rel: '관계',\r
+       selectAnchor: '책갈피 선택',\r
+       styles: '스타일',\r
+       tabIndex: '탭 순서',\r
+       target: '타겟',\r
+       targetFrame: '<프레임>',\r
+       targetFrameName: '타겟 프레임 이름',\r
+       targetPopup: '<팝업 창>',\r
+       targetPopupName: '팝업 창 이름',\r
+       title: '링크',\r
+       toAnchor: '책갈피',\r
+       toEmail: '이메일',\r
+       toUrl: '주소(URL)',\r
+       toolbar: '링크 삽입/변경',\r
+       type: '링크 종류',\r
+       unlink: '링크 지우기',\r
+       upload: '업로드'\r
+} );\r
diff --git a/sources/plugins/link/lang/ku.js b/sources/plugins/link/lang/ku.js
new file mode 100644 (file)
index 0000000..16faf24
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ku', {\r
+       acccessKey: 'کلیلی دەستپێگەیشتن',\r
+       advanced: 'پێشکەوتوو',\r
+       advisoryContentType: 'جۆری ناوەڕۆکی ڕاویژکار',\r
+       advisoryTitle: 'ڕاوێژکاری سەردێڕ',\r
+       anchor: {\r
+               toolbar: 'دانان/چاکسازی لەنگەر',\r
+               menu: 'چاکسازی لەنگەر',\r
+               title: 'خاسیەتی لەنگەر',\r
+               name: 'ناوی لەنگەر',\r
+               errorName: 'تکایه ناوی لەنگەر بنووسه',\r
+               remove: 'لابردنی لەنگەر'\r
+       },\r
+       anchorId: 'بەپێی ناسنامەی توخم',\r
+       anchorName: 'بەپێی ناوی لەنگەر',\r
+       charset: 'بەستەری سەرچاوەی نووسە',\r
+       cssClasses: 'شێوازی چینی پەڕه',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ناونیشانی ئیمەیل',\r
+       emailBody: 'ناوەڕۆکی نامە',\r
+       emailSubject: 'بابەتی نامە',\r
+       id: 'ناسنامە',\r
+       info: 'زانیاری بەستەر',\r
+       langCode: 'هێمای زمان',\r
+       langDir: 'ئاراستەی زمان',\r
+       langDirLTR: 'چەپ بۆ ڕاست (LTR)',\r
+       langDirRTL: 'ڕاست بۆ چەپ (RTL)',\r
+       menu: 'چاکسازی بەستەر',\r
+       name: 'ناو',\r
+       noAnchors: '(هیچ جۆرێکی لەنگەر ئامادە نیە لەم پەڕەیه)',\r
+       noEmail: 'تکایە ناونیشانی ئیمەیل بنووسە',\r
+       noUrl: 'تکایە ناونیشانی بەستەر بنووسە',\r
+       other: '<هیتر>',\r
+       popupDependent: 'پێوەبەستراو (Netscape)',\r
+       popupFeatures: 'خاسیەتی پەنجەرەی سەرهەڵدەر',\r
+       popupFullScreen: 'پڕ بەپڕی شاشە (IE)',\r
+       popupLeft: 'جێگای چەپ',\r
+       popupLocationBar: 'هێڵی ناونیشانی بەستەر',\r
+       popupMenuBar: 'هێڵی لیسته',\r
+       popupResizable: 'توانای گۆڕینی قەباره',\r
+       popupScrollBars: 'هێڵی هاتووچۆپێکردن',\r
+       popupStatusBar: 'هێڵی دۆخ',\r
+       popupToolbar: 'هێڵی تووڵامراز',\r
+       popupTop: 'جێگای سەرەوە',\r
+       rel: 'پەیوەندی',\r
+       selectAnchor: 'هەڵبژاردنی لەنگەرێك',\r
+       styles: 'شێواز',\r
+       tabIndex: 'بازدەری تابی  ئیندێکس',\r
+       target: 'ئامانج',\r
+       targetFrame: '<چووارچێوە>',\r
+       targetFrameName: 'ناوی ئامانجی چووارچێوە',\r
+       targetPopup: '<پەنجەرەی سەرهەڵدەر>',\r
+       targetPopupName: 'ناوی پەنجەرەی سەرهەڵدەر',\r
+       title: 'بەستەر',\r
+       toAnchor: 'بەستەر بۆ لەنگەر له دەق',\r
+       toEmail: 'ئیمەیل',\r
+       toUrl: 'ناونیشانی بەستەر',\r
+       toolbar: 'دانان/ڕێکخستنی بەستەر',\r
+       type: 'جۆری بەستەر',\r
+       unlink: 'لابردنی بەستەر',\r
+       upload: 'بارکردن'\r
+} );\r
diff --git a/sources/plugins/link/lang/lt.js b/sources/plugins/link/lang/lt.js
new file mode 100644 (file)
index 0000000..27aa8b7
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'lt', {\r
+       acccessKey: 'Prieigos raktas',\r
+       advanced: 'Papildomas',\r
+       advisoryContentType: 'Konsultacinio turinio tipas',\r
+       advisoryTitle: 'Konsultacinė antraštė',\r
+       anchor: {\r
+               toolbar: 'Įterpti/modifikuoti žymę',\r
+               menu: 'Žymės savybės',\r
+               title: 'Žymės savybės',\r
+               name: 'Žymės vardas',\r
+               errorName: 'Prašome įvesti žymės vardą',\r
+               remove: 'Pašalinti žymę'\r
+       },\r
+       anchorId: 'Pagal žymės Id',\r
+       anchorName: 'Pagal žymės vardą',\r
+       charset: 'Susietų išteklių simbolių lentelė',\r
+       cssClasses: 'Stilių lentelės klasės',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'El.pašto adresas',\r
+       emailBody: 'Žinutės turinys',\r
+       emailSubject: 'Žinutės tema',\r
+       id: 'Id',\r
+       info: 'Nuorodos informacija',\r
+       langCode: 'Teksto kryptis',\r
+       langDir: 'Teksto kryptis',\r
+       langDirLTR: 'Iš kairės į dešinę (LTR)',\r
+       langDirRTL: 'Iš dešinės į kairę (RTL)',\r
+       menu: 'Taisyti nuorodą',\r
+       name: 'Vardas',\r
+       noAnchors: '(Šiame dokumente žymių nėra)',\r
+       noEmail: 'Prašome įvesti el.pašto adresą',\r
+       noUrl: 'Prašome įvesti nuorodos URL',\r
+       other: '<kitas>',\r
+       popupDependent: 'Priklausomas (Netscape)',\r
+       popupFeatures: 'Išskleidžiamo lango savybės',\r
+       popupFullScreen: 'Visas ekranas (IE)',\r
+       popupLeft: 'Kairė pozicija',\r
+       popupLocationBar: 'Adreso juosta',\r
+       popupMenuBar: 'Meniu juosta',\r
+       popupResizable: 'Kintamas dydis',\r
+       popupScrollBars: 'Slinkties juostos',\r
+       popupStatusBar: 'Būsenos juosta',\r
+       popupToolbar: 'Mygtukų juosta',\r
+       popupTop: 'Viršutinė pozicija',\r
+       rel: 'Sąsajos',\r
+       selectAnchor: 'Pasirinkite žymę',\r
+       styles: 'Stilius',\r
+       tabIndex: 'Tabuliavimo indeksas',\r
+       target: 'Paskirties vieta',\r
+       targetFrame: '<kadras>',\r
+       targetFrameName: 'Paskirties kadro vardas',\r
+       targetPopup: '<išskleidžiamas langas>',\r
+       targetPopupName: 'Paskirties lango vardas',\r
+       title: 'Nuoroda',\r
+       toAnchor: 'Žymė šiame puslapyje',\r
+       toEmail: 'El.paštas',\r
+       toUrl: 'Nuoroda',\r
+       toolbar: 'Įterpti/taisyti nuorodą',\r
+       type: 'Nuorodos tipas',\r
+       unlink: 'Panaikinti nuorodą',\r
+       upload: 'Siųsti'\r
+} );\r
diff --git a/sources/plugins/link/lang/lv.js b/sources/plugins/link/lang/lv.js
new file mode 100644 (file)
index 0000000..ef8a3f2
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'lv', {\r
+       acccessKey: 'Pieejas taustiņš',\r
+       advanced: 'Izvērstais',\r
+       advisoryContentType: 'Konsultatīvs satura tips',\r
+       advisoryTitle: 'Konsultatīvs virsraksts',\r
+       anchor: {\r
+               toolbar: 'Ievietot/Labot iezīmi',\r
+               menu: 'Labot iezīmi',\r
+               title: 'Iezīmes uzstādījumi',\r
+               name: 'Iezīmes nosaukums',\r
+               errorName: 'Lūdzu norādiet iezīmes nosaukumu',\r
+               remove: 'Noņemt iezīmi'\r
+       },\r
+       anchorId: 'Pēc elementa ID',\r
+       anchorName: 'Pēc iezīmes nosaukuma',\r
+       charset: 'Pievienotā resursa kodējums',\r
+       cssClasses: 'Stilu saraksta klases',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-pasta adrese',\r
+       emailBody: 'Ziņas saturs',\r
+       emailSubject: 'Ziņas tēma',\r
+       id: 'ID',\r
+       info: 'Hipersaites informācija',\r
+       langCode: 'Valodas kods',\r
+       langDir: 'Valodas lasīšanas virziens',\r
+       langDirLTR: 'No kreisās uz labo (LTR)',\r
+       langDirRTL: 'No labās uz kreiso (RTL)',\r
+       menu: 'Labot hipersaiti',\r
+       name: 'Nosaukums',\r
+       noAnchors: '(Šajā dokumentā nav iezīmju)',\r
+       noEmail: 'Lūdzu norādi e-pasta adresi',\r
+       noUrl: 'Lūdzu norādi hipersaiti',\r
+       other: '<cits>',\r
+       popupDependent: 'Atkarīgs (Netscape)',\r
+       popupFeatures: 'Uznirstošā loga nosaukums īpašības',\r
+       popupFullScreen: 'Pilnā ekrānā (IE)',\r
+       popupLeft: 'Kreisā koordināte',\r
+       popupLocationBar: 'Atrašanās vietas josla',\r
+       popupMenuBar: 'Izvēlnes josla',\r
+       popupResizable: 'Mērogojams',\r
+       popupScrollBars: 'Ritjoslas',\r
+       popupStatusBar: 'Statusa josla',\r
+       popupToolbar: 'Rīku josla',\r
+       popupTop: 'Augšējā koordināte',\r
+       rel: 'Relācija',\r
+       selectAnchor: 'Izvēlēties iezīmi',\r
+       styles: 'Stils',\r
+       tabIndex: 'Ciļņu indekss',\r
+       target: 'Mērķis',\r
+       targetFrame: '<ietvars>',\r
+       targetFrameName: 'Mērķa ietvara nosaukums',\r
+       targetPopup: '<uznirstošā logā>',\r
+       targetPopupName: 'Uznirstošā loga nosaukums',\r
+       title: 'Hipersaite',\r
+       toAnchor: 'Iezīme šajā lapā',\r
+       toEmail: 'E-pasts',\r
+       toUrl: 'Adrese',\r
+       toolbar: 'Ievietot/Labot hipersaiti',\r
+       type: 'Hipersaites tips',\r
+       unlink: 'Noņemt hipersaiti',\r
+       upload: 'Augšupielādēt'\r
+} );\r
diff --git a/sources/plugins/link/lang/mk.js b/sources/plugins/link/lang/mk.js
new file mode 100644 (file)
index 0000000..5fb9655
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'mk', {\r
+       acccessKey: 'Access Key', // MISSING\r
+       advanced: 'Advanced', // MISSING\r
+       advisoryContentType: 'Advisory Content Type', // MISSING\r
+       advisoryTitle: 'Advisory Title', // MISSING\r
+       anchor: {\r
+               toolbar: 'Anchor',\r
+               menu: 'Edit Anchor',\r
+               title: 'Anchor Properties',\r
+               name: 'Anchor Name',\r
+               errorName: 'Please type the anchor name',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'By Element Id', // MISSING\r
+       anchorName: 'By Anchor Name', // MISSING\r
+       charset: 'Linked Resource Charset', // MISSING\r
+       cssClasses: 'Stylesheet Classes', // MISSING\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Address', // MISSING\r
+       emailBody: 'Message Body', // MISSING\r
+       emailSubject: 'Message Subject', // MISSING\r
+       id: 'Id',\r
+       info: 'Link Info', // MISSING\r
+       langCode: 'Код на јазик',\r
+       langDir: 'Насока на јазик',\r
+       langDirLTR: 'Лево кон десно',\r
+       langDirRTL: 'Десно кон лево',\r
+       menu: 'Edit Link', // MISSING\r
+       name: 'Name',\r
+       noAnchors: '(No anchors available in the document)', // MISSING\r
+       noEmail: 'Please type the e-mail address', // MISSING\r
+       noUrl: 'Please type the link URL', // MISSING\r
+       other: '<other>', // MISSING\r
+       popupDependent: 'Dependent (Netscape)', // MISSING\r
+       popupFeatures: 'Popup Window Features', // MISSING\r
+       popupFullScreen: 'Full Screen (IE)', // MISSING\r
+       popupLeft: 'Left Position', // MISSING\r
+       popupLocationBar: 'Location Bar', // MISSING\r
+       popupMenuBar: 'Menu Bar', // MISSING\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Scroll Bars', // MISSING\r
+       popupStatusBar: 'Status Bar', // MISSING\r
+       popupToolbar: 'Toolbar', // MISSING\r
+       popupTop: 'Top Position', // MISSING\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Select an Anchor', // MISSING\r
+       styles: 'Стил',\r
+       tabIndex: 'Tab Index', // MISSING\r
+       target: 'Target', // MISSING\r
+       targetFrame: '<frame>', // MISSING\r
+       targetFrameName: 'Target Frame Name', // MISSING\r
+       targetPopup: '<popup window>', // MISSING\r
+       targetPopupName: 'Popup Window Name', // MISSING\r
+       title: 'Врска',\r
+       toAnchor: 'Link to anchor in the text', // MISSING\r
+       toEmail: 'E-mail', // MISSING\r
+       toUrl: 'URL',\r
+       toolbar: 'Врска',\r
+       type: 'Link Type', // MISSING\r
+       unlink: 'Unlink', // MISSING\r
+       upload: 'Прикачи'\r
+} );\r
diff --git a/sources/plugins/link/lang/mn.js b/sources/plugins/link/lang/mn.js
new file mode 100644 (file)
index 0000000..ed159c7
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'mn', {\r
+       acccessKey: 'Холбох түлхүүр',\r
+       advanced: 'Нэмэлт',\r
+       advisoryContentType: 'Зөвлөлдөх төрлийн агуулга',\r
+       advisoryTitle: 'Зөвлөлдөх гарчиг',\r
+       anchor: {\r
+               toolbar: 'Зангуу',\r
+               menu: 'Зангууг болосруулах',\r
+               title: 'Зангуугийн шинж чанар',\r
+               name: 'Зангуугийн нэр',\r
+               errorName: 'Зангуугийн нэрийг оруулна уу',\r
+               remove: 'Зангууг устгах'\r
+       },\r
+       anchorId: 'Элемэнтйн Id нэрээр',\r
+       anchorName: 'Зангуугийн нэрээр',\r
+       charset: 'Тэмдэгт оноох нөөцөд холбогдсон',\r
+       cssClasses: 'Stylesheet классууд',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Э-шуудангийн хаяг',\r
+       emailBody: 'Зурвасны их бие',\r
+       emailSubject: 'Зурвасны гарчиг',\r
+       id: 'Id',\r
+       info: 'Холбоосын тухай мэдээлэл',\r
+       langCode: 'Хэлний код',\r
+       langDir: 'Хэлний чиглэл',\r
+       langDirLTR: 'Зүүнээс баруун (LTR)',\r
+       langDirRTL: 'Баруунаас зүүн (RTL)',\r
+       menu: 'Холбоос засварлах',\r
+       name: 'Нэр',\r
+       noAnchors: '(Баримт бичиг зангуугүй байна)',\r
+       noEmail: 'Э-шуудангий хаягаа шивнэ үү',\r
+       noUrl: 'Холбоосны URL хаягийг шивнэ үү',\r
+       other: '<other>', // MISSING\r
+       popupDependent: 'Хамаатай (Netscape)',\r
+       popupFeatures: 'Popup цонхны онцлог',\r
+       popupFullScreen: 'Цонх дүүргэх (Internet Explorer)',\r
+       popupLeft: 'Зүүн байрлал',\r
+       popupLocationBar: 'Location хэсэг',\r
+       popupMenuBar: 'Цэсний самбар',\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Скрол хэсэгүүд',\r
+       popupStatusBar: 'Статус хэсэг',\r
+       popupToolbar: 'Багажны самбар',\r
+       popupTop: 'Дээд байрлал',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Нэг зангууг сонгоно уу',\r
+       styles: 'Загвар',\r
+       tabIndex: 'Tab индекс',\r
+       target: 'Байрлал',\r
+       targetFrame: '<Агуулах хүрээ>',\r
+       targetFrameName: 'Очих фремын нэр',\r
+       targetPopup: '<popup цонх>',\r
+       targetPopupName: 'Popup цонхны нэр',\r
+       title: 'Холбоос',\r
+       toAnchor: 'Энэ бичвэр дэх зангуу руу очих холбоос',\r
+       toEmail: 'Э-захиа',\r
+       toUrl: 'цахим хуудасны хаяг (URL)',\r
+       toolbar: 'Холбоос',\r
+       type: 'Линкийн төрөл',\r
+       unlink: 'Холбоос авч хаях',\r
+       upload: 'Хуулах'\r
+} );\r
diff --git a/sources/plugins/link/lang/ms.js b/sources/plugins/link/lang/ms.js
new file mode 100644 (file)
index 0000000..9a2e499
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ms', {\r
+       acccessKey: 'Kunci Akses',\r
+       advanced: 'Advanced',\r
+       advisoryContentType: 'Jenis Kandungan Makluman',\r
+       advisoryTitle: 'Tajuk Makluman',\r
+       anchor: {\r
+               toolbar: 'Masukkan/Sunting Pautan',\r
+               menu: 'Ciri-ciri Pautan',\r
+               title: 'Ciri-ciri Pautan',\r
+               name: 'Nama Pautan',\r
+               errorName: 'Sila taip nama pautan',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'dengan menggunakan ID elemen',\r
+       anchorName: 'dengan menggunakan nama pautan',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Kelas-kelas Stylesheet',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Alamat E-Mail',\r
+       emailBody: 'Isi Kandungan Mesej',\r
+       emailSubject: 'Subjek Mesej',\r
+       id: 'Id',\r
+       info: 'Butiran Sambungan',\r
+       langCode: 'Arah Tulisan',\r
+       langDir: 'Arah Tulisan',\r
+       langDirLTR: 'Kiri ke Kanan (LTR)',\r
+       langDirRTL: 'Kanan ke Kiri (RTL)',\r
+       menu: 'Sunting Sambungan',\r
+       name: 'Nama',\r
+       noAnchors: '(Tiada pautan terdapat dalam dokumen ini)',\r
+       noEmail: 'Sila taip alamat e-mail',\r
+       noUrl: 'Sila taip sambungan URL',\r
+       other: '<lain>',\r
+       popupDependent: 'Bergantungan (Netscape)',\r
+       popupFeatures: 'Ciri Tetingkap Popup',\r
+       popupFullScreen: 'Skrin Penuh (IE)',\r
+       popupLeft: 'Posisi Kiri',\r
+       popupLocationBar: 'Bar Lokasi',\r
+       popupMenuBar: 'Bar Menu',\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Bar-bar skrol',\r
+       popupStatusBar: 'Bar Status',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Posisi Atas',\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Sila pilih pautan',\r
+       styles: 'Stail',\r
+       tabIndex: 'Indeks Tab ',\r
+       target: 'Sasaran',\r
+       targetFrame: '<bingkai>',\r
+       targetFrameName: 'Nama Bingkai Sasaran',\r
+       targetPopup: '<tetingkap popup>',\r
+       targetPopupName: 'Nama Tetingkap Popup',\r
+       title: 'Sambungan',\r
+       toAnchor: 'Pautan dalam muka surat ini',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Masukkan/Sunting Sambungan',\r
+       type: 'Jenis Sambungan',\r
+       unlink: 'Buang Sambungan',\r
+       upload: 'Muat Naik'\r
+} );\r
diff --git a/sources/plugins/link/lang/nb.js b/sources/plugins/link/lang/nb.js
new file mode 100644 (file)
index 0000000..7253b4a
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'nb', {\r
+       acccessKey: 'Aksessknapp',\r
+       advanced: 'Avansert',\r
+       advisoryContentType: 'Type',\r
+       advisoryTitle: 'Tittel',\r
+       anchor: {\r
+               toolbar: 'Anker',\r
+               menu: 'Rediger anker',\r
+               title: 'Egenskaper for anker',\r
+               name: 'Ankernavn',\r
+               errorName: 'Vennligst skriv inn ankernavnet',\r
+               remove: 'Fjern anker'\r
+       },\r
+       anchorId: 'Element etter ID',\r
+       anchorName: 'Anker etter navn',\r
+       charset: 'Lenket tegnsett',\r
+       cssClasses: 'Stilarkklasser',\r
+       download: 'Tving nedlasting',\r
+       displayText: 'Tekst som skal vises',\r
+       emailAddress: 'E-postadresse',\r
+       emailBody: 'Melding',\r
+       emailSubject: 'Meldingsemne',\r
+       id: 'Id',\r
+       info: 'Lenkeinfo',\r
+       langCode: 'Språkkode',\r
+       langDir: 'Språkretning',\r
+       langDirLTR: 'Venstre til høyre (LTR)',\r
+       langDirRTL: 'Høyre til venstre (RTL)',\r
+       menu: 'Rediger lenke',\r
+       name: 'Navn',\r
+       noAnchors: '(Ingen anker i dokumentet)',\r
+       noEmail: 'Vennligst skriv inn e-postadressen',\r
+       noUrl: 'Vennligst skriv inn lenkens URL',\r
+       other: '<annen>',\r
+       popupDependent: 'Avhenging (Netscape)',\r
+       popupFeatures: 'Egenskaper for popup-vindu',\r
+       popupFullScreen: 'Fullskjerm (IE)',\r
+       popupLeft: 'Venstre posisjon',\r
+       popupLocationBar: 'Adresselinje',\r
+       popupMenuBar: 'Menylinje',\r
+       popupResizable: 'Skalerbar',\r
+       popupScrollBars: 'Scrollbar',\r
+       popupStatusBar: 'Statuslinje',\r
+       popupToolbar: 'Verktøylinje',\r
+       popupTop: 'Topp-posisjon',\r
+       rel: 'Relasjon (rel)',\r
+       selectAnchor: 'Velg et anker',\r
+       styles: 'Stil',\r
+       tabIndex: 'Tabindeks',\r
+       target: 'Mål',\r
+       targetFrame: '<ramme>',\r
+       targetFrameName: 'Målramme',\r
+       targetPopup: '<popup-vindu>',\r
+       targetPopupName: 'Navn på popup-vindu',\r
+       title: 'Lenke',\r
+       toAnchor: 'Lenke til anker i teksten',\r
+       toEmail: 'E-post',\r
+       toUrl: 'URL',\r
+       toolbar: 'Lenke',\r
+       type: 'Lenketype',\r
+       unlink: 'Fjern lenke',\r
+       upload: 'Last opp'\r
+} );\r
diff --git a/sources/plugins/link/lang/nl.js b/sources/plugins/link/lang/nl.js
new file mode 100644 (file)
index 0000000..12cb509
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'nl', {\r
+       acccessKey: 'Toegangstoets',\r
+       advanced: 'Geavanceerd',\r
+       advisoryContentType: 'Aanbevolen content-type',\r
+       advisoryTitle: 'Adviserende titel',\r
+       anchor: {\r
+               toolbar: 'Interne link',\r
+               menu: 'Eigenschappen interne link',\r
+               title: 'Eigenschappen interne link',\r
+               name: 'Naam interne link',\r
+               errorName: 'Geef de naam van de interne link op',\r
+               remove: 'Interne link verwijderen'\r
+       },\r
+       anchorId: 'Op kenmerk interne link',\r
+       anchorName: 'Op naam interne link',\r
+       charset: 'Karakterset van gelinkte bron',\r
+       cssClasses: 'Stylesheet-klassen',\r
+       download: 'Download forceren',\r
+       displayText: 'Weergavetekst',\r
+       emailAddress: 'E-mailadres',\r
+       emailBody: 'Inhoud bericht',\r
+       emailSubject: 'Onderwerp bericht',\r
+       id: 'Id',\r
+       info: 'Linkomschrijving',\r
+       langCode: 'Taalcode',\r
+       langDir: 'Schrijfrichting',\r
+       langDirLTR: 'Links naar rechts (LTR)',\r
+       langDirRTL: 'Rechts naar links (RTL)',\r
+       menu: 'Link wijzigen',\r
+       name: 'Naam',\r
+       noAnchors: '(Geen interne links in document gevonden)',\r
+       noEmail: 'Geef een e-mailadres',\r
+       noUrl: 'Geef de link van de URL',\r
+       other: '<ander>',\r
+       popupDependent: 'Afhankelijk (Netscape)',\r
+       popupFeatures: 'Instellingen popupvenster',\r
+       popupFullScreen: 'Volledig scherm (IE)',\r
+       popupLeft: 'Positie links',\r
+       popupLocationBar: 'Locatiemenu',\r
+       popupMenuBar: 'Menubalk',\r
+       popupResizable: 'Herschaalbaar',\r
+       popupScrollBars: 'Schuifbalken',\r
+       popupStatusBar: 'Statusbalk',\r
+       popupToolbar: 'Werkbalk',\r
+       popupTop: 'Positie boven',\r
+       rel: 'Relatie',\r
+       selectAnchor: 'Kies een interne link',\r
+       styles: 'Stijl',\r
+       tabIndex: 'Tabvolgorde',\r
+       target: 'Doelvenster',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Naam doelframe',\r
+       targetPopup: '<popupvenster>',\r
+       targetPopupName: 'Naam popupvenster',\r
+       title: 'Link',\r
+       toAnchor: 'Interne link in pagina',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link invoegen/wijzigen',\r
+       type: 'Linktype',\r
+       unlink: 'Link verwijderen',\r
+       upload: 'Upload'\r
+} );\r
diff --git a/sources/plugins/link/lang/no.js b/sources/plugins/link/lang/no.js
new file mode 100644 (file)
index 0000000..bdd7fc6
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'no', {\r
+       acccessKey: 'Aksessknapp',\r
+       advanced: 'Avansert',\r
+       advisoryContentType: 'Type',\r
+       advisoryTitle: 'Tittel',\r
+       anchor: {\r
+               toolbar: 'Sett inn/Rediger anker',\r
+               menu: 'Egenskaper for anker',\r
+               title: 'Egenskaper for anker',\r
+               name: 'Ankernavn',\r
+               errorName: 'Vennligst skriv inn ankernavnet',\r
+               remove: 'Fjern anker'\r
+       },\r
+       anchorId: 'Element etter ID',\r
+       anchorName: 'Anker etter navn',\r
+       charset: 'Lenket tegnsett',\r
+       cssClasses: 'Stilarkklasser',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Tekst som skal vises',\r
+       emailAddress: 'E-postadresse',\r
+       emailBody: 'Melding',\r
+       emailSubject: 'Meldingsemne',\r
+       id: 'Id',\r
+       info: 'Lenkeinfo',\r
+       langCode: 'Språkkode',\r
+       langDir: 'Språkretning',\r
+       langDirLTR: 'Venstre til høyre (VTH)',\r
+       langDirRTL: 'Høyre til venstre (HTV)',\r
+       menu: 'Rediger lenke',\r
+       name: 'Navn',\r
+       noAnchors: '(Ingen anker i dokumentet)',\r
+       noEmail: 'Vennligst skriv inn e-postadressen',\r
+       noUrl: 'Vennligst skriv inn lenkens URL',\r
+       other: '<annen>',\r
+       popupDependent: 'Avhenging (Netscape)',\r
+       popupFeatures: 'Egenskaper for popup-vindu',\r
+       popupFullScreen: 'Fullskjerm (IE)',\r
+       popupLeft: 'Venstre posisjon',\r
+       popupLocationBar: 'Adresselinje',\r
+       popupMenuBar: 'Menylinje',\r
+       popupResizable: 'Skalerbar',\r
+       popupScrollBars: 'Scrollbar',\r
+       popupStatusBar: 'Statuslinje',\r
+       popupToolbar: 'Verktøylinje',\r
+       popupTop: 'Topp-posisjon',\r
+       rel: 'Relasjon (rel)',\r
+       selectAnchor: 'Velg et anker',\r
+       styles: 'Stil',\r
+       tabIndex: 'Tabindeks',\r
+       target: 'Mål',\r
+       targetFrame: '<ramme>',\r
+       targetFrameName: 'Målramme',\r
+       targetPopup: '<popup-vindu>',\r
+       targetPopupName: 'Navn på popup-vindu',\r
+       title: 'Lenke',\r
+       toAnchor: 'Lenke til anker i teksten',\r
+       toEmail: 'E-post',\r
+       toUrl: 'URL',\r
+       toolbar: 'Sett inn/Rediger lenke',\r
+       type: 'Lenketype',\r
+       unlink: 'Fjern lenke',\r
+       upload: 'Last opp'\r
+} );\r
diff --git a/sources/plugins/link/lang/oc.js b/sources/plugins/link/lang/oc.js
new file mode 100644 (file)
index 0000000..f9e51cd
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'oc', {\r
+       acccessKey: 'Tòca d\'accessibilitat',\r
+       advanced: 'Avançat',\r
+       advisoryContentType: 'Tipe de contengut (indicatiu)',\r
+       advisoryTitle: 'Infobulla',\r
+       anchor: {\r
+               toolbar: 'Ancòra',\r
+               menu: 'Modificar l\'ancòra',\r
+               title: 'Proprietats de l\'ancòra',\r
+               name: 'Nom de l\'ancòra',\r
+               errorName: 'Entratz lo nom de l\'ancòra',\r
+               remove: 'Suprimir l\'ancòra'\r
+       },\r
+       anchorId: 'Per ID d\'element',\r
+       anchorName: 'Per nom d\'ancòra',\r
+       charset: 'Encodatge de la ressorsa ligada',\r
+       cssClasses: 'Classas d\'estil',\r
+       download: 'Forçar lo telecargament',\r
+       displayText: 'Afichar lo tèxte',\r
+       emailAddress: 'Adreça electronica',\r
+       emailBody: 'Còs del messatge',\r
+       emailSubject: 'Subjècte del messatge',\r
+       id: 'Id',\r
+       info: 'Informacions sul ligam',\r
+       langCode: 'Còdi de lenga',\r
+       langDir: 'Sens d\'escritura',\r
+       langDirLTR: 'Esquèrra a dreita (LTR)',\r
+       langDirRTL: 'Dreita a esquèrra (RTL)',\r
+       menu: 'Modificar lo ligam',\r
+       name: 'Nom',\r
+       noAnchors: '(Cap d\'ancòra pas disponibla dins aqueste document)',\r
+       noEmail: 'Entratz l\'adreça electronica',\r
+       noUrl: 'Entratz l\'URL del ligam',\r
+       other: '<autre>',\r
+       popupDependent: 'Dependenta (Netscape)',\r
+       popupFeatures: 'Caracteristicas de la fenèstra sorgissenta',\r
+       popupFullScreen: 'Ecran complet (IE)',\r
+       popupLeft: 'A esquèrra',\r
+       popupLocationBar: 'Barra d\'adreça',\r
+       popupMenuBar: 'Barra de menú',\r
+       popupResizable: 'Redimensionable',\r
+       popupScrollBars: 'Barras de desfilament',\r
+       popupStatusBar: 'Barra d\'estat',\r
+       popupToolbar: 'Barra d\'aisinas',\r
+       popupTop: 'Amont',\r
+       rel: 'Relacion',\r
+       selectAnchor: 'Seleccionar una ancòra',\r
+       styles: 'Estil',\r
+       tabIndex: 'Indici de tabulacion',\r
+       target: 'Cibla',\r
+       targetFrame: '<quadre>',\r
+       targetFrameName: 'Nom del quadre afectat',\r
+       targetPopup: '<fenèstra sorgissenta>',\r
+       targetPopupName: 'Nom de la fenèstra sorgissenta',\r
+       title: 'Ligam',\r
+       toAnchor: 'Ancòra',\r
+       toEmail: 'Corrièl',\r
+       toUrl: 'URL',\r
+       toolbar: 'Ligam',\r
+       type: 'Tipe de ligam',\r
+       unlink: 'Suprimir lo ligam',\r
+       upload: 'Mandar'\r
+} );\r
diff --git a/sources/plugins/link/lang/pl.js b/sources/plugins/link/lang/pl.js
new file mode 100644 (file)
index 0000000..41858d3
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'pl', {\r
+       acccessKey: 'Klawisz dostępu',\r
+       advanced: 'Zaawansowane',\r
+       advisoryContentType: 'Typ MIME obiektu docelowego',\r
+       advisoryTitle: 'Opis obiektu docelowego',\r
+       anchor: {\r
+               toolbar: 'Wstaw/edytuj kotwicę',\r
+               menu: 'Właściwości kotwicy',\r
+               title: 'Właściwości kotwicy',\r
+               name: 'Nazwa kotwicy',\r
+               errorName: 'Wpisz nazwę kotwicy',\r
+               remove: 'Usuń kotwicę'\r
+       },\r
+       anchorId: 'Wg identyfikatora',\r
+       anchorName: 'Wg nazwy',\r
+       charset: 'Kodowanie znaków obiektu docelowego',\r
+       cssClasses: 'Nazwa klasy CSS',\r
+       download: 'Wymuś pobieranie',\r
+       displayText: 'Wyświetlany tekst',\r
+       emailAddress: 'Adres e-mail',\r
+       emailBody: 'Treść',\r
+       emailSubject: 'Temat',\r
+       id: 'Id',\r
+       info: 'Informacje ',\r
+       langCode: 'Kod języka',\r
+       langDir: 'Kierunek tekstu',\r
+       langDirLTR: 'Od lewej do prawej (LTR)',\r
+       langDirRTL: 'Od prawej do lewej (RTL)',\r
+       menu: 'Edytuj odnośnik',\r
+       name: 'Nazwa',\r
+       noAnchors: '(W dokumencie nie zdefiniowano żadnych kotwic)',\r
+       noEmail: 'Podaj adres e-mail',\r
+       noUrl: 'Podaj adres URL',\r
+       other: '<inny>',\r
+       popupDependent: 'Okno zależne (Netscape)',\r
+       popupFeatures: 'Właściwości wyskakującego okna',\r
+       popupFullScreen: 'Pełny ekran (IE)',\r
+       popupLeft: 'Pozycja w poziomie',\r
+       popupLocationBar: 'Pasek adresu',\r
+       popupMenuBar: 'Pasek menu',\r
+       popupResizable: 'Skalowalny',\r
+       popupScrollBars: 'Paski przewijania',\r
+       popupStatusBar: 'Pasek statusu',\r
+       popupToolbar: 'Pasek narzędzi',\r
+       popupTop: 'Pozycja w pionie',\r
+       rel: 'Relacja',\r
+       selectAnchor: 'Wybierz kotwicę',\r
+       styles: 'Styl',\r
+       tabIndex: 'Indeks kolejności',\r
+       target: 'Obiekt docelowy',\r
+       targetFrame: '<ramka>',\r
+       targetFrameName: 'Nazwa ramki docelowej',\r
+       targetPopup: '<wyskakujące okno>',\r
+       targetPopupName: 'Nazwa wyskakującego okna',\r
+       title: 'Odnośnik',\r
+       toAnchor: 'Odnośnik wewnątrz strony (kotwica)',\r
+       toEmail: 'Adres e-mail',\r
+       toUrl: 'Adres URL',\r
+       toolbar: 'Wstaw/edytuj odnośnik',\r
+       type: 'Typ odnośnika',\r
+       unlink: 'Usuń odnośnik',\r
+       upload: 'Wyślij'\r
+} );\r
diff --git a/sources/plugins/link/lang/pt-br.js b/sources/plugins/link/lang/pt-br.js
new file mode 100644 (file)
index 0000000..0c43149
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'pt-br', {\r
+       acccessKey: 'Chave de Acesso',\r
+       advanced: 'Avançado',\r
+       advisoryContentType: 'Tipo de Conteúdo',\r
+       advisoryTitle: 'Título',\r
+       anchor: {\r
+               toolbar: 'Inserir/Editar Âncora',\r
+               menu: 'Formatar Âncora',\r
+               title: 'Formatar Âncora',\r
+               name: 'Nome da Âncora',\r
+               errorName: 'Por favor, digite o nome da âncora',\r
+               remove: 'Remover Âncora'\r
+       },\r
+       anchorId: 'Id da âncora',\r
+       anchorName: 'Nome da âncora',\r
+       charset: 'Charset do Link',\r
+       cssClasses: 'Classe de CSS',\r
+       download: 'Forçar Download',\r
+       displayText: 'Exibir Texto',\r
+       emailAddress: 'Endereço E-Mail',\r
+       emailBody: 'Corpo da Mensagem',\r
+       emailSubject: 'Assunto da Mensagem',\r
+       id: 'Id',\r
+       info: 'Informações',\r
+       langCode: 'Direção do idioma',\r
+       langDir: 'Direção do idioma',\r
+       langDirLTR: 'Esquerda para Direita (LTR)',\r
+       langDirRTL: 'Direita para Esquerda (RTL)',\r
+       menu: 'Editar Link',\r
+       name: 'Nome',\r
+       noAnchors: '(Não há âncoras no documento)',\r
+       noEmail: 'Por favor, digite o endereço de e-mail',\r
+       noUrl: 'Por favor, digite o endereço do Link',\r
+       other: '<outro>',\r
+       popupDependent: 'Dependente (Netscape)',\r
+       popupFeatures: 'Propriedades da Janela Pop-up',\r
+       popupFullScreen: 'Modo Tela Cheia (IE)',\r
+       popupLeft: 'Esquerda',\r
+       popupLocationBar: 'Barra de Endereços',\r
+       popupMenuBar: 'Barra de Menus',\r
+       popupResizable: 'Redimensionável',\r
+       popupScrollBars: 'Barras de Rolagem',\r
+       popupStatusBar: 'Barra de Status',\r
+       popupToolbar: 'Barra de Ferramentas',\r
+       popupTop: 'Topo',\r
+       rel: 'Tipo de Relação',\r
+       selectAnchor: 'Selecione uma âncora',\r
+       styles: 'Estilos',\r
+       tabIndex: 'Índice de Tabulação',\r
+       target: 'Destino',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Nome do Frame de Destino',\r
+       targetPopup: '<janela popup>',\r
+       targetPopupName: 'Nome da Janela Pop-up',\r
+       title: 'Editar Link',\r
+       toAnchor: 'Âncora nesta página',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Inserir/Editar Link',\r
+       type: 'Tipo de hiperlink',\r
+       unlink: 'Remover Link',\r
+       upload: 'Enviar ao Servidor'\r
+} );\r
diff --git a/sources/plugins/link/lang/pt.js b/sources/plugins/link/lang/pt.js
new file mode 100644 (file)
index 0000000..5f45548
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'pt', {\r
+       acccessKey: 'Chave de acesso',\r
+       advanced: 'Avançado',\r
+       advisoryContentType: 'Tipo de conteúdo',\r
+       advisoryTitle: 'Título',\r
+       anchor: {\r
+               toolbar: ' Inserir/Editar âncora',\r
+               menu: 'Propriedades da âncora',\r
+               title: 'Propriedades da âncora',\r
+               name: 'Nome da âncora',\r
+               errorName: 'Por favor, introduza o nome da âncora',\r
+               remove: 'Remover âncora'\r
+       },\r
+       anchorId: 'Por ID do elemento',\r
+       anchorName: 'Por Nome de Referência',\r
+       charset: 'Fonte de caracteres vinculado',\r
+       cssClasses: 'Classes de Estilo',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Mostrar texto',\r
+       emailAddress: 'Endereço de email',\r
+       emailBody: 'Corpo da mensagem',\r
+       emailSubject: 'Título de mensagem',\r
+       id: 'ID',\r
+       info: 'Informação da hiperligação',\r
+       langCode: 'Código de idioma',\r
+       langDir: 'Orientação de idioma',\r
+       langDirLTR: 'Esquerda para a Direita (EPD)',\r
+       langDirRTL: 'Direita para a Esquerda (DPE)',\r
+       menu: 'Editar hiperligação',\r
+       name: 'Nome',\r
+       noAnchors: '(Não existem âncoras no documento)',\r
+       noEmail: 'Por favor, escreva o endereço de email',\r
+       noUrl: 'Por favor, introduza o endereço URL',\r
+       other: '<outro>',\r
+       popupDependent: 'Dependente (Netscape)',\r
+       popupFeatures: 'Características de janela flutuante',\r
+       popupFullScreen: 'Janela completa (IE)',\r
+       popupLeft: 'Posição esquerda',\r
+       popupLocationBar: 'Barra de localização',\r
+       popupMenuBar: 'Barra de menu',\r
+       popupResizable: 'Redimensionável',\r
+       popupScrollBars: 'Barras de deslocamento',\r
+       popupStatusBar: 'Barra de estado',\r
+       popupToolbar: 'Barra de ferramentas',\r
+       popupTop: 'Posição topo',\r
+       rel: 'Relação',\r
+       selectAnchor: 'Selecionar âncora',\r
+       styles: 'Estilo',\r
+       tabIndex: 'Índice de tabulação',\r
+       target: 'Alvo',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Nome da janela de destino',\r
+       targetPopup: '<janela de popup>',\r
+       targetPopupName: 'Nome da janela flutuante',\r
+       title: 'Hiperligação',\r
+       toAnchor: 'Ligar a âncora no texto',\r
+       toEmail: 'Email',\r
+       toUrl: 'URL',\r
+       toolbar: 'Hiperligação',\r
+       type: 'Tipo de hiperligação',\r
+       unlink: 'Eliminar hiperligação',\r
+       upload: 'Carregar'\r
+} );\r
diff --git a/sources/plugins/link/lang/ro.js b/sources/plugins/link/lang/ro.js
new file mode 100644 (file)
index 0000000..a5d79a3
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ro', {\r
+       acccessKey: 'Tasta de acces',\r
+       advanced: 'Avansat',\r
+       advisoryContentType: 'Tipul consultativ al titlului',\r
+       advisoryTitle: 'Titlul consultativ',\r
+       anchor: {\r
+               toolbar: 'Inserează/Editează ancoră',\r
+               menu: 'Proprietăţi ancoră',\r
+               title: 'Proprietăţi ancoră',\r
+               name: 'Numele ancorei',\r
+               errorName: 'Vă rugăm scrieţi numele ancorei',\r
+               remove: 'Elimină ancora'\r
+       },\r
+       anchorId: 'după Id-ul elementului',\r
+       anchorName: 'după numele ancorei',\r
+       charset: 'Setul de caractere al resursei legate',\r
+       cssClasses: 'Clasele cu stilul paginii (CSS)',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Adresă de e-mail',\r
+       emailBody: 'Opțiuni Meniu Contextual',\r
+       emailSubject: 'Subiectul mesajului',\r
+       id: 'Id',\r
+       info: 'Informaţii despre link (Legătură web)',\r
+       langCode: 'Direcţia cuvintelor',\r
+       langDir: 'Direcţia cuvintelor',\r
+       langDirLTR: 'stânga-dreapta (LTR)',\r
+       langDirRTL: 'dreapta-stânga (RTL)',\r
+       menu: 'Editează Link',\r
+       name: 'Nume',\r
+       noAnchors: '(Nicio ancoră disponibilă în document)',\r
+       noEmail: 'Vă rugăm să scrieţi adresa de e-mail',\r
+       noUrl: 'Vă rugăm să scrieţi URL-ul',\r
+       other: '<alt>',\r
+       popupDependent: 'Dependent (Netscape)',\r
+       popupFeatures: 'Proprietăţile ferestrei popup',\r
+       popupFullScreen: 'Tot ecranul (Full Screen)(IE)',\r
+       popupLeft: 'Poziţia la stânga',\r
+       popupLocationBar: 'Bara de locaţie',\r
+       popupMenuBar: 'Bara de meniu',\r
+       popupResizable: 'Redimensionabil',\r
+       popupScrollBars: 'Bare de derulare',\r
+       popupStatusBar: 'Bara de status',\r
+       popupToolbar: 'Bara de opţiuni',\r
+       popupTop: 'Poziţia la dreapta',\r
+       rel: 'Relație',\r
+       selectAnchor: 'Selectaţi o ancoră',\r
+       styles: 'Stil',\r
+       tabIndex: 'Indexul tabului',\r
+       target: 'Ţintă (Target)',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Numele frameului ţintă',\r
+       targetPopup: '<fereastra popup>',\r
+       targetPopupName: 'Numele ferestrei popup',\r
+       title: 'Link (Legătură web)',\r
+       toAnchor: 'Ancoră în această pagină',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Inserează/Editează link (legătură web)',\r
+       type: 'Tipul link-ului (al legăturii web)',\r
+       unlink: 'Înlătură link (legătură web)',\r
+       upload: 'Încarcă'\r
+} );\r
diff --git a/sources/plugins/link/lang/ru.js b/sources/plugins/link/lang/ru.js
new file mode 100644 (file)
index 0000000..7f4b775
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ru', {\r
+       acccessKey: 'Клавиша доступа',\r
+       advanced: 'Дополнительно',\r
+       advisoryContentType: 'Тип содержимого',\r
+       advisoryTitle: 'Заголовок',\r
+       anchor: {\r
+               toolbar: 'Вставить / редактировать якорь',\r
+               menu: 'Изменить якорь',\r
+               title: 'Свойства якоря',\r
+               name: 'Имя якоря',\r
+               errorName: 'Пожалуйста, введите имя якоря',\r
+               remove: 'Удалить якорь'\r
+       },\r
+       anchorId: 'По идентификатору',\r
+       anchorName: 'По имени',\r
+       charset: 'Кодировка ресурса',\r
+       cssClasses: 'Классы CSS',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Отображаемый текст',\r
+       emailAddress: 'Email адрес',\r
+       emailBody: 'Текст сообщения',\r
+       emailSubject: 'Тема сообщения',\r
+       id: 'Идентификатор',\r
+       info: 'Информация о ссылке',\r
+       langCode: 'Код языка',\r
+       langDir: 'Направление текста',\r
+       langDirLTR: 'Слева направо (LTR)',\r
+       langDirRTL: 'Справа налево (RTL)',\r
+       menu: 'Редактировать ссылку',\r
+       name: 'Имя',\r
+       noAnchors: '(В документе нет ни одного якоря)',\r
+       noEmail: 'Пожалуйста, введите email адрес',\r
+       noUrl: 'Пожалуйста, введите ссылку',\r
+       other: '<другой>',\r
+       popupDependent: 'Зависимое (Netscape)',\r
+       popupFeatures: 'Параметры всплывающего окна',\r
+       popupFullScreen: 'Полноэкранное (IE)',\r
+       popupLeft: 'Отступ слева',\r
+       popupLocationBar: 'Панель адреса',\r
+       popupMenuBar: 'Панель меню',\r
+       popupResizable: 'Изменяемый размер',\r
+       popupScrollBars: 'Полосы прокрутки',\r
+       popupStatusBar: 'Строка состояния',\r
+       popupToolbar: 'Панель инструментов',\r
+       popupTop: 'Отступ сверху',\r
+       rel: 'Отношение',\r
+       selectAnchor: 'Выберите якорь',\r
+       styles: 'Стиль',\r
+       tabIndex: 'Последовательность перехода',\r
+       target: 'Цель',\r
+       targetFrame: '<фрейм>',\r
+       targetFrameName: 'Имя целевого фрейма',\r
+       targetPopup: '<всплывающее окно>',\r
+       targetPopupName: 'Имя всплывающего окна',\r
+       title: 'Ссылка',\r
+       toAnchor: 'Ссылка на якорь в тексте',\r
+       toEmail: 'Email',\r
+       toUrl: 'Ссылка',\r
+       toolbar: 'Вставить/Редактировать ссылку',\r
+       type: 'Тип ссылки',\r
+       unlink: 'Убрать ссылку',\r
+       upload: 'Загрузка'\r
+} );\r
diff --git a/sources/plugins/link/lang/si.js b/sources/plugins/link/lang/si.js
new file mode 100644 (file)
index 0000000..7ad9935
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'si', {\r
+       acccessKey: 'ප්‍රවේශ  යතුර',\r
+       advanced: 'දීය',\r
+       advisoryContentType: 'උපදේශාත්මක අන්තර්ගත ආකාරය',\r
+       advisoryTitle: 'උපදේශාත්මක නාමය',\r
+       anchor: {\r
+               toolbar: 'ආධාරය',\r
+               menu: 'ආධාරය වෙනස් කිරීම',\r
+               title: 'ආධාරක ',\r
+               name: 'ආධාරකයේ නාමය',\r
+               errorName: 'කරුණාකර ආධාරකයේ නාමය ඇතුල් කරන්න',\r
+               remove: 'ආධාරකය ඉවත් කිරීම'\r
+       },\r
+       anchorId: 'By Element Id', // MISSING\r
+       anchorName: 'By Anchor Name', // MISSING\r
+       charset: 'Linked Resource Charset', // MISSING\r
+       cssClasses: 'විලාසපත්‍ර පන්තිය',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail Address', // MISSING\r
+       emailBody: 'Message Body', // MISSING\r
+       emailSubject: 'Message Subject', // MISSING\r
+       id: 'අංකය',\r
+       info: 'Link Info', // MISSING\r
+       langCode: 'භාෂා කේතය',\r
+       langDir: 'භාෂා දිශාව',\r
+       langDirLTR: 'වමේසිට දකුණුට',\r
+       langDirRTL: 'දකුණේ සිට වමට',\r
+       menu: 'Edit Link', // MISSING\r
+       name: 'නම',\r
+       noAnchors: '(No anchors available in the document)', // MISSING\r
+       noEmail: 'Please type the e-mail address', // MISSING\r
+       noUrl: 'Please type the link URL', // MISSING\r
+       other: '<other>', // MISSING\r
+       popupDependent: 'Dependent (Netscape)', // MISSING\r
+       popupFeatures: 'Popup Window Features', // MISSING\r
+       popupFullScreen: 'Full Screen (IE)', // MISSING\r
+       popupLeft: 'Left Position', // MISSING\r
+       popupLocationBar: 'Location Bar', // MISSING\r
+       popupMenuBar: 'Menu Bar', // MISSING\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Scroll Bars', // MISSING\r
+       popupStatusBar: 'Status Bar', // MISSING\r
+       popupToolbar: 'Toolbar', // MISSING\r
+       popupTop: 'Top Position', // MISSING\r
+       rel: 'Relationship', // MISSING\r
+       selectAnchor: 'Select an Anchor', // MISSING\r
+       styles: 'විලාසය',\r
+       tabIndex: 'Tab Index', // MISSING\r
+       target: 'අරමුණ',\r
+       targetFrame: '<frame>', // MISSING\r
+       targetFrameName: 'Target Frame Name', // MISSING\r
+       targetPopup: '<popup window>', // MISSING\r
+       targetPopupName: 'Popup Window Name', // MISSING\r
+       title: 'සබැඳිය',\r
+       toAnchor: 'Link to anchor in the text', // MISSING\r
+       toEmail: 'E-mail', // MISSING\r
+       toUrl: 'URL',\r
+       toolbar: 'සබැඳිය',\r
+       type: 'Link Type', // MISSING\r
+       unlink: 'Unlink', // MISSING\r
+       upload: 'උඩුගතකිරීම'\r
+} );\r
diff --git a/sources/plugins/link/lang/sk.js b/sources/plugins/link/lang/sk.js
new file mode 100644 (file)
index 0000000..87b60bd
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sk', {\r
+       acccessKey: 'Prístupový kľúč',\r
+       advanced: 'Rozšírené',\r
+       advisoryContentType: 'Pomocný typ obsahu',\r
+       advisoryTitle: 'Pomocný titulok',\r
+       anchor: {\r
+               toolbar: 'Kotva',\r
+               menu: 'Upraviť kotvu',\r
+               title: 'Vlastnosti kotvy',\r
+               name: 'Názov kotvy',\r
+               errorName: 'Zadajte prosím názov kotvy',\r
+               remove: 'Odstrániť kotvu'\r
+       },\r
+       anchorId: 'Podľa Id objektu',\r
+       anchorName: 'Podľa mena kotvy',\r
+       charset: 'Priradená znaková sada',\r
+       cssClasses: 'Triedy štýlu',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mailová adresa',\r
+       emailBody: 'Telo správy',\r
+       emailSubject: 'Predmet správy',\r
+       id: 'Id',\r
+       info: 'Informácie o odkaze',\r
+       langCode: 'Orientácia jazyka',\r
+       langDir: 'Orientácia jazyka',\r
+       langDirLTR: 'Zľava doprava (LTR)',\r
+       langDirRTL: 'Sprava doľava (RTL)',\r
+       menu: 'Upraviť odkaz',\r
+       name: 'Názov',\r
+       noAnchors: '(V dokumente nie sú dostupné žiadne kotvy)',\r
+       noEmail: 'Zadajte prosím e-mailovú adresu',\r
+       noUrl: 'Zadajte prosím URL odkazu',\r
+       other: '<iný>',\r
+       popupDependent: 'Závislosť (Netscape)',\r
+       popupFeatures: 'Vlastnosti vyskakovacieho okna',\r
+       popupFullScreen: 'Celá obrazovka (IE)',\r
+       popupLeft: 'Ľavý okraj',\r
+       popupLocationBar: 'Panel umiestnenia (location bar)',\r
+       popupMenuBar: 'Panel ponuky (menu bar)',\r
+       popupResizable: 'Meniteľná veľkosť (resizable)',\r
+       popupScrollBars: 'Posuvníky (scroll bars)',\r
+       popupStatusBar: 'Stavový riadok (status bar)',\r
+       popupToolbar: 'Panel nástrojov (toolbar)',\r
+       popupTop: 'Horný okraj',\r
+       rel: 'Vzťah (rel)',\r
+       selectAnchor: 'Vybrať kotvu',\r
+       styles: 'Štýl',\r
+       tabIndex: 'Poradie prvku (tab index)',\r
+       target: 'Cieľ',\r
+       targetFrame: '<rámec>',\r
+       targetFrameName: 'Názov rámu cieľa',\r
+       targetPopup: '<vyskakovacie okno>',\r
+       targetPopupName: 'Názov vyskakovacieho okna',\r
+       title: 'Odkaz',\r
+       toAnchor: 'Odkaz na kotvu v texte',\r
+       toEmail: 'E-mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Odkaz',\r
+       type: 'Typ odkazu',\r
+       unlink: 'Odstrániť odkaz',\r
+       upload: 'Nahrať'\r
+} );\r
diff --git a/sources/plugins/link/lang/sl.js b/sources/plugins/link/lang/sl.js
new file mode 100644 (file)
index 0000000..911203f
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sl', {\r
+       acccessKey: 'Tipka za dostop',\r
+       advanced: 'Napredno',\r
+       advisoryContentType: 'Predlagana vrsta vsebine',\r
+       advisoryTitle: 'Predlagani naslov',\r
+       anchor: {\r
+               toolbar: 'Sidro',\r
+               menu: 'Uredi sidro',\r
+               title: 'Lastnosti sidra',\r
+               name: 'Ime sidra',\r
+               errorName: 'Prosimo, vnesite ime sidra',\r
+               remove: 'Odstrani sidro'\r
+       },\r
+       anchorId: 'Po ID-ju elementa',\r
+       anchorName: 'Po imenu sidra',\r
+       charset: 'Nabor znakov povezanega vira',\r
+       cssClasses: 'Razredi slogovne predloge',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-poštni naslov',\r
+       emailBody: 'Telo sporočila',\r
+       emailSubject: 'Zadeva sporočila',\r
+       id: 'Id',\r
+       info: 'Podatki o povezavi',\r
+       langCode: 'Koda jezika',\r
+       langDir: 'Smer jezika',\r
+       langDirLTR: 'Od leve proti desni (LTR)',\r
+       langDirRTL: 'Od desne proti levi (RTL)',\r
+       menu: 'Uredi povezavo',\r
+       name: 'Ime',\r
+       noAnchors: '(V tem dokumentu ni sider)',\r
+       noEmail: 'Vnesite e-poštni naslov',\r
+       noUrl: 'Vnesite URL povezave',\r
+       other: '<drugo>',\r
+       popupDependent: 'Podokno (Netscape)',\r
+       popupFeatures: 'Značilnosti pojavnega okna',\r
+       popupFullScreen: 'Celozaslonsko (IE)',\r
+       popupLeft: 'Lega levo',\r
+       popupLocationBar: 'Naslovna vrstica',\r
+       popupMenuBar: 'Menijska vrstica',\r
+       popupResizable: 'Spremenljive velikosti',\r
+       popupScrollBars: 'Drsniki',\r
+       popupStatusBar: 'Vrstica stanja',\r
+       popupToolbar: 'Orodna vrstica',\r
+       popupTop: 'Lega na vrhu',\r
+       rel: 'Odnos',\r
+       selectAnchor: 'Izberite sidro',\r
+       styles: 'Slog',\r
+       tabIndex: 'Številka tabulatorja',\r
+       target: 'Cilj',\r
+       targetFrame: '<okvir>',\r
+       targetFrameName: 'Ime ciljnega okvirja',\r
+       targetPopup: '<pojavno okno>',\r
+       targetPopupName: 'Ime pojavnega okna',\r
+       title: 'Povezava',\r
+       toAnchor: 'Sidro na tej strani',\r
+       toEmail: 'E-pošta',\r
+       toUrl: 'URL',\r
+       toolbar: 'Vstavi/uredi povezavo',\r
+       type: 'Vrsta povezave',\r
+       unlink: 'Odstrani povezavo',\r
+       upload: 'Naloži'\r
+} );\r
diff --git a/sources/plugins/link/lang/sq.js b/sources/plugins/link/lang/sq.js
new file mode 100644 (file)
index 0000000..83b2fb7
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sq', {\r
+       acccessKey: 'Sipas ID-së së Elementit',\r
+       advanced: 'Të përparuara',\r
+       advisoryContentType: 'Lloji i Përmbajtjes Këshillimore',\r
+       advisoryTitle: 'Titull',\r
+       anchor: {\r
+               toolbar: 'Spirancë',\r
+               menu: 'Redakto Spirancën',\r
+               title: 'Anchor Properties', // MISSING\r
+               name: 'Emri i Spirancës',\r
+               errorName: 'Ju lutemi shkruani emrin e spirancës',\r
+               remove: 'Largo Spirancën'\r
+       },\r
+       anchorId: 'Sipas ID-së së Elementit',\r
+       anchorName: 'Sipas Emrit të Spirancës',\r
+       charset: 'Seti i Karaktereve të Burimeve të Nëdlidhura',\r
+       cssClasses: 'Klasa stili CSS',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Posta Elektronike',\r
+       emailBody: 'Trupi i Porosisë',\r
+       emailSubject: 'Titulli i Porosisë',\r
+       id: 'Id',\r
+       info: 'Informacione të Nyjes',\r
+       langCode: 'Kod gjuhe',\r
+       langDir: 'Drejtim teksti',\r
+       langDirLTR: 'Nga e majta në të djathë (LTR)',\r
+       langDirRTL: 'Nga e djathta në të majtë (RTL)',\r
+       menu: 'Redakto Nyjen',\r
+       name: 'Emër',\r
+       noAnchors: '(Nuk ka asnjë spirancë në dokument)',\r
+       noEmail: 'Ju lutemi shkruani postën elektronike',\r
+       noUrl: 'Ju lutemi shkruani URL-në e nyjes',\r
+       other: '<tjetër>',\r
+       popupDependent: 'E Varur (Netscape)',\r
+       popupFeatures: 'Karakteristikat e Dritares së Dialogut',\r
+       popupFullScreen: 'Ekran i Plotë  (IE)',\r
+       popupLeft: 'Pozita Majtas',\r
+       popupLocationBar: 'Shiriti i Lokacionit',\r
+       popupMenuBar: 'Shiriti i Menysë',\r
+       popupResizable: 'I ndryshueshëm',\r
+       popupScrollBars: 'Shiritat zvarritës',\r
+       popupStatusBar: 'Shiriti i Statutit',\r
+       popupToolbar: 'Shiriti i Mejteve',\r
+       popupTop: 'Top Pozita',\r
+       rel: 'Marrëdhëniet',\r
+       selectAnchor: 'Përzgjidh një Spirancë',\r
+       styles: 'Stil',\r
+       tabIndex: 'Indeksi i fletave',\r
+       target: 'Objektivi',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Emri i Kornizës së Synuar',\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Emri i Dritares së Dialogut',\r
+       title: 'Nyja',\r
+       toAnchor: 'Lidhu me spirancën në tekst',\r
+       toEmail: 'Posta Elektronike',\r
+       toUrl: 'URL',\r
+       toolbar: 'Nyja',\r
+       type: 'Lloji i Nyjes',\r
+       unlink: 'Largo Nyjen',\r
+       upload: 'Ngarko'\r
+} );\r
diff --git a/sources/plugins/link/lang/sr-latn.js b/sources/plugins/link/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..8f6f6a7
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sr-latn', {\r
+       acccessKey: 'Pristupni taster',\r
+       advanced: 'Napredni tagovi',\r
+       advisoryContentType: 'Advisory vrsta sadržaja',\r
+       advisoryTitle: 'Advisory naslov',\r
+       anchor: {\r
+               toolbar: 'Unesi/izmeni sidro',\r
+               menu: 'Osobine sidra',\r
+               title: 'Osobine sidra',\r
+               name: 'Naziv sidra',\r
+               errorName: 'Unesite naziv sidra',\r
+               remove: 'Ukloni sidro'\r
+       },\r
+       anchorId: 'Po Id-u elementa',\r
+       anchorName: 'Po nazivu sidra',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet klase',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'E-Mail adresa',\r
+       emailBody: 'Sadržaj poruke',\r
+       emailSubject: 'Naslov',\r
+       id: 'Id',\r
+       info: 'Link Info',\r
+       langCode: 'Smer jezika',\r
+       langDir: 'Smer jezika',\r
+       langDirLTR: 'S leva na desno (LTR)',\r
+       langDirRTL: 'S desna na levo (RTL)',\r
+       menu: 'Izmeni link',\r
+       name: 'Naziv',\r
+       noAnchors: '(Nema dostupnih sidra)',\r
+       noEmail: 'Otkucajte adresu elektronske pote',\r
+       noUrl: 'Unesite URL linka',\r
+       other: '<остало>',\r
+       popupDependent: 'Zavisno (Netscape)',\r
+       popupFeatures: 'Mogućnosti popup prozora',\r
+       popupFullScreen: 'Prikaz preko celog ekrana (IE)',\r
+       popupLeft: 'Od leve ivice ekrana (px)',\r
+       popupLocationBar: 'Lokacija',\r
+       popupMenuBar: 'Kontekstni meni',\r
+       popupResizable: 'Promenljive veličine',\r
+       popupScrollBars: 'Scroll bar',\r
+       popupStatusBar: 'Statusna linija',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Od vrha ekrana (px)',\r
+       rel: 'Odnos',\r
+       selectAnchor: 'Odaberi sidro',\r
+       styles: 'Stil',\r
+       tabIndex: 'Tab indeks',\r
+       target: 'Meta',\r
+       targetFrame: '<okvir>',\r
+       targetFrameName: 'Naziv odredišnog frejma',\r
+       targetPopup: '<popup prozor>',\r
+       targetPopupName: 'Naziv popup prozora',\r
+       title: 'Link',\r
+       toAnchor: 'Sidro na ovoj stranici',\r
+       toEmail: 'E-Mail',\r
+       toUrl: 'URL',\r
+       toolbar: 'Unesi/izmeni link',\r
+       type: 'Vrsta linka',\r
+       unlink: 'Ukloni link',\r
+       upload: 'Pošalji'\r
+} );\r
diff --git a/sources/plugins/link/lang/sr.js b/sources/plugins/link/lang/sr.js
new file mode 100644 (file)
index 0000000..18689da
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sr', {\r
+       acccessKey: 'Приступни тастер',\r
+       advanced: 'Напредни тагови',\r
+       advisoryContentType: 'Advisory врста садржаја',\r
+       advisoryTitle: 'Advisory наслов',\r
+       anchor: {\r
+               toolbar: 'Унеси/измени сидро',\r
+               menu: 'Особине сидра',\r
+               title: 'Особине сидра',\r
+               name: 'Име сидра',\r
+               errorName: 'Молимо Вас да унесете име сидра',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'Пo Ид-jу елемента',\r
+       anchorName: 'По називу сидра',\r
+       charset: 'Linked Resource Charset',\r
+       cssClasses: 'Stylesheet класе',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Адреса електронске поште',\r
+       emailBody: 'Садржај поруке',\r
+       emailSubject: 'Наслов',\r
+       id: 'Ид',\r
+       info: 'Линк инфо',\r
+       langCode: 'Смер језика',\r
+       langDir: 'Смер језика',\r
+       langDirLTR: 'С лева на десно (LTR)',\r
+       langDirRTL: 'С десна на лево (RTL)',\r
+       menu: 'Промени линк',\r
+       name: 'Назив',\r
+       noAnchors: '(Нема доступних сидра)',\r
+       noEmail: 'Откуцајте адресу електронске поште',\r
+       noUrl: 'Унесите УРЛ линка',\r
+       other: '<друго>',\r
+       popupDependent: 'Зависно (Netscape)',\r
+       popupFeatures: 'Могућности искачућег прозора',\r
+       popupFullScreen: 'Приказ преко целог екрана (ИE)',\r
+       popupLeft: 'Од леве ивице екрана (пиксела)',\r
+       popupLocationBar: 'Локација',\r
+       popupMenuBar: 'Контекстни мени',\r
+       popupResizable: 'Величина се мења',\r
+       popupScrollBars: 'Скрол бар',\r
+       popupStatusBar: 'Статусна линија',\r
+       popupToolbar: 'Toolbar',\r
+       popupTop: 'Од врха екрана (пиксела)',\r
+       rel: 'Однос',\r
+       selectAnchor: 'Одабери сидро',\r
+       styles: 'Стил',\r
+       tabIndex: 'Таб индекс',\r
+       target: 'Meтa',\r
+       targetFrame: '<оквир>',\r
+       targetFrameName: 'Назив одредишног фрејма',\r
+       targetPopup: '<искачући прозор>',\r
+       targetPopupName: 'Назив искачућег прозора',\r
+       title: 'Линк',\r
+       toAnchor: 'Сидро на овој страници',\r
+       toEmail: 'Eлектронска пошта',\r
+       toUrl: 'УРЛ',\r
+       toolbar: 'Унеси/измени линк',\r
+       type: 'Врста линка',\r
+       unlink: 'Уклони линк',\r
+       upload: 'Пошаљи'\r
+} );\r
diff --git a/sources/plugins/link/lang/sv.js b/sources/plugins/link/lang/sv.js
new file mode 100644 (file)
index 0000000..bc9f4c2
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'sv', {\r
+       acccessKey: 'Behörighetsnyckel',\r
+       advanced: 'Avancerad',\r
+       advisoryContentType: 'Innehållstyp',\r
+       advisoryTitle: 'Titel',\r
+       anchor: {\r
+               toolbar: 'Infoga/Redigera ankarlänk',\r
+               menu: 'Egenskaper för ankarlänk',\r
+               title: 'Egenskaper för ankarlänk',\r
+               name: 'Ankarnamn',\r
+               errorName: 'Var god ange ett ankarnamn',\r
+               remove: 'Radera ankare'\r
+       },\r
+       anchorId: 'Efter element-id',\r
+       anchorName: 'Efter ankarnamn',\r
+       charset: 'Teckenuppställning',\r
+       cssClasses: 'Stilmall',\r
+       download: 'Tvinga nerladdning',\r
+       displayText: 'Visningstext',\r
+       emailAddress: 'E-postadress',\r
+       emailBody: 'Innehåll',\r
+       emailSubject: 'Ämne',\r
+       id: 'Id',\r
+       info: 'Länkinformation',\r
+       langCode: 'Språkkod',\r
+       langDir: 'Språkriktning',\r
+       langDirLTR: 'Vänster till höger (VTH)',\r
+       langDirRTL: 'Höger till vänster (HTV)',\r
+       menu: 'Redigera länk',\r
+       name: 'Namn',\r
+       noAnchors: '(Inga ankare kunde hittas)',\r
+       noEmail: 'Var god ange e-postadress',\r
+       noUrl: 'Var god ange länkens URL',\r
+       other: '<annan>',\r
+       popupDependent: 'Beroende (endast Netscape)',\r
+       popupFeatures: 'Popup-fönstrets egenskaper',\r
+       popupFullScreen: 'Helskärm (endast IE)',\r
+       popupLeft: 'Position från vänster',\r
+       popupLocationBar: 'Adressfält',\r
+       popupMenuBar: 'Menyfält',\r
+       popupResizable: 'Skalbart',\r
+       popupScrollBars: 'Scrolllista',\r
+       popupStatusBar: 'Statusfält',\r
+       popupToolbar: 'Verktygsfält',\r
+       popupTop: 'Position från sidans topp',\r
+       rel: 'Förhållande',\r
+       selectAnchor: 'Välj ett ankare',\r
+       styles: 'Stilmall',\r
+       tabIndex: 'Tabindex',\r
+       target: 'Mål',\r
+       targetFrame: '<ram>',\r
+       targetFrameName: 'Målets ramnamn',\r
+       targetPopup: '<popup-fönster>',\r
+       targetPopupName: 'Popup-fönstrets namn',\r
+       title: 'Länk',\r
+       toAnchor: 'Länk till ankare i texten',\r
+       toEmail: 'E-post',\r
+       toUrl: 'URL',\r
+       toolbar: 'Infoga/Redigera länk',\r
+       type: 'Länktyp',\r
+       unlink: 'Radera länk',\r
+       upload: 'Ladda upp'\r
+} );\r
diff --git a/sources/plugins/link/lang/th.js b/sources/plugins/link/lang/th.js
new file mode 100644 (file)
index 0000000..593838d
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'th', {\r
+       acccessKey: 'แอคเซส คีย์',\r
+       advanced: 'ขั้นสูง',\r
+       advisoryContentType: 'ชนิดของคำเกริ่นนำ',\r
+       advisoryTitle: 'คำเกริ่นนำ',\r
+       anchor: {\r
+               toolbar: 'แทรก/แก้ไข Anchor',\r
+               menu: 'รายละเอียด Anchor',\r
+               title: 'รายละเอียด Anchor',\r
+               name: 'ชื่อ Anchor',\r
+               errorName: 'กรุณาระบุชื่อของ Anchor',\r
+               remove: 'Remove Anchor'\r
+       },\r
+       anchorId: 'ไอดี',\r
+       anchorName: 'ชื่อ',\r
+       charset: 'ลิงค์เชื่อมโยงไปยังชุดตัวอักษร',\r
+       cssClasses: 'คลาสของไฟล์กำหนดลักษณะการแสดงผล',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'อีเมล์ (E-Mail)',\r
+       emailBody: 'ข้อความ',\r
+       emailSubject: 'หัวเรื่อง',\r
+       id: 'ไอดี',\r
+       info: 'รายละเอียด',\r
+       langCode: 'การเขียน-อ่านภาษา',\r
+       langDir: 'การเขียน-อ่านภาษา',\r
+       langDirLTR: 'จากซ้ายไปขวา (LTR)',\r
+       langDirRTL: 'จากขวามาซ้าย (RTL)',\r
+       menu: 'แก้ไข ลิงค์',\r
+       name: 'ชื่อ',\r
+       noAnchors: '(ยังไม่มีจุดเชื่อมโยงภายในหน้าเอกสารนี้)',\r
+       noEmail: 'กรุณาระบุอีเมล์ (E-mail)',\r
+       noUrl: 'กรุณาระบุที่อยู่อ้างอิงออนไลน์ (URL)',\r
+       other: '<อื่น ๆ>',\r
+       popupDependent: 'แสดงเต็มหน้าจอ (Netscape)',\r
+       popupFeatures: 'คุณสมบัติของหน้าจอเล็ก (Pop-up)',\r
+       popupFullScreen: 'แสดงเต็มหน้าจอ (IE5.5++ เท่านั้น)',\r
+       popupLeft: 'พิกัดซ้าย (Left Position)',\r
+       popupLocationBar: 'แสดงที่อยู่ของไฟล์',\r
+       popupMenuBar: 'แสดงแถบเมนู',\r
+       popupResizable: 'สามารถปรับขนาดได้',\r
+       popupScrollBars: 'แสดงแถบเลื่อน',\r
+       popupStatusBar: 'แสดงแถบสถานะ',\r
+       popupToolbar: 'แสดงแถบเครื่องมือ',\r
+       popupTop: 'พิกัดบน (Top Position)',\r
+       rel: 'ความสัมพันธ์',\r
+       selectAnchor: 'ระบุข้อมูลของจุดเชื่อมโยง (Anchor)',\r
+       styles: 'ลักษณะการแสดงผล',\r
+       tabIndex: 'ลำดับของ แท็บ',\r
+       target: 'การเปิดหน้าลิงค์',\r
+       targetFrame: '<เปิดในเฟรม>',\r
+       targetFrameName: 'ชื่อทาร์เก็ตเฟรม',\r
+       targetPopup: '<เปิดหน้าจอเล็ก (Pop-up)>',\r
+       targetPopupName: 'ระบุชื่อหน้าจอเล็ก (Pop-up)',\r
+       title: 'ลิงค์เชื่อมโยงเว็บ อีเมล์ รูปภาพ หรือไฟล์อื่นๆ',\r
+       toAnchor: 'จุดเชื่อมโยง (Anchor)',\r
+       toEmail: 'ส่งอีเมล์ (E-Mail)',\r
+       toUrl: 'ที่อยู่อ้างอิง URL',\r
+       toolbar: 'แทรก/แก้ไข ลิงค์',\r
+       type: 'ประเภทของลิงค์',\r
+       unlink: 'ลบ ลิงค์',\r
+       upload: 'อัพโหลดไฟล์'\r
+} );\r
diff --git a/sources/plugins/link/lang/tr.js b/sources/plugins/link/lang/tr.js
new file mode 100644 (file)
index 0000000..424ad7b
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'tr', {\r
+       acccessKey: 'Erişim Tuşu',\r
+       advanced: 'Gelişmiş',\r
+       advisoryContentType: 'Danışma İçerik Türü',\r
+       advisoryTitle: 'Danışma Başlığı',\r
+       anchor: {\r
+               toolbar: 'Bağlantı Ekle/Düzenle',\r
+               menu: 'Bağlantı Özellikleri',\r
+               title: 'Bağlantı Özellikleri',\r
+               name: 'Bağlantı Adı',\r
+               errorName: 'Lütfen bağlantı için ad giriniz',\r
+               remove: 'Bağlantıyı Kaldır'\r
+       },\r
+       anchorId: 'Eleman Kimlik Numarası ile',\r
+       anchorName: 'Bağlantı Adı ile',\r
+       charset: 'Bağlı Kaynak Karakter Gurubu',\r
+       cssClasses: 'Biçem Sayfası Sınıfları',\r
+       download: 'İndirmeye Zorla',\r
+       displayText: 'Gösterim Metni',\r
+       emailAddress: 'E-Posta Adresi',\r
+       emailBody: 'İleti Gövdesi',\r
+       emailSubject: 'İleti Konusu',\r
+       id: 'Id',\r
+       info: 'Link Bilgisi',\r
+       langCode: 'Dil Yönü',\r
+       langDir: 'Dil Yönü',\r
+       langDirLTR: 'Soldan Sağa (LTR)',\r
+       langDirRTL: 'Sağdan Sola (RTL)',\r
+       menu: 'Link Düzenle',\r
+       name: 'Ad',\r
+       noAnchors: '(Bu belgede hiç çapa yok)',\r
+       noEmail: 'Lütfen E-posta adresini yazın',\r
+       noUrl: 'Lütfen Link URL\'sini yazın',\r
+       other: '<diğer>',\r
+       popupDependent: 'Bağımlı (Netscape)',\r
+       popupFeatures: 'Yeni Açılan Pencere Özellikleri',\r
+       popupFullScreen: 'Tam Ekran (IE)',\r
+       popupLeft: 'Sola Göre Konum',\r
+       popupLocationBar: 'Yer Çubuğu',\r
+       popupMenuBar: 'Menü Çubuğu',\r
+       popupResizable: 'Resizable',\r
+       popupScrollBars: 'Kaydırma Çubukları',\r
+       popupStatusBar: 'Durum Çubuğu',\r
+       popupToolbar: 'Araç Çubuğu',\r
+       popupTop: 'Yukarıya Göre Konum',\r
+       rel: 'İlişki',\r
+       selectAnchor: 'Bağlantı Seç',\r
+       styles: 'Biçem',\r
+       tabIndex: 'Sekme İndeksi',\r
+       target: 'Hedef',\r
+       targetFrame: '<çerçeve>',\r
+       targetFrameName: 'Hedef Çerçeve Adı',\r
+       targetPopup: '<yeni açılan pencere>',\r
+       targetPopupName: 'Yeni Açılan Pencere Adı',\r
+       title: 'Link',\r
+       toAnchor: 'Bu sayfada çapa',\r
+       toEmail: 'E-Posta',\r
+       toUrl: 'URL',\r
+       toolbar: 'Link Ekle/Düzenle',\r
+       type: 'Link Türü',\r
+       unlink: 'Köprü Kaldır',\r
+       upload: 'Karşıya Yükle'\r
+} );\r
diff --git a/sources/plugins/link/lang/tt.js b/sources/plugins/link/lang/tt.js
new file mode 100644 (file)
index 0000000..25bd354
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'tt', {\r
+       acccessKey: 'Access Key', // MISSING\r
+       advanced: 'Киңәйтелгән көйләүләр',\r
+       advisoryContentType: 'Advisory Content Type', // MISSING\r
+       advisoryTitle: 'Киңәш исем',\r
+       anchor: {\r
+               toolbar: 'Якорь',\r
+               menu: 'Якорьне үзгәртү',\r
+               title: 'Якорь үзлекләре',\r
+               name: 'Якорь исеме',\r
+               errorName: 'Якорьнең исемен языгыз',\r
+               remove: 'Якорьне бетерү'\r
+       },\r
+       anchorId: 'Элемент идентификаторы буенча',\r
+       anchorName: 'Якорь исеме буенча',\r
+       charset: 'Linked Resource Charset', // MISSING\r
+       cssClasses: 'Стильләр класслары',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Электрон почта адресы',\r
+       emailBody: 'Хат эчтәлеге',\r
+       emailSubject: 'Хат темасы',\r
+       id: 'Идентификатор',\r
+       info: 'Сылталама тасвирламасы',\r
+       langCode: 'Тел коды',\r
+       langDir: 'Язылыш юнəлеше',\r
+       langDirLTR: 'Сулдан уңга язылыш (LTR)',\r
+       langDirRTL: 'Уңнан сулга язылыш (RTL)',\r
+       menu: 'Сылталамаyны үзгәртү',\r
+       name: 'Исем',\r
+       noAnchors: '(Әлеге документта якорьләр табылмады)',\r
+       noEmail: 'Электрон почта адресын языгыз',\r
+       noUrl: 'Сылталаманы языгыз',\r
+       other: '<бүтән>',\r
+       popupDependent: 'Бәйле (Netscape)',\r
+       popupFeatures: 'Popup Window Features', // MISSING\r
+       popupFullScreen: 'Тулы экран (IE)',\r
+       popupLeft: 'Left Position', // MISSING\r
+       popupLocationBar: 'Location Bar', // MISSING\r
+       popupMenuBar: 'Menu Bar', // MISSING\r
+       popupResizable: 'Resizable', // MISSING\r
+       popupScrollBars: 'Scroll Bars', // MISSING\r
+       popupStatusBar: 'Status Bar', // MISSING\r
+       popupToolbar: 'Toolbar', // MISSING\r
+       popupTop: 'Top Position', // MISSING\r
+       rel: 'Бәйләнеш',\r
+       selectAnchor: 'Якорьне сайлау',\r
+       styles: 'Стиль',\r
+       tabIndex: 'Tab Index', // MISSING\r
+       target: 'Максат',\r
+       targetFrame: '<frame>',\r
+       targetFrameName: 'Target Frame Name', // MISSING\r
+       targetPopup: '<popup window>',\r
+       targetPopupName: 'Попап тәрәзәсе исеме',\r
+       title: 'Сылталама',\r
+       toAnchor: 'Якорьне текст белән бәйләү',\r
+       toEmail: 'Электрон почта',\r
+       toUrl: 'Сылталама',\r
+       toolbar: 'Сылталама',\r
+       type: 'Сылталама төре',\r
+       unlink: 'Сылталаманы бетерү',\r
+       upload: 'Йөкләү'\r
+} );\r
diff --git a/sources/plugins/link/lang/ug.js b/sources/plugins/link/lang/ug.js
new file mode 100644 (file)
index 0000000..3cf75b4
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'ug', {\r
+       acccessKey: 'زىيارەت كۇنۇپكا',\r
+       advanced: 'ئالىي',\r
+       advisoryContentType: 'مەزمۇن تىپى',\r
+       advisoryTitle: 'ماۋزۇ',\r
+       anchor: {\r
+               toolbar: 'لەڭگەرلىك نۇقتا ئۇلانمىسى قىستۇر/تەھرىرلە',\r
+               menu: 'لەڭگەرلىك نۇقتا ئۇلانما خاسلىقى',\r
+               title: 'لەڭگەرلىك نۇقتا ئۇلانما خاسلىقى',\r
+               name: 'لەڭگەرلىك نۇقتا ئاتى',\r
+               errorName: 'لەڭگەرلىك نۇقتا ئاتىنى كىرگۈزۈڭ',\r
+               remove: 'لەڭگەرلىك نۇقتا ئۆچۈر'\r
+       },\r
+       anchorId: 'لەڭگەرلىك نۇقتا ID سى بويىچە',\r
+       anchorName: 'لەڭگەرلىك نۇقتا ئاتى بويىچە',\r
+       charset: 'ھەرپ كودلىنىشى',\r
+       cssClasses: 'ئۇسلۇب خىلى ئاتى',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'ئادرېس',\r
+       emailBody: 'مەزمۇن',\r
+       emailSubject: 'ماۋزۇ',\r
+       id: 'ID',\r
+       info: 'ئۇلانما ئۇچۇرى',\r
+       langCode: 'تىل كودى',\r
+       langDir: 'تىل يۆنىلىشى',\r
+       langDirLTR: 'سولدىن ئوڭغا (LTR)',\r
+       langDirRTL: 'ئوڭدىن سولغا (RTL)',\r
+       menu: 'ئۇلانما تەھرىر',\r
+       name: 'ئات',\r
+       noAnchors: '(بۇ پۈتۈكتە ئىشلەتكىلى بولىدىغان لەڭگەرلىك نۇقتا يوق)',\r
+       noEmail: 'ئېلخەت ئادرېسىنى كىرگۈزۈڭ',\r
+       noUrl: 'ئۇلانما ئادرېسىنى كىرگۈزۈڭ',\r
+       other: '‹باشقا›',\r
+       popupDependent: 'تەۋە (NS)',\r
+       popupFeatures: 'قاڭقىش كۆزنەك خاسلىقى',\r
+       popupFullScreen: 'پۈتۈن ئېكران (IE)',\r
+       popupLeft: 'سول',\r
+       popupLocationBar: 'ئادرېس بالداق',\r
+       popupMenuBar: 'تىزىملىك بالداق',\r
+       popupResizable: 'چوڭلۇقى ئۆزگەرتىشچان',\r
+       popupScrollBars: 'دومىلىما سۈرگۈچ',\r
+       popupStatusBar: 'ھالەت بالداق',\r
+       popupToolbar: 'قورال بالداق',\r
+       popupTop: 'ئوڭ',\r
+       rel: 'باغلىنىش',\r
+       selectAnchor: 'بىر لەڭگەرلىك نۇقتا تاللاڭ',\r
+       styles: 'قۇر ئىچىدىكى ئۇسلۇبى',\r
+       tabIndex: 'Tab تەرتىپى',\r
+       target: 'نىشان',\r
+       targetFrame: '‹كاندۇك›',\r
+       targetFrameName: 'نىشان كاندۇك ئاتى',\r
+       targetPopup: '‹قاڭقىش كۆزنەك›',\r
+       targetPopupName: 'قاڭقىش كۆزنەك ئاتى',\r
+       title: 'ئۇلانما',\r
+       toAnchor: 'بەت ئىچىدىكى لەڭگەرلىك نۇقتا ئۇلانمىسى',\r
+       toEmail: 'ئېلخەت',\r
+       toUrl: 'ئادرېس',\r
+       toolbar: 'ئۇلانما قىستۇر/تەھرىرلە',\r
+       type: 'ئۇلانما تىپى',\r
+       unlink: 'ئۇلانما بىكار قىل',\r
+       upload: 'يۈكلە'\r
+} );\r
diff --git a/sources/plugins/link/lang/uk.js b/sources/plugins/link/lang/uk.js
new file mode 100644 (file)
index 0000000..8322d86
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'uk', {\r
+       acccessKey: 'Гаряча клавіша',\r
+       advanced: 'Додаткове',\r
+       advisoryContentType: 'Тип вмісту',\r
+       advisoryTitle: 'Заголовок',\r
+       anchor: {\r
+               toolbar: 'Вставити/Редагувати якір',\r
+               menu: 'Властивості якоря',\r
+               title: 'Властивості якоря',\r
+               name: 'Ім\'я якоря',\r
+               errorName: 'Будь ласка, вкажіть ім\'я якоря',\r
+               remove: 'Прибрати якір'\r
+       },\r
+       anchorId: 'За ідентифікатором елементу',\r
+       anchorName: 'За ім\'ям елементу',\r
+       charset: 'Кодування',\r
+       cssClasses: 'Клас CSS',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Адреса ел. пошти',\r
+       emailBody: 'Тіло повідомлення',\r
+       emailSubject: 'Тема листа',\r
+       id: 'Ідентифікатор',\r
+       info: 'Інформація посилання',\r
+       langCode: 'Код мови',\r
+       langDir: 'Напрямок мови',\r
+       langDirLTR: 'Зліва направо (LTR)',\r
+       langDirRTL: 'Справа наліво (RTL)',\r
+       menu: 'Вставити посилання',\r
+       name: 'Ім\'я',\r
+       noAnchors: '(В цьому документі немає якорів)',\r
+       noEmail: 'Будь ласка, вкажіть адрес ел. пошти',\r
+       noUrl: 'Будь ласка, вкажіть URL посилання',\r
+       other: '<інший>',\r
+       popupDependent: 'Залежний (Netscape)',\r
+       popupFeatures: 'Властивості випливаючого вікна',\r
+       popupFullScreen: 'Повний екран (IE)',\r
+       popupLeft: 'Позиція зліва',\r
+       popupLocationBar: 'Панель локації',\r
+       popupMenuBar: 'Панель меню',\r
+       popupResizable: 'Масштабоване',\r
+       popupScrollBars: 'Стрічки прокрутки',\r
+       popupStatusBar: 'Рядок статусу',\r
+       popupToolbar: 'Панель інструментів',\r
+       popupTop: 'Позиція зверху',\r
+       rel: 'Зв\'язок',\r
+       selectAnchor: 'Оберіть якір',\r
+       styles: 'Стиль CSS',\r
+       tabIndex: 'Послідовність переходу',\r
+       target: 'Ціль',\r
+       targetFrame: '<фрейм>',\r
+       targetFrameName: 'Ім\'я цільового фрейму',\r
+       targetPopup: '<випливаюче вікно>',\r
+       targetPopupName: 'Ім\'я випливаючого вікна',\r
+       title: 'Посилання',\r
+       toAnchor: 'Якір на цю сторінку',\r
+       toEmail: 'Ел. пошта',\r
+       toUrl: 'URL',\r
+       toolbar: 'Вставити/Редагувати посилання',\r
+       type: 'Тип посилання',\r
+       unlink: 'Видалити посилання',\r
+       upload: 'Надіслати'\r
+} );\r
diff --git a/sources/plugins/link/lang/vi.js b/sources/plugins/link/lang/vi.js
new file mode 100644 (file)
index 0000000..d78012d
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'vi', {\r
+       acccessKey: 'Phím hỗ trợ truy cập',\r
+       advanced: 'Mở rộng',\r
+       advisoryContentType: 'Nội dung hướng dẫn',\r
+       advisoryTitle: 'Nhan đề hướng dẫn',\r
+       anchor: {\r
+               toolbar: 'Chèn/Sửa điểm neo',\r
+               menu: 'Thuộc tính điểm neo',\r
+               title: 'Thuộc tính điểm neo',\r
+               name: 'Tên của điểm neo',\r
+               errorName: 'Hãy nhập vào tên của điểm neo',\r
+               remove: 'Xóa neo'\r
+       },\r
+       anchorId: 'Theo định danh thành phần',\r
+       anchorName: 'Theo tên điểm neo',\r
+       charset: 'Bảng mã của tài nguyên được liên kết đến',\r
+       cssClasses: 'Lớp Stylesheet',\r
+       download: 'Force Download', // MISSING\r
+       displayText: 'Display Text', // MISSING\r
+       emailAddress: 'Thư điện tử',\r
+       emailBody: 'Nội dung thông điệp',\r
+       emailSubject: 'Tiêu đề thông điệp',\r
+       id: 'Định danh',\r
+       info: 'Thông tin liên kết',\r
+       langCode: 'Mã ngôn ngữ',\r
+       langDir: 'Hướng ngôn ngữ',\r
+       langDirLTR: 'Trái sang phải (LTR)',\r
+       langDirRTL: 'Phải sang trái (RTL)',\r
+       menu: 'Sửa liên kết',\r
+       name: 'Tên',\r
+       noAnchors: '(Không có điểm neo nào trong tài liệu)',\r
+       noEmail: 'Hãy đưa vào địa chỉ thư điện tử',\r
+       noUrl: 'Hãy đưa vào đường dẫn liên kết (URL)',\r
+       other: '<khác>',\r
+       popupDependent: 'Phụ thuộc (Netscape)',\r
+       popupFeatures: 'Đặc điểm của cửa sổ Popup',\r
+       popupFullScreen: 'Toàn màn hình (IE)',\r
+       popupLeft: 'Vị trí bên trái',\r
+       popupLocationBar: 'Thanh vị trí',\r
+       popupMenuBar: 'Thanh Menu',\r
+       popupResizable: 'Có thể thay đổi kích cỡ',\r
+       popupScrollBars: 'Thanh cuộn',\r
+       popupStatusBar: 'Thanh trạng thái',\r
+       popupToolbar: 'Thanh công cụ',\r
+       popupTop: 'Vị trí phía trên',\r
+       rel: 'Quan hệ',\r
+       selectAnchor: 'Chọn một điểm neo',\r
+       styles: 'Kiểu (style)',\r
+       tabIndex: 'Chỉ số của Tab',\r
+       target: 'Đích',\r
+       targetFrame: '<khung>',\r
+       targetFrameName: 'Tên khung đích',\r
+       targetPopup: '<cửa sổ popup>',\r
+       targetPopupName: 'Tên cửa sổ Popup',\r
+       title: 'Liên kết',\r
+       toAnchor: 'Neo trong trang này',\r
+       toEmail: 'Thư điện tử',\r
+       toUrl: 'URL',\r
+       toolbar: 'Chèn/Sửa liên kết',\r
+       type: 'Kiểu liên kết',\r
+       unlink: 'Xoá liên kết',\r
+       upload: 'Tải lên'\r
+} );\r
diff --git a/sources/plugins/link/lang/zh-cn.js b/sources/plugins/link/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..6da9e96
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'zh-cn', {\r
+       acccessKey: '访问键',\r
+       advanced: '高级',\r
+       advisoryContentType: '内容类型',\r
+       advisoryTitle: '标题',\r
+       anchor: {\r
+               toolbar: '插入/编辑锚点链接',\r
+               menu: '锚点链接属性',\r
+               title: '锚点链接属性',\r
+               name: '锚点名称',\r
+               errorName: '请输入锚点名称',\r
+               remove: '删除锚点'\r
+       },\r
+       anchorId: '按锚点 ID',\r
+       anchorName: '按锚点名称',\r
+       charset: '字符编码',\r
+       cssClasses: '样式类名称',\r
+       download: '强制下载',\r
+       displayText: '显示文本',\r
+       emailAddress: '地址',\r
+       emailBody: '内容',\r
+       emailSubject: '主题',\r
+       id: 'ID',\r
+       info: '超链接信息',\r
+       langCode: '语言代码',\r
+       langDir: '语言方向',\r
+       langDirLTR: '从左到右 (LTR)',\r
+       langDirRTL: '从右到左 (RTL)',\r
+       menu: '编辑超链接',\r
+       name: '名称',\r
+       noAnchors: '(此文档没有可用的锚点)',\r
+       noEmail: '请输入电子邮件地址',\r
+       noUrl: '请输入超链接地址',\r
+       other: '<其他>',\r
+       popupDependent: '依附 (NS)',\r
+       popupFeatures: '弹出窗口属性',\r
+       popupFullScreen: '全屏 (IE)',\r
+       popupLeft: '左',\r
+       popupLocationBar: '地址栏',\r
+       popupMenuBar: '菜单栏',\r
+       popupResizable: '可缩放',\r
+       popupScrollBars: '滚动条',\r
+       popupStatusBar: '状态栏',\r
+       popupToolbar: '工具栏',\r
+       popupTop: '右',\r
+       rel: '关联',\r
+       selectAnchor: '选择一个锚点',\r
+       styles: '行内样式',\r
+       tabIndex: 'Tab 键次序',\r
+       target: '目标',\r
+       targetFrame: '<框架>',\r
+       targetFrameName: '目标框架名称',\r
+       targetPopup: '<弹出窗口>',\r
+       targetPopupName: '弹出窗口名称',\r
+       title: '超链接',\r
+       toAnchor: '页内锚点链接',\r
+       toEmail: '电子邮件',\r
+       toUrl: '地址',\r
+       toolbar: '插入/编辑超链接',\r
+       type: '超链接类型',\r
+       unlink: '取消超链接',\r
+       upload: '上传'\r
+} );\r
diff --git a/sources/plugins/link/lang/zh.js b/sources/plugins/link/lang/zh.js
new file mode 100644 (file)
index 0000000..5ba3d1c
--- /dev/null
@@ -0,0 +1,67 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'link', 'zh', {\r
+       acccessKey: '便捷鍵',\r
+       advanced: '進階',\r
+       advisoryContentType: '建議內容類型',\r
+       advisoryTitle: '標題',\r
+       anchor: {\r
+               toolbar: '錨點',\r
+               menu: '編輯錨點',\r
+               title: '錨點內容',\r
+               name: '錨點名稱',\r
+               errorName: '請輸入錨點名稱',\r
+               remove: '移除錨點'\r
+       },\r
+       anchorId: '依元件編號',\r
+       anchorName: '依錨點名稱',\r
+       charset: '連結資源的字元集',\r
+       cssClasses: '樣式表類別',\r
+       download: 'Force Download', // MISSING\r
+       displayText: '顯示文字',\r
+       emailAddress: '電子郵件地址',\r
+       emailBody: '郵件本文',\r
+       emailSubject: '郵件主旨',\r
+       id: 'ID',\r
+       info: '連結資訊',\r
+       langCode: '語言碼',\r
+       langDir: '語言方向',\r
+       langDirLTR: '由左至右 (LTR)',\r
+       langDirRTL: '由右至左 (RTL)',\r
+       menu: '編輯連結',\r
+       name: '名稱',\r
+       noAnchors: '(本文件中無可用之錨點)',\r
+       noEmail: '請輸入電子郵件',\r
+       noUrl: '請輸入連結 URL',\r
+       other: '<其他>',\r
+       popupDependent: '獨立 (Netscape)',\r
+       popupFeatures: '快顯視窗功能',\r
+       popupFullScreen: '全螢幕 (IE)',\r
+       popupLeft: '左側位置',\r
+       popupLocationBar: '位置列',\r
+       popupMenuBar: '功能表列',\r
+       popupResizable: '可調大小',\r
+       popupScrollBars: '捲軸',\r
+       popupStatusBar: '狀態列',\r
+       popupToolbar: '工具列',\r
+       popupTop: '頂端位置',\r
+       rel: '關係',\r
+       selectAnchor: '選取一個錨點',\r
+       styles: '樣式',\r
+       tabIndex: '定位順序',\r
+       target: '目標',\r
+       targetFrame: '<框架>',\r
+       targetFrameName: '目標框架名稱',\r
+       targetPopup: '<快顯視窗>',\r
+       targetPopupName: '快顯視窗名稱',\r
+       title: '連結',\r
+       toAnchor: '文字中的錨點連結',\r
+       toEmail: '電子郵件',\r
+       toUrl: '網址',\r
+       toolbar: '連結',\r
+       type: '連結類型',\r
+       unlink: '取消連結',\r
+       upload: '上傳'\r
+} );\r
diff --git a/sources/plugins/link/plugin.js b/sources/plugins/link/plugin.js
new file mode 100644 (file)
index 0000000..94d582b
--- /dev/null
@@ -0,0 +1,828 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'link', {\r
+               requires: 'dialog,fakeobjects',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'anchor,anchor-rtl,link,unlink', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               onLoad: function() {\r
+                       // Add the CSS styles for anchor placeholders.\r
+                       var iconPath = CKEDITOR.getUrl( this.path + 'images' + ( CKEDITOR.env.hidpi ? '/hidpi' : '' ) + '/anchor.png' ),\r
+                               baseStyle = 'background:url(' + iconPath + ') no-repeat %1 center;border:1px dotted #00f;background-size:16px;';\r
+\r
+                       var template = '.%2 a.cke_anchor,' +\r
+                               '.%2 a.cke_anchor_empty' +\r
+                               ',.cke_editable.%2 a[name]' +\r
+                               ',.cke_editable.%2 a[data-cke-saved-name]' +\r
+                               '{' +\r
+                                       baseStyle +\r
+                                       'padding-%1:18px;' +\r
+                                       // Show the arrow cursor for the anchor image (FF at least).\r
+                                       'cursor:auto;' +\r
+                               '}' +\r
+                               '.%2 img.cke_anchor' +\r
+                               '{' +\r
+                                       baseStyle +\r
+                                       'width:16px;' +\r
+                                       'min-height:15px;' +\r
+                                       // The default line-height on IE.\r
+                                       'height:1.15em;' +\r
+                                       // Opera works better with "middle" (even if not perfect)\r
+                                       'vertical-align:text-bottom;' +\r
+                               '}';\r
+\r
+                       // Styles with contents direction awareness.\r
+                       function cssWithDir( dir ) {\r
+                               return template.replace( /%1/g, dir == 'rtl' ? 'right' : 'left' ).replace( /%2/g, 'cke_contents_' + dir );\r
+                       }\r
+\r
+                       CKEDITOR.addCss( cssWithDir( 'ltr' ) + cssWithDir( 'rtl' ) );\r
+               },\r
+\r
+               init: function( editor ) {\r
+                       var allowed = 'a[!href]',\r
+                               required = 'a[href]';\r
+\r
+                       if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'advanced' ) )\r
+                               allowed = allowed.replace( ']', ',accesskey,charset,dir,id,lang,name,rel,tabindex,title,type,download]{*}(*)' );\r
+                       if ( CKEDITOR.dialog.isTabEnabled( editor, 'link', 'target' ) )\r
+                               allowed = allowed.replace( ']', ',target,onclick]' );\r
+\r
+                       // Add the link and unlink buttons.\r
+                       editor.addCommand( 'link', new CKEDITOR.dialogCommand( 'link', {\r
+                               allowedContent: allowed,\r
+                               requiredContent: required\r
+                       } ) );\r
+                       editor.addCommand( 'anchor', new CKEDITOR.dialogCommand( 'anchor', {\r
+                               allowedContent: 'a[!name,id]',\r
+                               requiredContent: 'a[name]'\r
+                       } ) );\r
+                       editor.addCommand( 'unlink', new CKEDITOR.unlinkCommand() );\r
+                       editor.addCommand( 'removeAnchor', new CKEDITOR.removeAnchorCommand() );\r
+\r
+                       editor.setKeystroke( CKEDITOR.CTRL + 76 /*L*/, 'link' );\r
+\r
+                       if ( editor.ui.addButton ) {\r
+                               editor.ui.addButton( 'Link', {\r
+                                       label: editor.lang.link.toolbar,\r
+                                       command: 'link',\r
+                                       toolbar: 'links,10'\r
+                               } );\r
+                               editor.ui.addButton( 'Unlink', {\r
+                                       label: editor.lang.link.unlink,\r
+                                       command: 'unlink',\r
+                                       toolbar: 'links,20'\r
+                               } );\r
+                               editor.ui.addButton( 'Anchor', {\r
+                                       label: editor.lang.link.anchor.toolbar,\r
+                                       command: 'anchor',\r
+                                       toolbar: 'links,30'\r
+                               } );\r
+                       }\r
+\r
+                       CKEDITOR.dialog.add( 'link', this.path + 'dialogs/link.js' );\r
+                       CKEDITOR.dialog.add( 'anchor', this.path + 'dialogs/anchor.js' );\r
+\r
+                       editor.on( 'doubleclick', function( evt ) {\r
+                               var element = CKEDITOR.plugins.link.getSelectedLink( editor ) || evt.data.element;\r
+\r
+                               if ( !element.isReadOnly() ) {\r
+                                       if ( element.is( 'a' ) ) {\r
+                                               evt.data.dialog = ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) ? 'anchor' : 'link';\r
+\r
+                                               // Pass the link to be selected along with event data.\r
+                                               evt.data.link = element;\r
+                                       } else if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) ) {\r
+                                               evt.data.dialog = 'anchor';\r
+                                       }\r
+                               }\r
+                       }, null, null, 0 );\r
+\r
+                       // If event was cancelled, link passed in event data will not be selected.\r
+                       editor.on( 'doubleclick', function( evt ) {\r
+                               // Make sure both links and anchors are selected (#11822).\r
+                               if ( evt.data.dialog in { link: 1, anchor: 1 } && evt.data.link )\r
+                                       editor.getSelection().selectElement( evt.data.link );\r
+                       }, null, null, 20 );\r
+\r
+                       // If the "menu" plugin is loaded, register the menu items.\r
+                       if ( editor.addMenuItems ) {\r
+                               editor.addMenuItems( {\r
+                                       anchor: {\r
+                                               label: editor.lang.link.anchor.menu,\r
+                                               command: 'anchor',\r
+                                               group: 'anchor',\r
+                                               order: 1\r
+                                       },\r
+\r
+                                       removeAnchor: {\r
+                                               label: editor.lang.link.anchor.remove,\r
+                                               command: 'removeAnchor',\r
+                                               group: 'anchor',\r
+                                               order: 5\r
+                                       },\r
+\r
+                                       link: {\r
+                                               label: editor.lang.link.menu,\r
+                                               command: 'link',\r
+                                               group: 'link',\r
+                                               order: 1\r
+                                       },\r
+\r
+                                       unlink: {\r
+                                               label: editor.lang.link.unlink,\r
+                                               command: 'unlink',\r
+                                               group: 'link',\r
+                                               order: 5\r
+                                       }\r
+                               } );\r
+                       }\r
+\r
+                       // If the "contextmenu" plugin is loaded, register the listeners.\r
+                       if ( editor.contextMenu ) {\r
+                               editor.contextMenu.addListener( function( element ) {\r
+                                       if ( !element || element.isReadOnly() )\r
+                                               return null;\r
+\r
+                                       var anchor = CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element );\r
+\r
+                                       if ( !anchor && !( anchor = CKEDITOR.plugins.link.getSelectedLink( editor ) ) )\r
+                                               return null;\r
+\r
+                                       var menu = {};\r
+\r
+                                       if ( anchor.getAttribute( 'href' ) && anchor.getChildCount() )\r
+                                               menu = { link: CKEDITOR.TRISTATE_OFF, unlink: CKEDITOR.TRISTATE_OFF };\r
+\r
+                                       if ( anchor && anchor.hasAttribute( 'name' ) )\r
+                                               menu.anchor = menu.removeAnchor = CKEDITOR.TRISTATE_OFF;\r
+\r
+                                       return menu;\r
+                               } );\r
+                       }\r
+\r
+                       this.compiledProtectionFunction = getCompiledProtectionFunction( editor );\r
+               },\r
+\r
+               afterInit: function( editor ) {\r
+                       // Empty anchors upcasting to fake objects.\r
+                       editor.dataProcessor.dataFilter.addRules( {\r
+                               elements: {\r
+                                       a: function( element ) {\r
+                                               if ( !element.attributes.name )\r
+                                                       return null;\r
+\r
+                                               if ( !element.children.length )\r
+                                                       return editor.createFakeParserElement( element, 'cke_anchor', 'anchor' );\r
+\r
+                                               return null;\r
+                                       }\r
+                               }\r
+                       } );\r
+\r
+                       var pathFilters = editor._.elementsPath && editor._.elementsPath.filters;\r
+                       if ( pathFilters ) {\r
+                               pathFilters.push( function( element, name ) {\r
+                                       if ( name == 'a' ) {\r
+                                               if ( CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, element ) || ( element.getAttribute( 'name' ) && ( !element.getAttribute( 'href' ) || !element.getChildCount() ) ) )\r
+                                                       return 'anchor';\r
+                                       }\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+\r
+       // Loads the parameters in a selected link to the link dialog fields.\r
+       var javascriptProtocolRegex = /^javascript:/,\r
+               emailRegex = /^mailto:([^?]+)(?:\?(.+))?$/,\r
+               emailSubjectRegex = /subject=([^;?:@&=$,\/]*)/i,\r
+               emailBodyRegex = /body=([^;?:@&=$,\/]*)/i,\r
+               anchorRegex = /^#(.*)$/,\r
+               urlRegex = /^((?:http|https|ftp|news):\/\/)?(.*)$/,\r
+               selectableTargets = /^(_(?:self|top|parent|blank))$/,\r
+               encodedEmailLinkRegex = /^javascript:void\(location\.href='mailto:'\+String\.fromCharCode\(([^)]+)\)(?:\+'(.*)')?\)$/,\r
+               functionCallProtectedEmailLinkRegex = /^javascript:([^(]+)\(([^)]+)\)$/,\r
+               popupRegex = /\s*window.open\(\s*this\.href\s*,\s*(?:'([^']*)'|null)\s*,\s*'([^']*)'\s*\)\s*;\s*return\s*false;*\s*/,\r
+               popupFeaturesRegex = /(?:^|,)([^=]+)=(\d+|yes|no)/gi;\r
+\r
+       var advAttrNames = {\r
+               id: 'advId',\r
+               dir: 'advLangDir',\r
+               accessKey: 'advAccessKey',\r
+               // 'data-cke-saved-name': 'advName',\r
+               name: 'advName',\r
+               lang: 'advLangCode',\r
+               tabindex: 'advTabIndex',\r
+               title: 'advTitle',\r
+               type: 'advContentType',\r
+               'class': 'advCSSClasses',\r
+               charset: 'advCharset',\r
+               style: 'advStyles',\r
+               rel: 'advRel'\r
+       };\r
+\r
+       function unescapeSingleQuote( str ) {\r
+               return str.replace( /\\'/g, '\'' );\r
+       }\r
+\r
+       function escapeSingleQuote( str ) {\r
+               return str.replace( /'/g, '\\$&' );\r
+       }\r
+\r
+       function protectEmailAddressAsEncodedString( address ) {\r
+               var charCode,\r
+                       length = address.length,\r
+                       encodedChars = [];\r
+\r
+               for ( var i = 0; i < length; i++ ) {\r
+                       charCode = address.charCodeAt( i );\r
+                       encodedChars.push( charCode );\r
+               }\r
+\r
+               return 'String.fromCharCode(' + encodedChars.join( ',' ) + ')';\r
+       }\r
+\r
+       function protectEmailLinkAsFunction( editor, email ) {\r
+               var plugin = editor.plugins.link,\r
+                       name = plugin.compiledProtectionFunction.name,\r
+                       params = plugin.compiledProtectionFunction.params,\r
+                       paramName, paramValue, retval;\r
+\r
+               retval = [ name, '(' ];\r
+               for ( var i = 0; i < params.length; i++ ) {\r
+                       paramName = params[ i ].toLowerCase();\r
+                       paramValue = email[ paramName ];\r
+\r
+                       i > 0 && retval.push( ',' );\r
+                       retval.push( '\'', paramValue ? escapeSingleQuote( encodeURIComponent( email[ paramName ] ) ) : '', '\'' );\r
+               }\r
+               retval.push( ')' );\r
+               return retval.join( '' );\r
+       }\r
+\r
+       function getCompiledProtectionFunction( editor ) {\r
+               var emailProtection = editor.config.emailProtection || '',\r
+                       compiledProtectionFunction;\r
+\r
+               // Compile the protection function pattern.\r
+               if ( emailProtection && emailProtection != 'encode' ) {\r
+                       compiledProtectionFunction = {};\r
+\r
+                       emailProtection.replace( /^([^(]+)\(([^)]+)\)$/, function( match, funcName, params ) {\r
+                               compiledProtectionFunction.name = funcName;\r
+                               compiledProtectionFunction.params = [];\r
+                               params.replace( /[^,\s]+/g, function( param ) {\r
+                                       compiledProtectionFunction.params.push( param );\r
+                               } );\r
+                       } );\r
+               }\r
+\r
+               return compiledProtectionFunction;\r
+       }\r
+\r
+       /**\r
+        * Set of Link plugin helpers.\r
+        *\r
+        * @class\r
+        * @singleton\r
+        */\r
+       CKEDITOR.plugins.link = {\r
+               /**\r
+                * Get the surrounding link element of the current selection.\r
+                *\r
+                *              CKEDITOR.plugins.link.getSelectedLink( editor );\r
+                *\r
+                *              // The following selections will all return the link element.\r
+                *\r
+                *              <a href="#">li^nk</a>\r
+                *              <a href="#">[link]</a>\r
+                *              text[<a href="#">link]</a>\r
+                *              <a href="#">li[nk</a>]\r
+                *              [<b><a href="#">li]nk</a></b>]\r
+                *              [<a href="#"><b>li]nk</b></a>\r
+                *\r
+                * @since 3.2.1\r
+                * @param {CKEDITOR.editor} editor\r
+                */\r
+               getSelectedLink: function( editor ) {\r
+                       var selection = editor.getSelection();\r
+                       var selectedElement = selection.getSelectedElement();\r
+                       if ( selectedElement && selectedElement.is( 'a' ) )\r
+                               return selectedElement;\r
+\r
+                       var range = selection.getRanges()[ 0 ];\r
+\r
+                       if ( range ) {\r
+                               range.shrink( CKEDITOR.SHRINK_TEXT );\r
+                               return editor.elementPath( range.getCommonAncestor() ).contains( 'a', 1 );\r
+                       }\r
+                       return null;\r
+               },\r
+\r
+               /**\r
+                * Collects anchors available in the editor (i.e. used by the Link plugin).\r
+                * Note that the scope of search is different for inline (the "global" document) and\r
+                * classic (`iframe`-based) editors (the "inner" document).\r
+                *\r
+                * @since 4.3.3\r
+                * @param {CKEDITOR.editor} editor\r
+                * @returns {CKEDITOR.dom.element[]} An array of anchor elements.\r
+                */\r
+               getEditorAnchors: function( editor ) {\r
+                       var editable = editor.editable(),\r
+\r
+                               // The scope of search for anchors is the entire document for inline editors\r
+                               // and editor's editable for classic editor/divarea (#11359).\r
+                               scope = ( editable.isInline() && !editor.plugins.divarea ) ? editor.document : editable,\r
+\r
+                               links = scope.getElementsByTag( 'a' ),\r
+                               imgs = scope.getElementsByTag( 'img' ),\r
+                               anchors = [],\r
+                               i = 0,\r
+                               item;\r
+\r
+                       // Retrieve all anchors within the scope.\r
+                       while ( ( item = links.getItem( i++ ) ) ) {\r
+                               if ( item.data( 'cke-saved-name' ) || item.hasAttribute( 'name' ) ) {\r
+                                       anchors.push( {\r
+                                               name: item.data( 'cke-saved-name' ) || item.getAttribute( 'name' ),\r
+                                               id: item.getAttribute( 'id' )\r
+                                       } );\r
+                               }\r
+                       }\r
+                       // Retrieve all "fake anchors" within the scope.\r
+                       i = 0;\r
+\r
+                       while ( ( item = imgs.getItem( i++ ) ) ) {\r
+                               if ( ( item = this.tryRestoreFakeAnchor( editor, item ) ) ) {\r
+                                       anchors.push( {\r
+                                               name: item.getAttribute( 'name' ),\r
+                                               id: item.getAttribute( 'id' )\r
+                                       } );\r
+                               }\r
+                       }\r
+\r
+                       return anchors;\r
+               },\r
+\r
+               /**\r
+                * Opera and WebKit do not make it possible to select empty anchors. Fake\r
+                * elements must be used for them.\r
+                *\r
+                * @readonly\r
+                * @deprecated 4.3.3 It is set to `true` in every browser.\r
+                * @property {Boolean}\r
+                */\r
+               fakeAnchor: true,\r
+\r
+               /**\r
+                * For browsers that do not support CSS3 `a[name]:empty()`. Note that IE9 is included because of #7783.\r
+                *\r
+                * @readonly\r
+                * @deprecated 4.3.3 It is set to `false` in every browser.\r
+                * @property {Boolean} synAnchorSelector\r
+                */\r
+\r
+               /**\r
+                * For browsers that have editing issues with an empty anchor.\r
+                *\r
+                * @readonly\r
+                * @deprecated 4.3.3 It is set to `false` in every browser.\r
+                * @property {Boolean} emptyAnchorFix\r
+                */\r
+\r
+               /**\r
+                * Returns an element representing a real anchor restored from a fake anchor.\r
+                *\r
+                * @param {CKEDITOR.editor} editor\r
+                * @param {CKEDITOR.dom.element} element\r
+                * @returns {CKEDITOR.dom.element} Restored anchor element or nothing if the\r
+                * passed element was not a fake anchor.\r
+                */\r
+               tryRestoreFakeAnchor: function( editor, element ) {\r
+                       if ( element && element.data( 'cke-real-element-type' ) && element.data( 'cke-real-element-type' ) == 'anchor' ) {\r
+                               var link = editor.restoreRealElement( element );\r
+                               if ( link.data( 'cke-saved-name' ) )\r
+                                       return link;\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Parses attributes of the link element and returns an object representing\r
+                * the current state (data) of the link. This data format is a plain object accepted\r
+                * e.g. by the Link dialog window and {@link #getLinkAttributes}.\r
+                *\r
+                * **Note:** Data model format produced by the parser must be compatible with the Link\r
+                * plugin dialog because it is passed directly to {@link CKEDITOR.dialog#setupContent}.\r
+                *\r
+                * @since 4.4\r
+                * @param {CKEDITOR.editor} editor\r
+                * @param {CKEDITOR.dom.element} element\r
+                * @returns {Object} An object of link data.\r
+                */\r
+               parseLinkAttributes: function( editor, element ) {\r
+                       var href = ( element && ( element.data( 'cke-saved-href' ) || element.getAttribute( 'href' ) ) ) || '',\r
+                               compiledProtectionFunction = editor.plugins.link.compiledProtectionFunction,\r
+                               emailProtection = editor.config.emailProtection,\r
+                               javascriptMatch, emailMatch, anchorMatch, urlMatch,\r
+                               retval = {};\r
+\r
+                       if ( ( javascriptMatch = href.match( javascriptProtocolRegex ) ) ) {\r
+                               if ( emailProtection == 'encode' ) {\r
+                                       href = href.replace( encodedEmailLinkRegex, function( match, protectedAddress, rest ) {\r
+                                               // Without it 'undefined' is appended to e-mails without subject and body (#9192).\r
+                                               rest = rest || '';\r
+\r
+                                               return 'mailto:' +\r
+                                                       String.fromCharCode.apply( String, protectedAddress.split( ',' ) ) +\r
+                                                       unescapeSingleQuote( rest );\r
+                                       } );\r
+                               }\r
+                               // Protected email link as function call.\r
+                               else if ( emailProtection ) {\r
+                                       href.replace( functionCallProtectedEmailLinkRegex, function( match, funcName, funcArgs ) {\r
+                                               if ( funcName == compiledProtectionFunction.name ) {\r
+                                                       retval.type = 'email';\r
+                                                       var email = retval.email = {};\r
+\r
+                                                       var paramRegex = /[^,\s]+/g,\r
+                                                               paramQuoteRegex = /(^')|('$)/g,\r
+                                                               paramsMatch = funcArgs.match( paramRegex ),\r
+                                                               paramsMatchLength = paramsMatch.length,\r
+                                                               paramName, paramVal;\r
+\r
+                                                       for ( var i = 0; i < paramsMatchLength; i++ ) {\r
+                                                               paramVal = decodeURIComponent( unescapeSingleQuote( paramsMatch[ i ].replace( paramQuoteRegex, '' ) ) );\r
+                                                               paramName = compiledProtectionFunction.params[ i ].toLowerCase();\r
+                                                               email[ paramName ] = paramVal;\r
+                                                       }\r
+                                                       email.address = [ email.name, email.domain ].join( '@' );\r
+                                               }\r
+                                       } );\r
+                               }\r
+                       }\r
+\r
+                       if ( !retval.type ) {\r
+                               if ( ( anchorMatch = href.match( anchorRegex ) ) ) {\r
+                                       retval.type = 'anchor';\r
+                                       retval.anchor = {};\r
+                                       retval.anchor.name = retval.anchor.id = anchorMatch[ 1 ];\r
+                               }\r
+                               // Protected email link as encoded string.\r
+                               else if ( ( emailMatch = href.match( emailRegex ) ) ) {\r
+                                       var subjectMatch = href.match( emailSubjectRegex ),\r
+                                               bodyMatch = href.match( emailBodyRegex );\r
+\r
+                                       retval.type = 'email';\r
+                                       var email = ( retval.email = {} );\r
+                                       email.address = emailMatch[ 1 ];\r
+                                       subjectMatch && ( email.subject = decodeURIComponent( subjectMatch[ 1 ] ) );\r
+                                       bodyMatch && ( email.body = decodeURIComponent( bodyMatch[ 1 ] ) );\r
+                               }\r
+                               // urlRegex matches empty strings, so need to check for href as well.\r
+                               else if ( href && ( urlMatch = href.match( urlRegex ) ) ) {\r
+                                       retval.type = 'url';\r
+                                       retval.url = {};\r
+                                       retval.url.protocol = urlMatch[ 1 ];\r
+                                       retval.url.url = urlMatch[ 2 ];\r
+                               }\r
+                       }\r
+\r
+                       // Load target and popup settings.\r
+                       if ( element ) {\r
+                               var target = element.getAttribute( 'target' );\r
+\r
+                               // IE BUG: target attribute is an empty string instead of null in IE if it's not set.\r
+                               if ( !target ) {\r
+                                       var onclick = element.data( 'cke-pa-onclick' ) || element.getAttribute( 'onclick' ),\r
+                                               onclickMatch = onclick && onclick.match( popupRegex );\r
+\r
+                                       if ( onclickMatch ) {\r
+                                               retval.target = {\r
+                                                       type: 'popup',\r
+                                                       name: onclickMatch[ 1 ]\r
+                                               };\r
+\r
+                                               var featureMatch;\r
+                                               while ( ( featureMatch = popupFeaturesRegex.exec( onclickMatch[ 2 ] ) ) ) {\r
+                                                       // Some values should remain numbers (#7300)\r
+                                                       if ( ( featureMatch[ 2 ] == 'yes' || featureMatch[ 2 ] == '1' ) && !( featureMatch[ 1 ] in { height: 1, width: 1, top: 1, left: 1 } ) )\r
+                                                               retval.target[ featureMatch[ 1 ] ] = true;\r
+                                                       else if ( isFinite( featureMatch[ 2 ] ) )\r
+                                                               retval.target[ featureMatch[ 1 ] ] = featureMatch[ 2 ];\r
+                                               }\r
+                                       }\r
+                               } else {\r
+                                       retval.target = {\r
+                                               type: target.match( selectableTargets ) ? target : 'frame',\r
+                                               name: target\r
+                                       };\r
+                               }\r
+\r
+                               var download = element.getAttribute( 'download' );\r
+                               if ( download !== null ) {\r
+                                       retval.download = true;\r
+                               }\r
+\r
+                               var advanced = {};\r
+\r
+                               for ( var a in advAttrNames ) {\r
+                                       var val = element.getAttribute( a );\r
+\r
+                                       if ( val )\r
+                                               advanced[ advAttrNames[ a ] ] = val;\r
+                               }\r
+\r
+                               var advName = element.data( 'cke-saved-name' ) || advanced.advName;\r
+\r
+                               if ( advName )\r
+                                       advanced.advName = advName;\r
+\r
+                               if ( !CKEDITOR.tools.isEmpty( advanced ) )\r
+                                       retval.advanced = advanced;\r
+                       }\r
+\r
+                       return retval;\r
+               },\r
+\r
+               /**\r
+                * Converts link data produced by {@link #parseLinkAttributes} into an object which consists\r
+                * of attributes to be set (with their values) and an array of attributes to be removed.\r
+                * This method can be used to compose or to update any link element with the given data.\r
+                *\r
+                * @since 4.4\r
+                * @param {CKEDITOR.editor} editor\r
+                * @param {Object} data Data in {@link #parseLinkAttributes} format.\r
+                * @returns {Object} An object consisting of two keys, i.e.:\r
+                *\r
+                *              {\r
+                *                      // Attributes to be set.\r
+                *                      set: {\r
+                *                              href: 'http://foo.bar',\r
+                *                              target: 'bang'\r
+                *                      },\r
+                *                      // Attributes to be removed.\r
+                *                      removed: [\r
+                *                              'id', 'style'\r
+                *                      ]\r
+                *              }\r
+                *\r
+                */\r
+               getLinkAttributes: function( editor, data ) {\r
+                       var emailProtection = editor.config.emailProtection || '',\r
+                               set = {};\r
+\r
+                       // Compose the URL.\r
+                       switch ( data.type ) {\r
+                               case 'url':\r
+                                       var protocol = ( data.url && data.url.protocol !== undefined ) ? data.url.protocol : 'http://',\r
+                                               url = ( data.url && CKEDITOR.tools.trim( data.url.url ) ) || '';\r
+\r
+                                       set[ 'data-cke-saved-href' ] = ( url.indexOf( '/' ) === 0 ) ? url : protocol + url;\r
+\r
+                                       break;\r
+                               case 'anchor':\r
+                                       var name = ( data.anchor && data.anchor.name ),\r
+                                               id = ( data.anchor && data.anchor.id );\r
+\r
+                                       set[ 'data-cke-saved-href' ] = '#' + ( name || id || '' );\r
+\r
+                                       break;\r
+                               case 'email':\r
+                                       var email = data.email,\r
+                                               address = email.address,\r
+                                               linkHref;\r
+\r
+                                       switch ( emailProtection ) {\r
+                                               case '':\r
+                                               case 'encode':\r
+                                                       var subject = encodeURIComponent( email.subject || '' ),\r
+                                                               body = encodeURIComponent( email.body || '' ),\r
+                                                               argList = [];\r
+\r
+                                                       // Build the e-mail parameters first.\r
+                                                       subject && argList.push( 'subject=' + subject );\r
+                                                       body && argList.push( 'body=' + body );\r
+                                                       argList = argList.length ? '?' + argList.join( '&' ) : '';\r
+\r
+                                                       if ( emailProtection == 'encode' ) {\r
+                                                               linkHref = [\r
+                                                                       'javascript:void(location.href=\'mailto:\'+', // jshint ignore:line\r
+                                                                       protectEmailAddressAsEncodedString( address )\r
+                                                               ];\r
+                                                               // parameters are optional.\r
+                                                               argList && linkHref.push( '+\'', escapeSingleQuote( argList ), '\'' );\r
+\r
+                                                               linkHref.push( ')' );\r
+                                                       } else {\r
+                                                               linkHref = [ 'mailto:', address, argList ];\r
+                                                       }\r
+\r
+                                                       break;\r
+                                               default:\r
+                                                       // Separating name and domain.\r
+                                                       var nameAndDomain = address.split( '@', 2 );\r
+                                                       email.name = nameAndDomain[ 0 ];\r
+                                                       email.domain = nameAndDomain[ 1 ];\r
+\r
+                                                       linkHref = [ 'javascript:', protectEmailLinkAsFunction( editor, email ) ]; // jshint ignore:line\r
+                                       }\r
+\r
+                                       set[ 'data-cke-saved-href' ] = linkHref.join( '' );\r
+                                       break;\r
+                       }\r
+\r
+                       // Popups and target.\r
+                       if ( data.target ) {\r
+                               if ( data.target.type == 'popup' ) {\r
+                                       var onclickList = [\r
+                                                       'window.open(this.href, \'', data.target.name || '', '\', \''\r
+                                               ],\r
+                                               featureList = [\r
+                                                       'resizable', 'status', 'location', 'toolbar', 'menubar', 'fullscreen', 'scrollbars', 'dependent'\r
+                                               ],\r
+                                               featureLength = featureList.length,\r
+                                               addFeature = function( featureName ) {\r
+                                                       if ( data.target[ featureName ] )\r
+                                                               featureList.push( featureName + '=' + data.target[ featureName ] );\r
+                                               };\r
+\r
+                                       for ( var i = 0; i < featureLength; i++ )\r
+                                               featureList[ i ] = featureList[ i ] + ( data.target[ featureList[ i ] ] ? '=yes' : '=no' );\r
+\r
+                                       addFeature( 'width' );\r
+                                       addFeature( 'left' );\r
+                                       addFeature( 'height' );\r
+                                       addFeature( 'top' );\r
+\r
+                                       onclickList.push( featureList.join( ',' ), '\'); return false;' );\r
+                                       set[ 'data-cke-pa-onclick' ] = onclickList.join( '' );\r
+                               }\r
+                               else if ( data.target.type != 'notSet' && data.target.name ) {\r
+                                       set.target = data.target.name;\r
+                               }\r
+                       }\r
+\r
+                       // Force download attribute.\r
+                       if ( data.download ) {\r
+                               set.download = '';\r
+                       }\r
+\r
+                       // Advanced attributes.\r
+                       if ( data.advanced ) {\r
+                               for ( var a in advAttrNames ) {\r
+                                       var val = data.advanced[ advAttrNames[ a ] ];\r
+\r
+                                       if ( val )\r
+                                               set[ a ] = val;\r
+                               }\r
+\r
+                               if ( set.name )\r
+                                       set[ 'data-cke-saved-name' ] = set.name;\r
+                       }\r
+\r
+                       // Browser need the "href" fro copy/paste link to work. (#6641)\r
+                       if ( set[ 'data-cke-saved-href' ] )\r
+                               set.href = set[ 'data-cke-saved-href' ];\r
+\r
+                       var removed = {\r
+                               target: 1,\r
+                               onclick: 1,\r
+                               'data-cke-pa-onclick': 1,\r
+                               'data-cke-saved-name': 1,\r
+                               'download': 1\r
+                       };\r
+\r
+                       if ( data.advanced )\r
+                               CKEDITOR.tools.extend( removed, advAttrNames );\r
+\r
+                       // Remove all attributes which are not currently set.\r
+                       for ( var s in set )\r
+                               delete removed[ s ];\r
+\r
+                       return {\r
+                               set: set,\r
+                               removed: CKEDITOR.tools.objectKeys( removed )\r
+                       };\r
+               },\r
+\r
+\r
+               /**\r
+                * Determines whether an element should have a "Display Text" field in the Link dialog.\r
+                *\r
+                * @since 4.5.11\r
+                * @param {CKEDITOR.dom.element/null} element Selected element, `null` if none selected or if a ranged selection\r
+                * is made.\r
+                * @param {CKEDITOR.editor} editor The editor instance for which the check is performed.\r
+                * @returns {Boolean}\r
+                */\r
+               showDisplayTextForElement: function( element, editor ) {\r
+                       var undesiredElements = {\r
+                               img: 1,\r
+                               table: 1,\r
+                               tbody: 1,\r
+                               thead: 1,\r
+                               tfoot: 1,\r
+                               input: 1,\r
+                               select: 1,\r
+                               textarea: 1\r
+                       };\r
+\r
+                       // Widget duck typing, we don't want to show display text for widgets.\r
+                       if ( editor.widgets && editor.widgets.focused ) {\r
+                               return false;\r
+                       }\r
+\r
+                       return !element || !element.getName || !element.is( undesiredElements );\r
+               }\r
+       };\r
+\r
+       // TODO Much probably there's no need to expose these as public objects.\r
+\r
+       CKEDITOR.unlinkCommand = function() {};\r
+       CKEDITOR.unlinkCommand.prototype = {\r
+               exec: function( editor ) {\r
+                       var style = new CKEDITOR.style( { element: 'a', type: CKEDITOR.STYLE_INLINE, alwaysRemoveElement: 1 } );\r
+                       editor.removeStyle( style );\r
+               },\r
+\r
+               refresh: function( editor, path ) {\r
+                       // Despite our initial hope, document.queryCommandEnabled() does not work\r
+                       // for this in Firefox. So we must detect the state by element paths.\r
+\r
+                       var element = path.lastElement && path.lastElement.getAscendant( 'a', true );\r
+\r
+                       if ( element && element.getName() == 'a' && element.getAttribute( 'href' ) && element.getChildCount() )\r
+                               this.setState( CKEDITOR.TRISTATE_OFF );\r
+                       else\r
+                               this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+               },\r
+\r
+               contextSensitive: 1,\r
+               startDisabled: 1,\r
+               requiredContent: 'a[href]'\r
+       };\r
+\r
+       CKEDITOR.removeAnchorCommand = function() {};\r
+       CKEDITOR.removeAnchorCommand.prototype = {\r
+               exec: function( editor ) {\r
+                       var sel = editor.getSelection(),\r
+                               bms = sel.createBookmarks(),\r
+                               anchor;\r
+                       if ( sel && ( anchor = sel.getSelectedElement() ) && ( !anchor.getChildCount() ? CKEDITOR.plugins.link.tryRestoreFakeAnchor( editor, anchor ) : anchor.is( 'a' ) ) )\r
+                               anchor.remove( 1 );\r
+                       else {\r
+                               if ( ( anchor = CKEDITOR.plugins.link.getSelectedLink( editor ) ) ) {\r
+                                       if ( anchor.hasAttribute( 'href' ) ) {\r
+                                               anchor.removeAttributes( { name: 1, 'data-cke-saved-name': 1 } );\r
+                                               anchor.removeClass( 'cke_anchor' );\r
+                                       } else {\r
+                                               anchor.remove( 1 );\r
+                                       }\r
+                               }\r
+                       }\r
+                       sel.selectBookmarks( bms );\r
+               },\r
+               requiredContent: 'a[name]'\r
+       };\r
+\r
+       CKEDITOR.tools.extend( CKEDITOR.config, {\r
+               /**\r
+                * Whether to show the Advanced tab in the Link dialog window.\r
+                *\r
+                * @cfg {Boolean} [linkShowAdvancedTab=true]\r
+                * @member CKEDITOR.config\r
+                */\r
+               linkShowAdvancedTab: true,\r
+\r
+               /**\r
+                * Whether to show the Target tab in the Link dialog window.\r
+                *\r
+                * @cfg {Boolean} [linkShowTargetTab=true]\r
+                * @member CKEDITOR.config\r
+                */\r
+               linkShowTargetTab: true\r
+\r
+               /**\r
+                * Whether JavaScript code is allowed as a `href` attribute in an anchor tag.\r
+                * With this option enabled it is possible to create links like:\r
+                *\r
+                *              <a href="javascript:alert('Hello world!')">hello world</a>\r
+                *\r
+                * By default JavaScript links are not allowed and will not pass\r
+                * the Link dialog window validation.\r
+                *\r
+                * @since 4.4.1\r
+                * @cfg {Boolean} [linkJavaScriptLinksAllowed=false]\r
+                * @member CKEDITOR.config\r
+                */\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/list/icons/bulletedlist-rtl.png b/sources/plugins/list/icons/bulletedlist-rtl.png
new file mode 100644 (file)
index 0000000..2fed6b5
Binary files /dev/null and b/sources/plugins/list/icons/bulletedlist-rtl.png differ
diff --git a/sources/plugins/list/icons/bulletedlist.png b/sources/plugins/list/icons/bulletedlist.png
new file mode 100644 (file)
index 0000000..8d33138
Binary files /dev/null and b/sources/plugins/list/icons/bulletedlist.png differ
diff --git a/sources/plugins/list/icons/hidpi/bulletedlist-rtl.png b/sources/plugins/list/icons/hidpi/bulletedlist-rtl.png
new file mode 100644 (file)
index 0000000..7e08fb3
Binary files /dev/null and b/sources/plugins/list/icons/hidpi/bulletedlist-rtl.png differ
diff --git a/sources/plugins/list/icons/hidpi/bulletedlist.png b/sources/plugins/list/icons/hidpi/bulletedlist.png
new file mode 100644 (file)
index 0000000..796923f
Binary files /dev/null and b/sources/plugins/list/icons/hidpi/bulletedlist.png differ
diff --git a/sources/plugins/list/icons/hidpi/numberedlist-rtl.png b/sources/plugins/list/icons/hidpi/numberedlist-rtl.png
new file mode 100644 (file)
index 0000000..2ece272
Binary files /dev/null and b/sources/plugins/list/icons/hidpi/numberedlist-rtl.png differ
diff --git a/sources/plugins/list/icons/hidpi/numberedlist.png b/sources/plugins/list/icons/hidpi/numberedlist.png
new file mode 100644 (file)
index 0000000..20fe003
Binary files /dev/null and b/sources/plugins/list/icons/hidpi/numberedlist.png differ
diff --git a/sources/plugins/list/icons/numberedlist-rtl.png b/sources/plugins/list/icons/numberedlist-rtl.png
new file mode 100644 (file)
index 0000000..3c62d8d
Binary files /dev/null and b/sources/plugins/list/icons/numberedlist-rtl.png differ
diff --git a/sources/plugins/list/icons/numberedlist.png b/sources/plugins/list/icons/numberedlist.png
new file mode 100644 (file)
index 0000000..d47e0d5
Binary files /dev/null and b/sources/plugins/list/icons/numberedlist.png differ
diff --git a/sources/plugins/list/lang/af.js b/sources/plugins/list/lang/af.js
new file mode 100644 (file)
index 0000000..6b92ff6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'af', {\r
+       bulletedlist: 'Ongenommerde lys',\r
+       numberedlist: 'Genommerde lys'\r
+} );\r
diff --git a/sources/plugins/list/lang/ar.js b/sources/plugins/list/lang/ar.js
new file mode 100644 (file)
index 0000000..a7a7de7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ar', {\r
+       bulletedlist: 'ادخال/حذف تعداد نقطي',\r
+       numberedlist: 'ادخال/حذف تعداد رقمي'\r
+} );\r
diff --git a/sources/plugins/list/lang/az.js b/sources/plugins/list/lang/az.js
new file mode 100644 (file)
index 0000000..5d4e513
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'az', {\r
+       bulletedlist: 'Markerlənmiş siyahını başlat/sil',\r
+       numberedlist: 'Nömrələnmiş siyahını başlat/sil'\r
+} );\r
diff --git a/sources/plugins/list/lang/bg.js b/sources/plugins/list/lang/bg.js
new file mode 100644 (file)
index 0000000..6ac7ab6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'bg', {\r
+       bulletedlist: 'Вмъкване/Премахване на точков списък',\r
+       numberedlist: 'Вмъкване/Премахване на номериран списък'\r
+} );\r
diff --git a/sources/plugins/list/lang/bn.js b/sources/plugins/list/lang/bn.js
new file mode 100644 (file)
index 0000000..cf6a85a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'bn', {\r
+       bulletedlist: 'বুলেটেড তালিকা প্রবেশ/অপসারন করি',\r
+       numberedlist: 'সাংখ্যিক লিস্টের লেবেল'\r
+} );\r
diff --git a/sources/plugins/list/lang/bs.js b/sources/plugins/list/lang/bs.js
new file mode 100644 (file)
index 0000000..76877b5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'bs', {\r
+       bulletedlist: 'Lista',\r
+       numberedlist: 'Numerisana lista'\r
+} );\r
diff --git a/sources/plugins/list/lang/ca.js b/sources/plugins/list/lang/ca.js
new file mode 100644 (file)
index 0000000..408cf53
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ca', {\r
+       bulletedlist: 'Llista de pics',\r
+       numberedlist: 'Llista numerada'\r
+} );\r
diff --git a/sources/plugins/list/lang/cs.js b/sources/plugins/list/lang/cs.js
new file mode 100644 (file)
index 0000000..e04b94d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'cs', {\r
+       bulletedlist: 'Odrážky',\r
+       numberedlist: 'Číslování'\r
+} );\r
diff --git a/sources/plugins/list/lang/cy.js b/sources/plugins/list/lang/cy.js
new file mode 100644 (file)
index 0000000..c786d4b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'cy', {\r
+       bulletedlist: 'Mewnosod/Tynnu Rhestr Bwled',\r
+       numberedlist: 'Mewnosod/Tynnu Rhestr Rhifol'\r
+} );\r
diff --git a/sources/plugins/list/lang/da.js b/sources/plugins/list/lang/da.js
new file mode 100644 (file)
index 0000000..5c90ec9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'da', {\r
+       bulletedlist: 'Punktopstilling',\r
+       numberedlist: 'Talopstilling'\r
+} );\r
diff --git a/sources/plugins/list/lang/de-ch.js b/sources/plugins/list/lang/de-ch.js
new file mode 100644 (file)
index 0000000..7d72503
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'de-ch', {\r
+       bulletedlist: 'Liste',\r
+       numberedlist: 'Nummerierte Liste einfügen/entfernen'\r
+} );\r
diff --git a/sources/plugins/list/lang/de.js b/sources/plugins/list/lang/de.js
new file mode 100644 (file)
index 0000000..ef4b5f2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'de', {\r
+       bulletedlist: 'Liste',\r
+       numberedlist: 'Nummerierte Liste einfügen/entfernen'\r
+} );\r
diff --git a/sources/plugins/list/lang/el.js b/sources/plugins/list/lang/el.js
new file mode 100644 (file)
index 0000000..feeebac
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'el', {\r
+       bulletedlist: 'Εισαγωγή/Απομάκρυνση Λίστας Κουκκίδων',\r
+       numberedlist: 'Εισαγωγή/Απομάκρυνση Αριθμημένης Λίστας'\r
+} );\r
diff --git a/sources/plugins/list/lang/en-au.js b/sources/plugins/list/lang/en-au.js
new file mode 100644 (file)
index 0000000..d3bbc2b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'en-au', {\r
+       bulletedlist: 'Insert/Remove Bulleted List',\r
+       numberedlist: 'Insert/Remove Numbered List'\r
+} );\r
diff --git a/sources/plugins/list/lang/en-ca.js b/sources/plugins/list/lang/en-ca.js
new file mode 100644 (file)
index 0000000..80be02f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'en-ca', {\r
+       bulletedlist: 'Insert/Remove Bulleted List',\r
+       numberedlist: 'Insert/Remove Numbered List'\r
+} );\r
diff --git a/sources/plugins/list/lang/en-gb.js b/sources/plugins/list/lang/en-gb.js
new file mode 100644 (file)
index 0000000..07db96c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'en-gb', {\r
+       bulletedlist: 'Insert/Remove Bulleted List',\r
+       numberedlist: 'Insert/Remove Numbered List'\r
+} );\r
diff --git a/sources/plugins/list/lang/en.js b/sources/plugins/list/lang/en.js
new file mode 100644 (file)
index 0000000..0bdc852
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'en', {\r
+       bulletedlist: 'Insert/Remove Bulleted List',\r
+       numberedlist: 'Insert/Remove Numbered List'\r
+} );\r
diff --git a/sources/plugins/list/lang/eo.js b/sources/plugins/list/lang/eo.js
new file mode 100644 (file)
index 0000000..9242615
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'eo', {\r
+       bulletedlist: 'Bula Listo',\r
+       numberedlist: 'Numera Listo'\r
+} );\r
diff --git a/sources/plugins/list/lang/es.js b/sources/plugins/list/lang/es.js
new file mode 100644 (file)
index 0000000..37f1904
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'es', {\r
+       bulletedlist: 'Viñetas',\r
+       numberedlist: 'Numeración'\r
+} );\r
diff --git a/sources/plugins/list/lang/et.js b/sources/plugins/list/lang/et.js
new file mode 100644 (file)
index 0000000..498c8a5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'et', {\r
+       bulletedlist: 'Punktloend',\r
+       numberedlist: 'Numberloend'\r
+} );\r
diff --git a/sources/plugins/list/lang/eu.js b/sources/plugins/list/lang/eu.js
new file mode 100644 (file)
index 0000000..254793d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'eu', {\r
+       bulletedlist: 'Buletdun Zerrenda',\r
+       numberedlist: 'Zenbakidun Zerrenda'\r
+} );\r
diff --git a/sources/plugins/list/lang/fa.js b/sources/plugins/list/lang/fa.js
new file mode 100644 (file)
index 0000000..af3f9dd
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'fa', {\r
+       bulletedlist: 'فهرست نقطه​ای',\r
+       numberedlist: 'فهرست شماره​دار'\r
+} );\r
diff --git a/sources/plugins/list/lang/fi.js b/sources/plugins/list/lang/fi.js
new file mode 100644 (file)
index 0000000..3874597
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'fi', {\r
+       bulletedlist: 'Luettelomerkit',\r
+       numberedlist: 'Numerointi'\r
+} );\r
diff --git a/sources/plugins/list/lang/fo.js b/sources/plugins/list/lang/fo.js
new file mode 100644 (file)
index 0000000..416c667
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'fo', {\r
+       bulletedlist: 'Punktmerktur listi',\r
+       numberedlist: 'Talmerktur listi'\r
+} );\r
diff --git a/sources/plugins/list/lang/fr-ca.js b/sources/plugins/list/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..e9eb2b7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'fr-ca', {\r
+       bulletedlist: 'Liste à puces',\r
+       numberedlist: 'Liste numérotée'\r
+} );\r
diff --git a/sources/plugins/list/lang/fr.js b/sources/plugins/list/lang/fr.js
new file mode 100644 (file)
index 0000000..cb49ec7
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'fr', {\r
+       bulletedlist: 'Insérer/Supprimer une liste à puces',\r
+       numberedlist: 'Insérer/Supprimer une liste numérotée'\r
+} );\r
diff --git a/sources/plugins/list/lang/gl.js b/sources/plugins/list/lang/gl.js
new file mode 100644 (file)
index 0000000..d020a69
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'gl', {\r
+       bulletedlist: 'Inserir/retirar lista viñeteada',\r
+       numberedlist: 'Inserir/retirar lista numerada'\r
+} );\r
diff --git a/sources/plugins/list/lang/gu.js b/sources/plugins/list/lang/gu.js
new file mode 100644 (file)
index 0000000..24a728f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'gu', {\r
+       bulletedlist: 'બુલેટ સૂચિ',\r
+       numberedlist: 'સંખ્યાંકન સૂચિ'\r
+} );\r
diff --git a/sources/plugins/list/lang/he.js b/sources/plugins/list/lang/he.js
new file mode 100644 (file)
index 0000000..118ddae
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'he', {\r
+       bulletedlist: 'רשימת נקודות',\r
+       numberedlist: 'רשימה ממוספרת'\r
+} );\r
diff --git a/sources/plugins/list/lang/hi.js b/sources/plugins/list/lang/hi.js
new file mode 100644 (file)
index 0000000..a6bbca5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'hi', {\r
+       bulletedlist: 'बुलॅट सूची',\r
+       numberedlist: 'अंकीय सूची'\r
+} );\r
diff --git a/sources/plugins/list/lang/hr.js b/sources/plugins/list/lang/hr.js
new file mode 100644 (file)
index 0000000..ceb0a4c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'hr', {\r
+       bulletedlist: 'Obična lista',\r
+       numberedlist: 'Brojčana lista'\r
+} );\r
diff --git a/sources/plugins/list/lang/hu.js b/sources/plugins/list/lang/hu.js
new file mode 100644 (file)
index 0000000..cf2fe96
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'hu', {\r
+       bulletedlist: 'Felsorolás',\r
+       numberedlist: 'Számozás'\r
+} );\r
diff --git a/sources/plugins/list/lang/id.js b/sources/plugins/list/lang/id.js
new file mode 100644 (file)
index 0000000..0b360dc
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'id', {\r
+       bulletedlist: 'Sisip/Hapus Daftar Bullet',\r
+       numberedlist: 'Sisip/Hapus Daftar Bernomor'\r
+} );\r
diff --git a/sources/plugins/list/lang/is.js b/sources/plugins/list/lang/is.js
new file mode 100644 (file)
index 0000000..a23e87e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'is', {\r
+       bulletedlist: 'Punktalisti',\r
+       numberedlist: 'Númeraður listi'\r
+} );\r
diff --git a/sources/plugins/list/lang/it.js b/sources/plugins/list/lang/it.js
new file mode 100644 (file)
index 0000000..611f6fb
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'it', {\r
+       bulletedlist: 'Inserisci/Rimuovi Elenco Puntato',\r
+       numberedlist: 'Inserisci/Rimuovi Elenco Numerato'\r
+} );\r
diff --git a/sources/plugins/list/lang/ja.js b/sources/plugins/list/lang/ja.js
new file mode 100644 (file)
index 0000000..c2df282
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ja', {\r
+       bulletedlist: '番号無しリスト',\r
+       numberedlist: '番号付きリスト'\r
+} );\r
diff --git a/sources/plugins/list/lang/ka.js b/sources/plugins/list/lang/ka.js
new file mode 100644 (file)
index 0000000..2053130
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ka', {\r
+       bulletedlist: 'ღილიანი სია',\r
+       numberedlist: 'გადანომრილი სია'\r
+} );\r
diff --git a/sources/plugins/list/lang/km.js b/sources/plugins/list/lang/km.js
new file mode 100644 (file)
index 0000000..71c0c7b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'km', {\r
+       bulletedlist: 'បញ្ចូល / លុប​បញ្ជី​ជា​ចំណុច​មូល',\r
+       numberedlist: 'បញ្ចូល / លុប​បញ្ជី​ជា​លេខ'\r
+} );\r
diff --git a/sources/plugins/list/lang/ko.js b/sources/plugins/list/lang/ko.js
new file mode 100644 (file)
index 0000000..48b4fd0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ko', {\r
+       bulletedlist: '순서 없는 목록',\r
+       numberedlist: '순서 있는 목록'\r
+} );\r
diff --git a/sources/plugins/list/lang/ku.js b/sources/plugins/list/lang/ku.js
new file mode 100644 (file)
index 0000000..c5d0d9c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ku', {\r
+       bulletedlist: 'دانان/لابردنی خاڵی لیست',\r
+       numberedlist: 'دانان/لابردنی ژمارەی لیست'\r
+} );\r
diff --git a/sources/plugins/list/lang/lt.js b/sources/plugins/list/lang/lt.js
new file mode 100644 (file)
index 0000000..0eac62e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'lt', {\r
+       bulletedlist: 'Suženklintas sąrašas',\r
+       numberedlist: 'Numeruotas sąrašas'\r
+} );\r
diff --git a/sources/plugins/list/lang/lv.js b/sources/plugins/list/lang/lv.js
new file mode 100644 (file)
index 0000000..6738856
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'lv', {\r
+       bulletedlist: 'Pievienot/Noņemt vienkāršu sarakstu',\r
+       numberedlist: 'Numurēts saraksts'\r
+} );\r
diff --git a/sources/plugins/list/lang/mk.js b/sources/plugins/list/lang/mk.js
new file mode 100644 (file)
index 0000000..4054ea2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'mk', {\r
+       bulletedlist: 'Insert/Remove Bulleted List', // MISSING\r
+       numberedlist: 'Insert/Remove Numbered List' // MISSING\r
+} );\r
diff --git a/sources/plugins/list/lang/mn.js b/sources/plugins/list/lang/mn.js
new file mode 100644 (file)
index 0000000..ef9d4e0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'mn', {\r
+       bulletedlist: 'Цэгтэй жагсаалт',\r
+       numberedlist: 'Дугаарлагдсан жагсаалт'\r
+} );\r
diff --git a/sources/plugins/list/lang/ms.js b/sources/plugins/list/lang/ms.js
new file mode 100644 (file)
index 0000000..6d51a33
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ms', {\r
+       bulletedlist: 'Senarai tidak bernombor',\r
+       numberedlist: 'Senarai bernombor'\r
+} );\r
diff --git a/sources/plugins/list/lang/nb.js b/sources/plugins/list/lang/nb.js
new file mode 100644 (file)
index 0000000..0e817c8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'nb', {\r
+       bulletedlist: 'Legg til / fjern punktliste',\r
+       numberedlist: 'Legg til / fjern nummerert liste'\r
+} );\r
diff --git a/sources/plugins/list/lang/nl.js b/sources/plugins/list/lang/nl.js
new file mode 100644 (file)
index 0000000..65f71e9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'nl', {\r
+       bulletedlist: 'Opsomming invoegen',\r
+       numberedlist: 'Genummerde lijst invoegen'\r
+} );\r
diff --git a/sources/plugins/list/lang/no.js b/sources/plugins/list/lang/no.js
new file mode 100644 (file)
index 0000000..dc129c5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'no', {\r
+       bulletedlist: 'Legg til/Fjern punktmerket liste',\r
+       numberedlist: 'Legg til/Fjern nummerert liste'\r
+} );\r
diff --git a/sources/plugins/list/lang/oc.js b/sources/plugins/list/lang/oc.js
new file mode 100644 (file)
index 0000000..4705e9a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'oc', {\r
+       bulletedlist: 'Inserir/Suprimir una lista amb de piuses',\r
+       numberedlist: 'Inserir/Suprimir una lista numerotada'\r
+} );\r
diff --git a/sources/plugins/list/lang/pl.js b/sources/plugins/list/lang/pl.js
new file mode 100644 (file)
index 0000000..0a0e552
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'pl', {\r
+       bulletedlist: 'Lista wypunktowana',\r
+       numberedlist: 'Lista numerowana'\r
+} );\r
diff --git a/sources/plugins/list/lang/pt-br.js b/sources/plugins/list/lang/pt-br.js
new file mode 100644 (file)
index 0000000..b0edd8e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'pt-br', {\r
+       bulletedlist: 'Lista sem números',\r
+       numberedlist: 'Lista numerada'\r
+} );\r
diff --git a/sources/plugins/list/lang/pt.js b/sources/plugins/list/lang/pt.js
new file mode 100644 (file)
index 0000000..52d4348
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'pt', {\r
+       bulletedlist: 'Marcas',\r
+       numberedlist: 'Numeração'\r
+} );\r
diff --git a/sources/plugins/list/lang/ro.js b/sources/plugins/list/lang/ro.js
new file mode 100644 (file)
index 0000000..c229901
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ro', {\r
+       bulletedlist: 'Inserează / Elimină Listă cu puncte',\r
+       numberedlist: 'Inserează / Elimină Listă numerotată'\r
+} );\r
diff --git a/sources/plugins/list/lang/ru.js b/sources/plugins/list/lang/ru.js
new file mode 100644 (file)
index 0000000..862fa78
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ru', {\r
+       bulletedlist: 'Вставить / удалить маркированный список',\r
+       numberedlist: 'Вставить / удалить нумерованный список'\r
+} );\r
diff --git a/sources/plugins/list/lang/si.js b/sources/plugins/list/lang/si.js
new file mode 100644 (file)
index 0000000..de2fc4d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'si', {\r
+       bulletedlist: 'ඇතුලත් / ඉවත් කිරීම ලඉස්තුව',\r
+       numberedlist: 'ඇතුලත් / ඉවත් කිරීම අන්න්කිත ලඉස්තුව'\r
+} );\r
diff --git a/sources/plugins/list/lang/sk.js b/sources/plugins/list/lang/sk.js
new file mode 100644 (file)
index 0000000..11ca0ee
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sk', {\r
+       bulletedlist: 'Vložiť/odstrániť zoznam s odrážkami',\r
+       numberedlist: 'Vložiť/odstrániť číslovaný zoznam'\r
+} );\r
diff --git a/sources/plugins/list/lang/sl.js b/sources/plugins/list/lang/sl.js
new file mode 100644 (file)
index 0000000..368f9f6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sl', {\r
+       bulletedlist: 'Vstavi/odstrani neoštevilčen seznam',\r
+       numberedlist: 'Vstavi/odstrani oštevilčen seznam'\r
+} );\r
diff --git a/sources/plugins/list/lang/sq.js b/sources/plugins/list/lang/sq.js
new file mode 100644 (file)
index 0000000..121b41e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sq', {\r
+       bulletedlist: 'Vendos/Largo Listën me Pika',\r
+       numberedlist: 'Vendos/Largo Listën me Numra'\r
+} );\r
diff --git a/sources/plugins/list/lang/sr-latn.js b/sources/plugins/list/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..134aa69
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sr-latn', {\r
+       bulletedlist: 'Nenabrojiva lista',\r
+       numberedlist: 'Nabrojiva lista'\r
+} );\r
diff --git a/sources/plugins/list/lang/sr.js b/sources/plugins/list/lang/sr.js
new file mode 100644 (file)
index 0000000..c54ca8a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sr', {\r
+       bulletedlist: 'Ненабројива листа',\r
+       numberedlist: 'Набројиву листу'\r
+} );\r
diff --git a/sources/plugins/list/lang/sv.js b/sources/plugins/list/lang/sv.js
new file mode 100644 (file)
index 0000000..3a12793
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'sv', {\r
+       bulletedlist: 'Infoga/ta bort punktlista',\r
+       numberedlist: 'Infoga/ta bort numrerad lista'\r
+} );\r
diff --git a/sources/plugins/list/lang/th.js b/sources/plugins/list/lang/th.js
new file mode 100644 (file)
index 0000000..8a47731
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'th', {\r
+       bulletedlist: 'ลำดับรายการแบบสัญลักษณ์',\r
+       numberedlist: 'ลำดับรายการแบบตัวเลข'\r
+} );\r
diff --git a/sources/plugins/list/lang/tr.js b/sources/plugins/list/lang/tr.js
new file mode 100644 (file)
index 0000000..976e479
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'tr', {\r
+       bulletedlist: 'Simgeli Liste',\r
+       numberedlist: 'Numaralı Liste'\r
+} );\r
diff --git a/sources/plugins/list/lang/tt.js b/sources/plugins/list/lang/tt.js
new file mode 100644 (file)
index 0000000..eb103ab
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'tt', {\r
+       bulletedlist: 'Маркерлы тезмә өстәү/бетерү',\r
+       numberedlist: ' Номерланган тезмә өстәү/бетерү'\r
+} );\r
diff --git a/sources/plugins/list/lang/ug.js b/sources/plugins/list/lang/ug.js
new file mode 100644 (file)
index 0000000..442b92e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'ug', {\r
+       bulletedlist: 'تۈر بەلگە تىزىمى',\r
+       numberedlist: 'تەرتىپ نومۇر تىزىمى'\r
+} );\r
diff --git a/sources/plugins/list/lang/uk.js b/sources/plugins/list/lang/uk.js
new file mode 100644 (file)
index 0000000..65a3e1d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'uk', {\r
+       bulletedlist: 'Маркірований список',\r
+       numberedlist: 'Нумерований список'\r
+} );\r
diff --git a/sources/plugins/list/lang/vi.js b/sources/plugins/list/lang/vi.js
new file mode 100644 (file)
index 0000000..e9e3acc
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'vi', {\r
+       bulletedlist: 'Chèn/Xoá Danh sách không thứ tự',\r
+       numberedlist: 'Chèn/Xoá Danh sách có thứ tự'\r
+} );\r
diff --git a/sources/plugins/list/lang/zh-cn.js b/sources/plugins/list/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..5e0408b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'zh-cn', {\r
+       bulletedlist: '项目列表',\r
+       numberedlist: '编号列表'\r
+} );\r
diff --git a/sources/plugins/list/lang/zh.js b/sources/plugins/list/lang/zh.js
new file mode 100644 (file)
index 0000000..3d207d6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'list', 'zh', {\r
+       bulletedlist: '插入/移除項目符號清單',\r
+       numberedlist: '插入/移除編號清單清單'\r
+} );\r
diff --git a/sources/plugins/list/plugin.js b/sources/plugins/list/plugin.js
new file mode 100644 (file)
index 0000000..7280cc2
--- /dev/null
@@ -0,0 +1,1111 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview Insert and remove numbered and bulleted lists.\r
+ */\r
+\r
+( function() {\r
+       var listNodeNames = { ol: 1, ul: 1 };\r
+\r
+       var whitespaces = CKEDITOR.dom.walker.whitespaces(),\r
+               bookmarks = CKEDITOR.dom.walker.bookmark(),\r
+               nonEmpty = function( node ) {\r
+                       return !( whitespaces( node ) || bookmarks( node ) );\r
+               },\r
+               blockBogus = CKEDITOR.dom.walker.bogus();\r
+\r
+       function cleanUpDirection( element ) {\r
+               var dir, parent, parentDir;\r
+               if ( ( dir = element.getDirection() ) ) {\r
+                       parent = element.getParent();\r
+                       while ( parent && !( parentDir = parent.getDirection() ) )\r
+                               parent = parent.getParent();\r
+\r
+                       if ( dir == parentDir )\r
+                               element.removeAttribute( 'dir' );\r
+               }\r
+       }\r
+\r
+       // Inherit inline styles from another element.\r
+       function inheritInlineStyles( parent, el ) {\r
+               var style = parent.getAttribute( 'style' );\r
+\r
+               // Put parent styles before child styles.\r
+               style && el.setAttribute( 'style', style.replace( /([^;])$/, '$1;' ) + ( el.getAttribute( 'style' ) || '' ) );\r
+       }\r
+\r
+       CKEDITOR.plugins.list = {\r
+               /**\r
+                * Convert a DOM list tree into a data structure that is easier to\r
+                * manipulate. This operation should be non-intrusive in the sense that it\r
+                * does not change the DOM tree, with the exception that it may add some\r
+                * markers to the list item nodes when database is specified.\r
+                *\r
+                * @member CKEDITOR.plugins.list\r
+                * @todo params\r
+                */\r
+               listToArray: function( listNode, database, baseArray, baseIndentLevel, grandparentNode ) {\r
+                       if ( !listNodeNames[ listNode.getName() ] )\r
+                               return [];\r
+\r
+                       if ( !baseIndentLevel )\r
+                               baseIndentLevel = 0;\r
+                       if ( !baseArray )\r
+                               baseArray = [];\r
+\r
+                       // Iterate over all list items to and look for inner lists.\r
+                       for ( var i = 0, count = listNode.getChildCount(); i < count; i++ ) {\r
+                               var listItem = listNode.getChild( i );\r
+\r
+                               // Fixing malformed nested lists by moving it into a previous list item. (#6236)\r
+                               if ( listItem.type == CKEDITOR.NODE_ELEMENT && listItem.getName() in CKEDITOR.dtd.$list )\r
+                                       CKEDITOR.plugins.list.listToArray( listItem, database, baseArray, baseIndentLevel + 1 );\r
+\r
+                               // It may be a text node or some funny stuff.\r
+                               if ( listItem.$.nodeName.toLowerCase() != 'li' )\r
+                                       continue;\r
+\r
+                               var itemObj = { 'parent': listNode, indent: baseIndentLevel, element: listItem, contents: [] };\r
+                               if ( !grandparentNode ) {\r
+                                       itemObj.grandparent = listNode.getParent();\r
+                                       if ( itemObj.grandparent && itemObj.grandparent.$.nodeName.toLowerCase() == 'li' )\r
+                                               itemObj.grandparent = itemObj.grandparent.getParent();\r
+                               } else {\r
+                                       itemObj.grandparent = grandparentNode;\r
+                               }\r
+\r
+                               if ( database )\r
+                                       CKEDITOR.dom.element.setMarker( database, listItem, 'listarray_index', baseArray.length );\r
+                               baseArray.push( itemObj );\r
+\r
+                               for ( var j = 0, itemChildCount = listItem.getChildCount(), child; j < itemChildCount; j++ ) {\r
+                                       child = listItem.getChild( j );\r
+                                       if ( child.type == CKEDITOR.NODE_ELEMENT && listNodeNames[ child.getName() ] )\r
+                                       // Note the recursion here, it pushes inner list items with\r
+                                       // +1 indentation in the correct order.\r
+                                       CKEDITOR.plugins.list.listToArray( child, database, baseArray, baseIndentLevel + 1, itemObj.grandparent );\r
+                                       else\r
+                                               itemObj.contents.push( child );\r
+                               }\r
+                       }\r
+                       return baseArray;\r
+               },\r
+\r
+               /**\r
+                * Convert our internal representation of a list back to a DOM forest.\r
+                *\r
+                * @member CKEDITOR.plugins.list\r
+                * @todo params\r
+                */\r
+               arrayToList: function( listArray, database, baseIndex, paragraphMode, dir ) {\r
+                       if ( !baseIndex )\r
+                               baseIndex = 0;\r
+                       if ( !listArray || listArray.length < baseIndex + 1 )\r
+                               return null;\r
+\r
+                       var i,\r
+                               doc = listArray[ baseIndex ].parent.getDocument(),\r
+                               retval = new CKEDITOR.dom.documentFragment( doc ),\r
+                               rootNode = null,\r
+                               currentIndex = baseIndex,\r
+                               indentLevel = Math.max( listArray[ baseIndex ].indent, 0 ),\r
+                               currentListItem = null,\r
+                               orgDir, block,\r
+                               paragraphName = ( paragraphMode == CKEDITOR.ENTER_P ? 'p' : 'div' );\r
+\r
+                       while ( 1 ) {\r
+                               var item = listArray[ currentIndex ],\r
+                                       itemGrandParent = item.grandparent;\r
+\r
+                               orgDir = item.element.getDirection( 1 );\r
+\r
+                               if ( item.indent == indentLevel ) {\r
+                                       if ( !rootNode || listArray[ currentIndex ].parent.getName() != rootNode.getName() ) {\r
+                                               rootNode = listArray[ currentIndex ].parent.clone( false, 1 );\r
+                                               dir && rootNode.setAttribute( 'dir', dir );\r
+                                               retval.append( rootNode );\r
+                                       }\r
+                                       currentListItem = rootNode.append( item.element.clone( 0, 1 ) );\r
+\r
+                                       if ( orgDir != rootNode.getDirection( 1 ) )\r
+                                               currentListItem.setAttribute( 'dir', orgDir );\r
+\r
+                                       for ( i = 0; i < item.contents.length; i++ )\r
+                                               currentListItem.append( item.contents[ i ].clone( 1, 1 ) );\r
+                                       currentIndex++;\r
+                               } else if ( item.indent == Math.max( indentLevel, 0 ) + 1 ) {\r
+                                       // Maintain original direction (#6861).\r
+                                       var currDir = listArray[ currentIndex - 1 ].element.getDirection( 1 ),\r
+                                               listData = CKEDITOR.plugins.list.arrayToList( listArray, null, currentIndex, paragraphMode, currDir != orgDir ? orgDir : null );\r
+\r
+                                       // If the next block is an <li> with another list tree as the first\r
+                                       // child, we'll need to append a filler (<br>/NBSP) or the list item\r
+                                       // wouldn't be editable. (#6724)\r
+                                       if ( !currentListItem.getChildCount() && CKEDITOR.env.needsNbspFiller && doc.$.documentMode <= 7 )\r
+                                               currentListItem.append( doc.createText( '\xa0' ) );\r
+                                       currentListItem.append( listData.listNode );\r
+                                       currentIndex = listData.nextIndex;\r
+                               } else if ( item.indent == -1 && !baseIndex && itemGrandParent ) {\r
+                                       if ( listNodeNames[ itemGrandParent.getName() ] ) {\r
+                                               currentListItem = item.element.clone( false, true );\r
+                                               if ( orgDir != itemGrandParent.getDirection( 1 ) )\r
+                                                       currentListItem.setAttribute( 'dir', orgDir );\r
+                                       } else {\r
+                                               currentListItem = new CKEDITOR.dom.documentFragment( doc );\r
+                                       }\r
+\r
+                                       // Migrate all children to the new container,\r
+                                       // apply the proper text direction.\r
+                                       var dirLoose = itemGrandParent.getDirection( 1 ) != orgDir,\r
+                                               li = item.element,\r
+                                               className = li.getAttribute( 'class' ),\r
+                                               style = li.getAttribute( 'style' );\r
+\r
+                                       var needsBlock = currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && ( paragraphMode != CKEDITOR.ENTER_BR || dirLoose || style || className );\r
+\r
+                                       var child,\r
+                                               count = item.contents.length,\r
+                                               cachedBookmark;\r
+\r
+                                       for ( i = 0; i < count; i++ ) {\r
+                                               child = item.contents[ i ];\r
+\r
+                                               // Append bookmark if we can, or cache it and append it when we'll know\r
+                                               // what to do with it. Generally - we want to keep it next to its original neighbour.\r
+                                               // Exception: if bookmark is the only child it hasn't got any neighbour, so handle it normally\r
+                                               // (wrap with block if needed).\r
+                                               if ( bookmarks( child ) && count > 1 ) {\r
+                                                       // If we don't need block, it's simple - append bookmark directly to the current list item.\r
+                                                       if ( !needsBlock )\r
+                                                               currentListItem.append( child.clone( 1, 1 ) );\r
+                                                       else\r
+                                                               cachedBookmark = child.clone( 1, 1 );\r
+                                               }\r
+                                               // Block content goes directly to the current list item, without wrapping.\r
+                                               else if ( child.type == CKEDITOR.NODE_ELEMENT && child.isBlockBoundary() ) {\r
+                                                       // Apply direction on content blocks.\r
+                                                       if ( dirLoose && !child.getDirection() )\r
+                                                               child.setAttribute( 'dir', orgDir );\r
+\r
+                                                       inheritInlineStyles( li, child );\r
+\r
+                                                       className && child.addClass( className );\r
+\r
+                                                       // Close the block which we started for inline content.\r
+                                                       block = null;\r
+                                                       // Append bookmark directly before current child.\r
+                                                       if ( cachedBookmark ) {\r
+                                                               currentListItem.append( cachedBookmark );\r
+                                                               cachedBookmark = null;\r
+                                                       }\r
+                                                       // Append this block element to the list item.\r
+                                                       currentListItem.append( child.clone( 1, 1 ) );\r
+                                               }\r
+                                               // Some inline content was found - wrap it with block and append that\r
+                                               // block to the current list item or append it to the block previously created.\r
+                                               else if ( needsBlock ) {\r
+                                                       // Establish new block to hold text direction and styles.\r
+                                                       if ( !block ) {\r
+                                                               block = doc.createElement( paragraphName );\r
+                                                               currentListItem.append( block );\r
+                                                               dirLoose && block.setAttribute( 'dir', orgDir );\r
+                                                       }\r
+\r
+                                                       // Copy over styles to new block;\r
+                                                       style && block.setAttribute( 'style', style );\r
+                                                       className && block.setAttribute( 'class', className );\r
+\r
+                                                       // Append bookmark directly before current child.\r
+                                                       if ( cachedBookmark ) {\r
+                                                               block.append( cachedBookmark );\r
+                                                               cachedBookmark = null;\r
+                                                       }\r
+                                                       block.append( child.clone( 1, 1 ) );\r
+                                               }\r
+                                               // E.g. BR mode - inline content appended directly to the list item.\r
+                                               else {\r
+                                                       currentListItem.append( child.clone( 1, 1 ) );\r
+                                               }\r
+                                       }\r
+\r
+                                       // No content after bookmark - append it to the block if we had one\r
+                                       // or directly to the current list item if we finished directly in the current list item.\r
+                                       if ( cachedBookmark ) {\r
+                                               ( block || currentListItem ).append( cachedBookmark );\r
+                                               cachedBookmark = null;\r
+                                       }\r
+\r
+                                       if ( currentListItem.type == CKEDITOR.NODE_DOCUMENT_FRAGMENT && currentIndex != listArray.length - 1 ) {\r
+                                               var last;\r
+\r
+                                               // Remove bogus <br> if this browser uses them.\r
+                                               if ( CKEDITOR.env.needsBrFiller ) {\r
+                                                       last = currentListItem.getLast();\r
+                                                       if ( last && last.type == CKEDITOR.NODE_ELEMENT && last.is( 'br' ) )\r
+                                                               last.remove();\r
+                                               }\r
+\r
+                                               // If the last element is not a block, append <br> to separate merged list items.\r
+                                               last = currentListItem.getLast( nonEmpty );\r
+                                               if ( !( last && last.type == CKEDITOR.NODE_ELEMENT && last.is( CKEDITOR.dtd.$block ) ) )\r
+                                                       currentListItem.append( doc.createElement( 'br' ) );\r
+                                       }\r
+\r
+                                       var currentListItemName = currentListItem.$.nodeName.toLowerCase();\r
+                                       if ( currentListItemName == 'div' || currentListItemName == 'p' ) {\r
+                                               currentListItem.appendBogus();\r
+                                       }\r
+                                       retval.append( currentListItem );\r
+                                       rootNode = null;\r
+                                       currentIndex++;\r
+                               } else {\r
+                                       return null;\r
+                               }\r
+\r
+                               block = null;\r
+\r
+                               if ( listArray.length <= currentIndex || Math.max( listArray[ currentIndex ].indent, 0 ) < indentLevel )\r
+                                       break;\r
+                       }\r
+\r
+                       if ( database ) {\r
+                               var currentNode = retval.getFirst();\r
+\r
+                               while ( currentNode ) {\r
+                                       if ( currentNode.type == CKEDITOR.NODE_ELEMENT ) {\r
+                                               // Clear marker attributes for the new list tree made of cloned nodes, if any.\r
+                                               CKEDITOR.dom.element.clearMarkers( database, currentNode );\r
+\r
+                                               // Clear redundant direction attribute specified on list items.\r
+                                               if ( currentNode.getName() in CKEDITOR.dtd.$listItem )\r
+                                                       cleanUpDirection( currentNode );\r
+                                       }\r
+\r
+                                       currentNode = currentNode.getNextSourceNode();\r
+                               }\r
+                       }\r
+\r
+                       return { listNode: retval, nextIndex: currentIndex };\r
+               }\r
+       };\r
+\r
+       function changeListType( editor, groupObj, database, listsCreated ) {\r
+               // This case is easy...\r
+               // 1. Convert the whole list into a one-dimensional array.\r
+               // 2. Change the list type by modifying the array.\r
+               // 3. Recreate the whole list by converting the array to a list.\r
+               // 4. Replace the original list with the recreated list.\r
+               var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),\r
+                       selectedListItems = [];\r
+\r
+               for ( var i = 0; i < groupObj.contents.length; i++ ) {\r
+                       var itemNode = groupObj.contents[ i ];\r
+                       itemNode = itemNode.getAscendant( 'li', true );\r
+                       if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )\r
+                               continue;\r
+                       selectedListItems.push( itemNode );\r
+                       CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );\r
+               }\r
+\r
+               var root = groupObj.root,\r
+                       doc = root.getDocument(),\r
+                       listNode, newListNode;\r
+\r
+               for ( i = 0; i < selectedListItems.length; i++ ) {\r
+                       var listIndex = selectedListItems[ i ].getCustomData( 'listarray_index' );\r
+                       listNode = listArray[ listIndex ].parent;\r
+\r
+                       // Switch to new list node for this particular item.\r
+                       if ( !listNode.is( this.type ) ) {\r
+                               newListNode = doc.createElement( this.type );\r
+                               // Copy all attributes, except from 'start' and 'type'.\r
+                               listNode.copyAttributes( newListNode, { start: 1, type: 1 } );\r
+                               // The list-style-type property should be ignored.\r
+                               newListNode.removeStyle( 'list-style-type' );\r
+                               listArray[ listIndex ].parent = newListNode;\r
+                       }\r
+               }\r
+\r
+               var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode );\r
+               var child,\r
+                       length = newList.listNode.getChildCount();\r
+               for ( i = 0; i < length && ( child = newList.listNode.getChild( i ) ); i++ ) {\r
+                       if ( child.getName() == this.type )\r
+                               listsCreated.push( child );\r
+               }\r
+               newList.listNode.replace( groupObj.root );\r
+\r
+               editor.fire( 'contentDomInvalidated' );\r
+       }\r
+\r
+       function createList( editor, groupObj, listsCreated ) {\r
+               var contents = groupObj.contents,\r
+                       doc = groupObj.root.getDocument(),\r
+                       listContents = [];\r
+\r
+               // It is possible to have the contents returned by DomRangeIterator to be the same as the root.\r
+               // e.g. when we're running into table cells.\r
+               // In such a case, enclose the childNodes of contents[0] into a <div>.\r
+               if ( contents.length == 1 && contents[ 0 ].equals( groupObj.root ) ) {\r
+                       var divBlock = doc.createElement( 'div' );\r
+                       contents[ 0 ].moveChildren && contents[ 0 ].moveChildren( divBlock );\r
+                       contents[ 0 ].append( divBlock );\r
+                       contents[ 0 ] = divBlock;\r
+               }\r
+\r
+               // Calculate the common parent node of all content blocks.\r
+               var commonParent = groupObj.contents[ 0 ].getParent();\r
+               for ( var i = 0; i < contents.length; i++ )\r
+                       commonParent = commonParent.getCommonAncestor( contents[ i ].getParent() );\r
+\r
+               var useComputedState = editor.config.useComputedState,\r
+                       listDir, explicitDirection;\r
+\r
+               useComputedState = useComputedState === undefined || useComputedState;\r
+\r
+               // We want to insert things that are in the same tree level only, so calculate the contents again\r
+               // by expanding the selected blocks to the same tree level.\r
+               for ( i = 0; i < contents.length; i++ ) {\r
+                       var contentNode = contents[ i ],\r
+                               parentNode;\r
+                       while ( ( parentNode = contentNode.getParent() ) ) {\r
+                               if ( parentNode.equals( commonParent ) ) {\r
+                                       listContents.push( contentNode );\r
+\r
+                                       // Determine the lists's direction.\r
+                                       if ( !explicitDirection && contentNode.getDirection() )\r
+                                               explicitDirection = 1;\r
+\r
+                                       var itemDir = contentNode.getDirection( useComputedState );\r
+\r
+                                       if ( listDir !== null ) {\r
+                                               // If at least one LI have a different direction than current listDir, we can't have listDir.\r
+                                               if ( listDir && listDir != itemDir )\r
+                                                       listDir = null;\r
+                                               else\r
+                                                       listDir = itemDir;\r
+                                       }\r
+\r
+                                       break;\r
+                               }\r
+                               contentNode = parentNode;\r
+                       }\r
+               }\r
+\r
+               if ( listContents.length < 1 )\r
+                       return;\r
+\r
+               // Insert the list to the DOM tree.\r
+               var insertAnchor = listContents[ listContents.length - 1 ].getNext(),\r
+                       listNode = doc.createElement( this.type );\r
+\r
+               listsCreated.push( listNode );\r
+\r
+               var contentBlock, listItem;\r
+\r
+               while ( listContents.length ) {\r
+                       contentBlock = listContents.shift();\r
+                       listItem = doc.createElement( 'li' );\r
+\r
+                       // If current block should be preserved, append it to list item instead of\r
+                       // transforming it to <li> element.\r
+                       if ( shouldPreserveBlock( contentBlock ) )\r
+                               contentBlock.appendTo( listItem );\r
+                       else {\r
+                               contentBlock.copyAttributes( listItem );\r
+                               // Remove direction attribute after it was merged into list root. (#7657)\r
+                               if ( listDir && contentBlock.getDirection() ) {\r
+                                       listItem.removeStyle( 'direction' );\r
+                                       listItem.removeAttribute( 'dir' );\r
+                               }\r
+                               contentBlock.moveChildren( listItem );\r
+                               contentBlock.remove();\r
+                       }\r
+\r
+                       listItem.appendTo( listNode );\r
+               }\r
+\r
+               // Apply list root dir only if it has been explicitly declared.\r
+               if ( listDir && explicitDirection )\r
+                       listNode.setAttribute( 'dir', listDir );\r
+\r
+               if ( insertAnchor )\r
+                       listNode.insertBefore( insertAnchor );\r
+               else\r
+                       listNode.appendTo( commonParent );\r
+       }\r
+\r
+       function removeList( editor, groupObj, database ) {\r
+               // This is very much like the change list type operation.\r
+               // Except that we're changing the selected items' indent to -1 in the list array.\r
+               var listArray = CKEDITOR.plugins.list.listToArray( groupObj.root, database ),\r
+                       selectedListItems = [];\r
+\r
+               for ( var i = 0; i < groupObj.contents.length; i++ ) {\r
+                       var itemNode = groupObj.contents[ i ];\r
+                       itemNode = itemNode.getAscendant( 'li', true );\r
+                       if ( !itemNode || itemNode.getCustomData( 'list_item_processed' ) )\r
+                               continue;\r
+                       selectedListItems.push( itemNode );\r
+                       CKEDITOR.dom.element.setMarker( database, itemNode, 'list_item_processed', true );\r
+               }\r
+\r
+               var lastListIndex = null;\r
+               for ( i = 0; i < selectedListItems.length; i++ ) {\r
+                       var listIndex = selectedListItems[ i ].getCustomData( 'listarray_index' );\r
+                       listArray[ listIndex ].indent = -1;\r
+                       lastListIndex = listIndex;\r
+               }\r
+\r
+               // After cutting parts of the list out with indent=-1, we still have to maintain the array list\r
+               // model's nextItem.indent <= currentItem.indent + 1 invariant. Otherwise the array model of the\r
+               // list cannot be converted back to a real DOM list.\r
+               for ( i = lastListIndex + 1; i < listArray.length; i++ ) {\r
+                       if ( listArray[ i ].indent > listArray[ i - 1 ].indent + 1 ) {\r
+                               var indentOffset = listArray[ i - 1 ].indent + 1 - listArray[ i ].indent;\r
+                               var oldIndent = listArray[ i ].indent;\r
+                               while ( listArray[ i ] && listArray[ i ].indent >= oldIndent ) {\r
+                                       listArray[ i ].indent += indentOffset;\r
+                                       i++;\r
+                               }\r
+                               i--;\r
+                       }\r
+               }\r
+\r
+               var newList = CKEDITOR.plugins.list.arrayToList( listArray, database, null, editor.config.enterMode, groupObj.root.getAttribute( 'dir' ) );\r
+\r
+               // Compensate <br> before/after the list node if the surrounds are non-blocks.(#3836)\r
+               var docFragment = newList.listNode,\r
+                       boundaryNode, siblingNode;\r
+\r
+               function compensateBrs( isStart ) {\r
+                       if (\r
+                               ( boundaryNode = docFragment[ isStart ? 'getFirst' : 'getLast' ]() ) &&\r
+                               !( boundaryNode.is && boundaryNode.isBlockBoundary() ) &&\r
+                               ( siblingNode = groupObj.root[ isStart ? 'getPrevious' : 'getNext' ]( CKEDITOR.dom.walker.invisible( true ) ) ) &&\r
+                               !( siblingNode.is && siblingNode.isBlockBoundary( { br: 1 } ) )\r
+                       ) {\r
+                               editor.document.createElement( 'br' )[ isStart ? 'insertBefore' : 'insertAfter' ]( boundaryNode );\r
+                       }\r
+               }\r
+               compensateBrs( true );\r
+               compensateBrs();\r
+\r
+               docFragment.replace( groupObj.root );\r
+\r
+               editor.fire( 'contentDomInvalidated' );\r
+       }\r
+\r
+       var headerTagRegex = /^h[1-6]$/;\r
+\r
+       // Checks wheather this block should be element preserved (not transformed to <li>) when creating list.\r
+       function shouldPreserveBlock( block ) {\r
+               return (\r
+                       // #5335\r
+                       block.is( 'pre' ) ||\r
+                       // #5271 - this is a header.\r
+                       headerTagRegex.test( block.getName() ) ||\r
+                       // 11083 - this is a non-editable element.\r
+                       block.getAttribute( 'contenteditable' ) == 'false'\r
+               );\r
+       }\r
+\r
+       function listCommand( name, type ) {\r
+               this.name = name;\r
+               this.type = type;\r
+               this.context = type;\r
+               this.allowedContent = type + ' li';\r
+               this.requiredContent = type;\r
+       }\r
+\r
+       var elementType = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_ELEMENT );\r
+\r
+       // Merge child nodes with direction preserved. (#7448)\r
+       function mergeChildren( from, into, refNode, forward ) {\r
+               var child, itemDir;\r
+               while ( ( child = from[ forward ? 'getLast' : 'getFirst' ]( elementType ) ) ) {\r
+                       if ( ( itemDir = child.getDirection( 1 ) ) !== into.getDirection( 1 ) )\r
+                               child.setAttribute( 'dir', itemDir );\r
+\r
+                       child.remove();\r
+\r
+                       refNode ? child[ forward ? 'insertBefore' : 'insertAfter' ]( refNode ) : into.append( child, forward );\r
+               }\r
+       }\r
+\r
+       listCommand.prototype = {\r
+               exec: function( editor ) {\r
+                       // Run state check first of all.\r
+                       this.refresh( editor, editor.elementPath() );\r
+\r
+                       var config = editor.config,\r
+                               selection = editor.getSelection(),\r
+                               ranges = selection && selection.getRanges();\r
+\r
+                       // Midas lists rule #1 says we can create a list even in an empty document.\r
+                       // But DOM iterator wouldn't run if the document is really empty.\r
+                       // So create a paragraph if the document is empty and we're going to create a list.\r
+                       if ( this.state == CKEDITOR.TRISTATE_OFF ) {\r
+                               var editable = editor.editable();\r
+                               if ( !editable.getFirst( nonEmpty ) ) {\r
+                                       config.enterMode == CKEDITOR.ENTER_BR ? editable.appendBogus() : ranges[ 0 ].fixBlock( 1, config.enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' );\r
+\r
+                                       selection.selectRanges( ranges );\r
+                               }\r
+                               // Maybe a single range there enclosing the whole list,\r
+                               // turn on the list state manually(#4129).\r
+                               else {\r
+                                       var range = ranges.length == 1 && ranges[ 0 ],\r
+                                               enclosedNode = range && range.getEnclosedNode();\r
+                                       if ( enclosedNode && enclosedNode.is && this.type == enclosedNode.getName() )\r
+                                               this.setState( CKEDITOR.TRISTATE_ON );\r
+                               }\r
+                       }\r
+\r
+                       var bookmarks = selection.createBookmarks( true );\r
+\r
+                       // Group the blocks up because there are many cases where multiple lists have to be created,\r
+                       // or multiple lists have to be cancelled.\r
+                       var listGroups = [],\r
+                               database = {},\r
+                               rangeIterator = ranges.createIterator(),\r
+                               index = 0;\r
+\r
+                       while ( ( range = rangeIterator.getNextRange() ) && ++index ) {\r
+                               var boundaryNodes = range.getBoundaryNodes(),\r
+                                       startNode = boundaryNodes.startNode,\r
+                                       endNode = boundaryNodes.endNode;\r
+\r
+                               if ( startNode.type == CKEDITOR.NODE_ELEMENT && startNode.getName() == 'td' )\r
+                                       range.setStartAt( boundaryNodes.startNode, CKEDITOR.POSITION_AFTER_START );\r
+\r
+                               if ( endNode.type == CKEDITOR.NODE_ELEMENT && endNode.getName() == 'td' )\r
+                                       range.setEndAt( boundaryNodes.endNode, CKEDITOR.POSITION_BEFORE_END );\r
+\r
+                               var iterator = range.createIterator(),\r
+                                       block;\r
+\r
+                               iterator.forceBrBreak = ( this.state == CKEDITOR.TRISTATE_OFF );\r
+\r
+                               while ( ( block = iterator.getNextParagraph() ) ) {\r
+                                       // Avoid duplicate blocks get processed across ranges.\r
+                                       if ( block.getCustomData( 'list_block' ) )\r
+                                               continue;\r
+                                       else\r
+                                               CKEDITOR.dom.element.setMarker( database, block, 'list_block', 1 );\r
+\r
+                                       var path = editor.elementPath( block ),\r
+                                               pathElements = path.elements,\r
+                                               pathElementsCount = pathElements.length,\r
+                                               processedFlag = 0,\r
+                                               blockLimit = path.blockLimit,\r
+                                               element;\r
+\r
+                                       // First, try to group by a list ancestor.\r
+                                       for ( var i = pathElementsCount - 1; i >= 0 && ( element = pathElements[ i ] ); i-- ) {\r
+                                               // Don't leak outside block limit (#3940).\r
+                                               if ( listNodeNames[ element.getName() ] && blockLimit.contains( element ) ) {\r
+                                                       // If we've encountered a list inside a block limit\r
+                                                       // The last group object of the block limit element should\r
+                                                       // no longer be valid. Since paragraphs after the list\r
+                                                       // should belong to a different group of paragraphs before\r
+                                                       // the list. (Bug #1309)\r
+                                                       blockLimit.removeCustomData( 'list_group_object_' + index );\r
+\r
+                                                       var groupObj = element.getCustomData( 'list_group_object' );\r
+                                                       if ( groupObj )\r
+                                                               groupObj.contents.push( block );\r
+                                                       else {\r
+                                                               groupObj = { root: element, contents: [ block ] };\r
+                                                               listGroups.push( groupObj );\r
+                                                               CKEDITOR.dom.element.setMarker( database, element, 'list_group_object', groupObj );\r
+                                                       }\r
+                                                       processedFlag = 1;\r
+                                                       break;\r
+                                               }\r
+                                       }\r
+\r
+                                       if ( processedFlag )\r
+                                               continue;\r
+\r
+                                       // No list ancestor? Group by block limit, but don't mix contents from different ranges.\r
+                                       var root = blockLimit;\r
+                                       if ( root.getCustomData( 'list_group_object_' + index ) )\r
+                                               root.getCustomData( 'list_group_object_' + index ).contents.push( block );\r
+                                       else {\r
+                                               groupObj = { root: root, contents: [ block ] };\r
+                                               CKEDITOR.dom.element.setMarker( database, root, 'list_group_object_' + index, groupObj );\r
+                                               listGroups.push( groupObj );\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       // Now we have two kinds of list groups, groups rooted at a list, and groups rooted at a block limit element.\r
+                       // We either have to build lists or remove lists, for removing a list does not makes sense when we are looking\r
+                       // at the group that's not rooted at lists. So we have three cases to handle.\r
+                       var listsCreated = [];\r
+                       while ( listGroups.length > 0 ) {\r
+                               groupObj = listGroups.shift();\r
+                               if ( this.state == CKEDITOR.TRISTATE_OFF ) {\r
+                                       if ( listNodeNames[ groupObj.root.getName() ] )\r
+                                               changeListType.call( this, editor, groupObj, database, listsCreated );\r
+                                       else\r
+                                               createList.call( this, editor, groupObj, listsCreated );\r
+                               } else if ( this.state == CKEDITOR.TRISTATE_ON && listNodeNames[ groupObj.root.getName() ] ) {\r
+                                       removeList.call( this, editor, groupObj, database );\r
+                               }\r
+                       }\r
+\r
+                       // For all new lists created, merge into adjacent, same type lists.\r
+                       for ( i = 0; i < listsCreated.length; i++ )\r
+                               mergeListSiblings( listsCreated[ i ] );\r
+\r
+                       // Clean up, restore selection and update toolbar button states.\r
+                       CKEDITOR.dom.element.clearAllMarkers( database );\r
+                       selection.selectBookmarks( bookmarks );\r
+                       editor.focus();\r
+               },\r
+\r
+               refresh: function( editor, path ) {\r
+                       var list = path.contains( listNodeNames, 1 ),\r
+                               limit = path.blockLimit || path.root;\r
+\r
+                       // 1. Only a single type of list activate.\r
+                       // 2. Do not show list outside of block limit.\r
+                       if ( list && limit.contains( list ) )\r
+                               this.setState( list.is( this.type ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
+                       else\r
+                               this.setState( CKEDITOR.TRISTATE_OFF );\r
+               }\r
+       };\r
+\r
+       // Merge list adjacent, of same type lists.\r
+       function mergeListSiblings( listNode ) {\r
+\r
+               function mergeSibling( rtl ) {\r
+                       var sibling = listNode[ rtl ? 'getPrevious' : 'getNext' ]( nonEmpty );\r
+                       if ( sibling && sibling.type == CKEDITOR.NODE_ELEMENT && sibling.is( listNode.getName() ) ) {\r
+                               // Move children order by merge direction.(#3820)\r
+                               mergeChildren( listNode, sibling, null, !rtl );\r
+\r
+                               listNode.remove();\r
+                               listNode = sibling;\r
+                       }\r
+               }\r
+\r
+               mergeSibling();\r
+               mergeSibling( 1 );\r
+       }\r
+\r
+       // Check if node is block element that recieves text.\r
+       function isTextBlock( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && ( node.getName() in CKEDITOR.dtd.$block || node.getName() in CKEDITOR.dtd.$listItem ) && CKEDITOR.dtd[ node.getName() ][ '#' ];\r
+       }\r
+\r
+       // Join visually two block lines.\r
+       function joinNextLineToCursor( editor, cursor, nextCursor ) {\r
+               editor.fire( 'saveSnapshot' );\r
+\r
+               // Merge with previous block's content.\r
+               nextCursor.enlarge( CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS );\r
+               var frag = nextCursor.extractContents();\r
+\r
+               cursor.trim( false, true );\r
+               var bm = cursor.createBookmark();\r
+\r
+               // Kill original bogus;\r
+               var currentPath = new CKEDITOR.dom.elementPath( cursor.startContainer ),\r
+                               pathBlock = currentPath.block,\r
+                               currentBlock = currentPath.lastElement.getAscendant( 'li', 1 ) || pathBlock,\r
+                               nextPath = new CKEDITOR.dom.elementPath( nextCursor.startContainer ),\r
+                               nextLi = nextPath.contains( CKEDITOR.dtd.$listItem ),\r
+                               nextList = nextPath.contains( CKEDITOR.dtd.$list ),\r
+                               last;\r
+\r
+               // Remove bogus node the current block/pseudo block.\r
+               if ( pathBlock ) {\r
+                       var bogus = pathBlock.getBogus();\r
+                       bogus && bogus.remove();\r
+               }\r
+               else if ( nextList ) {\r
+                       last = nextList.getPrevious( nonEmpty );\r
+                       if ( last && blockBogus( last ) )\r
+                               last.remove();\r
+               }\r
+\r
+               // Kill the tail br in extracted.\r
+               last = frag.getLast();\r
+               if ( last && last.type == CKEDITOR.NODE_ELEMENT && last.is( 'br' ) )\r
+                       last.remove();\r
+\r
+               // Insert fragment at the range position.\r
+               var nextNode = cursor.startContainer.getChild( cursor.startOffset );\r
+               if ( nextNode )\r
+                       frag.insertBefore( nextNode );\r
+               else\r
+                       cursor.startContainer.append( frag );\r
+\r
+               // Move the sub list nested in the next list item.\r
+               if ( nextLi ) {\r
+                       var sublist = getSubList( nextLi );\r
+                       if ( sublist ) {\r
+                               // If next line is in the sub list of the current list item.\r
+                               if ( currentBlock.contains( nextLi ) ) {\r
+                                       mergeChildren( sublist, nextLi.getParent(), nextLi );\r
+                                       sublist.remove();\r
+                               }\r
+                               // Migrate the sub list to current list item.\r
+                               else {\r
+                                       currentBlock.append( sublist );\r
+                               }\r
+                       }\r
+               }\r
+\r
+               var nextBlock, parent;\r
+               // Remove any remaining zombies path blocks at the end after line merged.\r
+               while ( nextCursor.checkStartOfBlock() && nextCursor.checkEndOfBlock() ) {\r
+                       nextPath = nextCursor.startPath();\r
+                       nextBlock = nextPath.block;\r
+\r
+                       // Abort when nothing to be removed (#10890).\r
+                       if ( !nextBlock )\r
+                               break;\r
+\r
+                       // Check if also to remove empty list.\r
+                       if ( nextBlock.is( 'li' ) ) {\r
+                               parent = nextBlock.getParent();\r
+                               if ( nextBlock.equals( parent.getLast( nonEmpty ) ) && nextBlock.equals( parent.getFirst( nonEmpty ) ) )\r
+                                       nextBlock = parent;\r
+                       }\r
+\r
+                       nextCursor.moveToPosition( nextBlock, CKEDITOR.POSITION_BEFORE_START );\r
+                       nextBlock.remove();\r
+               }\r
+\r
+               // Check if need to further merge with the list resides after the merged block. (#9080)\r
+               var walkerRng = nextCursor.clone(), editable = editor.editable();\r
+               walkerRng.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END );\r
+               var walker = new CKEDITOR.dom.walker( walkerRng );\r
+               walker.evaluator = function( node ) {\r
+                       return nonEmpty( node ) && !blockBogus( node );\r
+               };\r
+               var next = walker.next();\r
+               if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.getName() in CKEDITOR.dtd.$list )\r
+                       mergeListSiblings( next );\r
+\r
+               cursor.moveToBookmark( bm );\r
+\r
+               // Make fresh selection.\r
+               cursor.select();\r
+\r
+               editor.fire( 'saveSnapshot' );\r
+       }\r
+\r
+       function getSubList( li ) {\r
+               var last = li.getLast( nonEmpty );\r
+               return last && last.type == CKEDITOR.NODE_ELEMENT && last.getName() in listNodeNames ? last : null;\r
+       }\r
+\r
+       CKEDITOR.plugins.add( 'list', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'bulletedlist,bulletedlist-rtl,numberedlist,numberedlist-rtl', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               requires: 'indentlist',\r
+               init: function( editor ) {\r
+                       if ( editor.blockless )\r
+                               return;\r
+\r
+                       // Register commands.\r
+                       editor.addCommand( 'numberedlist', new listCommand( 'numberedlist', 'ol' ) );\r
+                       editor.addCommand( 'bulletedlist', new listCommand( 'bulletedlist', 'ul' ) );\r
+\r
+                       // Register the toolbar button.\r
+                       if ( editor.ui.addButton ) {\r
+                               editor.ui.addButton( 'NumberedList', {\r
+                                       label: editor.lang.list.numberedlist,\r
+                                       command: 'numberedlist',\r
+                                       directional: true,\r
+                                       toolbar: 'list,10'\r
+                               } );\r
+                               editor.ui.addButton( 'BulletedList', {\r
+                                       label: editor.lang.list.bulletedlist,\r
+                                       command: 'bulletedlist',\r
+                                       directional: true,\r
+                                       toolbar: 'list,20'\r
+                               } );\r
+                       }\r
+\r
+                       // Handled backspace/del key to join list items. (#8248,#9080)\r
+                       editor.on( 'key', function( evt ) {\r
+                               // Use getKey directly in order to ignore modifiers.\r
+                               // Justification: http://dev.ckeditor.com/ticket/11861#comment:13\r
+                               var key = evt.data.domEvent.getKey(), li;\r
+\r
+                               // DEl/BACKSPACE\r
+                               if ( editor.mode == 'wysiwyg' && key in { 8: 1, 46: 1 } ) {\r
+                                       var sel = editor.getSelection(),\r
+                                               range = sel.getRanges()[ 0 ],\r
+                                               path = range && range.startPath();\r
+\r
+                                       if ( !range || !range.collapsed )\r
+                                               return;\r
+\r
+                                       var isBackspace = key == 8;\r
+                                       var editable = editor.editable();\r
+                                       var walker = new CKEDITOR.dom.walker( range.clone() );\r
+                                       walker.evaluator = function( node ) {\r
+                                               return nonEmpty( node ) && !blockBogus( node );\r
+                                       };\r
+                                       // Backspace/Del behavior at the start/end of table is handled in core.\r
+                                       walker.guard = function( node, isOut ) {\r
+                                               return !( isOut && node.type == CKEDITOR.NODE_ELEMENT && node.is( 'table' ) );\r
+                                       };\r
+\r
+                                       var cursor = range.clone();\r
+\r
+                                       if ( isBackspace ) {\r
+                                               var previous, joinWith;\r
+\r
+                                               // Join a sub list's first line, with the previous visual line in parent.\r
+                                               if (\r
+                                                       ( previous = path.contains( listNodeNames ) ) &&\r
+                                                       range.checkBoundaryOfElement( previous, CKEDITOR.START ) &&\r
+                                                       ( previous = previous.getParent() ) && previous.is( 'li' ) &&\r
+                                                       ( previous = getSubList( previous ) )\r
+                                               ) {\r
+                                                       joinWith = previous;\r
+                                                       previous = previous.getPrevious( nonEmpty );\r
+                                                       // Place cursor before the nested list.\r
+                                                       cursor.moveToPosition(\r
+                                                               previous && blockBogus( previous ) ? previous : joinWith,\r
+                                                               CKEDITOR.POSITION_BEFORE_START );\r
+                                               }\r
+                                               // Join any line following a list, with the last visual line of the list.\r
+                                               else {\r
+                                                       walker.range.setStartAt( editable, CKEDITOR.POSITION_AFTER_START );\r
+                                                       walker.range.setEnd( range.startContainer, range.startOffset );\r
+\r
+                                                       previous = walker.previous();\r
+\r
+                                                       if (\r
+                                                               previous && previous.type == CKEDITOR.NODE_ELEMENT &&\r
+                                                               ( previous.getName() in listNodeNames ||\r
+                                                               previous.is( 'li' ) )\r
+                                                       ) {\r
+                                                               if ( !previous.is( 'li' ) ) {\r
+                                                                       walker.range.selectNodeContents( previous );\r
+                                                                       walker.reset();\r
+                                                                       walker.evaluator = isTextBlock;\r
+                                                                       previous = walker.previous();\r
+                                                               }\r
+\r
+                                                               joinWith = previous;\r
+                                                               // Place cursor at the end of previous block.\r
+                                                               cursor.moveToElementEditEnd( joinWith );\r
+\r
+                                                               // And then just before end of closest block element (#12729).\r
+                                                               cursor.moveToPosition( cursor.endPath().block, CKEDITOR.POSITION_BEFORE_END );\r
+                                                       }\r
+                                               }\r
+\r
+                                               if ( joinWith ) {\r
+                                                       joinNextLineToCursor( editor, cursor, range );\r
+                                                       evt.cancel();\r
+                                               }\r
+                                               else {\r
+                                                       var list = path.contains( listNodeNames );\r
+                                                       // Backspace pressed at the start of list outdents the first list item. (#9129)\r
+                                                       if ( list && range.checkBoundaryOfElement( list, CKEDITOR.START ) ) {\r
+                                                               li = list.getFirst( nonEmpty );\r
+\r
+                                                               if ( range.checkBoundaryOfElement( li, CKEDITOR.START ) ) {\r
+                                                                       previous = list.getPrevious( nonEmpty );\r
+\r
+                                                                       // Only if the list item contains a sub list, do nothing but\r
+                                                                       // simply move cursor backward one character.\r
+                                                                       if ( getSubList( li ) ) {\r
+                                                                               if ( previous ) {\r
+                                                                                       range.moveToElementEditEnd( previous );\r
+                                                                                       range.select();\r
+                                                                               }\r
+\r
+                                                                               evt.cancel();\r
+                                                                       }\r
+                                                                       else {\r
+                                                                               editor.execCommand( 'outdent' );\r
+                                                                               evt.cancel();\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+\r
+                                       } else {\r
+                                               var next, nextLine;\r
+\r
+                                               li = path.contains( 'li' );\r
+\r
+                                               if ( li ) {\r
+                                                       walker.range.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END );\r
+\r
+                                                       var last = li.getLast( nonEmpty );\r
+                                                       var block = last && isTextBlock( last ) ? last : li;\r
+\r
+                                                       // Indicate cursor at the visual end of an list item.\r
+                                                       var isAtEnd = 0;\r
+\r
+                                                       next = walker.next();\r
+\r
+                                                       // When list item contains a sub list.\r
+                                                       if (\r
+                                                               next && next.type == CKEDITOR.NODE_ELEMENT &&\r
+                                                               next.getName() in listNodeNames &&\r
+                                                               next.equals( last )\r
+                                                       ) {\r
+                                                               isAtEnd = 1;\r
+\r
+                                                               // Move to the first item in sub list.\r
+                                                               next = walker.next();\r
+                                                       }\r
+                                                       // Right at the end of list item.\r
+                                                       else if ( range.checkBoundaryOfElement( block, CKEDITOR.END ) ) {\r
+                                                               isAtEnd = 2;\r
+                                                       }\r
+\r
+                                                       if ( isAtEnd && next ) {\r
+                                                               // Put cursor range there.\r
+                                                               nextLine = range.clone();\r
+                                                               nextLine.moveToElementEditStart( next );\r
+\r
+                                                               // #13409\r
+                                                               // For the following case and similar\r
+                                                               //\r
+                                                               // <ul>\r
+                                                               //      <li>\r
+                                                               //              <p><a href="#one"><em>x^</em></a></p>\r
+                                                               //              <ul>\r
+                                                               //                      <li><span>y</span></li>\r
+                                                               //              </ul>\r
+                                                               //      </li>\r
+                                                               // </ul>\r
+                                                               if ( isAtEnd == 1 ) {\r
+                                                                       // Move the cursor to <em> if attached to "x" text node.\r
+                                                                       cursor.optimize();\r
+\r
+                                                                       // Abort if the range is attached directly in <li>, like\r
+                                                                       //\r
+                                                                       // <ul>\r
+                                                                       //      <li>\r
+                                                                       //              x^\r
+                                                                       //              <ul>\r
+                                                                       //                      <li><span>y</span></li>\r
+                                                                       //              </ul>\r
+                                                                       //      </li>\r
+                                                                       // </ul>\r
+                                                                       if ( !cursor.startContainer.equals( li ) ) {\r
+                                                                               var node = cursor.startContainer,\r
+                                                                                       farthestInlineAscendant;\r
+\r
+                                                                               // Find <a>, which is farthest from <em> but still inline element.\r
+                                                                               while ( node.is( CKEDITOR.dtd.$inline ) ) {\r
+                                                                                       farthestInlineAscendant = node;\r
+                                                                                       node = node.getParent();\r
+                                                                               }\r
+\r
+                                                                               // Move the range so it does not contain inline elements.\r
+                                                                               // It prevents <span> from being included in <em>.\r
+                                                                               //\r
+                                                                               // <ul>\r
+                                                                               //      <li>\r
+                                                                               //              <p><a href="#one"><em>x</em></a>^</p>\r
+                                                                               //              <ul>\r
+                                                                               //                      <li><span>y</span></li>\r
+                                                                               //              </ul>\r
+                                                                               //      </li>\r
+                                                                               // </ul>\r
+                                                                               //\r
+                                                                               // so instead of\r
+                                                                               //\r
+                                                                               // <ul>\r
+                                                                               //      <li>\r
+                                                                               //              <p><a href="#one"><em>x^<span>y</span></em></a></p>\r
+                                                                               //      </li>\r
+                                                                               // </ul>\r
+                                                                               //\r
+                                                                               // pressing DELETE produces\r
+                                                                               //\r
+                                                                               // <ul>\r
+                                                                               //      <li>\r
+                                                                               //              <p><a href="#one"><em>x</em></a>^<span>y</span></p>\r
+                                                                               //      </li>\r
+                                                                               // </ul>\r
+                                                                               if ( farthestInlineAscendant ) {\r
+                                                                                       cursor.moveToPosition( farthestInlineAscendant, CKEDITOR.POSITION_AFTER_END );\r
+                                                                               }\r
+                                                                       }\r
+                                                               }\r
+\r
+                                                               // Moving `cursor` and `next line` only when at the end literally (#12729).\r
+                                                               if ( isAtEnd == 2 ) {\r
+                                                                       cursor.moveToPosition( cursor.endPath().block, CKEDITOR.POSITION_BEFORE_END );\r
+\r
+                                                                       // Next line might be text node not wrapped in block element.\r
+                                                                       if ( nextLine.endPath().block ) {\r
+                                                                               nextLine.moveToPosition( nextLine.endPath().block, CKEDITOR.POSITION_AFTER_START );\r
+                                                                       }\r
+                                                               }\r
+\r
+                                                               joinNextLineToCursor( editor, cursor, nextLine );\r
+                                                               evt.cancel();\r
+                                                       }\r
+                                               } else {\r
+                                                       // Handle Del key pressed before the list.\r
+                                                       walker.range.setEndAt( editable, CKEDITOR.POSITION_BEFORE_END );\r
+                                                       next = walker.next();\r
+\r
+                                                       if ( next && next.type == CKEDITOR.NODE_ELEMENT && next.is( listNodeNames ) ) {\r
+                                                               // The start <li>\r
+                                                               next = next.getFirst( nonEmpty );\r
+\r
+                                                               // Simply remove the current empty block, move cursor to the\r
+                                                               // subsequent list.\r
+                                                               if ( path.block && range.checkStartOfBlock() && range.checkEndOfBlock() ) {\r
+                                                                       path.block.remove();\r
+                                                                       range.moveToElementEditStart( next );\r
+                                                                       range.select();\r
+                                                                       evt.cancel();\r
+                                                               }\r
+                                                               // Preventing the default (merge behavior), but simply move\r
+                                                               // the cursor one character forward if subsequent list item\r
+                                                               // contains sub list.\r
+                                                               else if ( getSubList( next )  ) {\r
+                                                                       range.moveToElementEditStart( next );\r
+                                                                       range.select();\r
+                                                                       evt.cancel();\r
+                                                               }\r
+                                                               // Merge the first list item with the current line.\r
+                                                               else {\r
+                                                                       nextLine = range.clone();\r
+                                                                       nextLine.moveToElementEditStart( next );\r
+                                                                       joinNextLineToCursor( editor, cursor, nextLine );\r
+                                                                       evt.cancel();\r
+                                                               }\r
+                                                       }\r
+                                               }\r
+\r
+                                       }\r
+\r
+                                       // The backspace/del could potentially put cursor at a bad position,\r
+                                       // being it handled or not, check immediately the selection to have it fixed.\r
+                                       setTimeout( function() {\r
+                                               editor.selectionChange( 1 );\r
+                                       } );\r
+                               }\r
+                       } );\r
+               }\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/listblock/plugin.js b/sources/plugins/listblock/plugin.js
new file mode 100644 (file)
index 0000000..21e6b08
--- /dev/null
@@ -0,0 +1,241 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'listblock', {\r
+       requires: 'panel',\r
+\r
+       onLoad: function() {\r
+               var list = CKEDITOR.addTemplate( 'panel-list', '<ul role="presentation" class="cke_panel_list">{items}</ul>' ),\r
+                       listItem = CKEDITOR.addTemplate( 'panel-list-item', '<li id="{id}" class="cke_panel_listItem" role=presentation>' +\r
+                               '<a id="{id}_option" _cke_focus=1 hidefocus=true' +\r
+                                       ' title="{title}"' +\r
+                                       ' href="javascript:void(\'{val}\')" ' +\r
+                                       ' {onclick}="CKEDITOR.tools.callFunction({clickFn},\'{val}\'); return false;"' + // #188\r
+                                               ' role="option">' +\r
+                                       '{text}' +\r
+                               '</a>' +\r
+                               '</li>' ),\r
+                       listGroup = CKEDITOR.addTemplate( 'panel-list-group', '<h1 id="{id}" class="cke_panel_grouptitle" role="presentation" >{label}</h1>' ),\r
+                       reSingleQuote = /\'/g,\r
+                       escapeSingleQuotes = function( str ) {\r
+                               return str.replace( reSingleQuote, '\\\'' );\r
+                       };\r
+\r
+               CKEDITOR.ui.panel.prototype.addListBlock = function( name, definition ) {\r
+                       return this.addBlock( name, new CKEDITOR.ui.listBlock( this.getHolderElement(), definition ) );\r
+               };\r
+\r
+               CKEDITOR.ui.listBlock = CKEDITOR.tools.createClass( {\r
+                       base: CKEDITOR.ui.panel.block,\r
+\r
+                       $: function( blockHolder, blockDefinition ) {\r
+                               blockDefinition = blockDefinition || {};\r
+\r
+                               var attribs = blockDefinition.attributes || ( blockDefinition.attributes = {} );\r
+                               ( this.multiSelect = !!blockDefinition.multiSelect ) && ( attribs[ 'aria-multiselectable' ] = true );\r
+                               // Provide default role of 'listbox'.\r
+                               !attribs.role && ( attribs.role = 'listbox' );\r
+\r
+                               // Call the base contructor.\r
+                               this.base.apply( this, arguments );\r
+\r
+                               // Set the proper a11y attributes.\r
+                               this.element.setAttribute( 'role', attribs.role );\r
+\r
+                               var keys = this.keys;\r
+                               keys[ 40 ] = 'next'; // ARROW-DOWN\r
+                               keys[ 9 ] = 'next'; // TAB\r
+                               keys[ 38 ] = 'prev'; // ARROW-UP\r
+                               keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB\r
+                               keys[ 32 ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // SPACE\r
+                               CKEDITOR.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (#8041).\r
+\r
+                               this._.pendingHtml = [];\r
+                               this._.pendingList = [];\r
+                               this._.items = {};\r
+                               this._.groups = {};\r
+                       },\r
+\r
+                       _: {\r
+                               close: function() {\r
+                                       if ( this._.started ) {\r
+                                               var output = list.output( { items: this._.pendingList.join( '' ) } );\r
+                                               this._.pendingList = [];\r
+                                               this._.pendingHtml.push( output );\r
+                                               delete this._.started;\r
+                                       }\r
+                               },\r
+\r
+                               getClick: function() {\r
+                                       if ( !this._.click ) {\r
+                                               this._.click = CKEDITOR.tools.addFunction( function( value ) {\r
+                                                       var marked = this.toggle( value );\r
+                                                       if ( this.onClick )\r
+                                                               this.onClick( value, marked );\r
+                                               }, this );\r
+                                       }\r
+                                       return this._.click;\r
+                               }\r
+                       },\r
+\r
+                       proto: {\r
+                               add: function( value, html, title ) {\r
+                                       var id = CKEDITOR.tools.getNextId();\r
+\r
+                                       if ( !this._.started ) {\r
+                                               this._.started = 1;\r
+                                               this._.size = this._.size || 0;\r
+                                       }\r
+\r
+                                       this._.items[ value ] = id;\r
+\r
+                                       var data = {\r
+                                               id: id,\r
+                                               val: escapeSingleQuotes( CKEDITOR.tools.htmlEncodeAttr( value ) ),\r
+                                               onclick: CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick',\r
+                                               clickFn: this._.getClick(),\r
+                                               title: CKEDITOR.tools.htmlEncodeAttr( title || value ),\r
+                                               text: html || value\r
+                                       };\r
+\r
+                                       this._.pendingList.push( listItem.output( data ) );\r
+                               },\r
+\r
+                               startGroup: function( title ) {\r
+                                       this._.close();\r
+\r
+                                       var id = CKEDITOR.tools.getNextId();\r
+\r
+                                       this._.groups[ title ] = id;\r
+\r
+                                       this._.pendingHtml.push( listGroup.output( { id: id, label: title } ) );\r
+                               },\r
+\r
+                               commit: function() {\r
+                                       this._.close();\r
+                                       this.element.appendHtml( this._.pendingHtml.join( '' ) );\r
+                                       delete this._.size;\r
+\r
+                                       this._.pendingHtml = [];\r
+                               },\r
+\r
+                               toggle: function( value ) {\r
+                                       var isMarked = this.isMarked( value );\r
+\r
+                                       if ( isMarked )\r
+                                               this.unmark( value );\r
+                                       else\r
+                                               this.mark( value );\r
+\r
+                                       return !isMarked;\r
+                               },\r
+\r
+                               hideGroup: function( groupTitle ) {\r
+                                       var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ),\r
+                                               list = group && group.getNext();\r
+\r
+                                       if ( group ) {\r
+                                               group.setStyle( 'display', 'none' );\r
+\r
+                                               if ( list && list.getName() == 'ul' )\r
+                                                       list.setStyle( 'display', 'none' );\r
+                                       }\r
+                               },\r
+\r
+                               hideItem: function( value ) {\r
+                                       this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );\r
+                               },\r
+\r
+                               showAll: function() {\r
+                                       var items = this._.items,\r
+                                               groups = this._.groups,\r
+                                               doc = this.element.getDocument();\r
+\r
+                                       for ( var value in items ) {\r
+                                               doc.getById( items[ value ] ).setStyle( 'display', '' );\r
+                                       }\r
+\r
+                                       for ( var title in groups ) {\r
+                                               var group = doc.getById( groups[ title ] ),\r
+                                                       list = group.getNext();\r
+\r
+                                               group.setStyle( 'display', '' );\r
+\r
+                                               if ( list && list.getName() == 'ul' )\r
+                                                       list.setStyle( 'display', '' );\r
+                                       }\r
+                               },\r
+\r
+                               mark: function( value ) {\r
+                                       if ( !this.multiSelect )\r
+                                               this.unmarkAll();\r
+\r
+                                       var itemId = this._.items[ value ],\r
+                                               item = this.element.getDocument().getById( itemId );\r
+                                       item.addClass( 'cke_selected' );\r
+\r
+                                       this.element.getDocument().getById( itemId + '_option' ).setAttribute( 'aria-selected', true );\r
+                                       this.onMark && this.onMark( item );\r
+                               },\r
+\r
+                               unmark: function( value ) {\r
+                                       var doc = this.element.getDocument(),\r
+                                               itemId = this._.items[ value ],\r
+                                               item = doc.getById( itemId );\r
+\r
+                                       item.removeClass( 'cke_selected' );\r
+                                       doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );\r
+\r
+                                       this.onUnmark && this.onUnmark( item );\r
+                               },\r
+\r
+                               unmarkAll: function() {\r
+                                       var items = this._.items,\r
+                                               doc = this.element.getDocument();\r
+\r
+                                       for ( var value in items ) {\r
+                                               var itemId = items[ value ];\r
+\r
+                                               doc.getById( itemId ).removeClass( 'cke_selected' );\r
+                                               doc.getById( itemId + '_option' ).removeAttribute( 'aria-selected' );\r
+                                       }\r
+\r
+                                       this.onUnmark && this.onUnmark();\r
+                               },\r
+\r
+                               isMarked: function( value ) {\r
+                                       return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' );\r
+                               },\r
+\r
+                               focus: function( value ) {\r
+                                       this._.focusIndex = -1;\r
+\r
+                                       var links = this.element.getElementsByTag( 'a' ),\r
+                                               link,\r
+                                               selected,\r
+                                               i = -1;\r
+\r
+                                       if ( value ) {\r
+                                               selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst();\r
+\r
+                                               while ( ( link = links.getItem( ++i ) ) ) {\r
+                                                       if ( link.equals( selected ) ) {\r
+                                                               this._.focusIndex = i;\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               this.element.focus();\r
+                                       }\r
+\r
+                                       selected && setTimeout( function() {\r
+                                               selected.focus();\r
+                                       }, 0 );\r
+                               }\r
+                       }\r
+               } );\r
+       }\r
+} );\r
diff --git a/sources/plugins/liststyle/dialogs/liststyle.js b/sources/plugins/liststyle/dialogs/liststyle.js
new file mode 100644 (file)
index 0000000..4f8f39b
--- /dev/null
@@ -0,0 +1,189 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       function getListElement( editor, listTag ) {\r
+               var range;\r
+               try {\r
+                       range = editor.getSelection().getRanges()[ 0 ];\r
+               } catch ( e ) {\r
+                       return null;\r
+               }\r
+\r
+               range.shrink( CKEDITOR.SHRINK_TEXT );\r
+               return editor.elementPath( range.getCommonAncestor() ).contains( listTag, 1 );\r
+       }\r
+\r
+       var listItem = function( node ) {\r
+                       return node.type == CKEDITOR.NODE_ELEMENT && node.is( 'li' );\r
+               };\r
+\r
+       var mapListStyle = {\r
+               'a': 'lower-alpha',\r
+               'A': 'upper-alpha',\r
+               'i': 'lower-roman',\r
+               'I': 'upper-roman',\r
+               '1': 'decimal',\r
+               'disc': 'disc',\r
+               'circle': 'circle',\r
+               'square': 'square'\r
+       };\r
+\r
+       function listStyle( editor, startupPage ) {\r
+               var lang = editor.lang.liststyle;\r
+               if ( startupPage == 'bulletedListStyle' ) {\r
+                       return {\r
+                               title: lang.bulletedTitle,\r
+                               minWidth: 300,\r
+                               minHeight: 50,\r
+                               contents: [ {\r
+                                       id: 'info',\r
+                                       accessKey: 'I',\r
+                                       elements: [ {\r
+                                               type: 'select',\r
+                                               label: lang.type,\r
+                                               id: 'type',\r
+                                               align: 'center',\r
+                                               style: 'width:150px',\r
+                                               items: [\r
+                                                       [ lang.notset, '' ],\r
+                                                       [ lang.circle, 'circle' ],\r
+                                                       [ lang.disc, 'disc' ],\r
+                                                       [ lang.square, 'square' ]\r
+                                               ],\r
+                                               setup: function( element ) {\r
+                                                       var value = element.getStyle( 'list-style-type' ) || mapListStyle[ element.getAttribute( 'type' ) ] || element.getAttribute( 'type' ) || '';\r
+\r
+                                                       this.setValue( value );\r
+                                               },\r
+                                               commit: function( element ) {\r
+                                                       var value = this.getValue();\r
+                                                       if ( value )\r
+                                                               element.setStyle( 'list-style-type', value );\r
+                                                       else\r
+                                                               element.removeStyle( 'list-style-type' );\r
+                                               }\r
+                                       } ]\r
+                               } ],\r
+                               onShow: function() {\r
+                                       var editor = this.getParentEditor(),\r
+                                               element = getListElement( editor, 'ul' );\r
+\r
+                                       element && this.setupContent( element );\r
+                               },\r
+                               onOk: function() {\r
+                                       var editor = this.getParentEditor(),\r
+                                               element = getListElement( editor, 'ul' );\r
+\r
+                                       element && this.commitContent( element );\r
+                               }\r
+                       };\r
+               } else if ( startupPage == 'numberedListStyle' ) {\r
+\r
+                       var listStyleOptions = [\r
+                               [ lang.notset, '' ],\r
+                               [ lang.lowerRoman, 'lower-roman' ],\r
+                               [ lang.upperRoman, 'upper-roman' ],\r
+                               [ lang.lowerAlpha, 'lower-alpha' ],\r
+                               [ lang.upperAlpha, 'upper-alpha' ],\r
+                               [ lang.decimal, 'decimal' ]\r
+                       ];\r
+\r
+                       if ( !CKEDITOR.env.ie || CKEDITOR.env.version > 7 ) {\r
+                               listStyleOptions.concat( [\r
+                                       [ lang.armenian, 'armenian' ],\r
+                                       [ lang.decimalLeadingZero, 'decimal-leading-zero' ],\r
+                                       [ lang.georgian, 'georgian' ],\r
+                                       [ lang.lowerGreek, 'lower-greek' ]\r
+                               ] );\r
+                       }\r
+\r
+                       return {\r
+                               title: lang.numberedTitle,\r
+                               minWidth: 300,\r
+                               minHeight: 50,\r
+                               contents: [ {\r
+                                       id: 'info',\r
+                                       accessKey: 'I',\r
+                                       elements: [ {\r
+                                               type: 'hbox',\r
+                                               widths: [ '25%', '75%' ],\r
+                                               children: [ {\r
+                                                       label: lang.start,\r
+                                                       type: 'text',\r
+                                                       id: 'start',\r
+                                                       validate: CKEDITOR.dialog.validate.integer( lang.validateStartNumber ),\r
+                                                       setup: function( element ) {\r
+                                                               // List item start number dominates.\r
+                                                               var value = element.getFirst( listItem ).getAttribute( 'value' ) || element.getAttribute( 'start' ) || 1;\r
+                                                               value && this.setValue( value );\r
+                                                       },\r
+                                                       commit: function( element ) {\r
+                                                               var firstItem = element.getFirst( listItem );\r
+                                                               var oldStart = firstItem.getAttribute( 'value' ) || element.getAttribute( 'start' ) || 1;\r
+\r
+                                                               // Force start number on list root.\r
+                                                               element.getFirst( listItem ).removeAttribute( 'value' );\r
+                                                               var val = parseInt( this.getValue(), 10 );\r
+                                                               if ( isNaN( val ) )\r
+                                                                       element.removeAttribute( 'start' );\r
+                                                               else\r
+                                                                       element.setAttribute( 'start', val );\r
+\r
+                                                               // Update consequent list item numbering.\r
+                                                               var nextItem = firstItem,\r
+                                                                       conseq = oldStart,\r
+                                                                       startNumber = isNaN( val ) ? 1 : val;\r
+                                                               while ( ( nextItem = nextItem.getNext( listItem ) ) && conseq++ ) {\r
+                                                                       if ( nextItem.getAttribute( 'value' ) == conseq )\r
+                                                                               nextItem.setAttribute( 'value', startNumber + conseq - oldStart );\r
+                                                               }\r
+                                                       }\r
+                                               },\r
+                                               {\r
+                                                       type: 'select',\r
+                                                       label: lang.type,\r
+                                                       id: 'type',\r
+                                                       style: 'width: 100%;',\r
+                                                       items: listStyleOptions,\r
+                                                       setup: function( element ) {\r
+                                                               var value = element.getStyle( 'list-style-type' ) || mapListStyle[ element.getAttribute( 'type' ) ] || element.getAttribute( 'type' ) || '';\r
+\r
+                                                               this.setValue( value );\r
+                                                       },\r
+                                                       commit: function( element ) {\r
+                                                               var value = this.getValue();\r
+                                                               if ( value )\r
+                                                                       element.setStyle( 'list-style-type', value );\r
+                                                               else\r
+                                                                       element.removeStyle( 'list-style-type' );\r
+                                                       }\r
+                                               } ]\r
+                                       } ]\r
+                               } ],\r
+                               onShow: function() {\r
+                                       var editor = this.getParentEditor(),\r
+                                               element = getListElement( editor, 'ol' );\r
+\r
+                                       element && this.setupContent( element );\r
+                               },\r
+                               onOk: function() {\r
+                                       var editor = this.getParentEditor(),\r
+                                               element = getListElement( editor, 'ol' );\r
+\r
+                                       element && this.commitContent( element );\r
+                               }\r
+                       };\r
+               }\r
+       }\r
+\r
+       CKEDITOR.dialog.add( 'numberedListStyle', function( editor ) {\r
+               return listStyle( editor, 'numberedListStyle' );\r
+       } );\r
+\r
+       CKEDITOR.dialog.add( 'bulletedListStyle', function( editor ) {\r
+               return listStyle( editor, 'bulletedListStyle' );\r
+       } );\r
+} )();\r
diff --git a/sources/plugins/liststyle/lang/af.js b/sources/plugins/liststyle/lang/af.js
new file mode 100644 (file)
index 0000000..71ba760
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'af', {\r
+       armenian: 'Armeense nommering',\r
+       bulletedTitle: 'Eienskappe van ongenommerde lys',\r
+       circle: 'Sirkel',\r
+       decimal: 'Desimale syfers (1, 2, 3, ens.)',\r
+       decimalLeadingZero: 'Desimale syfers met voorloopnul (01, 02, 03, ens.)',\r
+       disc: 'Skyf',\r
+       georgian: 'Georgiese nommering (an, ban, gan, ens.)',\r
+       lowerAlpha: 'Kleinletters (a, b, c, d, e, ens.)',\r
+       lowerGreek: 'Griekse kleinletters (alpha, beta, gamma, ens.)',\r
+       lowerRoman: 'Romeinse kleinletters (i, ii, iii, iv, v, ens.)',\r
+       none: 'Geen',\r
+       notset: '<nie ingestel nie>',\r
+       numberedTitle: 'Eienskappe van genommerde lys',\r
+       square: 'Vierkant',\r
+       start: 'Begin',\r
+       type: 'Tipe',\r
+       upperAlpha: 'Hoofletters (A, B, C, D, E, ens.)',\r
+       upperRoman: 'Romeinse hoofletters (I, II, III, IV, V, ens.)',\r
+       validateStartNumber: 'Beginnommer van lys moet \'n heelgetal wees.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ar.js b/sources/plugins/liststyle/lang/ar.js
new file mode 100644 (file)
index 0000000..7d961df
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ar', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/az.js b/sources/plugins/liststyle/lang/az.js
new file mode 100644 (file)
index 0000000..73fc927
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'az', {\r
+       armenian: 'Erməni nömrələmə',\r
+       bulletedTitle: 'Markerlənmiş siyahının xüsusiyyətləri',\r
+       circle: 'Dəirəcik',\r
+       decimal: 'Rəqəm (1, 2, 3 və s.)',\r
+       decimalLeadingZero: 'Aparıcı sıfır olan rəqəm (01, 02, 03 və s.)',\r
+       disc: 'Disk',\r
+       georgian: 'Gürcü nömrələmə (an, ban, gan, və s.)',\r
+       lowerAlpha: 'Kiçik hərflər (a, b, c, d, e və s.)',\r
+       lowerGreek: 'Kiçik Yunan hərfləri (alfa, beta, qamma və s.)',\r
+       lowerRoman: 'Rum rəqəmləri (i, ii, iii, iv, v və s.)',\r
+       none: 'Yoxdur',\r
+       notset: '<seçilməmiş>',\r
+       numberedTitle: 'Nömrəli siyahının xüsusiyyətləri',\r
+       square: 'Dördbucaq',\r
+       start: 'Başlanğıc',\r
+       type: 'Növ',\r
+       upperAlpha: 'Böyük hərflər (a, b, c, d, e və s.)',\r
+       upperRoman: 'Böyük Rum rəqəmləri (I, II, III, IV, V və s.)',\r
+       validateStartNumber: 'Siyahının başlanğıc nömrəsi tam və müsbət rəqəm olmalıdır.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/bg.js b/sources/plugins/liststyle/lang/bg.js
new file mode 100644 (file)
index 0000000..a119fd4
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'bg', {\r
+       armenian: 'Арменско номериране',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Кръг',\r
+       decimal: 'Числа (1, 2, 3 и др.)',\r
+       decimalLeadingZero: 'Числа с водеща нула (01, 02, 03 и т.н.)',\r
+       disc: 'Диск',\r
+       georgian: 'Грузинско номериране (an, ban, gan, и т.н.)',\r
+       lowerAlpha: 'Малки букви (а, б, в, г, д и т.н.)',\r
+       lowerGreek: 'Малки гръцки букви (алфа, бета, гама и т.н.)',\r
+       lowerRoman: 'Малки римски числа (i, ii, iii, iv, v и т.н.)',\r
+       none: 'Няма',\r
+       notset: '<не е указано>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Квадрат',\r
+       start: 'Старт',\r
+       type: 'Тип',\r
+       upperAlpha: 'Големи букви (А, Б, В, Г, Д и т.н.)',\r
+       upperRoman: 'Големи римски числа (I, II, III, IV, V и т.н.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/bn.js b/sources/plugins/liststyle/lang/bn.js
new file mode 100644 (file)
index 0000000..f1b7bf3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'bn', {\r
+       armenian: 'আর্মেনিয়ান সংখ্যাক্রমে বিন্যাস',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/bs.js b/sources/plugins/liststyle/lang/bs.js
new file mode 100644 (file)
index 0000000..163d1fb
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'bs', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ca.js b/sources/plugins/liststyle/lang/ca.js
new file mode 100644 (file)
index 0000000..8006ff8
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ca', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/cs.js b/sources/plugins/liststyle/lang/cs.js
new file mode 100644 (file)
index 0000000..c1e9a07
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'cs', {\r
+       armenian: 'Arménské',\r
+       bulletedTitle: 'Vlastnosti odrážek',\r
+       circle: 'Kroužky',\r
+       decimal: 'Arabská čísla (1, 2, 3, atd.)',\r
+       decimalLeadingZero: 'Arabská čísla uvozená nulou (01, 02, 03, atd.)',\r
+       disc: 'Kolečka',\r
+       georgian: 'Gruzínské (an, ban, gan, atd.)',\r
+       lowerAlpha: 'Malá latinka (a, b, c, d, e, atd.)',\r
+       lowerGreek: 'Malé řecké (alpha, beta, gamma, atd.)',\r
+       lowerRoman: 'Malé římské (i, ii, iii, iv, v, atd.)',\r
+       none: 'Nic',\r
+       notset: '<nenastaveno>',\r
+       numberedTitle: 'Vlastnosti číslování',\r
+       square: 'Čtverce',\r
+       start: 'Počátek',\r
+       type: 'Typ',\r
+       upperAlpha: 'Velká latinka (A, B, C, D, E, atd.)',\r
+       upperRoman: 'Velké římské (I, II, III, IV, V, atd.)',\r
+       validateStartNumber: 'Číslování musí začínat celým číslem.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/cy.js b/sources/plugins/liststyle/lang/cy.js
new file mode 100644 (file)
index 0000000..97902b5
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'cy', {\r
+       armenian: 'Rhifo Armeneg',\r
+       bulletedTitle: 'Priodweddau Rhestr Fwled',\r
+       circle: 'Cylch',\r
+       decimal: 'Degol (1, 2, 3, ayyb.)',\r
+       decimalLeadingZero: 'Degol â sero arweiniol (01, 02, 03, ayyb.)',\r
+       disc: 'Disg',\r
+       georgian: 'Rhifau Sioraidd (an, ban, gan, ayyb.)',\r
+       lowerAlpha: 'Alffa Is (a, b, c, d, e, ayyb.)',\r
+       lowerGreek: 'Groeg Is (alpha, beta, gamma, ayyb.)',\r
+       lowerRoman: 'Rhufeinig Is (i, ii, iii, iv, v, ayyb.)',\r
+       none: 'Dim',\r
+       notset: '<heb osod>',\r
+       numberedTitle: 'Priodweddau Rhestr Rifol',\r
+       square: 'Sgwâr',\r
+       start: 'Dechrau',\r
+       type: 'Math',\r
+       upperAlpha: 'Alffa Uwch (A, B, C, D, E, ayyb.)',\r
+       upperRoman: 'Rhufeinig Uwch (I, II, III, IV, V, ayyb.)',\r
+       validateStartNumber: 'Rhaid bod y rhif cychwynnol yn gyfanrif.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/da.js b/sources/plugins/liststyle/lang/da.js
new file mode 100644 (file)
index 0000000..27c47b5
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'da', {\r
+       armenian: 'Armensk nummering',\r
+       bulletedTitle: 'Værdier for cirkelpunktopstilling',\r
+       circle: 'Cirkel',\r
+       decimal: 'Decimal (1, 2, 3, osv.)',\r
+       decimalLeadingZero: 'Decimaler med 0 først (01, 02, 03, etc.)',\r
+       disc: 'Værdier for diskpunktopstilling',\r
+       georgian: 'Georgiansk nummering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Små alfabet (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Små græsk (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Små romerske (i, ii, iii, iv, v, etc.)',\r
+       none: 'Ingen',\r
+       notset: '<ikke defineret>',\r
+       numberedTitle: 'Egenskaber for nummereret liste',\r
+       square: 'Firkant',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Store alfabet (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Store romerske (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Den nummererede liste skal starte med et rundt nummer'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/de-ch.js b/sources/plugins/liststyle/lang/de-ch.js
new file mode 100644 (file)
index 0000000..47d8634
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'de-ch', {\r
+       armenian: 'Armenische Nummerierung',\r
+       bulletedTitle: 'Aufzählungslisteneigenschaften',\r
+       circle: 'Ring',\r
+       decimal: 'Dezimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Dezimal mit führender Null (01, 02, 03, usw.)',\r
+       disc: 'Kreis',\r
+       georgian: 'Georgische Nummerierung (an, ban, gan, usw.)',\r
+       lowerAlpha: 'Klein Alpha (a, b, c, d, e, usw.)',\r
+       lowerGreek: 'Klein griechisch (alpha, beta, gamma, usw.)',\r
+       lowerRoman: 'Klein römisch (i, ii, iii, iv, v, usw.)',\r
+       none: 'Keine',\r
+       notset: '<nicht festgelegt>',\r
+       numberedTitle: 'Nummerierte Listeneigenschaften',\r
+       square: 'Quadrat',\r
+       start: 'Start',\r
+       type: 'Typ',\r
+       upperAlpha: 'Gross alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Gross römisch (I, II, III, IV, V, usw.)',\r
+       validateStartNumber: 'Listenstartnummer muss eine ganze Zahl sein.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/de.js b/sources/plugins/liststyle/lang/de.js
new file mode 100644 (file)
index 0000000..cdbf0b3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'de', {\r
+       armenian: 'Armenische Nummerierung',\r
+       bulletedTitle: 'Aufzählungslisteneigenschaften',\r
+       circle: 'Ring',\r
+       decimal: 'Dezimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Dezimal mit führender Null (01, 02, 03, usw.)',\r
+       disc: 'Kreis',\r
+       georgian: 'Georgische Nummerierung (an, ban, gan, usw.)',\r
+       lowerAlpha: 'Klein Alpha (a, b, c, d, e, usw.)',\r
+       lowerGreek: 'Klein griechisch (alpha, beta, gamma, usw.)',\r
+       lowerRoman: 'Klein römisch (i, ii, iii, iv, v, usw.)',\r
+       none: 'Keine',\r
+       notset: '<nicht festgelegt>',\r
+       numberedTitle: 'Nummerierte Listeneigenschaften',\r
+       square: 'Quadrat',\r
+       start: 'Start',\r
+       type: 'Typ',\r
+       upperAlpha: 'Groß alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Groß römisch (I, II, III, IV, V, usw.)',\r
+       validateStartNumber: 'Listenstartnummer muss eine ganze Zahl sein.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/el.js b/sources/plugins/liststyle/lang/el.js
new file mode 100644 (file)
index 0000000..2bd7ce2
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'el', {\r
+       armenian: 'Αρμενική αρίθμηση',\r
+       bulletedTitle: 'Ιδιότητες Λίστας Σημείων',\r
+       circle: 'Κύκλος',\r
+       decimal: 'Δεκαδική (1, 2, 3, κτλ)',\r
+       decimalLeadingZero: 'Δεκαδική με αρχικό μηδεν (01, 02, 03, κτλ)',\r
+       disc: 'Δίσκος',\r
+       georgian: 'Γεωργιανή αρίθμηση (ა, ბ, გ, κτλ)',\r
+       lowerAlpha: 'Μικρά Λατινικά (a, b, c, d, e, κτλ.)',\r
+       lowerGreek: 'Μικρά Ελληνικά (α, β, γ, κτλ)',\r
+       lowerRoman: 'Μικρά Ρωμαϊκά (i, ii, iii, iv, v, κτλ)',\r
+       none: 'Καμία',\r
+       notset: '<δεν έχει οριστεί>',\r
+       numberedTitle: 'Ιδιότητες Αριθμημένης Λίστας ',\r
+       square: 'Τετράγωνο',\r
+       start: 'Εκκίνηση',\r
+       type: 'Τύπος',\r
+       upperAlpha: 'Κεφαλαία Λατινικά (A, B, C, D, E, κτλ)',\r
+       upperRoman: 'Κεφαλαία Ρωμαϊκά (I, II, III, IV, V, κτλ)',\r
+       validateStartNumber: 'Ο αριθμός εκκίνησης της αρίθμησης πρέπει να είναι ακέραιος αριθμός.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/en-au.js b/sources/plugins/liststyle/lang/en-au.js
new file mode 100644 (file)
index 0000000..af38b3e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'en-au', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/en-ca.js b/sources/plugins/liststyle/lang/en-ca.js
new file mode 100644 (file)
index 0000000..ce76d82
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'en-ca', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/en-gb.js b/sources/plugins/liststyle/lang/en-gb.js
new file mode 100644 (file)
index 0000000..7f67124
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'en-gb', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/en.js b/sources/plugins/liststyle/lang/en.js
new file mode 100644 (file)
index 0000000..c41b7d7
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'en', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/eo.js b/sources/plugins/liststyle/lang/eo.js
new file mode 100644 (file)
index 0000000..b601e76
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'eo', {\r
+       armenian: 'Armena nombrado',\r
+       bulletedTitle: 'Atributoj de Bula Listo',\r
+       circle: 'Cirklo',\r
+       decimal: 'Dekumaj Nombroj (1, 2, 3, ktp.)',\r
+       decimalLeadingZero: 'Dekumaj Nombroj malantaŭ nulo (01, 02, 03, ktp.)',\r
+       disc: 'Disko',\r
+       georgian: 'Gruza nombrado (an, ban, gan, ktp.)',\r
+       lowerAlpha: 'Minusklaj Literoj (a, b, c, d, e, ktp.)',\r
+       lowerGreek: 'Grekaj Minusklaj Literoj (alpha, beta, gamma, ktp.)',\r
+       lowerRoman: 'Minusklaj Romanaj Nombroj (i, ii, iii, iv, v, ktp.)',\r
+       none: 'Neniu',\r
+       notset: '<Defaŭlta>',\r
+       numberedTitle: 'Atributoj de Numera Listo',\r
+       square: 'kvadrato',\r
+       start: 'Komenco',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Majusklaj Literoj (A, B, C, D, E, ktp.)',\r
+       upperRoman: 'Majusklaj Romanaj Nombroj (I, II, III, IV, V, ktp.)',\r
+       validateStartNumber: 'La unua listero devas esti entjera nombro.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/es.js b/sources/plugins/liststyle/lang/es.js
new file mode 100644 (file)
index 0000000..75d2920
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'es', {\r
+       armenian: 'Numeración armenia',\r
+       bulletedTitle: 'Propiedades de viñetas',\r
+       circle: 'Círculo',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal con cero inicial (01, 02, 03, etc.)',\r
+       disc: 'Disco',\r
+       georgian: 'Numeración georgiana (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Alfabeto en minúsculas (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Letras griegas (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Números romanos en minúsculas (i, ii, iii, iv, v, etc.)',\r
+       none: 'Ninguno',\r
+       notset: '<sin establecer>',\r
+       numberedTitle: 'Propiedades de lista numerada',\r
+       square: 'Cuadrado',\r
+       start: 'Inicio',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Alfabeto en mayúsculas  (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Números romanos en mayúsculas (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'El Inicio debe ser un número entero.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/et.js b/sources/plugins/liststyle/lang/et.js
new file mode 100644 (file)
index 0000000..d2dfd5e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'et', {\r
+       armenian: 'Armeenia numbrid',\r
+       bulletedTitle: 'Punktloendi omadused',\r
+       circle: 'Ring',\r
+       decimal: 'Numbrid (1, 2, 3, jne)',\r
+       decimalLeadingZero: 'Numbrid algusnulliga (01, 02, 03, jne)',\r
+       disc: 'Täpp',\r
+       georgian: 'Gruusia numbrid (an, ban, gan, jne)',\r
+       lowerAlpha: 'Väiketähed (a, b, c, d, e, jne)',\r
+       lowerGreek: 'Kreeka väiketähed (alpha, beta, gamma, jne)',\r
+       lowerRoman: 'Väiksed rooma numbrid (i, ii, iii, iv, v, jne)',\r
+       none: 'Puudub',\r
+       notset: '<pole määratud>',\r
+       numberedTitle: 'Numberloendi omadused',\r
+       square: 'Ruut',\r
+       start: 'Algus',\r
+       type: 'Liik',\r
+       upperAlpha: 'Suurtähed (A, B, C, D, E, jne)',\r
+       upperRoman: 'Suured rooma numbrid (I, II, III, IV, V, jne)',\r
+       validateStartNumber: 'Loendi algusnumber peab olema täisarv.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/eu.js b/sources/plugins/liststyle/lang/eu.js
new file mode 100644 (file)
index 0000000..ef616e5
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'eu', {\r
+       armenian: 'Zenbakitze armeniarra',\r
+       bulletedTitle: 'Buletadun zerrendaren propietateak',\r
+       circle: 'Zirkulua',\r
+       decimal: 'Hamartarra (1, 2, 3...)',\r
+       decimalLeadingZero: 'Aurretik zeroa duen hamartarra (01, 02, 03...)',\r
+       disc: 'Diskoa',\r
+       georgian: 'Zenbakitze georgiarra (an, ban, gan...)',\r
+       lowerAlpha: 'Alfabetoa minuskulaz (a, b, c, d, e...)',\r
+       lowerGreek: 'Greziera minuskulaz (alpha, beta, gamma...)',\r
+       lowerRoman: 'Erromatarra minuskulaz (i, ii, iii, iv, v...)',\r
+       none: 'Bat ere ez',\r
+       notset: '<ezarri gabea>',\r
+       numberedTitle: 'Zenbakidun zerrendaren propietateak',\r
+       square: 'Karratua',\r
+       start: 'Hasi',\r
+       type: 'Mota',\r
+       upperAlpha: 'Alfabetoa maiuskulaz (A, B, C, D, E...)',\r
+       upperRoman: 'Erromatarra maiuskulaz (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Zerrendaren hasierako zenbakiak zenbaki osoa izan behar du.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/fa.js b/sources/plugins/liststyle/lang/fa.js
new file mode 100644 (file)
index 0000000..7a4517c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'fa', {\r
+       armenian: 'شماره‌گذاری ارمنی',\r
+       bulletedTitle: 'خصوصیات فهرست نقطه‌ای',\r
+       circle: 'دایره',\r
+       decimal: 'ده‌دهی (۱، ۲، ۳، ...)',\r
+       decimalLeadingZero: 'دهدهی همراه با صفر (۰۱، ۰۲، ۰۳، ...)',\r
+       disc: 'صفحه گرد',\r
+       georgian: 'شمارهگذاری گریگورین (an, ban, gan, etc.)',\r
+       lowerAlpha: 'پانویس الفبایی (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'پانویس یونانی (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'پانویس رومی (i, ii, iii, iv, v, etc.)',\r
+       none: 'هیچ',\r
+       notset: '<تنظیم نشده>',\r
+       numberedTitle: 'ویژگیهای فهرست شمارهدار',\r
+       square: 'چهارگوش',\r
+       start: 'شروع',\r
+       type: 'نوع',\r
+       upperAlpha: 'بالانویس الفبایی (A, B, C, D, E, etc.)',\r
+       upperRoman: 'بالانویس رومی (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'فهرست شماره شروع باید یک عدد صحیح باشد.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/fi.js b/sources/plugins/liststyle/lang/fi.js
new file mode 100644 (file)
index 0000000..b0cf1b3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'fi', {\r
+       armenian: 'Armeenialainen numerointi',\r
+       bulletedTitle: 'Numeroimattoman listan ominaisuudet',\r
+       circle: 'Ympyrä',\r
+       decimal: 'Desimaalit (1, 2, 3, jne.)',\r
+       decimalLeadingZero: 'Desimaalit, alussa nolla (01, 02, 03, jne.)',\r
+       disc: 'Levy',\r
+       georgian: 'Georgialainen numerointi (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Pienet aakkoset (a, b, c, d, e, jne.)',\r
+       lowerGreek: 'Pienet kreikkalaiset (alpha, beta, gamma, jne.)',\r
+       lowerRoman: 'Pienet roomalaiset (i, ii, iii, iv, v, jne.)',\r
+       none: 'Ei mikään',\r
+       notset: '<ei asetettu>',\r
+       numberedTitle: 'Numeroidun listan ominaisuudet',\r
+       square: 'Neliö',\r
+       start: 'Alku',\r
+       type: 'Tyyppi',\r
+       upperAlpha: 'Isot aakkoset (A, B, C, D, E, jne.)',\r
+       upperRoman: 'Isot roomalaiset (I, II, III, IV, V, jne.)',\r
+       validateStartNumber: 'Listan ensimmäisen numeron tulee olla kokonaisluku.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/fo.js b/sources/plugins/liststyle/lang/fo.js
new file mode 100644 (file)
index 0000000..922a85c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'fo', {\r
+       armenian: 'Armensk talskipan',\r
+       bulletedTitle: 'Eginleikar fyri lista við prikkum',\r
+       circle: 'Sirkul',\r
+       decimal: 'Vanlig tøl (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Tøl við null frammanfyri (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgisk talskipan (an, ban, gan, osv.)',\r
+       lowerAlpha: 'Lítlir bókstavir (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grikskt við lítlum (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lítil rómaratøl (i, ii, iii, iv, v, etc.)',\r
+       none: 'Einki',\r
+       notset: '<ikki sett>',\r
+       numberedTitle: 'Eginleikar fyri lista við tølum',\r
+       square: 'Fýrkantur',\r
+       start: 'Byrjan',\r
+       type: 'Slag',\r
+       upperAlpha: 'Stórir bókstavir (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Stór rómaratøl (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Byrjunartalið fyri lista má vera eitt heiltal.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/fr-ca.js b/sources/plugins/liststyle/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..06c2af9
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'fr-ca', {\r
+       armenian: 'Numération arménienne',\r
+       bulletedTitle: 'Propriété de liste à puce',\r
+       circle: 'Cercle',\r
+       decimal: 'Décimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Décimal avec zéro (01, 02, 03, etc.)',\r
+       disc: 'Disque',\r
+       georgian: 'Numération géorgienne (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Alphabétique minuscule (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grecque minuscule (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Romain minuscule (i, ii, iii, iv, v, etc.)',\r
+       none: 'Aucun',\r
+       notset: '<non défini>',\r
+       numberedTitle: 'Propriété de la liste numérotée',\r
+       square: 'Carré',\r
+       start: 'Début',\r
+       type: 'Type',\r
+       upperAlpha: 'Alphabétique majuscule (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Romain Majuscule (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Le numéro de début de liste doit être un entier.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/fr.js b/sources/plugins/liststyle/lang/fr.js
new file mode 100644 (file)
index 0000000..ccb6944
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'fr', {\r
+       armenian: 'Numération arménienne',\r
+       bulletedTitle: 'Propriétés de la liste à puces',\r
+       circle: 'Cercle',\r
+       decimal: 'Décimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Décimal précédé par un 0 (01, 02, 03, etc.)',\r
+       disc: 'Disque',\r
+       georgian: 'Numération géorgienne (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lettres minuscules (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grec minuscule (alpha, bêta, gamma, etc.)',\r
+       lowerRoman: 'Chiffres romains minuscules (i, ii, iii, iv, v, etc.)',\r
+       none: 'Aucun',\r
+       notset: '<indéfini>',\r
+       numberedTitle: 'Propriétés de la liste numérotée',\r
+       square: 'Carré',\r
+       start: 'Début',\r
+       type: 'Type',\r
+       upperAlpha: 'Lettres majuscules (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Chiffres romains majuscules (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Le premier élément de la liste doit être un nombre entier.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/gl.js b/sources/plugins/liststyle/lang/gl.js
new file mode 100644 (file)
index 0000000..eeb622d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'gl', {\r
+       armenian: 'Numeración armenia',\r
+       bulletedTitle: 'Propiedades da lista viñeteada',\r
+       circle: 'Circulo',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal con cero á esquerda (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Numeración xeorxiana (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Alfabeto en minúsculas (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grego en minúsculas (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Números romanos en minúsculas (i, ii, iii, iv, v, etc.)',\r
+       none: 'Ningún',\r
+       notset: '<sen estabelecer>',\r
+       numberedTitle: 'Propiedades da lista numerada',\r
+       square: 'Cadrado',\r
+       start: 'Inicio',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Alfabeto en maiúsculas (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Números romanos en maiúsculas (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'O número de inicio da lista debe ser un número enteiro.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/gu.js b/sources/plugins/liststyle/lang/gu.js
new file mode 100644 (file)
index 0000000..434f218
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'gu', {\r
+       armenian: 'અરમેનિયન આંકડા પદ્ધતિ',\r
+       bulletedTitle: 'બુલેટેડ લીસ્ટના ગુણ',\r
+       circle: 'વર્તુળ',\r
+       decimal: 'આંકડા (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'સુન્ય આગળ આંકડા (01, 02, 03, etc.)',\r
+       disc: 'ડિસ્ક',\r
+       georgian: 'ગેઓર્ગિયન આંકડા પદ્ધતિ (an, ban, gan, etc.)',\r
+       lowerAlpha: 'આલ્ફા નાના (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'ગ્રીક નાના (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'રોમન નાના (i, ii, iii, iv, v, etc.)',\r
+       none: 'કસુ ',\r
+       notset: '<સેટ નથી>',\r
+       numberedTitle: 'આંકડાના લીસ્ટના ગુણ',\r
+       square: 'ચોરસ',\r
+       start: 'શરુ કરવું',\r
+       type: 'પ્રકાર',\r
+       upperAlpha: 'આલ્ફા મોટા (A, B, C, D, E, etc.)',\r
+       upperRoman: 'રોમન મોટા (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'લીસ્ટના સરુઆતનો આંકડો પુરો હોવો જોઈએ.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/he.js b/sources/plugins/liststyle/lang/he.js
new file mode 100644 (file)
index 0000000..93b6106
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'he', {\r
+       armenian: 'ספרות ארמניות',\r
+       bulletedTitle: 'תכונות רשימת תבליטים',\r
+       circle: 'עיגול ריק',\r
+       decimal: 'ספרות (1, 2, 3 וכו\')',\r
+       decimalLeadingZero: 'ספרות עם 0 בהתחלה (01, 02, 03 וכו\')',\r
+       disc: 'עיגול מלא',\r
+       georgian: 'ספרות גיאורגיות (an, ban, gan וכו\')',\r
+       lowerAlpha: 'אותיות אנגליות קטנות (a, b, c, d, e וכו\')',\r
+       lowerGreek: 'אותיות יווניות קטנות (alpha, beta, gamma וכו\')',\r
+       lowerRoman: 'ספירה רומית באותיות קטנות (i, ii, iii, iv, v וכו\')',\r
+       none: 'ללא',\r
+       notset: '<לא נקבע>',\r
+       numberedTitle: 'תכונות רשימה ממוספרת',\r
+       square: 'ריבוע',\r
+       start: 'תחילת מספור',\r
+       type: 'סוג',\r
+       upperAlpha: 'אותיות אנגליות גדולות (A, B, C, D, E וכו\')',\r
+       upperRoman: 'ספירה רומיות באותיות גדולות (I, II, III, IV, V וכו\')',\r
+       validateStartNumber: 'שדה תחילת המספור חייב להכיל מספר שלם.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/hi.js b/sources/plugins/liststyle/lang/hi.js
new file mode 100644 (file)
index 0000000..0f1ae03
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'hi', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/hr.js b/sources/plugins/liststyle/lang/hr.js
new file mode 100644 (file)
index 0000000..8da2ff3
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'hr', {\r
+       armenian: 'Armenijska numeracija',\r
+       bulletedTitle: 'Svojstva liste',\r
+       circle: 'Krug',\r
+       decimal: 'Decimalna numeracija (1, 2, 3, itd.)',\r
+       decimalLeadingZero: 'Decimalna s vodećom nulom (01, 02, 03, itd)',\r
+       disc: 'Disk',\r
+       georgian: 'Gruzijska numeracija(an, ban, gan, etc.)',\r
+       lowerAlpha: 'Znakovi mala slova (a, b, c, d, e, itd.)',\r
+       lowerGreek: 'Grčka numeracija mala slova (alfa, beta, gama, itd).',\r
+       lowerRoman: 'Romanska numeracija mala slova (i, ii, iii, iv, v, itd.)',\r
+       none: 'Bez',\r
+       notset: '<nije određen>',\r
+       numberedTitle: 'Svojstva brojčane liste',\r
+       square: 'Kvadrat',\r
+       start: 'Početak',\r
+       type: 'Vrsta',\r
+       upperAlpha: 'Znakovi velika slova (A, B, C, D, E, itd.)',\r
+       upperRoman: 'Romanska numeracija velika slova (I, II, III, IV, V, itd.)',\r
+       validateStartNumber: 'Početak brojčane liste mora biti cijeli broj.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/hu.js b/sources/plugins/liststyle/lang/hu.js
new file mode 100644 (file)
index 0000000..4e3d922
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'hu', {\r
+       armenian: 'Örmény számozás',\r
+       bulletedTitle: 'Pontozott lista tulajdonságai',\r
+       circle: 'Kör',\r
+       decimal: 'Arab számozás (1, 2, 3, stb.)',\r
+       decimalLeadingZero: 'Számozás bevezető nullákkal (01, 02, 03, stb.)',\r
+       disc: 'Korong',\r
+       georgian: 'Grúz számozás (an, ban, gan, stb.)',\r
+       lowerAlpha: 'Kisbetűs (a, b, c, d, e, stb.)',\r
+       lowerGreek: 'Görög (alpha, beta, gamma, stb.)',\r
+       lowerRoman: 'Római kisbetűs (i, ii, iii, iv, v, stb.)',\r
+       none: 'Nincs',\r
+       notset: '<Nincs beállítva>',\r
+       numberedTitle: 'Sorszámozott lista tulajdonságai',\r
+       square: 'Négyzet',\r
+       start: 'Kezdőszám',\r
+       type: 'Típus',\r
+       upperAlpha: 'Nagybetűs (A, B, C, D, E, stb.)',\r
+       upperRoman: 'Római nagybetűs (I, II, III, IV, V, stb.)',\r
+       validateStartNumber: 'A kezdőszám nem lehet tört érték.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/id.js b/sources/plugins/liststyle/lang/id.js
new file mode 100644 (file)
index 0000000..36ec1ec
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'id', {\r
+       armenian: 'Armenian numbering', // MISSING\r
+       bulletedTitle: 'Bulleted List Properties', // MISSING\r
+       circle: 'Lingkaran',\r
+       decimal: 'Desimal (1, 2, 3, dst.)',\r
+       decimalLeadingZero: 'Desimal diawali angka nol (01, 02, 03, dst.)',\r
+       disc: 'Cakram',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)', // MISSING\r
+       lowerAlpha: 'Huruf Kecil (a, b, c, d, e, dst.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)', // MISSING\r
+       lowerRoman: 'Angka Romawi (i, ii, iii, iv, v, dst.)',\r
+       none: 'Tidak ada',\r
+       notset: '<tidak diatur>',\r
+       numberedTitle: 'Numbered List Properties', // MISSING\r
+       square: 'Persegi',\r
+       start: 'Mulai',\r
+       type: 'Tipe',\r
+       upperAlpha: 'Huruf Besar (A, B, C, D, E, dst.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)', // MISSING\r
+       validateStartNumber: 'List start number must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/is.js b/sources/plugins/liststyle/lang/is.js
new file mode 100644 (file)
index 0000000..a05c5bc
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'is', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/it.js b/sources/plugins/liststyle/lang/it.js
new file mode 100644 (file)
index 0000000..6ef919d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'it', {\r
+       armenian: 'Numerazione Armena',\r
+       bulletedTitle: 'Proprietà liste puntate',\r
+       circle: 'Cerchio',\r
+       decimal: 'Decimale (1, 2, 3, ecc.)',\r
+       decimalLeadingZero: 'Decimale preceduto da 0 (01, 02, 03, ecc.)',\r
+       disc: 'Disco',\r
+       georgian: 'Numerazione Georgiana (an, ban, gan, ecc.)',\r
+       lowerAlpha: 'Alfabetico minuscolo (a, b, c, d, e, ecc.)',\r
+       lowerGreek: 'Greco minuscolo (alpha, beta, gamma, ecc.)',\r
+       lowerRoman: 'Numerazione Romana minuscola (i, ii, iii, iv, v, ecc.)',\r
+       none: 'Nessuno',\r
+       notset: '<non impostato>',\r
+       numberedTitle: 'Proprietà liste numerate',\r
+       square: 'Quadrato',\r
+       start: 'Inizio',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Alfabetico maiuscolo (A, B, C, D, E, ecc.)',\r
+       upperRoman: 'Numerazione Romana maiuscola (I, II, III, IV, V, ecc.)',\r
+       validateStartNumber: 'Il numero di inizio di una lista numerata deve essere un numero intero.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ja.js b/sources/plugins/liststyle/lang/ja.js
new file mode 100644 (file)
index 0000000..e55dafc
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ja', {\r
+       armenian: 'アルメニア数字',\r
+       bulletedTitle: '箇条書きのプロパティ',\r
+       circle: '白丸',\r
+       decimal: '数字 (1, 2, 3, etc.)',\r
+       decimalLeadingZero: '0付きの数字 (01, 02, 03, etc.)',\r
+       disc: '黒丸',\r
+       georgian: 'グルジア数字 (an, ban, gan, etc.)',\r
+       lowerAlpha: '小文字アルファベット (a, b, c, d, e, etc.)',\r
+       lowerGreek: '小文字ギリシャ文字 (alpha, beta, gamma, etc.)',\r
+       lowerRoman: '小文字ローマ数字 (i, ii, iii, iv, v, etc.)',\r
+       none: 'なし',\r
+       notset: '<なし>',\r
+       numberedTitle: '番号付きリストのプロパティ',\r
+       square: '四角',\r
+       start: '開始',\r
+       type: '種類',\r
+       upperAlpha: '大文字アルファベット (A, B, C, D, E, etc.)',\r
+       upperRoman: '大文字ローマ数字 (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'リストの開始番号は数値で入力してください。'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ka.js b/sources/plugins/liststyle/lang/ka.js
new file mode 100644 (file)
index 0000000..0ede82d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ka', {\r
+       armenian: 'სომხური გადანომრვა',\r
+       bulletedTitle: 'ღილებიანი სიის პარამეტრები',\r
+       circle: 'წრეწირი',\r
+       decimal: 'რიცხვებით (1, 2, 3, ..)',\r
+       decimalLeadingZero: 'ნულით დაწყებული რიცხვებით (01, 02, 03, ..)',\r
+       disc: 'წრე',\r
+       georgian: 'ქართული გადანომრვა (ან, ბან, გან, ..)',\r
+       lowerAlpha: 'პატარა ლათინური ასოებით (a, b, c, d, e, ..)',\r
+       lowerGreek: 'პატარა ბერძნული ასოებით (ალფა, ბეტა, გამა, ..)',\r
+       lowerRoman: 'რომაული გადანომრვცა პატარა ციფრებით (i, ii, iii, iv, v, ..)',\r
+       none: 'არაფერი',\r
+       notset: '<არაფერი>',\r
+       numberedTitle: 'გადანომრილი სიის პარამეტრები',\r
+       square: 'კვადრატი',\r
+       start: 'საწყისი',\r
+       type: 'ტიპი',\r
+       upperAlpha: 'დიდი ლათინური ასოებით (A, B, C, D, E, ..)',\r
+       upperRoman: 'რომაული გადანომრვა დიდი ციფრებით (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'სიის საწყისი მთელი რიცხვი უნდა იყოს.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/km.js b/sources/plugins/liststyle/lang/km.js
new file mode 100644 (file)
index 0000000..51d7365
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'km', {\r
+       armenian: 'លេខ​អារមេនី',\r
+       bulletedTitle: 'លក្ខណៈ​សម្បត្តិ​បញ្ជី​ជា​ចំណុច',\r
+       circle: 'រង្វង់​មូល',\r
+       decimal: 'លេខ​ទសភាគ (1, 2, 3, ...)',\r
+       decimalLeadingZero: 'ទសភាគ​ចាប់​ផ្ដើម​ពី​សូន្យ (01, 02, 03, ...)',\r
+       disc: 'ថាស',\r
+       georgian: 'លេខ​ចចជា (an, ban, gan, ...)',\r
+       lowerAlpha: 'ព្យញ្ជនៈ​តូច (a, b, c, d, e, ...)',\r
+       lowerGreek: 'លេខ​ក្រិក​តូច (alpha, beta, gamma, ...)',\r
+       lowerRoman: 'លេខ​រ៉ូម៉ាំង​តូច (i, ii, iii, iv, v, ...)',\r
+       none: 'គ្មាន',\r
+       notset: '<not set>',\r
+       numberedTitle: 'លក្ខណៈ​សម្បត្តិ​បញ្ជី​ជា​លេខ',\r
+       square: 'ការេ',\r
+       start: 'ចាប់​ផ្ដើម',\r
+       type: 'ប្រភេទ',\r
+       upperAlpha: 'អក្សរ​ធំ (A, B, C, D, E, ...)',\r
+       upperRoman: 'លេខ​រ៉ូម៉ាំង​ធំ (I, II, III, IV, V, ...)',\r
+       validateStartNumber: 'លេខ​ចាប់​ផ្ដើម​បញ្ជី ត្រូវ​តែ​ជា​តួ​លេខ​ពិត​ប្រាកដ។'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ko.js b/sources/plugins/liststyle/lang/ko.js
new file mode 100644 (file)
index 0000000..8b88e2d
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ko', {\r
+       armenian: '아르메니아 숫자',\r
+       bulletedTitle: '순서 없는 목록 속성',\r
+       circle: '원',\r
+       decimal: '수 (1, 2, 3, 등)',\r
+       decimalLeadingZero: '0이 붙은 수 (01, 02, 03, 등)',\r
+       disc: '내림차순',\r
+       georgian: '그루지야 숫자 (an, ban, gan, 등)',\r
+       lowerAlpha: '영소문자 (a, b, c, d, e, 등)',\r
+       lowerGreek: '그리스 소문자 (alpha, beta, gamma, 등)',\r
+       lowerRoman: '로마 소문자 (i, ii, iii, iv, v, 등)',\r
+       none: '없음',\r
+       notset: '<설정 없음>',\r
+       numberedTitle: '순서 있는 목록 속성',\r
+       square: '사각',\r
+       start: '시작',\r
+       type: '유형',\r
+       upperAlpha: '영대문자 (A, B, C, D, E, 등)',\r
+       upperRoman: '로마 대문자 (I, II, III, IV, V, 등)',\r
+       validateStartNumber: '목록 시작 숫자는 정수여야 합니다.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ku.js b/sources/plugins/liststyle/lang/ku.js
new file mode 100644 (file)
index 0000000..a3a7b47
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ku', {\r
+       armenian: 'ئاراستەی ژمارەی ئەرمەنی',\r
+       bulletedTitle: 'خاسیەتی لیستی خاڵی',\r
+       circle: 'بازنه',\r
+       decimal: 'ژمارە (1, 2, 3, وە هیتر.)',\r
+       decimalLeadingZero: 'ژمارە سفڕی لەپێشەوه (01, 02, 03, وە هیتر.)',\r
+       disc: 'پەپکە',\r
+       georgian: 'ئاراستەی ژمارەی جۆڕجی (an, ban, gan, وە هیتر.)',\r
+       lowerAlpha: 'ئەلفابێی بچووك (a, b, c, d, e, وە هیتر.)',\r
+       lowerGreek: 'یۆنانی بچووك (alpha, beta, gamma, وە هیتر.)',\r
+       lowerRoman: 'ژمارەی ڕۆمی بچووك (i, ii, iii, iv, v, وە هیتر.)',\r
+       none: 'هیچ',\r
+       notset: '<دانەندراوه>',\r
+       numberedTitle: 'خاسیەتی لیستی ژمارەیی',\r
+       square: 'چووراگۆشە',\r
+       start: 'دەستپێکردن',\r
+       type: 'جۆر',\r
+       upperAlpha: 'ئەلفابێی گەوره (A, B, C, D, E, وە هیتر.)',\r
+       upperRoman: 'ژمارەی ڕۆمی گەوره (I, II, III, IV, V, وە هیتر.)',\r
+       validateStartNumber: 'دەستپێکەری لیستی ژمارەیی دەبێت تەنها ژمارە بێت.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/lt.js b/sources/plugins/liststyle/lang/lt.js
new file mode 100644 (file)
index 0000000..6b7c949
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'lt', {\r
+       armenian: 'Armėniški skaitmenys',\r
+       bulletedTitle: 'Ženklelinio sąrašo nustatymai',\r
+       circle: 'Apskritimas',\r
+       decimal: 'Dešimtainis (1, 2, 3, t.t)',\r
+       decimalLeadingZero: 'Dešimtainis su nuliu priekyje (01, 02, 03, t.t)',\r
+       disc: 'Diskas',\r
+       georgian: 'Gruziniški skaitmenys (an, ban, gan, t.t)',\r
+       lowerAlpha: 'Mažosios Alpha (a, b, c, d, e, t.t)',\r
+       lowerGreek: 'Mažosios Graikų (alpha, beta, gamma, t.t)',\r
+       lowerRoman: 'Mažosios Romėnų (i, ii, iii, iv, v, t.t)',\r
+       none: 'Niekas',\r
+       notset: '<nenurodytas>',\r
+       numberedTitle: 'Skaitmeninio sąrašo nustatymai',\r
+       square: 'Kvadratas',\r
+       start: 'Pradžia',\r
+       type: 'Rūšis',\r
+       upperAlpha: 'Didžiosios Alpha (A, B, C, D, E, t.t)',\r
+       upperRoman: 'Didžiosios Romėnų (I, II, III, IV, V, t.t)',\r
+       validateStartNumber: 'Sąrašo pradžios skaitmuo turi būti sveikas skaičius.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/lv.js b/sources/plugins/liststyle/lang/lv.js
new file mode 100644 (file)
index 0000000..17b6da7
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'lv', {\r
+       armenian: 'Armēņu skaitļi',\r
+       bulletedTitle: 'Vienkārša saraksta uzstādījumi',\r
+       circle: 'Aplis',\r
+       decimal: 'Decimālie (1, 2, 3, utt)',\r
+       decimalLeadingZero: 'Decimālie ar nulli (01, 02, 03, utt)',\r
+       disc: 'Disks',\r
+       georgian: 'Gruzīņu skaitļi (an, ban, gan, utt)',\r
+       lowerAlpha: 'Mazie alfabēta (a, b, c, d, e, utt)',\r
+       lowerGreek: 'Mazie grieķu (alfa, beta, gamma, utt)',\r
+       lowerRoman: 'Mazie romāņu (i, ii, iii, iv, v, utt)',\r
+       none: 'Nekas',\r
+       notset: '<nav norādīts>',\r
+       numberedTitle: 'Numurēta saraksta uzstādījumi',\r
+       square: 'Kvadrāts',\r
+       start: 'Sākt',\r
+       type: 'Tips',\r
+       upperAlpha: 'Lielie alfabēta (A, B, C, D, E, utt)',\r
+       upperRoman: 'Lielie romāņu (I, II, III, IV, V, utt)',\r
+       validateStartNumber: 'Saraksta sākuma numuram jābūt veselam skaitlim'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/mk.js b/sources/plugins/liststyle/lang/mk.js
new file mode 100644 (file)
index 0000000..dbb640b
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'mk', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/mn.js b/sources/plugins/liststyle/lang/mn.js
new file mode 100644 (file)
index 0000000..54e884c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'mn', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Төрөл',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ms.js b/sources/plugins/liststyle/lang/ms.js
new file mode 100644 (file)
index 0000000..297c02c
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ms', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/nb.js b/sources/plugins/liststyle/lang/nb.js
new file mode 100644 (file)
index 0000000..0fe7859
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'nb', {\r
+       armenian: 'Armensk nummerering',\r
+       bulletedTitle: 'Egenskaper for punktliste',\r
+       circle: 'Sirkel',\r
+       decimal: 'Tall (1, 2, 3, osv.)',\r
+       decimalLeadingZero: 'Tall, med førstesiffer null (01, 02, 03, osv.)',\r
+       disc: 'Disk',\r
+       georgian: 'Georgisk nummerering (an, ban, gan, osv.)',\r
+       lowerAlpha: 'Alfabetisk, små (a, b, c, d, e, osv.)',\r
+       lowerGreek: 'Gresk, små (alpha, beta, gamma, osv.)',\r
+       lowerRoman: 'Romertall, små (i, ii, iii, iv, v, osv.)',\r
+       none: 'Ingen',\r
+       notset: '<ikke satt>',\r
+       numberedTitle: 'Egenskaper for nummerert liste',\r
+       square: 'Firkant',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Alfabetisk, store (A, B, C, D, E, osv.)',\r
+       upperRoman: 'Romertall, store (I, II, III, IV, V, osv.)',\r
+       validateStartNumber: 'Starten på listen må være et heltall.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/nl.js b/sources/plugins/liststyle/lang/nl.js
new file mode 100644 (file)
index 0000000..88ea3f8
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'nl', {\r
+       armenian: 'Armeense nummering',\r
+       bulletedTitle: 'Eigenschappen lijst met opsommingstekens',\r
+       circle: 'Cirkel',\r
+       decimal: 'Cijfers (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Cijfers beginnen met nul (01, 02, 03, etc.)',\r
+       disc: 'Schijf',\r
+       georgian: 'Georgische nummering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Kleine letters (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grieks kleine letters (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Romeins kleine letters (i, ii, iii, iv, v, etc.)',\r
+       none: 'Geen',\r
+       notset: '<niet gezet>',\r
+       numberedTitle: 'Eigenschappen genummerde lijst',\r
+       square: 'Vierkant',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Hoofdletters (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Romeinse hoofdletters (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Startnummer van de lijst moet een heel nummer zijn.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/no.js b/sources/plugins/liststyle/lang/no.js
new file mode 100644 (file)
index 0000000..26927e6
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'no', {\r
+       armenian: 'Armensk nummerering',\r
+       bulletedTitle: 'Egenskaper for punktmerket liste',\r
+       circle: 'Sirkel',\r
+       decimal: 'Tall (1, 2, 3, osv.)',\r
+       decimalLeadingZero: 'Tall, med førstesiffer null (01, 02, 03, osv.)',\r
+       disc: 'Disk',\r
+       georgian: 'Georgisk nummerering (an, ban, gan, osv.)',\r
+       lowerAlpha: 'Alfabetisk, små (a, b, c, d, e, osv.)',\r
+       lowerGreek: 'Gresk, små (alpha, beta, gamma, osv.)',\r
+       lowerRoman: 'Romertall, små (i, ii, iii, iv, v, osv.)',\r
+       none: 'Ingen',\r
+       notset: '<ikke satt>',\r
+       numberedTitle: 'Egenskaper for nummerert liste',\r
+       square: 'Firkant',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Alfabetisk, store (A, B, C, D, E, osv.)',\r
+       upperRoman: 'Romertall, store (I, II, III, IV, V, osv.)',\r
+       validateStartNumber: 'Starten på listen må være et heltall.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/oc.js b/sources/plugins/liststyle/lang/oc.js
new file mode 100644 (file)
index 0000000..eb64753
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'oc', {\r
+       armenian: 'Numerotacion armènia',\r
+       bulletedTitle: 'Proprietats de la lista de piuses',\r
+       circle: 'Cercle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal precedit per un 0 (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Numeracion georgiana (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Letras minusculas (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grèc minuscula (alfa, bèta, gamma, etc.)',\r
+       lowerRoman: 'Chifras romanas minusculas (i, ii, iii, iv, v, etc.)',\r
+       none: 'Pas cap',\r
+       notset: '<indefinit>',\r
+       numberedTitle: 'Proprietats de la lista numerotada',\r
+       square: 'Carrat',\r
+       start: 'Començament',\r
+       type: 'Tipe',\r
+       upperAlpha: 'Letras majusculas (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Chifras romanas majusculas (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Lo primièr element de la lista deu èsser un nombre entièr.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/pl.js b/sources/plugins/liststyle/lang/pl.js
new file mode 100644 (file)
index 0000000..37d2cd7
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'pl', {\r
+       armenian: 'Numerowanie armeńskie',\r
+       bulletedTitle: 'Właściwości list wypunktowanych',\r
+       circle: 'Koło',\r
+       decimal: 'Liczby (1, 2, 3 itd.)',\r
+       decimalLeadingZero: 'Liczby z początkowym zerem (01, 02, 03 itd.)',\r
+       disc: 'Okrąg',\r
+       georgian: 'Numerowanie gruzińskie (an, ban, gan itd.)',\r
+       lowerAlpha: 'Małe litery (a, b, c, d, e itd.)',\r
+       lowerGreek: 'Małe litery greckie (alpha, beta, gamma itd.)',\r
+       lowerRoman: 'Małe cyfry rzymskie (i, ii, iii, iv, v itd.)',\r
+       none: 'Brak',\r
+       notset: '<nie ustawiono>',\r
+       numberedTitle: 'Właściwości list numerowanych',\r
+       square: 'Kwadrat',\r
+       start: 'Początek',\r
+       type: 'Typ punktora',\r
+       upperAlpha: 'Duże litery (A, B, C, D, E itd.)',\r
+       upperRoman: 'Duże cyfry rzymskie (I, II, III, IV, V itd.)',\r
+       validateStartNumber: 'Listę musi rozpoczynać liczba całkowita.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/pt-br.js b/sources/plugins/liststyle/lang/pt-br.js
new file mode 100644 (file)
index 0000000..c5f0296
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'pt-br', {\r
+       armenian: 'Numeração Armêna',\r
+       bulletedTitle: 'Propriedades da Lista sem Numeros',\r
+       circle: 'Círculo',\r
+       decimal: 'Numeração Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Numeração Decimal com zeros (01, 02, 03, etc.)',\r
+       disc: 'Disco',\r
+       georgian: 'Numeração da Geórgia (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Numeração Alfabética minúscula (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Numeração Grega minúscula (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Numeração Romana minúscula (i, ii, iii, iv, v, etc.)',\r
+       none: 'Nenhum',\r
+       notset: '<não definido>',\r
+       numberedTitle: 'Propriedades da Lista Numerada',\r
+       square: 'Quadrado',\r
+       start: 'Início',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Numeração Alfabética Maiúscula (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Numeração Romana maiúscula (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'O número inicial da lista deve ser um número inteiro.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/pt.js b/sources/plugins/liststyle/lang/pt.js
new file mode 100644 (file)
index 0000000..7dc1f25
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'pt', {\r
+       armenian: 'Numeração armênia',\r
+       bulletedTitle: 'Propriedades da lista não numerada',\r
+       circle: 'Círculo',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Zero decimal à esquerda (01, 02, 03, etc.)',\r
+       disc: 'Disco',\r
+       georgian: 'Numeração georgiana (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Minúsculas (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grego em minúsculas (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Romano em minúsculas (i, ii, iii, iv, v, etc.)',\r
+       none: 'Nenhum',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Quadrado',\r
+       start: 'Iniciar',\r
+       type: 'Tipo',\r
+       upperAlpha: 'Maiúsculas (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Romanos em maiúscula (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'A lista tem iniciar por um número inteiro'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ro.js b/sources/plugins/liststyle/lang/ro.js
new file mode 100644 (file)
index 0000000..5a8c327
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ro', {\r
+       armenian: 'Numerotare armeniană',\r
+       bulletedTitle: 'Proprietățile listei cu simboluri',\r
+       circle: 'Cerc',\r
+       decimal: 'Decimale (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimale cu zero în față (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Numerotare georgiană (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Litere mici (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Litere grecești mici (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Cifre romane mici (i, ii, iii, iv, v, etc.)',\r
+       none: 'Nimic',\r
+       notset: '<nesetat>',\r
+       numberedTitle: 'Proprietățile listei numerotate',\r
+       square: 'Pătrat',\r
+       start: 'Start',\r
+       type: 'Tip',\r
+       upperAlpha: 'Litere mari (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Cifre romane mari (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Începutul listei trebuie să fie un număr întreg.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ru.js b/sources/plugins/liststyle/lang/ru.js
new file mode 100644 (file)
index 0000000..5bfa8c6
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ru', {\r
+       armenian: 'Армянская нумерация',\r
+       bulletedTitle: 'Свойства маркированного списка',\r
+       circle: 'Круг',\r
+       decimal: 'Десятичные (1, 2, 3, и т.д.)',\r
+       decimalLeadingZero: 'Десятичные с ведущим нулём (01, 02, 03, и т.д.)',\r
+       disc: 'Окружность',\r
+       georgian: 'Грузинская нумерация (ани, бани, гани, и т.д.)',\r
+       lowerAlpha: 'Строчные латинские (a, b, c, d, e, и т.д.)',\r
+       lowerGreek: 'Строчные греческие (альфа, бета, гамма, и т.д.)',\r
+       lowerRoman: 'Строчные римские (i, ii, iii, iv, v, и т.д.)',\r
+       none: 'Нет',\r
+       notset: '<не указано>',\r
+       numberedTitle: 'Свойства нумерованного списка',\r
+       square: 'Квадрат',\r
+       start: 'Начиная с',\r
+       type: 'Тип',\r
+       upperAlpha: 'Заглавные латинские (A, B, C, D, E, и т.д.)',\r
+       upperRoman: 'Заглавные римские (I, II, III, IV, V, и т.д.)',\r
+       validateStartNumber: 'Первый номер списка должен быть задан обычным целым числом.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/si.js b/sources/plugins/liststyle/lang/si.js
new file mode 100644 (file)
index 0000000..b401a13
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'si', {\r
+       armenian: 'Armenian numbering', // MISSING\r
+       bulletedTitle: 'Bulleted List Properties', // MISSING\r
+       circle: 'Circle', // MISSING\r
+       decimal: 'Decimal (1, 2, 3, etc.)', // MISSING\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)', // MISSING\r
+       disc: 'Disc', // MISSING\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)', // MISSING\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)', // MISSING\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)', // MISSING\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)', // MISSING\r
+       none: 'කිසිවක්ම නොවේ',\r
+       notset: '<යොදා >',\r
+       numberedTitle: 'Numbered List Properties', // MISSING\r
+       square: 'Square', // MISSING\r
+       start: 'Start', // MISSING\r
+       type: 'වර්ගය',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)', // MISSING\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)', // MISSING\r
+       validateStartNumber: 'List start number must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sk.js b/sources/plugins/liststyle/lang/sk.js
new file mode 100644 (file)
index 0000000..2529c18
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sk', {\r
+       armenian: 'Arménske číslovanie',\r
+       bulletedTitle: 'Vlastnosti odrážkového zoznamu',\r
+       circle: 'Kruh',\r
+       decimal: 'Číselné (1, 2, 3, atď.)',\r
+       decimalLeadingZero: 'Číselné s nulou (01, 02, 03, atď.)',\r
+       disc: 'Disk',\r
+       georgian: 'Gruzínske číslovanie (an, ban, gan, atď.)',\r
+       lowerAlpha: 'Malé latinské (a, b, c, d, e, atď.)',\r
+       lowerGreek: 'Malé grécke (alfa, beta, gama, atď.)',\r
+       lowerRoman: 'Malé rímske (i, ii, iii, iv, v, atď.)',\r
+       none: 'Nič',\r
+       notset: '<nenastavené>',\r
+       numberedTitle: 'Vlastnosti číselného zoznamu',\r
+       square: 'Štvorec',\r
+       start: 'Začiatok',\r
+       type: 'Typ',\r
+       upperAlpha: 'Veľké latinské (A, B, C, D, E, atď.)',\r
+       upperRoman: 'Veľké rímske (I, II, III, IV, V, atď.)',\r
+       validateStartNumber: 'Začiatočné číslo číselného zoznamu musí byť celé číslo.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sl.js b/sources/plugins/liststyle/lang/sl.js
new file mode 100644 (file)
index 0000000..bd6c27f
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sl', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sq.js b/sources/plugins/liststyle/lang/sq.js
new file mode 100644 (file)
index 0000000..6ee94a5
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sq', {\r
+       armenian: 'Numërim armenian',\r
+       bulletedTitle: 'Karakteristikat e Listës me Pulla',\r
+       circle: 'Rreth',\r
+       decimal: 'Decimal (1, 2, 3, etj.)',\r
+       decimalLeadingZero: 'Decimal me zerro udhëheqëse (01, 02, 03, etj.)',\r
+       disc: 'Disk',\r
+       georgian: 'Numërim gjeorgjian (an, ban, gan, etj.)',\r
+       lowerAlpha: 'Të vogla alfa (a, b, c, d, e, etj.)',\r
+       lowerGreek: 'Të vogla greke (alpha, beta, gamma, etj.)',\r
+       lowerRoman: 'Të vogla romake (i, ii, iii, iv, v, etj.)',\r
+       none: 'Asnjë',\r
+       notset: '<e pazgjedhur>',\r
+       numberedTitle: 'Karakteristikat e Listës me Numra',\r
+       square: 'Katror',\r
+       start: 'Fillimi',\r
+       type: 'LLoji',\r
+       upperAlpha: 'Të mëdha alfa (A, B, C, D, E, etj.)',\r
+       upperRoman: 'Të mëdha romake (I, II, III, IV, V, etj.)',\r
+       validateStartNumber: 'Numri i fillimit të listës duhet të është numër i plotë.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sr-latn.js b/sources/plugins/liststyle/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..75d1cfa
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sr-latn', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sr.js b/sources/plugins/liststyle/lang/sr.js
new file mode 100644 (file)
index 0000000..f89a441
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sr', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/sv.js b/sources/plugins/liststyle/lang/sv.js
new file mode 100644 (file)
index 0000000..49bbf48
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'sv', {\r
+       armenian: 'Armenisk numrering',\r
+       bulletedTitle: 'Egenskaper för punktlista',\r
+       circle: 'Cirkel',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal nolla (01, 02, 03, etc.)',\r
+       disc: 'Disk',\r
+       georgian: 'Georgisk numrering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Alpha gemener (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Grekiska gemener (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Romerska gemener (i, ii, iii, iv, v, etc.)',\r
+       none: 'Ingen',\r
+       notset: '<ej angiven>',\r
+       numberedTitle: 'Egenskaper för punktlista',\r
+       square: 'Fyrkant',\r
+       start: 'Start',\r
+       type: 'Typ',\r
+       upperAlpha: 'Alpha versaler (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Romerska versaler (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'Listans startnummer måste vara ett heltal.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/th.js b/sources/plugins/liststyle/lang/th.js
new file mode 100644 (file)
index 0000000..d1425e8
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'th', {\r
+       armenian: 'Armenian numbering',\r
+       bulletedTitle: 'Bulleted List Properties',\r
+       circle: 'Circle',\r
+       decimal: 'Decimal (1, 2, 3, etc.)',\r
+       decimalLeadingZero: 'Decimal leading zero (01, 02, 03, etc.)',\r
+       disc: 'Disc',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)',\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)',\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)',\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)',\r
+       none: 'None',\r
+       notset: '<not set>',\r
+       numberedTitle: 'Numbered List Properties',\r
+       square: 'Square',\r
+       start: 'Start',\r
+       type: 'Type',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)',\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)',\r
+       validateStartNumber: 'List start number must be a whole number.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/tr.js b/sources/plugins/liststyle/lang/tr.js
new file mode 100644 (file)
index 0000000..f08131e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'tr', {\r
+       armenian: 'Ermenice sayılandırma',\r
+       bulletedTitle: 'Simgeli Liste Özellikleri',\r
+       circle: 'Daire',\r
+       decimal: 'Ondalık (1, 2, 3, vs.)',\r
+       decimalLeadingZero: 'Başı sıfırlı ondalık (01, 02, 03, vs.)',\r
+       disc: 'Disk',\r
+       georgian: 'Gürcüce numaralandırma (an, ban, gan, vs.)',\r
+       lowerAlpha: 'Küçük Alpha (a, b, c, d, e, vs.)',\r
+       lowerGreek: 'Küçük Greek (alpha, beta, gamma, vs.)',\r
+       lowerRoman: 'Küçük Roman (i, ii, iii, iv, v, vs.)',\r
+       none: 'Yok',\r
+       notset: '<ayarlanmamış>',\r
+       numberedTitle: 'Sayılandırılmış Liste Özellikleri',\r
+       square: 'Kare',\r
+       start: 'Başla',\r
+       type: 'Tipi',\r
+       upperAlpha: 'Büyük Alpha (A, B, C, D, E, vs.)',\r
+       upperRoman: 'Büyük Roman (I, II, III, IV, V, vs.)',\r
+       validateStartNumber: 'Liste başlangıcı tam sayı olmalıdır.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/tt.js b/sources/plugins/liststyle/lang/tt.js
new file mode 100644 (file)
index 0000000..13991f4
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'tt', {\r
+       armenian: 'Әрмән номерлавы',\r
+       bulletedTitle: 'Маркерлы тезмә үзлекләре',\r
+       circle: 'Түгәрәк',\r
+       decimal: 'Унарлы (1, 2, 3, ...)',\r
+       decimalLeadingZero: 'Ноль белән башланган унарлы (01, 02, 03, ...)',\r
+       disc: 'Диск',\r
+       georgian: 'Georgian numbering (an, ban, gan, etc.)', // MISSING\r
+       lowerAlpha: 'Lower Alpha (a, b, c, d, e, etc.)', // MISSING\r
+       lowerGreek: 'Lower Greek (alpha, beta, gamma, etc.)', // MISSING\r
+       lowerRoman: 'Lower Roman (i, ii, iii, iv, v, etc.)', // MISSING\r
+       none: 'Һичбер',\r
+       notset: '<билгеләнмәгән>',\r
+       numberedTitle: 'Номерлы тезмә үзлекләре',\r
+       square: 'Шакмак',\r
+       start: 'Башлау',\r
+       type: 'Төр',\r
+       upperAlpha: 'Upper Alpha (A, B, C, D, E, etc.)', // MISSING\r
+       upperRoman: 'Upper Roman (I, II, III, IV, V, etc.)', // MISSING\r
+       validateStartNumber: 'List start number must be a whole number.' // MISSING\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/ug.js b/sources/plugins/liststyle/lang/ug.js
new file mode 100644 (file)
index 0000000..2d4336e
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'ug', {\r
+       armenian: 'قەدىمكى ئەرمىنىيە تەرتىپ نومۇرى شەكلى',\r
+       bulletedTitle: 'تۈر بەلگە تىزىم خاسلىقى',\r
+       circle: 'بوش چەمبەر',\r
+       decimal: 'سان (1, 2, 3 قاتارلىق)',\r
+       decimalLeadingZero: 'نۆلدىن باشلانغان سان بەلگە (01, 02, 03 قاتارلىق)',\r
+       disc: 'تولدۇرۇلغان چەمبەر',\r
+       georgian: 'قەدىمكى جورجىيە تەرتىپ نومۇرى شەكلى (an, ban, gan قاتارلىق)',\r
+       lowerAlpha: 'ئىنگلىزچە كىچىك ھەرپ (a, b, c, d, e قاتارلىق)',\r
+       lowerGreek: 'گرېكچە كىچىك ھەرپ (alpha, beta, gamma قاتارلىق)',\r
+       lowerRoman: 'كىچىك ھەرپلىك رىم رەقىمى (i, ii, iii, iv, v قاتارلىق)',\r
+       none: 'بەلگە يوق',\r
+       notset: '‹تەڭشەلمىگەن›',\r
+       numberedTitle: 'تەرتىپ نومۇر تىزىم خاسلىقى',\r
+       square: 'تولدۇرۇلغان تۆت چاسا',\r
+       start: 'باشلىنىش نومۇرى',\r
+       type: 'بەلگە تىپى',\r
+       upperAlpha: 'ئىنگلىزچە چوڭ ھەرپ (A, B, C, D, E قاتارلىق)',\r
+       upperRoman: 'چوڭ ھەرپلىك رىم رەقىمى (I, II, III, IV, V قاتارلىق)',\r
+       validateStartNumber: 'تىزىم باشلىنىش تەرتىپ نومۇرى چوقۇم پۈتۈن سان پىچىمىدا بولۇشى لازىم'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/uk.js b/sources/plugins/liststyle/lang/uk.js
new file mode 100644 (file)
index 0000000..7ef2343
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'uk', {\r
+       armenian: 'Вірменська нумерація',\r
+       bulletedTitle: 'Опції маркованого списку',\r
+       circle: 'Кільце',\r
+       decimal: 'Десяткові (1, 2, 3 і т.д.)',\r
+       decimalLeadingZero: 'Десяткові з нулем (01, 02, 03 і т.д.)',\r
+       disc: 'Кружечок',\r
+       georgian: 'Грузинська нумерація (an, ban, gan і т.д.)',\r
+       lowerAlpha: 'Малі лат. букви (a, b, c, d, e і т.д.)',\r
+       lowerGreek: 'Малі гр. букви (альфа, бета, гамма і т.д.)',\r
+       lowerRoman: 'Малі римські (i, ii, iii, iv, v і т.д.)',\r
+       none: 'Нема',\r
+       notset: '<не вказано>',\r
+       numberedTitle: 'Опції нумерованого списку',\r
+       square: 'Квадратик',\r
+       start: 'Почати з...',\r
+       type: 'Тип',\r
+       upperAlpha: 'Великі лат. букви (A, B, C, D, E і т.д.)',\r
+       upperRoman: 'Великі римські (I, II, III, IV, V і т.д.)',\r
+       validateStartNumber: 'Початковий номер списку повинен бути цілим числом.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/vi.js b/sources/plugins/liststyle/lang/vi.js
new file mode 100644 (file)
index 0000000..c5ecc44
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'vi', {\r
+       armenian: 'Số theo kiểu Armenian',\r
+       bulletedTitle: 'Thuộc tính danh sách không thứ tự',\r
+       circle: 'Khuyên tròn',\r
+       decimal: 'Kiểu số (1, 2, 3 ...)',\r
+       decimalLeadingZero: 'Kiểu số (01, 02, 03...)',\r
+       disc: 'Hình đĩa',\r
+       georgian: 'Số theo kiểu Georgian (an, ban, gan...)',\r
+       lowerAlpha: 'Kiểu abc thường (a, b, c, d, e...)',\r
+       lowerGreek: 'Kiểu Hy Lạp (alpha, beta, gamma...)',\r
+       lowerRoman: 'Số La Mã kiểu thường (i, ii, iii, iv, v...)',\r
+       none: 'Không gì cả',\r
+       notset: '<không thiết lập>',\r
+       numberedTitle: 'Thuộc tính danh sách có thứ tự',\r
+       square: 'Hình vuông',\r
+       start: 'Bắt đầu',\r
+       type: 'Kiểu loại',\r
+       upperAlpha: 'Kiểu ABC HOA (A, B, C, D, E...)',\r
+       upperRoman: 'Số La Mã kiểu HOA (I, II, III, IV, V...)',\r
+       validateStartNumber: 'Số bắt đầu danh sách phải là một số nguyên.'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/zh-cn.js b/sources/plugins/liststyle/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..9d274c2
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'zh-cn', {\r
+       armenian: '传统的亚美尼亚编号方式',\r
+       bulletedTitle: '项目列表属性',\r
+       circle: '空心圆',\r
+       decimal: '数字 (1, 2, 3, 等)',\r
+       decimalLeadingZero: '0开头的数字标记(01, 02, 03, 等)',\r
+       disc: '实心圆',\r
+       georgian: '传统的乔治亚编号方式(an, ban, gan, 等)',\r
+       lowerAlpha: '小写英文字母(a, b, c, d, e, 等)',\r
+       lowerGreek: '小写希腊字母(alpha, beta, gamma, 等)',\r
+       lowerRoman: '小写罗马数字(i, ii, iii, iv, v, 等)',\r
+       none: '无标记',\r
+       notset: '<没有设置>',\r
+       numberedTitle: '编号列表属性',\r
+       square: '实心方块',\r
+       start: '开始序号',\r
+       type: '标记类型',\r
+       upperAlpha: '大写英文字母(A, B, C, D, E, 等)',\r
+       upperRoman: '大写罗马数字(I, II, III, IV, V, 等)',\r
+       validateStartNumber: '列表开始序号必须为整数格式'\r
+} );\r
diff --git a/sources/plugins/liststyle/lang/zh.js b/sources/plugins/liststyle/lang/zh.js
new file mode 100644 (file)
index 0000000..e832518
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'liststyle', 'zh', {\r
+       armenian: '亞美尼亞數字',\r
+       bulletedTitle: '項目符號清單屬性',\r
+       circle: '圓圈',\r
+       decimal: '小數點 (1, 2, 3, etc.)',\r
+       decimalLeadingZero: '前綴 0 十位數字 (01, 02, 03, 等)',\r
+       disc: '圓點',\r
+       georgian: '喬治王時代數字 (an, ban, gan, 等)',\r
+       lowerAlpha: '小寫字母 (a, b, c, d, e 等)',\r
+       lowerGreek: '小寫希臘字母 (alpha, beta, gamma, 等)',\r
+       lowerRoman: '小寫羅馬數字 (i, ii, iii, iv, v 等)',\r
+       none: '無',\r
+       notset: '<未設定>',\r
+       numberedTitle: '編號清單屬性',\r
+       square: '方塊',\r
+       start: '開始',\r
+       type: '類型',\r
+       upperAlpha: '大寫字母 (A, B, C, D, E 等)',\r
+       upperRoman: '大寫羅馬數字 (I, II, III, IV, V 等)',\r
+       validateStartNumber: '清單起始號碼須為一完整數字。'\r
+} );\r
diff --git a/sources/plugins/liststyle/plugin.js b/sources/plugins/liststyle/plugin.js
new file mode 100644 (file)
index 0000000..2d94142
--- /dev/null
@@ -0,0 +1,75 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       CKEDITOR.plugins.liststyle = {\r
+               requires: 'dialog,contextmenu',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               init: function( editor ) {\r
+                       if ( editor.blockless )\r
+                               return;\r
+\r
+                       var def, cmd;\r
+\r
+                       def = new CKEDITOR.dialogCommand( 'numberedListStyle', {\r
+                               requiredContent: 'ol',\r
+                               allowedContent: 'ol{list-style-type}[start]; li{list-style-type}[value]',\r
+                               contentTransformations: [\r
+                                       [ 'ol: listTypeToStyle' ]\r
+                               ]\r
+                       } );\r
+                       cmd = editor.addCommand( 'numberedListStyle', def );\r
+                       editor.addFeature( cmd );\r
+                       CKEDITOR.dialog.add( 'numberedListStyle', this.path + 'dialogs/liststyle.js' );\r
+\r
+                       def = new CKEDITOR.dialogCommand( 'bulletedListStyle', {\r
+                               requiredContent: 'ul',\r
+                               allowedContent: 'ul{list-style-type}',\r
+                               contentTransformations: [\r
+                                       [ 'ul: listTypeToStyle' ]\r
+                               ]\r
+                       } );\r
+                       cmd = editor.addCommand( 'bulletedListStyle', def );\r
+                       editor.addFeature( cmd );\r
+                       CKEDITOR.dialog.add( 'bulletedListStyle', this.path + 'dialogs/liststyle.js' );\r
+\r
+                       //Register map group;\r
+                       editor.addMenuGroup( 'list', 108 );\r
+\r
+                       editor.addMenuItems( {\r
+                               numberedlist: {\r
+                                       label: editor.lang.liststyle.numberedTitle,\r
+                                       group: 'list',\r
+                                       command: 'numberedListStyle'\r
+                               },\r
+                               bulletedlist: {\r
+                                       label: editor.lang.liststyle.bulletedTitle,\r
+                                       group: 'list',\r
+                                       command: 'bulletedListStyle'\r
+                               }\r
+                       } );\r
+\r
+                       editor.contextMenu.addListener( function( element ) {\r
+                               if ( !element || element.isReadOnly() )\r
+                                       return null;\r
+\r
+                               while ( element ) {\r
+                                       var name = element.getName();\r
+                                       if ( name == 'ol' )\r
+                                               return { numberedlist: CKEDITOR.TRISTATE_OFF };\r
+                                       else if ( name == 'ul' )\r
+                                               return { bulletedlist: CKEDITOR.TRISTATE_OFF };\r
+\r
+                                       element = element.getParent();\r
+                               }\r
+                               return null;\r
+                       } );\r
+               }\r
+       };\r
+\r
+       CKEDITOR.plugins.add( 'liststyle', CKEDITOR.plugins.liststyle );\r
+} )();\r
diff --git a/sources/plugins/magicline/dev/magicline.html b/sources/plugins/magicline/dev/magicline.html
new file mode 100644 (file)
index 0000000..077b670
--- /dev/null
@@ -0,0 +1,594 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Magicline muddy trenches &ndash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+       <style>\r
+               body {\r
+                       margin: 0 0 130px;\r
+               }\r
+               #dev {\r
+                       border-top: 1px solid #555;\r
+                       position: fixed;\r
+                       bottom: 0px;\r
+                       left: 0px;\r
+                       right: 0px;\r
+                       height: 110px;\r
+                       background: #B5E5EE;\r
+                       font-size: 15px;\r
+               }\r
+               #dev .hl {\r
+                       color: red;\r
+               }\r
+               #tr_upper, #tr_lower {\r
+                       padding: 3px 6px;\r
+               }\r
+               #tr_upper {\r
+                       background: rgba(255,0,0,.3);\r
+               }\r
+               #tr_lower {\r
+                       background: rgba(0,255,0,.3);\r
+               }\r
+\r
+               #dev p {\r
+                       margin: 0;\r
+                       padding: 0;\r
+               }\r
+\r
+               #timeData,\r
+               #triggerData,\r
+               #mouseData,\r
+               #hiddenData {\r
+                       position: absolute;\r
+               }\r
+               #timeData {\r
+                       right: 10px;\r
+                       top: 10px;\r
+               }\r
+               #hiddenData {\r
+                       right: 10px;\r
+                       top: 40px;\r
+               }\r
+               #mouseData {\r
+                       left: 10px;\r
+                       top: 10px;\r
+               }\r
+               #dev h2 {\r
+                       top: 10px;\r
+                       left: 10px;\r
+               }\r
+               #triggerData {\r
+                       bottom: 10px;\r
+                       left: 10px;\r
+               }\r
+       </style>\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               CKEditor Sample &mdash; magicline muddy trenches\r
+       </h1>\r
+\r
+       <h2>Various cases</h2>\r
+       <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+               <div style="padding: 20px; background: gray; width: 300px" class="1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim.</div>\r
+               <div style="background: violet; padding: 30px" class="static">Position static</div>\r
+               <dl class="2">\r
+                       <dt>Key</dt><dd>Value</dd>\r
+               </dl>\r
+               <div>Whatever</div>\r
+               <hr id="hr">\r
+               <div style="\r
+                       display: block;\r
+                       cursor: pointer;\r
+                       background: green;\r
+                       height: 50px; width: 50px;" >aasd\r
+               </div>\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <hr>\r
+               <hr>\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <table border="1" class="first">\r
+                       <tbody><tr>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>\r
+                                       Table Cell 2<br>\r
+                                       Table Cell 2<br>\r
+                               </td>\r
+                       </tr>\r
+                       </tbody>\r
+               </table>\r
+               <div style="border: 1px solid red; padding: 50px">\r
+                       Parent\r
+                       <div style="border: 10px solid green; padding: 10px">Child</div>\r
+               </div>\r
+               I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body.\r
+               I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body. I'm in a body.\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <table border="1" style="margin: 15px 0 100px"  class="outer">\r
+                       <tbody>\r
+                       <tr>\r
+                               <td>Table Cell 1</td>\r
+                               <td>Table Cell 1</td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>\r
+                                       <table border="10" class="inner">\r
+                                               <tbody>\r
+                                                       <tr>\r
+                                                               <td>Table Cell 1</td>\r
+                                                       </tr>\r
+                                                       <tr>\r
+                                                               <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                                                       </tr>\r
+                                               </tbody>\r
+                                       </table>\r
+                               </td>\r
+                       </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1" style="margin: 15px"  class="third">\r
+                       <tbody><tr>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>\r
+                                       Table Cell 2\r
+                               </td>\r
+                       </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1" style="margin: 15px"  class="fourth">\r
+                       <tbody><tr>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                               <td>\r
+                                       Table Cell 1\r
+                               </td>\r
+                       </tr>\r
+                       <tr>\r
+                               <td>\r
+                                       Table Cell 2\r
+                               </td>\r
+                       </tr>\r
+                       </tbody>\r
+               </table>\r
+               <ul style=""  class="fifth">\r
+                       <li name="ul_first">List item</li>\r
+                       <li name="ul_second">\r
+                               <ol style="">\r
+                                       <li name="ol_first">Nested item</li>\r
+                                       <li>Nested item</li>\r
+                                       <li>Nested item</li>\r
+                               </ol>\r
+                       </li>\r
+                       <li>List item</li>\r
+               </ul>\r
+               <table border="1" class="table#123">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1" align="right"  class="aligned">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1" style="float: right" class="floated">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1" align=""class="table#124">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <table border="1"class="table#125">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <p> enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas male</p>\r
+               <table border="1"class="table#126">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>Table Cell 1</td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>Table Cell 2<br> Table Cell 2<br></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <div style="background: orange; margin: 20px">Upper div</div>\r
+               <table style="background: blue; margin: 20px"><tr><td>Lower table</td></tr></table>\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <div><strong>I'm a div. Let me stay here.</strong></div><dl>\r
+                       <dt>Key</dt>\r
+                       <dd>pendisse a pellentesque dui, non felis</dd>\r
+                       <dt>Key</dt>\r
+                       <dd>pendisse a pellentesque dui, non felis</dd>\r
+               </dl>\r
+               <div class="11" style="padding: 20px; background: pink; width: 400px">\r
+                       Parent\r
+                       <div class="12" style="padding: 20px; background: orange">\r
+                               <!-- comment -->\r
+                               <!-- another comment -->\r
+                               <div class="13" style="padding: 20px; background: green">\r
+                                       Child#2\r
+                               </div>\r
+                       </div>\r
+               </div>\r
+       </textarea>\r
+\r
+       <h2>Odd case: first (last) element at the very beginning, short editable</h2>\r
+       <textarea cols="80" id="editor2" name="editor1a" rows="10">\r
+               <table border="1" style="width: 300px">\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>\r
+                                               Test</td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+       </textarea>\r
+\r
+       <h2>Large document, put everywhere</h2>\r
+       <textarea id="editor3">\r
+               <p><div class="navbar" align="center" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><a accesskey="p" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">previous</a>   <a accesskey="n" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/idl-definitions.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">next</a>   <a accesskey="c" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/Overview.html#contents" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">contents</a>   <a accesskey="i" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/def-index.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">index</a><hr title="Navigation area separator"></div><div class="noprint" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;text-align: right;"><p style="font-family: monospace;font-size: small;">13 November, 2000</p></div><div class="div1" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><a id="Range" name="Range"></a><h1 id="Range-h1" class="div1" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 27px;font-weight: normal; background-color: violet">2. Document Object Model Range</h1><dl style="background: green"><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><i>Editors</i></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Peter Sharpe, SoftQuad Software Inc.</dd><dd style="margin-top: 0px;margin-bottom: 0px;">Vidur Apparao, Netscape Communications Corp.</dd><dd style="margin-top: 0px;margin-bottom: 0px;">Lauren Wood, SoftQuad Software Inc.</dd></dl><div class="noprint"><h2 id="table-of-contents" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">Table of contents</h2><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-introduction" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.1. Introduction</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Definitions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial; background: red">2.2. Definitions and Notation</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Position" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.1. Position</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Containment" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.2. Selection and Partial Selection</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Notation" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.2.3. Notation</a></li></ul></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Creating" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.3. Creating a Range</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Changing" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.4. Changing a Range's Position</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Comparing" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.5. Comparing Range Boundary-Points</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Deleting-Content" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.6. Deleting Content with a Range</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Extracting" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.7. Extracting Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Cloning" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.8. Cloning Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Inserting" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.9. Inserting Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Surrounding" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.10. Surrounding Content</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Misc" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.11. Miscellaneous Members</a></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Mutation" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12. Range modification under document mutation</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Insertions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12.1. Insertions</a></li><li class="tocline4" style="font-style: italic;"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Deletions" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.12.2. Deletions</a></li></ul></li><li class="tocline3"><a class="tocxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-Interface" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">2.13. Formal Description of the Range Interface</a><ul class="toc" style="list-style-type: none;list-style-position: initial;list-style-image: initial;"><li class="tocline4" style="font-style: italic;"><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">Range</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-DocumentRange-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DocumentRange</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">RangeException</a>, <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeExceptionCode" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">RangeExceptionCode</a></li></ul></li></ul></div><div class="div2"><a id="Level-2-Range-introduction" name="Level-2-Range-introduction"></a><h2 id="Level-2-Range-introduction-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.1. Introduction</h2><p>A Range identifies a range of content in a Document, DocumentFragment or Attr. It is contiguous in the sense that it can be characterized as selecting all of the content between a pair of boundary-points.</p><p><b>Note:</b> In a text editor or a word processor, a user can make a selection by pressing down the mouse at one point in a document, moving the mouse to another point, and releasing the mouse. The resulting selection is contiguous and consists of the content between the two points.</p><p>The term 'selecting' does not mean that every Range corresponds to a selection made by a GUI user;however, such a selection can be returned to a DOM user as a Range.</p><p><b>Note:</b> In bidirectional writing (Arabic, Hebrew), a range may correspond to a logical selection that is not necessarily contiguous when displayed. A visually contiguous selection, also used in some cases, may not correspond to a single logical selection, and may therefore have to be represented by more than one range.</p><p>The Range interface provides methods for accessing and manipulating the document tree at a higher level than similar methods in the Node interface. The expectation is that each of the methods provided by the Range interface for the insertion, deletion and copying of content can be directly mapped to a series of Node editing operations enabled by DOM Core. In this sense, the Range operations can be viewed as convenience methods that also enable the implementation to optimize common editing patterns.</p><p>This chapter describes the Range interface, including methods for creating and moving a Range and methods for manipulating content with Ranges.</p><p>The interfaces found within this section are not mandatory. A DOM application may use the <code>hasFeature(feature, version)</code> method of the <code>DOMImplementation</code> interface with parameter values "Range" and "2.0" (respectively) to determine whether or not this module is supported by the implementation. In order to fully support this module, an implementation must also support the "Core" feature defined defined in the DOM Level 2 Core specification [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>]. Please refer to additional information about <a href="http://www.w3.org/TR/DOM-Level-2-Core/introduction.html#ID-Conformance" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>conformance</em></a> in the DOM Level 2 Core specification [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>].</p></div><div class="div2" style="background: blue;"><a id="Level-2-Range-Definitions" name="Level-2-Range-Definitions"></a><h2 id="Level-2-Range-Definitions-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal; background: red">2.2. Definitions and Notation</h2><div style="background: yellow" class="div3"><a id="Level-2-Range-Position" name="Level-2-Range-Position"></a><h3 id="Level-2-Range-Position-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.1. Position</h3><p>This chapter refers to two different representations of a document: the text or source form that includes the document markup and the tree representation similar to the one described in the introduction section of the DOM Level 2 Core [<a class="noxref" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/references.html#DOMCore" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">DOM Level 2 Core</a>].</p><p>A Range consists of two <i>boundary-points</i> corresponding to the start and the end of the Range. <a id="td-boundarypoint" name="td-boundarypoint"></a>A boundary-point's position in a Document or DocumentFragment tree can be characterized by a node and an offset. <a id="td-container" name="td-container"></a>The node is called the <i>container</i> of the boundary-point and of its position. <a id="td-ancestor-container" name="td-ancestor-container"></a>The container and its ancestors are the <i>ancestor container</i>s of the boundary-point and of its position.<a id="td-offset" name="td-offset"></a>The offset within the node is called the <i>offset</i> of the boundary-point and its position. If the container is an Attr, Document, DocumentFragment, Element or EntityReference node, the offset is between its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-child" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>child</em></a> nodes. If the container is a CharacterData, Comment or ProcessingInstruction node, the offset is between the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> of the UTF-16 encoded string contained by it.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of a Range must have a common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> which is either a Document, DocumentFragment or Attr node. That is, the content of a Range must be entirely within the subtree rooted by a single Document, DocumentFragment or Attr Node. <a id="td-root-container" name="td-root-container"></a>This common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> is known as the <i>root container</i> of the Range. <a id="td-context-tree" name="td-context-tree"></a>The tree rooted by the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a> is known as the Range's <i>context tree</i>.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range must be an Element, Comment, ProcessingInstruction, EntityReference, CDATASection, Document, DocumentFragment, Attr, or Text node. None of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a>s of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range can be a DocumentType, Entity or Notation node.</p><p>In terms of the text representation of a document, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of a Range can only be on token boundaries. That is, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the text range cannot be in the middle of a start- or end-tag of an element or within the name of an entity or character reference. A Range locates a contiguous portion of the content of the structure model.</p><p>The relationship between locations in a text representation of the document and in the Node tree interface of the DOM is illustrated in the following diagram:<br></p><div align="center"><hr width="90%" size="2"><img src="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/images/RangeExample.gif" alt="Range Example"><hr width="90%" size="2"><b>Range Example</b><hr width="90%" size="2"></div><p>In this diagram, four different Ranges are illustrated. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-points</em></a> of each Range are labelled with <i>s#</i> (the start of the Range) and <i>e#</i> (the end of the Range), where # is the number of the Range. For Range 2, the start is in the BODY element and is immediately after the H1 element and immediately before the P element, so its position is between the H1 and P children of BODY. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> whose <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is not a CharacterData node is 0 if it is before the first child, 1 if between the first and second child, and so on. So, for the start of the Range 2, the<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is BODY and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is 1. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> whose <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is a CharacterData node is obtained similarly but using <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a> positions instead. For example, the<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> labelled s1 of the Range 1 has a Text node (the one containing "Title") as its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of 2 since it is between the second and third <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a>.</p><p>Notice that the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of Ranges 3 and 4 correspond to the same location in the text representation. An important feature of the Range is that a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of a Range can unambiguously represent every position within the document tree.</p><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a>s of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s can be obtained through the following read-only Range attributes:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute Node startContainer;readonly attribute long startOffset;readonly attribute Node endContainer;readonly attribute long endOffset;</pre></div><p><a id="td-collapsed" name="td-collapsed"></a>If the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of a Range have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a>s, the Range is said to be a <i>collapsed</i> Range. (This is often referred to as an insertion point in a user agent.)</p></div><div class="div3"><a id="Level-2-Range-Containment" name="Level-2-Range-Containment"></a><h3 id="Level-2-Range-Containment-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.2. Selection and Partial Selection</h3><p><a id="td-selected" name="td-selected"></a>A node or <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit unit</em></a> unit is said to be <i>selected</i> by a Range if it is between the two <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of the Range, that is, if the position immediately before the node or 16-bit unit is before the end of the Range and the position immediately after the node or 16-bit unit is after the start of the range. For example, in terms of a text representation of the document, an element would be <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selected</em></a>by a Range if its corresponding start-tag was located after the start of the Range and its end-tag was located before the end of the Range. In the examples in the above diagram, the Range 2<a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selects</em></a> the P node and the Range 3 <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selects</em></a> the text node containing the text "Blah xyz."</p><p><a id="td-partially-selected" name="td-partially-selected"></a>A node is said to be <i>partially selected</i> by a Range if it is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of exactly one <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range. For example, consider Range 1 in the above diagram. The element H1 is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by that Range since the start of the Range is within one of its children.</p></div><div class="div3"><a id="Level-2-Range-Notation" name="Level-2-Range-Notation"></a><h3 id="Level-2-Range-Notation-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.2.3. Notation</h3><p>Many of the examples in this chapter are illustrated using a text representation of a document. The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s of a Range are indicated by displaying the characters (be they markup or data characters) between the two <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s in bold, as in</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>BC<BAR>DE</b>F</BAR></FOO></pre></div><p>When both <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s are at the same position, they are indicated with a bold caret ('<b>^</b>'), as in</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>^</b>BC<BAR>DEF</BAR></FOO></pre></div></div></div><div class="div2"><a id="Level-2-Range-Creating" name="Level-2-Range-Creating"></a><h2 id="Level-2-Range-Creating-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.3. Creating a Range</h2><p>A Range is created by calling the <code>createRange()</code> method on the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-DocumentRange-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>DocumentRange</code></a> interface. This interface can be obtained from the object implementing the <code>Document</code> interface using binding-specific casting methods.</p><div class="eg"><pre style="margin-left: 2em;"> interface DocumentRange{Range createRange();}</pre></div><p>The initial state of the Range returned from this method is such that both of its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a>s are positioned at the beginning of the corresponding Document, before any content. In other words, the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of each <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> is the Document node and the offset within that node is 0.</p><p>Like some objects created using methods in the Document interface (such as Nodes and DocumentFragments), Ranges created via a particular document instance can select only content associated with that Document, or with DocumentFragments and Attrs for which that Document is the <code>ownerDocument</code>. Such Ranges, then, can not be used with other Document instances.</p></div><div class="div2"><a id="Level-2-Range-Changing" name="Level-2-Range-Changing"></a><h2 id="Level-2-Range-Changing-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.4. Changing a Range's Position</h2><p>A Range's position can be specified by setting the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of each boundary-point with the <code>setStart</code> and <code>setEnd</code> methods.</p><div class="eg"><pre style="margin-left: 2em;"> void setStart(in Node parent, in long offset) raises(RangeException);void setEnd(in Node parent, in long offset) raises(RangeException);</pre></div><p>If one boundary-point of a Range is set to have a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a> other than the current one for the Range, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to the new position. This enforces the restriction that both boundary-points of a Range must have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a>.</p><p>The start position of a Range is guaranteed to never be after the end position. To enforce this restriction, if the start is set to be at a position after the end, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to that position. Similarly, if the end is set to be at a position before the start, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to that position.</p><p>It is also possible to set a Range's position relative to nodes in the tree:</p><div class="eg"><pre style="margin-left: 2em;"> void setStartBefore(in Node node);raises(RangeException);void setStartAfter(in Node node);raises(RangeException);void setEndBefore(in Node node);raises(RangeException);void setEndAfter(in Node node);raises(RangeException);</pre></div><p>The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-parent" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>parent</em></a> of the node becomes the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> and the Range is subject to the same restrictions as given above in the description of <code>setStart()</code>and <code>setEnd()</code>.</p><p>A Range can be <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to either boundary-point:</p><div class="eg"><pre style="margin-left: 2em;"> void collapse(in boolean toStart);</pre></div><p>Passing <code>TRUE</code> as the parameter <code>toStart</code> will <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapse</em></a> the Range to its start, <code>FALSE</code> to its end.</p><p>Testing whether a Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> can be done by examining the <code>collapsed</code> attribute:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute boolean collapsed;</pre></div><p>The following methods can be used to make a Range select the contents of a node or the node itself.</p><div class="eg"><pre style="margin-left: 2em;"> void selectNode(in Node n);void selectNodeContents(in Node n);</pre></div><p>The following examples demonstrate the operation of the methods <code>selectNode</code> and <code>selectNodeContents</code>:</p><div class="eg"><pre style="margin-left: 2em;">Before:  <b>^</b><BAR><FOO>A<MOO>B</MOO>C</FOO></BAR>After Range.selectNodeContents(FOO):  <BAR><FOO><b>A<MOO>B</MOO>C</b></FOO></BAR>(In this case, FOO is the parent of both boundary-points)After Range.selectNode(FOO):<BAR><b><FOO>A<MOO>B</MOO>C</FOO></b></BAR></pre></div></div><div class="div2"><a id="Level-2-Range-Comparing" name="Level-2-Range-Comparing"></a><h2 id="Level-2-Range-Comparing-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.5. Comparing Range Boundary-Points</h2><p>It is possible to compare two Ranges by comparing their boundary-points:</p><div class="eg"><pre style="margin-left: 2em;"> short compareBoundaryPoints(in CompareHow how, in Range sourceRange) raises(RangeException);</pre></div><p>where <code>CompareHow</code> is one of four values: <code>START_TO_START</code>, <code>START_TO_END</code>, <code>END_TO_END</code> and <code>END_TO_START</code>. The return value is -1, 0 or 1 depending on whether the corresponding boundary-point of the Range is before, equal to, or after the corresponding boundary-point of <code>sourceRange</code>. An exception is thrown if the two Ranges have different <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a>s.</p><p>The result of comparing two boundary-points (or positions) is specified below. An informal but not always correct specification is that an boundary-point is before, equal to, or after another if it corresponds to a location in a text representation before, equal to, or after the other's corresponding location.</p><p><a id="td-comparison" name="td-comparison"></a>Let A and B be two boundary-points or positions. Then one of the following holds: A is <i>before</i> B, A is <i>equal to</i> B, or A is <i>after</i> B. Which one holds is specified in the following by examining four cases:</p><p>In the first case the boundary-points have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>. A is <i>before</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B, A is <i>equal to</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is equal to the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B, and A is <i>after</i> B if its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> is greater than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B.</p><p>In the second case a child node C of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of A is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of B. In this case, A is <i>before</i> B if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of A is less than or equal to the index of the child node C and A is <i>after</i>B otherwise.</p><p>In the third case a child node C of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of B is an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of A. In this case, A is <i>before</i> B if the index of the child node C is less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of B and A is <i>after</i> B otherwise.</p><p>In the fourth case, none of three other cases hold: the containers of A and B are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-sibling" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>siblings</em></a> or <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-descendant" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>descendants</em></a> of sibling nodes. In this case, A is <i>before</i> B if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of A is before the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of B in a pre-order traversal of the Ranges' <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> and A is <i>after</i> B otherwise.</p><p>Note that because the same location in a text representation of the document can correspond to two different positions in the DOM tree, it is possible for two boundary-points to not compare equal even though they would be equal in the text representation. For this reason, the informal definition above can sometimes be incorrect.</p></div><div class="div2"><a id="Level-2-Range-Deleting-Content" name="Level-2-Range-Deleting-Content"></a><h2 id="Level-2-Range-Deleting-Content-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.6. Deleting Content with a Range</h2><p>One can delete the contents selected by a Range with:</p><div class="eg"><pre style="margin-left: 2em;"> void deleteContents();</pre></div><p><code>deleteContents()</code> deletes all nodes and characters selected by the Range. All other nodes and characters remain in the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> of the Range. Some examples of this deletion operation are:</p><div class="eg"><pre style="margin-left: 2em;">(1) <FOO>A<b>B<MOO>CD</MOO></b>CD</FOO>--><FOO>A<b>^</b>CD</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(2) <FOO>A<MOO>B<b>C</MOO>D</b>E</FOO>--><FOO>A<MOO>B</MOO><b>^</b>E</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(3) <FOO>X<b>Y<BAR>Z</b>W</BAR>Q</FOO>--><FOO>X<b>^</b><BAR>W</BAR>Q</FOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(4) <FOO><BAR1>A<b>B</BAR1><BAR2/><BAR3>C</b>D</BAR3></FOO>--><FOO><BAR1>A</BAR1><b>^</b><BAR3>D</BAR3></pre></div><p>After <code>deleteContents()</code> is invoked on a Range, the Range is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a>. If no node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range, then it is <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a> to its original start point, as in example (1). If a node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range and was an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the start of the Range and no <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-ancestor" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor</em></a> of the node satisfies these two conditions, then the Range is collapsed to the position immediately after the node, as in examples (2) and (4). If a node was <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range and was an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the end of the Range and no ancestor of the node satisfies these two conditions, then the Range is collapsed to the position immediately before the node, as in examples (3) and (4).</p><p>Note that if deletion of a Range leaves adjacent Text nodes, they are not automatically merged, and empty Text nodes are not automatically removed. Two Text nodes should be joined only if each is the container of one of the boundary-points of a Range whose contents are deleted. To merge adjacent Text nodes, or remove empty text nodes, the <code>normalize()</code> method on the <code>Node</code>interface should be used.</p></div><div class="div2"><a id="Level-2-Range-Extracting" name="Level-2-Range-Extracting"></a><h2 id="Level-2-Range-Extracting-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.7. Extracting Content</h2><p>If the contents of a Range need to be extracted rather than deleted, the following method may be used:</p><div class="eg"><pre style="margin-left: 2em;"> DocumentFragment extractContents();</pre></div><p>The <code>extractContents()</code> method removes nodes from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> similarly to the <code>deleteContents()</code> method. In addition, it places the deleted contents in a new <code>DocumentFragment</code>. The following examples illustrate the contents of the returned DocumentFragment:</p><div class="eg"><pre style="margin-left: 2em;">(1) <FOO>A<b>B<MOO>CD</MOO></b>CD</FOO>-->B<MOO>CD</MOO></pre></div><div class="eg"><pre style="margin-left: 2em;">(2) <FOO>A<MOO>B<b>C</MOO>D</b>E</FOO>--><MOO>C<MOO>D</pre></div><div class="eg"><pre style="margin-left: 2em;">(3) <FOO>X<b>Y<BAR>Z</b>W</BAR>Q</FOO>-->Y<BAR>Z</BAR></pre></div><div class="eg"><pre style="margin-left: 2em;">(4)<FOO><BAR1>A<b>B</BAR1><BAR2/><BAR3>C</b>D</BAR3></FOO>--><BAR1>B</BAR1><BAR2/><BAR3>C</BAR3></pre></div><p>It is important to note that nodes that are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> by the Range are cloned. Since part of such a node's contents must remain in the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> and part of the contents must be moved to the new DocumentFragment, a clone of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selected</em></a> node is included in the new DocumentFragment. Note that cloning does not take place for <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>selected</em></a> elements;these nodes are moved to the new DocumentFragment.</p></div><div class="div2"><a id="Level-2-Range-Cloning" name="Level-2-Range-Cloning"></a><h2 id="Level-2-Range-Cloning-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.8. Cloning Content</h2><p>The contents of a Range may be duplicated using the following method:</p><div class="eg"><pre style="margin-left: 2em;"> DocumentFragment cloneContents();</pre></div><p>This method returns a <code>DocumentFragment</code> that is similar to the one returned by the method <code>extractContents()</code>. However, in this case, the original nodes and character data in the Range are not removed from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a>. Instead, all of the nodes and text content within the returned <code>DocumentFragment</code> are cloned.</p></div><div class="div2"><a id="Level-2-Range-Inserting" name="Level-2-Range-Inserting"></a><h2 id="Level-2-Range-Inserting-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.9. Inserting Content</h2><p>A node may be inserted into a Range using the following method:</p><div class="eg"><pre style="margin-left: 2em;"> void insertNode(in Node n) raises(RangeException);</pre></div><p>The <code>insertNode()</code> method inserts the specified node into the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a>. The node is inserted at the start <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range, without modifying it.</p><p>If the start boundary point of the Range is in a <code>Text</code> node, the <code>insertNode</code> operation splits the <code>Text</code> node at the boundary point. If the node to be inserted is also a <code>Text</code> node, the resulting adjacent<code>Text</code> nodes are not normalized automatically;this operation is left to the application.</p><p>The Node passed into this method can be a <code>DocumentFragment</code>. In that case, the contents of the <code>DocumentFragment</code> are inserted at the start <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-boundarypoint" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>boundary-point</em></a> of the Range, but the <code>DocumentFragment</code>itself is not. Note that if the Node represents the root of a sub-tree, the entire sub-tree is inserted.</p><p>The same rules that apply to the <code>insertBefore()</code> method on the Node interface apply here. Specifically, the Node passed in, if it already has a parent, will be removed from its existing position.</p></div><div class="div2"><a id="Level-2-Range-Surrounding" name="Level-2-Range-Surrounding"></a><h2 id="Level-2-Range-Surrounding-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.10. Surrounding Content</h2><p>The insertion of a single node to subsume the content selected by a Range can be performed with:</p><div class="eg"><pre style="margin-left: 2em;"> void surroundContents(in Node newParent);</pre></div><p>The <code>surroundContents()</code> method causes all of the content selected by the Range to be rooted by the specified node. The nodes may not be Attr, Entity, DocumentType, Notation, Document, or DocumentFragment nodes. Calling <code>surroundContents()</code> with the Element node FOO in the following examples yields:</p><div class="eg"><pre style="margin-left: 2em;"> Before:       <BAR>A<b>B<MOO>C</MOO>D</b>E</BAR>After surroundContents(FOO):<BAR>A<b><FOO>B<MOO>C</MOO>D</FOO></b>E</BAR></pre></div><p>Another way of describing the effect of this method on the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-context-tree" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>context tree</em></a> is to decompose it in terms of other operations:</p><ol><li>Remove the contents selected by the Range with a call to <code>extractContents()</code>.</li><li>Insert the node <code>newParent</code> where the Range is collapsed (after the extraction) with <code>insertNode().</code></li><li>Insert the entire contents of the extracted DocumentFragment into <code>newParent</code>. Specifically, invoke the <code>appendChild()</code> on <code>newParent</code> passing in the DocumentFragment returned as a result of the call to <code>extractContents()</code></li><li>Select <code>newParent</code> and all of its contents with <code>selectNode()</code>.</li></ol><p>The <code>surroundContents()</code> method raises an exception if the Range <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selects</em></a> a non-Text node. An example of a Range for which <code>surroundContents()</code>raises an exception is:</p><div class="eg"><pre style="margin-left: 2em;"> <FOO>A<b>B<BAR>C</b>D</BAR>E</FOO></pre></div><p>If the node <code>newParent</code> has any children, those children are removed before its insertion. Also, if the node <code>newParent</code> already has a parent, it is removed from the original parent's <code>childNodes</code> list.</p></div><div class="div2"><a id="Level-2-Range-Misc" name="Level-2-Range-Misc"></a><h2 id="Level-2-Range-Misc-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.11. Miscellaneous Members</h2><p>One can clone a Range:</p><div class="eg"><pre style="margin-left: 2em;"> Range cloneRange();</pre></div><p>This creates a new Range which selects exactly the same content as that selected by the Range on which the method <code>cloneRange</code> was invoked. No content is affected by this operation.</p><p>Because the boundary-points of a Range do not necessarily have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>s, use:</p><div class="eg"><pre style="margin-left: 2em;"> readonly attribute Node commonAncestorContainer;</pre></div><p>to get the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of both boundary-points that is furthest down from the Range's <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-root-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>root container</em></a></p><p>One can get a copy of all the character data selected or partially selected by a Range with:</p><div class="eg"><pre style="margin-left: 2em;"> DOMString toString();</pre></div><p>This does nothing more than simply concatenate all the character data selected by the Range. This includes character data in both <code>Text</code> and <code>CDATASection</code> nodes.</p></div><div class="div2"><a id="Level-2-Range-Mutation" name="Level-2-Range-Mutation"></a><h2 id="Level-2-Range-Mutation-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.12. Range modification under document mutation</h2><p>As a document is modified, the Ranges within the document need to be updated. For example, if one boundary-point of a Range is within a node and that node is removed from the document, then the Range would be invalid unless it is fixed up in some way. This section describes how Ranges are modified under document mutations so that they remain valid.</p><p>There are two general principles which apply to Ranges under document mutation: The first is that all Ranges in a document will remain valid after any mutation operation and the second is that, as much as possible, all Ranges will select the same portion of the document after any mutation operation.</p><p>Any mutation of the document tree which affect Ranges can be considered to be a combination of basic deletion and insertion operations. In fact, it can be convenient to think of those operations as being accomplished using the <code>deleteContents()</code> and <code>insertNode()</code> Range methods and, in the case of Text mutations, the <code>splitText()</code> and <code>normalize()</code> methods.</p><div class="div3"><a id="Level-2-Range-Insertions" name="Level-2-Range-Insertions"></a><h3 id="Level-2-Range-Insertions-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.12.1. Insertions</h3><p>An insertion occurs at a single point, the insertion point, in the document. For any Range in the document tree, consider each boundary-point. The only case in which the boundary-point will be changed after the insertion is when the boundary-point and the insertion point have the same <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the insertion point is strictly less than the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the Range's boundary-point. In that case the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the Range's boundary-point will be increased so that it is between the same nodes or characters as it was before the insertion.</p><p>Note that when content is inserted at a boundary-point, it is ambiguous as to where the boundary-point should be repositioned if its relative position is to be maintained. There are two possibilities: at the start or at the end of the newly inserted content. We have chosen that in this case neither the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> nor <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-offset" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>offset</em></a> of the boundary-point is changed. As a result, the boundary-point will be positioned at the start of the newly inserted content.</p><p><em>Examples:</em></p><p>Suppose the Range selects the following:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd efgh X<b>Y blah i</b>jkl</P></pre></div><p>Consider the insertion of the text "<i>inserted text</i>" at the following positions:</p><div class="eg"><pre style="margin-left: 2em;">1. Before the 'X':<P>Abcd efgh <i>inserted text</i>X<b>Y blah i</b>jkl</P>2. After the 'X':<P>Abcd efgh X<b><i>inserted text</i>Y blah i</b>jkl</P>3. After the 'Y':<P>Abcd efgh X<b>Y<i>inserted text</i> blah i</b>jkl</P>4. After the 'h' in "Y blah":<P>Abcd efgh X<b>Y blah<i>inserted text</i> i</b>jkl</P></pre></div></div><div class="div3"><a id="Level-2-Range-Deletions" name="Level-2-Range-Deletions"></a><h3 id="Level-2-Range-Deletions-h3" class="div3" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 19px;font-weight: normal;">2.12.2. Deletions</h3><p>Any deletion from the document tree can be considered as a sequence of <code>deleteContents()</code> operations applied to a minimal set of disjoint Ranges. To specify how a Range is modified under deletions we need only consider what happens to a Range under a single <code>deleteContents()</code>operation of another Range. And, in fact, we need only consider what happens to a single boundary-point of the Range since both boundary-points are modified using the same algorithm.</p><p>If a boundary-point of the original Range is within the content being deleted, then after the deletion it will be at the same position as the resulting boundary-point of the (now <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-collapsed" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>collapsed</em></a>) Range used to delete the contents.</p><p>If a boundary-point is after the content being deleted then it is not affected by the deletion unless its <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> is also the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of one of the boundary-points of the Range being deleted. If there is such a common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>, then the index of the boundary-point is modified so that the boundary-point maintains its position relative to the content of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>.</p><p>If a boundary-point is before the content being deleted then it is not affected by the deletion at all.</p><p><em>Examples:</em></p><p>In these examples, the Range on which <code>deleteContents()</code>is invoked is indicated by the underline.</p><p><em>Example 1.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u>efgh T</u><b><u>he</u> Range i</b>jkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>Range i</b>jkl</P></pre></div><p><em>Example 2.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><p>Abcd <u>efgh T<b>he Range i</b>j</u>kl</p></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><p>Abcd <b>^</b>kl</p></pre></div><p><em>Example 3.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>ABCD <u>efgh T</u><b><u>he <EM>R</u>ange</b></EM>ijkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>ABCD <EM><b>ange</b></EM>ijkl</P></pre></div><p>In this example, the container of the start boundary-point after the deletion is the Text node holding the string "ange".</p><p><em>Example 4.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u>efgh T</u><b>he Range i</b>jkl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>he Range i</b>jkl</P></pre></div><p><em>Example 5.</em></p><p>Before:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <u><EM>efgh T<b>he Range i</b>j</EM></u>kl</P></pre></div><p>After:</p><div class="eg"><pre style="margin-left: 2em;"><P>Abcd <b>^</b>kl</P></pre></div></div></div><div class="div2"><a id="Level-2-Range-Interface" name="Level-2-Range-Interface"></a><h2 id="Level-2-Range-Interface-h2" class="div2" style="text-align: left;color: rgb(0, 90, 156);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: white;font-size: 22px;font-weight: normal;">2.13. Formal Description of the Range Interface</h2><p>To summarize, the complete, formal description of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a> interface is given below:</p><dl ><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Interface <i><a id="Level-2-Range-idl" name="Level-2-Range-idl">Range</a></i></b> (introduced in <b class="since">DOM Level 2</b>)</dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:interface Range{readonly attribute Node             startContainer;// raises(DOMException) on retrieval  readonly attribute long             startOffset;// raises(DOMException) on retrieval  readonly attribute Node             endContainer;// raises(DOMException) on retrieval  readonly attribute long             endOffset;// raises(DOMException) on retrieval  readonly attribute boolean          collapsed;// raises(DOMException) on retrieval  readonly attribute Node             commonAncestorContainer;// raises(DOMException) on retrieval  void               setStart(in Node refNode, in long offset) raises(RangeException, DOMException);void               setEnd(in Node refNode, in long offset) raises(RangeException, DOMException);void               setStartBefore(in Node refNode) raises(RangeException, DOMException);void               setStartAfter(in Node refNode) raises(RangeException, DOMException);void               setEndBefore(in Node refNode) raises(RangeException, DOMException);void               setEndAfter(in Node refNode) raises(RangeException, DOMException);void               collapse(in boolean toStart) raises(DOMException);void               selectNode(in Node refNode) raises(RangeException, DOMException);void               selectNodeContents(in Node refNode) raises(RangeException, DOMException);// CompareHow  const unsigned short      START_TO_START=0;const unsigned short      START_TO_END=1;const unsigned short      END_TO_END=2;const unsigned short      END_TO_START=3;short              compareBoundaryPoints(in unsigned short how, in Range sourceRange) raises(DOMException);void               deleteContents() raises(DOMException);DocumentFragment   extractContents() raises(DOMException);DocumentFragment   cloneContents() raises(DOMException);void               insertNode(in Node newNode) raises(DOMException, RangeException);void               surroundContents(in Node newParent) raises(DOMException, RangeException);Range              cloneRange() raises(DOMException);DOMString          toString() raises(DOMException);void               detach() raises(DOMException);};</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Definition group <i><a id="Level2-Range-compareHow" name="Level2-Range-compareHow">CompareHow</a></i></b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>Passed as a parameter to the <code>compareBoundaryPoints</code> method.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Defined Constants</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">END_TO_END</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare end boundary-point of <code>sourceRange</code> to end boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">END_TO_START</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare end boundary-point of <code>sourceRange</code> to start boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">START_TO_END</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare start boundary-point of <code>sourceRange</code> to end boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">START_TO_START</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Compare start boundary-point of <code>sourceRange</code> to start boundary-point of Range on which <code>compareBoundaryPoints</code> is invoked.</dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Attributes</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-collapsed" name="Level-2-Range-attr-collapsed">collapsed</a></code> of type <code>boolean</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">TRUE if the Range is collapsed<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-commonParent" name="Level-2-Range-attr-commonParent">commonAncestorContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-deepest" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>deepest</em></a> common <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the Range's two boundary-points.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-endParent" name="Level-2-Range-attr-endParent">endContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node within which the Range ends<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-endOffset" name="Level-2-Range-attr-endOffset">endOffset</a></code> of type <code>long</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Offset within the ending node of the Range.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-startParent" name="Level-2-Range-attr-startParent">startContainer</a></code> of type <code>Node</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node within which the Range begins<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="attribute-name" style="background-color: rgb(255, 255, 210);"><a id="Level-2-Range-attr-startOffset" name="Level-2-Range-attr-startOffset">startOffset</a></code> of type <code>long</code>, readonly</dt><dd style="margin-top: 0px;margin-bottom: 0px;">Offset within the starting node of the Range.<br><div class="exceptions"><b>Exceptions on retrieval</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Methods</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-cloneContents" name="Level2-Range-method-cloneContents">cloneContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Duplicates the contents of a Range<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DocumentFragment</code></p></td><td><p>A DocumentFragment that contains content equivalent to this Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-clone" name="Level2-Range-method-clone">cloneRange</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Produces a new Range whose boundary-points are equal to the boundary-points of the Range.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></p></td><td><p>The duplicated Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-collapse" name="Level2-Range-method-collapse">collapse</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Collapse a Range onto one of its boundary-points<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">toStart</code> of type <code>boolean</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If TRUE, collapses the Range onto its start;if FALSE, collapses it onto its end.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-compareBoundaryPoints" name="Level2-Range-method-compareBoundaryPoints">compareBoundaryPoints</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Compare the boundary-points of two Ranges in a document.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">how</code> of type <code>unsigned short</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">A code representing the type of comparison, as defined above.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">sourceRange</code> of type <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>Range</code> on which this current <code>Range</code> is compared to.<br></dd></dl></div></div><div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>short</code></p></td><td><p>-1, 0 or 1 depending on whether the corresponding boundary-point of the Range is respectively before, equal to, or after the corresponding boundary-point of<code>sourceRange</code>.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>WRONG_DOCUMENT_ERR: Raised if the two Ranges are not in the same Document or DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-deleteContents" name="Level2-Range-method-deleteContents">deleteContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Removes the contents of a Range from the containing document or document fragment without returning a reference to the removed content.<div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes that contain any of the content of the Range are read-only.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-detach" name="Level2-Range-method-detach">detach</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Called to indicate that the Range is no longer in use and that the implementation may relinquish any resources associated with this Range. Subsequent calls to any methods or attribute getters on this Range will result in a <code>DOMException</code> being thrown with an error code of <code>INVALID_STATE_ERR</code>.<div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-extractContents" name="Level2-Range-method-extractContents">extractContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Moves the contents of a Range from the containing document or document fragment to a new DocumentFragment.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DocumentFragment</code></p></td><td><p>A DocumentFragment containing the extracted contents.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if any portion of the content of the Range is read-only or any of the nodes which contain any of the content of the Range are read-only.</p><p>HIERARCHY_REQUEST_ERR: Raised if a DocumentType node would be extracted into the new DocumentFragment.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-insertNode" name="Level2-Range-method-insertNode">insertNode</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Inserts a node into the Document or DocumentFragment at the start of the Range. If the container is a Text node, this will be split at the start of the Range (as if the Text node's splitText method was performed at the insertion point) and the insertion will occur between the two resulting Text nodes. Adjacent Text nodes will not be automatically merged. If the node to be inserted is a DocumentFragment node, the children will be inserted rather than the DocumentFragment node itself.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">newNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to insert at the start of the Range<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of the start of the Range is read-only.</p><p>WRONG_DOCUMENT_ERR: Raised if <code>newNode</code> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range were not created from the same document.</p><p>HIERARCHY_REQUEST_ERR: Raised if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range is of a type that does not allow children of the type of <code>newNode</code> or if <code>newNode</code>is an ancestor of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a>.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>newNode</code> is an Attr, Entity, Notation, or Document node.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-selectNode" name="Level2-Range-method-selectNode">selectNode</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Select a node and its contents<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to select.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if an ancestor of <code>refNode</code> is an Entity, Notation or DocumentType node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-selectNodeContents" name="Level2-Range-method-selectNodeContents">selectNodeContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Select the contents within a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Node to select from<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEnd" name="Level2-Range-method-setEnd">setEnd</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the attributes describing the end of a Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>refNode</code> value. This parameter must be different from <code>null</code>.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">offset</code> of type <code>long</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>endOffset</code> value.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation, or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater than the number of child units in <code>refNode</code>. Child units are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> if <code>refNode</code> is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction node. Child units are Nodes in all other cases.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEndAfter" name="Level2-Range-method-setEndAfter">setEndAfter</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the end of a Range to be after a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range ends after <code>refNode</code>.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setEndBefore" name="Level2-Range-method-setEndBefore">setEndBefore</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the end position to be before a node.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range ends before <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setStart" name="Level2-Range-method-setStart">setStart</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the attributes describing the start of the Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>refNode</code> value. This parameter must be different from <code>null</code>.<br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">offset</code> of type <code>long</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The <code>startOffset</code> value.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if <code>refNode</code> or an ancestor of <code>refNode</code> is an Entity, Notation, or DocumentType node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INDEX_SIZE_ERR: Raised if <code>offset</code> is negative or greater than the number of child units in <code>refNode</code>. Child units are <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/glossary.html#dt-16-bit-unit" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>16-bit units</em></a> if <code>refNode</code> is a type of CharacterData node (e.g., a Text or Comment node) or a ProcessingInstruction node. Child units are Nodes in all other cases.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-setStartAfter" name="Level2-Range-method-setStartAfter">setStartAfter</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the start position to be after a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range starts after <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-setStartBefore" name="Level2-Range-setStartBefore">setStartBefore</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Sets the start position to be before a node<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">refNode</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">Range starts before <code>refNode</code><br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>INVALID_NODE_TYPE_ERR: Raised if the root container of <code>refNode</code> is not an Attr, Document, or DocumentFragment node or if <code>refNode</code> is a Document, DocumentFragment, Attr, Entity, or Notation node.</p></td></tr><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-surroundContents" name="Level2-Range-method-surroundContents">surroundContents</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Reparents the contents of the Range to the given node and inserts the node at the position of the start of the Range.<div class="parameters"><b>Parameters</b><div class="paramtable" style="margin-left: 1em;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="parameter-name" style="background-color: rgb(254, 230, 248);">newParent</code> of type <code>Node</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">The node to surround the contents with.<br></dd></dl></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>NO_MODIFICATION_ALLOWED_ERR: Raised if an <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-ancestor-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>ancestor container</em></a> of either boundary-point of the Range is read-only.</p><p>WRONG_DOCUMENT_ERR: Raised if <code>newParent</code> and the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range were not created from the same document.</p><p>HIERARCHY_REQUEST_ERR: Raised if the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of the start of the Range is of a type that does not allow children of the type of <code>newParent</code> or if<code>newParent</code> is an ancestor of the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> or if <code>node</code> would end up with a child node of a type not allowed by the type of <code>node</code>.</p><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a></p></td><td><p>BAD_BOUNDARYPOINTS_ERR: Raised if the Range <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-partially-selected" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>partially selects</em></a> a non-text node.</p><p>INVALID_NODE_TYPE_ERR: Raised if <code>node</code> is an Attr, Entity, DocumentType, Notation, Document, or DocumentFragment node.</p></td></tr></tbody></table></div></div><div><b>No Return Value</b></div></div></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-Range-method-toString" name="Level2-Range-method-toString">toString</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">Returns the contents of a Range as a string. This string contains only the data characters, not any markup.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMString</code></p></td><td><p>The contents of the Range.</p></td></tr></tbody></table></div></div><div class="exceptions"><b>Exceptions</b><div class="exceptiontable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the exception, the second contains the specific error code and a short description" border="0"><tbody><tr><td valign="top"><p><code>DOMException</code></p></td><td><p>INVALID_STATE_ERR: Raised if <code>detach()</code> has already been invoked on this object.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div></div></dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Interface <i><a id="Level-2-DocumentRange-idl" name="Level-2-DocumentRange-idl">DocumentRange</a></i></b> (introduced in <b class="since">DOM Level 2</b>)</dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:interface DocumentRange{Range              createRange();};</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Methods</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="method-name" style="background-color: rgb(217, 230, 248);"><a id="Level2-DocumentRange-method-createRange" name="Level2-DocumentRange-method-createRange">createRange</a></code></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="method">This interface can be obtained from the object implementing the <code>Document</code> interface using binding-specific casting methods.<div class="return"><b>Return Value</b><div class="returntable" style="margin-left: 1em;"><table summary="Layout table: the first cell contains the type of the return value, the second contains a short description" border="0"><tbody><tr><td valign="top"><p><a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#Level-2-Range-idl" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>Range</code></a></p></td><td><p>The initial state of the Range returned from this method is such that both of its boundary-points are positioned at the beginning of the corresponding Document, before any content. The Range returned can only be used to select content associated with this Document, or with DocumentFragments and Attrs for which this Document is the <code>ownerDocument</code>.</p></td></tr></tbody></table></div></div><div><b>No Parameters</b></div><div><b>No Exceptions</b></div></div></dd></dl></dd></dl></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Exception <i><a id="RangeException" name="RangeException">RangeException</a></i></b> introduced in <b class="version">DOM Level 2</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>Range operations may throw a <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#RangeException" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><code>RangeException</code></a> as specified in their method descriptions.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><br><b>IDL Definition</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><div class="idl-code" style="font-family: monospace;border-top-width: 1px;border-right-width: 1px;border-bottom-width: 1px;border-left-width: 1px;border-top-style: solid;border-right-style: solid;border-bottom-style: solid;border-left-style: solid;border-top-color: black;border-right-color: black;border-bottom-color: black;border-left-color: black;border-image: initial;white-space: pre;background-color: rgb(223, 223, 223);"><pre style="margin-left: 2em;">// Introduced in DOM Level 2:exception RangeException{unsigned short   code;};// RangeExceptionCodeconst unsigned short      BAD_BOUNDARYPOINTS_ERR=1;const unsigned short      INVALID_NODE_TYPE_ERR=2;</pre></div><br></dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Definition group <i><a id="RangeExceptionCode" name="RangeExceptionCode">RangeExceptionCode</a></i></b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><p>An integer indicating the type of error generated.</p><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><b>Defined Constants</b></dt><dd style="margin-top: 0px;margin-bottom: 0px;"><dl><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">BAD_BOUNDARYPOINTS_ERR</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If the boundary-points of a Range do not meet specific requirements.</dd><dt style="margin-top: 0px;margin-bottom: 0px;font-weight: bold;"><code class="constant-name" style="background-color: rgb(221, 255, 210);">INVALID_NODE_TYPE_ERR</code></dt><dd style="margin-top: 0px;margin-bottom: 0px;">If the <a href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/ranges.html#td-container" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;"><em>container</em></a> of an boundary-point of a Range is being set to either a node of an invalid type or a node with an ancestor of an invalid type.</dd></dl></dd></dl></dd></dl></dd></dl></div></div><div class="navbar" align="center" style="color: rgb(0, 0, 0);font-family: sans-serif;font-size: medium;"><hr title="Navigation area separator"><a accesskey="p" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/traversal.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">previous</a>   <a accesskey="n" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/idl-definitions.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">next</a>   <a accesskey="c" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/Overview.html#contents" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">contents</a>   <a accesskey="i" href="http://www.w3.org/TR/DOM-Level-2-Traversal-Range/def-index.html" style="color: rgb(102, 0, 153);background-image: initial;background-attachment: initial;background-origin: initial;background-clip: initial;background-color: transparent;background-position: initial initial;background-repeat: initial initial;">index</a></div></p><dl></dl>\r
+       </textarea>\r
+\r
+       <h2>Deeply nested divs</h2>\r
+       <textarea name="editor4">\r
+               <p> </p><h1 id="mainHeader" style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-weight: normal; font-size: 26px; color: rgb(7, 130, 193); font-family: Arial, Helvetica, sans-serif; background-color: rgb(226, 226, 226); ">Jobs</h1><div id="node-438" class="node node-type-page" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 18px; color: rgb(85, 85, 85); font-family: Arial, Helvetica, sans-serif; background-color: rgb(226, 226, 226); "><div class="node-inner" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><div class="meta" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "> </div><div class="content" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><div class="contentBox" style="margin-top: 0px; margin-right: 0px; margin-bottom: 20px; margin-left: 0px; padding-top: 15px; padding-right: 15px; padding-bottom: 1px; padding-left: 15px; border-top-width: 1px; border-right-width: 1px; border-bottom-width: 1px; border-left-width: 1px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; background-color: rgb(239, 239, 239); border-top-style: solid; border-right-style: solid; border-bottom-style: solid; border-left-style: solid; border-top-color: rgb(226, 226, 226); border-right-color: rgb(226, 226, 226); border-bottom-color: rgb(226, 226, 226); border-left-color: rgb(226, 226, 226); position: relative; "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">CKSource is a successful company with thousands of customers all around the world, including top names like IBM and Oracle. Our company is growing fast, with impressive sales results. This strong growth expands our range of opportunities, followed by the growth of our team. Take this chance and&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">join us!</strong></p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Working in a&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">successful Open Source project&nbsp;</strong>is certainly a lot of fun. CKEditor is one of the most frequently used text editors out there, and this success means new responsibilities. We are providing a key component for the software that is powering the Web today. It is downloaded daily by thousands of people all around the world and used by hundreds of thousands out there.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are constantly looking for top-notch, creative, and enthusiastic professionals ready to join our international team.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We offer a work culture where ideas are free to fly and diversity is our everyday life.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">There is no need to relocate. No matter where you are, as long as you love what you do, you are the right person for us!</p><div class="post joboffer" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 5px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); " id=""><h2 style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-size: 15px; color: rgb(0, 0, 0); ">AJD - Advanced JavaScript Developer</h2><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Location:&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Europe and Its Neighbourhood</strong>&nbsp;(from GMT 0 to GMT +2).</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Employment type:&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Full time</strong>.</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are looking for talented people to join our team. Ideal candidates will have:</p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Several years of experience with professional JavaScript programming, which we consider is;<ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Writing pure, object-oriented JavaScript applications.</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Ability to create complex JavaScript applications based on your own skills only (excluding usage of external libraries such as jQuery, Prototype, Dojo, or MooTools).</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Being aware and able to solving asynchronous issues.</li></ul></li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">In-depth knowledge of core Web standards, like HTML, XML, DOM, and CSS — including their intrinsic implementation differences among browsers (with IE6 also);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Ability to understand and fix complicated DOM manipulation problems.</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Good (enough) English speaking and writing skills. This is the language used in the company.</li></ul><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">"Wow" candidates will also have (not required though):</p><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with CKEditor or FCKeditor, having possibly collaborated with the project;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with rich text editors;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with HTML5, CSS3 development;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Experience with Test Cases (like YUI Test);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">A Bachelor's or Master's degree in Computer Science;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Passion for Open Source.</li></ul></div><div class="post" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 30px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); " id=""><h3 style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; font-size: 14px; ">In return we offer:</h3><ul style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-right: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Permanent full time employment contract;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Flexible working hours;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Competitive salary;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; "><strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Work&nbsp;</strong>from&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">home</strong>&nbsp;(you will forget what a traffic jam is);</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Working with smart and motivated&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">professionals</strong>;</li><li style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 40px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Becoming a&nbsp;<strong style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">part of great team</strong>&nbsp;who delivers worldwide known software.</li></ul><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Let us start talking. Tell us about the projects you have worked on and your role in them; point to your experience and anything you think might make you a perfect candidate. Contact us with your CV at:&nbsp;<a href="" title="jobs at (spam protection) cksource dot com" id="jobmail1" style="color: rgb(24, 157, 225); ">jobs@cksource.com</a>&nbsp;now!</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">We are sure you will enjoy it!</p></div><div class="post" style="margin-top: 0px; margin-right: 0px; margin-bottom: 0px; margin-left: 0px; padding-top: 10px; padding-right: 0px; padding-bottom: 30px; padding-left: 0px; border-top-width: 1px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; border-top-style: solid; border-top-color: rgb(229, 230, 231); "><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">Please note we only accept CV's in English. Your application must include the following note:</p><p style="margin-top: 0px; margin-right: 0px; margin-bottom: 15px; margin-left: 0px; padding-top: 0px; padding-right: 0px; padding-bottom: 0px; padding-left: 0px; border-top-width: 0px; border-right-width: 0px; border-bottom-width: 0px; border-left-width: 0px; border-style: initial; border-color: initial; border-image: initial; line-height: 1.5em; ">"I hereby authorize you to process my personal data included in my job application for the needs of the recruitment process (in accordance to the Personal Data Protection Act 29.08.1997 no 133 position 883).”</p></div></div></div></div></div><dl></dl>\r
+       </textarea>\r
+\r
+       <h2>Line custom look</h2>\r
+       <div id="hood">\r
+               <h1>\r
+                       <img alt="" src="http://a.cksource.com/c/1/inc/img/demo-little-red.jpg" style="margin-left: 10px; margin-right: 10px; float: left; width: 120px; height: 168px;" />Little Red Riding Hood</h1>\r
+               <p>\r
+                       &quot;<b>Little Red Riding Hood</b>&quot; is a famous <a href="http://en.wikipedia.org/wiki/Fairy_tale" title="Fairy tale">fairy tale</a> about a young girl&#39;s encounter with a wolf. The story has been changed considerably in its history and subject to numerous modern adaptations and readings.</p>\r
+               <table align="right" border="1" cellpadding="1" cellspacing="1" style="width: 200px;">\r
+                       <caption>\r
+                               <strong>International Names</strong></caption>\r
+                       <tbody>\r
+                               <tr>\r
+                                       <td>\r
+                                               Chinese</td>\r
+                                       <td>\r
+                                               <i>小紅帽</i></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>\r
+                                               Italian</td>\r
+                                       <td>\r
+                                               <i>Cappuccetto Rosso</i></td>\r
+                               </tr>\r
+                               <tr>\r
+                                       <td>\r
+                                               Spanish</td>\r
+                                       <td>\r
+                                               <i>Caperucita Roja</i></td>\r
+                               </tr>\r
+                       </tbody>\r
+               </table>\r
+               <hr>\r
+               <hr>\r
+               <p>\r
+                       The version most widely known today is based on the <a href="http://en.wikipedia.org/wiki/Brothers_Grimm" title="Brothers Grimm">Brothers Grimm</a> variant. It is about a girl called Little Red Riding Hood, after the red <a href="http://en.wikipedia.org/wiki/Hood_%28headgear%29" title="Hood (headgear)">hooded</a> <a href="http://en.wikipedia.org/wiki/Cape" title="Cape">cape</a> or <a href="http://en.wikipedia.org/wiki/Cloak" title="Cloak">cloak</a> she wears. The girl walks through the woods to deliver food to her sick grandmother.</p>\r
+               <p>\r
+                       A wolf wants to eat the girl but is afraid to do so in public. He approaches the girl, and she na&iuml;vely tells him where she is going. He suggests the girl pick some flowers, which she does. In the meantime, he goes to the grandmother&#39;s house and gains entry by pretending to be the girl. He swallows the grandmother whole, and waits for the girl, disguised as the grandmother.</p>\r
+               <p>\r
+                       When the girl arrives, she notices he looks very strange to be her grandma. In most retellings, this eventually culminates with Little Red Riding Hood saying, &quot;My, what big teeth you have!&quot;<br />\r
+                       To which the wolf replies, &quot;The better to eat you with,&quot; and swallows her whole, too.</p>\r
+               <p>\r
+                       A <a href="http://en.wikipedia.org/wiki/Hunter" title="Hunter">hunter</a>, however, comes to the rescue and cuts the wolf open. Little Red Riding Hood and her grandmother emerge unharmed. They fill the wolf&#39;s body with heavy stones, which drown him when he falls into a well. Other versions of the story have had the grandmother shut in the closet instead of eaten, and some have Little Red Riding Hood saved by the hunter as the wolf advances on her rather than after she is eaten.</p>\r
+               <p>\r
+                       The tale makes the clearest contrast between the safe world of the village and the dangers of the <a href="http://en.wikipedia.org/wiki/Enchanted_forest" title="Enchanted forest">forest</a>, conventional antitheses that are essentially medieval, though no written versions are as old as that.</p>\r
+       </div>\r
+\r
+       <h2>Extreme inline editing</h2>\r
+       <div id="interpret" contenteditable="true" style="left: 123px; outline: 1px solid red; border: 15px solid green; position: relative; top: 30; left: 30px;">\r
+               <div style="padding: 20px; background: gray; width: 300px" class="1">Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies. Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim.</div>\r
+               <div style="background: violet; padding: 30px;" class="static">\r
+                       Position static\r
+                       <div style="background: green; padding: 30px;  border: 14px solid orange">foo</div>\r
+               </div>\r
+               <dl class="2">\r
+                       <dt>Key</dt><dd>Value</dd>\r
+               </dl>\r
+               <div>Whatever</div>\r
+               <hr id="hr">\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <hr>\r
+               <hr>\r
+               <p>Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies</p>\r
+               <div style="background: green; padding: 30px; width: 200px">foo</div>\r
+       </div>\r
+\r
+       <h2>Enter mode: BR</h2>\r
+       <textarea cols="80" id="editor5" name="editor5" rows="10">\r
+               Foo<br />\r
+               <hr style="margin: 50px" />\r
+               <hr style="margin: 50px" />\r
+               Foo\r
+       </textarea>\r
+\r
+       <div id="dev">\r
+               <p id="mouseData">\r
+                       <span>Mouse over: <strong id="over"></strong></span>\r
+                       <span style="display: block">Mouse Y-pos.: <span id="my"></span></span>\r
+               </p>\r
+               <p id="triggerData">\r
+                       <span id="tr_type"></span>\r
+                       <span id="tr_upper"></span>\r
+                       <span id="tr_lower"></span>\r
+                       <span id="tr_edge"></span>\r
+               </dl>\r
+               <p id="timeData">Time: <span id="time"></span></p>\r
+               <p id="hiddenData">Hidden state: <span id="hid"></span></p>\r
+       </div>\r
+       <script>\r
+\r
+               'use strict';\r
+\r
+               function fixedWidthNumber( text, chars ) {\r
+                       return ( Array( chars ).join( 0 ) + text ).slice( -chars );\r
+               }\r
+\r
+               var DEBUG = {\r
+                       startTimer: function() {\r
+                               DEBUG.timer = new Date().getTime();\r
+                       },\r
+\r
+                       stopTimer: (function() {\r
+                               var label = CKEDITOR.document.getById( 'time' ),\r
+                                       max = 0,\r
+                                       count = 0,\r
+                                       values = [],\r
+                                       mean = 0,\r
+                                       time = 0;\r
+\r
+                               return function() {\r
+                                       time = new Date().getTime() - DEBUG.timer;\r
+                                       max = Math.max( time, max );\r
+\r
+                                       values.unshift( time );\r
+                                       ( 20 in values ) && values.pop();\r
+                                       mean = 0;\r
+\r
+                                       for( var i = 0 ; i < values.length ; i++ )\r
+                                               mean += values[ i ];\r
+\r
+                                       mean = mean / i;\r
+\r
+                                       label.setText( fixedWidthNumber( time, 3 ) +\r
+                                               ' ms, mean: ' + fixedWidthNumber( 0 | mean, 3 ) +\r
+                                               ' ms, max: ' + fixedWidthNumber( max, 3 ) +\r
+                                               ' ms' )\r
+                                       count++;\r
+                               }\r
+                       })(),\r
+\r
+                       mousePos: (function( y, element )\r
+                       {\r
+                               var     my = CKEDITOR.document.getById( 'my' ),\r
+                                       over = CKEDITOR.document.getById( 'over' ),\r
+                                       name;\r
+\r
+                               return function( y, element ) {\r
+                                       my.setText( y );\r
+\r
+                                       if( element && element.$ && element.type == CKEDITOR.NODE_ELEMENT ) {\r
+                                               try {\r
+                                                       name = element.getName();\r
+                                                       over.setText( name + '.' + element.getAttribute( 'class' ) );\r
+                                               } catch( e ) {}\r
+                                       }\r
+                                       else\r
+                                               over.setText( '-' );\r
+                               }\r
+                       })(),\r
+\r
+                       showTrigger: (function( trigger )\r
+                       {\r
+                               var tr_type = CKEDITOR.document.getById( 'tr_type' ),\r
+                                       tr_upper = CKEDITOR.document.getById( 'tr_upper' ),\r
+                                       tr_lower = CKEDITOR.document.getById( 'tr_lower' ),\r
+                                       tr_edge = CKEDITOR.document.getById( 'tr_edge' ),\r
+                                       tup, tbo, upper, lower;\r
+\r
+                               return function( trigger ) {\r
+                                       tup && tup.removeAttribute('id') && ( tup = null );\r
+                                       tbo && tbo.removeAttribute('id') && ( tbo = null );\r
+\r
+                                       if ( !trigger )\r
+                                               return  tr_type.setText( '-' ) &&\r
+                                                               tr_upper.setText( '-' ) &&\r
+                                                               tr_lower.setText( '-' ) &&\r
+                                                               tr_edge.setText( '-' );\r
+\r
+                                       upper = trigger.upper,\r
+                                       lower = trigger.lower;\r
+\r
+                                       tr_type.setText( trigger.type == 2 ? 'EXPAND': 'EDGE' );\r
+                                       tr_upper.setText( upper ? upper.getName() + '.' + upper.getAttribute( 'class' ): 'NULL' );\r
+                                       tr_lower.setText( lower ? lower.getName() + '.' + lower.getAttribute( 'class' ): 'NULL' );\r
+                                       tr_edge.setText( trigger.edge ? [ 'EDGE_TOP', 'EDGE_BOTTOM', 'EDGE_MIDDLE' ][ trigger.edge - 1 ]: 'NULL' );\r
+\r
+                                       upper && ( tup = upper ) && tup.setAttribute( 'id', 'tup' );\r
+                                       lower && ( tbo = lower ) && tbo.setAttribute( 'id', 'tbo' );\r
+                               }\r
+                       })(),\r
+\r
+                       showHidden: (function( state )\r
+                       {\r
+                               var     cnt = CKEDITOR.document.getById( 'hid' );\r
+\r
+                               return function( state ) {\r
+                                       cnt[ state ? 'addClass': 'removeClass' ]( 'hl' );\r
+                                       cnt.setText( state ? 'enabled': 'disabled' );\r
+                               }\r
+                       })(),\r
+\r
+                       markElement: function( element ) {\r
+                               if( !isHtml( element ))\r
+                                       return;\r
+\r
+                               DEBUG.marked && DEBUG.marked.setStyles( {\r
+                                       'outline': 'none'\r
+                               } );\r
+\r
+                               DEBUG.marked = element;\r
+\r
+                               element.setStyles( {\r
+                                       'outline': 'red solid 2px'\r
+                               } );\r
+                       },\r
+\r
+                       // Log functions.\r
+                       log: function() {},\r
+                       logElements: function() {},\r
+                       groupStart: function() {},\r
+                       groupEnd: function() {},\r
+                       logEnd: function() {},\r
+                       logElementsEnd: function() {}\r
+               };\r
+\r
+               var logEnable = {\r
+                       log: function() {\r
+                               var args = [];\r
+                               for( var i = 0; i < arguments.length ; i++ )\r
+                                       args.push( arguments[ i ] );\r
+\r
+                               console.log.apply( console, args );\r
+                       },\r
+\r
+                       logElements: function( elements, labels, info ) {\r
+                               var log = {},\r
+                                       label;\r
+\r
+                               for ( var i = 0 ; i < elements.length; i++ ) {\r
+                                       label = labels ? labels [ i ] : i;\r
+\r
+                                       if( !elements[ i ] ) {\r
+                                               log[ label ] = {\r
+                                                       'name': 'null',\r
+                                                       'class': 'null'\r
+                                               }\r
+                                       }\r
+                                       else {\r
+                                               log[ labels ? labels [ i ]: i ] = {\r
+                                                       'name':  elements[ i ].is ? elements[ i ].getName(): 'null',\r
+                                                       'class': elements[ i ].is ? elements[ i ].getAttribute( 'class' ): 'null'\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               typeof JSON != 'undefined' && DEBUG.log( ( info ? info.toUpperCase() + ' ': '' ) + JSON.stringify( log ) );\r
+                       },\r
+\r
+                       groupStart: function( label ) {\r
+                               console.group( label );\r
+                       },\r
+\r
+                       groupEnd: function() {\r
+                               console.groupEnd();\r
+                       },\r
+\r
+                       logEnd: function() {\r
+                               DEBUG.log.apply( null, arguments );\r
+                               DEBUG.groupEnd();\r
+                       },\r
+\r
+                       logElementsEnd: function() {\r
+                               DEBUG.logElements.apply( null, arguments );\r
+                               DEBUG.groupEnd();\r
+                       }\r
+               }\r
+\r
+               // Enable console.log debugging with ?debug address parameter.\r
+               window.location.href.match( /debug$/g ) ? CKEDITOR.tools.extend( DEBUG, logEnable, true ): null;\r
+\r
+               // CKEDITOR.addCss('\\r
+                       //      #tup { outline: #FEB2B2 solid 2px; box-shadow: 3px 3px 0 #FEB2B2; } \\r
+                       //      #tbo { outline: #B2FEB2 solid 2px; box-shadow: 3px 3px 0 #B2FEB2; } \\r
+                       //      p { background: pink }\\r
+               // ');\r
+\r
+               CKEDITOR.replace( 'editor1' );\r
+\r
+               CKEDITOR.replace( 'editor2', { height: 150 } );\r
+\r
+               CKEDITOR.replace( 'editor3', {\r
+                       magicline_everywhere: 1,\r
+                       magicline_holdDistance: .2,\r
+                       language: 'pl'\r
+               });\r
+\r
+               CKEDITOR.replace( 'editor4' );\r
+\r
+               CKEDITOR.replace( 'hood', {\r
+                       magicline_color: 'green'\r
+               });\r
+\r
+               CKEDITOR.replace( 'editor5', {\r
+                       enterMode : CKEDITOR.ENTER_BR\r
+               });\r
+\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/magicline/images/hidpi/icon-rtl.png b/sources/plugins/magicline/images/hidpi/icon-rtl.png
new file mode 100644 (file)
index 0000000..4a8d2bf
Binary files /dev/null and b/sources/plugins/magicline/images/hidpi/icon-rtl.png differ
diff --git a/sources/plugins/magicline/images/hidpi/icon.png b/sources/plugins/magicline/images/hidpi/icon.png
new file mode 100644 (file)
index 0000000..b981bb5
Binary files /dev/null and b/sources/plugins/magicline/images/hidpi/icon.png differ
diff --git a/sources/plugins/magicline/images/icon-rtl.png b/sources/plugins/magicline/images/icon-rtl.png
new file mode 100644 (file)
index 0000000..55b5b5f
Binary files /dev/null and b/sources/plugins/magicline/images/icon-rtl.png differ
diff --git a/sources/plugins/magicline/images/icon.png b/sources/plugins/magicline/images/icon.png
new file mode 100644 (file)
index 0000000..e063433
Binary files /dev/null and b/sources/plugins/magicline/images/icon.png differ
diff --git a/sources/plugins/magicline/lang/af.js b/sources/plugins/magicline/lang/af.js
new file mode 100644 (file)
index 0000000..9b9dc2b
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'af', {\r
+       title: 'Voeg paragraaf hier in'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ar.js b/sources/plugins/magicline/lang/ar.js
new file mode 100644 (file)
index 0000000..1c411f3
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ar', {\r
+       title: 'إدراج فقرة هنا'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/az.js b/sources/plugins/magicline/lang/az.js
new file mode 100644 (file)
index 0000000..02664f1
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'az', {\r
+       title: 'Abzası burada əlavə et'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/bg.js b/sources/plugins/magicline/lang/bg.js
new file mode 100644 (file)
index 0000000..768af06
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'bg', {\r
+       title: 'Вмъкнете параграф тук'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ca.js b/sources/plugins/magicline/lang/ca.js
new file mode 100644 (file)
index 0000000..dcd9c1a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ca', {\r
+       title: 'Insereix el paràgraf aquí'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/cs.js b/sources/plugins/magicline/lang/cs.js
new file mode 100644 (file)
index 0000000..4705efd
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'cs', {\r
+       title: 'zde vložit odstavec'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/cy.js b/sources/plugins/magicline/lang/cy.js
new file mode 100644 (file)
index 0000000..13e1085
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'cy', {\r
+       title: 'Mewnosod paragraff yma'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/da.js b/sources/plugins/magicline/lang/da.js
new file mode 100644 (file)
index 0000000..ee4fa17
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'da', {\r
+       title: 'Indsæt afsnit'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/de-ch.js b/sources/plugins/magicline/lang/de-ch.js
new file mode 100644 (file)
index 0000000..d6bd3b7
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'de-ch', {\r
+       title: 'Absatz hier einfügen'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/de.js b/sources/plugins/magicline/lang/de.js
new file mode 100644 (file)
index 0000000..189d564
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'de', {\r
+       title: 'Absatz hier einfügen'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/el.js b/sources/plugins/magicline/lang/el.js
new file mode 100644 (file)
index 0000000..528a554
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'el', {\r
+       title: 'Εισάγετε παράγραφο εδώ'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/en-gb.js b/sources/plugins/magicline/lang/en-gb.js
new file mode 100644 (file)
index 0000000..e0d3779
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'en-gb', {\r
+       title: 'Insert paragraph here'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/en.js b/sources/plugins/magicline/lang/en.js
new file mode 100644 (file)
index 0000000..37ef2ed
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'en', {\r
+       title: 'Insert paragraph here'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/eo.js b/sources/plugins/magicline/lang/eo.js
new file mode 100644 (file)
index 0000000..3cf6286
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'eo', {\r
+       title: 'Enmeti paragrafon ĉi-tien'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/es.js b/sources/plugins/magicline/lang/es.js
new file mode 100644 (file)
index 0000000..f9a8f52
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'es', {\r
+       title: 'Insertar párrafo aquí'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/et.js b/sources/plugins/magicline/lang/et.js
new file mode 100644 (file)
index 0000000..9d2fe53
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'et', {\r
+       title: 'Sisesta siia lõigu tekst'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/eu.js b/sources/plugins/magicline/lang/eu.js
new file mode 100644 (file)
index 0000000..25daf45
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'eu', {\r
+       title: 'Txertatu paragrafoa hemen'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/fa.js b/sources/plugins/magicline/lang/fa.js
new file mode 100644 (file)
index 0000000..d09ddfc
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'fa', {\r
+       title: 'قرار دادن بند در اینجا'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/fi.js b/sources/plugins/magicline/lang/fi.js
new file mode 100644 (file)
index 0000000..094bd9d
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'fi', {\r
+       title: 'Lisää kappale tähän.'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/fr-ca.js b/sources/plugins/magicline/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..6319f1c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'fr-ca', {\r
+       title: 'Insérer le paragraphe ici'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/fr.js b/sources/plugins/magicline/lang/fr.js
new file mode 100644 (file)
index 0000000..430fc5f
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'fr', {\r
+       title: 'Insérer un paragraphe ici'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/gl.js b/sources/plugins/magicline/lang/gl.js
new file mode 100644 (file)
index 0000000..5aaa968
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'gl', {\r
+       title: 'Inserir aquí o parágrafo'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/he.js b/sources/plugins/magicline/lang/he.js
new file mode 100644 (file)
index 0000000..9c01d48
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'he', {\r
+       title: 'הכנס פסקה כאן'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/hr.js b/sources/plugins/magicline/lang/hr.js
new file mode 100644 (file)
index 0000000..1916e65
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'hr', {\r
+       title: 'Ubaci paragraf ovdje'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/hu.js b/sources/plugins/magicline/lang/hu.js
new file mode 100644 (file)
index 0000000..86650d5
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'hu', {\r
+       title: 'Szúrja be a bekezdést ide'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/id.js b/sources/plugins/magicline/lang/id.js
new file mode 100644 (file)
index 0000000..3651e37
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'id', {\r
+       title: 'Masukkan paragraf disini'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/it.js b/sources/plugins/magicline/lang/it.js
new file mode 100644 (file)
index 0000000..9cc27e0
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'it', {\r
+       title: 'Inserisci paragrafo qui'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ja.js b/sources/plugins/magicline/lang/ja.js
new file mode 100644 (file)
index 0000000..84d6b74
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ja', {\r
+       title: 'ここに段落を挿入'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/km.js b/sources/plugins/magicline/lang/km.js
new file mode 100644 (file)
index 0000000..f670a7e
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'km', {\r
+       title: 'បញ្ចូល​កថាខណ្ឌ​នៅ​ទីនេះ'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ko.js b/sources/plugins/magicline/lang/ko.js
new file mode 100644 (file)
index 0000000..0e718f3
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ko', {\r
+       title: '여기에 단락 삽입'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ku.js b/sources/plugins/magicline/lang/ku.js
new file mode 100644 (file)
index 0000000..cc3f3a4
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ku', {\r
+       title: 'بڕگە لێرە دابنێ'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/lv.js b/sources/plugins/magicline/lang/lv.js
new file mode 100644 (file)
index 0000000..f96cc44
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'lv', {\r
+       title: 'Ievietot šeit rindkopu'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/nb.js b/sources/plugins/magicline/lang/nb.js
new file mode 100644 (file)
index 0000000..297f270
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'nb', {\r
+       title: 'Sett inn nytt avsnitt her'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/nl.js b/sources/plugins/magicline/lang/nl.js
new file mode 100644 (file)
index 0000000..bfe36ff
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'nl', {\r
+       title: 'Hier paragraaf invoeren'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/no.js b/sources/plugins/magicline/lang/no.js
new file mode 100644 (file)
index 0000000..e78ca76
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'no', {\r
+       title: 'Sett inn nytt avsnitt her'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/oc.js b/sources/plugins/magicline/lang/oc.js
new file mode 100644 (file)
index 0000000..312f547
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'oc', {\r
+       title: 'Inserir un paragraf aicí'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/pl.js b/sources/plugins/magicline/lang/pl.js
new file mode 100644 (file)
index 0000000..324bf1e
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'pl', {\r
+       title: 'Wstaw nowy akapit'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/pt-br.js b/sources/plugins/magicline/lang/pt-br.js
new file mode 100644 (file)
index 0000000..35f3daa
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'pt-br', {\r
+       title: 'Insera um parágrafo aqui'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/pt.js b/sources/plugins/magicline/lang/pt.js
new file mode 100644 (file)
index 0000000..c03c48a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'pt', {\r
+       title: 'Insira aqui o parágrafo'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ru.js b/sources/plugins/magicline/lang/ru.js
new file mode 100644 (file)
index 0000000..bc41703
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ru', {\r
+       title: 'Вставить здесь параграф'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/si.js b/sources/plugins/magicline/lang/si.js
new file mode 100644 (file)
index 0000000..a5cdbe8
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'si', {\r
+       title: 'චේදය ඇතුලත් කරන්න'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/sk.js b/sources/plugins/magicline/lang/sk.js
new file mode 100644 (file)
index 0000000..84761b2
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'sk', {\r
+       title: 'Odsek vložiť sem'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/sl.js b/sources/plugins/magicline/lang/sl.js
new file mode 100644 (file)
index 0000000..6d0cf76
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'sl', {\r
+       title: 'Vstavite odstavek tukaj'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/sq.js b/sources/plugins/magicline/lang/sq.js
new file mode 100644 (file)
index 0000000..d405596
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'sq', {\r
+       title: 'Vendos paragraf këtu'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/sv.js b/sources/plugins/magicline/lang/sv.js
new file mode 100644 (file)
index 0000000..63327fd
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'sv', {\r
+       title: 'Infoga paragraf här'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/tr.js b/sources/plugins/magicline/lang/tr.js
new file mode 100644 (file)
index 0000000..02dd216
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'tr', {\r
+       title: 'Parağrafı buraya ekle'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/tt.js b/sources/plugins/magicline/lang/tt.js
new file mode 100644 (file)
index 0000000..7de33bf
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'tt', {\r
+       title: 'Бирегә параграф өстәү'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/ug.js b/sources/plugins/magicline/lang/ug.js
new file mode 100644 (file)
index 0000000..0017fd4
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'ug', {\r
+       title: 'بۇ جايغا ئابزاس قىستۇر'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/uk.js b/sources/plugins/magicline/lang/uk.js
new file mode 100644 (file)
index 0000000..980f0e0
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'uk', {\r
+       title: 'Вставити абзац'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/vi.js b/sources/plugins/magicline/lang/vi.js
new file mode 100644 (file)
index 0000000..b302bd0
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'vi', {\r
+       title: 'Chèn đoạn vào đây'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/zh-cn.js b/sources/plugins/magicline/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..f0a0b3b
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'zh-cn', {\r
+       title: '在这插入段落'\r
+} );\r
diff --git a/sources/plugins/magicline/lang/zh.js b/sources/plugins/magicline/lang/zh.js
new file mode 100644 (file)
index 0000000..3ac9f68
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.setLang( 'magicline', 'zh', {\r
+       title: '在此插入段落'\r
+} );\r
diff --git a/sources/plugins/magicline/plugin.js b/sources/plugins/magicline/plugin.js
new file mode 100644 (file)
index 0000000..ac4bb78
--- /dev/null
@@ -0,0 +1,1874 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The [Magic Line](http://ckeditor.com/addon/magicline) plugin that makes it easier to access some document areas that\r
+ * are difficult to focus.\r
+ */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'magicline', {\r
+               lang: 'af,ar,az,bg,ca,cs,cy,da,de,de-ch,el,en,en-gb,eo,es,et,eu,fa,fi,fr,fr-ca,gl,he,hr,hu,id,it,ja,km,ko,ku,lv,nb,nl,no,oc,pl,pt,pt-br,ru,si,sk,sl,sq,sv,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               init: initPlugin\r
+       } );\r
+\r
+       // Activates the box inside of an editor.\r
+       function initPlugin( editor ) {\r
+               // Configurables\r
+               var config = editor.config,\r
+                       triggerOffset = config.magicline_triggerOffset || 30,\r
+                       enterMode = config.enterMode,\r
+                       that = {\r
+                               // Global stuff is being initialized here.\r
+                               editor: editor,\r
+                               enterMode: enterMode,\r
+                               triggerOffset: triggerOffset,\r
+                               holdDistance: 0 | triggerOffset * ( config.magicline_holdDistance || 0.5 ),\r
+                               boxColor: config.magicline_color || '#ff0000',\r
+                               rtl: config.contentsLangDirection == 'rtl',\r
+                               tabuList: [ 'data-cke-hidden-sel' ].concat( config.magicline_tabuList || [] ),\r
+                               triggers: config.magicline_everywhere ? DTD_BLOCK : { table: 1, hr: 1, div: 1, ul: 1, ol: 1, dl: 1, form: 1, blockquote: 1 }\r
+                       },\r
+                       scrollTimeout, checkMouseTimeoutPending, checkMouseTimer;\r
+\r
+               // %REMOVE_START%\r
+               // Internal DEBUG uses tools located in the topmost window.\r
+\r
+               // (#9701) Due to security limitations some browsers may throw\r
+               // errors when accessing window.top object. Do it safely first then.\r
+               try {\r
+                       that.debug = window.top.DEBUG;\r
+               }\r
+               catch ( e ) {}\r
+\r
+               that.debug = that.debug || {\r
+                       groupEnd: function() {},\r
+                       groupStart: function() {},\r
+                       log: function() {},\r
+                       logElements: function() {},\r
+                       logElementsEnd: function() {},\r
+                       logEnd: function() {},\r
+                       mousePos: function() {},\r
+                       showHidden: function() {},\r
+                       showTrigger: function() {},\r
+                       startTimer: function() {},\r
+                       stopTimer: function() {}\r
+               };\r
+               // %REMOVE_END%\r
+\r
+               // Simple irrelevant elements filter.\r
+               that.isRelevant = function( node ) {\r
+                       return isHtml( node ) && // -> Node must be an existing HTML element.\r
+                               !isLine( that, node ) && // -> Node can be neither the box nor its child.\r
+                               !isFlowBreaker( node ); // -> Node can be neither floated nor positioned nor aligned.\r
+               };\r
+\r
+               editor.on( 'contentDom', addListeners, this );\r
+\r
+               function addListeners() {\r
+                       var editable = editor.editable(),\r
+                               doc = editor.document,\r
+                               win = editor.window;\r
+\r
+                       // Global stuff is being initialized here.\r
+                       extend( that, {\r
+                               editable: editable,\r
+                               inInlineMode: editable.isInline(),\r
+                               doc: doc,\r
+                               win: win,\r
+                               hotNode: null\r
+                       }, true );\r
+\r
+                       // This is the boundary of the editor. For inline the boundary is editable itself.\r
+                       // For classic (`iframe`-based) editor, the HTML element is a real boundary.\r
+                       that.boundary = that.inInlineMode ? that.editable : that.doc.getDocumentElement();\r
+\r
+                       // Enabling the box inside of inline editable is pointless.\r
+                       // There's no need to access spaces inside paragraphs, links, spans, etc.\r
+                       if ( editable.is( dtd.$inline ) )\r
+                               return;\r
+\r
+                       // Handle in-line editing by setting appropriate position.\r
+                       // If current position is static, make it relative and clear top/left coordinates.\r
+                       if ( that.inInlineMode && !isPositioned( editable ) ) {\r
+                               editable.setStyles( {\r
+                                       position: 'relative',\r
+                                       top: null,\r
+                                       left: null\r
+                               } );\r
+                       }\r
+                       // Enable the box. Let it produce children elements, initialize\r
+                       // event handlers and own methods.\r
+                       initLine.call( this, that );\r
+\r
+                       // Get view dimensions and scroll positions.\r
+                       // At this stage (before any checkMouse call) it is used mostly\r
+                       // by tests. Nevertheless it a crucial thing.\r
+                       updateWindowSize( that );\r
+\r
+                       // Remove the box before an undo image is created.\r
+                       // This is important. If we didn't do that, the *undo thing* would revert the box into an editor.\r
+                       // Thanks to that, undo doesn't even know about the existence of the box.\r
+                       editable.attachListener( editor, 'beforeUndoImage', function() {\r
+                               that.line.detach();\r
+                       } );\r
+\r
+                       // Removes the box HTML from editor data string if getData is called.\r
+                       // Thanks to that, an editor never yields data polluted by the box.\r
+                       // Listen with very high priority, so line will be removed before other\r
+                       // listeners will see it.\r
+                       editable.attachListener( editor, 'beforeGetData', function() {\r
+                               // If the box is in editable, remove it.\r
+                               if ( that.line.wrap.getParent() ) {\r
+                                       that.line.detach();\r
+\r
+                                       // Restore line in the last listener for 'getData'.\r
+                                       editor.once( 'getData', function() {\r
+                                               that.line.attach();\r
+                                       }, null, null, 1000 );\r
+                               }\r
+                       }, null, null, 0 );\r
+\r
+                       // Hide the box on mouseout if mouse leaves document.\r
+                       editable.attachListener( that.inInlineMode ? doc : doc.getWindow().getFrame(), 'mouseout', function( event ) {\r
+                               if ( editor.mode != 'wysiwyg' )\r
+                                       return;\r
+\r
+                               // Check for inline-mode editor. If so, check mouse position\r
+                               // and remove the box if mouse outside of an editor.\r
+                               if ( that.inInlineMode ) {\r
+                                       var mouse = {\r
+                                               x: event.data.$.clientX,\r
+                                               y: event.data.$.clientY\r
+                                       };\r
+\r
+                                       updateWindowSize( that );\r
+                                       updateEditableSize( that, true );\r
+\r
+                                       var size = that.view.editable,\r
+                                               scroll = that.view.scroll;\r
+\r
+                                       // If outside of an editor...\r
+                                       if ( !inBetween( mouse.x, size.left - scroll.x, size.right - scroll.x ) || !inBetween( mouse.y, size.top - scroll.y, size.bottom - scroll.y ) ) {\r
+                                               clearTimeout( checkMouseTimer );\r
+                                               checkMouseTimer = null;\r
+                                               that.line.detach();\r
+                                       }\r
+                               }\r
+\r
+                               else {\r
+                                       clearTimeout( checkMouseTimer );\r
+                                       checkMouseTimer = null;\r
+                                       that.line.detach();\r
+                               }\r
+                       } );\r
+\r
+                       // This one deactivates hidden mode of an editor which\r
+                       // prevents the box from being shown.\r
+                       editable.attachListener( editable, 'keyup', function() {\r
+                               that.hiddenMode = 0;\r
+                               that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                       } );\r
+\r
+                       editable.attachListener( editable, 'keydown', function( event ) {\r
+                               if ( editor.mode != 'wysiwyg' )\r
+                                       return;\r
+\r
+                               var keyStroke = event.data.getKeystroke();\r
+\r
+                               switch ( keyStroke ) {\r
+                                       // Shift pressed\r
+                                       case 2228240: // IE\r
+                                       case 16:\r
+                                               that.hiddenMode = 1;\r
+                                               that.line.detach();\r
+                               }\r
+\r
+                               that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                       } );\r
+\r
+                       // This method ensures that checkMouse aren't executed\r
+                       // in parallel and no more frequently than specified in timeout function.\r
+                       // In classic (`iframe`-based) editor, document is used as a trigger, to provide magicline\r
+                       // functionality when mouse is below the body (short content, short body).\r
+                       editable.attachListener( that.inInlineMode ? editable : doc, 'mousemove', function( event ) {\r
+                               checkMouseTimeoutPending = true;\r
+\r
+                               if ( editor.mode != 'wysiwyg' || editor.readOnly || checkMouseTimer )\r
+                                       return;\r
+\r
+                               // IE<9 requires this event-driven object to be created\r
+                               // outside of the setTimeout statement.\r
+                               // Otherwise it loses the event object with its properties.\r
+                               var mouse = {\r
+                                       x: event.data.$.clientX,\r
+                                       y: event.data.$.clientY\r
+                               };\r
+\r
+                               checkMouseTimer = setTimeout( function() {\r
+                                       checkMouse( mouse );\r
+                               }, 30 ); // balances performance and accessibility\r
+                       } );\r
+\r
+                       // This one removes box on scroll event.\r
+                       // It is to avoid box displacement.\r
+                       editable.attachListener( win, 'scroll', function() {\r
+                               if ( editor.mode != 'wysiwyg' )\r
+                                       return;\r
+\r
+                               that.line.detach();\r
+\r
+                               // To figure this out just look at the mouseup\r
+                               // event handler below.\r
+                               if ( env.webkit ) {\r
+                                       that.hiddenMode = 1;\r
+\r
+                                       clearTimeout( scrollTimeout );\r
+                                       scrollTimeout = setTimeout( function() {\r
+                                               // Don't leave hidden mode until mouse remains pressed and\r
+                                               // scroll is being used, i.e. when dragging something.\r
+                                               if ( !that.mouseDown )\r
+                                                       that.hiddenMode = 0;\r
+                                               that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                                       }, 50 );\r
+\r
+                                       that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                               }\r
+                       } );\r
+\r
+                       // Those event handlers remove the box on mousedown\r
+                       // and don't reveal it until the mouse is released.\r
+                       // It is to prevent box insertion e.g. while scrolling\r
+                       // (w/ scrollbar), selecting and so on.\r
+                       editable.attachListener( env_ie8 ? doc : win, 'mousedown', function() {\r
+                               if ( editor.mode != 'wysiwyg' )\r
+                                       return;\r
+\r
+                               that.line.detach();\r
+                               that.hiddenMode = 1;\r
+                               that.mouseDown = 1;\r
+\r
+                               that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                       } );\r
+\r
+                       // Google Chrome doesn't trigger this on the scrollbar (since 2009...)\r
+                       // so it is totally useless to check for scroll finish\r
+                       // see: http://code.google.com/p/chromium/issues/detail?id=14204\r
+                       editable.attachListener( env_ie8 ? doc : win, 'mouseup', function() {\r
+                               that.hiddenMode = 0;\r
+                               that.mouseDown = 0;\r
+                               that.debug.showHidden( that.hiddenMode ); // %REMOVE_LINE%\r
+                       } );\r
+\r
+                       // Editor commands for accessing difficult focus spaces.\r
+                       editor.addCommand( 'accessPreviousSpace', accessFocusSpaceCmd( that ) );\r
+                       editor.addCommand( 'accessNextSpace', accessFocusSpaceCmd( that, true ) );\r
+\r
+                       editor.setKeystroke( [\r
+                               [ config.magicline_keystrokePrevious, 'accessPreviousSpace' ],\r
+                               [ config.magicline_keystrokeNext, 'accessNextSpace' ]\r
+                       ] );\r
+\r
+                       // Revert magicline hot node on undo/redo.\r
+                       editor.on( 'loadSnapshot', function() {\r
+                               var elements, element, i;\r
+\r
+                               for ( var t in { p: 1, br: 1, div: 1 } ) {\r
+                                       // document.find is not available in QM (#11149).\r
+                                       elements = editor.document.getElementsByTag( t );\r
+\r
+                                       for ( i = elements.count(); i--; ) {\r
+                                               if ( ( element = elements.getItem( i ) ).data( 'cke-magicline-hot' ) ) {\r
+                                                       // Restore hotNode\r
+                                                       that.hotNode = element;\r
+                                                       // Restore last access direction\r
+                                                       that.lastCmdDirection = element.data( 'cke-magicline-dir' ) === 'true' ? true : false;\r
+\r
+                                                       return;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       } );\r
+\r
+                       // This method handles mousemove mouse for box toggling.\r
+                       // It uses mouse position to determine underlying element, then\r
+                       // it tries to use different trigger type in order to place the box\r
+                       // in correct place. The following procedure is executed periodically.\r
+                       function checkMouse( mouse ) {\r
+                               that.debug.groupStart( 'CheckMouse' ); // %REMOVE_LINE%\r
+                               that.debug.startTimer(); // %REMOVE_LINE%\r
+\r
+                               that.mouse = mouse;\r
+                               that.trigger = null;\r
+\r
+                               checkMouseTimer = null;\r
+                               updateWindowSize( that );\r
+\r
+                               if (\r
+                                       checkMouseTimeoutPending &&                                                             // There must be an event pending.\r
+                                       !that.hiddenMode &&                                                                             // Can't be in hidden mode.\r
+                                       editor.focusManager.hasFocus &&                                                 // Editor must have focus.\r
+                                       !that.line.mouseNear() &&                                                               // Mouse pointer can't be close to the box.\r
+                                       ( that.element = elementFromMouse( that, true ) )               // There must be valid element.\r
+                               ) {\r
+                                       // If trigger exists, and trigger is correct -> show the box.\r
+                                       // Don't show the line if trigger is a descendant of some tabu-list element.\r
+                                       if ( ( that.trigger = triggerEditable( that ) || triggerEdge( that ) || triggerExpand( that ) ) &&\r
+                                               !isInTabu( that, that.trigger.upper || that.trigger.lower ) ) {\r
+                                               that.line.attach().place();\r
+                                       }\r
+\r
+                                       // Otherwise remove the box\r
+                                       else {\r
+                                               that.trigger = null;\r
+                                               that.line.detach();\r
+                                       }\r
+\r
+                                       that.debug.showTrigger( that.trigger ); // %REMOVE_LINE%\r
+                                       that.debug.mousePos( mouse.y, that.element ); // %REMOVE_LINE%\r
+\r
+                                       checkMouseTimeoutPending = false;\r
+                               }\r
+\r
+                               that.debug.stopTimer(); // %REMOVE_LINE%\r
+                               that.debug.groupEnd(); // %REMOVE_LINE%\r
+                       }\r
+\r
+                       // This one allows testing and debugging. It reveals some\r
+                       // inner methods to the world.\r
+                       this.backdoor = {\r
+                               accessFocusSpace: accessFocusSpace,\r
+                               boxTrigger: boxTrigger,\r
+                               isLine: isLine,\r
+                               getAscendantTrigger: getAscendantTrigger,\r
+                               getNonEmptyNeighbour: getNonEmptyNeighbour,\r
+                               getSize: getSize,\r
+                               that: that,\r
+                               triggerEdge: triggerEdge,\r
+                               triggerEditable: triggerEditable,\r
+                               triggerExpand: triggerExpand\r
+                       };\r
+               }\r
+       }\r
+\r
+       // Some shorthands for common methods to save bytes\r
+       var extend = CKEDITOR.tools.extend,\r
+               newElement = CKEDITOR.dom.element,\r
+               newElementFromHtml = newElement.createFromHtml,\r
+               env = CKEDITOR.env,\r
+               env_ie8 = CKEDITOR.env.ie && CKEDITOR.env.version < 9,\r
+               dtd = CKEDITOR.dtd,\r
+\r
+               // Global object associating enter modes with elements.\r
+               enterElements = {},\r
+\r
+               // Constant values, types and so on.\r
+               EDGE_TOP = 128,\r
+               EDGE_BOTTOM = 64,\r
+               EDGE_MIDDLE = 32,\r
+               TYPE_EDGE = 16,\r
+               TYPE_EXPAND = 8,\r
+               LOOK_TOP = 4,\r
+               LOOK_BOTTOM = 2,\r
+               LOOK_NORMAL = 1,\r
+               WHITE_SPACE = '\u00A0',\r
+               DTD_LISTITEM = dtd.$listItem,\r
+               DTD_TABLECONTENT = dtd.$tableContent,\r
+               DTD_NONACCESSIBLE = extend( {}, dtd.$nonEditable, dtd.$empty ),\r
+               DTD_BLOCK = dtd.$block,\r
+\r
+               // Minimum time that must elapse between two update*Size calls.\r
+               // It prevents constant getComuptedStyle calls and improves performance.\r
+               CACHE_TIME = 100,\r
+\r
+               // Shared CSS stuff for box elements\r
+               CSS_COMMON = 'width:0px;height:0px;padding:0px;margin:0px;display:block;' + 'z-index:9999;color:#fff;position:absolute;font-size: 0px;line-height:0px;',\r
+               CSS_TRIANGLE = CSS_COMMON + 'border-color:transparent;display:block;border-style:solid;',\r
+               TRIANGLE_HTML = '<span>' + WHITE_SPACE + '</span>';\r
+\r
+       enterElements[ CKEDITOR.ENTER_BR ] = 'br';\r
+       enterElements[ CKEDITOR.ENTER_P ] = 'p';\r
+       enterElements[ CKEDITOR.ENTER_DIV ] = 'div';\r
+\r
+       function areSiblings( that, upper, lower ) {\r
+               return isHtml( upper ) && isHtml( lower ) && lower.equals( upper.getNext( function( node ) {\r
+                       return !( isEmptyTextNode( node ) || isComment( node ) || isFlowBreaker( node ) );\r
+               } ) );\r
+       }\r
+\r
+       // boxTrigger is an abstract type which describes\r
+       // the relationship between elements that may result\r
+       // in showing the box.\r
+       //\r
+       // The following type is used by numerous methods\r
+       // to share information about the hypothetical box placement\r
+       // and look by referring to boxTrigger properties.\r
+       function boxTrigger( triggerSetup ) {\r
+               this.upper = triggerSetup[ 0 ];\r
+               this.lower = triggerSetup[ 1 ];\r
+               this.set.apply( this, triggerSetup.slice( 2 ) );\r
+       }\r
+\r
+       boxTrigger.prototype = {\r
+               set: function( edge, type, look ) {\r
+                       this.properties = edge + type + ( look || LOOK_NORMAL );\r
+                       return this;\r
+               },\r
+\r
+               is: function( property ) {\r
+                       return ( this.properties & property ) == property;\r
+               }\r
+       };\r
+\r
+       var elementFromMouse = ( function() {\r
+               function elementFromPoint( doc, mouse ) {\r
+                       var pointedElement = doc.$.elementFromPoint( mouse.x, mouse.y );\r
+\r
+                       // IE9QM: from times to times it will return an empty object on scroll bar hover. (#12185)\r
+                       return pointedElement && pointedElement.nodeType ?\r
+                               new CKEDITOR.dom.element( pointedElement ) :\r
+                               null;\r
+               }\r
+\r
+               return function( that, ignoreBox, forceMouse ) {\r
+                       if ( !that.mouse )\r
+                               return null;\r
+\r
+                       var doc = that.doc,\r
+                               lineWrap = that.line.wrap,\r
+                               mouse = forceMouse || that.mouse,\r
+                               // Note: element might be null.\r
+                               element = elementFromPoint( doc, mouse );\r
+\r
+                       // If ignoreBox is set and element is the box, it means that we\r
+                       // need to hide the box for a while, repeat elementFromPoint\r
+                       // and show it again.\r
+                       if ( ignoreBox && isLine( that, element ) ) {\r
+                               lineWrap.hide();\r
+                               element = elementFromPoint( doc, mouse );\r
+                               lineWrap.show();\r
+                       }\r
+\r
+                       // Return nothing if:\r
+                       //      \-> Element is not HTML.\r
+                       if ( !( element && element.type == CKEDITOR.NODE_ELEMENT && element.$ ) )\r
+                               return null;\r
+\r
+                       // Also return nothing if:\r
+                       //      \-> We're IE<9 and element is out of the top-level element (editable for inline and HTML for classic (`iframe`-based)).\r
+                       //              This is due to the bug which allows IE<9 firing mouse events on element\r
+                       //              with contenteditable=true while doing selection out (far, away) of the element.\r
+                       //              Thus we must always be sure that we stay in editable or HTML.\r
+                       if ( env.ie && env.version < 9 ) {\r
+                               if ( !( that.boundary.equals( element ) || that.boundary.contains( element ) ) )\r
+                                       return null;\r
+                       }\r
+\r
+                       return element;\r
+               };\r
+       } )();\r
+\r
+       // Gets the closest parent node that belongs to triggers group.\r
+       function getAscendantTrigger( that ) {\r
+               var node = that.element,\r
+                       trigger;\r
+\r
+               if ( node && isHtml( node ) ) {\r
+                       trigger = node.getAscendant( that.triggers, true );\r
+\r
+                       // If trigger is an element, neither editable nor editable's ascendant.\r
+                       if ( trigger && that.editable.contains( trigger ) ) {\r
+                               // Check for closest editable limit.\r
+                               // Don't consider trigger as a limit as it may be nested editable (includeSelf=false) (#12009).\r
+                               var limit = getClosestEditableLimit( trigger );\r
+\r
+                               // Trigger in nested editable area.\r
+                               if ( limit.getAttribute( 'contenteditable' ) == 'true' )\r
+                                       return trigger;\r
+                               // Trigger in non-editable area.\r
+                               else if ( limit.is( that.triggers ) )\r
+                                       return limit;\r
+                               else\r
+                                       return null;\r
+                       } else {\r
+                               return null;\r
+                       }\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       function getMidpoint( that, upper, lower ) {\r
+               updateSize( that, upper );\r
+               updateSize( that, lower );\r
+\r
+               var upperSizeBottom = upper.size.bottom,\r
+                       lowerSizeTop = lower.size.top;\r
+\r
+               return upperSizeBottom && lowerSizeTop ? 0 | ( upperSizeBottom + lowerSizeTop ) / 2 : upperSizeBottom || lowerSizeTop;\r
+       }\r
+\r
+       // Get nearest node (either text or HTML), but:\r
+       //      \->     Omit all empty text nodes (containing white characters only).\r
+       //      \-> Omit BR elements\r
+       //      \-> Omit flow breakers.\r
+       function getNonEmptyNeighbour( that, node, goBack ) {\r
+               node = node[ goBack ? 'getPrevious' : 'getNext' ]( function( node ) {\r
+                       return ( isTextNode( node ) && !isEmptyTextNode( node ) ) ||\r
+                               ( isHtml( node ) && !isFlowBreaker( node ) && !isLine( that, node ) );\r
+               } );\r
+\r
+               return node;\r
+       }\r
+\r
+       function inBetween( val, lower, upper ) {\r
+               return val > lower && val < upper;\r
+       }\r
+\r
+       // Returns the closest ancestor that has contenteditable attribute.\r
+       // Such ancestor is the limit of (non-)editable DOM branch that element\r
+       // belongs to. This method omits editor editable.\r
+       function getClosestEditableLimit( element, includeSelf ) {\r
+               if ( element.data( 'cke-editable' ) )\r
+                       return null;\r
+\r
+               if ( !includeSelf )\r
+                       element = element.getParent();\r
+\r
+               while ( element ) {\r
+                       if ( element.data( 'cke-editable' ) )\r
+                               return null;\r
+\r
+                       if ( element.hasAttribute( 'contenteditable' ) )\r
+                               return element;\r
+\r
+                       element = element.getParent();\r
+               }\r
+\r
+               return null;\r
+       }\r
+\r
+       // Access space line consists of a few elements (spans):\r
+       //      \-> Line wrapper.\r
+       //      \-> Line.\r
+       //      \-> Line triangles: left triangle (LT), right triangle (RT).\r
+       //      \-> Button handler (BTN).\r
+       //\r
+       //      +--------------------------------------------------- line.wrap (span) -----+\r
+       //      | +---------------------------------------------------- line (span) -----+ |\r
+       //      | | +- LT \                                           +- BTN -+  / RT -+ | |\r
+       //      | | |      \                                          |     | | /      | | |\r
+       //      | | |      /                                          |  <__| | \      | | |\r
+       //      | | +-----/                                           +-------+  \-----+ | |\r
+       //      | +----------------------------------------------------------------------+ |\r
+       //  +--------------------------------------------------------------------------+\r
+       //\r
+       function initLine( that ) {\r
+               var doc = that.doc,\r
+                       // This the main box element that holds triangles and the insertion button\r
+                       line = newElementFromHtml( '<span contenteditable="false" style="' + CSS_COMMON + 'position:absolute;border-top:1px dashed ' + that.boxColor + '"></span>', doc ),\r
+                       iconPath = CKEDITOR.getUrl( this.path + 'images/' + ( env.hidpi ? 'hidpi/' : '' ) + 'icon' + ( that.rtl ? '-rtl' : '' ) + '.png' );\r
+\r
+               extend( line, {\r
+\r
+                       attach: function() {\r
+                               // Only if not already attached\r
+                               if ( !this.wrap.getParent() )\r
+                                       this.wrap.appendTo( that.editable, true );\r
+\r
+                               return this;\r
+                       },\r
+\r
+                       // Looks are as follows: [ LOOK_TOP, LOOK_BOTTOM, LOOK_NORMAL ].\r
+                       lineChildren: [\r
+                               extend(\r
+                                       newElementFromHtml(\r
+                                               '<span title="' + that.editor.lang.magicline.title +\r
+                                               '" contenteditable="false">&#8629;</span>', doc\r
+                                       ), {\r
+                                               base: CSS_COMMON + 'height:17px;width:17px;' + ( that.rtl ? 'left' : 'right' ) + ':17px;' +\r
+                                                               'background:url(' + iconPath + ') center no-repeat ' + that.boxColor + ';cursor:pointer;' +\r
+                                                               ( env.hc ? 'font-size: 15px;line-height:14px;border:1px solid #fff;text-align:center;' : '' ) +\r
+                                                               ( env.hidpi ? 'background-size: 9px 10px;' : '' ),\r
+                                               looks: [\r
+                                                       'top:-8px; border-radius: 2px;',\r
+                                                       'top:-17px; border-radius: 2px 2px 0px 0px;',\r
+                                                       'top:-1px; border-radius: 0px 0px 2px 2px;'\r
+                                               ]\r
+                                       }\r
+                               ),\r
+                               extend( newElementFromHtml( TRIANGLE_HTML, doc ), {\r
+                                       base: CSS_TRIANGLE + 'left:0px;border-left-color:' + that.boxColor + ';',\r
+                                       looks: [\r
+                                               'border-width:8px 0 8px 8px;top:-8px',\r
+                                               'border-width:8px 0 0 8px;top:-8px',\r
+                                               'border-width:0 0 8px 8px;top:0px'\r
+                                       ]\r
+                               } ),\r
+                               extend( newElementFromHtml( TRIANGLE_HTML, doc ), {\r
+                                       base: CSS_TRIANGLE + 'right:0px;border-right-color:' + that.boxColor + ';',\r
+                                       looks: [\r
+                                               'border-width:8px 8px 8px 0;top:-8px',\r
+                                               'border-width:8px 8px 0 0;top:-8px',\r
+                                               'border-width:0 8px 8px 0;top:0px'\r
+                                       ]\r
+                               } )\r
+                       ],\r
+\r
+                       detach: function() {\r
+                               // Detach only if already attached.\r
+                               if ( this.wrap.getParent() )\r
+                                       this.wrap.remove();\r
+\r
+                               return this;\r
+                       },\r
+\r
+                       // Checks whether mouseY is around an element by comparing boundaries and considering\r
+                       // an offset distance.\r
+                       mouseNear: function() {\r
+                               that.debug.groupStart( 'mouseNear' ); // %REMOVE_LINE%\r
+\r
+                               updateSize( that, this );\r
+                               var offset = that.holdDistance,\r
+                                       size = this.size;\r
+\r
+                               // Determine neighborhood by element dimensions and offsets.\r
+                               if ( size && inBetween( that.mouse.y, size.top - offset, size.bottom + offset ) && inBetween( that.mouse.x, size.left - offset, size.right + offset ) ) {\r
+                                       that.debug.logEnd( 'Mouse is near.' ); // %REMOVE_LINE%\r
+                                       return true;\r
+                               }\r
+\r
+                               that.debug.logEnd( 'Mouse isn\'t near.' ); // %REMOVE_LINE%\r
+                               return false;\r
+                       },\r
+\r
+                       // Adjusts position of the box according to the trigger properties.\r
+                       // If also affects look of the box depending on the type of the trigger.\r
+                       place: function() {\r
+                               var view = that.view,\r
+                                       editable = that.editable,\r
+                                       trigger = that.trigger,\r
+                                       upper = trigger.upper,\r
+                                       lower = trigger.lower,\r
+                                       any = upper || lower,\r
+                                       parent = any.getParent(),\r
+                                       styleSet = {};\r
+\r
+                               // Save recent trigger for further insertion.\r
+                               // It is necessary due to the fact, that that.trigger may\r
+                               // contain different boxTrigger at the moment of insertion\r
+                               // or may be even null.\r
+                               this.trigger = trigger;\r
+\r
+                               upper && updateSize( that, upper, true );\r
+                               lower && updateSize( that, lower, true );\r
+                               updateSize( that, parent, true );\r
+\r
+                               // Yeah, that's gonna be useful in inline-mode case.\r
+                               if ( that.inInlineMode )\r
+                                       updateEditableSize( that, true );\r
+\r
+                               // Set X coordinate (left, right, width).\r
+                               if ( parent.equals( editable ) ) {\r
+                                       styleSet.left = view.scroll.x;\r
+                                       styleSet.right = -view.scroll.x;\r
+                                       styleSet.width = '';\r
+                               } else {\r
+                                       styleSet.left = any.size.left - any.size.margin.left + view.scroll.x - ( that.inInlineMode ? view.editable.left + view.editable.border.left : 0 );\r
+                                       styleSet.width = any.size.outerWidth + any.size.margin.left + any.size.margin.right + view.scroll.x;\r
+                                       styleSet.right = '';\r
+                               }\r
+\r
+                               // Set Y coordinate (top) for trigger consisting of two elements.\r
+                               if ( upper && lower ) {\r
+                                       // No margins at all or they're equal. Place box right between.\r
+                                       if ( upper.size.margin.bottom === lower.size.margin.top )\r
+                                               styleSet.top = 0 | ( upper.size.bottom + upper.size.margin.bottom / 2 );\r
+                                       else {\r
+                                               // Upper margin < lower margin. Place at lower margin.\r
+                                               if ( upper.size.margin.bottom < lower.size.margin.top )\r
+                                                       styleSet.top = upper.size.bottom + upper.size.margin.bottom;\r
+                                               // Upper margin > lower margin. Place at upper margin - lower margin.\r
+                                               else\r
+                                                       styleSet.top = upper.size.bottom + upper.size.margin.bottom - lower.size.margin.top;\r
+                                       }\r
+                               }\r
+                               // Set Y coordinate (top) for single-edge trigger.\r
+                               else if ( !upper )\r
+                                       styleSet.top = lower.size.top - lower.size.margin.top;\r
+                               else if ( !lower ) {\r
+                                       styleSet.top = upper.size.bottom + upper.size.margin.bottom;\r
+                               }\r
+\r
+                               // Set box button modes if close to the viewport horizontal edge\r
+                               // or look forced by the trigger.\r
+                               if ( trigger.is( LOOK_TOP ) || inBetween( styleSet.top, view.scroll.y - 15, view.scroll.y + 5 ) ) {\r
+                                       styleSet.top = that.inInlineMode ? 0 : view.scroll.y;\r
+                                       this.look( LOOK_TOP );\r
+                               } else if ( trigger.is( LOOK_BOTTOM ) || inBetween( styleSet.top, view.pane.bottom - 5, view.pane.bottom + 15 ) ) {\r
+                                       styleSet.top = that.inInlineMode ? (\r
+                                                       view.editable.height + view.editable.padding.top + view.editable.padding.bottom\r
+                                               ) : (\r
+                                                       view.pane.bottom - 1\r
+                                               );\r
+\r
+                                       this.look( LOOK_BOTTOM );\r
+                               } else {\r
+                                       if ( that.inInlineMode )\r
+                                               styleSet.top -= view.editable.top + view.editable.border.top;\r
+\r
+                                       this.look( LOOK_NORMAL );\r
+                               }\r
+\r
+                               if ( that.inInlineMode ) {\r
+                                       // 1px bug here...\r
+                                       styleSet.top--;\r
+\r
+                                       // Consider the editable to be an element with overflow:scroll\r
+                                       // and non-zero scrollTop/scrollLeft value.\r
+                                       // For example: divarea editable. (#9383)\r
+                                       styleSet.top += view.editable.scroll.top;\r
+                                       styleSet.left += view.editable.scroll.left;\r
+                               }\r
+\r
+                               // Append `px` prefixes.\r
+                               for ( var style in styleSet )\r
+                                       styleSet[ style ] = CKEDITOR.tools.cssLength( styleSet[ style ] );\r
+\r
+                               this.setStyles( styleSet );\r
+                       },\r
+\r
+                       // Changes look of the box according to current needs.\r
+                       // Three different styles are available: [ LOOK_TOP, LOOK_BOTTOM, LOOK_NORMAL ].\r
+                       look: function( look ) {\r
+                               if ( this.oldLook == look )\r
+                                       return;\r
+\r
+                               for ( var i = this.lineChildren.length, child; i--; )\r
+                                       ( child = this.lineChildren[ i ] ).setAttribute( 'style', child.base + child.looks[ 0 | look / 2 ] );\r
+\r
+                               this.oldLook = look;\r
+                       },\r
+\r
+                       wrap: new newElement( 'span', that.doc )\r
+\r
+               } );\r
+\r
+               // Insert children into the box.\r
+               for ( var i = line.lineChildren.length; i--; )\r
+                       line.lineChildren[ i ].appendTo( line );\r
+\r
+               // Set default look of the box.\r
+               line.look( LOOK_NORMAL );\r
+\r
+               // Using that wrapper prevents IE (8,9) from resizing editable area at the moment\r
+               // of box insertion. This works thanks to the fact, that positioned box is wrapped by\r
+               // an inline element. So much tricky.\r
+               line.appendTo( line.wrap );\r
+\r
+               // Make the box unselectable.\r
+               line.unselectable();\r
+\r
+               // Handle accessSpace node insertion.\r
+               line.lineChildren[ 0 ].on( 'mouseup', function( event ) {\r
+                       line.detach();\r
+\r
+                       accessFocusSpace( that, function( accessNode ) {\r
+                               // Use old trigger that was saved by 'place' method. Look: line.place\r
+                               var trigger = that.line.trigger;\r
+\r
+                               accessNode[ trigger.is( EDGE_TOP ) ? 'insertBefore' : 'insertAfter' ](\r
+                                       trigger.is( EDGE_TOP ) ? trigger.lower : trigger.upper );\r
+                       }, true );\r
+\r
+                       that.editor.focus();\r
+\r
+                       if ( !env.ie && that.enterMode != CKEDITOR.ENTER_BR )\r
+                               that.hotNode.scrollIntoView();\r
+\r
+                       event.data.preventDefault( true );\r
+               } );\r
+\r
+               // Prevents IE9 from displaying the resize box and disables drag'n'drop functionality.\r
+               line.on( 'mousedown', function( event ) {\r
+                       event.data.preventDefault( true );\r
+               } );\r
+\r
+               that.line = line;\r
+       }\r
+\r
+       // This function allows accessing any focus space according to the insert function:\r
+       //      * For enterMode ENTER_P it creates P element filled with dummy white-space.\r
+       //      * For enterMode ENTER_DIV it creates DIV element filled with dummy white-space.\r
+       //      * For enterMode ENTER_BR it creates BR element or &nbsp; in IE.\r
+       //\r
+       // The node is being inserted according to insertFunction. Finally the method\r
+       // selects the non-breaking space making the node ready for typing.\r
+       function accessFocusSpace( that, insertFunction, doSave ) {\r
+               var range = new CKEDITOR.dom.range( that.doc ),\r
+                       editor = that.editor,\r
+                       accessNode;\r
+\r
+               // IE requires text node of &nbsp; in ENTER_BR mode.\r
+               if ( env.ie && that.enterMode == CKEDITOR.ENTER_BR )\r
+                       accessNode = that.doc.createText( WHITE_SPACE );\r
+\r
+               // In other cases a regular element is used.\r
+               else {\r
+                       // Use the enterMode of editable's limit or editor's\r
+                       // enter mode if not in nested editable.\r
+                       var limit = getClosestEditableLimit( that.element, true ),\r
+\r
+                               // This is an enter mode for the context. We cannot use\r
+                               // editor.activeEnterMode because the focused nested editable will\r
+                               // have a different enterMode as editor but magicline will be inserted\r
+                               // directly into editor's editable.\r
+                               enterMode = limit && limit.data( 'cke-enter-mode' ) || that.enterMode;\r
+\r
+                       accessNode = new newElement( enterElements[ enterMode ], that.doc );\r
+\r
+                       if ( !accessNode.is( 'br' ) ) {\r
+                               var dummy = that.doc.createText( WHITE_SPACE );\r
+                               dummy.appendTo( accessNode );\r
+                       }\r
+               }\r
+\r
+               doSave && editor.fire( 'saveSnapshot' );\r
+\r
+               insertFunction( accessNode );\r
+               //dummy.appendTo( accessNode );\r
+               range.moveToPosition( accessNode, CKEDITOR.POSITION_AFTER_START );\r
+               editor.getSelection().selectRanges( [ range ] );\r
+               that.hotNode = accessNode;\r
+\r
+               doSave && editor.fire( 'saveSnapshot' );\r
+       }\r
+\r
+       // Access focus space on demand by taking an element under the caret as a reference.\r
+       // The space is accessed provided the element under the caret is trigger AND:\r
+       //\r
+       //  1. First/last-child of its parent:\r
+       //              +----------------------- Parent element -+\r
+       //              | +------------------------------ DIV -+ |      <-- Access before\r
+       //              | | Foo^                               | |\r
+       //              | |                                    | |\r
+       //              | +------------------------------------+ |      <-- Access after\r
+       //              +----------------------------------------+\r
+       //\r
+       //                       OR\r
+       //\r
+       //  2. It has a direct sibling element, which is also a trigger:\r
+       //              +-------------------------------- DIV#1 -+\r
+       //              | Foo^                                   |\r
+       //              |                                        |\r
+       //              +----------------------------------------+\r
+       //                                                      <-- Access here\r
+       //              +-------------------------------- DIV#2 -+\r
+       //              | Bar                                    |\r
+       //              |                                        |\r
+       //              +----------------------------------------+\r
+       //\r
+       //                       OR\r
+       //\r
+       //  3. It has a direct sibling, which is a trigger and has a valid neighbour trigger,\r
+       //     but belongs to dtd.$.empty/nonEditable:\r
+       //              +------------------------------------ P -+\r
+       //              | Foo^                                   |\r
+       //              |                                        |\r
+       //              +----------------------------------------+\r
+       //              +----------------------------------- HR -+\r
+       //                                                      <-- Access here\r
+       //              +-------------------------------- DIV#2 -+\r
+       //              | Bar                                    |\r
+       //              |                                        |\r
+       //              +----------------------------------------+\r
+       //\r
+       function accessFocusSpaceCmd( that, insertAfter ) {\r
+               return {\r
+                       canUndo: true,\r
+                       modes: { wysiwyg: 1 },\r
+                       exec: ( function() {\r
+\r
+                               // Inserts line (accessNode) at the position by taking target node as a reference.\r
+                               function doAccess( target ) {\r
+                                       // Remove old hotNode under certain circumstances.\r
+                                       var hotNodeChar = ( env.ie && env.version < 9 ? ' ' : WHITE_SPACE ),\r
+                                               removeOld = that.hotNode &&                                                     // Old hotNode must exist.\r
+                                                       that.hotNode.getText() == hotNodeChar &&                // Old hotNode hasn't been changed.\r
+                                                       that.element.equals( that.hotNode ) &&                  // Caret is inside old hotNode.\r
+                                                       // Command is executed in the same direction.\r
+                                                       that.lastCmdDirection === !!insertAfter; // jshint ignore:line\r
+\r
+                                       accessFocusSpace( that, function( accessNode ) {\r
+                                               if ( removeOld && that.hotNode )\r
+                                                       that.hotNode.remove();\r
+\r
+                                               accessNode[ insertAfter ? 'insertAfter' : 'insertBefore' ]( target );\r
+\r
+                                               // Make this element distinguishable. Also remember the direction\r
+                                               // it's been inserted into document.\r
+                                               accessNode.setAttributes( {\r
+                                                       'data-cke-magicline-hot': 1,\r
+                                                       'data-cke-magicline-dir': !!insertAfter\r
+                                               } );\r
+\r
+                                               // Save last direction of the command (is insertAfter?).\r
+                                               that.lastCmdDirection = !!insertAfter;\r
+                                       } );\r
+\r
+                                       if ( !env.ie && that.enterMode != CKEDITOR.ENTER_BR )\r
+                                               that.hotNode.scrollIntoView();\r
+\r
+                                       // Detach the line if was visible (previously triggered by mouse).\r
+                                       that.line.detach();\r
+                               }\r
+\r
+                               return function( editor ) {\r
+                                       var selected = editor.getSelection().getStartElement(),\r
+                                               limit;\r
+\r
+                                       // (#9833) Go down to the closest non-inline element in DOM structure\r
+                                       // since inline elements don't participate in in magicline.\r
+                                       selected = selected.getAscendant( DTD_BLOCK, 1 );\r
+\r
+                                       // Stop if selected is a child of a tabu-list element.\r
+                                       if ( isInTabu( that, selected ) )\r
+                                               return;\r
+\r
+                                       // Sometimes it may happen that there's no parent block below selected element\r
+                                       // or, for example, getAscendant reaches editable or editable parent.\r
+                                       // We must avoid such pathological cases.\r
+                                       if ( !selected || selected.equals( that.editable ) || selected.contains( that.editable ) )\r
+                                               return;\r
+\r
+                                       // Executing the command directly in nested editable should\r
+                                       // access space before/after it.\r
+                                       if ( ( limit = getClosestEditableLimit( selected ) ) && limit.getAttribute( 'contenteditable' ) == 'false' )\r
+                                               selected = limit;\r
+\r
+                                       // That holds element from mouse. Replace it with the\r
+                                       // element under the caret.\r
+                                       that.element = selected;\r
+\r
+                                       // (3.) Handle the following cases where selected neighbour\r
+                                       // is a trigger inaccessible for the caret AND:\r
+                                       //      - Is first/last-child\r
+                                       //      OR\r
+                                       //      - Has a sibling, which is also a trigger.\r
+                                       var neighbor = getNonEmptyNeighbour( that, selected, !insertAfter ),\r
+                                               neighborSibling;\r
+\r
+                                       // Check for a neighbour that belongs to triggers.\r
+                                       // Consider only non-accessible elements (they cannot have any children)\r
+                                       // since they cannot be given a caret inside, to run the command\r
+                                       // the regular way (1. & 2.).\r
+                                       if (\r
+                                               isHtml( neighbor ) && neighbor.is( that.triggers ) && neighbor.is( DTD_NONACCESSIBLE ) &&\r
+                                               (\r
+                                                       // Check whether neighbor is first/last-child.\r
+                                                       !getNonEmptyNeighbour( that, neighbor, !insertAfter ) ||\r
+                                                       // Check for a sibling of a neighbour that also is a trigger.\r
+                                                       (\r
+                                                               ( neighborSibling = getNonEmptyNeighbour( that, neighbor, !insertAfter ) ) &&\r
+                                                               isHtml( neighborSibling ) &&\r
+                                                               neighborSibling.is( that.triggers )\r
+                                                       )\r
+                                               )\r
+                                       ) {\r
+                                               doAccess( neighbor );\r
+                                               return;\r
+                                       }\r
+\r
+                                       // Look for possible target element DOWN "selected" DOM branch (towards editable)\r
+                                       // that belong to that.triggers\r
+                                       var target = getAscendantTrigger( that, selected );\r
+\r
+                                       // No HTML target -> no access.\r
+                                       if ( !isHtml( target ) )\r
+                                               return;\r
+\r
+                                       // (1.) Target is first/last child -> access.\r
+                                       if ( !getNonEmptyNeighbour( that, target, !insertAfter ) ) {\r
+                                               doAccess( target );\r
+                                               return;\r
+                                       }\r
+\r
+                                       var sibling = getNonEmptyNeighbour( that, target, !insertAfter );\r
+\r
+                                       // (2.) Target has a sibling that belongs to that.triggers -> access.\r
+                                       if ( sibling && isHtml( sibling ) && sibling.is( that.triggers ) ) {\r
+                                               doAccess( target );\r
+                                               return;\r
+                                       }\r
+                               };\r
+                       } )()\r
+               };\r
+       }\r
+\r
+       function isLine( that, node ) {\r
+               if ( !( node && node.type == CKEDITOR.NODE_ELEMENT && node.$ ) )\r
+                       return false;\r
+\r
+               var line = that.line;\r
+\r
+               return line.wrap.equals( node ) || line.wrap.contains( node );\r
+       }\r
+\r
+       // Is text node containing white-spaces only?\r
+       var isEmptyTextNode = CKEDITOR.dom.walker.whitespaces();\r
+\r
+       // Is fully visible HTML node?\r
+       function isHtml( node ) {\r
+               return node && node.type == CKEDITOR.NODE_ELEMENT && node.$;    // IE requires that\r
+       }\r
+\r
+       function isFloated( element ) {\r
+               if ( !isHtml( element ) )\r
+                       return false;\r
+\r
+               var options = { left: 1, right: 1, center: 1 };\r
+\r
+               return !!( options[ element.getComputedStyle( 'float' ) ] || options[ element.getAttribute( 'align' ) ] );\r
+       }\r
+\r
+       function isFlowBreaker( element ) {\r
+               if ( !isHtml( element ) )\r
+                       return false;\r
+\r
+               return isPositioned( element ) || isFloated( element );\r
+       }\r
+\r
+       // Isn't node of NODE_COMMENT type?\r
+       var isComment = CKEDITOR.dom.walker.nodeType( CKEDITOR.NODE_COMMENT );\r
+\r
+       function isPositioned( element ) {\r
+               return !!{ absolute: 1, fixed: 1 }[ element.getComputedStyle( 'position' ) ];\r
+       }\r
+\r
+       // Is text node?\r
+       function isTextNode( node ) {\r
+               return node && node.type == CKEDITOR.NODE_TEXT;\r
+       }\r
+\r
+       function isTrigger( that, element ) {\r
+               return isHtml( element ) ? element.is( that.triggers ) : null;\r
+       }\r
+\r
+       function isInTabu( that, element ) {\r
+               if ( !element )\r
+                       return false;\r
+\r
+               var parents = element.getParents( 1 );\r
+\r
+               for ( var i = parents.length ; i-- ; ) {\r
+                       for ( var j = that.tabuList.length ; j-- ; ) {\r
+                               if ( parents[ i ].hasAttribute( that.tabuList[ j ] ) )\r
+                                       return true;\r
+                       }\r
+               }\r
+\r
+               return false;\r
+       }\r
+\r
+       // This function checks vertically is there's a relevant child between element's edge\r
+       // and the pointer.\r
+       //      \-> Table contents are omitted.\r
+       function isChildBetweenPointerAndEdge( that, parent, edgeBottom ) {\r
+               var edgeChild = parent[ edgeBottom ? 'getLast' : 'getFirst' ]( function( node ) {\r
+                       return that.isRelevant( node ) && !node.is( DTD_TABLECONTENT );\r
+               } );\r
+\r
+               if ( !edgeChild )\r
+                       return false;\r
+\r
+               updateSize( that, edgeChild );\r
+\r
+               return edgeBottom ? edgeChild.size.top > that.mouse.y : edgeChild.size.bottom < that.mouse.y;\r
+       }\r
+\r
+       // This method handles edge cases:\r
+       //      \-> Mouse is around upper or lower edge of view pane.\r
+       //      \-> Also scroll position is either minimal or maximal.\r
+       //      \-> It's OK to show LOOK_TOP(BOTTOM) type line.\r
+       //\r
+       // This trigger doesn't need additional post-filtering.\r
+       //\r
+       //      +----------------------------- Editable -+  /--\r
+       //      | +---------------------- First child -+ |  | <-- Top edge (first child)\r
+       //      | |                                    | |  |\r
+       //      | |                                    | |  |    * Mouse activation area *\r
+       //      | |                                    | |  |\r
+       //      | |                 ...                | |      \-- Top edge + trigger offset\r
+       //      | .                                    . |\r
+       //      |                                        |\r
+       //      | .                                    . |\r
+       //      | |                 ...                | |  /-- Bottom edge - trigger offset\r
+       //      | |                                    | |  |\r
+       //      | |                                    | |  |    * Mouse activation area *\r
+       //      | |                                    | |  |\r
+       //      | +----------------------- Last child -+ |  | <-- Bottom edge (last child)\r
+       //      +----------------------------------------+  \--\r
+       //\r
+       function triggerEditable( that ) {\r
+               that.debug.groupStart( 'triggerEditable' ); // %REMOVE_LINE%\r
+\r
+               var editable = that.editable,\r
+                       mouse = that.mouse,\r
+                       view = that.view,\r
+                       triggerOffset = that.triggerOffset,\r
+                       triggerLook;\r
+\r
+               // Update editable dimensions.\r
+               updateEditableSize( that );\r
+\r
+               // This flag determines whether checking bottom trigger.\r
+               var bottomTrigger = mouse.y > (\r
+                               that.inInlineMode ? (\r
+                                       view.editable.top + view.editable.height / 2\r
+                               ) : (\r
+                                       // This is to handle case when editable.height / 2 <<< pane.height.\r
+                                       Math.min( view.editable.height, view.pane.height ) / 2\r
+                               )\r
+                       ),\r
+\r
+               // Edge node according to bottomTrigger.\r
+               edgeNode = editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( function( node ) {\r
+                       return !( isEmptyTextNode( node ) || isComment( node ) );\r
+               } );\r
+\r
+               // There's no edge node. Abort.\r
+               if ( !edgeNode ) {\r
+                       that.debug.logEnd( 'ABORT. No edge node found.' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // If the edgeNode in editable is ML, get the next one.\r
+               if ( isLine( that, edgeNode ) ) {\r
+                       edgeNode = that.line.wrap[ bottomTrigger ? 'getPrevious' : 'getNext' ]( function( node ) {\r
+                               return !( isEmptyTextNode( node ) || isComment( node ) );\r
+                       } );\r
+               }\r
+\r
+               // Exclude bad nodes (no ML needed then):\r
+               //      \-> Edge node is text.\r
+               //      \-> Edge node is floated, etc.\r
+               //\r
+               // Edge node *must be* a valid trigger at this stage as well.\r
+               if ( !isHtml( edgeNode ) || isFlowBreaker( edgeNode ) || !isTrigger( that, edgeNode ) ) {\r
+                       that.debug.logEnd( 'ABORT. Invalid edge node.' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // Update size of edge node. Dimensions will be necessary.\r
+               updateSize( that, edgeNode );\r
+\r
+               // Return appropriate trigger according to bottomTrigger.\r
+               // \->  Top edge trigger case first.\r
+               if ( !bottomTrigger &&                                                                                                  // Top trigger case.\r
+                       edgeNode.size.top >= 0 &&                                                                                       // Check if the first element is fully visible.\r
+                       inBetween( mouse.y, 0, edgeNode.size.top + triggerOffset ) ) {          // Check if mouse in [0, edgeNode.top + triggerOffset].\r
+\r
+                       // Determine trigger look.\r
+                       triggerLook = that.inInlineMode || view.scroll.y === 0 ?\r
+                               LOOK_TOP : LOOK_NORMAL;\r
+\r
+                       that.debug.logEnd( 'SUCCESS. Created box trigger. EDGE_TOP.' ); // %REMOVE_LINE%\r
+\r
+                       return new boxTrigger( [ null, edgeNode,\r
+                               EDGE_TOP,\r
+                               TYPE_EDGE,\r
+                               triggerLook\r
+                       ] );\r
+               }\r
+\r
+               // \->  Bottom case.\r
+               else if ( bottomTrigger &&\r
+                       edgeNode.size.bottom <= view.pane.height &&                                                     // Check if the last element is fully visible\r
+                       inBetween( mouse.y,                                                                                                     // Check if mouse in...\r
+                               edgeNode.size.bottom - triggerOffset, view.pane.height ) ) {    // [ edgeNode.bottom - triggerOffset, paneHeight ]\r
+\r
+                       // Determine trigger look.\r
+                       triggerLook = that.inInlineMode ||\r
+                               inBetween( edgeNode.size.bottom, view.pane.height - triggerOffset, view.pane.height ) ?\r
+                                       LOOK_BOTTOM : LOOK_NORMAL;\r
+\r
+                       that.debug.logEnd( 'SUCCESS. Created box trigger. EDGE_BOTTOM.' ); // %REMOVE_LINE%\r
+\r
+                       return new boxTrigger( [ edgeNode, null,\r
+                               EDGE_BOTTOM,\r
+                               TYPE_EDGE,\r
+                               triggerLook\r
+                       ] );\r
+               }\r
+\r
+               that.debug.logEnd( 'ABORT. No trigger created.' ); // %REMOVE_LINE%\r
+               return null;\r
+       }\r
+\r
+       // This method covers cases *inside* of an element:\r
+       //      \->     The pointer is in the top (bottom) area of an element and there's\r
+       //              HTML node before (after) this element.\r
+       //      \-> An element being the first or last child of its parent.\r
+       //\r
+       //      +----------------------- Parent element -+\r
+       //      | +----------------------- Element #1 -+ |  /--\r
+       //      | |                                    | |  |    * Mouse activation area (as first child) *\r
+       //      | |                                    | |  \--\r
+       //      | |                                    | |  /--\r
+       //      | |                                    | |  |    * Mouse activation area (Element #2) *\r
+       //      | +------------------------------------+ |  \--\r
+       //      |                                        |\r
+       //      | +----------------------- Element #2 -+ |  /--\r
+       //      | |                                    | |  |    * Mouse activation area (Element #1) *\r
+       //      | |                                    | |  \--\r
+       //      | |                                    | |\r
+       //      | +------------------------------------+ |\r
+       //      |                                        |\r
+       //      |            Text node is here.          |\r
+       //      |                                        |\r
+       //      | +----------------------- Element #3 -+ |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | |                                    | |  /--\r
+       //      | |                                    | |  |    * Mouse activation area (as last child) *\r
+       //      | +------------------------------------+ |  \--\r
+       //      +----------------------------------------+\r
+       //\r
+       function triggerEdge( that ) {\r
+               that.debug.groupStart( 'triggerEdge' ); // %REMOVE_LINE%\r
+\r
+               var mouse = that.mouse,\r
+                       view = that.view,\r
+                       triggerOffset = that.triggerOffset;\r
+\r
+               // Get the ascendant trigger basing on elementFromMouse.\r
+               var element = getAscendantTrigger( that );\r
+\r
+               that.debug.logElements( [ element ], [ 'Ascendant trigger' ], 'First stage' ); // %REMOVE_LINE%\r
+\r
+               // Abort if there's no appropriate element.\r
+               if ( !element ) {\r
+                       that.debug.logEnd( 'ABORT. No element, element is editable or element contains editable.' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // Dimensions will be necessary.\r
+               updateSize( that, element );\r
+\r
+               // If triggerOffset is larger than a half of element's height,\r
+               // use an offset of 1/2 of element's height. If the offset wasn't reduced,\r
+               // top area would cover most (all) cases.\r
+               var fixedOffset = Math.min( triggerOffset,\r
+                               0 | ( element.size.outerHeight / 2 ) ),\r
+\r
+               // This variable will hold the trigger to be returned.\r
+                       triggerSetup = [],\r
+                       triggerLook,\r
+\r
+               // This flag determines whether dealing with a bottom trigger.\r
+                       bottomTrigger;\r
+\r
+               //      \-> Top trigger.\r
+               if ( inBetween( mouse.y, element.size.top - 1, element.size.top + fixedOffset ) )\r
+                       bottomTrigger = false;\r
+               //      \-> Bottom trigger.\r
+               else if ( inBetween( mouse.y, element.size.bottom - fixedOffset, element.size.bottom + 1 ) )\r
+                       bottomTrigger = true;\r
+               //      \-> Abort. Not in a valid trigger space.\r
+               else {\r
+                       that.debug.logEnd( 'ABORT. Not around of any edge.' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // Reject wrong elements.\r
+               //      \-> Reject an element which is a flow breaker.\r
+               //      \-> Reject an element which has a child above/below the mouse pointer.\r
+               //      \-> Reject an element which belongs to list items.\r
+               if (\r
+                       isFlowBreaker( element ) ||\r
+                       isChildBetweenPointerAndEdge( that, element, bottomTrigger ) ||\r
+                       element.getParent().is( DTD_LISTITEM )\r
+               ) {\r
+                       that.debug.logEnd( 'ABORT. element is wrong', element ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // Get sibling according to bottomTrigger.\r
+               var elementSibling = getNonEmptyNeighbour( that, element, !bottomTrigger );\r
+\r
+               // No sibling element.\r
+               // This is a first or last child case.\r
+               if ( !elementSibling ) {\r
+                       // No need to reject the element as it has already been done before.\r
+                       // Prepare a trigger.\r
+\r
+                       // Determine trigger look.\r
+                       if ( element.equals( that.editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( that.isRelevant ) ) ) {\r
+                               updateEditableSize( that );\r
+\r
+                               if (\r
+                                       bottomTrigger && inBetween( mouse.y,\r
+                                       element.size.bottom - fixedOffset, view.pane.height ) &&\r
+                                       inBetween( element.size.bottom, view.pane.height - fixedOffset, view.pane.height )\r
+                               ) {\r
+                                       triggerLook = LOOK_BOTTOM;\r
+                               } else if ( inBetween( mouse.y, 0, element.size.top + fixedOffset ) ) {\r
+                                       triggerLook = LOOK_TOP;\r
+                               }\r
+                       } else {\r
+                               triggerLook = LOOK_NORMAL;\r
+                       }\r
+\r
+                       triggerSetup = [ null, element ][ bottomTrigger ? 'reverse' : 'concat' ]().concat( [\r
+                               bottomTrigger ? EDGE_BOTTOM : EDGE_TOP,\r
+                               TYPE_EDGE,\r
+                               triggerLook,\r
+                               element.equals( that.editable[ bottomTrigger ? 'getLast' : 'getFirst' ]( that.isRelevant ) ) ?\r
+                                               ( bottomTrigger ? LOOK_BOTTOM : LOOK_TOP ) : LOOK_NORMAL\r
+                       ] );\r
+\r
+                       that.debug.log( 'Configured edge trigger of ' + ( bottomTrigger ? 'EDGE_BOTTOM' : 'EDGE_TOP' ) ); // %REMOVE_LINE%\r
+               }\r
+\r
+               // Abort. Sibling is a text element.\r
+               else if ( isTextNode( elementSibling ) ) {\r
+                       that.debug.logEnd( 'ABORT. Sibling is non-empty text element' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               // Check if the sibling is a HTML element.\r
+               // If so, create an TYPE_EDGE, EDGE_MIDDLE trigger.\r
+               else if ( isHtml( elementSibling ) ) {\r
+                       // Reject wrong elementSiblings.\r
+                       //      \-> Reject an elementSibling which is a flow breaker.\r
+                       //      \-> Reject an elementSibling which isn't a trigger.\r
+                       //      \-> Reject an elementSibling which belongs to list items.\r
+                       if (\r
+                               isFlowBreaker( elementSibling ) ||\r
+                               !isTrigger( that, elementSibling ) ||\r
+                               elementSibling.getParent().is( DTD_LISTITEM )\r
+                       ) {\r
+                               that.debug.logEnd( 'ABORT. elementSibling is wrong', elementSibling ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       // Prepare a trigger.\r
+                       triggerSetup = [ elementSibling, element ][ bottomTrigger ? 'reverse' : 'concat' ]().concat( [\r
+                               EDGE_MIDDLE,\r
+                               TYPE_EDGE\r
+                       ] );\r
+\r
+                       that.debug.log( 'Configured edge trigger of EDGE_MIDDLE' ); // %REMOVE_LINE%\r
+               }\r
+\r
+               if ( 0 in triggerSetup ) {\r
+                       that.debug.logEnd( 'SUCCESS. Returning a trigger.' ); // %REMOVE_LINE%\r
+                       return new boxTrigger( triggerSetup );\r
+               }\r
+\r
+               that.debug.logEnd( 'ABORT. No trigger generated.' ); // %REMOVE_LINE%\r
+               return null;\r
+       }\r
+\r
+       // Checks iteratively up and down in search for elements using elementFromMouse method.\r
+       // Useful if between two triggers.\r
+       //\r
+       //      +----------------------- Parent element -+\r
+       //      | +----------------------- Element #1 -+ |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | +------------------------------------+ |\r
+       //      |                                        |  /--\r
+       //      |                  .                     |  |\r
+       //      |                  .      +-- Floated -+ |  |\r
+       //      |                  |      |            | |  |   * Mouse activation area *\r
+       //      |                  |      |   IGNORE   | |  |\r
+       //      |                  X      |            | |  |   Method searches vertically for sibling elements.\r
+       //      |                  |      +------------+ |  |   Start point is X (mouse-y coordinate).\r
+       //      |                  |                     |  |   Floated elements, comments and empty text nodes are omitted.\r
+       //      |                  .                     |  |\r
+       //      |                  .                     |  |\r
+       //      |                                        |  \--\r
+       //      | +----------------------- Element #2 -+ |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | |                                    | |\r
+       //      | +------------------------------------+ |\r
+       //      +----------------------------------------+\r
+       //\r
+       var triggerExpand = ( function() {\r
+               // The heart of the procedure. This method creates triggers that are\r
+               // filtered by expandFilter method.\r
+               function expandEngine( that ) {\r
+                       that.debug.groupStart( 'expandEngine' ); // %REMOVE_LINE%\r
+\r
+                       var startElement = that.element,\r
+                               upper, lower, trigger;\r
+\r
+                       if ( !isHtml( startElement ) || startElement.contains( that.editable ) ) {\r
+                               that.debug.logEnd( 'ABORT. No start element, or start element contains editable.' ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       // Stop searching if element is in non-editable branch of DOM.\r
+                       if ( startElement.isReadOnly() )\r
+                               return null;\r
+\r
+                       trigger = verticalSearch( that,\r
+                               function( current, startElement ) {\r
+                                       return !startElement.equals( current ); // stop when start element and the current one differ\r
+                               }, function( that, mouse ) {\r
+                                       return elementFromMouse( that, true, mouse );\r
+                               }, startElement ),\r
+\r
+                       upper = trigger.upper,\r
+                       lower = trigger.lower;\r
+\r
+                       that.debug.logElements( [ upper, lower ], [ 'Upper', 'Lower' ], 'Pair found' ); // %REMOVE_LINE%\r
+\r
+                       // Success: two siblings have been found\r
+                       if ( areSiblings( that, upper, lower ) ) {\r
+                               that.debug.logEnd( 'SUCCESS. Expand trigger created.' ); // %REMOVE_LINE%\r
+                               return trigger.set( EDGE_MIDDLE, TYPE_EXPAND );\r
+                       }\r
+\r
+                       that.debug.logElements( [ startElement, upper, lower ], // %REMOVE_LINE%\r
+                               [ 'Start', 'Upper', 'Lower' ], 'Post-processing' ); // %REMOVE_LINE%\r
+\r
+                       // Danger. Dragons ahead.\r
+                       // No siblings have been found during previous phase, post-processing may be necessary.\r
+                       // We can traverse DOM until a valid pair of elements around the pointer is found.\r
+\r
+                       // Prepare for post-processing:\r
+                       //      1. Determine if upper and lower are children of startElement.\r
+                       //              1.1. If so, find their ascendants that are closest to startElement (one level deeper than startElement).\r
+                       //              1.2. Otherwise use first/last-child of the startElement as upper/lower. Why?:\r
+                       //                      a)      upper/lower belongs to another branch of the DOM tree.\r
+                       //                      b)      verticalSearch encountered an edge of the viewport and failed.\r
+                       //              1.3. Make sure upper and lower still exist. Why?:\r
+                       //                      a)      Upper and lower may be not belong to the branch of the startElement (may not exist at all) and\r
+                       //                              startElement has no children.\r
+                       //      2. Perform the post-processing.\r
+                       //              2.1. Gather dimensions of an upper element.\r
+                       //              2.2. Abort if lower edge of upper is already under the mouse pointer. Why?:\r
+                       //                      a)      We expect upper to be above and lower below the mouse pointer.\r
+                       //      3. Perform iterative search while upper != lower.\r
+                       //              3.1. Find the upper-next element. If there's no such element, break current search. Why?:\r
+                       //                      a)      There's no point in further search if there are only text nodes ahead.\r
+                       //              3.2. Calculate the distance between the middle point of ( upper, upperNext ) and mouse-y.\r
+                       //              3.3. If the distance is shorter than the previous best, save it (save upper, upperNext as well).\r
+                       //              3.4. If the optimal pair is found, assign it back to the trigger.\r
+\r
+                       // 1.1., 1.2.\r
+                       if ( upper && startElement.contains( upper ) ) {\r
+                               while ( !upper.getParent().equals( startElement ) )\r
+                                       upper = upper.getParent();\r
+                       } else {\r
+                               upper = startElement.getFirst( function( node ) {\r
+                                       return expandSelector( that, node );\r
+                               } );\r
+                       }\r
+\r
+                       if ( lower && startElement.contains( lower ) ) {\r
+                               while ( !lower.getParent().equals( startElement ) )\r
+                                       lower = lower.getParent();\r
+                       } else {\r
+                               lower = startElement.getLast( function( node ) {\r
+                                       return expandSelector( that, node );\r
+                               } );\r
+                       }\r
+\r
+                       // 1.3.\r
+                       if ( !upper || !lower ) {\r
+                               that.debug.logEnd( 'ABORT. There is no upper or no lower element.' ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       // 2.1.\r
+                       updateSize( that, upper );\r
+                       updateSize( that, lower );\r
+\r
+                       if ( !checkMouseBetweenElements( that, upper, lower ) ) {\r
+                               that.debug.logEnd( 'ABORT. Mouse is already above upper or below lower.' ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       var minDistance = Number.MAX_VALUE,\r
+                               currentDistance, upperNext, minElement, minElementNext;\r
+\r
+                       while ( lower && !lower.equals( upper ) ) {\r
+                               // 3.1.\r
+                               if ( !( upperNext = upper.getNext( that.isRelevant ) ) )\r
+                                       break;\r
+\r
+                               // 3.2.\r
+                               currentDistance = Math.abs( getMidpoint( that, upper, upperNext ) - that.mouse.y );\r
+\r
+                               // 3.3.\r
+                               if ( currentDistance < minDistance ) {\r
+                                       minDistance = currentDistance;\r
+                                       minElement = upper;\r
+                                       minElementNext = upperNext;\r
+                               }\r
+\r
+                               upper = upperNext;\r
+                               updateSize( that, upper );\r
+                       }\r
+\r
+                       that.debug.logElements( [ minElement, minElementNext ], // %REMOVE_LINE%\r
+                               [ 'Min', 'MinNext' ], 'Post-processing results' ); // %REMOVE_LINE%\r
+\r
+                       // 3.4.\r
+                       if ( !minElement || !minElementNext ) {\r
+                               that.debug.logEnd( 'ABORT. No Min or MinNext' ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       if ( !checkMouseBetweenElements( that, minElement, minElementNext ) ) {\r
+                               that.debug.logEnd( 'ABORT. Mouse is already above minElement or below minElementNext.' ); // %REMOVE_LINE%\r
+                               return null;\r
+                       }\r
+\r
+                       // An element of minimal distance has been found. Assign it to the trigger.\r
+                       trigger.upper = minElement;\r
+                       trigger.lower = minElementNext;\r
+\r
+                       // Success: post-processing revealed a pair of elements.\r
+                       that.debug.logEnd( 'SUCCESSFUL post-processing. Trigger created.' ); // %REMOVE_LINE%\r
+                       return trigger.set( EDGE_MIDDLE, TYPE_EXPAND );\r
+               }\r
+\r
+               // This is default element selector used by the engine.\r
+               function expandSelector( that, node ) {\r
+                       return !( isTextNode( node ) ||\r
+                               isComment( node ) ||\r
+                               isFlowBreaker( node ) ||\r
+                               isLine( that, node ) ||\r
+                               ( node.type == CKEDITOR.NODE_ELEMENT && node.$ && node.is( 'br' ) ) );\r
+               }\r
+\r
+               // This method checks whether mouse-y is between the top edge of upper\r
+               // and bottom edge of lower.\r
+               //\r
+               // NOTE: This method assumes that updateSize has already been called\r
+               // for the elements and is up-to-date.\r
+               //\r
+               //      +---------------------------- Upper -+  /--\r
+               //      |                                    |  |\r
+               //      +------------------------------------+  |\r
+               //                                          |\r
+               //                     ...                  |\r
+               //                                          |\r
+               //                                              X                   |   * Return true for mouse-y in this range *\r
+               //                                          |\r
+               //                     ...                  |\r
+               //                                          |\r
+               //      +---------------------------- Lower -+  |\r
+               //      |                                    |  |\r
+               //      +------------------------------------+  \--\r
+               //\r
+               function checkMouseBetweenElements( that, upper, lower ) {\r
+                       return inBetween( that.mouse.y, upper.size.top, lower.size.bottom );\r
+               }\r
+\r
+               // A method for trigger filtering. Accepts or rejects trigger pairs\r
+               // by their location in DOM etc.\r
+               function expandFilter( that, trigger ) {\r
+                       that.debug.groupStart( 'expandFilter' ); // %REMOVE_LINE%\r
+\r
+                       var upper = trigger.upper,\r
+                               lower = trigger.lower;\r
+\r
+                       if (\r
+                               !upper || !lower ||                                                                                     // NOT: EDGE_MIDDLE trigger ALWAYS has two elements.\r
+                               isFlowBreaker( lower ) || isFlowBreaker( upper ) ||                     // NOT: one of the elements is floated or positioned\r
+                               lower.equals( upper ) || upper.equals( lower ) ||                       // NOT: two trigger elements, one equals another.\r
+                               lower.contains( upper ) || upper.contains( lower )\r
+                       ) {     // NOT: two trigger elements, one contains another.\r
+                               that.debug.logEnd( 'REJECTED. No upper or no lower or they contain each other.' ); // %REMOVE_LINE%\r
+\r
+                               return false;\r
+                       }\r
+\r
+                       // YES: two trigger elements, pure siblings.\r
+                       else if ( isTrigger( that, upper ) && isTrigger( that, lower ) && areSiblings( that, upper, lower ) ) {\r
+                               that.debug.logElementsEnd( [ upper, lower ], // %REMOVE_LINE%\r
+                                       [ 'upper', 'lower' ], 'APPROVED EDGE_MIDDLE' ); // %REMOVE_LINE%\r
+\r
+                               return true;\r
+                       }\r
+\r
+                       that.debug.logElementsEnd( [ upper, lower ], // %REMOVE_LINE%\r
+                               [ 'upper', 'lower' ], 'Rejected unknown pair' ); // %REMOVE_LINE%\r
+\r
+                       return false;\r
+               }\r
+\r
+               // Simple wrapper for expandEngine and expandFilter.\r
+               return function( that ) {\r
+                       that.debug.groupStart( 'triggerExpand' ); // %REMOVE_LINE%\r
+\r
+                       var trigger = expandEngine( that );\r
+\r
+                       that.debug.groupEnd(); // %REMOVE_LINE%\r
+                       return trigger && expandFilter( that, trigger ) ? trigger : null;\r
+               };\r
+       } )();\r
+\r
+       // Collects dimensions of an element.\r
+       var sizePrefixes = [ 'top', 'left', 'right', 'bottom' ];\r
+\r
+       function getSize( that, element, ignoreScroll, force ) {\r
+               var docPosition = element.getDocumentPosition(),\r
+                       border = {},\r
+                       margin = {},\r
+                       padding = {},\r
+                       box = {};\r
+\r
+               for ( var i = sizePrefixes.length; i--; ) {\r
+                       border[ sizePrefixes[ i ] ] = parseInt( getStyle( 'border-' + sizePrefixes[ i ] + '-width' ), 10 ) || 0;\r
+                       padding[ sizePrefixes[ i ] ] = parseInt( getStyle( 'padding-' + sizePrefixes[ i ] ), 10 ) || 0;\r
+                       margin[ sizePrefixes[ i ] ] = parseInt( getStyle( 'margin-' + sizePrefixes[ i ] ), 10 ) || 0;\r
+               }\r
+\r
+               // updateWindowSize if forced to do so OR NOT ignoring scroll.\r
+               if ( !ignoreScroll || force )\r
+                       updateWindowSize( that, force );\r
+\r
+               box.top = docPosition.y - ( ignoreScroll ? 0 : that.view.scroll.y ), box.left = docPosition.x - ( ignoreScroll ? 0 : that.view.scroll.x ),\r
+\r
+               // w/ borders and paddings.\r
+               box.outerWidth = element.$.offsetWidth, box.outerHeight = element.$.offsetHeight,\r
+\r
+               // w/o borders and paddings.\r
+               box.height = box.outerHeight - ( padding.top + padding.bottom + border.top + border.bottom ), box.width = box.outerWidth - ( padding.left + padding.right + border.left + border.right ),\r
+\r
+               box.bottom = box.top + box.outerHeight, box.right = box.left + box.outerWidth;\r
+\r
+               if ( that.inInlineMode ) {\r
+                       box.scroll = {\r
+                               top: element.$.scrollTop,\r
+                               left: element.$.scrollLeft\r
+                       };\r
+               }\r
+\r
+               return extend( {\r
+                       border: border,\r
+                       padding: padding,\r
+                       margin: margin,\r
+                       ignoreScroll: ignoreScroll\r
+               }, box, true );\r
+\r
+               function getStyle( propertyName ) {\r
+                       return element.getComputedStyle.call( element, propertyName );\r
+               }\r
+       }\r
+\r
+       function updateSize( that, element, ignoreScroll ) {\r
+               if ( !isHtml( element ) ) // i.e. an element is hidden\r
+                       return ( element.size = null ); //      -> reset size to make it useless for other methods\r
+\r
+               if ( !element.size )\r
+                       element.size = {};\r
+\r
+               // Abort if there was a similar query performed recently.\r
+               // This kind of caching provides great performance improvement.\r
+               else if ( element.size.ignoreScroll == ignoreScroll && element.size.date > new Date() - CACHE_TIME ) {\r
+                       that.debug.log( 'element.size: get from cache' ); // %REMOVE_LINE%\r
+                       return null;\r
+               }\r
+\r
+               that.debug.log( 'element.size: capture' ); // %REMOVE_LINE%\r
+\r
+               return extend( element.size, getSize( that, element, ignoreScroll ), {\r
+                       date: +new Date()\r
+               }, true );\r
+       }\r
+\r
+       // Updates that.view.editable object.\r
+       // This one must be called separately outside of updateWindowSize\r
+       // to prevent cyclic dependency getSize<->updateWindowSize.\r
+       // It calls getSize with force flag to avoid getWindowSize cache (look: getSize).\r
+       function updateEditableSize( that, ignoreScroll ) {\r
+               that.view.editable = getSize( that, that.editable, ignoreScroll, true );\r
+       }\r
+\r
+       function updateWindowSize( that, force ) {\r
+               if ( !that.view )\r
+                       that.view = {};\r
+\r
+               var view = that.view;\r
+\r
+               if ( !force && view && view.date > new Date() - CACHE_TIME ) {\r
+                       that.debug.log( 'win.size: get from cache' ); // %REMOVE_LINE%\r
+                       return;\r
+               }\r
+\r
+               that.debug.log( 'win.size: capturing' ); // %REMOVE_LINE%\r
+\r
+               var win = that.win,\r
+                       scroll = win.getScrollPosition(),\r
+                       paneSize = win.getViewPaneSize();\r
+\r
+               extend( that.view, {\r
+                       scroll: {\r
+                               x: scroll.x,\r
+                               y: scroll.y,\r
+                               width: that.doc.$.documentElement.scrollWidth - paneSize.width,\r
+                               height: that.doc.$.documentElement.scrollHeight - paneSize.height\r
+                       },\r
+                       pane: {\r
+                               width: paneSize.width,\r
+                               height: paneSize.height,\r
+                               bottom: paneSize.height + scroll.y\r
+                       },\r
+                       date: +new Date()\r
+               }, true );\r
+       }\r
+\r
+       // This method searches document vertically using given\r
+       // select criterion until stop criterion is fulfilled.\r
+       function verticalSearch( that, stopCondition, selectCriterion, startElement ) {\r
+               var upper = startElement,\r
+                       lower = startElement,\r
+                       mouseStep = 0,\r
+                       upperFound = false,\r
+                       lowerFound = false,\r
+                       viewPaneHeight = that.view.pane.height,\r
+                       mouse = that.mouse;\r
+\r
+               while ( mouse.y + mouseStep < viewPaneHeight && mouse.y - mouseStep > 0 ) {\r
+                       if ( !upperFound )\r
+                               upperFound = stopCondition( upper, startElement );\r
+\r
+                       if ( !lowerFound )\r
+                               lowerFound = stopCondition( lower, startElement );\r
+\r
+                       // Still not found...\r
+                       if ( !upperFound && mouse.y - mouseStep > 0 )\r
+                               upper = selectCriterion( that, { x: mouse.x, y: mouse.y - mouseStep } );\r
+\r
+                       if ( !lowerFound && mouse.y + mouseStep < viewPaneHeight )\r
+                               lower = selectCriterion( that, { x: mouse.x, y: mouse.y + mouseStep } );\r
+\r
+                       if ( upperFound && lowerFound )\r
+                               break;\r
+\r
+                       // Instead of ++ to reduce the number of invocations by half.\r
+                       // It's trades off accuracy in some edge cases for improved performance.\r
+                       mouseStep += 2;\r
+               }\r
+\r
+               return new boxTrigger( [ upper, lower, null, null ] );\r
+       }\r
+\r
+} )();\r
+\r
+/**\r
+ * Sets the default vertical distance between the edge of the element and the mouse pointer that\r
+ * causes the magic line to appear. This option accepts a value in pixels, without the unit (for example:\r
+ * `15` for 15 pixels).\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Changes the offset to 15px.\r
+ *             CKEDITOR.config.magicline_triggerOffset = 15;\r
+ *\r
+ * @cfg {Number} [magicline_triggerOffset=30]\r
+ * @member CKEDITOR.config\r
+ * @see CKEDITOR.config#magicline_holdDistance\r
+ */\r
+\r
+/**\r
+ * Defines the distance between the mouse pointer and the box within\r
+ * which the magic line stays revealed and no other focus space is offered to be accessed.\r
+ * This value is relative to {@link #magicline_triggerOffset}.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Increases the distance to 80% of CKEDITOR.config.magicline_triggerOffset.\r
+ *             CKEDITOR.config.magicline_holdDistance = .8;\r
+ *\r
+ * @cfg {Number} [magicline_holdDistance=0.5]\r
+ * @member CKEDITOR.config\r
+ * @see CKEDITOR.config#magicline_triggerOffset\r
+ */\r
+\r
+/**\r
+ * Defines the default keystroke that accesses the closest unreachable focus space **before**\r
+ * the caret (start of the selection). If there is no focus space available, the selection remains unchanged.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Changes the default keystroke to "Ctrl + ,".\r
+ *             CKEDITOR.config.magicline_keystrokePrevious = CKEDITOR.CTRL + 188;\r
+ *\r
+ * @cfg {Number} [magicline_keystrokePrevious=CKEDITOR.CTRL + CKEDITOR.SHIFT + 51 (CTRL + SHIFT + 3)]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.magicline_keystrokePrevious = CKEDITOR.CTRL + CKEDITOR.SHIFT + 51; // CTRL + SHIFT + 3\r
+\r
+/**\r
+ * Defines the default keystroke that accesses the closest unreachable focus space **after**\r
+ * the caret (start of the selection). If there is no focus space available, the selection remains unchanged.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Changes keystroke to "Ctrl + .".\r
+ *             CKEDITOR.config.magicline_keystrokeNext = CKEDITOR.CTRL + 190;\r
+ *\r
+ * @cfg {Number} [magicline_keystrokeNext=CKEDITOR.CTRL + CKEDITOR.SHIFT + 52 (CTRL + SHIFT + 4)]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.magicline_keystrokeNext = CKEDITOR.CTRL + CKEDITOR.SHIFT + 52; // CTRL + SHIFT + 4\r
+\r
+/**\r
+ * Defines a list of attributes that, if assigned to some elements, prevent the magic line from being\r
+ * used within these elements.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Adds the "data-tabu" attribute to the magic line tabu list.\r
+ *             CKEDITOR.config.magicline_tabuList = [ 'data-tabu' ];\r
+ *\r
+ * @cfg {Number} [magicline_tabuList=[ 'data-widget-wrapper' ]]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Defines the color of the magic line. The color may be adjusted to enhance readability.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Changes magic line color to blue.\r
+ *             CKEDITOR.config.magicline_color = '#0000FF';\r
+ *\r
+ * @cfg {String} [magicline_color='#FF0000']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Activates the special all-encompassing mode that considers all focus spaces between\r
+ * {@link CKEDITOR.dtd#$block} elements as accessible by the magic line.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_magicline)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/magicline.html).\r
+ *\r
+ *             // Enables the greedy "put everywhere" mode.\r
+ *             CKEDITOR.config.magicline_everywhere = true;\r
+ *\r
+ * @cfg {Boolean} [magicline_everywhere=false]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/magicline/samples/magicline.html b/sources/plugins/magicline/samples/magicline.html
new file mode 100644 (file)
index 0000000..8fff40e
--- /dev/null
@@ -0,0 +1,209 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Using Magicline plugin &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-name" content="Magicline plugin">\r
+       <meta name="ckeditor-sample-group" content="Plugins">\r
+       <meta name="ckeditor-sample-description" content="Using the Magicline plugin to access difficult focus spaces.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Using Magicline plugin\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/magicline.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows the advantages of <strong>Magicline</strong> plugin\r
+                       which is to enhance the editing process. Thanks to this plugin,\r
+                       a number of difficult focus spaces which are inaccessible due to\r
+                       browser issues can now be focused.\r
+               </p>\r
+               <p>\r
+                       <strong>Magicline</strong> plugin shows a red line with a handler\r
+                       which, when clicked, inserts a paragraph and allows typing. To see this,\r
+                       focus an editor and move your mouse above the focus space you want\r
+                       to access. The plugin is enabled by default so no additional\r
+                       configuration is necessary.\r
+               </p>\r
+       </div>\r
+       <div>\r
+               <label for="editor1">\r
+                       Editor 1:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor uses a default <strong>Magicline</strong> setup.\r
+                       </p>\r
+               </div>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                               &lt;tbody&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;This table&lt;/td&gt;\r
+                                               &lt;td&gt;is the&lt;/td&gt;\r
+                                               &lt;td&gt;very first&lt;/td&gt;\r
+                                               &lt;td&gt;element of the document.&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;We are still&lt;/td&gt;\r
+                                               &lt;td&gt;able to acces&lt;/td&gt;\r
+                                               &lt;td&gt;the space before it.&lt;/td&gt;\r
+                                               &lt;td&gt;\r
+                                               &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                                                       &lt;tbody&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;This table is inside of a cell of another table.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;We can type&amp;nbsp;either before or after it though.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                       &lt;/tbody&gt;\r
+                                               &lt;/table&gt;\r
+                                               &lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                               &lt;/tbody&gt;\r
+                       &lt;/table&gt;\r
+\r
+                       &lt;p&gt;Two succesive horizontal lines (&lt;tt&gt;HR&lt;/tt&gt; tags). We can access the space in between:&lt;/p&gt;\r
+\r
+                       &lt;hr /&gt;\r
+                       &lt;hr /&gt;\r
+                       &lt;ol&gt;\r
+                               &lt;li&gt;This numbered list...&lt;/li&gt;\r
+                               &lt;li&gt;...is a neighbour of a horizontal line...&lt;/li&gt;\r
+                               &lt;li&gt;...and another list.&lt;/li&gt;\r
+                       &lt;/ol&gt;\r
+\r
+                       &lt;ul&gt;\r
+                               &lt;li&gt;We can type between the lists...&lt;/li&gt;\r
+                               &lt;li&gt;...thanks to &lt;strong&gt;Magicline&lt;/strong&gt;.&lt;/li&gt;\r
+                       &lt;/ul&gt;\r
+\r
+                       &lt;p&gt;Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.&lt;/p&gt;\r
+\r
+                       &lt;div style=&quot;border: 2px dashed green; background: #ddd; text-align: center;&quot;&gt;\r
+                       &lt;p&gt;This text is wrapped in a&amp;nbsp;&lt;tt&gt;DIV&lt;/tt&gt;&amp;nbsp;element. We can type after this element though.&lt;/p&gt;\r
+                       &lt;/div&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // <textarea>, or inside a <head><script> in a\r
+                       // window.onload event handler.\r
+\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               extraPlugins: 'magicline',      // Ensure that magicline plugin, which is required for this sample, is loaded.\r
+                               allowedContent: true            // Switch off the ACF, so very complex content created to\r
+                                                                                       // show magicline's power isn't filtered.\r
+                       } );\r
+\r
+               </script>\r
+       </div>\r
+       <br>\r
+       <div>\r
+               <label for="editor2">\r
+                       Editor 2:\r
+               </label>\r
+               <div class="description">\r
+                       <p>\r
+                               This editor is using a blue line.\r
+                       </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( 'editor2', {\r
+       magicline_color: 'blue'\r
+});</pre>\r
+               </div>\r
+               <textarea cols="80" id="editor2" name="editor2" rows="10">\r
+                       &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                               &lt;tbody&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;This table&lt;/td&gt;\r
+                                               &lt;td&gt;is the&lt;/td&gt;\r
+                                               &lt;td&gt;very first&lt;/td&gt;\r
+                                               &lt;td&gt;element of the document.&lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                                       &lt;tr&gt;\r
+                                               &lt;td&gt;We are still&lt;/td&gt;\r
+                                               &lt;td&gt;able to acces&lt;/td&gt;\r
+                                               &lt;td&gt;the space before it.&lt;/td&gt;\r
+                                               &lt;td&gt;\r
+                                               &lt;table border=&quot;1&quot; cellpadding=&quot;1&quot; cellspacing=&quot;1&quot; style=&quot;width: 100%; &quot;&gt;\r
+                                                       &lt;tbody&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;This table is inside of a cell of another table.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                               &lt;tr&gt;\r
+                                                                       &lt;td&gt;We can type&amp;nbsp;either before or after it though.&lt;/td&gt;\r
+                                                               &lt;/tr&gt;\r
+                                                       &lt;/tbody&gt;\r
+                                               &lt;/table&gt;\r
+                                               &lt;/td&gt;\r
+                                       &lt;/tr&gt;\r
+                               &lt;/tbody&gt;\r
+                       &lt;/table&gt;\r
+\r
+                       &lt;p&gt;Two succesive horizontal lines (&lt;tt&gt;HR&lt;/tt&gt; tags). We can access the space in between:&lt;/p&gt;\r
+\r
+                       &lt;hr /&gt;\r
+                       &lt;hr /&gt;\r
+                       &lt;ol&gt;\r
+                               &lt;li&gt;This numbered list...&lt;/li&gt;\r
+                               &lt;li&gt;...is a neighbour of a horizontal line...&lt;/li&gt;\r
+                               &lt;li&gt;...and another list.&lt;/li&gt;\r
+                       &lt;/ol&gt;\r
+\r
+                       &lt;ul&gt;\r
+                               &lt;li&gt;We can type between the lists...&lt;/li&gt;\r
+                               &lt;li&gt;...thanks to &lt;strong&gt;Magicline&lt;/strong&gt;.&lt;/li&gt;\r
+                       &lt;/ul&gt;\r
+\r
+                       &lt;p&gt;Lorem ipsum dolor sit amet dui. Morbi vel turpis. Nullam et leo. Etiam rutrum, urna tellus dui vel tincidunt mattis egestas, justo fringilla vel, massa. Phasellus.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Quisque iaculis, dui lectus varius vitae, tortor. Proin lacus. Pellentesque ac lacus. Aenean nonummy commodo nec, pede. Etiam blandit risus elit.&lt;/p&gt;\r
+\r
+                       &lt;p&gt;Ut pretium. Vestibulum rutrum in, adipiscing elit. Sed in quam in purus sem vitae pede. Pellentesque bibendum, urna sem vel risus. Vivamus posuere metus. Aliquam gravida iaculis nisl. Nam enim. Aliquam erat ac lacus tellus ac felis.&lt;/p&gt;\r
+\r
+                       &lt;div style=&quot;border: 2px dashed green; background: #ddd; text-align: center;&quot;&gt;\r
+                       &lt;p&gt;This text is wrapped in a&amp;nbsp;&lt;tt&gt;DIV&lt;/tt&gt;&amp;nbsp;element. We can type after this element though.&lt;/p&gt;\r
+                       &lt;/div&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       // This call can be placed at any point after the\r
+                       // <textarea>, or inside a <head><script> in a\r
+                       // window.onload event handler.\r
+\r
+                       CKEDITOR.replace( 'editor2', {\r
+                               extraPlugins: 'magicline',      // Ensure that magicline plugin, which is required for this sample, is loaded.\r
+                               magicline_color: 'blue',        // Blue line\r
+                               allowedContent: true            // Switch off the ACF, so very complex content created to\r
+                                                                                       // show magicline's power isn't filtered.\r
+                       });\r
+\r
+               </script>\r
+       </div>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/maximize/icons/hidpi/maximize.png b/sources/plugins/maximize/icons/hidpi/maximize.png
new file mode 100644 (file)
index 0000000..865c582
Binary files /dev/null and b/sources/plugins/maximize/icons/hidpi/maximize.png differ
diff --git a/sources/plugins/maximize/icons/maximize.png b/sources/plugins/maximize/icons/maximize.png
new file mode 100644 (file)
index 0000000..ab25547
Binary files /dev/null and b/sources/plugins/maximize/icons/maximize.png differ
diff --git a/sources/plugins/maximize/lang/af.js b/sources/plugins/maximize/lang/af.js
new file mode 100644 (file)
index 0000000..5f17e23
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'af', {\r
+       maximize: 'Maksimaliseer',\r
+       minimize: 'Minimaliseer'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ar.js b/sources/plugins/maximize/lang/ar.js
new file mode 100644 (file)
index 0000000..cdfb258
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ar', {\r
+       maximize: 'تكبير',\r
+       minimize: 'تصغير'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/az.js b/sources/plugins/maximize/lang/az.js
new file mode 100644 (file)
index 0000000..d3a92ac
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'az', {\r
+       maximize: 'Aşkarla',\r
+       minimize: 'Gizlət'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/bg.js b/sources/plugins/maximize/lang/bg.js
new file mode 100644 (file)
index 0000000..a56e04e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'bg', {\r
+       maximize: 'Максимизиране',\r
+       minimize: 'Минимизиране'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/bn.js b/sources/plugins/maximize/lang/bn.js
new file mode 100644 (file)
index 0000000..3fd4087
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'bn', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/bs.js b/sources/plugins/maximize/lang/bs.js
new file mode 100644 (file)
index 0000000..cb49710
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'bs', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ca.js b/sources/plugins/maximize/lang/ca.js
new file mode 100644 (file)
index 0000000..fc88615
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ca', {\r
+       maximize: 'Maximitza',\r
+       minimize: 'Minimitza'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/cs.js b/sources/plugins/maximize/lang/cs.js
new file mode 100644 (file)
index 0000000..2234af2
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'cs', {\r
+       maximize: 'Maximalizovat',\r
+       minimize: 'Minimalizovat'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/cy.js b/sources/plugins/maximize/lang/cy.js
new file mode 100644 (file)
index 0000000..c3370b3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'cy', {\r
+       maximize: 'Mwyhau',\r
+       minimize: 'Lleihau'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/da.js b/sources/plugins/maximize/lang/da.js
new file mode 100644 (file)
index 0000000..8dd2d88
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'da', {\r
+       maximize: 'Maksimér',\r
+       minimize: 'Minimér'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/de-ch.js b/sources/plugins/maximize/lang/de-ch.js
new file mode 100644 (file)
index 0000000..440814b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'de-ch', {\r
+       maximize: 'Maximieren',\r
+       minimize: 'Minimieren'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/de.js b/sources/plugins/maximize/lang/de.js
new file mode 100644 (file)
index 0000000..9af6706
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'de', {\r
+       maximize: 'Maximieren',\r
+       minimize: 'Minimieren'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/el.js b/sources/plugins/maximize/lang/el.js
new file mode 100644 (file)
index 0000000..7da1b0b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'el', {\r
+       maximize: 'Μεγιστοποίηση',\r
+       minimize: 'Ελαχιστοποίηση'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/en-au.js b/sources/plugins/maximize/lang/en-au.js
new file mode 100644 (file)
index 0000000..de0310d
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'en-au', {\r
+       maximize: 'Maximize',\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/en-ca.js b/sources/plugins/maximize/lang/en-ca.js
new file mode 100644 (file)
index 0000000..1c48ee0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'en-ca', {\r
+       maximize: 'Maximize',\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/en-gb.js b/sources/plugins/maximize/lang/en-gb.js
new file mode 100644 (file)
index 0000000..433a065
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'en-gb', {\r
+       maximize: 'Maximise',\r
+       minimize: 'Minimise'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/en.js b/sources/plugins/maximize/lang/en.js
new file mode 100644 (file)
index 0000000..1e45418
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'en', {\r
+       maximize: 'Maximize',\r
+       minimize: 'Minimize'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/eo.js b/sources/plugins/maximize/lang/eo.js
new file mode 100644 (file)
index 0000000..852f529
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'eo', {\r
+       maximize: 'Pligrandigi',\r
+       minimize: 'Malgrandigi'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/es.js b/sources/plugins/maximize/lang/es.js
new file mode 100644 (file)
index 0000000..411aae5
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'es', {\r
+       maximize: 'Maximizar',\r
+       minimize: 'Minimizar'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/et.js b/sources/plugins/maximize/lang/et.js
new file mode 100644 (file)
index 0000000..1682ec9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'et', {\r
+       maximize: 'Maksimeerimine',\r
+       minimize: 'Minimeerimine'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/eu.js b/sources/plugins/maximize/lang/eu.js
new file mode 100644 (file)
index 0000000..a25c164
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'eu', {\r
+       maximize: 'Maximizatu',\r
+       minimize: 'Minimizatu'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/fa.js b/sources/plugins/maximize/lang/fa.js
new file mode 100644 (file)
index 0000000..e08e9ea
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'fa', {\r
+       maximize: 'بیشنه کردن',\r
+       minimize: 'کمینه کردن'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/fi.js b/sources/plugins/maximize/lang/fi.js
new file mode 100644 (file)
index 0000000..763eede
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'fi', {\r
+       maximize: 'Suurenna',\r
+       minimize: 'Pienennä'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/fo.js b/sources/plugins/maximize/lang/fo.js
new file mode 100644 (file)
index 0000000..635415a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'fo', {\r
+       maximize: 'Maksimera',\r
+       minimize: 'Minimera'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/fr-ca.js b/sources/plugins/maximize/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..59ed278
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'fr-ca', {\r
+       maximize: 'Maximizer',\r
+       minimize: 'Minimizer'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/fr.js b/sources/plugins/maximize/lang/fr.js
new file mode 100644 (file)
index 0000000..cb3d4dd
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'fr', {\r
+       maximize: 'Agrandir',\r
+       minimize: 'Réduire'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/gl.js b/sources/plugins/maximize/lang/gl.js
new file mode 100644 (file)
index 0000000..79009f8
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'gl', {\r
+       maximize: 'Maximizar',\r
+       minimize: 'Minimizar'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/gu.js b/sources/plugins/maximize/lang/gu.js
new file mode 100644 (file)
index 0000000..bbd4b52
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'gu', {\r
+       maximize: 'મોટું કરવું',\r
+       minimize: 'નાનું કરવું'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/he.js b/sources/plugins/maximize/lang/he.js
new file mode 100644 (file)
index 0000000..d46856b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'he', {\r
+       maximize: 'הגדלה למקסימום',\r
+       minimize: 'הקטנה למינימום'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/hi.js b/sources/plugins/maximize/lang/hi.js
new file mode 100644 (file)
index 0000000..76b0c0c
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'hi', {\r
+       maximize: 'मेक्सिमाईज़',\r
+       minimize: 'मिनिमाईज़'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/hr.js b/sources/plugins/maximize/lang/hr.js
new file mode 100644 (file)
index 0000000..4b7a7b3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'hr', {\r
+       maximize: 'Povećaj',\r
+       minimize: 'Smanji'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/hu.js b/sources/plugins/maximize/lang/hu.js
new file mode 100644 (file)
index 0000000..3e11e22
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'hu', {\r
+       maximize: 'Teljes méret',\r
+       minimize: 'Kis méret'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/id.js b/sources/plugins/maximize/lang/id.js
new file mode 100644 (file)
index 0000000..1a32383
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'id', {\r
+       maximize: 'Memperbesar',\r
+       minimize: 'Memperkecil'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/is.js b/sources/plugins/maximize/lang/is.js
new file mode 100644 (file)
index 0000000..dec813f
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'is', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/it.js b/sources/plugins/maximize/lang/it.js
new file mode 100644 (file)
index 0000000..67a8a29
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'it', {\r
+       maximize: 'Massimizza',\r
+       minimize: 'Minimizza'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ja.js b/sources/plugins/maximize/lang/ja.js
new file mode 100644 (file)
index 0000000..33184da
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ja', {\r
+       maximize: '最大化',\r
+       minimize: '最小化'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ka.js b/sources/plugins/maximize/lang/ka.js
new file mode 100644 (file)
index 0000000..a90fb04
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ka', {\r
+       maximize: 'გადიდება',\r
+       minimize: 'დაპატარავება'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/km.js b/sources/plugins/maximize/lang/km.js
new file mode 100644 (file)
index 0000000..4cda2db
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'km', {\r
+       maximize: 'ពង្រីក​អតិបរមា',\r
+       minimize: 'បង្រួម​អប្បបរមា'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ko.js b/sources/plugins/maximize/lang/ko.js
new file mode 100644 (file)
index 0000000..f4af9d4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ko', {\r
+       maximize: '최대화',\r
+       minimize: '최소화'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ku.js b/sources/plugins/maximize/lang/ku.js
new file mode 100644 (file)
index 0000000..d34e588
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ku', {\r
+       maximize: 'ئەوپەڕی گەورەیی',\r
+       minimize: 'ئەوپەڕی بچووکی'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/lt.js b/sources/plugins/maximize/lang/lt.js
new file mode 100644 (file)
index 0000000..064291b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'lt', {\r
+       maximize: 'Išdidinti',\r
+       minimize: 'Sumažinti'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/lv.js b/sources/plugins/maximize/lang/lv.js
new file mode 100644 (file)
index 0000000..afbbbbe
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'lv', {\r
+       maximize: 'Maksimizēt',\r
+       minimize: 'Minimizēt'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/mk.js b/sources/plugins/maximize/lang/mk.js
new file mode 100644 (file)
index 0000000..69fcfe9
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'mk', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/mn.js b/sources/plugins/maximize/lang/mn.js
new file mode 100644 (file)
index 0000000..6c4a076
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'mn', {\r
+       maximize: 'Дэлгэц дүүргэх',\r
+       minimize: 'Цонхыг багсгаж харуулах'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ms.js b/sources/plugins/maximize/lang/ms.js
new file mode 100644 (file)
index 0000000..0f27d91
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ms', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/nb.js b/sources/plugins/maximize/lang/nb.js
new file mode 100644 (file)
index 0000000..a8ec9dd
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'nb', {\r
+       maximize: 'Maksimer',\r
+       minimize: 'Minimer'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/nl.js b/sources/plugins/maximize/lang/nl.js
new file mode 100644 (file)
index 0000000..978bda0
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'nl', {\r
+       maximize: 'Maximaliseren',\r
+       minimize: 'Minimaliseren'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/no.js b/sources/plugins/maximize/lang/no.js
new file mode 100644 (file)
index 0000000..02afe8a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'no', {\r
+       maximize: 'Maksimer',\r
+       minimize: 'Minimer'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/oc.js b/sources/plugins/maximize/lang/oc.js
new file mode 100644 (file)
index 0000000..cbd94a4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'oc', {\r
+       maximize: 'Maximizar',\r
+       minimize: 'Minimizar'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/pl.js b/sources/plugins/maximize/lang/pl.js
new file mode 100644 (file)
index 0000000..1bf6d07
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'pl', {\r
+       maximize: 'Maksymalizuj',\r
+       minimize: 'Minimalizuj'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/pt-br.js b/sources/plugins/maximize/lang/pt-br.js
new file mode 100644 (file)
index 0000000..e5c2a52
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'pt-br', {\r
+       maximize: 'Maximizar',\r
+       minimize: 'Minimize'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/pt.js b/sources/plugins/maximize/lang/pt.js
new file mode 100644 (file)
index 0000000..a379036
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'pt', {\r
+       maximize: 'Maximizar',\r
+       minimize: 'Minimizar'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ro.js b/sources/plugins/maximize/lang/ro.js
new file mode 100644 (file)
index 0000000..0a3ded6
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ro', {\r
+       maximize: 'Mărește',\r
+       minimize: 'Micșorează'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ru.js b/sources/plugins/maximize/lang/ru.js
new file mode 100644 (file)
index 0000000..30c491a
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ru', {\r
+       maximize: 'Развернуть',\r
+       minimize: 'Свернуть'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/si.js b/sources/plugins/maximize/lang/si.js
new file mode 100644 (file)
index 0000000..a0331ab
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'si', {\r
+       maximize: 'විශාල කිරීම',\r
+       minimize: 'කුඩා කිරීම'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sk.js b/sources/plugins/maximize/lang/sk.js
new file mode 100644 (file)
index 0000000..a9f2515
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sk', {\r
+       maximize: 'Maximalizovať',\r
+       minimize: 'Minimalizovať'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sl.js b/sources/plugins/maximize/lang/sl.js
new file mode 100644 (file)
index 0000000..73d5e91
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sl', {\r
+       maximize: 'Maksimiraj',\r
+       minimize: 'Minimiraj'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sq.js b/sources/plugins/maximize/lang/sq.js
new file mode 100644 (file)
index 0000000..e6b5bc3
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sq', {\r
+       maximize: 'Zmadho',\r
+       minimize: 'Zvogëlo'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sr-latn.js b/sources/plugins/maximize/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..33dcd9e
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sr-latn', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sr.js b/sources/plugins/maximize/lang/sr.js
new file mode 100644 (file)
index 0000000..f1ef2d1
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sr', {\r
+       maximize: 'Maximize', // MISSING\r
+       minimize: 'Minimize' // MISSING\r
+} );\r
diff --git a/sources/plugins/maximize/lang/sv.js b/sources/plugins/maximize/lang/sv.js
new file mode 100644 (file)
index 0000000..d14fb84
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'sv', {\r
+       maximize: 'Maximera',\r
+       minimize: 'Minimera'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/th.js b/sources/plugins/maximize/lang/th.js
new file mode 100644 (file)
index 0000000..df09eef
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'th', {\r
+       maximize: 'ขยายใหญ่',\r
+       minimize: 'ย่อขนาด'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/tr.js b/sources/plugins/maximize/lang/tr.js
new file mode 100644 (file)
index 0000000..90724f4
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'tr', {\r
+       maximize: 'Büyült',\r
+       minimize: 'Küçült'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/tt.js b/sources/plugins/maximize/lang/tt.js
new file mode 100644 (file)
index 0000000..cc92021
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'tt', {\r
+       maximize: 'Зурайту',\r
+       minimize: 'Кечерәйтү'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/ug.js b/sources/plugins/maximize/lang/ug.js
new file mode 100644 (file)
index 0000000..85af046
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'ug', {\r
+       maximize: 'چوڭايت',\r
+       minimize: 'كىچىكلەت'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/uk.js b/sources/plugins/maximize/lang/uk.js
new file mode 100644 (file)
index 0000000..5ca1021
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'uk', {\r
+       maximize: 'Максимізувати',\r
+       minimize: 'Мінімізувати'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/vi.js b/sources/plugins/maximize/lang/vi.js
new file mode 100644 (file)
index 0000000..4ab3a6b
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'vi', {\r
+       maximize: 'Phóng to tối đa',\r
+       minimize: 'Thu nhỏ'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/zh-cn.js b/sources/plugins/maximize/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..f4ddf72
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'zh-cn', {\r
+       maximize: '全屏',\r
+       minimize: '最小化'\r
+} );\r
diff --git a/sources/plugins/maximize/lang/zh.js b/sources/plugins/maximize/lang/zh.js
new file mode 100644 (file)
index 0000000..6bca434
--- /dev/null
@@ -0,0 +1,8 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'maximize', 'zh', {\r
+       maximize: '最大化',\r
+       minimize: '最小化'\r
+} );\r
diff --git a/sources/plugins/maximize/plugin.js b/sources/plugins/maximize/plugin.js
new file mode 100644 (file)
index 0000000..16967a0
--- /dev/null
@@ -0,0 +1,314 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       function protectFormStyles( formElement ) {\r
+               if ( !formElement || formElement.type != CKEDITOR.NODE_ELEMENT || formElement.getName() != 'form' )\r
+                       return [];\r
+\r
+               var hijackRecord = [],\r
+                       hijackNames = [ 'style', 'className' ];\r
+               for ( var i = 0; i < hijackNames.length; i++ ) {\r
+                       var name = hijackNames[ i ];\r
+                       var $node = formElement.$.elements.namedItem( name );\r
+                       if ( $node ) {\r
+                               var hijackNode = new CKEDITOR.dom.element( $node );\r
+                               hijackRecord.push( [ hijackNode, hijackNode.nextSibling ] );\r
+                               hijackNode.remove();\r
+                       }\r
+               }\r
+\r
+               return hijackRecord;\r
+       }\r
+\r
+       function restoreFormStyles( formElement, hijackRecord ) {\r
+               if ( !formElement || formElement.type != CKEDITOR.NODE_ELEMENT || formElement.getName() != 'form' )\r
+                       return;\r
+\r
+               if ( hijackRecord.length > 0 ) {\r
+                       for ( var i = hijackRecord.length - 1; i >= 0; i-- ) {\r
+                               var node = hijackRecord[ i ][ 0 ];\r
+                               var sibling = hijackRecord[ i ][ 1 ];\r
+                               if ( sibling )\r
+                                       node.insertBefore( sibling );\r
+                               else\r
+                                       node.appendTo( formElement );\r
+                       }\r
+               }\r
+       }\r
+\r
+       function saveStyles( element, isInsideEditor ) {\r
+               var data = protectFormStyles( element );\r
+               var retval = {};\r
+\r
+               var $element = element.$;\r
+\r
+               if ( !isInsideEditor ) {\r
+                       retval[ 'class' ] = $element.className || '';\r
+                       $element.className = '';\r
+               }\r
+\r
+               retval.inline = $element.style.cssText || '';\r
+               if ( !isInsideEditor ) // Reset any external styles that might interfere. (#2474)\r
+               $element.style.cssText = 'position: static; overflow: visible';\r
+\r
+               restoreFormStyles( data );\r
+               return retval;\r
+       }\r
+\r
+       function restoreStyles( element, savedStyles ) {\r
+               var data = protectFormStyles( element );\r
+               var $element = element.$;\r
+               if ( 'class' in savedStyles )\r
+                       $element.className = savedStyles[ 'class' ];\r
+               if ( 'inline' in savedStyles )\r
+                       $element.style.cssText = savedStyles.inline;\r
+               restoreFormStyles( data );\r
+       }\r
+\r
+       function refreshCursor( editor ) {\r
+               if ( editor.editable().isInline() )\r
+                       return;\r
+\r
+               // Refresh all editor instances on the page (#5724).\r
+               var all = CKEDITOR.instances;\r
+               for ( var i in all ) {\r
+                       var one = all[ i ];\r
+                       if ( one.mode == 'wysiwyg' && !one.readOnly ) {\r
+                               var body = one.document.getBody();\r
+                               // Refresh 'contentEditable' otherwise\r
+                               // DOM lifting breaks design mode. (#5560)\r
+                               body.setAttribute( 'contentEditable', false );\r
+                               body.setAttribute( 'contentEditable', true );\r
+                       }\r
+               }\r
+\r
+               if ( editor.editable().hasFocus ) {\r
+                       editor.toolbox.focus();\r
+                       editor.focus();\r
+               }\r
+       }\r
+\r
+       CKEDITOR.plugins.add( 'maximize', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'maximize', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       // Maximize plugin isn't available in inline mode yet.\r
+                       if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )\r
+                               return;\r
+\r
+                       var lang = editor.lang;\r
+                       var mainDocument = CKEDITOR.document,\r
+                               mainWindow = mainDocument.getWindow();\r
+\r
+                       // Saved selection and scroll position for the editing area.\r
+                       var savedSelection, savedScroll;\r
+\r
+                       // Saved scroll position for the outer window.\r
+                       var outerScroll;\r
+\r
+                       // Saved resize handler function.\r
+                       function resizeHandler() {\r
+                               var viewPaneSize = mainWindow.getViewPaneSize();\r
+                               editor.resize( viewPaneSize.width, viewPaneSize.height, null, true );\r
+                       }\r
+\r
+                       // Retain state after mode switches.\r
+                       var savedState = CKEDITOR.TRISTATE_OFF;\r
+\r
+                       editor.addCommand( 'maximize', {\r
+                               // Disabled on iOS (#8307).\r
+                               modes: { wysiwyg: !CKEDITOR.env.iOS, source: !CKEDITOR.env.iOS },\r
+                               readOnly: 1,\r
+                               editorFocus: false,\r
+                               exec: function() {\r
+                                       var container = editor.container.getFirst( function( node ) {\r
+                                               return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_inner' );\r
+                                       } );\r
+                                       var contents = editor.ui.space( 'contents' );\r
+\r
+                                       // Save current selection and scroll position in editing area.\r
+                                       if ( editor.mode == 'wysiwyg' ) {\r
+                                               var selection = editor.getSelection();\r
+                                               savedSelection = selection && selection.getRanges();\r
+                                               savedScroll = mainWindow.getScrollPosition();\r
+                                       } else {\r
+                                               var $textarea = editor.editable().$;\r
+                                               savedSelection = !CKEDITOR.env.ie && [ $textarea.selectionStart, $textarea.selectionEnd ];\r
+                                               savedScroll = [ $textarea.scrollLeft, $textarea.scrollTop ];\r
+                                       }\r
+\r
+                                       // Go fullscreen if the state is off.\r
+                                       if ( this.state == CKEDITOR.TRISTATE_OFF ) {\r
+                                               // Add event handler for resizing.\r
+                                               mainWindow.on( 'resize', resizeHandler );\r
+\r
+                                               // Save the scroll bar position.\r
+                                               outerScroll = mainWindow.getScrollPosition();\r
+\r
+                                               // Save and reset the styles for the entire node tree.\r
+                                               var currentNode = editor.container;\r
+                                               while ( ( currentNode = currentNode.getParent() ) ) {\r
+                                                       currentNode.setCustomData( 'maximize_saved_styles', saveStyles( currentNode ) );\r
+                                                       // Show under floatpanels (-1) and context menu (-2).\r
+                                                       currentNode.setStyle( 'z-index', editor.config.baseFloatZIndex - 5 );\r
+                                               }\r
+                                               contents.setCustomData( 'maximize_saved_styles', saveStyles( contents, true ) );\r
+                                               container.setCustomData( 'maximize_saved_styles', saveStyles( container, true ) );\r
+\r
+                                               // Hide scroll bars.\r
+                                               var styles = {\r
+                                                       overflow: CKEDITOR.env.webkit ? '' : 'hidden', // #6896\r
+                                                       width: 0,\r
+                                                       height: 0\r
+                                               };\r
+\r
+                                               mainDocument.getDocumentElement().setStyles( styles );\r
+                                               !CKEDITOR.env.gecko && mainDocument.getDocumentElement().setStyle( 'position', 'fixed' );\r
+                                               !( CKEDITOR.env.gecko && CKEDITOR.env.quirks ) && mainDocument.getBody().setStyles( styles );\r
+\r
+                                               // Scroll to the top left (IE needs some time for it - #4923).\r
+                                               CKEDITOR.env.ie ? setTimeout( function() {\r
+                                                       mainWindow.$.scrollTo( 0, 0 );\r
+                                               }, 0 ) : mainWindow.$.scrollTo( 0, 0 );\r
+\r
+                                               // Resize and move to top left.\r
+                                               // Special treatment for FF Quirks (#7284)\r
+                                               container.setStyle( 'position', CKEDITOR.env.gecko && CKEDITOR.env.quirks ? 'fixed' : 'absolute' );\r
+                                               container.$.offsetLeft; // SAFARI BUG: See #2066.\r
+                                               container.setStyles( {\r
+                                                       // Show under floatpanels (-1) and context menu (-2).\r
+                                                       'z-index': editor.config.baseFloatZIndex - 5,\r
+                                                       left: '0px',\r
+                                                       top: '0px'\r
+                                               } );\r
+\r
+                                               // Add cke_maximized class before resize handle since that will change things sizes (#5580)\r
+                                               container.addClass( 'cke_maximized' );\r
+\r
+                                               resizeHandler();\r
+\r
+                                               // Still not top left? Fix it. (Bug #174)\r
+                                               var offset = container.getDocumentPosition();\r
+                                               container.setStyles( {\r
+                                                       left: ( -1 * offset.x ) + 'px',\r
+                                                       top: ( -1 * offset.y ) + 'px'\r
+                                               } );\r
+\r
+                                               // Fixing positioning editor chrome in Firefox break design mode. (#5149)\r
+                                               CKEDITOR.env.gecko && refreshCursor( editor );\r
+                                       }\r
+                                       // Restore from fullscreen if the state is on.\r
+                                       else if ( this.state == CKEDITOR.TRISTATE_ON ) {\r
+                                               // Remove event handler for resizing.\r
+                                               mainWindow.removeListener( 'resize', resizeHandler );\r
+\r
+                                               // Restore CSS styles for the entire node tree.\r
+                                               var editorElements = [ contents, container ];\r
+                                               for ( var i = 0; i < editorElements.length; i++ ) {\r
+                                                       restoreStyles( editorElements[ i ], editorElements[ i ].getCustomData( 'maximize_saved_styles' ) );\r
+                                                       editorElements[ i ].removeCustomData( 'maximize_saved_styles' );\r
+                                               }\r
+\r
+                                               currentNode = editor.container;\r
+                                               while ( ( currentNode = currentNode.getParent() ) ) {\r
+                                                       restoreStyles( currentNode, currentNode.getCustomData( 'maximize_saved_styles' ) );\r
+                                                       currentNode.removeCustomData( 'maximize_saved_styles' );\r
+                                               }\r
+\r
+                                               // Restore the window scroll position.\r
+                                               CKEDITOR.env.ie ? setTimeout( function() {\r
+                                                       mainWindow.$.scrollTo( outerScroll.x, outerScroll.y );\r
+                                               }, 0 ) : mainWindow.$.scrollTo( outerScroll.x, outerScroll.y );\r
+\r
+                                               // Remove cke_maximized class.\r
+                                               container.removeClass( 'cke_maximized' );\r
+\r
+                                               // Webkit requires a re-layout on editor chrome. (#6695)\r
+                                               if ( CKEDITOR.env.webkit ) {\r
+                                                       container.setStyle( 'display', 'inline' );\r
+                                                       setTimeout( function() {\r
+                                                               container.setStyle( 'display', 'block' );\r
+                                                       }, 0 );\r
+                                               }\r
+\r
+                                               // Emit a resize event, because this time the size is modified in\r
+                                               // restoreStyles.\r
+                                               editor.fire( 'resize', {\r
+                                                       outerHeight: editor.container.$.offsetHeight,\r
+                                                       contentsHeight: contents.$.offsetHeight,\r
+                                                       outerWidth: editor.container.$.offsetWidth\r
+                                               } );\r
+                                       }\r
+\r
+                                       this.toggleState();\r
+\r
+                                       // Toggle button label.\r
+                                       var button = this.uiItems[ 0 ];\r
+                                       // Only try to change the button if it exists (#6166)\r
+                                       if ( button ) {\r
+                                               var label = ( this.state == CKEDITOR.TRISTATE_OFF ) ? lang.maximize.maximize : lang.maximize.minimize;\r
+                                               var buttonNode = CKEDITOR.document.getById( button._.id );\r
+                                               buttonNode.getChild( 1 ).setHtml( label );\r
+                                               buttonNode.setAttribute( 'title', label );\r
+                                               buttonNode.setAttribute( 'href', 'javascript:void("' + label + '");' ); // jshint ignore:line\r
+                                       }\r
+\r
+                                       // Restore selection and scroll position in editing area.\r
+                                       if ( editor.mode == 'wysiwyg' ) {\r
+                                               if ( savedSelection ) {\r
+                                                       // Fixing positioning editor chrome in Firefox break design mode. (#5149)\r
+                                                       CKEDITOR.env.gecko && refreshCursor( editor );\r
+\r
+                                                       editor.getSelection().selectRanges( savedSelection );\r
+                                                       var element = editor.getSelection().getStartElement();\r
+                                                       element && element.scrollIntoView( true );\r
+                                               } else {\r
+                                                       mainWindow.$.scrollTo( savedScroll.x, savedScroll.y );\r
+                                               }\r
+                                       } else {\r
+                                               if ( savedSelection ) {\r
+                                                       $textarea.selectionStart = savedSelection[ 0 ];\r
+                                                       $textarea.selectionEnd = savedSelection[ 1 ];\r
+                                               }\r
+                                               $textarea.scrollLeft = savedScroll[ 0 ];\r
+                                               $textarea.scrollTop = savedScroll[ 1 ];\r
+                                       }\r
+\r
+                                       savedSelection = savedScroll = null;\r
+                                       savedState = this.state;\r
+\r
+                                       editor.fire( 'maximize', this.state );\r
+                               },\r
+                               canUndo: false\r
+                       } );\r
+\r
+                       editor.ui.addButton && editor.ui.addButton( 'Maximize', {\r
+                               label: lang.maximize.maximize,\r
+                               command: 'maximize',\r
+                               toolbar: 'tools,10'\r
+                       } );\r
+\r
+                       // Restore the command state after mode change, unless it has been changed to disabled (#6467)\r
+                       editor.on( 'mode', function() {\r
+                               var command = editor.getCommand( 'maximize' );\r
+                               command.setState( command.state == CKEDITOR.TRISTATE_DISABLED ? CKEDITOR.TRISTATE_DISABLED : savedState );\r
+                       }, null, null, 100 );\r
+               }\r
+       } );\r
+} )();\r
+\r
+/**\r
+ * Event fired when the maximize command is called.\r
+ * It also indicates whether an editor is maximized or not.\r
+ *\r
+ * @event maximize\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {Number} data Current state of the command. See {@link CKEDITOR#TRISTATE_ON} and {@link CKEDITOR#TRISTATE_OFF}.\r
+ */\r
diff --git a/sources/plugins/menu/plugin.js b/sources/plugins/menu/plugin.js
new file mode 100644 (file)
index 0000000..1312a62
--- /dev/null
@@ -0,0 +1,572 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'menu', {\r
+       requires: 'floatpanel',\r
+\r
+       beforeInit: function( editor ) {\r
+               var groups = editor.config.menu_groups.split( ',' ),\r
+                       groupsOrder = editor._.menuGroups = {},\r
+                       menuItems = editor._.menuItems = {};\r
+\r
+               for ( var i = 0; i < groups.length; i++ )\r
+                       groupsOrder[ groups[ i ] ] = i + 1;\r
+\r
+               /**\r
+                * Registers an item group to the editor context menu in order to make it\r
+                * possible to associate it with menu items later.\r
+                *\r
+                * @param {String} name Specify a group name.\r
+                * @param {Number} [order=100] Define the display sequence of this group\r
+                * inside the menu. A smaller value gets displayed first.\r
+                * @member CKEDITOR.editor\r
+                */\r
+               editor.addMenuGroup = function( name, order ) {\r
+                       groupsOrder[ name ] = order || 100;\r
+               };\r
+\r
+               /**\r
+                * Adds an item from the specified definition to the editor context menu.\r
+                *\r
+                * @method\r
+                * @param {String} name The menu item name.\r
+                * @param {Object} definition The menu item definition.\r
+                * @member CKEDITOR.editor\r
+                */\r
+               editor.addMenuItem = function( name, definition ) {\r
+                       if ( groupsOrder[ definition.group ] )\r
+                               menuItems[ name ] = new CKEDITOR.menuItem( this, name, definition );\r
+               };\r
+\r
+               /**\r
+                * Adds one or more items from the specified definition object to the editor context menu.\r
+                *\r
+                * @method\r
+                * @param {Object} definitions Object where keys are used as itemName and corresponding values as definition for a {@link #addMenuItem} call.\r
+                * @member CKEDITOR.editor\r
+                */\r
+               editor.addMenuItems = function( definitions ) {\r
+                       for ( var itemName in definitions ) {\r
+                               this.addMenuItem( itemName, definitions[ itemName ] );\r
+                       }\r
+               };\r
+\r
+               /**\r
+                * Retrieves a particular menu item definition from the editor context menu.\r
+                *\r
+                * @method\r
+                * @param {String} name The name of the desired menu item.\r
+                * @returns {Object}\r
+                * @member CKEDITOR.editor\r
+                */\r
+               editor.getMenuItem = function( name ) {\r
+                       return menuItems[ name ];\r
+               };\r
+\r
+               /**\r
+                * Removes a particular menu item added before from the editor context menu.\r
+                *\r
+                * @since 3.6.1\r
+                * @method\r
+                * @param {String} name The name of the desired menu item.\r
+                * @member CKEDITOR.editor\r
+                */\r
+               editor.removeMenuItem = function( name ) {\r
+                       delete menuItems[ name ];\r
+               };\r
+       }\r
+} );\r
+\r
+( function() {\r
+       var menuItemSource = '<span class="cke_menuitem">' +\r
+               '<a id="{id}"' +\r
+               ' class="cke_menubutton cke_menubutton__{name} cke_menubutton_{state} {cls}" href="{href}"' +\r
+               ' title="{title}"' +\r
+               ' tabindex="-1"' +\r
+               ' _cke_focus=1' +\r
+               ' hidefocus="true"' +\r
+               ' role="{role}"' +\r
+               ' aria-label="{label}"' +\r
+               ' aria-describedby="{id}_description"' +\r
+               ' aria-haspopup="{hasPopup}"' +\r
+               ' aria-disabled="{disabled}"' +\r
+               ' {ariaChecked}' +\r
+               ' draggable="false"';\r
+\r
+       // Some browsers don't cancel key events in the keydown but in the\r
+       // keypress.\r
+       // TODO: Check if really needed.\r
+       if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )\r
+               menuItemSource += ' onkeypress="return false;"';\r
+\r
+       // With Firefox, we need to force the button to redraw, otherwise it\r
+       // will remain in the focus state. Also we some extra help to prevent dragging (#10373).\r
+       if ( CKEDITOR.env.gecko ) {\r
+               menuItemSource += ( ' onblur="this.style.cssText = this.style.cssText;"' +\r
+                       ' ondragstart="return false;"' );\r
+       }\r
+\r
+       // #188\r
+       menuItemSource += ' onmouseover="CKEDITOR.tools.callFunction({hoverFn},{index});"' +\r
+                       ' onmouseout="CKEDITOR.tools.callFunction({moveOutFn},{index});" ' +\r
+                       ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) +\r
+                               '="CKEDITOR.tools.callFunction({clickFn},{index}); return false;"' +\r
+                       '>';\r
+\r
+       menuItemSource +=\r
+                               //'' +\r
+                               '<span class="cke_menubutton_inner">' +\r
+                                       '<span class="cke_menubutton_icon">' +\r
+                                               '<span class="cke_button_icon cke_button__{iconName}_icon" style="{iconStyle}"></span>' +\r
+                                       '</span>' +\r
+                                       '<span class="cke_menubutton_label">' +\r
+                                               '{label}' +\r
+                                       '</span>' +\r
+                                       '{shortcutHtml}' +\r
+                                       '{arrowHtml}' +\r
+                               '</span>' +\r
+                       '</a><span id="{id}_description" class="cke_voice_label" aria-hidden="false">{ariaShortcut}</span></span>';\r
+\r
+       var menuArrowSource = '<span class="cke_menuarrow">' +\r
+                               '<span>{label}</span>' +\r
+                       '</span>';\r
+\r
+       var menuShortcutSource = '<span class="cke_menubutton_label cke_menubutton_shortcut">' +\r
+                               '{shortcut}' +\r
+                       '</span>';\r
+\r
+       var menuItemTpl = CKEDITOR.addTemplate( 'menuItem', menuItemSource ),\r
+               menuArrowTpl = CKEDITOR.addTemplate( 'menuArrow', menuArrowSource ),\r
+               menuShortcutTpl = CKEDITOR.addTemplate( 'menuShortcut', menuShortcutSource );\r
+\r
+       /**\r
+        * @class\r
+        * @todo\r
+        */\r
+       CKEDITOR.menu = CKEDITOR.tools.createClass( {\r
+               /**\r
+                * @constructor\r
+                */\r
+               $: function( editor, definition ) {\r
+                       definition = this._.definition = definition || {};\r
+                       this.id = CKEDITOR.tools.getNextId();\r
+\r
+                       this.editor = editor;\r
+                       this.items = [];\r
+                       this._.listeners = [];\r
+\r
+                       this._.level = definition.level || 1;\r
+\r
+                       var panelDefinition = CKEDITOR.tools.extend( {}, definition.panel, {\r
+                               css: [ CKEDITOR.skin.getPath( 'editor' ) ],\r
+                               level: this._.level - 1,\r
+                               block: {}\r
+                       } );\r
+\r
+                       var attrs = panelDefinition.block.attributes = ( panelDefinition.attributes || {} );\r
+                       // Provide default role of 'menu'.\r
+                       !attrs.role && ( attrs.role = 'menu' );\r
+                       this._.panelDefinition = panelDefinition;\r
+               },\r
+\r
+               _: {\r
+                       onShow: function() {\r
+                               var selection = this.editor.getSelection(),\r
+                                       start = selection && selection.getStartElement(),\r
+                                       path = this.editor.elementPath(),\r
+                                       listeners = this._.listeners;\r
+\r
+                               this.removeAll();\r
+                               // Call all listeners, filling the list of items to be displayed.\r
+                               for ( var i = 0; i < listeners.length; i++ ) {\r
+                                       var listenerItems = listeners[ i ]( start, selection, path );\r
+\r
+                                       if ( listenerItems ) {\r
+                                               for ( var itemName in listenerItems ) {\r
+                                                       var item = this.editor.getMenuItem( itemName );\r
+\r
+                                                       if ( item && ( !item.command || this.editor.getCommand( item.command ).state ) ) {\r
+                                                               item.state = listenerItems[ itemName ];\r
+                                                               this.add( item );\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+                       },\r
+\r
+                       onClick: function( item ) {\r
+                               this.hide();\r
+\r
+                               if ( item.onClick )\r
+                                       item.onClick();\r
+                               else if ( item.command )\r
+                                       this.editor.execCommand( item.command );\r
+                       },\r
+\r
+                       onEscape: function( keystroke ) {\r
+                               var parent = this.parent;\r
+                               // 1. If it's sub-menu, close it, with focus restored on this.\r
+                               // 2. In case of a top-menu, close it, with focus returned to page.\r
+                               if ( parent )\r
+                                       parent._.panel.hideChild( 1 );\r
+                               else if ( keystroke == 27 )\r
+                                       this.hide( 1 );\r
+\r
+                               return false;\r
+                       },\r
+\r
+                       onHide: function() {\r
+                               this.onHide && this.onHide();\r
+                       },\r
+\r
+                       showSubMenu: function( index ) {\r
+                               var menu = this._.subMenu,\r
+                                       item = this.items[ index ],\r
+                                       subItemDefs = item.getItems && item.getItems();\r
+\r
+                               // If this item has no subitems, we just hide the submenu, if\r
+                               // available, and return back.\r
+                               if ( !subItemDefs ) {\r
+                                       // Hide sub menu with focus returned.\r
+                                       this._.panel.hideChild( 1 );\r
+                                       return;\r
+                               }\r
+\r
+                               // Create the submenu, if not available, or clean the existing\r
+                               // one.\r
+                               if ( menu )\r
+                                       menu.removeAll();\r
+                               else {\r
+                                       menu = this._.subMenu = new CKEDITOR.menu( this.editor, CKEDITOR.tools.extend( {}, this._.definition, { level: this._.level + 1 }, true ) );\r
+                                       menu.parent = this;\r
+                                       menu._.onClick = CKEDITOR.tools.bind( this._.onClick, this );\r
+                               }\r
+\r
+                               // Add all submenu items to the menu.\r
+                               for ( var subItemName in subItemDefs ) {\r
+                                       var subItem = this.editor.getMenuItem( subItemName );\r
+                                       if ( subItem ) {\r
+                                               subItem.state = subItemDefs[ subItemName ];\r
+                                               menu.add( subItem );\r
+                                       }\r
+                               }\r
+\r
+                               // Get the element representing the current item.\r
+                               var element = this._.panel.getBlock( this.id ).element.getDocument().getById( this.id + String( index ) );\r
+\r
+                               // Show the submenu.\r
+                               // This timeout is needed to give time for the sub-menu get\r
+                               // focus when JAWS is running. (#9844)\r
+                               setTimeout( function() {\r
+                                       menu.show( element, 2 );\r
+                               }, 0 );\r
+                       }\r
+               },\r
+\r
+               proto: {\r
+                       /**\r
+                        * Adds an item.\r
+                        *\r
+                        * @param item\r
+                        */\r
+                       add: function( item ) {\r
+                               // Later we may sort the items, but Array#sort is not stable in\r
+                               // some browsers, here we're forcing the original sequence with\r
+                               // 'order' attribute if it hasn't been assigned. (#3868)\r
+                               if ( !item.order )\r
+                                       item.order = this.items.length;\r
+\r
+                               this.items.push( item );\r
+                       },\r
+\r
+                       /**\r
+                        * Removes all items.\r
+                        */\r
+                       removeAll: function() {\r
+                               this.items = [];\r
+                       },\r
+\r
+                       /**\r
+                        * Shows the menu in given location.\r
+                        *\r
+                        * @param {CKEDITOR.dom.element} offsetParent\r
+                        * @param {Number} [corner]\r
+                        * @param {Number} [offsetX]\r
+                        * @param {Number} [offsetY]\r
+                        */\r
+                       show: function( offsetParent, corner, offsetX, offsetY ) {\r
+                               // Not for sub menu.\r
+                               if ( !this.parent ) {\r
+                                       this._.onShow();\r
+                                       // Don't menu with zero items.\r
+                                       if ( !this.items.length )\r
+                                               return;\r
+                               }\r
+\r
+                               corner = corner || ( this.editor.lang.dir == 'rtl' ? 2 : 1 );\r
+\r
+                               var items = this.items,\r
+                                       editor = this.editor,\r
+                                       panel = this._.panel,\r
+                                       element = this._.element;\r
+\r
+                               // Create the floating panel for this menu.\r
+                               if ( !panel ) {\r
+                                       panel = this._.panel = new CKEDITOR.ui.floatPanel( this.editor, CKEDITOR.document.getBody(), this._.panelDefinition, this._.level );\r
+\r
+                                       panel.onEscape = CKEDITOR.tools.bind( function( keystroke ) {\r
+                                               if ( this._.onEscape( keystroke ) === false )\r
+                                                       return false;\r
+                                       }, this );\r
+\r
+                                       panel.onShow = function() {\r
+                                               // Menu need CSS resets, compensate class name.\r
+                                               var holder = panel._.panel.getHolderElement();\r
+                                               holder.getParent().addClass( 'cke' ).addClass( 'cke_reset_all' );\r
+                                       };\r
+\r
+                                       panel.onHide = CKEDITOR.tools.bind( function() {\r
+                                               this._.onHide && this._.onHide();\r
+                                       }, this );\r
+\r
+                                       // Create an autosize block inside the panel.\r
+                                       var block = panel.addBlock( this.id, this._.panelDefinition.block );\r
+                                       block.autoSize = true;\r
+\r
+                                       var keys = block.keys;\r
+                                       keys[ 40 ] = 'next'; // ARROW-DOWN\r
+                                       keys[ 9 ] = 'next'; // TAB\r
+                                       keys[ 38 ] = 'prev'; // ARROW-UP\r
+                                       keys[ CKEDITOR.SHIFT + 9 ] = 'prev'; // SHIFT + TAB\r
+                                       keys[ ( editor.lang.dir == 'rtl' ? 37 : 39 ) ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // ARROW-RIGHT/ARROW-LEFT(rtl)\r
+                                       keys[ 32 ] = CKEDITOR.env.ie ? 'mouseup' : 'click'; // SPACE\r
+                                       CKEDITOR.env.ie && ( keys[ 13 ] = 'mouseup' ); // Manage ENTER, since onclick is blocked in IE (#8041).\r
+\r
+                                       element = this._.element = block.element;\r
+\r
+                                       var elementDoc = element.getDocument();\r
+                                       elementDoc.getBody().setStyle( 'overflow', 'hidden' );\r
+                                       elementDoc.getElementsByTag( 'html' ).getItem( 0 ).setStyle( 'overflow', 'hidden' );\r
+\r
+                                       this._.itemOverFn = CKEDITOR.tools.addFunction( function( index ) {\r
+                                               clearTimeout( this._.showSubTimeout );\r
+                                               this._.showSubTimeout = CKEDITOR.tools.setTimeout( this._.showSubMenu, editor.config.menu_subMenuDelay || 400, this, [ index ] );\r
+                                       }, this );\r
+\r
+                                       this._.itemOutFn = CKEDITOR.tools.addFunction( function() {\r
+                                               clearTimeout( this._.showSubTimeout );\r
+                                       }, this );\r
+\r
+                                       this._.itemClickFn = CKEDITOR.tools.addFunction( function( index ) {\r
+                                               var item = this.items[ index ];\r
+\r
+                                               if ( item.state == CKEDITOR.TRISTATE_DISABLED ) {\r
+                                                       this.hide( 1 );\r
+                                                       return;\r
+                                               }\r
+\r
+                                               if ( item.getItems )\r
+                                                       this._.showSubMenu( index );\r
+                                               else\r
+                                                       this._.onClick( item );\r
+                                       }, this );\r
+                               }\r
+\r
+                               // Put the items in the right order.\r
+                               sortItems( items );\r
+\r
+                               // Apply the editor mixed direction status to menu.\r
+                               var path = editor.elementPath(),\r
+                                       mixedDirCls = ( path && path.direction() != editor.lang.dir ) ? ' cke_mixed_dir_content' : '';\r
+\r
+                               // Build the HTML that composes the menu and its items.\r
+                               var output = [ '<div class="cke_menu' + mixedDirCls + '" role="presentation">' ];\r
+\r
+                               var length = items.length,\r
+                                       lastGroup = length && items[ 0 ].group;\r
+\r
+                               for ( var i = 0; i < length; i++ ) {\r
+                                       var item = items[ i ];\r
+                                       if ( lastGroup != item.group ) {\r
+                                               output.push( '<div class="cke_menuseparator" role="separator"></div>' );\r
+                                               lastGroup = item.group;\r
+                                       }\r
+\r
+                                       item.render( this, i, output );\r
+                               }\r
+\r
+                               output.push( '</div>' );\r
+\r
+                               // Inject the HTML inside the panel.\r
+                               element.setHtml( output.join( '' ) );\r
+\r
+                               CKEDITOR.ui.fire( 'ready', this );\r
+\r
+                               // Show the panel.\r
+                               if ( this.parent )\r
+                                       this.parent._.panel.showAsChild( panel, this.id, offsetParent, corner, offsetX, offsetY );\r
+                               else\r
+                                       panel.showBlock( this.id, offsetParent, corner, offsetX, offsetY );\r
+\r
+                               editor.fire( 'menuShow', [ panel ] );\r
+                       },\r
+\r
+                       /**\r
+                        * Adds a callback executed on opening the menu. Items\r
+                        * returned by that callback are added to the menu.\r
+                        *\r
+                        * @param {Function} listenerFn\r
+                        * @param {CKEDITOR.dom.element} listenerFn.startElement The selection start anchor element.\r
+                        * @param {CKEDITOR.dom.selection} listenerFn.selection The current selection.\r
+                        * @param {CKEDITOR.dom.elementPath} listenerFn.path The current elements path.\r
+                        * @param listenerFn.return Object (`commandName` => `state`) of items that should be added to the menu.\r
+                        */\r
+                       addListener: function( listenerFn ) {\r
+                               this._.listeners.push( listenerFn );\r
+                       },\r
+\r
+                       /**\r
+                        * Hides the menu.\r
+                        *\r
+                        * @param {Boolean} [returnFocus]\r
+                        */\r
+                       hide: function( returnFocus ) {\r
+                               this._.onHide && this._.onHide();\r
+                               this._.panel && this._.panel.hide( returnFocus );\r
+                       }\r
+               }\r
+       } );\r
+\r
+       function sortItems( items ) {\r
+               items.sort( function( itemA, itemB ) {\r
+                       if ( itemA.group < itemB.group )\r
+                               return -1;\r
+                       else if ( itemA.group > itemB.group )\r
+                               return 1;\r
+\r
+                       return itemA.order < itemB.order ? -1 : itemA.order > itemB.order ? 1 : 0;\r
+               } );\r
+       }\r
+\r
+       /**\r
+        * @class\r
+        * @todo\r
+        */\r
+       CKEDITOR.menuItem = CKEDITOR.tools.createClass( {\r
+               $: function( editor, name, definition ) {\r
+                       CKEDITOR.tools.extend( this, definition,\r
+                       // Defaults\r
+                       {\r
+                               order: 0,\r
+                               className: 'cke_menubutton__' + name\r
+                       } );\r
+\r
+                       // Transform the group name into its order number.\r
+                       this.group = editor._.menuGroups[ this.group ];\r
+\r
+                       this.editor = editor;\r
+                       this.name = name;\r
+               },\r
+\r
+               proto: {\r
+                       render: function( menu, index, output ) {\r
+                               var id = menu.id + String( index ),\r
+                                       state = ( typeof this.state == 'undefined' ) ? CKEDITOR.TRISTATE_OFF : this.state,\r
+                                       ariaChecked = '',\r
+                                       editor = this.editor,\r
+                                       keystroke,\r
+                                       command,\r
+                                       shortcut;\r
+\r
+                               var stateName = state == CKEDITOR.TRISTATE_ON ? 'on' : state == CKEDITOR.TRISTATE_DISABLED ? 'disabled' : 'off';\r
+\r
+                               if ( this.role in { menuitemcheckbox: 1, menuitemradio: 1 } )\r
+                                       ariaChecked = ' aria-checked="' + ( state == CKEDITOR.TRISTATE_ON ? 'true' : 'false' ) + '"';\r
+\r
+                               var hasSubMenu = this.getItems;\r
+                               // ltr: BLACK LEFT-POINTING POINTER\r
+                               // rtl: BLACK RIGHT-POINTING POINTER\r
+                               var arrowLabel = '&#' + ( this.editor.lang.dir == 'rtl' ? '9668' : '9658' ) + ';';\r
+\r
+                               var iconName = this.name;\r
+                               if ( this.icon && !( /\./ ).test( this.icon ) )\r
+                                       iconName = this.icon;\r
+\r
+                               if ( this.command ) {\r
+                                       command = editor.getCommand( this.command );\r
+                                       keystroke = editor.getCommandKeystroke( command );\r
+\r
+                                       if ( keystroke ) {\r
+                                               shortcut = CKEDITOR.tools.keystrokeToString( editor.lang.common.keyboard, keystroke );\r
+                                       }\r
+                               }\r
+\r
+                               var params = {\r
+                                       id: id,\r
+                                       name: this.name,\r
+                                       iconName: iconName,\r
+                                       label: this.label,\r
+                                       cls: this.className || '',\r
+                                       state: stateName,\r
+                                       hasPopup: hasSubMenu ? 'true' : 'false',\r
+                                       disabled: state == CKEDITOR.TRISTATE_DISABLED,\r
+                                       title: this.label + ( shortcut ? ' (' + shortcut.display + ')' : '' ),\r
+                                       ariaShortcut: shortcut ? editor.lang.common.keyboardShortcut + ' ' + shortcut.aria : '',\r
+                                       href: 'javascript:void(\'' + ( this.label || '' ).replace( "'" + '' ) + '\')', // jshint ignore:line\r
+                                       hoverFn: menu._.itemOverFn,\r
+                                       moveOutFn: menu._.itemOutFn,\r
+                                       clickFn: menu._.itemClickFn,\r
+                                       index: index,\r
+                                       iconStyle: CKEDITOR.skin.getIconStyle( iconName, ( this.editor.lang.dir == 'rtl' ), iconName == this.icon ? null : this.icon, this.iconOffset ),\r
+                                       shortcutHtml: shortcut ? menuShortcutTpl.output( { shortcut: shortcut.display } ) : '',\r
+                                       arrowHtml: hasSubMenu ? menuArrowTpl.output( { label: arrowLabel } ) : '',\r
+                                       role: this.role ? this.role : 'menuitem',\r
+                                       ariaChecked: ariaChecked\r
+                               };\r
+\r
+                               menuItemTpl.output( params, output );\r
+                       }\r
+               }\r
+       } );\r
+\r
+} )();\r
+\r
+\r
+/**\r
+ * The amount of time, in milliseconds, the editor waits before displaying submenu\r
+ * options when moving the mouse over options that contain submenus, like the\r
+ * "Cell Properties" entry for tables.\r
+ *\r
+ *             // Remove the submenu delay.\r
+ *             config.menu_subMenuDelay = 0;\r
+ *\r
+ * @cfg {Number} [menu_subMenuDelay=400]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Fired when a menu is shown.\r
+ *\r
+ * @event menuShow\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {CKEDITOR.ui.panel[]} data\r
+ */\r
+\r
+/**\r
+ * A comma separated list of items group names to be displayed in the context\r
+ * menu. The order of items will reflect the order specified in this list if\r
+ * no priority was defined in the groups.\r
+ *\r
+ *             config.menu_groups = 'clipboard,table,anchor,link,image';\r
+ *\r
+ * @cfg {String} [menu_groups=see source]\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.menu_groups = 'clipboard,' +\r
+       'form,' +\r
+       'tablecell,tablecellproperties,tablerow,tablecolumn,table,' +\r
+       'anchor,link,image,flash,' +\r
+       'checkbox,radio,textfield,hiddenfield,imagebutton,button,select,textarea,div';\r
diff --git a/sources/plugins/oembed/LICENSE.md b/sources/plugins/oembed/LICENSE.md
new file mode 100644 (file)
index 0000000..be0064f
--- /dev/null
@@ -0,0 +1,21 @@
+The MIT License (MIT)\r
+\r
+Copyright (c) Ingo Herbote\r
+\r
+Permission is hereby granted, free of charge, to any person obtaining a copy\r
+of this software and associated documentation files (the "Software"), to deal\r
+in the Software without restriction, including without limitation the rights\r
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
+copies of the Software, and to permit persons to whom the Software is\r
+furnished to do so, subject to the following conditions:\r
+\r
+The above copyright notice and this permission notice shall be included in all\r
+copies or substantial portions of the Software.\r
+\r
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\r
+SOFTWARE.\r
diff --git a/sources/plugins/oembed/README.md b/sources/plugins/oembed/README.md
new file mode 100644 (file)
index 0000000..64c729c
--- /dev/null
@@ -0,0 +1,201 @@
+CKEditor-oEmbed-Plugin\r
+======================\r
+\r
+oEmbed Plugin for CKEditor\r
+\r
+This Plugin allows to insert embedded content (such as photos, videos, audio, and other rich media) via the OEmbed API. You only have to provide the url to the site (It works also when the url is shortened) you want to embed and the plugin does the rest.\r
+\r
+This Plugin uses the jquery-oembed-all Plugin  located at https://github.com/starfishmod/jquery-oembed-all.\r
+\r
+####Demo\r
+\r
+http://w8tcha.github.com/CKEditor-oEmbed-Plugin/\r
+\r
+####Currently Supported Sites...\r
+\r
+###Video\r
+* Youtube - oembed - YQL\r
+* Blip - oEmbed\r
+* Hulu - oEmbed\r
+* Vimeo - oEmbed\r
+* National film board of Canada - oEmbed\r
+* Qik - oEmbed\r
+* Dotsub - oEmbed\r
+* Clikthrough - oEmbed\r
+* Kino Map - oEmbed\r
+* Funny Or Die - Embedded\r
+* College Humour - Embedded\r
+* Metacafe - Embedded\r
+* embedr - Embedded\r
+* 5min - oEmbed is XML only - using YQL to translate it\r
+* ustream.tv - oEmbed is not JSONP enabled - using YQL to translate it\r
+* viddler - OGP\r
+* twitvid - Embedded\r
+* bambuser - Embedded\r
+* xtranormal - Embedded\r
+* Gametrailers - Embedded\r
+* Vzarr - Embedded\r
+* VHX - oembed\r
+* bambuser - oembed\r
+* dailymotion.com - oembed\r
+* animoto - oembed\r
+* justin.tv - YQL JSON\r
+* livestream - OGP\r
+* scivee - embedded\r
+* veoh - embedded\r
+* minoto-video - oembed using YQL\r
+* TrailerAddict - OGP\r
+* vodpod - oembed YQL - broken as the oembed has absolute positioning which breaks the display\r
+* fora.tv -OGP YQL\r
+* TED - OGP YQL\r
+* Aniboom - embedded\r
+* Comedy Central - OGP\r
+* snotr - embedded\r
+* zapiks - OGP\r
+* youku - embedded\r
+* wistia - Oembed\r
+\r
+###Audio\r
+* Soundcloud - oEmbed\r
+* HuffDuffer - oEmbed\r
+* BandCamp - YQL and Embedded\r
+* podomatic - OGP\r
+* rdio.com - oEmbed\r
+* hark.com - OGP\r
+* chirb.it - YQL and oembed\r
+* official.fm - YQL and oembed\r
+* mixcloud - YQL and oembed\r
+* shoudio - oembed\r
+* audioboo.fm - OGP\r
+* Spotify - OGP YQL\r
+\r
+###Photo\r
+* flickr - oEmbed\r
+* photobucket - oEmbed\r
+* instagram - oEmbed\r
+* yfrog - oEmbed\r
+* 23HQ - oEmbed\r
+* Smugmug - oEmbed\r
+* twitpic - OGP YQL\r
+* 500px.com - OGP\r
+* visual.ly - YQL Lookup\r
+* img.ly - Thumbnail view\r
+* imgur.com - Thumbnail view\r
+* twitgoo.com - Thumbnail view\r
+* gravatar - Thumbnail view when using mailto\r
+* pintrest - YQL - Embedded view of a sort.\r
+* circuitlab - image view\r
+* skitch - YQL oembed\r
+* graphic.ly  - OGP\r
+* dribble - jsonp lookup\r
+* Lockerz - YQL lookup\r
+* AsciiArtFarts - YQL Lookup\r
+* lego cusoo - OGP over YQL\r
+* plannary - OGP over YQL\r
+* propic - OGP\r
+* avairy.com - OGP\r
+* lomography - ogp\r
+* weheartit - ogp\r
+* glogster - ogp\r
+* chart.ly - embedded\r
+* twitrpix - OGP\r
+* chictopia - OGP\r
+\r
+###Rich\r
+* Meetup - oEmbed\r
+* gigapans - Embedded\r
+* Slideshare - oEmbed\r
+* ebay - Embedded\r
+* scribd - Embedded\r
+* screenr - Embedded\r
+* tumblr- JSONP lookup\r
+* imdb - JSONP lookup via imdbapi.com\r
+* wikipedia- JSONP lookup\r
+* github- JSONP lookup (CSS)\r
+* eventful - OGP\r
+* myspace - OGP\r
+* live Journal - JSONP Lookup (CSS)\r
+* wordpress - oEmbed (wordpress.com, wp.me, blogs.cnn.com, techcrunch.com). I can add other wordpress sites as well.\r
+* circuitbee -Embedded\r
+* stack overflow - JSONP Lookup (CSS)\r
+* Facebook - JSONP Lookup (CSS)\r
+* Pastebin - Embedded\r
+* Pastie - YQL lookup\r
+* kickstarter - Embedded\r
+* issuu - OGP\r
+* reelapp.com - Embedded\r
+* Etsy - OGP over YQL\r
+* Amazon - Embedded - Requires Affiliate code\r
+* linkedin - Embedded IFRAME - found a link that works :)\r
+* Lanyrd - YQL (CSS)\r
+* twitter - Oembed - status only - but that is ok I think\r
+* github gist - oembed\r
+* speakerdeck - yql oembed\r
+* dipity - yql oembed\r
+* dailymile - oembed\r
+* deviantart - oembed\r
+* Roomshare Japan - oembed\r
+* mobypictures - oembed\r
+* prezi - embedded\r
+* popplet - embedded\r
+* authorstream - OGP\r
+* googlecalendar - Iframe\r
+* cacoo - oembed\r
+* pearltrees - embedded\r
+* urtak - oembed - is broken in iframe return atm -seems to be an embed.ly issue??\r
+* jotform - embedded\r
+* Urban Dictionary - YQL lookup\r
+* Ars Technica - YQL Lookup\r
+* Eventbrite - OGP YQL\r
+* last.fm OGP YQL\r
+* Rotten Tomatoes - OGP YQL\r
+* iFixit - OGP\r
+* qwiki - OGP\r
+* brighttalk - Meta info\r
+* tinychat - OGP\r
+* tourwrist - embedded\r
+* bnter - OGP\r
+* bigthink - OGP\r
+* wirewax - OGP\r
+* whosay - OGP\r
+* timetoast - embedded\r
+* tripline - OGP\r
+* jsfiddle - embedded\r
+\r
+\r
+####License\r
+\r
+Licensed under the terms of the MIT License.\r
+\r
+####Dependencies\r
+This Plugin requires the following plugins to work: Widget, Dialog.\r
+\r
+####Installation\r
+\r
+ 1. Before you can use the plugin you also need to download & install the widget plugin, if you have it not installed. http://ckeditor.com/addon/widget\r
+ 2. Extract the contents of the file into the "plugins" folder of CKEditor.\r
+ 3. In the CKEditor configuration file (config.js) add the following code:\r
+\r
+````js\r
+config.extraPlugins = 'oembed,widget';\r
+````\r
+\r
+2a. Additionally you can also set the default values vor the Max. Width/Height Values\r
+\r
+````js\r
+config.oembed_maxWidth = '560';\r
+config.oembed_maxHeight = '315';\r
+````\r
+\r
+and also you can define an css class for the embeded content wrapper (div), by default there is no Class defined\r
+\r
+````js\r
+config.oembed_WrapperClass = 'embededContent';\r
+````\r
+\r
+\r
+3. and also include the plugin in the toolbar\r
+\r
+````js\r
+toolbar :[ ... ['oembed']...]\r
+````\r
diff --git a/sources/plugins/oembed/icons/hidpi/oembed.png b/sources/plugins/oembed/icons/hidpi/oembed.png
new file mode 100644 (file)
index 0000000..a568d17
Binary files /dev/null and b/sources/plugins/oembed/icons/hidpi/oembed.png differ
diff --git a/sources/plugins/oembed/icons/oembed.png b/sources/plugins/oembed/icons/oembed.png
new file mode 100644 (file)
index 0000000..2ba7cce
Binary files /dev/null and b/sources/plugins/oembed/icons/oembed.png differ
diff --git a/sources/plugins/oembed/lang/de.js b/sources/plugins/oembed/lang/de.js
new file mode 100644 (file)
index 0000000..69422ae
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'de', {\r
+    title : "Medien Inhalt einbinden (Bilder, Video, Inhalt)",\r
+       button : "Medien Inhalt von Verschiedenen Seiten einbinden",\r
+       pasteUrl : "Fügen Sie eine Url (Gekürzte Urls werden auch erkannt) ein von einer Seite die Unterstützt wird (z.B.: YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.) ...",\r
+       invalidUrl : "Sie müssem eine korrekte URL an!",\r
+       noEmbedCode : "Kein embed Code gefunden, oder Seite wird nicht Unterstützt!",\r
+       url : "URL:",\r
+       width: "Breite:",\r
+       height: "Höhe:",\r
+       widthTitle: "Breite für den eingebundenen Inhalt",\r
+       heightTitle: "Höhe für den eingebundenen Inhalt",\r
+       maxWidth: "Max. Breite:",\r
+       maxHeight: "Max. Höhe:",\r
+       maxWidthTitle: "Maximale Breite für den eingebundenen Inhalt",\r
+       maxHeightTitle: "Maximale Höhe für den eingebundenen Inhalt",\r
+       resizeType: "Größenveränderungsmodus (Nur Video's):",\r
+       none:'None',\r
+    noresize: "Keine Veränderung (Standardgröße)",\r
+       responsive: "Responsive",\r
+       custom: "Eigene Größe",\r
+       noVimeo: "Der Eigentümber dieses Videos hat Domain einschränkungen für dieses Video gesetzt das Video kann nicht in die Webseite eingebunden werden.",\r
+       Error: "Inhalt konnte nicht gefunden werden, bitte Versuchen sie eine Andere URL."\r
+});\r
diff --git a/sources/plugins/oembed/lang/en.js b/sources/plugins/oembed/lang/en.js
new file mode 100644 (file)
index 0000000..e461f03
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'en', {\r
+       title: "Embed Media Content (Photo, Video, Audio or Rich Content)",\r
+    button: "Embed Media from External Sites",\r
+    pasteUrl: "Paste a URL (shorted URLs are also supported) from one of the supported sites (e.g. YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.).",\r
+    invalidUrl: "Please provide a valid URL.",\r
+    noEmbedCode: "No embed code found, or site is not supported.",\r
+    url: "URL:",\r
+    width: "Width:",\r
+    height: "Height:",\r
+    widthTitle: "Width for the embeded content",\r
+    heightTitle: "Height for the embeded content",\r
+    maxWidth: "Max. Width:",\r
+    maxHeight: "Max. Height:",\r
+    maxWidthTitle: "Maximum Width for the embeded Content",\r
+    maxHeightTitle: "Maximum Height for the embeded Content",\r
+       none:'None',\r
+    resizeType: "Resize Type (videos only):",\r
+    noresize: "No Resize (use default)",\r
+    responsive: "Responsive Resize",\r
+    custom: "Specific Resize",\r
+    noVimeo: "The owner of this video has set domain restrictions and you will not be able to embed it on your website.",\r
+    Error: "Media Content could not been retrieved, please try a different URL."\r
+});\r
diff --git a/sources/plugins/oembed/lang/fr.js b/sources/plugins/oembed/lang/fr.js
new file mode 100644 (file)
index 0000000..c1e0650
--- /dev/null
@@ -0,0 +1,25 @@
+// French Translation by https://github.com/wissim\r
+\r
+CKEDITOR.plugins.setLang('oembed', 'fr', {\r
+       title : "Intégrer des contenus multimédia externes. (Photo, Video, Audio, ...)",\r
+       button : "Insérer des contenus multimédia provenant de nombreux sites.",\r
+       pasteUrl : "Coller l'URL de partage que vous voulez publier. De nombreux services sont pris en charge tels que : (YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.). Vous pouvez aussi utiliser les URLs courtes.",\r
+       invalidUrl : "Merci de fournir une URL valide !",\r
+       noEmbedCode : "Aucun code d'intégration trouvé ou le site n'est pas supporté !",\r
+       url : "URL:",\r
+       width: "Largeur:",\r
+       height: "Hauteur:",\r
+       widthTitle: "Largeur du conteneur.",\r
+       heightTitle: "Hauteur du conteneur.",\r
+       maxWidth: "Max. Largeur:",\r
+       maxHeight: "Max. Hauteur:",\r
+       maxWidthTitle: "Largeur maximale du conteneur.",\r
+       maxHeightTitle: "Hauteur maximale du conteneur.",\r
+       resizeType: "Resize Type (Only Video's):",\r
+       none:'None',\r
+    noresize: "No Resize (use default)",\r
+       responsive: "Responsive Resize",\r
+       custom: "Specific Resize",\r
+       noVimeo: "The owner of this video has set domain restrictions and you will not be able to embed it on your website.",\r
+       Error: "Media Content could not been retrieved, please try a different URL."\r
+});\r
diff --git a/sources/plugins/oembed/lang/nl.js b/sources/plugins/oembed/lang/nl.js
new file mode 100644 (file)
index 0000000..94cf8ad
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'nl', {\r
+       title : "Integratie van media-inhoud (foto's, video, content)",\r
+       button : "Media-inhoud van externe websites",\r
+       pasteUrl : "Geef een URL van een pagina in dat ondersteund wordt (Bijv.: YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.) ...",\r
+       invalidUrl : "Gelieve een geldige URL op te geven!",\r
+       noEmbedCode : "Geen embed code gevonden, of de website wordt niet ondersteund!",\r
+       url : "URL:",\r
+       width: "Breedte:",\r
+       height: "Hoogte:",\r
+       widthTitle: "Breedte voor de ingevoegde inhoud",\r
+       heightTitle: "Hoogte voor de ingevoegde inhoud",\r
+       maxWidth: "Maximale breedte:",\r
+       maxHeight: "Maximale hoogte:",\r
+       maxWidthTitle: "Maximum breedte voor de ingevoegde inhoud",\r
+       maxHeightTitle: "Maximum hoogte voor de ingevoegde inhoud",\r
+       none:'None',\r
+    resizeType: "Type formaat aanpassing (enkel video's):",\r
+       noresize: "Geen formaat aanpassing (gebruik standaard)",\r
+       responsive: "Responsieve formaat aanpassing",\r
+       custom: "Specifieke formaat aanpassing",\r
+       noVimeo: "De eigenaar van deze video heeft restricties ingesteld waardoor je deze video niet kunt invoegen op je eigen website.",\r
+       Error: "Media inhoud kon niet worden opgehaald, gelieve een andere URL te proberen."\r
+});\r
diff --git a/sources/plugins/oembed/lang/pl.js b/sources/plugins/oembed/lang/pl.js
new file mode 100644 (file)
index 0000000..a7d7b92
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'pl', {\r
+    title: "Osadzanie multimediów (zdjęć, filmów, dźwięku, bogatych treści)",\r
+    button: "Osadzanie multimediów z witryn zewnętrznych",\r
+    pasteUrl: "Wklej tutaj adres URL (adresy skrócone są również obsługiwane) z jednej z obsługiwanych stron (YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, itp.).",\r
+    invalidUrl: "Proszę wprowadzić prawidłowy adres URL!",\r
+    noEmbedCode: "Odnośnik nieprawidłowy lub nieobsługiwany!",\r
+    url: "URL:",\r
+    width: "szerokość:",\r
+    height: "wysokość:",\r
+    widthTitle: "Szerokość osadzanej zawartości",\r
+    heightTitle: "Wysokość osadzanej zawartości",\r
+    maxWidth: "Maks. szerokość:",\r
+    maxHeight: "Maks. wysokość:",\r
+    maxWidthTitle: "Maksymalna szerokość osadzanej zawartości",\r
+    maxHeightTitle: "Maksymalna wysokość osadzanej zawartości",\r
+    resizeType: "Typ zmiany rozmiaru (tylko nagrania wideo):",\r
+    none:'None',\r
+    noresize: "Bez zmiany rozmiaru (domyślne)",\r
+    responsive: "Responsywna zmiana rozmiaru",\r
+    custom: "Narzucona zmiana rozmiaru",\r
+    noVimeo: "Właściciel nagrania wideo nałożył ograniczenia domenowe, nagrania nie można osadzić w witrynie.",\r
+    Error: "Nie można uzyskać zawartości multimedialnej, proszę spróbować inny adres URL."\r
+});\r
diff --git a/sources/plugins/oembed/lang/pt-br.js b/sources/plugins/oembed/lang/pt-br.js
new file mode 100644 (file)
index 0000000..6616432
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'pt-br', {\r
+    title: "Conteúdo embed de mídia (foto, vídeo, audio, rich)",\r
+    button: "Conteúdo embed de mídia de vários sites",\r
+       pasteUrl: "Cole aqui a URL (inclusive URLs encurtadas) de um dos sites que o plugin suporta (ex. YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.) ...",\r
+    invalidUrl: "Por favor informe uma URL válida!",\r
+    noEmbedCode: "Nenhum código embed foi encontrado, ou esse site não está na lista dos sites suportados pelo plugin!",\r
+    url: "URL:",\r
+    width: "Largura:",\r
+    height: "Altura:",\r
+    widthTitle: "Largura do conteúdo embebed",\r
+    heightTitle: "Altura do conteúdo embeded",\r
+    maxWidth: "Largura máx.:",\r
+    maxHeight: "Altura máx.:",\r
+    maxWidthTitle: "Largura máxima do conteúdo embeded",\r
+    maxHeightTitle: "Altura máxima do conteúdo embeded",\r
+    resizeType: "Tipo de redimensionamento (Somente para video):",\r
+    none:'None',\r
+    noresize: "Sem redimensionamento (default)",\r
+    responsive: "Redimensionamento responsivo",\r
+    custom: "Redimensionamento específico",\r
+    noVimeo: "O dono desse vídeo tem restrições de domínio a você não poderá utilizá-lo em seu site.",\r
+    Error: "Esse conteúdo de mídia não foi encontrado, por favor tente uma URL diferente."\r
+});\r
diff --git a/sources/plugins/oembed/lang/ru.js b/sources/plugins/oembed/lang/ru.js
new file mode 100644 (file)
index 0000000..f2a1e53
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'ru', {\r
+    title: "Внедрить медиа-контент (видео, аудио, фото и т.д.)",\r
+    button: "Внедрить медиа-контент с различных сайтов",\r
+    pasteUrl: "Вставьте ссылку на страницу с медиа-контентом (например YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, и т.д.)",\r
+    invalidUrl: "Вы ввели некорректный URL",\r
+    noEmbedCode: "Не обнаружен код для вставки. Возможно, вы ввели ссылку с неподдерживаемого сайта.",\r
+    url: "URL:",\r
+    width: "Ширина:",\r
+    height: "Высота:",\r
+    widthTitle: "Ширина внедряемого медиа-контента",\r
+    heightTitle: "Высота внедряемого медиа-контента",\r
+    maxWidth: "Макс. ширина:",\r
+    maxHeight: "Макс. высота:",\r
+    maxWidthTitle: "Максимальная ширина внедряемого медиа-контента",\r
+    maxHeightTitle: "Максимальная высота внедряемого медиа-контента",\r
+    resizeType: "Изменение размера (только для видео):",\r
+    none:'None',\r
+    noresize: "Без изменения (стандартный размер)",\r
+    responsive: "Задать максимальный размер",\r
+    custom: "Задать конкретный размер",\r
+    noVimeo: "Владелец этого видео установил ограничения на домен, и вы не можете его встроить на ваш сайт.",\r
+    Error: "Невозможно получить медиа-контент. Попробуйте другой URL."\r
+});\r
diff --git a/sources/plugins/oembed/lang/tr.js b/sources/plugins/oembed/lang/tr.js
new file mode 100644 (file)
index 0000000..f027106
--- /dev/null
@@ -0,0 +1,23 @@
+CKEDITOR.plugins.setLang('oembed', 'tr', {\r
+    title: "Medya içeriği ekle (Fotoğraf, Video, Ses Dosyası, Zengin Medya İçeriği)",\r
+    button: "Farklı sitelerden medya içeriği ekle",\r
+    pasteUrl: "Desteklenen sitelerden bir URL ekleyin (Kısaltılmış URL de olabilir) (örnek: YouTube, Flickr, Qik, Vimeo, Hulu, Viddler, MyOpera, etc.)...",\r
+    invalidUrl: "Lütfen geçerli bir URL adresi tanımlayın!",\r
+    noEmbedCode: "Embed kodu bulunamadı veya site desteklenmiyor!",\r
+    url: "URL:",\r
+    width: "Genişlik:",\r
+    height: "Yükseklik:",\r
+    widthTitle: "Eklenecek içerik için genişlik",\r
+    heightTitle: "Eklenecek içerik için yükseklik",\r
+    maxWidth: "Max. genişlik:",\r
+    maxHeight: "Max. yükseklik:",\r
+    maxWidthTitle: "Eklenecek içerik için max. genişlik",\r
+    maxHeightTitle: "Eklenecek içerik için max. yükseklik",\r
+    resizeType: "Boyutlandır (sadece videolarda geçerli):",\r
+    none:'None',\r
+    noresize: "Boyutlandırma yapma (default kullan)",\r
+    responsive: "Esnek (Responsive) boyutlandırma",\r
+    custom: "Özel boyutlandırma",\r
+    noVimeo: "Bu videonun sahibi alan adı kısıtlaması ayarlamış, web sitenizde bu video çalışmayacaktır.",\r
+    Error: "Medya içeriği alınamadı, farklı bir URL deneyin."\r
+});\r
diff --git a/sources/plugins/oembed/libs/jquery.oembed.min.js b/sources/plugins/oembed/libs/jquery.oembed.min.js
new file mode 100644 (file)
index 0000000..e5bd1c5
--- /dev/null
@@ -0,0 +1 @@
+(function(n){function r(){var n=window.location.protocol;return n==="file:"?"http://":"//"}function f(n,t){return t=t?t:"",n?f(--n,"0123456789ABCDEFGHIJKLMNOPQRSTUVWXTZabcdefghiklmnopqrstuvwxyz".charAt(Math.floor(Math.random()*60))+t):t}function s(n,t){var i=n.apiendpoint,u="",r;i+=i.indexOf("?")<=0?"?":"&";i=i.replace("#","%23");n.maxWidth!==null&&(typeof n.params.maxwidth=="undefined"||n.params.maxwidth===null)&&(n.params.maxwidth=n.maxWidth);n.maxHeight!==null&&(typeof n.params.maxheight=="undefined"||n.params.maxheight===null)&&(n.params.maxheight=n.maxHeight);for(r in n.params)r!=n.callbackparameter&&n.params[r]!==null&&(u+="&"+escape(r)+"="+n.params[r]);return i+="format="+n.format+"&url="+escape(t)+u,n.dataType!="json"&&(i+="&"+n.callbackparameter+"=?"),i}function u(i,r,u){n("#jqoembeddata").data(r,i.code);t.beforeEmbed.call(u,i);t.onEmbed.call(u,i);t.afterEmbed.call(u,i)}function e(i,e,o){var p,a,tt,v;if(n("#jqoembeddata").data(e)!=undefined&&o.embedtag.tag!="iframe")a={code:n("#jqoembeddata").data(e)},u(a,e,i);else if(o.yql){var w=o.yql.from||"htmlstring",g=o.yql.url?o.yql.url(e):e,nt="SELECT * FROM "+w+' WHERE url="'+g+'" and '+(/html/.test(w)?"xpath":"itemPath")+"='"+(o.yql.xpath||"/")+"'";w=="html"&&(nt+=" and compat='html5'");v=n.extend({url:r()+"query.yahooapis.com/v1/public/yql",dataType:"jsonp",data:{q:nt,format:"json",env:"store://datatables.org/alltableswithkeys",callback:"?"},success:function(t){var s,f,c,r,h,l;if(o.yql.xpath&&o.yql.xpath=="//meta|//title|//link"){for(f={},t.query.results==null&&(t.query.results={meta:[]}),r=0,h=t.query.results.meta.length;r<h;r++)(c=t.query.results.meta[r].name||t.query.results.meta[r].property||null,c!=null)&&(f[c.toLowerCase()]=t.query.results.meta[r].content);if(f.hasOwnProperty("title")&&f.hasOwnProperty("og:title")||t.query.results.title!=null&&(f.title=t.query.results.title),!f.hasOwnProperty("og:image")&&t.query.results.hasOwnProperty("link"))for(r=0,h=t.query.results.link.length;r<h;r++)t.query.results.link[r].hasOwnProperty("rel")&&t.query.results.link[r].rel=="apple-touch-icon"&&(f["og:image"]=t.query.results.link[r].href.charAt(0)=="/"?g.match(/^(([a-z]+:)?(\/\/)?[^\/]+\/).*$/)[1]+t.query.results.link[r].href:t.query.results.link[r].href);s=o.yql.datareturn(f)}else s=o.yql.datareturn?o.yql.datareturn(t.query.results):t.query.results.result;s!==!1&&(l=n.extend({},s),l.code=s,u(l,e,i))},error:function(){t.onError.call(i,e,o)}},t.ajaxOptions||{});n.ajax(v)}else if(o.templateRegex)if(o.embedtag.tag!==""){var it=o.embedtag.flashvars||"",b=o.embedtag.tag||"embed",h=o.embedtag.width||"auto",rt=o.embedtag.nocache||0,c=o.embedtag.height||"auto",y=e.replace(o.templateRegex,o.apiendpoint);if(o.nocache||(y+="&jqoemcache="+f(5)),o.apikey&&(y=y.replace("_APIKEY_",t.apikeys[o.name])),t.maxHeight&&t.maxWidth)if(t.useResponsiveResize){var l=0,k=h,d=c;h>t.maxWidth&&(l=t.maxWidth/h,k=t.maxWidth,d=c*l,c=c*l,h=h*l);c>t.maxHeight&&(l=t.maxHeight/c,d=t.maxHeight,k=h*l,h=h*l);c=d;h=k}else c=t.maxHeight,h=t.maxWidth;p=n("<"+b+"/>").attr("src",y).attr("width",h).attr("height",c).attr("allowfullscreen",o.embedtag.allowfullscreen||"true").attr("allowscriptaccess",o.embedtag.allowfullscreen||"always").css("max-height",t.maxHeight||"auto").css("max-width",t.maxWidth||"auto");b=="embed"&&p.attr("type",o.embedtag.type||"application/x-shockwave-flash").attr("flashvars",e.replace(o.templateRegex,it));b=="iframe"&&p.attr("scrolling",o.embedtag.scrolling||"no").attr("frameborder",o.embedtag.frameborder||"0");a={code:p};u(a,e,i)}else o.apiendpoint?(o.apikey&&(o.apiendpoint=o.apiendpoint.replace("_APIKEY_",t.apikeys[o.name])),v=n.extend({url:e.replace(o.templateRegex,o.apiendpoint),dataType:"jsonp",success:function(t){var r=n.extend({},t);r.code=o.templateData(t);u(r,e,i)},error:function(){t.onError.call(i,e,o)}},t.ajaxOptions||{}),n.ajax(v)):(a={code:e.replace(o.templateRegex,o.template)},u(a,e,i));else tt=s(o,e),v=n.extend({url:tt,dataType:o.dataType||"jsonp",success:function(t){var r=n.extend({},t);switch(r.type){case"file":case"photo":r.code=n.fn.oembed.getPhotoCode(e,r);break;case"link":r.code=r.provider_name=="Flickr"?n.fn.oembed.getPhotoCode(e,r):n.fn.oembed.getGenericCode(e,r);break;case"video":case"rich":r.code=n.fn.oembed.getRichCode(e,r);break;default:r.code=n.fn.oembed.getGenericCode(e,r)}u(r,e,i)},error:function(){t.onError.call(i,e,o)}},t.ajaxOptions||{}),n.ajax(v)}function o(n){if(n===null)return null;var t,i={};for(t in n)t!==null&&(i[t.toLowerCase()]=n[t]);return i}n.fn.oembed=function(i,r,u){t=n.extend(!0,n.fn.oembed.defaults,r);var f=["0rz.tw","1link.in","1url.com","2.gp","2big.at","2tu.us","3.ly","307.to","4ms.me","4sq.com","4url.cc","6url.com","7.ly","a.gg","a.nf","aa.cx","abcurl.net","ad.vu","adf.ly","adjix.com","afx.cc","all.fuseurl.com","alturl.com","amzn.to","ar.gy","arst.ch","atu.ca","azc.cc","b23.ru","b2l.me","bacn.me","bcool.bz","binged.it","bit.ly","bizj.us","bloat.me","bravo.ly","bsa.ly","budurl.com","canurl.com","chilp.it","chzb.gr","cl.lk","cl.ly","clck.ru","cli.gs","cliccami.info","clickthru.ca","clop.in","conta.cc","cort.as","cot.ag","crks.me","ctvr.us","cutt.us","dai.ly","decenturl.com","dfl8.me","digbig.com","http://digg.com/[^/]+$","disq.us","dld.bz","dlvr.it","do.my","doiop.com","dopen.us","easyuri.com","easyurl.net","eepurl.com","eweri.com","fa.by","fav.me","fb.me","fbshare.me","ff.im","fff.to","fire.to","firsturl.de","firsturl.net","flic.kr","flq.us","fly2.ws","fon.gs","freak.to","fuseurl.com","fuzzy.to","fwd4.me","fwib.net","g.ro.lt","gizmo.do","gl.am","go.9nl.com","go.ign.com","go.usa.gov","goo.gl","goshrink.com","gurl.es","hex.io","hiderefer.com","hmm.ph","href.in","hsblinks.com","htxt.it","huff.to","hulu.com","hurl.me","hurl.ws","icanhaz.com","idek.net","ilix.in","is.gd","its.my","ix.lt","j.mp","jijr.com","kl.am","klck.me","korta.nu","krunchd.com","l9k.net","lat.ms","liip.to","liltext.com","linkbee.com","linkbun.ch","liurl.cn","ln-s.net","ln-s.ru","lnk.gd","lnk.ms","lnkd.in","lnkurl.com","lru.jp","lt.tl","lurl.no","macte.ch","mash.to","merky.de","migre.me","miniurl.com","minurl.fr","mke.me","moby.to","moourl.com","mrte.ch","myloc.me","myurl.in","n.pr","nbc.co","nblo.gs","nn.nf","not.my","notlong.com","nsfw.in","nutshellurl.com","nxy.in","nyti.ms","o-x.fr","oc1.us","om.ly","omf.gd","omoikane.net","on.cnn.com","on.mktw.net","onforb.es","orz.se","ow.ly","ping.fm","pli.gs","pnt.me","politi.co","post.ly","pp.gg","profile.to","ptiturl.com","pub.vitrue.com","qlnk.net","qte.me","qu.tc","qy.fi","r.ebay.com","r.im","rb6.me","read.bi","readthis.ca","reallytinyurl.com","redir.ec","redirects.ca","redirx.com","retwt.me","ri.ms","rickroll.it","riz.gd","rt.nu","ru.ly","rubyurl.com","rurl.org","rww.tw","s4c.in","s7y.us","safe.mn","sameurl.com","sdut.us","shar.es","shink.de","shorl.com","short.ie","short.to","shortlinks.co.uk","shorturl.com","shout.to","show.my","shrinkify.com","shrinkr.com","shrt.fr","shrt.st","shrten.com","shrunkin.com","simurl.com","slate.me","smallr.com","smsh.me","smurl.name","sn.im","snipr.com","snipurl.com","snurl.com","sp2.ro","spedr.com","srnk.net","srs.li","starturl.com","stks.co","su.pr","surl.co.uk","surl.hu","t.cn","t.co","t.lh.com","ta.gd","tbd.ly","tcrn.ch","tgr.me","tgr.ph","tighturl.com","tiniuri.com","tiny.cc","tiny.ly","tiny.pl","tinylink.in","tinyuri.ca","tinyurl.com","tk.","tl.gd","tmi.me","tnij.org","tnw.to","tny.com","to.ly","togoto.us","totc.us","toysr.us","tpm.ly","tr.im","tra.kz","trunc.it","twhub.com","twirl.at","twitclicks.com","twitterurl.net","twitterurl.org","twiturl.de","twurl.cc","twurl.nl","u.mavrev.com","u.nu","u76.org","ub0.cc","ulu.lu","updating.me","ur1.ca","url.az","url.co.uk","url.ie","url360.me","url4.eu","urlborg.com","urlbrief.com","urlcover.com","urlcut.com","urlenco.de","urli.nl","urls.im","urlshorteningservicefortwitter.com","urlx.ie","urlzen.com","usat.ly","use.my","vb.ly","vevo.ly","vgn.am","vl.am","vm.lc","w55.de","wapo.st","wapurl.co.uk","wipi.es","wp.me","x.vu","xr.com","xrl.in","xrl.us","xurl.es","xurl.jp","y.ahoo.it","yatuc.com","ye.pe","yep.it","yfrog.com","yhoo.it","yiyd.com","youtu.be","yuarel.com","z0p.de","zi.ma","zi.mu","zipmyurl.com","zud.me","zurl.ws","zz.gd","zzang.kr","›.ws","✩.ws","✿.ws","❥.ws","➔.ws","➞.ws","➡.ws","➨.ws","➯.ws","➹.ws","➽.ws"];return n("#jqoembeddata").length===0&&n('<span id="jqoembeddata"><\/span>').appendTo("body"),this.each(function(){var h=n(this),s=i&&(!i.indexOf("http://")||!i.indexOf("https://"))?i:h.attr("href"),r,c,l,a,v;if(u?t.onEmbed=u:t.onEmbed||(t.onEmbed=function(i){n.fn.oembed.insertCode(this,t.embedMethod,i)}),s!==null&&s!==undefined){for(c=0,l=f.length;c<l;c++)if(a=new RegExp("://"+f[c]+"/","i"),s.match(a)!==null)return v=n.extend({url:"http://api.longurl.org/v2/expand",dataType:"jsonp",data:{url:s,format:"json"},success:function(i){s=i["long-url"];r=n.fn.oembed.getOEmbedProvider(i["long-url"]);r!==null?(r.params=o(t[r.name])||{},r.maxWidth=t.maxWidth,r.maxHeight=t.maxHeight,e(h,s,r)):t.onProviderNotFound.call(h,s)}},t.ajaxOptions||{}),n.ajax(v),h;r=n.fn.oembed.getOEmbedProvider(s);r!==null?(r.params=o(t[r.name])||{},r.maxWidth=t.maxWidth,r.maxHeight=t.maxHeight,e(h,s,r)):t.onProviderNotFound.call(h,s)}return h})};var t;n.fn.oembed.defaults={maxWidth:null,maxHeight:null,useResponsiveResize:!1,includeHandle:!0,embedMethod:"auto",onProviderNotFound:function(){},beforeEmbed:function(){},afterEmbed:function(){},onEmbed:!1,onError:function(){},ajaxOptions:{timeout:2e3}};n.fn.oembed.insertCode=function(i,r,u){if(u!==null){r=="auto"&&i.attr("href")!==null?r="append":r=="auto"&&(r="replace");switch(r){case"replace":i.replaceWith(u.code);break;case"fill":i.html(u.code);break;case"append":i.wrap('<div class="oembedall-container"><\/div>');var f=i.parent();t.includeHandle&&n('<span class="oembedall-closehide">&darr;<\/span>').insertBefore(i).click(function(){var t=encodeURIComponent(n(this).text());n(this).html(t=="%E2%86%91"?"&darr;":"&uarr;");n(this).parent().children().last().toggle()});f.append("<br/>");try{u.code.clone().appendTo(f)}catch(e){f.append(u.code)}}}};n.fn.oembed.getPhotoCode=function(n,t){var i,r=t.title?t.title:"",u;return r+=t.author_name?" - "+t.author_name:"",r+=t.provider_name?" - "+t.provider_name:"",t.url?i='<div><a href="'+n+"\" target='_blank'><img src=\""+t.url+'" alt="'+r+'"/><\/a><\/div>':t.thumbnail_url?(u=t.thumbnail_url.replace("_s","_b"),i='<div><a href="'+n+"\" target='_blank'><img src=\""+u+'" alt="'+r+'"/><\/a><\/div>'):i=t.provider_name=="Flickr"?'<p><a href="'+n+"\" target='_blank'>"+n+"<\/a><\/p>":"<div>Error loading this picture<\/div>",i};n.fn.oembed.getRichCode=function(n,t){return t.html};n.fn.oembed.getGenericCode=function(n,t){var r=t.title!==null?t.title:n,i='<a href="'+n+'">'+r+"<\/a>";return t.html&&(i+="<div>"+t.html+"<\/div>"),i};n.fn.oembed.getOEmbedProvider=function(t){for(var r,u,f,i=0;i<n.fn.oembed.providers.length;i++)for(r=0,u=n.fn.oembed.providers[i].urlschemes.length;r<u;r++)if(f=new RegExp(n.fn.oembed.providers[i].urlschemes[r],"i"),t.match(f)!==null)return n.fn.oembed.providers[i];return null};n.fn.oembed.OEmbedProvider=function(i,r,u,f,e){this.name=i;this.type=r;this.urlschemes=u;this.apiendpoint=f;this.maxWidth=500;this.maxHeight=400;e=e||{};e.useYQL&&(e.yql=e.useYQL=="xml"?{xpath:"//oembed/html",from:"xml",apiendpoint:this.apiendpoint,url:function(n){return this.apiendpoint+"?format=xml&url="+n},datareturn:function(n){return n.html.replace(/.*\[CDATA\[(.*)\]\]>$/,"$1")||""}}:{from:"json",apiendpoint:this.apiendpoint,url:function(n){return this.apiendpoint+"?format=json&url="+n},datareturn:function(i){var f,o,s;if(i.json.type!="video"&&(i.json.url||i.json.thumbnail_url)&&!i.json.html.indexOf("iframe"))return'<img src="'+(i.json.url||i.json.thumbnail_url)+'"  />';if(i.json.html.indexOf("iframe")){i.json.html.indexOf("allowfullscreen>")&&(i.json.html=i.json.html.replace("allowfullscreen>",'allowfullscreen="false">'));var e=n.parseHTML(i.json.html),r=e[0].width,u=e[0].height;return t.maxHeight&&t.maxWidth&&(t.useResponsiveResize?(o=r,s=u,r>t.maxWidth&&(f=t.maxWidth/r,o=t.maxWidth,s=u*f,u=u*f,r=r*f),u>t.maxHeight&&(f=t.maxHeight/u,s=t.maxHeight,o=r*f),u=s,r=o):(u=t.maxHeight,r=t.maxWidth)),e[0].width=r,e[0].height=u,e[0].outerHTML}return i.json.html||""}},this.apiendpoint=null);for(var o in e)this[o]=e[o];this.format=this.format||"json";this.callbackparameter=this.callbackparameter||"callback";this.embedtag=this.embedtag||{tag:""}};n.fn.updateOEmbedProvider=function(t,i,r,u,f){for(var o,e=0;e<n.fn.oembed.providers.length;e++)if(n.fn.oembed.providers[e].name===t&&(i!==null&&(n.fn.oembed.providers[e].type=i),r!==null&&(n.fn.oembed.providers[e].urlschemes=r),u!==null&&(n.fn.oembed.providers[e].apiendpoint=u),f!==null)){n.fn.oembed.providers[e].extraSettings=f;for(o in f)f[o]!==null&&(n.fn.oembed.providers[e][o]=f[o])}};n.fn.oembed.providers=[new n.fn.oembed.OEmbedProvider("youtube","video",["youtube\\.com/watch.+v=[\\w-]+&?","youtu\\.be/[\\w-]+","youtube.com/embed"],r()+"www.youtube.com/embed/$1?wmode=transparent",{templateRegex:/.*(?:v\=|be\/|embed\/)([\w\-]+)&?.*/,embedtag:{tag:"iframe",width:"425",height:"349"}}),new n.fn.oembed.OEmbedProvider("youtubeiframe","video",["youtube.com/embed"],"$1?wmode=transparent",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"425",height:"349"}}),new n.fn.oembed.OEmbedProvider("wistia","video",["wistia.com/m/.+","wistia.com/embed/.+","wi.st/m/.+","wi.st/embed/.+"],"http://fast.wistia.com/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("xtranormal","video",["xtranormal\\.com/watch/.+"],"http://www.xtranormal.com/xtraplayr/$1/$2",{templateRegex:/.*com\/watch\/([\w\-]+)\/([\w\-]+).*/,embedtag:{tag:"iframe",width:"320",height:"269"}}),new n.fn.oembed.OEmbedProvider("scivee","video",["scivee.tv/node/.+"],"http://www.scivee.tv/flash/embedCast.swf?",{templateRegex:/.*tv\/node\/(.+)/,embedtag:{width:"480",height:"400",flashvars:"id=$1&type=3"}}),new n.fn.oembed.OEmbedProvider("veoh","video",["veoh.com/watch/.+"],"http://www.veoh.com/swf/webplayer/WebPlayer.swf?version=AFrontend.5.7.0.1337&permalinkId=$1&player=videodetailsembedded&videoAutoPlay=0&id=anonymous",{templateRegex:/.*watch\/([^\?]+).*/,embedtag:{width:"410",height:"341"}}),new n.fn.oembed.OEmbedProvider("gametrailers","video",["gametrailers\\.com/video/.+"],"http://media.mtvnservices.com/mgid:moses:video:gametrailers.com:$2",{templateRegex:/.*com\/video\/([\w\-]+)\/([\w\-]+).*/,embedtag:{width:"512",height:"288"}}),new n.fn.oembed.OEmbedProvider("funnyordie","video",["funnyordie\\.com/videos/.+"],"http://player.ordienetworks.com/flash/fodplayer.swf?",{templateRegex:/.*videos\/([^\/]+)\/([^\/]+)?/,embedtag:{width:512,height:328,flashvars:"key=$1"}}),new n.fn.oembed.OEmbedProvider("colledgehumour","video",["collegehumor\\.com/video/.+"],"http://www.collegehumor.com/moogaloop/moogaloop.swf?clip_id=$1&use_node_id=true&fullscreen=1",{templateRegex:/.*video\/([^\/]+).*/,embedtag:{width:600,height:338}}),new n.fn.oembed.OEmbedProvider("metacafe","video",["metacafe\\.com/watch/.+"],"http://www.metacafe.com/fplayer/$1/$2.swf",{templateRegex:/.*watch\/(\d+)\/(\w+)\/.*/,embedtag:{width:400,height:345}}),new n.fn.oembed.OEmbedProvider("bambuser","video",["bambuser\\.com/channel/.*/broadcast/.*"],"http://static.bambuser.com/r/player.swf?vid=$1",{templateRegex:/.*bambuser\.com\/channel\/.*\/broadcast\/(\w+).*/,embedtag:{width:512,height:339}}),new n.fn.oembed.OEmbedProvider("twitvid","video",["twitvid\\.com/.+"],"http://www.twitvid.com/embed.php?guid=$1&autoplay=0",{templateRegex:/.*twitvid\.com\/(\w+).*/,embedtag:{tag:"iframe",width:480,height:360}}),new n.fn.oembed.OEmbedProvider("aniboom","video",["aniboom\\.com/animation-video/.+"],"http://api.aniboom.com/e/$1",{templateRegex:/.*animation-video\/(\d+).*/,embedtag:{width:594,height:334}}),new n.fn.oembed.OEmbedProvider("vzaar","video",["vzaar\\.com/videos/.+","vzaar.tv/.+"],"http://view.vzaar.com/$1/player?",{templateRegex:/.*\/(\d+).*/,embedtag:{tag:"iframe",width:576,height:324}}),new n.fn.oembed.OEmbedProvider("snotr","video",["snotr\\.com/video/.+"],"http://www.snotr.com/embed/$1",{templateRegex:/.*\/(\d+).*/,embedtag:{tag:"iframe",width:400,height:330,nocache:1}}),new n.fn.oembed.OEmbedProvider("youku","video",["v.youku.com/v_show/id_.+"],"http://player.youku.com/player.php/sid/$1/v.swf",{templateRegex:/.*id_(.+)\.html.*/,embedtag:{width:480,height:400,nocache:1}}),new n.fn.oembed.OEmbedProvider("tudou","video",["tudou.com/programs/view/.+/"],"http://www.tudou.com/v/$1/v.swf",{templateRegex:/.*view\/(.+)\//,embedtag:{width:480,height:400,nocache:1}}),new n.fn.oembed.OEmbedProvider("embedr","video",["embedr\\.com/playlist/.+"],"http://embedr.com/swf/slider/$1/425/520/default/false/std?",{templateRegex:/.*playlist\/([^\/]+).*/,embedtag:{width:425,height:520}}),new n.fn.oembed.OEmbedProvider("blip","video",["blip\\.tv/.+"],"http://blip.tv/oembed/"),new n.fn.oembed.OEmbedProvider("minoto-video","video",["http://api.minoto-video.com/publishers/.+/videos/.+","http://dashboard.minoto-video.com/main/video/details/.+","http://embed.minoto-video.com/.+"],"http://api.minoto-video.com/services/oembed.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("animoto","video",["animoto.com/play/.+"],"http://animoto.com/services/oembed"),new n.fn.oembed.OEmbedProvider("hulu","video",["hulu\\.com/watch/.*"],"http://www.hulu.com/api/oembed.json"),new n.fn.oembed.OEmbedProvider("ustream","video",["ustream\\.tv/recorded/.*"],"http://www.ustream.tv/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("videojug","video",["videojug\\.com/(film|payer|interview).*"],"http://www.videojug.com/oembed.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("sapo","video",["videos\\.sapo\\.pt/.*"],"http://videos.sapo.pt/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("vodpod","video",["vodpod.com/watch/.*"],"http://vodpod.com/oembed.js",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("vimeo","video",["www.vimeo.com/groups/.*/videos/.*","www.vimeo.com/.*","vimeo.com/groups/.*/videos/.*","vimeo.com/.*"],"//vimeo.com/api/oembed.json"),new n.fn.oembed.OEmbedProvider("dailymotion","video",["dailymotion\\.com/.+"],"http://www.dailymotion.com/services/oembed"),new n.fn.oembed.OEmbedProvider("5min","video",["www\\.5min\\.com/.+"],"http://api.5min.com/oembed.xml",{useYQL:"xml"}),new n.fn.oembed.OEmbedProvider("National Film Board of Canada","video",["nfb\\.ca/film/.+"],"http://www.nfb.ca/remote/services/oembed/",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("qik","video",["qik\\.com/\\w+"],"http://qik.com/api/oembed.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("revision3","video",["revision3\\.com"],"http://revision3.com/api/oembed/"),new n.fn.oembed.OEmbedProvider("dotsub","video",["dotsub\\.com/view/.+"],"http://dotsub.com/services/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("clikthrough","video",["clikthrough\\.com/theater/video/\\d+"],"http://clikthrough.com/services/oembed"),new n.fn.oembed.OEmbedProvider("Kinomap","video",["kinomap\\.com/.+"],"http://www.kinomap.com/oembed"),new n.fn.oembed.OEmbedProvider("VHX","video",["vhx.tv/.+"],"http://vhx.tv/services/oembed.json"),new n.fn.oembed.OEmbedProvider("bambuser","video",["bambuser.com/.+"],"http://api.bambuser.com/oembed/iframe.json"),new n.fn.oembed.OEmbedProvider("justin.tv","video",["justin.tv/.+"],"http://api.justin.tv/api/embed/from_url.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("official.fm","rich",["official.fm/.+"],"http://official.fm/services/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("chirbit","rich",["chirb.it/.+"],"http://chirb.it/oembed.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("Huffduffer","rich",["huffduffer.com/[-.\\w@]+/\\d+"],"http://huffduffer.com/oembed"),new n.fn.oembed.OEmbedProvider("Spotify","rich",["open.spotify.com/(track|album|user)/"],"https://embed.spotify.com/oembed/"),new n.fn.oembed.OEmbedProvider("shoudio","rich",["shoudio.com/.+","shoud.io/.+"],"http://shoudio.com/api/oembed"),new n.fn.oembed.OEmbedProvider("mixcloud","rich",["mixcloud.com/.+"],r()+"www.mixcloud.com/oembed/",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("rdio.com","rich",["rd.io/.+","rdio.com"],r()+"www.rdio.com/api/oembed/"),new n.fn.oembed.OEmbedProvider("Soundcloud","rich",["soundcloud.com/.+","snd.sc/.+"],r()+"soundcloud.com/oembed",{format:"js"}),new n.fn.oembed.OEmbedProvider("bandcamp","rich",["bandcamp\\.com/album/.+"],null,{yql:{xpath:"//meta[contains(@content, \\'EmbeddedPlayer\\')]",from:"html",datareturn:function(n){return n.meta?'<iframe width="400" height="100" src="'+n.meta.content+'" allowtransparency="true" frameborder="0"><\/iframe>':!1}}}),new n.fn.oembed.OEmbedProvider("deviantart","photo",["deviantart.com/.+","fav.me/.+","deviantart.com/.+"],"http://backend.deviantart.com/oembed",{format:"jsonp"}),new n.fn.oembed.OEmbedProvider("skitch","photo",["skitch.com/.+"],null,{yql:{xpath:"json",from:"json",url:function(n){return"http://skitch.com/oembed/?format=json&url="+n},datareturn:function(t){return n.fn.oembed.getPhotoCode(t.json.url,t.json)}}}),new n.fn.oembed.OEmbedProvider("mobypicture","photo",["mobypicture.com/user/.+/view/.+","moby.to/.+"],"http://api.mobypicture.com/oEmbed"),new n.fn.oembed.OEmbedProvider("flickr","photo",["flickr\\.com/photos/.+"],"http://flickr.com/services/oembed",{callbackparameter:"jsoncallback"}),new n.fn.oembed.OEmbedProvider("photobucket","photo",["photobucket\\.com/(albums|groups)/.+"],r()+"photobucket.com/oembed/"),new n.fn.oembed.OEmbedProvider("instagram","photo",["instagr\\.?am(\\.com)?/.+"],r()+"api.instagram.com/oembed"),new n.fn.oembed.OEmbedProvider("SmugMug","photo",["smugmug.com/[-.\\w@]+/.+"],"http://api.smugmug.com/services/oembed/"),new n.fn.oembed.OEmbedProvider("dribbble","photo",["dribbble.com/shots/.+"],"http://api.dribbble.com/shots/$1?callback=?",{templateRegex:/.*shots\/([\d]+).*/,templateData:function(n){return n.image_teaser_url?'<img src="'+n.image_teaser_url+'"/>':!1}}),new n.fn.oembed.OEmbedProvider("chart.ly","photo",["chart\\.ly/[a-z0-9]{6,8}"],"http://chart.ly/uploads/large_$1.png",{templateRegex:/.*ly\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new n.fn.oembed.OEmbedProvider("circuitlab","photo",["circuitlab.com/circuit/.+"],"https://www.circuitlab.com/circuit/$1/screenshot/540x405/",{templateRegex:/.*circuit\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new n.fn.oembed.OEmbedProvider("23hq","photo",["23hq.com/[-.\\w@]+/photo/.+"],"http://www.23hq.com/23/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("img.ly","photo",["img\\.ly/.+"],"http://img.ly/show/thumb/$1",{templateRegex:/.*ly\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new n.fn.oembed.OEmbedProvider("twitgoo.com","photo",["twitgoo\\.com/.+"],"http://twitgoo.com/show/thumb/$1",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new n.fn.oembed.OEmbedProvider("imgur.com","photo",["imgur\\.com/gallery/.+"],r()+"imgur.com/$1l.jpg",{templateRegex:/.*gallery\/([^\/]+).*/,embedtag:{tag:"img"},nocache:1}),new n.fn.oembed.OEmbedProvider("visual.ly","rich",["visual\\.ly/.+"],null,{yql:{xpath:"//a[@id=\\'gc_article_graphic_image\\']/img",from:"htmlstring"}}),new n.fn.oembed.OEmbedProvider("gravtar","photo",["mailto:.+"],null,{templateRegex:/mailto:([^\/]+).*/,template:function(n,t){return'<img src="http://gravatar.com/avatar/'+t.md5()+'.jpg" alt="on Gravtar" class="jqoaImg">'}}),new n.fn.oembed.OEmbedProvider("twitter","rich",["twitter.com/.+"],"https://api.twitter.com/1/statuses/oembed.json?id="),new n.fn.oembed.OEmbedProvider("gmep","rich",["gmep.imeducate.com/.*","gmep.org/.*"],"http://gmep.org/oembed.json"),new n.fn.oembed.OEmbedProvider("urtak","rich",["urtak.com/(u|clr)/.+"],"http://oembed.urtak.com/1/oembed"),new n.fn.oembed.OEmbedProvider("cacoo","rich",["cacoo.com/.+"],"http://cacoo.com/oembed.json"),new n.fn.oembed.OEmbedProvider("dailymile","rich",["dailymile.com/people/.*/entries/.*"],"http://api.dailymile.com/oembed"),new n.fn.oembed.OEmbedProvider("dipity","rich",["dipity.com/timeline/.+"],"http://www.dipity.com/oembed/timeline/",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("sketchfab","rich",["sketchfab.com/show/.+"],"http://sketchfab.com/oembed",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("speakerdeck","rich",["speakerdeck.com/.+"],"http://speakerdeck.com/oembed.json",{useYQL:"json"}),new n.fn.oembed.OEmbedProvider("popplet","rich",["popplet.com/app/.*"],"http://popplet.com/app/Popplet_Alpha.swf?page_id=$1&em=1",{templateRegex:/.*#\/([^\/]+).*/,embedtag:{width:460,height:460}}),new n.fn.oembed.OEmbedProvider("pearltrees","rich",["pearltrees.com/.*"],"http://cdn.pearltrees.com/s/embed/getApp?",{templateRegex:/.*N-f=1_(\d+).*N-p=(\d+).*/,embedtag:{width:460,height:460,flashvars:"lang=en_US&amp;embedId=pt-embed-$1-693&amp;treeId=$1&amp;pearlId=$2&amp;treeTitle=Diagrams%2FVisualization&amp;site=www.pearltrees.com%2FF"}}),new n.fn.oembed.OEmbedProvider("prezi","rich",["prezi.com/.*"],"http://prezi.com/bin/preziloader.swf?",{templateRegex:/.*com\/([^\/]+)\/.*/,embedtag:{width:550,height:400,flashvars:"prezi_id=$1&amp;lock_to_path=0&amp;color=ffffff&amp;autoplay=no&amp;autohide_ctrls=0"}}),new n.fn.oembed.OEmbedProvider("tourwrist","rich",["tourwrist.com/tours/.+"],null,{templateRegex:/.*tours.([\d]+).*/,template:function(n,t){return setTimeout(function(){loadEmbeds&&loadEmbeds()},2e3),"<div id='"+t+"' class='tourwrist-tour-embed direct'><\/div> <script type='text/javascript' src='http://tourwrist.com/tour_embed.js'><\/script>"}}),new n.fn.oembed.OEmbedProvider("meetup","rich",["meetup\\.(com|ps)/.+"],r()+"api.meetup.com/oembed"),new n.fn.oembed.OEmbedProvider("ebay","rich",["ebay\\.*"],r()+"togo.ebay.com/togo/togo.swf?2008013100",{templateRegex:/.*\/([^\/]+)\/(\d{10,13}).*/,embedtag:{width:355,height:300,flashvars:"base=http://togo.ebay.com/togo/&lang=en-us&mode=normal&itemid=$2&query=$1"}}),new n.fn.oembed.OEmbedProvider("wikipedia","rich",["wikipedia.org/wiki/.+"],"http://$1.wikipedia.org/w/api.php?action=parse&page=$2&format=json&section=0&callback=?",{templateRegex:/.*\/\/([\w]+).*\/wiki\/([^\/]+).*/,templateData:function(n){if(!n.parse)return!1;var t=n.parse.text["*"].replace(/href="\/wiki/g,'href="http://en.wikipedia.org/wiki');return'<div id="content"><h3><a class="nav-link" href="http://en.wikipedia.org/wiki/'+n.parse.displaytitle+'">'+n.parse.displaytitle+"<\/a><\/h3>"+t+"<\/div>"}}),new n.fn.oembed.OEmbedProvider("imdb","rich",["imdb.com/title/.+"],"http://www.imdbapi.com/?i=$1&callback=?",{templateRegex:/.*\/title\/([^\/]+).*/,templateData:function(n){return n.Title?'<div id="content"><h3><a class="nav-link" href="http://imdb.com/title/'+n.ID+'/">'+n.Title+"<\/a> ("+n.Year+")<\/h3><p>Starring: "+n.Actors+'<\/p><div id="photo-wrap" style="margin: auto;width:600px;height:450px;"><img class="photo" id="photo-display" src="'+n.Poster+'" alt="'+n.Title+'"><\/div>  <div id="view-photo-caption">'+n.Plot+"<\/div><\/div>":!1}}),new n.fn.oembed.OEmbedProvider("livejournal","rich",["livejournal.com/"],"http://ljpic.seacrow.com/json/$2$4?jsonp=?",{templateRegex:/(http:\/\/(((?!users).)+)\.livejournal\.com|.*users\.livejournal\.com\/([^\/]+)).*/,templateData:function(n){return!!n.username&&'<div><img src="'+n.image+'" align="left" style="margin-right: 1em;" /><span class="oembedall-ljuser"><a href="http://'+n.username+'.livejournal.com/profile"><img src="http://www.livejournal.com/img/userinfo.gif" alt="[info]" width="17" height="17" /><\/a><a href="http://'+n.username+'.livejournal.com/">'+n.username+"<\/a><\/span><br />"+n.name+"<\/div>"}}),new n.fn.oembed.OEmbedProvider("circuitbee","rich",["circuitbee\\.com/circuit/view/.+"],"http://c.circuitbee.com/build/r/schematic-embed.html?id=$1",{templateRegex:/.*circuit\/view\/(\d+).*/,embedtag:{tag:"iframe",width:"500",height:"350"}}),new n.fn.oembed.OEmbedProvider("googlecalendar","rich",["www.google.com/calendar/embed?.+"],"$1",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"800",height:"600"}}),new n.fn.oembed.OEmbedProvider("jsfiddle","rich",["jsfiddle.net/[^/]+/?"],"http://jsfiddle.net/$1/embedded/result,js,resources,html,css/?",{templateRegex:/.*net\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"300"}}),new n.fn.oembed.OEmbedProvider("jsbin","rich",["jsbin.com/.+"],"http://jsbin.com/$1/?",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"300"}}),new n.fn.oembed.OEmbedProvider("jotform","rich",["form.jotform.co/form/.+"],"$1?",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"100%",height:"507"}}),new n.fn.oembed.OEmbedProvider("reelapp","rich",["reelapp\\.com/.+"],"http://www.reelapp.com/$1/embed",{templateRegex:/.*com\/(\S{6}).*/,embedtag:{tag:"iframe",width:"400",height:"338"}}),new n.fn.oembed.OEmbedProvider("linkedin","rich",["linkedin.com/pub/.+"],"https://www.linkedin.com/cws/member/public_profile?public_profile_url=$1&format=inline&isFramed=true",{templateRegex:/(.*)/,embedtag:{tag:"iframe",width:"368px",height:"auto"}}),new n.fn.oembed.OEmbedProvider("timetoast","rich",["timetoast.com/timelines/[0-9]+"],"http://www.timetoast.com/flash/TimelineViewer.swf?passedTimelines=$1",{templateRegex:/.*timelines\/([0-9]*)/,embedtag:{width:550,height:400,nocache:1}}),new n.fn.oembed.OEmbedProvider("pastebin","rich",["pastebin\\.com/[\\S]{8}"],"http://pastebin.com/embed_iframe.php?i=$1",{templateRegex:/.*\/(\S{8}).*/,embedtag:{tag:"iframe",width:"100%",height:"auto"}}),new n.fn.oembed.OEmbedProvider("mixlr","rich",["mixlr.com/.+"],"http://mixlr.com/embed/$1?autoplay=ae",{templateRegex:/.*com\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:"auto"}}),new n.fn.oembed.OEmbedProvider("pastie","rich",["pastie\\.org/pastes/.+"],null,{yql:{xpath:'//pre[@class="textmate-source"]'}}),new n.fn.oembed.OEmbedProvider("github","rich",["gist.github.com/.+"],"https://github.com/api/oembed"),new n.fn.oembed.OEmbedProvider("github","rich",["github.com/[-.\\w@]+/[-.\\w@]+"],"https://api.github.com/repos/$1/$2?callback=?",{templateRegex:/.*\/([^\/]+)\/([^\/]+).*/,templateData:function(n){return n.data.html_url?'<div class="oembedall-githubrepos"><ul class="oembedall-repo-stats"><li>'+n.data.language+'<\/li><li class="oembedall-watchers"><a title="Watchers" href="'+n.data.html_url+'/watchers">&#x25c9; '+n.data.watchers+'<\/a><\/li><li class="oembedall-forks"><a title="Forks" href="'+n.data.html_url+'/network">&#x0265; '+n.data.forks+'<\/a><\/li><\/ul><h3><a href="'+n.data.html_url+'">'+n.data.name+'<\/a><\/h3><div class="oembedall-body"><p class="oembedall-description">'+n.data.description+'<\/p><p class="oembedall-updated-at">Last updated: '+n.data.pushed_at+"<\/p><\/div><\/div>":!1}}),new n.fn.oembed.OEmbedProvider("facebook","rich",["facebook.com/(people/[^\\/]+/\\d+|[^\\/]+$)"],"https://graph.facebook.com/$2$3/?callback=?",{templateRegex:/.*facebook.com\/(people\/[^\/]+\/(\d+).*|([^\/]+$))/,templateData:function(n){if(!n.id)return!1;var t='<div class="oembedall-facebook1"><div class="oembedall-facebook2"><a href="http://www.facebook.com/">facebook<\/a> ';return t+=n.from?'<a href="http://www.facebook.com/'+n.from.id+'">'+n.from.name+"<\/a>":n.link?'<a href="'+n.link+'">'+n.name+"<\/a>":n.username?'<a href="http://www.facebook.com/'+n.username+'">'+n.name+"<\/a>":'<a href="http://www.facebook.com/'+n.id+'">'+n.name+"<\/a>",t+='<\/div><div class="oembedall-facebookBody"><div class="contents">',t+=n.picture?'<a href="'+n.link+'"><img src="'+n.picture+'"><\/a>':'<img src="https://graph.facebook.com/'+n.id+'/picture">',n.from&&(t+='<a href="'+n.link+'">'+n.name+"<\/a>"),n.founded&&(t+="Founded: <strong>"+n.founded+"<\/strong><br>"),n.category&&(t+="Category: <strong>"+n.category+"<\/strong><br>"),n.website&&(t+='Website: <strong><a href="'+n.website+'">'+n.website+"<\/a><\/strong><br>"),n.gender&&(t+="Gender: <strong>"+n.gender+"<\/strong><br>"),n.description&&(t+=n.description+"<br>"),t+"<\/div><\/div>"}}),new n.fn.oembed.OEmbedProvider("stackoverflow","rich",["stackoverflow.com/questions/[\\d]+"],"http://api.stackoverflow.com/1.1/questions/$1?body=true&jsonp=?",{templateRegex:/.*questions\/([\d]+).*/,templateData:function(t){if(!t.questions)return!1;var r=t.questions[0],f=n(r.body).text(),u='<div class="oembedall-stoqembed"><div class="oembedall-statscontainer"><div class="oembedall-statsarrow"><\/div><div class="oembedall-stats"><div class="oembedall-vote"><div class="oembedall-votes"><span class="oembedall-vote-count-post"><strong>'+(r.up_vote_count-r.down_vote_count)+'<\/strong><\/span><div class="oembedall-viewcount">vote(s)<\/div><\/div><\/div><div class="oembedall-status"><strong>'+r.answer_count+'<\/strong>answer<\/div><\/div><div class="oembedall-views">'+r.view_count+' view(s)<\/div><\/div><div class="oembedall-summary"><h3><a class="oembedall-question-hyperlink" href="http://stackoverflow.com/questions/'+r.question_id+'/">'+r.title+'<\/a><\/h3><div class="oembedall-excerpt">'+f.substring(0,100)+'...<\/div><div class="oembedall-tags">';for(i in r.tags)u+='<a title="" class="oembedall-post-tag" href="http://stackoverflow.com/questions/tagged/'+r.tags[i]+'">'+r.tags[i]+"<\/a>";return u+('<\/div><div class="oembedall-fr"><div class="oembedall-user-info"><div class="oembedall-user-gravatar32"><a href="http://stackoverflow.com/users/'+r.owner.user_id+"/"+r.owner.display_name+'"><img width="32" height="32" alt="" src="http://www.gravatar.com/avatar/'+r.owner.email_hash+'?s=32&amp;d=identicon&amp;r=PG"><\/a><\/div><div class="oembedall-user-details"><a href="http://stackoverflow.com/users/'+r.owner.user_id+"/"+r.owner.display_name+'">'+r.owner.display_name+'<\/a><br><span title="reputation score" class="oembedall-reputation-score">'+r.owner.reputation+"<\/span><\/div><\/div><\/div><\/div><\/div>")}}),new n.fn.oembed.OEmbedProvider("wordpress","rich",["wordpress\\.com/.+","blogs\\.cnn\\.com/.+","techcrunch\\.com/.+","wp\\.me/.+"],"http://public-api.wordpress.com/oembed/1.0/?for=jquery-oembed-all"),new n.fn.oembed.OEmbedProvider("screenr","rich",["screenr.com"],"http://www.screenr.com/embed/$1",{templateRegex:/.*\/([^\/]+).*/,embedtag:{tag:"iframe",width:"650",height:396}}),new n.fn.oembed.OEmbedProvider("gigpans","rich",["gigapan\\.org/[-.\\w@]+/\\d+"],"http://gigapan.org/gigapans/$1/options/nosnapshots/iframe/flash.html",{templateRegex:/.*\/(\d+)\/?.*/,embedtag:{tag:"iframe",width:"100%",height:400}}),new n.fn.oembed.OEmbedProvider("scribd","rich",["scribd\\.com/.+"],r()+"www.scribd.com/embeds/$1/content?start_page=1&view_mode=list",{templateRegex:/.*doc\/([^\/]+).*/,embedtag:{tag:"iframe",width:"100%",height:600}}),new n.fn.oembed.OEmbedProvider("kickstarter","rich",["kickstarter\\.com/projects/.+"],"$1/widget/card.html",{templateRegex:/([^\?]+).*/,embedtag:{tag:"iframe",width:"220",height:380}}),new n.fn.oembed.OEmbedProvider("amazon","rich",["amzn.com/B+","amazon.com.*/(B\\S+)($|\\/.*)"],r()+"rcm.amazon.com/e/cm?t=_APIKEY_&o=1&p=8&l=as1&asins=$1&ref=qf_br_asin_til&fc1=000000&IS2=1&lt1=_blank&m=amazon&lc1=0000FF&bc1=000000&bg1=FFFFFF&f=ifr",{apikey:!0,templateRegex:/.*\/(B[0-9A-Z]+)($|\/.*)/,embedtag:{tag:"iframe",width:"120px",height:"240px"}}),new n.fn.oembed.OEmbedProvider("slideshare","rich",["slideshare.net"],r()+"www.slideshare.net/api/oembed/2",{format:"jsonp"}),new n.fn.oembed.OEmbedProvider("roomsharejp","rich",["roomshare\\.jp/(en/)?post/.*"],"http://roomshare.jp/oembed.json"),new n.fn.oembed.OEmbedProvider("lanyard","rich",["lanyrd.com/\\d+/.+"],null,{yql:{xpath:'(//div[@class="primary"])[1]',from:"htmlstring",datareturn:function(n){return n.result?'<div class="oembedall-lanyard">'+n.result+"<\/div>":!1}}}),new n.fn.oembed.OEmbedProvider("asciiartfarts","rich",["asciiartfarts.com/\\d+.html"],null,{yql:{xpath:"//pre/font",from:"htmlstring",datareturn:function(n){return n.result?'<pre style="background-color:000;">'+n.result+"<\/div>":!1}}}),new n.fn.oembed.OEmbedProvider("opengraph","rich",[".*"],null,{yql:{xpath:"//meta|//title|//link",from:"html",datareturn:function(i){var r,u,f;return(!i["og:title"]&&i.title&&i.description&&(i["og:title"]=i.title),!i["og:title"]&&!i.title)?!1:(r=n("<p/>"),i["og:video"]?(u=n('<embed src="'+i["og:video"]+'"/>'),u.attr("type",i["og:video:type"]||"application/x-shockwave-flash").css("max-height",t.maxHeight||"auto").css("max-width",t.maxWidth||"auto"),i["og:video:width"]&&u.attr("width",i["og:video:width"]),i["og:video:height"]&&u.attr("height",i["og:video:height"]),r.append(u)):i["og:image"]&&(f=n('<img src="'+i["og:image"]+'">'),f.css("max-height",t.maxHeight||"auto").css("max-width",t.maxWidth||"auto"),i["og:image:width"]&&f.attr("width",i["og:image:width"]),i["og:image:height"]&&f.attr("height",i["og:image:height"]),r.append(f)),i["og:title"]&&r.append("<b>"+i["og:title"]+"<\/b><br/>"),i["og:description"]?r.append(i["og:description"]+"<br/>"):i.description&&r.append(i.description+"<br/>"),r)}}})]})(jQuery);String.prototype.md5=function(){var u=function(n,t){var i=(n&65535)+(t&65535),r=(n>>16)+(t>>16)+(i>>16);return r<<16|i&65535},e=function(n,t){return n<<t|n>>>32-t},f=function(n,t,i,r,f,o){return u(e(u(u(t,n),u(r,o)),f),i)},n=function(n,t,i,r,u,e,o){return f(t&i|~t&r,n,t,u,e,o)},t=function(n,t,i,r,u,e,o){return f(t&r|i&~r,n,t,u,e,o)},i=function(n,t,i,r,u,e,o){return f(t^i^r,n,t,u,e,o)},r=function(n,t,i,r,u,e,o){return f(i^(t|~r),n,t,u,e,o)},o=function(f){for(var l,a,v,y,p=f.length,e=1732584193,o=-271733879,s=-1732584194,h=271733878,c=0;c<p;c+=16)l=e,a=o,v=s,y=h,e=n(e,o,s,h,f[c+0],7,-680876936),h=n(h,e,o,s,f[c+1],12,-389564586),s=n(s,h,e,o,f[c+2],17,606105819),o=n(o,s,h,e,f[c+3],22,-1044525330),e=n(e,o,s,h,f[c+4],7,-176418897),h=n(h,e,o,s,f[c+5],12,1200080426),s=n(s,h,e,o,f[c+6],17,-1473231341),o=n(o,s,h,e,f[c+7],22,-45705983),e=n(e,o,s,h,f[c+8],7,1770035416),h=n(h,e,o,s,f[c+9],12,-1958414417),s=n(s,h,e,o,f[c+10],17,-42063),o=n(o,s,h,e,f[c+11],22,-1990404162),e=n(e,o,s,h,f[c+12],7,1804603682),h=n(h,e,o,s,f[c+13],12,-40341101),s=n(s,h,e,o,f[c+14],17,-1502002290),o=n(o,s,h,e,f[c+15],22,1236535329),e=t(e,o,s,h,f[c+1],5,-165796510),h=t(h,e,o,s,f[c+6],9,-1069501632),s=t(s,h,e,o,f[c+11],14,643717713),o=t(o,s,h,e,f[c+0],20,-373897302),e=t(e,o,s,h,f[c+5],5,-701558691),h=t(h,e,o,s,f[c+10],9,38016083),s=t(s,h,e,o,f[c+15],14,-660478335),o=t(o,s,h,e,f[c+4],20,-405537848),e=t(e,o,s,h,f[c+9],5,568446438),h=t(h,e,o,s,f[c+14],9,-1019803690),s=t(s,h,e,o,f[c+3],14,-187363961),o=t(o,s,h,e,f[c+8],20,1163531501),e=t(e,o,s,h,f[c+13],5,-1444681467),h=t(h,e,o,s,f[c+2],9,-51403784),s=t(s,h,e,o,f[c+7],14,1735328473),o=t(o,s,h,e,f[c+12],20,-1926607734),e=i(e,o,s,h,f[c+5],4,-378558),h=i(h,e,o,s,f[c+8],11,-2022574463),s=i(s,h,e,o,f[c+11],16,1839030562),o=i(o,s,h,e,f[c+14],23,-35309556),e=i(e,o,s,h,f[c+1],4,-1530992060),h=i(h,e,o,s,f[c+4],11,1272893353),s=i(s,h,e,o,f[c+7],16,-155497632),o=i(o,s,h,e,f[c+10],23,-1094730640),e=i(e,o,s,h,f[c+13],4,681279174),h=i(h,e,o,s,f[c+0],11,-358537222),s=i(s,h,e,o,f[c+3],16,-722521979),o=i(o,s,h,e,f[c+6],23,76029189),e=i(e,o,s,h,f[c+9],4,-640364487),h=i(h,e,o,s,f[c+12],11,-421815835),s=i(s,h,e,o,f[c+15],16,530742520),o=i(o,s,h,e,f[c+2],23,-995338651),e=r(e,o,s,h,f[c+0],6,-198630844),h=r(h,e,o,s,f[c+7],10,1126891415),s=r(s,h,e,o,f[c+14],15,-1416354905),o=r(o,s,h,e,f[c+5],21,-57434055),e=r(e,o,s,h,f[c+12],6,1700485571),h=r(h,e,o,s,f[c+3],10,-1894986606),s=r(s,h,e,o,f[c+10],15,-1051523),o=r(o,s,h,e,f[c+1],21,-2054922799),e=r(e,o,s,h,f[c+8],6,1873313359),h=r(h,e,o,s,f[c+15],10,-30611744),s=r(s,h,e,o,f[c+6],15,-1560198380),o=r(o,s,h,e,f[c+13],21,1309151649),e=r(e,o,s,h,f[c+4],6,-145523070),h=r(h,e,o,s,f[c+11],10,-1120210379),s=r(s,h,e,o,f[c+2],15,718787259),o=r(o,s,h,e,f[c+9],21,-343485551),e=u(e,l),o=u(o,a),s=u(s,v),h=u(h,y);return[e,o,s,h]},s=function(n){for(var i="0123456789abcdef",r="",u=n.length*4,t=0;t<u;t++)r+=i.charAt(n[t>>2]>>t%4*8+4&15)+i.charAt(n[t>>2]>>t%4*8&15);return r},h=function(n){for(var u=(n.length+8>>6)+1,i=[],e=u*16,t,f=n.length,r=0;r<e;r++)i.push(0);for(t=0;t<f;t++)i[t>>2]|=(n.charCodeAt(t)&255)<<t%4*8;return i[t>>2]|=128<<t%4*8,i[u*16-2]=f*8,i};return s(o(h(this)))};\r
diff --git a/sources/plugins/oembed/plugin.js b/sources/plugins/oembed/plugin.js
new file mode 100644 (file)
index 0000000..9ad1ead
--- /dev/null
@@ -0,0 +1,446 @@
+/**\r
+* oEmbed Plugin plugin\r
+* Licensed under the MIT license\r
+* jQuery Embed Plugin: http://code.google.com/p/jquery-oembed/ (MIT License)\r
+* Plugin for: http://ckeditor.com/license (GPL/LGPL/MPL: http://ckeditor.com/license)\r
+*/\r
+\r
+(function() {\r
+        CKEDITOR.plugins.add('oembed', {\r
+            icons: 'oembed',\r
+            hidpi: true,\r
+            requires: 'widget,dialog',\r
+            lang: 'de,en,fr,nl,pl,pt-br,ru,tr', // %REMOVE_LINE_CORE%\r
+            version: 1.17,\r
+            init: function(editor) {\r
+                // Load jquery?\r
+                loadjQueryLibaries();\r
+\r
+                CKEDITOR.tools.extend(CKEDITOR.editor.prototype, {\r
+                    oEmbed: function(url, maxWidth, maxHeight, responsiveResize) {\r
+\r
+                        if (url.length < 1 || url.indexOf('http') < 0) {\r
+                            alert(editor.lang.oembed.invalidUrl);\r
+                            return false;\r
+                        }\r
+\r
+                        function embed() {\r
+                            if (maxWidth == null || maxWidth == 'undefined') {\r
+                                maxWidth = null;\r
+                            }\r
+\r
+                            if (maxHeight == null || maxHeight == 'undefined') {\r
+                                maxHeight = null;\r
+                            }\r
+\r
+                            if (responsiveResize == null || responsiveResize == 'undefined') {\r
+                                responsiveResize = false;\r
+                            }\r
+\r
+                            embedCode(url, editor, false, maxWidth, maxHeight, responsiveResize);\r
+                        }\r
+\r
+                        if (typeof(jQuery.fn.oembed) === 'undefined') {\r
+                            CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js'), function() {\r
+                                embed();\r
+                            });\r
+                        } else {\r
+                            embed();\r
+                        }\r
+\r
+                        return true;\r
+                    }\r
+                });\r
+\r
+                editor.widgets.add('oembed', {\r
+                    draggable: false,\r
+                    mask: true,\r
+                    dialog: 'oembed',\r
+                    allowedContent: {\r
+                        div: {\r
+                            styles: 'text-align,float',\r
+                            attributes: '*',\r
+                            classes: editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent"\r
+                        },\r
+                        'div(embeddedContent,oembed-provider-*) iframe': {\r
+                            attributes: '*'\r
+                        },\r
+                        'div(embeddedContent,oembed-provider-*) blockquote': {\r
+                            attributes: '*'\r
+                        },\r
+                        'div(embeddedContent,oembed-provider-*) script': {\r
+                            attributes: '*'\r
+                        }\r
+                    },\r
+                    template:\r
+                        '<div class="' + (editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent") + '">' +\r
+                            '</div>',\r
+                    upcast: function(element) {\r
+                        return element.name == 'div' && element.hasClass(editor.config.oembed_WrapperClass != null ? editor.config.oembed_WrapperClass : "embeddedContent");\r
+                    },\r
+                    init: function() {\r
+                        var data = {\r
+                            oembed: this.element.data('oembed') || '',\r
+                            resizeType: this.element.data('resizeType') || 'noresize',\r
+                            maxWidth: this.element.data('maxWidth') || 560,\r
+                            maxHeight: this.element.data('maxHeight') || 315,\r
+                            align: this.element.data('align') || 'none',\r
+                            oembed_provider: this.element.data('oembed_provider') || ''\r
+                        };\r
+\r
+                        this.setData(data);\r
+                        this.element.addClass('oembed-provider-' + data.oembed_provider);\r
+\r
+                        this.on('dialog', function(evt) {\r
+                            evt.data.widget = this;\r
+                        }, this);\r
+                    }\r
+                });\r
+\r
+                editor.ui.addButton('oembed', {\r
+                    label: editor.lang.oembed.button,\r
+                    command: 'oembed',\r
+                    toolbar: 'insert,10',\r
+                    icon: this.path + "icons/" + (CKEDITOR.env.hidpi ? "hidpi/" : "") + "oembed.png"\r
+                });\r
+\r
+                var resizeTypeChanged = function() {\r
+                    var dialog = this.getDialog(),\r
+                        resizetype = this.getValue(),\r
+                        maxSizeBox = dialog.getContentElement('general', 'maxSizeBox').getElement(),\r
+                        sizeBox = dialog.getContentElement('general', 'sizeBox').getElement();\r
+\r
+                    if (resizetype == 'noresize') {\r
+                        maxSizeBox.hide();\r
+\r
+                        sizeBox.hide();\r
+                    } else if (resizetype == "custom") {\r
+                        maxSizeBox.hide();\r
+\r
+                        sizeBox.show();\r
+                    } else {\r
+                        maxSizeBox.show();\r
+\r
+                        sizeBox.hide();\r
+                    }\r
+\r
+                };\r
+\r
+                String.prototype.beginsWith = function(string) {\r
+                    return (this.indexOf(string) === 0);\r
+                };\r
+\r
+                function loadjQueryLibaries() {\r
+                    if (typeof(jQuery) === 'undefined') {\r
+                        CKEDITOR.scriptLoader.load('//ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js', function() {\r
+                            jQuery.noConflict();\r
+                            if (typeof(jQuery.fn.oembed) === 'undefined') {\r
+                                CKEDITOR.scriptLoader.load(\r
+                                    CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js')\r
+                                );\r
+                            }\r
+                        });\r
+\r
+                    } else if (typeof(jQuery.fn.oembed) === 'undefined') {\r
+                        CKEDITOR.scriptLoader.load(CKEDITOR.getUrl(CKEDITOR.plugins.getPath('oembed') + 'libs/jquery.oembed.min.js'));\r
+                    }\r
+                }\r
+\r
+                function embedCode(url, instance, maxWidth, maxHeight, responsiveResize, resizeType, align, widget) {\r
+                    jQuery('body').oembed(url, {\r
+                        onEmbed: function(e) {\r
+                            var elementAdded = false,\r
+                                provider = jQuery.fn.oembed.getOEmbedProvider(url);\r
+\r
+                            widget.element.data('resizeType', resizeType);\r
+                            if (resizeType == "responsive" || resizeType == "custom") {\r
+                                widget.element.data('maxWidth', maxWidth);\r
+                                widget.element.data('maxHeight', maxHeight);\r
+                            }\r
+\r
+                            widget.element.data('align', align);\r
+\r
+                            // TODO handle align\r
+                            if (align == 'center') {\r
+                                if (!widget.inline)\r
+                                    widget.element.setStyle('text-align', 'center');\r
+\r
+                                widget.element.removeStyle('float');\r
+                            } else {\r
+                                if (!widget.inline)\r
+                                    widget.element.removeStyle('text-align');\r
+\r
+                                if (align == 'none')\r
+                                    widget.element.removeStyle('float');\r
+                                else\r
+                                    widget.element.setStyle('float', align);\r
+                            }\r
+\r
+                            if (typeof e.code === 'string') {\r
+                                if (widget.element.$.firstChild) {\r
+                                    widget.element.$.removeChild(widget.element.$.firstChild);\r
+                                }\r
+\r
+                                widget.element.appendHtml(e.code);\r
+                                widget.element.data('oembed', url);\r
+                                widget.element.data('oembed_provider', provider.name);\r
+                                widget.element.addClass('oembed-provider-' + provider.name);\r
+\r
+                                elementAdded = true;\r
+                            } else if (typeof e.code[0].outerHTML === 'string') {\r
+\r
+                                if (widget.element.$.firstChild) {\r
+                                    widget.element.$.removeChild(widget.element.$.firstChild);\r
+                                }\r
+\r
+                                widget.element.appendHtml(e.code[0].outerHTML);\r
+                                widget.element.data('oembed', url);\r
+                                widget.element.data('oembed_provider', provider.name);\r
+                                widget.element.addClass('oembed-provider-' + provider.name);\r
+\r
+                                elementAdded = true;\r
+                            } else {\r
+                                alert(editor.lang.oembed.noEmbedCode);\r
+                            }\r
+                        },\r
+                        onError: function(externalUrl) {\r
+                            if (externalUrl.indexOf("vimeo.com") > 0) {\r
+                                alert(editor.lang.oembed.noVimeo);\r
+                            } else {\r
+                                alert(editor.lang.oembed.Error);\r
+                            }\r
+\r
+                        },\r
+                        maxHeight: maxHeight,\r
+                        maxWidth: maxWidth,\r
+                        useResponsiveResize: responsiveResize,\r
+                        embedMethod: 'editor'\r
+                    });\r
+                }\r
+\r
+                CKEDITOR.dialog.add('oembed', function(editor) {\r
+                    return {\r
+                        title: editor.lang.oembed.title,\r
+                        minWidth: CKEDITOR.env.ie && CKEDITOR.env.quirks ? 568 : 550,\r
+                        minHeight: 155,\r
+                        onShow: function() {\r
+                            var data = {\r
+                                oembed: this.widget.element.data('oembed') || '',\r
+                                resizeType: this.widget.element.data('resizeType') || 'noresize',\r
+                                maxWidth: this.widget.element.data('maxWidth'),\r
+                                maxHeight: this.widget.element.data('maxHeight'),\r
+                                align: this.widget.element.data('align') || 'none'\r
+                            };\r
+\r
+                            this.widget.setData(data);\r
+\r
+                            this.getContentElement('general', 'resizeType').setValue(data.resizeType);\r
+\r
+                            this.getContentElement('general', 'align').setValue(data.align);\r
+\r
+                            var resizetype = this.getContentElement('general', 'resizeType').getValue(),\r
+                                maxSizeBox = this.getContentElement('general', 'maxSizeBox').getElement(),\r
+                                sizeBox = this.getContentElement('general', 'sizeBox').getElement();\r
+\r
+                            if (resizetype == 'noresize') {\r
+                                maxSizeBox.hide();\r
+                                sizeBox.hide();\r
+                            } else if (resizetype == "custom") {\r
+                                maxSizeBox.hide();\r
+\r
+                                sizeBox.show();\r
+                            } else {\r
+                                maxSizeBox.show();\r
+\r
+                                sizeBox.hide();\r
+                            }\r
+                        },\r
+\r
+                        onOk: function() {\r
+                        },\r
+                        contents: [\r
+                            {\r
+                                label: editor.lang.common.generalTab,\r
+                                id: 'general',\r
+                                elements: [\r
+                                    {\r
+                                        type: 'html',\r
+                                        id: 'oembedHeader',\r
+                                        html: '<div style="white-space:normal;width:500px;padding-bottom:10px">' + editor.lang.oembed.pasteUrl + '</div>'\r
+                                    }, {\r
+                                        type: 'text',\r
+                                        id: 'embedCode',\r
+                                        focus: function() {\r
+                                            this.getElement().focus();\r
+                                        },\r
+                                        label: editor.lang.oembed.url,\r
+                                        title: editor.lang.oembed.pasteUrl,\r
+                                        setup: function(widget) {\r
+                                            if (widget.data.oembed) {\r
+                                                this.setValue(widget.data.oembed);\r
+                                            }\r
+                                        },\r
+                                        commit: function(widget) {\r
+                                            var dialog = CKEDITOR.dialog.getCurrent(),\r
+                                                inputCode = dialog.getValueOf('general', 'embedCode').replace(/\s/g, ""),\r
+                                                resizeType = dialog.getContentElement('general', 'resizeType').\r
+                                                    getValue(),\r
+                                                align = dialog.getContentElement('general', 'align').\r
+                                                    getValue(),\r
+                                                maxWidth = null,\r
+                                                maxHeight = null,\r
+                                                responsiveResize = false,\r
+                                                editorInstance = dialog.getParentEditor();\r
+\r
+                                            if (inputCode.length < 1 || inputCode.indexOf('http') < 0) {\r
+                                                alert(editor.lang.oembed.invalidUrl);\r
+                                                return false;\r
+                                            }\r
+\r
+                                            if (resizeType == "noresize") {\r
+                                                responsiveResize = false;\r
+                                                maxWidth = null;\r
+                                                maxHeight = null;\r
+                                            } else if (resizeType == "responsive") {\r
+                                                maxWidth = dialog.getContentElement('general', 'maxWidth').\r
+                                                    getInputElement().\r
+                                                    getValue();\r
+                                                maxHeight = dialog.getContentElement('general', 'maxHeight').\r
+                                                    getInputElement().\r
+                                                    getValue();\r
+\r
+                                                responsiveResize = true;\r
+                                            } else if (resizeType == "custom") {\r
+                                                maxWidth = dialog.getContentElement('general', 'width').\r
+                                                    getInputElement().\r
+                                                    getValue();\r
+                                                maxHeight = dialog.getContentElement('general', 'height').\r
+                                                    getInputElement().\r
+                                                    getValue();\r
+\r
+                                                responsiveResize = false;\r
+                                            }\r
+\r
+                                            embedCode(inputCode, editorInstance, maxWidth, maxHeight, responsiveResize, resizeType, align, widget);\r
+\r
+                                            widget.setData('oembed', inputCode);\r
+                                            widget.setData('resizeType', resizeType);\r
+                                            widget.setData('align', align);\r
+                                            widget.setData('maxWidth', maxWidth);\r
+                                            widget.setData('maxHeight', maxHeight);\r
+                                        }\r
+                                    }, {\r
+                                        type: 'hbox',\r
+                                        widths: ['50%', '50%'],\r
+                                        children: [\r
+                                            {\r
+                                                id: 'resizeType',\r
+                                                type: 'select',\r
+                                                label: editor.lang.oembed.resizeType,\r
+                                                'default': 'noresize',\r
+                                                setup: function(widget) {\r
+                                                    if (widget.data.resizeType) {\r
+                                                        this.setValue(widget.data.resizeType);\r
+                                                    }\r
+                                                },\r
+                                                items: [\r
+                                                    [editor.lang.oembed.noresize, 'noresize'],\r
+                                                    [editor.lang.oembed.responsive, 'responsive'],\r
+                                                    [editor.lang.oembed.custom, 'custom']\r
+                                                ],\r
+                                                onChange: resizeTypeChanged\r
+                                            }, {\r
+                                                type: 'hbox',\r
+                                                id: 'maxSizeBox',\r
+                                                widths: ['120px', '120px'],\r
+                                                style: 'float:left;position:absolute;left:58%;width:200px',\r
+                                                children: [\r
+                                                    {\r
+                                                        type: 'text',\r
+                                                        width: '100px',\r
+                                                        id: 'maxWidth',\r
+                                                        'default': editor.config.oembed_maxWidth != null ? editor.config.oembed_maxWidth : '560',\r
+                                                        label: editor.lang.oembed.maxWidth,\r
+                                                        title: editor.lang.oembed.maxWidthTitle,\r
+                                                        setup: function(widget) {\r
+                                                            if (widget.data.maxWidth) {\r
+                                                                this.setValue(widget.data.maxWidth);\r
+                                                            }\r
+                                                        }\r
+                                                    }, {\r
+                                                        type: 'text',\r
+                                                        id: 'maxHeight',\r
+                                                        width: '120px',\r
+                                                        'default': editor.config.oembed_maxHeight != null ? editor.config.oembed_maxHeight : '315',\r
+                                                        label: editor.lang.oembed.maxHeight,\r
+                                                        title: editor.lang.oembed.maxHeightTitle,\r
+                                                        setup: function(widget) {\r
+                                                            if (widget.data.maxHeight) {\r
+                                                                this.setValue(widget.data.maxHeight);\r
+                                                            }\r
+                                                        }\r
+                                                    }\r
+                                                ]\r
+                                            }, {\r
+                                                type: 'hbox',\r
+                                                id: 'sizeBox',\r
+                                                widths: ['120px', '120px'],\r
+                                                style: 'float:left;position:absolute;left:58%;width:200px',\r
+                                                children: [\r
+                                                    {\r
+                                                        type: 'text',\r
+                                                        id: 'width',\r
+                                                        width: '100px',\r
+                                                        'default': editor.config.oembed_maxWidth != null ? editor.config.oembed_maxWidth : '560',\r
+                                                        label: editor.lang.oembed.width,\r
+                                                        title: editor.lang.oembed.widthTitle,\r
+                                                        setup: function(widget) {\r
+                                                            if (widget.data.maxWidth) {\r
+                                                                this.setValue(widget.data.maxWidth);\r
+                                                            }\r
+                                                        }\r
+                                                    }, {\r
+                                                        type: 'text',\r
+                                                        id: 'height',\r
+                                                        width: '120px',\r
+                                                        'default': editor.config.oembed_maxHeight != null ? editor.config.oembed_maxHeight : '315',\r
+                                                        label: editor.lang.oembed.height,\r
+                                                        title: editor.lang.oembed.heightTitle,\r
+                                                        setup: function(widget) {\r
+                                                            if (widget.data.maxHeight) {\r
+                                                                this.setValue(widget.data.maxHeight);\r
+                                                            }\r
+                                                        }\r
+                                                    }\r
+                                                ]\r
+                                            }\r
+                                        ]\r
+                                    }, {\r
+                                        type: 'hbox',\r
+                                        id: 'alignment',\r
+                                        children: [\r
+                                            {\r
+                                                id: 'align',\r
+                                                type: 'radio',\r
+                                                items: [\r
+                                                    [editor.lang.oembed.none, 'none'],\r
+                                                    [editor.lang.common.alignLeft, 'left'],\r
+                                                    [editor.lang.common.alignCenter, 'center'],\r
+                                                    [editor.lang.common.alignRight, 'right']\r
+                                                ],\r
+                                                label: editor.lang.common.align,\r
+                                                setup: function(widget) {\r
+                                                    this.setValue(widget.data.align);\r
+                                                }\r
+                                            }\r
+                                        ]\r
+                                    }\r
+                                ]\r
+                            }\r
+                        ]\r
+                    };\r
+                });\r
+            }\r
+        });\r
+    }\r
+)();\r
diff --git a/sources/plugins/panel/plugin.js b/sources/plugins/panel/plugin.js
new file mode 100644 (file)
index 0000000..b64c540
--- /dev/null
@@ -0,0 +1,403 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'panel', {\r
+               beforeInit: function( editor ) {\r
+                       editor.ui.addHandler( CKEDITOR.UI_PANEL, CKEDITOR.ui.panel.handler );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * Panel UI element.\r
+        *\r
+        * @readonly\r
+        * @property {String} [='panel']\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.UI_PANEL = 'panel';\r
+\r
+       /**\r
+        * @class\r
+        * @constructor Creates a panel class instance.\r
+        * @param {CKEDITOR.dom.document} document\r
+        * @param {Object} definition\r
+        */\r
+       CKEDITOR.ui.panel = function( document, definition ) {\r
+               // Copy all definition properties to this object.\r
+               if ( definition )\r
+                       CKEDITOR.tools.extend( this, definition );\r
+\r
+               // Set defaults.\r
+               CKEDITOR.tools.extend( this, {\r
+                       className: '',\r
+                       css: []\r
+               } );\r
+\r
+               this.id = CKEDITOR.tools.getNextId();\r
+               this.document = document;\r
+               this.isFramed = this.forceIFrame || this.css.length;\r
+\r
+               this._ = {\r
+                       blocks: {}\r
+               };\r
+       };\r
+\r
+       /**\r
+        * Represents panel handler object.\r
+        *\r
+        * @class\r
+        * @singleton\r
+        * @extends CKEDITOR.ui.handlerDefinition\r
+        */\r
+       CKEDITOR.ui.panel.handler = {\r
+               /**\r
+                * Transforms a panel definition in a {@link CKEDITOR.ui.panel} instance.\r
+                *\r
+                * @param {Object} definition\r
+                * @returns {CKEDITOR.ui.panel}\r
+                */\r
+               create: function( definition ) {\r
+                       return new CKEDITOR.ui.panel( definition );\r
+               }\r
+       };\r
+\r
+       var panelTpl = CKEDITOR.addTemplate( 'panel', '<div lang="{langCode}" id="{id}" dir={dir}' +\r
+               ' class="cke cke_reset_all {editorId} cke_panel cke_panel {cls} cke_{dir}"' +\r
+               ' style="z-index:{z-index}" role="presentation">' +\r
+               '{frame}' +\r
+               '</div>' );\r
+\r
+       var frameTpl = CKEDITOR.addTemplate( 'panel-frame', '<iframe id="{id}" class="cke_panel_frame" role="presentation" frameborder="0" src="{src}"></iframe>' );\r
+\r
+       var frameDocTpl = CKEDITOR.addTemplate( 'panel-frame-inner', '<!DOCTYPE html>' +\r
+               '<html class="cke_panel_container {env}" dir="{dir}" lang="{langCode}">' +\r
+                       '<head>{css}</head>' +\r
+                       '<body class="cke_{dir}"' +\r
+                               ' style="margin:0;padding:0" onload="{onload}"></body>' +\r
+               '<\/html>' );\r
+\r
+       /** @class CKEDITOR.ui.panel */\r
+       CKEDITOR.ui.panel.prototype = {\r
+               /**\r
+                * Renders the combo.\r
+                *\r
+                * @param {CKEDITOR.editor} editor The editor instance which this button is\r
+                * to be used by.\r
+                * @param {Array} [output] The output array to which append the HTML relative\r
+                * to this button.\r
+                */\r
+               render: function( editor, output ) {\r
+                       this.getHolderElement = function() {\r
+                               var holder = this._.holder;\r
+\r
+                               if ( !holder ) {\r
+                                       if ( this.isFramed ) {\r
+                                               var iframe = this.document.getById( this.id + '_frame' ),\r
+                                                       parentDiv = iframe.getParent(),\r
+                                                       doc = iframe.getFrameDocument();\r
+\r
+                                               // Make it scrollable on iOS. (#8308)\r
+                                               CKEDITOR.env.iOS && parentDiv.setStyles( {\r
+                                                       'overflow': 'scroll',\r
+                                                       '-webkit-overflow-scrolling': 'touch'\r
+                                               } );\r
+\r
+                                               var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function() {\r
+                                                       this.isLoaded = true;\r
+                                                       if ( this.onLoad )\r
+                                                               this.onLoad();\r
+                                               }, this ) );\r
+\r
+                                               doc.write( frameDocTpl.output( CKEDITOR.tools.extend( {\r
+                                                       css: CKEDITOR.tools.buildStyleHtml( this.css ),\r
+                                                       onload: 'window.parent.CKEDITOR.tools.callFunction(' + onLoad + ');'\r
+                                               }, data ) ) );\r
+\r
+                                               var win = doc.getWindow();\r
+\r
+                                               // Register the CKEDITOR global.\r
+                                               win.$.CKEDITOR = CKEDITOR;\r
+\r
+                                               // Arrow keys for scrolling is only preventable with 'keypress' event in Opera (#4534).\r
+                                               doc.on( 'keydown', function( evt ) {\r
+                                                       var keystroke = evt.data.getKeystroke(),\r
+                                                               dir = this.document.getById( this.id ).getAttribute( 'dir' );\r
+\r
+                                                       // Delegate key processing to block.\r
+                                                       if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false ) {\r
+                                                               evt.data.preventDefault();\r
+                                                               return;\r
+                                                       }\r
+\r
+                                                       // ESC/ARROW-LEFT(ltr) OR ARROW-RIGHT(rtl)\r
+                                                       if ( keystroke == 27 || keystroke == ( dir == 'rtl' ? 39 : 37 ) ) {\r
+                                                               if ( this.onEscape && this.onEscape( keystroke ) === false )\r
+                                                                       evt.data.preventDefault();\r
+                                                       }\r
+                                               }, this );\r
+\r
+                                               holder = doc.getBody();\r
+                                               holder.unselectable();\r
+                                               CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad );\r
+                                       } else {\r
+                                               holder = this.document.getById( this.id );\r
+                                       }\r
+\r
+                                       this._.holder = holder;\r
+                               }\r
+\r
+                               return holder;\r
+                       };\r
+\r
+                       var data = {\r
+                               editorId: editor.id,\r
+                               id: this.id,\r
+                               langCode: editor.langCode,\r
+                               dir: editor.lang.dir,\r
+                               cls: this.className,\r
+                               frame: '',\r
+                               env: CKEDITOR.env.cssClass,\r
+                               'z-index': editor.config.baseFloatZIndex + 1\r
+                       };\r
+\r
+                       if ( this.isFramed ) {\r
+                               // With IE, the custom domain has to be taken care at first,\r
+                               // for other browers, the 'src' attribute should be left empty to\r
+                               // trigger iframe's 'load' event.\r
+                               var src =\r
+                                       CKEDITOR.env.air ? 'javascript:void(0)' : // jshint ignore:line\r
+                                       CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent( // jshint ignore:line\r
+                                               'document.open();' +\r
+                                               // In IE, the document domain must be set any time we call document.open().\r
+                                               '(' + CKEDITOR.tools.fixDomain + ')();' +\r
+                                               'document.close();'\r
+                                       ) + '}())' :\r
+                                       '';\r
+\r
+                               data.frame = frameTpl.output( {\r
+                                       id: this.id + '_frame',\r
+                                       src: src\r
+                               } );\r
+                       }\r
+\r
+                       var html = panelTpl.output( data );\r
+\r
+                       if ( output )\r
+                               output.push( html );\r
+\r
+                       return html;\r
+               },\r
+\r
+               /**\r
+                * @todo\r
+                */\r
+               addBlock: function( name, block ) {\r
+                       block = this._.blocks[ name ] = block instanceof CKEDITOR.ui.panel.block ? block : new CKEDITOR.ui.panel.block( this.getHolderElement(), block );\r
+\r
+                       if ( !this._.currentBlock )\r
+                               this.showBlock( name );\r
+\r
+                       return block;\r
+               },\r
+\r
+               /**\r
+                * @todo\r
+                */\r
+               getBlock: function( name ) {\r
+                       return this._.blocks[ name ];\r
+               },\r
+\r
+               /**\r
+                * @todo\r
+                */\r
+               showBlock: function( name ) {\r
+                       var blocks = this._.blocks,\r
+                               block = blocks[ name ],\r
+                               current = this._.currentBlock;\r
+\r
+                       // ARIA role works better in IE on the body element, while on the iframe\r
+                       // for FF. (#8864)\r
+                       var holder = !this.forceIFrame || CKEDITOR.env.ie ? this._.holder : this.document.getById( this.id + '_frame' );\r
+\r
+                       if ( current )\r
+                               current.hide();\r
+\r
+                       this._.currentBlock = block;\r
+\r
+                       CKEDITOR.fire( 'ariaWidget', holder );\r
+\r
+                       // Reset the focus index, so it will always go into the first one.\r
+                       block._.focusIndex = -1;\r
+\r
+                       this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block );\r
+\r
+                       block.show();\r
+\r
+                       return block;\r
+               },\r
+\r
+               /**\r
+                * @todo\r
+                */\r
+               destroy: function() {\r
+                       this.element && this.element.remove();\r
+               }\r
+       };\r
+\r
+       /**\r
+        * @class\r
+        *\r
+        * @todo class and all methods\r
+        */\r
+       CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass( {\r
+               /**\r
+                * Creates a block class instances.\r
+                *\r
+                * @constructor\r
+                * @todo\r
+                */\r
+               $: function( blockHolder, blockDefinition ) {\r
+                       this.element = blockHolder.append( blockHolder.getDocument().createElement( 'div', {\r
+                               attributes: {\r
+                                       'tabindex': -1,\r
+                                       'class': 'cke_panel_block'\r
+                               },\r
+                               styles: {\r
+                                       display: 'none'\r
+                               }\r
+                       } ) );\r
+\r
+                       // Copy all definition properties to this object.\r
+                       if ( blockDefinition )\r
+                               CKEDITOR.tools.extend( this, blockDefinition );\r
+\r
+                       // Set the a11y attributes of this element ...\r
+                       this.element.setAttributes( {\r
+                               'role': this.attributes.role || 'presentation',\r
+                               'aria-label': this.attributes[ 'aria-label' ],\r
+                               'title': this.attributes.title || this.attributes[ 'aria-label' ]\r
+                       } );\r
+\r
+                       this.keys = {};\r
+\r
+                       this._.focusIndex = -1;\r
+\r
+                       // Disable context menu for panels.\r
+                       this.element.disableContextMenu();\r
+               },\r
+\r
+               _: {\r
+\r
+                       /**\r
+                        * Mark the item specified by the index as current activated.\r
+                        */\r
+                       markItem: function( index ) {\r
+                               if ( index == -1 )\r
+                                       return;\r
+                               var links = this.element.getElementsByTag( 'a' );\r
+                               var item = links.getItem( this._.focusIndex = index );\r
+\r
+                               // Safari need focus on the iframe window first(#3389), but we need\r
+                               // lock the blur to avoid hiding the panel.\r
+                               if ( CKEDITOR.env.webkit )\r
+                                       item.getDocument().getWindow().focus();\r
+                               item.focus();\r
+\r
+                               this.onMark && this.onMark( item );\r
+                       }\r
+               },\r
+\r
+               proto: {\r
+                       show: function() {\r
+                               this.element.setStyle( 'display', '' );\r
+                       },\r
+\r
+                       hide: function() {\r
+                               if ( !this.onHide || this.onHide.call( this ) !== true )\r
+                                       this.element.setStyle( 'display', 'none' );\r
+                       },\r
+\r
+                       onKeyDown: function( keystroke, noCycle ) {\r
+                               var keyAction = this.keys[ keystroke ];\r
+                               switch ( keyAction ) {\r
+                                       // Move forward.\r
+                                       case 'next':\r
+                                               var index = this._.focusIndex,\r
+                                                       links = this.element.getElementsByTag( 'a' ),\r
+                                                       link;\r
+\r
+                                               while ( ( link = links.getItem( ++index ) ) ) {\r
+                                                       // Move the focus only if the element is marked with\r
+                                                       // the _cke_focus and it it's visible (check if it has\r
+                                                       // width).\r
+                                                       if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) {\r
+                                                               this._.focusIndex = index;\r
+                                                               link.focus();\r
+                                                               break;\r
+                                                       }\r
+                                               }\r
+\r
+                                               // If no link was found, cycle and restart from the top. (#11125)\r
+                                               if ( !link && !noCycle ) {\r
+                                                       this._.focusIndex = -1;\r
+                                                       return this.onKeyDown( keystroke, 1 );\r
+                                               }\r
+\r
+                                               return false;\r
+\r
+                                               // Move backward.\r
+                                       case 'prev':\r
+                                               index = this._.focusIndex;\r
+                                               links = this.element.getElementsByTag( 'a' );\r
+\r
+                                               while ( index > 0 && ( link = links.getItem( --index ) ) ) {\r
+                                                       // Move the focus only if the element is marked with\r
+                                                       // the _cke_focus and it it's visible (check if it has\r
+                                                       // width).\r
+                                                       if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth ) {\r
+                                                               this._.focusIndex = index;\r
+                                                               link.focus();\r
+                                                               break;\r
+                                                       }\r
+\r
+                                                       // Make sure link is null when the loop ends and nothing was\r
+                                                       // found (#11125).\r
+                                                       link = null;\r
+                                               }\r
+\r
+                                               // If no link was found, cycle and restart from the bottom. (#11125)\r
+                                               if ( !link && !noCycle ) {\r
+                                                       this._.focusIndex = links.count();\r
+                                                       return this.onKeyDown( keystroke, 1 );\r
+                                               }\r
+\r
+                                               return false;\r
+\r
+                                       case 'click':\r
+                                       case 'mouseup':\r
+                                               index = this._.focusIndex;\r
+                                               link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index );\r
+\r
+                                               if ( link )\r
+                                                       link.$[ keyAction ] ? link.$[ keyAction ]() : link.$[ 'on' + keyAction ]();\r
+\r
+                                               return false;\r
+                               }\r
+\r
+                               return true;\r
+                       }\r
+               }\r
+       } );\r
+\r
+} )();\r
+\r
+/**\r
+ * Fired when a panel is added to the document.\r
+ *\r
+ * @event ariaWidget\r
+ * @member CKEDITOR\r
+ * @param {Object} data The element wrapping the panel.\r
+ */\r
diff --git a/sources/plugins/popup/plugin.js b/sources/plugins/popup/plugin.js
new file mode 100644 (file)
index 0000000..352d239
--- /dev/null
@@ -0,0 +1,65 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'popup' );\r
+\r
+CKEDITOR.tools.extend( CKEDITOR.editor.prototype, {\r
+       /**\r
+        * Opens Browser in a popup. The `width` and `height` parameters accept\r
+        * numbers (pixels) or percent (of screen size) values.\r
+        *\r
+        * @member CKEDITOR.editor\r
+        * @param {String} url The url of the external file browser.\r
+        * @param {Number/String} [width='80%'] Popup window width.\r
+        * @param {Number/String} [height='70%'] Popup window height.\r
+        * @param {String} [options='location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes']\r
+        * Popup window features.\r
+        */\r
+       popup: function( url, width, height, options ) {\r
+               width = width || '80%';\r
+               height = height || '70%';\r
+\r
+               if ( typeof width == 'string' && width.length > 1 && width.substr( width.length - 1, 1 ) == '%' )\r
+                       width = parseInt( window.screen.width * parseInt( width, 10 ) / 100, 10 );\r
+\r
+               if ( typeof height == 'string' && height.length > 1 && height.substr( height.length - 1, 1 ) == '%' )\r
+                       height = parseInt( window.screen.height * parseInt( height, 10 ) / 100, 10 );\r
+\r
+               if ( width < 640 )\r
+                       width = 640;\r
+\r
+               if ( height < 420 )\r
+                       height = 420;\r
+\r
+               var top = parseInt( ( window.screen.height - height ) / 2, 10 ),\r
+                       left = parseInt( ( window.screen.width - width ) / 2, 10 );\r
+\r
+               options = ( options || 'location=no,menubar=no,toolbar=no,dependent=yes,minimizable=no,modal=yes,alwaysRaised=yes,resizable=yes,scrollbars=yes' ) + ',width=' + width +\r
+                       ',height=' + height +\r
+                       ',top=' + top +\r
+                       ',left=' + left;\r
+\r
+               var popupWindow = window.open( '', null, options, true );\r
+\r
+               // Blocked by a popup blocker.\r
+               if ( !popupWindow )\r
+                       return false;\r
+\r
+               try {\r
+                       // Chrome is problematic with moveTo/resizeTo, but it's not really needed here (#8855).\r
+                       var ua = navigator.userAgent.toLowerCase();\r
+                       if ( ua.indexOf( ' chrome/' ) == -1 ) {\r
+                               popupWindow.moveTo( left, top );\r
+                               popupWindow.resizeTo( width, height );\r
+                       }\r
+                       popupWindow.focus();\r
+                       popupWindow.location.href = url;\r
+               } catch ( e ) {\r
+                       popupWindow = window.open( url, null, options, true );\r
+               }\r
+\r
+               return true;\r
+       }\r
+} );\r
diff --git a/sources/plugins/removeformat/icons/hidpi/removeformat.png b/sources/plugins/removeformat/icons/hidpi/removeformat.png
new file mode 100644 (file)
index 0000000..0695878
Binary files /dev/null and b/sources/plugins/removeformat/icons/hidpi/removeformat.png differ
diff --git a/sources/plugins/removeformat/icons/removeformat.png b/sources/plugins/removeformat/icons/removeformat.png
new file mode 100644 (file)
index 0000000..f4597bf
Binary files /dev/null and b/sources/plugins/removeformat/icons/removeformat.png differ
diff --git a/sources/plugins/removeformat/lang/af.js b/sources/plugins/removeformat/lang/af.js
new file mode 100644 (file)
index 0000000..4904945
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'af', {\r
+       toolbar: 'Verwyder opmaak'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ar.js b/sources/plugins/removeformat/lang/ar.js
new file mode 100644 (file)
index 0000000..661e851
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ar', {\r
+       toolbar: 'إزالة التنسيقات'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/az.js b/sources/plugins/removeformat/lang/az.js
new file mode 100644 (file)
index 0000000..948837e
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'az', {\r
+       toolbar: 'Formatı sil'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/bg.js b/sources/plugins/removeformat/lang/bg.js
new file mode 100644 (file)
index 0000000..a96dc60
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'bg', {\r
+       toolbar: 'Премахване на форматирането'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/bn.js b/sources/plugins/removeformat/lang/bn.js
new file mode 100644 (file)
index 0000000..0c59c81
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'bn', {\r
+       toolbar: 'ধরন-প্রকৃতি অপসারণ করি'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/bs.js b/sources/plugins/removeformat/lang/bs.js
new file mode 100644 (file)
index 0000000..83fd723
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'bs', {\r
+       toolbar: 'Poništi format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ca.js b/sources/plugins/removeformat/lang/ca.js
new file mode 100644 (file)
index 0000000..01ead3b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ca', {\r
+       toolbar: 'Elimina Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/cs.js b/sources/plugins/removeformat/lang/cs.js
new file mode 100644 (file)
index 0000000..cab8cfc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'cs', {\r
+       toolbar: 'Odstranit formátování'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/cy.js b/sources/plugins/removeformat/lang/cy.js
new file mode 100644 (file)
index 0000000..7908104
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'cy', {\r
+       toolbar: 'Tynnu Fformat'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/da.js b/sources/plugins/removeformat/lang/da.js
new file mode 100644 (file)
index 0000000..6f35909
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'da', {\r
+       toolbar: 'Fjern formatering'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/de-ch.js b/sources/plugins/removeformat/lang/de-ch.js
new file mode 100644 (file)
index 0000000..37d1ccd
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'de-ch', {\r
+       toolbar: 'Formatierung entfernen'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/de.js b/sources/plugins/removeformat/lang/de.js
new file mode 100644 (file)
index 0000000..5d8901b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'de', {\r
+       toolbar: 'Formatierung entfernen'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/el.js b/sources/plugins/removeformat/lang/el.js
new file mode 100644 (file)
index 0000000..e0da8c6
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'el', {\r
+       toolbar: 'Εκκαθάριση Μορφοποίησης'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/en-au.js b/sources/plugins/removeformat/lang/en-au.js
new file mode 100644 (file)
index 0000000..4d98f6d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'en-au', {\r
+       toolbar: 'Remove Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/en-ca.js b/sources/plugins/removeformat/lang/en-ca.js
new file mode 100644 (file)
index 0000000..998eb01
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'en-ca', {\r
+       toolbar: 'Remove Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/en-gb.js b/sources/plugins/removeformat/lang/en-gb.js
new file mode 100644 (file)
index 0000000..f40ca18
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'en-gb', {\r
+       toolbar: 'Remove Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/en.js b/sources/plugins/removeformat/lang/en.js
new file mode 100644 (file)
index 0000000..ed26343
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'en', {\r
+       toolbar: 'Remove Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/eo.js b/sources/plugins/removeformat/lang/eo.js
new file mode 100644 (file)
index 0000000..bb25f96
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'eo', {\r
+       toolbar: 'Forigi Formaton'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/es.js b/sources/plugins/removeformat/lang/es.js
new file mode 100644 (file)
index 0000000..d097bdb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'es', {\r
+       toolbar: 'Eliminar Formato'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/et.js b/sources/plugins/removeformat/lang/et.js
new file mode 100644 (file)
index 0000000..823749d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'et', {\r
+       toolbar: 'Vormingu eemaldamine'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/eu.js b/sources/plugins/removeformat/lang/eu.js
new file mode 100644 (file)
index 0000000..bc487f7
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'eu', {\r
+       toolbar: 'Kendu formatua'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/fa.js b/sources/plugins/removeformat/lang/fa.js
new file mode 100644 (file)
index 0000000..8fc6b93
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'fa', {\r
+       toolbar: 'برداشتن فرمت'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/fi.js b/sources/plugins/removeformat/lang/fi.js
new file mode 100644 (file)
index 0000000..c61a093
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'fi', {\r
+       toolbar: 'Poista muotoilu'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/fo.js b/sources/plugins/removeformat/lang/fo.js
new file mode 100644 (file)
index 0000000..b80c158
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'fo', {\r
+       toolbar: 'Strika sniðgeving'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/fr-ca.js b/sources/plugins/removeformat/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..fe3534d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'fr-ca', {\r
+       toolbar: 'Supprimer le formatage'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/fr.js b/sources/plugins/removeformat/lang/fr.js
new file mode 100644 (file)
index 0000000..e18fd83
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'fr', {\r
+       toolbar: 'Supprimer la mise en forme'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/gl.js b/sources/plugins/removeformat/lang/gl.js
new file mode 100644 (file)
index 0000000..8190cca
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'gl', {\r
+       toolbar: 'Retirar o formato'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/gu.js b/sources/plugins/removeformat/lang/gu.js
new file mode 100644 (file)
index 0000000..621ad9d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'gu', {\r
+       toolbar: 'ફૉર્મટ કાઢવું'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/he.js b/sources/plugins/removeformat/lang/he.js
new file mode 100644 (file)
index 0000000..bcdc1bd
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'he', {\r
+       toolbar: 'הסרת העיצוב'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/hi.js b/sources/plugins/removeformat/lang/hi.js
new file mode 100644 (file)
index 0000000..ab15f5d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'hi', {\r
+       toolbar: 'फ़ॉर्मैट हटायें'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/hr.js b/sources/plugins/removeformat/lang/hr.js
new file mode 100644 (file)
index 0000000..c061400
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'hr', {\r
+       toolbar: 'Ukloni formatiranje'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/hu.js b/sources/plugins/removeformat/lang/hu.js
new file mode 100644 (file)
index 0000000..fe1c099
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'hu', {\r
+       toolbar: 'Formázás eltávolítása'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/id.js b/sources/plugins/removeformat/lang/id.js
new file mode 100644 (file)
index 0000000..e7eded0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'id', {\r
+       toolbar: 'Hapus Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/is.js b/sources/plugins/removeformat/lang/is.js
new file mode 100644 (file)
index 0000000..98b9b4d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'is', {\r
+       toolbar: 'Fjarlægja snið'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/it.js b/sources/plugins/removeformat/lang/it.js
new file mode 100644 (file)
index 0000000..0ea8fb9
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'it', {\r
+       toolbar: 'Elimina formattazione'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ja.js b/sources/plugins/removeformat/lang/ja.js
new file mode 100644 (file)
index 0000000..ca0970f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ja', {\r
+       toolbar: '書式を解除'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ka.js b/sources/plugins/removeformat/lang/ka.js
new file mode 100644 (file)
index 0000000..b624c5d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ka', {\r
+       toolbar: 'ფორმატირების მოხსნა'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/km.js b/sources/plugins/removeformat/lang/km.js
new file mode 100644 (file)
index 0000000..cacd321
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'km', {\r
+       toolbar: 'ជម្រះ​ទ្រង់​ទ្រាយ'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ko.js b/sources/plugins/removeformat/lang/ko.js
new file mode 100644 (file)
index 0000000..a594ccc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ko', {\r
+       toolbar: '형식 지우기'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ku.js b/sources/plugins/removeformat/lang/ku.js
new file mode 100644 (file)
index 0000000..51ae15a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ku', {\r
+       toolbar: 'لابردنی داڕشتەکە'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/lt.js b/sources/plugins/removeformat/lang/lt.js
new file mode 100644 (file)
index 0000000..1e7f2df
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'lt', {\r
+       toolbar: 'Panaikinti formatą'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/lv.js b/sources/plugins/removeformat/lang/lv.js
new file mode 100644 (file)
index 0000000..f382171
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'lv', {\r
+       toolbar: 'Noņemt stilus'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/mk.js b/sources/plugins/removeformat/lang/mk.js
new file mode 100644 (file)
index 0000000..be04ba4
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'mk', {\r
+       toolbar: 'Remove Format' // MISSING\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/mn.js b/sources/plugins/removeformat/lang/mn.js
new file mode 100644 (file)
index 0000000..378a898
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'mn', {\r
+       toolbar: 'Параргафын загварыг авч хаях'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ms.js b/sources/plugins/removeformat/lang/ms.js
new file mode 100644 (file)
index 0000000..ee81ba1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ms', {\r
+       toolbar: 'Buang Format'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/nb.js b/sources/plugins/removeformat/lang/nb.js
new file mode 100644 (file)
index 0000000..19f093d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'nb', {\r
+       toolbar: 'Fjern formatering'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/nl.js b/sources/plugins/removeformat/lang/nl.js
new file mode 100644 (file)
index 0000000..46be61b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'nl', {\r
+       toolbar: 'Opmaak verwijderen'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/no.js b/sources/plugins/removeformat/lang/no.js
new file mode 100644 (file)
index 0000000..84d38af
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'no', {\r
+       toolbar: 'Fjern formatering'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/oc.js b/sources/plugins/removeformat/lang/oc.js
new file mode 100644 (file)
index 0000000..7dda966
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'oc', {\r
+       toolbar: 'Suprimir la mesa en forma'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/pl.js b/sources/plugins/removeformat/lang/pl.js
new file mode 100644 (file)
index 0000000..41e7034
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'pl', {\r
+       toolbar: 'Usuń formatowanie'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/pt-br.js b/sources/plugins/removeformat/lang/pt-br.js
new file mode 100644 (file)
index 0000000..61b44c0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'pt-br', {\r
+       toolbar: 'Remover Formatação'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/pt.js b/sources/plugins/removeformat/lang/pt.js
new file mode 100644 (file)
index 0000000..b54dbce
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'pt', {\r
+       toolbar: 'Limpar formatação'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ro.js b/sources/plugins/removeformat/lang/ro.js
new file mode 100644 (file)
index 0000000..649bced
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ro', {\r
+       toolbar: 'Înlătură formatarea'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ru.js b/sources/plugins/removeformat/lang/ru.js
new file mode 100644 (file)
index 0000000..ea05d6e
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ru', {\r
+       toolbar: 'Убрать форматирование'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/si.js b/sources/plugins/removeformat/lang/si.js
new file mode 100644 (file)
index 0000000..db5d715
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'si', {\r
+       toolbar: 'සැකසීම වෙනස් කරන්න'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sk.js b/sources/plugins/removeformat/lang/sk.js
new file mode 100644 (file)
index 0000000..625c8d6
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sk', {\r
+       toolbar: 'Odstrániť formátovanie'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sl.js b/sources/plugins/removeformat/lang/sl.js
new file mode 100644 (file)
index 0000000..895c1e7
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sl', {\r
+       toolbar: 'Odstrani oblikovanje'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sq.js b/sources/plugins/removeformat/lang/sq.js
new file mode 100644 (file)
index 0000000..45f455a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sq', {\r
+       toolbar: 'Largo Formatin'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sr-latn.js b/sources/plugins/removeformat/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..51f34a7
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sr-latn', {\r
+       toolbar: 'Ukloni formatiranje'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sr.js b/sources/plugins/removeformat/lang/sr.js
new file mode 100644 (file)
index 0000000..c6080dd
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sr', {\r
+       toolbar: 'Уклони форматирање'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/sv.js b/sources/plugins/removeformat/lang/sv.js
new file mode 100644 (file)
index 0000000..2dd7edc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'sv', {\r
+       toolbar: 'Radera formatering'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/th.js b/sources/plugins/removeformat/lang/th.js
new file mode 100644 (file)
index 0000000..0bc74e2
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'th', {\r
+       toolbar: 'ล้างรูปแบบ'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/tr.js b/sources/plugins/removeformat/lang/tr.js
new file mode 100644 (file)
index 0000000..2c961c5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'tr', {\r
+       toolbar: 'Biçimi Kaldır'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/tt.js b/sources/plugins/removeformat/lang/tt.js
new file mode 100644 (file)
index 0000000..b3afbda
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'tt', {\r
+       toolbar: 'Форматлауны бетерү'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/ug.js b/sources/plugins/removeformat/lang/ug.js
new file mode 100644 (file)
index 0000000..07e5daf
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'ug', {\r
+       toolbar: 'پىچىمنى چىقىرىۋەت'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/uk.js b/sources/plugins/removeformat/lang/uk.js
new file mode 100644 (file)
index 0000000..7ef1f1c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'uk', {\r
+       toolbar: 'Видалити форматування'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/vi.js b/sources/plugins/removeformat/lang/vi.js
new file mode 100644 (file)
index 0000000..38316bf
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'vi', {\r
+       toolbar: 'Xoá định dạng'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/zh-cn.js b/sources/plugins/removeformat/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..ec833f1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'zh-cn', {\r
+       toolbar: '清除格式'\r
+} );\r
diff --git a/sources/plugins/removeformat/lang/zh.js b/sources/plugins/removeformat/lang/zh.js
new file mode 100644 (file)
index 0000000..dd23488
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'removeformat', 'zh', {\r
+       toolbar: '移除格式'\r
+} );\r
diff --git a/sources/plugins/removeformat/plugin.js b/sources/plugins/removeformat/plugin.js
new file mode 100644 (file)
index 0000000..20f7ecb
--- /dev/null
@@ -0,0 +1,193 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'removeformat', {\r
+       // jscs:disable maximumLineLength\r
+       lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+       // jscs:enable maximumLineLength\r
+       icons: 'removeformat', // %REMOVE_LINE_CORE%\r
+       hidpi: true, // %REMOVE_LINE_CORE%\r
+       init: function( editor ) {\r
+               editor.addCommand( 'removeFormat', CKEDITOR.plugins.removeformat.commands.removeformat );\r
+               editor.ui.addButton && editor.ui.addButton( 'RemoveFormat', {\r
+                       label: editor.lang.removeformat.toolbar,\r
+                       command: 'removeFormat',\r
+                       toolbar: 'cleanup,10'\r
+               } );\r
+       }\r
+} );\r
+\r
+CKEDITOR.plugins.removeformat = {\r
+       commands: {\r
+               removeformat: {\r
+                       exec: function( editor ) {\r
+                               var tagsRegex = editor._.removeFormatRegex || ( editor._.removeFormatRegex = new RegExp( '^(?:' + editor.config.removeFormatTags.replace( /,/g, '|' ) + ')$', 'i' ) );\r
+\r
+                               var removeAttributes = editor._.removeAttributes || ( editor._.removeAttributes = editor.config.removeFormatAttributes.split( ',' ) ),\r
+                                       filter = CKEDITOR.plugins.removeformat.filter,\r
+                                       ranges = editor.getSelection().getRanges(),\r
+                                       iterator = ranges.createIterator(),\r
+                                       isElement = function( element ) {\r
+                                               return element.type == CKEDITOR.NODE_ELEMENT;\r
+                                       },\r
+                                       range;\r
+\r
+                               while ( ( range = iterator.getNextRange() ) ) {\r
+                                       if ( !range.collapsed )\r
+                                               range.enlarge( CKEDITOR.ENLARGE_ELEMENT );\r
+\r
+                                       // Bookmark the range so we can re-select it after processing.\r
+                                       var bookmark = range.createBookmark(),\r
+                                               // The style will be applied within the bookmark boundaries.\r
+                                               startNode = bookmark.startNode,\r
+                                               endNode = bookmark.endNode,\r
+                                               currentNode;\r
+\r
+                                       // We need to check the selection boundaries (bookmark spans) to break\r
+                                       // the code in a way that we can properly remove partially selected nodes.\r
+                                       // For example, removing a <b> style from\r
+                                       //              <b>This is [some text</b> to show <b>the] problem</b>\r
+                                       // ... where [ and ] represent the selection, must result:\r
+                                       //              <b>This is </b>[some text to show the]<b> problem</b>\r
+                                       // The strategy is simple, we just break the partial nodes before the\r
+                                       // removal logic, having something that could be represented this way:\r
+                                       //              <b>This is </b>[<b>some text</b> to show <b>the</b>]<b> problem</b>\r
+\r
+                                       var breakParent = function( node ) {\r
+                                                       // Let's start checking the start boundary.\r
+                                                       var path = editor.elementPath( node ),\r
+                                                               pathElements = path.elements;\r
+\r
+                                                       for ( var i = 1, pathElement; pathElement = pathElements[ i ]; i++ ) {\r
+                                                               if ( pathElement.equals( path.block ) || pathElement.equals( path.blockLimit ) )\r
+                                                                       break;\r
+\r
+                                                               // If this element can be removed (even partially).\r
+                                                               if ( tagsRegex.test( pathElement.getName() ) && filter( editor, pathElement ) )\r
+                                                                       node.breakParent( pathElement );\r
+                                                       }\r
+                                               };\r
+\r
+                                       breakParent( startNode );\r
+                                       if ( endNode ) {\r
+                                               breakParent( endNode );\r
+\r
+                                               // Navigate through all nodes between the bookmarks.\r
+                                               currentNode = startNode.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT );\r
+\r
+                                               while ( currentNode ) {\r
+                                                       // If we have reached the end of the selection, stop looping.\r
+                                                       if ( currentNode.equals( endNode ) )\r
+                                                               break;\r
+\r
+                                                       if ( currentNode.isReadOnly() ) {\r
+                                                               // In case of non-editable we're skipping to the next sibling *elmenet*.\r
+\r
+                                                               // We need to be aware that endNode can be nested within current non-editable.\r
+                                                               // This condition tests if currentNode (non-editable) contains endNode. If it does\r
+                                                               // then we should break the filtering\r
+                                                               if ( currentNode.getPosition( endNode ) & CKEDITOR.POSITION_CONTAINS ) {\r
+                                                                       break;\r
+                                                               }\r
+\r
+                                                               currentNode = currentNode.getNext( isElement );\r
+                                                               continue;\r
+                                                       }\r
+\r
+                                                       // Cache the next node to be processed. Do it now, because\r
+                                                       // currentNode may be removed.\r
+                                                       var nextNode = currentNode.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ),\r
+                                                               isFakeElement = currentNode.getName() == 'img' && currentNode.data( 'cke-realelement' );\r
+\r
+                                                       // This node must not be a fake element, and must not be read-only.\r
+                                                       if ( !isFakeElement && filter( editor, currentNode ) ) {\r
+                                                               // Remove elements nodes that match with this style rules.\r
+                                                               if ( tagsRegex.test( currentNode.getName() ) )\r
+                                                                       currentNode.remove( 1 );\r
+                                                               else {\r
+                                                                       currentNode.removeAttributes( removeAttributes );\r
+                                                                       editor.fire( 'removeFormatCleanup', currentNode );\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       currentNode = nextNode;\r
+                                               }\r
+                                       }\r
+\r
+                                       range.moveToBookmark( bookmark );\r
+                               }\r
+\r
+                               // The selection path may not changed, but we should force a selection\r
+                               // change event to refresh command states, due to the above attribution change. (#9238)\r
+                               editor.forceNextSelectionCheck();\r
+                               editor.getSelection().selectRanges( ranges );\r
+                       }\r
+               }\r
+       },\r
+\r
+       // Perform the remove format filters on the passed element.\r
+       // @param {CKEDITOR.editor} editor\r
+       // @param {CKEDITOR.dom.element} element\r
+       filter: function( editor, element ) {\r
+               // If editor#addRemoveFotmatFilter hasn't been executed yet value is not initialized.\r
+               var filters = editor._.removeFormatFilters || [];\r
+               for ( var i = 0; i < filters.length; i++ ) {\r
+                       if ( filters[ i ]( element ) === false )\r
+                               return false;\r
+               }\r
+               return true;\r
+       }\r
+};\r
+\r
+/**\r
+ * Add to a collection of functions to decide whether a specific\r
+ * element should be considered as formatting element and thus\r
+ * could be removed during `removeFormat` command.\r
+ *\r
+ * **Note:** Only available with the existence of `removeformat` plugin.\r
+ *\r
+ *             // Don't remove empty span.\r
+ *             editor.addRemoveFormatFilter( function( element ) {\r
+ *                     return !( element.is( 'span' ) && CKEDITOR.tools.isEmpty( element.getAttributes() ) );\r
+ *             } );\r
+ *\r
+ * @since 3.3\r
+ * @member CKEDITOR.editor\r
+ * @param {Function} func The function to be called, which will be passed a {CKEDITOR.dom.element} element to test.\r
+ */\r
+CKEDITOR.editor.prototype.addRemoveFormatFilter = function( func ) {\r
+       if ( !this._.removeFormatFilters )\r
+               this._.removeFormatFilters = [];\r
+\r
+       this._.removeFormatFilters.push( func );\r
+};\r
+\r
+/**\r
+ * A comma separated list of elements to be removed when executing the `remove\r
+ * format` command. Note that only inline elements are allowed.\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.removeFormatTags = 'b,big,cite,code,del,dfn,em,font,i,ins,kbd,q,s,samp,small,span,strike,strong,sub,sup,tt,u,var';\r
+\r
+/**\r
+ * A comma separated list of elements attributes to be removed when executing\r
+ * the `remove format` command.\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.removeFormatAttributes = 'class,style,lang,width,height,align,hspace,valign';\r
+\r
+/**\r
+ * Fired after an element was cleaned by the removeFormat plugin.\r
+ *\r
+ * @event removeFormatCleanup\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param data\r
+ * @param {CKEDITOR.dom.element} data.element The element that was cleaned up.\r
+ */\r
diff --git a/sources/plugins/resize/plugin.js b/sources/plugins/resize/plugin.js
new file mode 100644 (file)
index 0000000..095ee12
--- /dev/null
@@ -0,0 +1,187 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'resize', {\r
+       init: function( editor ) {\r
+               function dragHandler( evt ) {\r
+                       var dx = evt.data.$.screenX - origin.x,\r
+                       dy = evt.data.$.screenY - origin.y,\r
+                       width = startSize.width,\r
+                       height = startSize.height,\r
+                       internalWidth = width + dx * ( resizeDir == 'rtl' ? -1 : 1 ),\r
+                       internalHeight = height + dy;\r
+\r
+                       if ( resizeHorizontal )\r
+                               width = Math.max( config.resize_minWidth, Math.min( internalWidth, config.resize_maxWidth ) );\r
+\r
+                       if ( resizeVertical )\r
+                               height = Math.max( config.resize_minHeight, Math.min( internalHeight, config.resize_maxHeight ) );\r
+\r
+                       // DO NOT impose fixed size with single direction resize. (#6308)\r
+                       editor.resize( resizeHorizontal ? width : null, height );\r
+               }\r
+\r
+               function dragEndHandler() {\r
+                       CKEDITOR.document.removeListener( 'mousemove', dragHandler );\r
+                       CKEDITOR.document.removeListener( 'mouseup', dragEndHandler );\r
+\r
+                       if ( editor.document ) {\r
+                               editor.document.removeListener( 'mousemove', dragHandler );\r
+                               editor.document.removeListener( 'mouseup', dragEndHandler );\r
+                       }\r
+               }\r
+\r
+               var config = editor.config;\r
+               var spaceId = editor.ui.spaceId( 'resizer' );\r
+\r
+               // Resize in the same direction of chrome,\r
+               // which is identical to dir of editor element. (#6614)\r
+               var resizeDir = editor.element ? editor.element.getDirection( 1 ) : 'ltr';\r
+\r
+               !config.resize_dir && ( config.resize_dir = 'vertical' );\r
+               ( config.resize_maxWidth === undefined ) && ( config.resize_maxWidth = 3000 );\r
+               ( config.resize_maxHeight === undefined ) && ( config.resize_maxHeight = 3000 );\r
+               ( config.resize_minWidth === undefined ) && ( config.resize_minWidth = 750 );\r
+               ( config.resize_minHeight === undefined ) && ( config.resize_minHeight = 250 );\r
+\r
+               if ( config.resize_enabled !== false ) {\r
+                       var container = null,\r
+                               origin, startSize,\r
+                               resizeHorizontal = ( config.resize_dir == 'both' || config.resize_dir == 'horizontal' ) && ( config.resize_minWidth != config.resize_maxWidth ),\r
+                               resizeVertical = ( config.resize_dir == 'both' || config.resize_dir == 'vertical' ) && ( config.resize_minHeight != config.resize_maxHeight );\r
+\r
+                       var mouseDownFn = CKEDITOR.tools.addFunction( function( $event ) {\r
+                               if ( !container )\r
+                                       container = editor.getResizable();\r
+\r
+                               startSize = { width: container.$.offsetWidth || 0, height: container.$.offsetHeight || 0 };\r
+                               origin = { x: $event.screenX, y: $event.screenY };\r
+\r
+                               config.resize_minWidth > startSize.width && ( config.resize_minWidth = startSize.width );\r
+                               config.resize_minHeight > startSize.height && ( config.resize_minHeight = startSize.height );\r
+\r
+                               CKEDITOR.document.on( 'mousemove', dragHandler );\r
+                               CKEDITOR.document.on( 'mouseup', dragEndHandler );\r
+\r
+                               if ( editor.document ) {\r
+                                       editor.document.on( 'mousemove', dragHandler );\r
+                                       editor.document.on( 'mouseup', dragEndHandler );\r
+                               }\r
+\r
+                               $event.preventDefault && $event.preventDefault();\r
+                       } );\r
+\r
+                       editor.on( 'destroy', function() {\r
+                               CKEDITOR.tools.removeFunction( mouseDownFn );\r
+                       } );\r
+\r
+                       editor.on( 'uiSpace', function( event ) {\r
+                               if ( event.data.space == 'bottom' ) {\r
+                                       var direction = '';\r
+                                       if ( resizeHorizontal && !resizeVertical )\r
+                                               direction = ' cke_resizer_horizontal';\r
+                                       if ( !resizeHorizontal && resizeVertical )\r
+                                               direction = ' cke_resizer_vertical';\r
+\r
+                                       var resizerHtml =\r
+                                               '<span' +\r
+                                               ' id="' + spaceId + '"' +\r
+                                               ' class="cke_resizer' + direction + ' cke_resizer_' + resizeDir + '"' +\r
+                                               ' title="' + CKEDITOR.tools.htmlEncode( editor.lang.common.resize ) + '"' +\r
+                                               ' onmousedown="CKEDITOR.tools.callFunction(' + mouseDownFn + ', event)"' +\r
+                                               '>' +\r
+                                               // BLACK LOWER RIGHT TRIANGLE (ltr)\r
+                                               // BLACK LOWER LEFT TRIANGLE (rtl)\r
+                                               ( resizeDir == 'ltr' ? '\u25E2' : '\u25E3' ) +\r
+                                               '</span>';\r
+\r
+                                       // Always sticks the corner of botttom space.\r
+                                       resizeDir == 'ltr' && direction == 'ltr' ? event.data.html += resizerHtml : event.data.html = resizerHtml + event.data.html;\r
+                               }\r
+                       }, editor, null, 100 );\r
+\r
+                       // Toggle the visibility of the resizer when an editor is being maximized or minimized.\r
+                       editor.on( 'maximize', function( event ) {\r
+                               editor.ui.space( 'resizer' )[ event.data == CKEDITOR.TRISTATE_ON ? 'hide' : 'show' ]();\r
+                       } );\r
+               }\r
+       }\r
+} );\r
+\r
+/**\r
+ * The minimum editor width, in pixels, when resizing the editor interface by using the resize handle.\r
+ * Note: It falls back to editor's actual width if it is smaller than the default value.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_minWidth = 500;\r
+ *\r
+ * @cfg {Number} [resize_minWidth=750]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The minimum editor height, in pixels, when resizing the editor interface by using the resize handle.\r
+ * Note: It falls back to editor's actual height if it is smaller than the default value.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_minHeight = 600;\r
+ *\r
+ * @cfg {Number} [resize_minHeight=250]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The maximum editor width, in pixels, when resizing the editor interface by using the resize handle.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_maxWidth = 750;\r
+ *\r
+ * @cfg {Number} [resize_maxWidth=3000]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The maximum editor height, in pixels, when resizing the editor interface by using the resize handle.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_maxHeight = 600;\r
+ *\r
+ * @cfg {Number} [resize_maxHeight=3000]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Whether to enable the resizing feature. If this feature is disabled, the resize handle will not be visible.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_enabled = false;\r
+ *\r
+ * @cfg {Boolean} [resize_enabled=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The dimensions for which the editor resizing is enabled. Possible values\r
+ * are `both`, `vertical`, and `horizontal`.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_resize)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/resize.html).\r
+ *\r
+ *             config.resize_dir = 'both';\r
+ *\r
+ * @since 3.3\r
+ * @cfg {String} [resize_dir='vertical']\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/richcombo/plugin.js b/sources/plugins/richcombo/plugin.js
new file mode 100644 (file)
index 0000000..231a7c7
--- /dev/null
@@ -0,0 +1,434 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+CKEDITOR.plugins.add( 'richcombo', {\r
+       requires: 'floatpanel,listblock,button',\r
+\r
+       beforeInit: function( editor ) {\r
+               editor.ui.addHandler( CKEDITOR.UI_RICHCOMBO, CKEDITOR.ui.richCombo.handler );\r
+       }\r
+} );\r
+\r
+( function() {\r
+       var template = '<span id="{id}"' +\r
+               ' class="cke_combo cke_combo__{name} {cls}"' +\r
+               ' role="presentation">' +\r
+                       '<span id="{id}_label" class="cke_combo_label">{label}</span>' +\r
+                       '<a class="cke_combo_button" title="{title}" tabindex="-1"' +\r
+                       ( CKEDITOR.env.gecko && !CKEDITOR.env.hc ? '' : ' href="javascript:void(\'{titleJs}\')"' ) +\r
+                       ' hidefocus="true"' +\r
+                       ' role="button"' +\r
+                       ' aria-labelledby="{id}_label"' +\r
+                       ' aria-haspopup="true"';\r
+\r
+       // Some browsers don't cancel key events in the keydown but in the\r
+       // keypress.\r
+       // TODO: Check if really needed.\r
+       if ( CKEDITOR.env.gecko && CKEDITOR.env.mac )\r
+               template += ' onkeypress="return false;"';\r
+\r
+       // With Firefox, we need to force the button to redraw, otherwise it\r
+       // will remain in the focus state.\r
+       if ( CKEDITOR.env.gecko )\r
+               template += ' onblur="this.style.cssText = this.style.cssText;"';\r
+\r
+       template +=\r
+               ' onkeydown="return CKEDITOR.tools.callFunction({keydownFn},event,this);"' +\r
+               ' onfocus="return CKEDITOR.tools.callFunction({focusFn},event);" ' +\r
+                       ( CKEDITOR.env.ie ? 'onclick="return false;" onmouseup' : 'onclick' ) + // #188\r
+                               '="CKEDITOR.tools.callFunction({clickFn},this);return false;">' +\r
+                       '<span id="{id}_text" class="cke_combo_text cke_combo_inlinelabel">{label}</span>' +\r
+                       '<span class="cke_combo_open">' +\r
+                               '<span class="cke_combo_arrow">' +\r
+                               // BLACK DOWN-POINTING TRIANGLE\r
+       ( CKEDITOR.env.hc ? '&#9660;' : CKEDITOR.env.air ? '&nbsp;' : '' ) +\r
+                               '</span>' +\r
+                       '</span>' +\r
+               '</a>' +\r
+               '</span>';\r
+\r
+       var rcomboTpl = CKEDITOR.addTemplate( 'combo', template );\r
+\r
+       /**\r
+        * Button UI element.\r
+        *\r
+        * @readonly\r
+        * @property {String} [='richcombo']\r
+        * @member CKEDITOR\r
+        */\r
+       CKEDITOR.UI_RICHCOMBO = 'richcombo';\r
+\r
+       /**\r
+        * @class\r
+        * @todo\r
+        */\r
+       CKEDITOR.ui.richCombo = CKEDITOR.tools.createClass( {\r
+               $: function( definition ) {\r
+                       // Copy all definition properties to this object.\r
+                       CKEDITOR.tools.extend( this, definition,\r
+                       // Set defaults.\r
+                       {\r
+                               // The combo won't participate in toolbar grouping.\r
+                               canGroup: false,\r
+                               title: definition.label,\r
+                               modes: { wysiwyg: 1 },\r
+                               editorFocus: 1\r
+                       } );\r
+\r
+                       // We don't want the panel definition in this object.\r
+                       var panelDefinition = this.panel || {};\r
+                       delete this.panel;\r
+\r
+                       this.id = CKEDITOR.tools.getNextNumber();\r
+\r
+                       this.document = ( panelDefinition.parent && panelDefinition.parent.getDocument() ) || CKEDITOR.document;\r
+\r
+                       panelDefinition.className = 'cke_combopanel';\r
+                       panelDefinition.block = {\r
+                               multiSelect: panelDefinition.multiSelect,\r
+                               attributes: panelDefinition.attributes\r
+                       };\r
+                       panelDefinition.toolbarRelated = true;\r
+\r
+                       this._ = {\r
+                               panelDefinition: panelDefinition,\r
+                               items: {}\r
+                       };\r
+               },\r
+\r
+               proto: {\r
+                       renderHtml: function( editor ) {\r
+                               var output = [];\r
+                               this.render( editor, output );\r
+                               return output.join( '' );\r
+                       },\r
+\r
+                       /**\r
+                        * Renders the combo.\r
+                        *\r
+                        * @param {CKEDITOR.editor} editor The editor instance which this button is\r
+                        * to be used by.\r
+                        * @param {Array} output The output array to which append the HTML relative\r
+                        * to this button.\r
+                        */\r
+                       render: function( editor, output ) {\r
+                               var env = CKEDITOR.env;\r
+\r
+                               var id = 'cke_' + this.id;\r
+                               var clickFn = CKEDITOR.tools.addFunction( function( el ) {\r
+                                       // Restore locked selection in Opera.\r
+                                       if ( selLocked ) {\r
+                                               editor.unlockSelection( 1 );\r
+                                               selLocked = 0;\r
+                                       }\r
+                                       instance.execute( el );\r
+                               }, this );\r
+\r
+                               var combo = this;\r
+                               var instance = {\r
+                                       id: id,\r
+                                       combo: this,\r
+                                       focus: function() {\r
+                                               var element = CKEDITOR.document.getById( id ).getChild( 1 );\r
+                                               element.focus();\r
+                                       },\r
+                                       execute: function( el ) {\r
+                                               var _ = combo._;\r
+\r
+                                               if ( _.state == CKEDITOR.TRISTATE_DISABLED )\r
+                                                       return;\r
+\r
+                                               combo.createPanel( editor );\r
+\r
+                                               if ( _.on ) {\r
+                                                       _.panel.hide();\r
+                                                       return;\r
+                                               }\r
+\r
+                                               combo.commit();\r
+                                               var value = combo.getValue();\r
+                                               if ( value )\r
+                                                       _.list.mark( value );\r
+                                               else\r
+                                                       _.list.unmarkAll();\r
+\r
+                                               _.panel.showBlock( combo.id, new CKEDITOR.dom.element( el ), 4 );\r
+                                       },\r
+                                       clickFn: clickFn\r
+                               };\r
+\r
+                               function updateState() {\r
+                                       // Don't change state while richcombo is active (#11793).\r
+                                       if ( this.getState() == CKEDITOR.TRISTATE_ON )\r
+                                               return;\r
+\r
+                                       var state = this.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED;\r
+\r
+                                       if ( editor.readOnly && !this.readOnly )\r
+                                               state = CKEDITOR.TRISTATE_DISABLED;\r
+\r
+                                       this.setState( state );\r
+                                       this.setValue( '' );\r
+\r
+                                       // Let plugin to disable button.\r
+                                       if ( state != CKEDITOR.TRISTATE_DISABLED && this.refresh )\r
+                                               this.refresh();\r
+                               }\r
+\r
+                               // Update status when activeFilter, mode, selection or readOnly changes.\r
+                               editor.on( 'activeFilterChange', updateState, this );\r
+                               editor.on( 'mode', updateState, this );\r
+                               editor.on( 'selectionChange', updateState, this );\r
+                               // If this combo is sensitive to readOnly state, update it accordingly.\r
+                               !this.readOnly && editor.on( 'readOnly', updateState, this );\r
+\r
+                               var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ) {\r
+                                       ev = new CKEDITOR.dom.event( ev );\r
+\r
+                                       var keystroke = ev.getKeystroke();\r
+\r
+                                       // ARROW-DOWN\r
+                                       // This call is duplicated in plugins/toolbar/plugin.js in itemKeystroke().\r
+                                       // Move focus to the first element after drop down was opened by the arrow down key.\r
+                                       if ( keystroke == 40 ) {\r
+                                               editor.once( 'panelShow', function( evt ) {\r
+                                                       evt.data._.panel._.currentBlock.onKeyDown( 40 );\r
+                                               } );\r
+                                       }\r
+\r
+                                       switch ( keystroke ) {\r
+                                               case 13: // ENTER\r
+                                               case 32: // SPACE\r
+                                               case 40: // ARROW-DOWN\r
+                                                       // Show panel\r
+                                                       CKEDITOR.tools.callFunction( clickFn, element );\r
+                                                       break;\r
+                                               default:\r
+                                                       // Delegate the default behavior to toolbar button key handling.\r
+                                                       instance.onkey( instance, keystroke );\r
+                                       }\r
+\r
+                                       // Avoid subsequent focus grab on editor document.\r
+                                       ev.preventDefault();\r
+                               } );\r
+\r
+                               var focusFn = CKEDITOR.tools.addFunction( function() {\r
+                                       instance.onfocus && instance.onfocus();\r
+                               } );\r
+\r
+                               var selLocked = 0;\r
+\r
+                               // For clean up\r
+                               instance.keyDownFn = keyDownFn;\r
+\r
+                               var params = {\r
+                                       id: id,\r
+                                       name: this.name || this.command,\r
+                                       label: this.label,\r
+                                       title: this.title,\r
+                                       cls: this.className || '',\r
+                                       titleJs: env.gecko && !env.hc ? '' : ( this.title || '' ).replace( "'", '' ),\r
+                                       keydownFn: keyDownFn,\r
+                                       focusFn: focusFn,\r
+                                       clickFn: clickFn\r
+                               };\r
+\r
+                               rcomboTpl.output( params, output );\r
+\r
+                               if ( this.onRender )\r
+                                       this.onRender();\r
+\r
+                               return instance;\r
+                       },\r
+\r
+                       createPanel: function( editor ) {\r
+                               if ( this._.panel )\r
+                                       return;\r
+\r
+                               var panelDefinition = this._.panelDefinition,\r
+                                       panelBlockDefinition = this._.panelDefinition.block,\r
+                                       panelParentElement = panelDefinition.parent || CKEDITOR.document.getBody(),\r
+                                       namedPanelCls = 'cke_combopanel__' + this.name,\r
+                                       panel = new CKEDITOR.ui.floatPanel( editor, panelParentElement, panelDefinition ),\r
+                                       list = panel.addListBlock( this.id, panelBlockDefinition ),\r
+                                       me = this;\r
+\r
+                               panel.onShow = function() {\r
+                                       this.element.addClass( namedPanelCls );\r
+\r
+                                       me.setState( CKEDITOR.TRISTATE_ON );\r
+\r
+                                       me._.on = 1;\r
+\r
+                                       me.editorFocus && !editor.focusManager.hasFocus && editor.focus();\r
+\r
+                                       if ( me.onOpen )\r
+                                               me.onOpen();\r
+\r
+                                       // The "panelShow" event is fired assinchronously, after the\r
+                                       // onShow method call.\r
+                                       editor.once( 'panelShow', function() {\r
+                                               list.focus( !list.multiSelect && me.getValue() );\r
+                                       } );\r
+                               };\r
+\r
+                               panel.onHide = function( preventOnClose ) {\r
+                                       this.element.removeClass( namedPanelCls );\r
+\r
+                                       me.setState( me.modes && me.modes[ editor.mode ] ? CKEDITOR.TRISTATE_OFF : CKEDITOR.TRISTATE_DISABLED );\r
+\r
+                                       me._.on = 0;\r
+\r
+                                       if ( !preventOnClose && me.onClose )\r
+                                               me.onClose();\r
+                               };\r
+\r
+                               panel.onEscape = function() {\r
+                                       // Hide drop-down with focus returned.\r
+                                       panel.hide( 1 );\r
+                               };\r
+\r
+                               list.onClick = function( value, marked ) {\r
+\r
+                                       if ( me.onClick )\r
+                                               me.onClick.call( me, value, marked );\r
+\r
+                                       panel.hide();\r
+                               };\r
+\r
+                               this._.panel = panel;\r
+                               this._.list = list;\r
+\r
+                               panel.getBlock( this.id ).onHide = function() {\r
+                                       me._.on = 0;\r
+                                       me.setState( CKEDITOR.TRISTATE_OFF );\r
+                               };\r
+\r
+                               if ( this.init )\r
+                                       this.init();\r
+                       },\r
+\r
+                       setValue: function( value, text ) {\r
+                               this._.value = value;\r
+\r
+                               var textElement = this.document.getById( 'cke_' + this.id + '_text' );\r
+                               if ( textElement ) {\r
+                                       if ( !( value || text ) ) {\r
+                                               text = this.label;\r
+                                               textElement.addClass( 'cke_combo_inlinelabel' );\r
+                                       } else {\r
+                                               textElement.removeClass( 'cke_combo_inlinelabel' );\r
+                                       }\r
+\r
+                                       textElement.setText( typeof text != 'undefined' ? text : value );\r
+                               }\r
+                       },\r
+\r
+                       getValue: function() {\r
+                               return this._.value || '';\r
+                       },\r
+\r
+                       unmarkAll: function() {\r
+                               this._.list.unmarkAll();\r
+                       },\r
+\r
+                       mark: function( value ) {\r
+                               this._.list.mark( value );\r
+                       },\r
+\r
+                       hideItem: function( value ) {\r
+                               this._.list.hideItem( value );\r
+                       },\r
+\r
+                       hideGroup: function( groupTitle ) {\r
+                               this._.list.hideGroup( groupTitle );\r
+                       },\r
+\r
+                       showAll: function() {\r
+                               this._.list.showAll();\r
+                       },\r
+\r
+                       add: function( value, html, text ) {\r
+                               this._.items[ value ] = text || value;\r
+                               this._.list.add( value, html, text );\r
+                       },\r
+\r
+                       startGroup: function( title ) {\r
+                               this._.list.startGroup( title );\r
+                       },\r
+\r
+                       commit: function() {\r
+                               if ( !this._.committed ) {\r
+                                       this._.list.commit();\r
+                                       this._.committed = 1;\r
+                                       CKEDITOR.ui.fire( 'ready', this );\r
+                               }\r
+                               this._.committed = 1;\r
+                       },\r
+\r
+                       setState: function( state ) {\r
+                               if ( this._.state == state )\r
+                                       return;\r
+\r
+                               var el = this.document.getById( 'cke_' + this.id );\r
+                               el.setState( state, 'cke_combo' );\r
+\r
+                               state == CKEDITOR.TRISTATE_DISABLED ?\r
+                                       el.setAttribute( 'aria-disabled', true ) :\r
+                                       el.removeAttribute( 'aria-disabled' );\r
+\r
+                               this._.state = state;\r
+                       },\r
+\r
+                       getState: function() {\r
+                               return this._.state;\r
+                       },\r
+\r
+                       enable: function() {\r
+                               if ( this._.state == CKEDITOR.TRISTATE_DISABLED )\r
+                                       this.setState( this._.lastState );\r
+                       },\r
+\r
+                       disable: function() {\r
+                               if ( this._.state != CKEDITOR.TRISTATE_DISABLED ) {\r
+                                       this._.lastState = this._.state;\r
+                                       this.setState( CKEDITOR.TRISTATE_DISABLED );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Represents richCombo handler object.\r
+                *\r
+                * @class CKEDITOR.ui.richCombo.handler\r
+                * @singleton\r
+                * @extends CKEDITOR.ui.handlerDefinition\r
+                */\r
+               statics: {\r
+                       handler: {\r
+                               /**\r
+                                * Transforms a richCombo definition in a {@link CKEDITOR.ui.richCombo} instance.\r
+                                *\r
+                                * @param {Object} definition\r
+                                * @returns {CKEDITOR.ui.richCombo}\r
+                                */\r
+                               create: function( definition ) {\r
+                                       return new CKEDITOR.ui.richCombo( definition );\r
+                               }\r
+                       }\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * @param {String} name\r
+        * @param {Object} definition\r
+        * @member CKEDITOR.ui\r
+        * @todo\r
+        */\r
+       CKEDITOR.ui.prototype.addRichCombo = function( name, definition ) {\r
+               this.add( name, CKEDITOR.UI_RICHCOMBO, definition );\r
+       };\r
+\r
+} )();\r
diff --git a/sources/plugins/showborders/plugin.js b/sources/plugins/showborders/plugin.js
new file mode 100644 (file)
index 0000000..7dbfb59
--- /dev/null
@@ -0,0 +1,174 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The "show border" plugin. The command display visible outline\r
+ * border line around all table elements if table doesn't have a none-zero 'border' attribute specified.\r
+ */\r
+\r
+( function() {\r
+       var commandDefinition = {\r
+               preserveState: true,\r
+               editorFocus: false,\r
+               readOnly: 1,\r
+\r
+               exec: function( editor ) {\r
+                       this.toggleState();\r
+                       this.refresh( editor );\r
+               },\r
+\r
+               refresh: function( editor ) {\r
+                       if ( editor.document ) {\r
+                               var funcName = ( this.state == CKEDITOR.TRISTATE_ON ) ? 'attachClass' : 'removeClass';\r
+                               editor.editable()[ funcName ]( 'cke_show_borders' );\r
+                       }\r
+               }\r
+       };\r
+\r
+       var showBorderClassName = 'cke_show_border';\r
+\r
+       CKEDITOR.plugins.add( 'showborders', {\r
+               modes: { 'wysiwyg': 1 },\r
+\r
+               onLoad: function() {\r
+                       var cssStyleText,\r
+                               cssTemplate =\r
+                       // TODO: For IE6, we don't have child selector support,\r
+                       // where nested table cells could be incorrect.\r
+                       ( CKEDITOR.env.ie6Compat ? [\r
+                               '.%1 table.%2,',\r
+                               '.%1 table.%2 td, .%1 table.%2 th',\r
+                               '{',\r
+                               'border : #d3d3d3 1px dotted',\r
+                               '}'\r
+                       ] : [\r
+                               '.%1 table.%2,',\r
+                               '.%1 table.%2 > tr > td, .%1 table.%2 > tr > th,',\r
+                               '.%1 table.%2 > tbody > tr > td, .%1 table.%2 > tbody > tr > th,',\r
+                               '.%1 table.%2 > thead > tr > td, .%1 table.%2 > thead > tr > th,',\r
+                               '.%1 table.%2 > tfoot > tr > td, .%1 table.%2 > tfoot > tr > th',\r
+                               '{',\r
+                               'border : #d3d3d3 1px dotted',\r
+                               '}'\r
+                       ] ).join( '' );\r
+\r
+                       cssStyleText = cssTemplate.replace( /%2/g, showBorderClassName ).replace( /%1/g, 'cke_show_borders ' );\r
+\r
+                       CKEDITOR.addCss( cssStyleText );\r
+               },\r
+\r
+               init: function( editor ) {\r
+\r
+                       var command = editor.addCommand( 'showborders', commandDefinition );\r
+                       command.canUndo = false;\r
+\r
+                       if ( editor.config.startupShowBorders !== false )\r
+                               command.setState( CKEDITOR.TRISTATE_ON );\r
+\r
+                       // Refresh the command on setData.\r
+                       editor.on( 'mode', function() {\r
+                               if ( command.state != CKEDITOR.TRISTATE_DISABLED )\r
+                                       command.refresh( editor );\r
+                       }, null, null, 100 );\r
+\r
+                       // Refresh the command on wysiwyg frame reloads.\r
+                       editor.on( 'contentDom', function() {\r
+                               if ( command.state != CKEDITOR.TRISTATE_DISABLED )\r
+                                       command.refresh( editor );\r
+                       } );\r
+\r
+                       editor.on( 'removeFormatCleanup', function( evt ) {\r
+                               var element = evt.data;\r
+                               if ( editor.getCommand( 'showborders' ).state == CKEDITOR.TRISTATE_ON && element.is( 'table' ) && ( !element.hasAttribute( 'border' ) || parseInt( element.getAttribute( 'border' ), 10 ) <= 0 ) )\r
+                                       element.addClass( showBorderClassName );\r
+                       } );\r
+               },\r
+\r
+               afterInit: function( editor ) {\r
+                       var dataProcessor = editor.dataProcessor,\r
+                               dataFilter = dataProcessor && dataProcessor.dataFilter,\r
+                               htmlFilter = dataProcessor && dataProcessor.htmlFilter;\r
+\r
+                       if ( dataFilter ) {\r
+                               dataFilter.addRules( {\r
+                                       elements: {\r
+                                               'table': function( element ) {\r
+                                                       var attributes = element.attributes,\r
+                                                               cssClass = attributes[ 'class' ],\r
+                                                               border = parseInt( attributes.border, 10 );\r
+\r
+                                                       if ( ( !border || border <= 0 ) && ( !cssClass || cssClass.indexOf( showBorderClassName ) == -1 ) )\r
+                                                               attributes[ 'class' ] = ( cssClass || '' ) + ' ' + showBorderClassName;\r
+                                               }\r
+                                       }\r
+                               } );\r
+                       }\r
+\r
+                       if ( htmlFilter ) {\r
+                               htmlFilter.addRules( {\r
+                                       elements: {\r
+                                               'table': function( table ) {\r
+                                                       var attributes = table.attributes,\r
+                                                               cssClass = attributes[ 'class' ];\r
+\r
+                                                       cssClass && ( attributes[ 'class' ] = cssClass.replace( showBorderClassName, '' ).replace( /\s{2}/, ' ' ).replace( /^\s+|\s+$/, '' ) );\r
+                                               }\r
+                                       }\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+\r
+       // Table dialog must be aware of it.\r
+       CKEDITOR.on( 'dialogDefinition', function( ev ) {\r
+               var dialogName = ev.data.name;\r
+\r
+               if ( dialogName == 'table' || dialogName == 'tableProperties' ) {\r
+                       var dialogDefinition = ev.data.definition,\r
+                               infoTab = dialogDefinition.getContents( 'info' ),\r
+                               borderField = infoTab.get( 'txtBorder' ),\r
+                               originalCommit = borderField.commit;\r
+\r
+                       borderField.commit = CKEDITOR.tools.override( originalCommit, function( org ) {\r
+                               return function( data, selectedTable ) {\r
+                                       org.apply( this, arguments );\r
+                                       var value = parseInt( this.getValue(), 10 );\r
+                                       selectedTable[ ( !value || value <= 0 ) ? 'addClass' : 'removeClass' ]( showBorderClassName );\r
+                               };\r
+                       } );\r
+\r
+                       var advTab = dialogDefinition.getContents( 'advanced' ),\r
+                               classField = advTab && advTab.get( 'advCSSClasses' );\r
+\r
+                       if ( classField ) {\r
+                               classField.setup = CKEDITOR.tools.override( classField.setup, function( originalSetup ) {\r
+                                       return function() {\r
+                                               originalSetup.apply( this, arguments );\r
+                                               this.setValue( this.getValue().replace( /cke_show_border/, '' ) );\r
+                                       };\r
+                               } );\r
+\r
+                               classField.commit = CKEDITOR.tools.override( classField.commit, function( originalCommit ) {\r
+                                       return function( data, element ) {\r
+                                               originalCommit.apply( this, arguments );\r
+\r
+                                               if ( !parseInt( element.getAttribute( 'border' ), 10 ) )\r
+                                                       element.addClass( 'cke_show_border' );\r
+                                       };\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+\r
+} )();\r
+\r
+/**\r
+ * Whether to automatically enable the "show borders" command when the editor loads.\r
+ *\r
+ *             config.startupShowBorders = false;\r
+ *\r
+ * @cfg {Boolean} [startupShowBorders=true]\r
+ * @member CKEDITOR.config\r
+ */\r
diff --git a/sources/plugins/sourcearea/icons/hidpi/source-rtl.png b/sources/plugins/sourcearea/icons/hidpi/source-rtl.png
new file mode 100644 (file)
index 0000000..c95da32
Binary files /dev/null and b/sources/plugins/sourcearea/icons/hidpi/source-rtl.png differ
diff --git a/sources/plugins/sourcearea/icons/hidpi/source.png b/sources/plugins/sourcearea/icons/hidpi/source.png
new file mode 100644 (file)
index 0000000..2f3eae1
Binary files /dev/null and b/sources/plugins/sourcearea/icons/hidpi/source.png differ
diff --git a/sources/plugins/sourcearea/icons/source-rtl.png b/sources/plugins/sourcearea/icons/source-rtl.png
new file mode 100644 (file)
index 0000000..5353eee
Binary files /dev/null and b/sources/plugins/sourcearea/icons/source-rtl.png differ
diff --git a/sources/plugins/sourcearea/icons/source.png b/sources/plugins/sourcearea/icons/source.png
new file mode 100644 (file)
index 0000000..0783e85
Binary files /dev/null and b/sources/plugins/sourcearea/icons/source.png differ
diff --git a/sources/plugins/sourcearea/lang/af.js b/sources/plugins/sourcearea/lang/af.js
new file mode 100644 (file)
index 0000000..a5a499e
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'af', {\r
+       toolbar: 'Bron'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ar.js b/sources/plugins/sourcearea/lang/ar.js
new file mode 100644 (file)
index 0000000..40808ac
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ar', {\r
+       toolbar: 'المصدر'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/az.js b/sources/plugins/sourcearea/lang/az.js
new file mode 100644 (file)
index 0000000..9aeff4b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'az', {\r
+       toolbar: 'HTML mənbəyini göstər'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/bg.js b/sources/plugins/sourcearea/lang/bg.js
new file mode 100644 (file)
index 0000000..4902635
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'bg', {\r
+       toolbar: 'Изходен код'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/bn.js b/sources/plugins/sourcearea/lang/bn.js
new file mode 100644 (file)
index 0000000..b050458
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'bn', {\r
+       toolbar: 'উৎস'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/bs.js b/sources/plugins/sourcearea/lang/bs.js
new file mode 100644 (file)
index 0000000..c0b5e09
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'bs', {\r
+       toolbar: 'HTML kôd'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ca.js b/sources/plugins/sourcearea/lang/ca.js
new file mode 100644 (file)
index 0000000..c958e9b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ca', {\r
+       toolbar: 'Codi font'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/cs.js b/sources/plugins/sourcearea/lang/cs.js
new file mode 100644 (file)
index 0000000..dccf574
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'cs', {\r
+       toolbar: 'Zdroj'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/cy.js b/sources/plugins/sourcearea/lang/cy.js
new file mode 100644 (file)
index 0000000..b8ce201
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'cy', {\r
+       toolbar: 'HTML'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/da.js b/sources/plugins/sourcearea/lang/da.js
new file mode 100644 (file)
index 0000000..bf02c14
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'da', {\r
+       toolbar: 'Kilde'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/de-ch.js b/sources/plugins/sourcearea/lang/de-ch.js
new file mode 100644 (file)
index 0000000..c039623
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'de-ch', {\r
+       toolbar: 'Quellcode'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/de.js b/sources/plugins/sourcearea/lang/de.js
new file mode 100644 (file)
index 0000000..dfa995f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'de', {\r
+       toolbar: 'Quellcode'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/el.js b/sources/plugins/sourcearea/lang/el.js
new file mode 100644 (file)
index 0000000..0a8d8a8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'el', {\r
+       toolbar: 'Κώδικας'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/en-au.js b/sources/plugins/sourcearea/lang/en-au.js
new file mode 100644 (file)
index 0000000..10e7843
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'en-au', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/en-ca.js b/sources/plugins/sourcearea/lang/en-ca.js
new file mode 100644 (file)
index 0000000..f5e61da
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'en-ca', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/en-gb.js b/sources/plugins/sourcearea/lang/en-gb.js
new file mode 100644 (file)
index 0000000..5d876aa
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'en-gb', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/en.js b/sources/plugins/sourcearea/lang/en.js
new file mode 100644 (file)
index 0000000..90a24e9
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'en', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/eo.js b/sources/plugins/sourcearea/lang/eo.js
new file mode 100644 (file)
index 0000000..613de63
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'eo', {\r
+       toolbar: 'Fonto'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/es.js b/sources/plugins/sourcearea/lang/es.js
new file mode 100644 (file)
index 0000000..014a967
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'es', {\r
+       toolbar: 'Fuente HTML'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/et.js b/sources/plugins/sourcearea/lang/et.js
new file mode 100644 (file)
index 0000000..9a73ece
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'et', {\r
+       toolbar: 'Lähtekood'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/eu.js b/sources/plugins/sourcearea/lang/eu.js
new file mode 100644 (file)
index 0000000..350b3e2
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'eu', {\r
+       toolbar: 'Iturburua'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/fa.js b/sources/plugins/sourcearea/lang/fa.js
new file mode 100644 (file)
index 0000000..40757c0
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'fa', {\r
+       toolbar: 'منبع'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/fi.js b/sources/plugins/sourcearea/lang/fi.js
new file mode 100644 (file)
index 0000000..fba260e
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'fi', {\r
+       toolbar: 'Koodi'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/fo.js b/sources/plugins/sourcearea/lang/fo.js
new file mode 100644 (file)
index 0000000..f384c40
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'fo', {\r
+       toolbar: 'Kelda'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/fr-ca.js b/sources/plugins/sourcearea/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..707686f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'fr-ca', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/fr.js b/sources/plugins/sourcearea/lang/fr.js
new file mode 100644 (file)
index 0000000..57d4f5f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'fr', {\r
+       toolbar: 'Source'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/gl.js b/sources/plugins/sourcearea/lang/gl.js
new file mode 100644 (file)
index 0000000..c68a1da
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'gl', {\r
+       toolbar: 'Orixe'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/gu.js b/sources/plugins/sourcearea/lang/gu.js
new file mode 100644 (file)
index 0000000..a1c9b66
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'gu', {\r
+       toolbar: 'મૂળ કે પ્રાથમિક દસ્તાવેજ'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/he.js b/sources/plugins/sourcearea/lang/he.js
new file mode 100644 (file)
index 0000000..8b0f28d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'he', {\r
+       toolbar: 'מקור'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/hi.js b/sources/plugins/sourcearea/lang/hi.js
new file mode 100644 (file)
index 0000000..0d8cc1b
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'hi', {\r
+       toolbar: 'सोर्स'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/hr.js b/sources/plugins/sourcearea/lang/hr.js
new file mode 100644 (file)
index 0000000..dca2202
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'hr', {\r
+       toolbar: 'Kôd'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/hu.js b/sources/plugins/sourcearea/lang/hu.js
new file mode 100644 (file)
index 0000000..9628fe4
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'hu', {\r
+       toolbar: 'Forráskód'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/id.js b/sources/plugins/sourcearea/lang/id.js
new file mode 100644 (file)
index 0000000..f8e25c5
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'id', {\r
+       toolbar: 'Sumber'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/is.js b/sources/plugins/sourcearea/lang/is.js
new file mode 100644 (file)
index 0000000..a90207d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'is', {\r
+       toolbar: 'Kóði'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/it.js b/sources/plugins/sourcearea/lang/it.js
new file mode 100644 (file)
index 0000000..b445a21
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'it', {\r
+       toolbar: 'Sorgente'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ja.js b/sources/plugins/sourcearea/lang/ja.js
new file mode 100644 (file)
index 0000000..3f026b6
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ja', {\r
+       toolbar: 'ソース'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ka.js b/sources/plugins/sourcearea/lang/ka.js
new file mode 100644 (file)
index 0000000..f06b130
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ka', {\r
+       toolbar: 'კოდები'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/km.js b/sources/plugins/sourcearea/lang/km.js
new file mode 100644 (file)
index 0000000..9cd4769
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'km', {\r
+       toolbar: 'អក្សរ​កូដ'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ko.js b/sources/plugins/sourcearea/lang/ko.js
new file mode 100644 (file)
index 0000000..26fe7ff
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ko', {\r
+       toolbar: '소스'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ku.js b/sources/plugins/sourcearea/lang/ku.js
new file mode 100644 (file)
index 0000000..a3f1263
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ku', {\r
+       toolbar: 'سەرچاوە'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/lt.js b/sources/plugins/sourcearea/lang/lt.js
new file mode 100644 (file)
index 0000000..c3304dc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'lt', {\r
+       toolbar: 'Šaltinis'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/lv.js b/sources/plugins/sourcearea/lang/lv.js
new file mode 100644 (file)
index 0000000..c3ef246
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'lv', {\r
+       toolbar: 'HTML kods'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/mk.js b/sources/plugins/sourcearea/lang/mk.js
new file mode 100644 (file)
index 0000000..eeccabd
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'mk', {\r
+       toolbar: 'Source' // MISSING\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/mn.js b/sources/plugins/sourcearea/lang/mn.js
new file mode 100644 (file)
index 0000000..a7c1288
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'mn', {\r
+       toolbar: 'Код'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ms.js b/sources/plugins/sourcearea/lang/ms.js
new file mode 100644 (file)
index 0000000..f09ac53
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ms', {\r
+       toolbar: 'Sumber'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/nb.js b/sources/plugins/sourcearea/lang/nb.js
new file mode 100644 (file)
index 0000000..87b75a8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'nb', {\r
+       toolbar: 'Kilde'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/nl.js b/sources/plugins/sourcearea/lang/nl.js
new file mode 100644 (file)
index 0000000..dc61f34
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'nl', {\r
+       toolbar: 'Broncode'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/no.js b/sources/plugins/sourcearea/lang/no.js
new file mode 100644 (file)
index 0000000..86f386d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'no', {\r
+       toolbar: 'Kilde'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/oc.js b/sources/plugins/sourcearea/lang/oc.js
new file mode 100644 (file)
index 0000000..90f418f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'oc', {\r
+       toolbar: 'Font'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/pl.js b/sources/plugins/sourcearea/lang/pl.js
new file mode 100644 (file)
index 0000000..48734a8
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'pl', {\r
+       toolbar: 'Źródło dokumentu'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/pt-br.js b/sources/plugins/sourcearea/lang/pt-br.js
new file mode 100644 (file)
index 0000000..54e3ce1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'pt-br', {\r
+       toolbar: 'Código-Fonte'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/pt.js b/sources/plugins/sourcearea/lang/pt.js
new file mode 100644 (file)
index 0000000..7fd6c23
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'pt', {\r
+       toolbar: 'Fonte'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ro.js b/sources/plugins/sourcearea/lang/ro.js
new file mode 100644 (file)
index 0000000..5eb00c4
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ro', {\r
+       toolbar: 'Sursa'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ru.js b/sources/plugins/sourcearea/lang/ru.js
new file mode 100644 (file)
index 0000000..304695c
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ru', {\r
+       toolbar: 'Источник'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/si.js b/sources/plugins/sourcearea/lang/si.js
new file mode 100644 (file)
index 0000000..22996eb
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'si', {\r
+       toolbar: 'මුලාශ්‍රය'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sk.js b/sources/plugins/sourcearea/lang/sk.js
new file mode 100644 (file)
index 0000000..aed1c61
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sk', {\r
+       toolbar: 'Zdroj'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sl.js b/sources/plugins/sourcearea/lang/sl.js
new file mode 100644 (file)
index 0000000..b9a2b5f
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sl', {\r
+       toolbar: 'Izvorna koda'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sq.js b/sources/plugins/sourcearea/lang/sq.js
new file mode 100644 (file)
index 0000000..f4512ce
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sq', {\r
+       toolbar: 'Burimi'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sr-latn.js b/sources/plugins/sourcearea/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..0d8ebd7
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sr-latn', {\r
+       toolbar: 'Kôd'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sr.js b/sources/plugins/sourcearea/lang/sr.js
new file mode 100644 (file)
index 0000000..a872556
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sr', {\r
+       toolbar: 'Kôд'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/sv.js b/sources/plugins/sourcearea/lang/sv.js
new file mode 100644 (file)
index 0000000..a05d49d
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'sv', {\r
+       toolbar: 'Källa'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/th.js b/sources/plugins/sourcearea/lang/th.js
new file mode 100644 (file)
index 0000000..4afb9bc
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'th', {\r
+       toolbar: 'ดูรหัส HTML'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/tr.js b/sources/plugins/sourcearea/lang/tr.js
new file mode 100644 (file)
index 0000000..7a9f70a
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'tr', {\r
+       toolbar: 'Kaynak'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/tt.js b/sources/plugins/sourcearea/lang/tt.js
new file mode 100644 (file)
index 0000000..ca05df1
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'tt', {\r
+       toolbar: 'Чыганак'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/ug.js b/sources/plugins/sourcearea/lang/ug.js
new file mode 100644 (file)
index 0000000..791c596
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'ug', {\r
+       toolbar: 'مەنبە'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/uk.js b/sources/plugins/sourcearea/lang/uk.js
new file mode 100644 (file)
index 0000000..905af47
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'uk', {\r
+       toolbar: 'Джерело'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/vi.js b/sources/plugins/sourcearea/lang/vi.js
new file mode 100644 (file)
index 0000000..df7eb93
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'vi', {\r
+       toolbar: 'Mã HTML'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/zh-cn.js b/sources/plugins/sourcearea/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..a98c869
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'zh-cn', {\r
+       toolbar: '源码'\r
+} );\r
diff --git a/sources/plugins/sourcearea/lang/zh.js b/sources/plugins/sourcearea/lang/zh.js
new file mode 100644 (file)
index 0000000..043dd11
--- /dev/null
@@ -0,0 +1,7 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'sourcearea', 'zh', {\r
+       toolbar: '原始碼'\r
+} );\r
diff --git a/sources/plugins/sourcearea/plugin.js b/sources/plugins/sourcearea/plugin.js
new file mode 100644 (file)
index 0000000..837bc30
--- /dev/null
@@ -0,0 +1,168 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The Source Editing Area plugin. It registers the "source" editing\r
+ *             mode, which displays raw  HTML data being edited in the editor.\r
+ */\r
+\r
+( function() {\r
+       CKEDITOR.plugins.add( 'sourcearea', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               icons: 'source,source-rtl', // %REMOVE_LINE_CORE%\r
+               hidpi: true, // %REMOVE_LINE_CORE%\r
+               init: function( editor ) {\r
+                       // Source mode in inline editors is only available through the "sourcedialog" plugin.\r
+                       if ( editor.elementMode == CKEDITOR.ELEMENT_MODE_INLINE )\r
+                               return;\r
+\r
+                       var sourcearea = CKEDITOR.plugins.sourcearea;\r
+\r
+                       editor.addMode( 'source', function( callback ) {\r
+                               var contentsSpace = editor.ui.space( 'contents' ),\r
+                                       textarea = contentsSpace.getDocument().createElement( 'textarea' );\r
+\r
+                               textarea.setStyles(\r
+                                       CKEDITOR.tools.extend( {\r
+                                               // IE7 has overflow the <textarea> from wrapping table cell.\r
+                                               width: CKEDITOR.env.ie7Compat ? '99%' : '100%',\r
+                                               height: '100%',\r
+                                               resize: 'none',\r
+                                               outline: 'none',\r
+                                               'text-align': 'left'\r
+                                       },\r
+                                       CKEDITOR.tools.cssVendorPrefix( 'tab-size', editor.config.sourceAreaTabSize || 4 ) ) );\r
+\r
+                               // Make sure that source code is always displayed LTR,\r
+                               // regardless of editor language (#10105).\r
+                               textarea.setAttribute( 'dir', 'ltr' );\r
+\r
+                               textarea.addClass( 'cke_source' ).addClass( 'cke_reset' ).addClass( 'cke_enable_context_menu' );\r
+\r
+                               editor.ui.space( 'contents' ).append( textarea );\r
+\r
+                               var editable = editor.editable( new sourceEditable( editor, textarea ) );\r
+\r
+                               // Fill the textarea with the current editor data.\r
+                               editable.setData( editor.getData( 1 ) );\r
+\r
+                               // Having to make <textarea> fixed sized to conquer the following bugs:\r
+                               // 1. The textarea height/width='100%' doesn't constraint to the 'td' in IE6/7.\r
+                               // 2. Unexpected vertical-scrolling behavior happens whenever focus is moving out of editor\r
+                               // if text content within it has overflowed. (#4762)\r
+                               if ( CKEDITOR.env.ie ) {\r
+                                       editable.attachListener( editor, 'resize', onResize, editable );\r
+                                       editable.attachListener( CKEDITOR.document.getWindow(), 'resize', onResize, editable );\r
+                                       CKEDITOR.tools.setTimeout( onResize, 0, editable );\r
+                               }\r
+\r
+                               editor.fire( 'ariaWidget', this );\r
+\r
+                               callback();\r
+                       } );\r
+\r
+                       editor.addCommand( 'source', sourcearea.commands.source );\r
+\r
+                       if ( editor.ui.addButton ) {\r
+                               editor.ui.addButton( 'Source', {\r
+                                       label: editor.lang.sourcearea.toolbar,\r
+                                       command: 'source',\r
+                                       toolbar: 'mode,10'\r
+                               } );\r
+                       }\r
+\r
+                       editor.on( 'mode', function() {\r
+                               editor.getCommand( 'source' ).setState( editor.mode == 'source' ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );\r
+                       } );\r
+\r
+                       var needsFocusHack = CKEDITOR.env.ie && CKEDITOR.env.version == 9;\r
+\r
+                       function onResize() {\r
+                               // We have to do something with focus on IE9, because if sourcearea had focus\r
+                               // before being resized, the caret ends somewhere in the editor UI (#11839).\r
+                               var wasActive = needsFocusHack && this.equals( CKEDITOR.document.getActive() );\r
+\r
+                               // Holder rectange size is stretched by textarea,\r
+                               // so hide it just for a moment.\r
+                               this.hide();\r
+                               this.setStyle( 'height', this.getParent().$.clientHeight + 'px' );\r
+                               this.setStyle( 'width', this.getParent().$.clientWidth + 'px' );\r
+                               // When we have proper holder size, show textarea again.\r
+                               this.show();\r
+\r
+                               if ( wasActive )\r
+                                       this.focus();\r
+                       }\r
+               }\r
+       } );\r
+\r
+       var sourceEditable = CKEDITOR.tools.createClass( {\r
+               base: CKEDITOR.editable,\r
+               proto: {\r
+                       setData: function( data ) {\r
+                               this.setValue( data );\r
+                               this.status = 'ready';\r
+                               this.editor.fire( 'dataReady' );\r
+                       },\r
+\r
+                       getData: function() {\r
+                               return this.getValue();\r
+                       },\r
+\r
+                       // Insertions are not supported in source editable.\r
+                       insertHtml: function() {},\r
+                       insertElement: function() {},\r
+                       insertText: function() {},\r
+\r
+                       // Read-only support for textarea.\r
+                       setReadOnly: function( isReadOnly ) {\r
+                               this[ ( isReadOnly ? 'set' : 'remove' ) + 'Attribute' ]( 'readOnly', 'readonly' );\r
+                       },\r
+\r
+                       detach: function() {\r
+                               sourceEditable.baseProto.detach.call( this );\r
+                               this.clearCustomData();\r
+                               this.remove();\r
+                       }\r
+               }\r
+       } );\r
+} )();\r
+\r
+CKEDITOR.plugins.sourcearea = {\r
+       commands: {\r
+               source: {\r
+                       modes: { wysiwyg: 1, source: 1 },\r
+                       editorFocus: false,\r
+                       readOnly: 1,\r
+                       exec: function( editor ) {\r
+                               if ( editor.mode == 'wysiwyg' )\r
+                                       editor.fire( 'saveSnapshot' );\r
+                               editor.getCommand( 'source' ).setState( CKEDITOR.TRISTATE_DISABLED );\r
+                               editor.setMode( editor.mode == 'source' ? 'wysiwyg' : 'source' );\r
+                       },\r
+\r
+                       canUndo: false\r
+               }\r
+       }\r
+};\r
+\r
+/**\r
+ * Controls the `tab-size` CSS property of the source editing area. Use it to set the width\r
+ * of the tab character in the source view. Enter an integer to denote the number of spaces\r
+ * that the tab will contain.\r
+ *\r
+ * **Note:** Works only with {@link #dataIndentationChars}\r
+ * set to `'\t'`. Please consider that not all browsers support the `tab-size` CSS\r
+ * property yet.\r
+ *\r
+ *             // Set tab-size to 10 characters.\r
+ *             config.sourceAreaTabSize = 10;\r
+ *\r
+ * @cfg {Number} [sourceAreaTabSize=4]\r
+ * @member CKEDITOR.config\r
+ * @see CKEDITOR.config#dataIndentationChars\r
+ */\r
diff --git a/sources/plugins/tab/plugin.js b/sources/plugins/tab/plugin.js
new file mode 100644 (file)
index 0000000..98acb2e
--- /dev/null
@@ -0,0 +1,302 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+( function() {\r
+       var meta = {\r
+               editorFocus: false,\r
+               modes: { wysiwyg: 1, source: 1 }\r
+       };\r
+\r
+       var blurCommand = {\r
+               exec: function( editor ) {\r
+                       editor.container.focusNext( true, editor.tabIndex );\r
+               }\r
+       };\r
+\r
+       var blurBackCommand = {\r
+               exec: function( editor ) {\r
+                       editor.container.focusPrevious( true, editor.tabIndex );\r
+               }\r
+       };\r
+\r
+       function selectNextCellCommand( backward ) {\r
+               return {\r
+                       editorFocus: false,\r
+                       canUndo: false,\r
+                       modes: { wysiwyg: 1 },\r
+                       exec: function( editor ) {\r
+                               if ( editor.editable().hasFocus ) {\r
+                                       var sel = editor.getSelection(),\r
+                                               path = new CKEDITOR.dom.elementPath( sel.getCommonAncestor(), sel.root ),\r
+                                               cell;\r
+\r
+                                       if ( ( cell = path.contains( { td: 1, th: 1 }, 1 ) ) ) {\r
+                                               var resultRange = editor.createRange(),\r
+                                                       next = CKEDITOR.tools.tryThese( function() {\r
+                                                               var row = cell.getParent(),\r
+                                                                       next = row.$.cells[ cell.$.cellIndex + ( backward ? -1 : 1 ) ];\r
+\r
+                                                               // Invalid any empty value.\r
+                                                               next.parentNode.parentNode;\r
+                                                               return next;\r
+                                                       }, function() {\r
+                                                               var row = cell.getParent(),\r
+                                                                       table = row.getAscendant( 'table' ),\r
+                                                                       nextRow = table.$.rows[ row.$.rowIndex + ( backward ? -1 : 1 ) ];\r
+\r
+                                                               return nextRow.cells[ backward ? nextRow.cells.length - 1 : 0 ];\r
+                                                       } );\r
+\r
+                                               // Clone one more row at the end of table and select the first newly established cell.\r
+                                               if ( !( next || backward ) ) {\r
+                                                       var table = cell.getAscendant( 'table' ).$,\r
+                                                               cells = cell.getParent().$.cells;\r
+\r
+                                                       var newRow = new CKEDITOR.dom.element( table.insertRow( -1 ), editor.document );\r
+\r
+                                                       for ( var i = 0, count = cells.length; i < count; i++ ) {\r
+                                                               var newCell = newRow.append( new CKEDITOR.dom.element( cells[ i ], editor.document ).clone( false, false ) );\r
+                                                               newCell.appendBogus();\r
+                                                       }\r
+\r
+                                                       resultRange.moveToElementEditStart( newRow );\r
+                                               } else if ( next ) {\r
+                                                       next = new CKEDITOR.dom.element( next );\r
+                                                       resultRange.moveToElementEditStart( next );\r
+                                                       // Avoid selecting empty block makes the cursor blind.\r
+                                                       if ( !( resultRange.checkStartOfBlock() && resultRange.checkEndOfBlock() ) )\r
+                                                               resultRange.selectNodeContents( next );\r
+                                               } else {\r
+                                                       return true;\r
+                                               }\r
+\r
+                                               resultRange.select( true );\r
+                                               return true;\r
+                                       }\r
+                               }\r
+\r
+                               return false;\r
+                       }\r
+               };\r
+       }\r
+\r
+       CKEDITOR.plugins.add( 'tab', {\r
+               init: function( editor ) {\r
+                       var tabTools = editor.config.enableTabKeyTools !== false,\r
+                               tabSpaces = editor.config.tabSpaces || 0,\r
+                               tabText = '';\r
+\r
+                       while ( tabSpaces-- )\r
+                               tabText += '\xa0';\r
+\r
+                       if ( tabText ) {\r
+                               editor.on( 'key', function( ev ) {\r
+                                       // TAB.\r
+                                       if ( ev.data.keyCode == 9 ) {\r
+                                               editor.insertText( tabText );\r
+                                               ev.cancel();\r
+                                       }\r
+                               } );\r
+                       }\r
+\r
+                       if ( tabTools ) {\r
+                               editor.on( 'key', function( ev ) {\r
+                                       if ( ev.data.keyCode == 9 && editor.execCommand( 'selectNextCell' ) || // TAB\r
+                                       ev.data.keyCode == ( CKEDITOR.SHIFT + 9 ) && editor.execCommand( 'selectPreviousCell' ) ) // SHIFT+TAB\r
+                                       ev.cancel();\r
+                               } );\r
+                       }\r
+\r
+                       editor.addCommand( 'blur', CKEDITOR.tools.extend( blurCommand, meta ) );\r
+                       editor.addCommand( 'blurBack', CKEDITOR.tools.extend( blurBackCommand, meta ) );\r
+                       editor.addCommand( 'selectNextCell', selectNextCellCommand() );\r
+                       editor.addCommand( 'selectPreviousCell', selectNextCellCommand( true ) );\r
+               }\r
+       } );\r
+} )();\r
+\r
+/**\r
+ * Moves the UI focus to the element following this element in the tabindex order.\r
+ *\r
+ *             var element = CKEDITOR.document.getById( 'example' );\r
+ *             element.focusNext();\r
+ *\r
+ * @param {Boolean} [ignoreChildren=false]\r
+ * @param {Number} [indexToUse]\r
+ * @member CKEDITOR.dom.element\r
+ */\r
+CKEDITOR.dom.element.prototype.focusNext = function( ignoreChildren, indexToUse ) {\r
+       var curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),\r
+               passedCurrent, enteredCurrent, elected, electedTabIndex, element, elementTabIndex;\r
+\r
+       if ( curTabIndex <= 0 ) {\r
+               // If this element has tabindex <= 0 then we must simply look for any\r
+               // element following it containing tabindex=0.\r
+\r
+               element = this.getNextSourceNode( ignoreChildren, CKEDITOR.NODE_ELEMENT );\r
+\r
+               while ( element ) {\r
+                       if ( element.isVisible() && element.getTabIndex() === 0 ) {\r
+                               elected = element;\r
+                               break;\r
+                       }\r
+\r
+                       element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT );\r
+               }\r
+       } else {\r
+               // If this element has tabindex > 0 then we must look for:\r
+               //              1. An element following this element with the same tabindex.\r
+               //              2. The first element in source other with the lowest tabindex\r
+               //                 that is higher than this element tabindex.\r
+               //              3. The first element with tabindex=0.\r
+\r
+               element = this.getDocument().getBody().getFirst();\r
+\r
+               while ( ( element = element.getNextSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) {\r
+                       if ( !passedCurrent ) {\r
+                               if ( !enteredCurrent && element.equals( this ) ) {\r
+                                       enteredCurrent = true;\r
+\r
+                                       // Ignore this element, if required.\r
+                                       if ( ignoreChildren ) {\r
+                                               if ( !( element = element.getNextSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) )\r
+                                                       break;\r
+                                               passedCurrent = 1;\r
+                                       }\r
+                               } else if ( enteredCurrent && !this.contains( element ) ) {\r
+                                       passedCurrent = 1;\r
+                               }\r
+                       }\r
+\r
+                       if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 )\r
+                               continue;\r
+\r
+                       if ( passedCurrent && elementTabIndex == curTabIndex ) {\r
+                               elected = element;\r
+                               break;\r
+                       }\r
+\r
+                       if ( elementTabIndex > curTabIndex && ( !elected || !electedTabIndex || elementTabIndex < electedTabIndex ) ) {\r
+                               elected = element;\r
+                               electedTabIndex = elementTabIndex;\r
+                       } else if ( !elected && elementTabIndex === 0 ) {\r
+                               elected = element;\r
+                               electedTabIndex = elementTabIndex;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if ( elected )\r
+               elected.focus();\r
+};\r
+\r
+/**\r
+ * Moves the UI focus to the element before this element in the tabindex order.\r
+ *\r
+ *             var element = CKEDITOR.document.getById( 'example' );\r
+ *             element.focusPrevious();\r
+ *\r
+ * @param {Boolean} [ignoreChildren=false]\r
+ * @param {Number} [indexToUse]\r
+ * @member CKEDITOR.dom.element\r
+ */\r
+CKEDITOR.dom.element.prototype.focusPrevious = function( ignoreChildren, indexToUse ) {\r
+       var curTabIndex = ( indexToUse === undefined ? this.getTabIndex() : indexToUse ),\r
+               passedCurrent, enteredCurrent, elected,\r
+               electedTabIndex = 0,\r
+               elementTabIndex;\r
+\r
+       var element = this.getDocument().getBody().getLast();\r
+\r
+       while ( ( element = element.getPreviousSourceNode( false, CKEDITOR.NODE_ELEMENT ) ) ) {\r
+               if ( !passedCurrent ) {\r
+                       if ( !enteredCurrent && element.equals( this ) ) {\r
+                               enteredCurrent = true;\r
+\r
+                               // Ignore this element, if required.\r
+                               if ( ignoreChildren ) {\r
+                                       if ( !( element = element.getPreviousSourceNode( true, CKEDITOR.NODE_ELEMENT ) ) )\r
+                                               break;\r
+                                       passedCurrent = 1;\r
+                               }\r
+                       } else if ( enteredCurrent && !this.contains( element ) ) {\r
+                               passedCurrent = 1;\r
+                       }\r
+               }\r
+\r
+               if ( !element.isVisible() || ( elementTabIndex = element.getTabIndex() ) < 0 )\r
+                       continue;\r
+\r
+               if ( curTabIndex <= 0 ) {\r
+                       // If this element has tabindex <= 0 then we must look for:\r
+                       //              1. An element before this one containing tabindex=0.\r
+                       //              2. The last element with the highest tabindex.\r
+\r
+                       if ( passedCurrent && elementTabIndex === 0 ) {\r
+                               elected = element;\r
+                               break;\r
+                       }\r
+\r
+                       if ( elementTabIndex > electedTabIndex ) {\r
+                               elected = element;\r
+                               electedTabIndex = elementTabIndex;\r
+                       }\r
+               } else {\r
+                       // If this element has tabindex > 0 we must look for:\r
+                       //              1. An element preceeding this one, with the same tabindex.\r
+                       //              2. The last element in source other with the highest tabindex\r
+                       //                 that is lower than this element tabindex.\r
+\r
+                       if ( passedCurrent && elementTabIndex == curTabIndex ) {\r
+                               elected = element;\r
+                               break;\r
+                       }\r
+\r
+                       if ( elementTabIndex < curTabIndex && ( !elected || elementTabIndex > electedTabIndex ) ) {\r
+                               elected = element;\r
+                               electedTabIndex = elementTabIndex;\r
+                       }\r
+               }\r
+       }\r
+\r
+       if ( elected )\r
+               elected.focus();\r
+};\r
+\r
+/**\r
+ * Intructs the editor to add a number of spaces (`&nbsp;`) to the text when\r
+ * hitting the <kbd>Tab</kbd> key. If set to zero, the <kbd>Tab</kbd> key will be used to move the\r
+ * cursor focus to the next element in the page, out of the editor focus.\r
+ *\r
+ *             config.tabSpaces = 4;\r
+ *\r
+ * @cfg {Number} [tabSpaces=0]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Allow context-sensitive <kbd>Tab</kbd> key behaviors, including the following scenarios:\r
+ *\r
+ * When selection is anchored inside **table cells**:\r
+ *\r
+ * * If <kbd>Tab</kbd> is pressed, select the content of the "next" cell. If in the last\r
+ *     cell in the table, add a new row to it and focus its first cell.\r
+ * * If <kbd>Shift+Tab</kbd> is pressed, select the content of the "previous" cell.\r
+ *     Do nothing when it is in the first cell.\r
+ *\r
+ * Example:\r
+ *\r
+ *             config.enableTabKeyTools = false;\r
+ *\r
+ * @cfg {Boolean} [enableTabKeyTools=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+// If the <kbd>Tab</kbd> key is not supposed to be enabled for navigation, the following\r
+// settings could be used alternatively:\r
+// config.keystrokes.push(\r
+//     [ CKEDITOR.ALT + 38 /*Arrow Up*/, 'selectPreviousCell' ],\r
+//     [ CKEDITOR.ALT + 40 /*Arrow Down*/, 'selectNextCell' ]\r
+// );\r
diff --git a/sources/plugins/toolbar/lang/af.js b/sources/plugins/toolbar/lang/af.js
new file mode 100644 (file)
index 0000000..8a3b1cd
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'af', {\r
+       toolbarCollapse: 'Verklein werkbalk',\r
+       toolbarExpand: 'Vergroot werkbalk',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Knipbord/Undo',\r
+               editing: 'Verander',\r
+               forms: 'Vorms',\r
+               basicstyles: 'Eenvoudige Styl',\r
+               paragraph: 'Paragraaf',\r
+               links: 'Skakels',\r
+               insert: 'Toevoeg',\r
+               styles: 'Style',\r
+               colors: 'Kleure',\r
+               tools: 'Gereedskap'\r
+       },\r
+       toolbars: 'Werkbalke'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ar.js b/sources/plugins/toolbar/lang/ar.js
new file mode 100644 (file)
index 0000000..8cef5e7
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ar', {\r
+       toolbarCollapse: 'تقليص شريط الأدوت',\r
+       toolbarExpand: 'تمديد شريط الأدوات',\r
+       toolbarGroups: {\r
+               document: 'مستند',\r
+               clipboard: 'الحافظة/الرجوع',\r
+               editing: 'تحرير',\r
+               forms: 'نماذج',\r
+               basicstyles: 'نمط بسيط',\r
+               paragraph: 'فقرة',\r
+               links: 'روابط',\r
+               insert: 'إدراج',\r
+               styles: 'أنماط',\r
+               colors: 'ألوان',\r
+               tools: 'أدوات'\r
+       },\r
+       toolbars: 'أشرطة أدوات المحرر'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/az.js b/sources/plugins/toolbar/lang/az.js
new file mode 100644 (file)
index 0000000..25c4a53
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'az', {\r
+       toolbarCollapse: 'Paneli gizlət',\r
+       toolbarExpand: 'Paneli göstər',\r
+       toolbarGroups: {\r
+               document: 'Mətn',\r
+               clipboard: 'Mübadilə buferi/İmtina et',\r
+               editing: 'Redaktə edilməsi',\r
+               forms: 'Formalar',\r
+               basicstyles: 'Əsas üslublar',\r
+               paragraph: 'Abzas',\r
+               links: 'Link',\r
+               insert: 'Əlavə et',\r
+               styles: 'Üslublar',\r
+               colors: 'Rənqlər',\r
+               tools: 'Alətləri'\r
+       },\r
+       toolbars: 'Redaktorun panelləri'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/bg.js b/sources/plugins/toolbar/lang/bg.js
new file mode 100644 (file)
index 0000000..0fb4384
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'bg', {\r
+       toolbarCollapse: 'Свиване на лентата с инструменти',\r
+       toolbarExpand: 'Разширяване на лентата с инструменти',\r
+       toolbarGroups: {\r
+               document: 'Документ',\r
+               clipboard: 'Клипборд/Отмяна',\r
+               editing: 'Промяна',\r
+               forms: 'Форми',\r
+               basicstyles: 'Базови стилове',\r
+               paragraph: 'Параграф',\r
+               links: 'Връзки',\r
+               insert: 'Вмъкване',\r
+               styles: 'Стилове',\r
+               colors: 'Цветове',\r
+               tools: 'Инструменти'\r
+       },\r
+       toolbars: 'Ленти с инструменти'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/bn.js b/sources/plugins/toolbar/lang/bn.js
new file mode 100644 (file)
index 0000000..dc9697e
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'bn', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/bs.js b/sources/plugins/toolbar/lang/bs.js
new file mode 100644 (file)
index 0000000..00f46d0
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'bs', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ca.js b/sources/plugins/toolbar/lang/ca.js
new file mode 100644 (file)
index 0000000..82e4413
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ca', {\r
+       toolbarCollapse: 'Redueix la barra d\'eines',\r
+       toolbarExpand: 'Amplia la barra d\'eines',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor de barra d\'eines'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/cs.js b/sources/plugins/toolbar/lang/cs.js
new file mode 100644 (file)
index 0000000..f8e650f
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'cs', {\r
+       toolbarCollapse: 'Skrýt panel nástrojů',\r
+       toolbarExpand: 'Zobrazit panel nástrojů',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Schránka/Zpět',\r
+               editing: 'Úpravy',\r
+               forms: 'Formuláře',\r
+               basicstyles: 'Základní styly',\r
+               paragraph: 'Odstavec',\r
+               links: 'Odkazy',\r
+               insert: 'Vložit',\r
+               styles: 'Styly',\r
+               colors: 'Barvy',\r
+               tools: 'Nástroje'\r
+       },\r
+       toolbars: 'Panely nástrojů editoru'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/cy.js b/sources/plugins/toolbar/lang/cy.js
new file mode 100644 (file)
index 0000000..faebd1b
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'cy', {\r
+       toolbarCollapse: 'Cyfangu\'r Bar Offer',\r
+       toolbarExpand: 'Ehangu\'r Bar Offer',\r
+       toolbarGroups: {\r
+               document: 'Dogfen',\r
+               clipboard: 'Clipfwrdd/Dadwneud',\r
+               editing: 'Golygu',\r
+               forms: 'Ffurflenni',\r
+               basicstyles: 'Arddulliau Sylfaenol',\r
+               paragraph: 'Paragraff',\r
+               links: 'Dolenni',\r
+               insert: 'Mewnosod',\r
+               styles: 'Arddulliau',\r
+               colors: 'Lliwiau',\r
+               tools: 'Offer'\r
+       },\r
+       toolbars: 'Bariau offer y golygydd'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/da.js b/sources/plugins/toolbar/lang/da.js
new file mode 100644 (file)
index 0000000..750bc64
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'da', {\r
+       toolbarCollapse: 'Sammenklap værktøjslinje',\r
+       toolbarExpand: 'Udvid værktøjslinje',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Udklipsholder/Fortryd',\r
+               editing: 'Redigering',\r
+               forms: 'Formularer',\r
+               basicstyles: 'Basis styles',\r
+               paragraph: 'Paragraf',\r
+               links: 'Links',\r
+               insert: 'Indsæt',\r
+               styles: 'Typografier',\r
+               colors: 'Farver',\r
+               tools: 'Værktøjer'\r
+       },\r
+       toolbars: 'Editors værktøjslinjer'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/de-ch.js b/sources/plugins/toolbar/lang/de-ch.js
new file mode 100644 (file)
index 0000000..399aa63
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'de-ch', {\r
+       toolbarCollapse: 'Werkzeugleiste einklappen',\r
+       toolbarExpand: 'Werkzeugleiste ausklappen',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Zwischenablage/Rückgängig',\r
+               editing: 'Editieren',\r
+               forms: 'Formulare',\r
+               basicstyles: 'Grundstile',\r
+               paragraph: 'Absatz',\r
+               links: 'Links',\r
+               insert: 'Einfügen',\r
+               styles: 'Stile',\r
+               colors: 'Farben',\r
+               tools: 'Werkzeuge'\r
+       },\r
+       toolbars: 'Editor Werkzeugleisten'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/de.js b/sources/plugins/toolbar/lang/de.js
new file mode 100644 (file)
index 0000000..fab73aa
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'de', {\r
+       toolbarCollapse: 'Werkzeugleiste einklappen',\r
+       toolbarExpand: 'Werkzeugleiste ausklappen',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Zwischenablage/Rückgängig',\r
+               editing: 'Editieren',\r
+               forms: 'Formulare',\r
+               basicstyles: 'Grundstile',\r
+               paragraph: 'Absatz',\r
+               links: 'Links',\r
+               insert: 'Einfügen',\r
+               styles: 'Stile',\r
+               colors: 'Farben',\r
+               tools: 'Werkzeuge'\r
+       },\r
+       toolbars: 'Editor Werkzeugleisten'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/el.js b/sources/plugins/toolbar/lang/el.js
new file mode 100644 (file)
index 0000000..ce46898
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'el', {\r
+       toolbarCollapse: 'Σύμπτυξη Εργαλειοθήκης',\r
+       toolbarExpand: 'Ανάπτυξη Εργαλειοθήκης',\r
+       toolbarGroups: {\r
+               document: 'Έγγραφο',\r
+               clipboard: 'Πρόχειρο/Αναίρεση',\r
+               editing: 'Επεξεργασία',\r
+               forms: 'Φόρμες',\r
+               basicstyles: 'Βασικά Στυλ',\r
+               paragraph: 'Παράγραφος',\r
+               links: 'Σύνδεσμοι',\r
+               insert: 'Εισαγωγή',\r
+               styles: 'Στυλ',\r
+               colors: 'Χρώματα',\r
+               tools: 'Εργαλεία'\r
+       },\r
+       toolbars: 'Εργαλειοθήκες επεξεργαστή'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/en-au.js b/sources/plugins/toolbar/lang/en-au.js
new file mode 100644 (file)
index 0000000..8517e62
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'en-au', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/en-ca.js b/sources/plugins/toolbar/lang/en-ca.js
new file mode 100644 (file)
index 0000000..fb2049a
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'en-ca', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/en-gb.js b/sources/plugins/toolbar/lang/en-gb.js
new file mode 100644 (file)
index 0000000..df7198e
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'en-gb', {\r
+       toolbarCollapse: 'Collapse Toolbar',\r
+       toolbarExpand: 'Expand Toolbar',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/en.js b/sources/plugins/toolbar/lang/en.js
new file mode 100644 (file)
index 0000000..263ac0e
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'en', {\r
+       toolbarCollapse: 'Collapse Toolbar',\r
+       toolbarExpand: 'Expand Toolbar',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/eo.js b/sources/plugins/toolbar/lang/eo.js
new file mode 100644 (file)
index 0000000..902a613
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'eo', {\r
+       toolbarCollapse: 'Faldi la ilbreton',\r
+       toolbarExpand: 'Malfaldi la ilbreton',\r
+       toolbarGroups: {\r
+               document: 'Dokumento',\r
+               clipboard: 'Poŝo/Malfari',\r
+               editing: 'Redaktado',\r
+               forms: 'Formularoj',\r
+               basicstyles: 'Bazaj stiloj',\r
+               paragraph: 'Paragrafo',\r
+               links: 'Ligiloj',\r
+               insert: 'Enmeti',\r
+               styles: 'Stiloj',\r
+               colors: 'Koloroj',\r
+               tools: 'Iloj'\r
+       },\r
+       toolbars: 'Ilobretoj de la redaktilo'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/es.js b/sources/plugins/toolbar/lang/es.js
new file mode 100644 (file)
index 0000000..bf5b457
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'es', {\r
+       toolbarCollapse: 'Contraer barra de herramientas',\r
+       toolbarExpand: 'Expandir barra de herramientas',\r
+       toolbarGroups: {\r
+               document: 'Documento',\r
+               clipboard: 'Portapapeles/Deshacer',\r
+               editing: 'Edición',\r
+               forms: 'Formularios',\r
+               basicstyles: 'Estilos básicos',\r
+               paragraph: 'Párrafo',\r
+               links: 'Enlaces',\r
+               insert: 'Insertar',\r
+               styles: 'Estilos',\r
+               colors: 'Colores',\r
+               tools: 'Herramientas'\r
+       },\r
+       toolbars: 'Barras de herramientas del editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/et.js b/sources/plugins/toolbar/lang/et.js
new file mode 100644 (file)
index 0000000..b83473f
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'et', {\r
+       toolbarCollapse: 'Tööriistariba peitmine',\r
+       toolbarExpand: 'Tööriistariba näitamine',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Lõikelaud/tagasivõtmine',\r
+               editing: 'Muutmine',\r
+               forms: 'Vormid',\r
+               basicstyles: 'Põhistiilid',\r
+               paragraph: 'Lõik',\r
+               links: 'Lingid',\r
+               insert: 'Sisesta',\r
+               styles: 'Stiilid',\r
+               colors: 'Värvid',\r
+               tools: 'Tööriistad'\r
+       },\r
+       toolbars: 'Redaktori tööriistaribad'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/eu.js b/sources/plugins/toolbar/lang/eu.js
new file mode 100644 (file)
index 0000000..831d285
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'eu', {\r
+       toolbarCollapse: 'Tolestu tresna-barra',\r
+       toolbarExpand: 'Zabaldu tresna-barra',\r
+       toolbarGroups: {\r
+               document: 'Dokumentua',\r
+               clipboard: 'Arbela/Desegin',\r
+               editing: 'Editatu',\r
+               forms: 'Formularioak',\r
+               basicstyles: 'Oinarrizko estiloak',\r
+               paragraph: 'Paragrafoa',\r
+               links: 'Estekak',\r
+               insert: 'Txertatu',\r
+               styles: 'Estiloak',\r
+               colors: 'Koloreak',\r
+               tools: 'Tresnak'\r
+       },\r
+       toolbars: 'Editorearen tresna-barrak'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/fa.js b/sources/plugins/toolbar/lang/fa.js
new file mode 100644 (file)
index 0000000..2d1bc5d
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'fa', {\r
+       toolbarCollapse: 'بستن نوار ابزار',\r
+       toolbarExpand: 'بازکردن نوار ابزار',\r
+       toolbarGroups: {\r
+               document: 'سند',\r
+               clipboard: 'حافظه موقت/برگشت',\r
+               editing: 'در حال ویرایش',\r
+               forms: 'فرم​ها',\r
+               basicstyles: 'سبک‌های پایه',\r
+               paragraph: 'بند',\r
+               links: 'پیوندها',\r
+               insert: 'ورود',\r
+               styles: 'سبک‌ها',\r
+               colors: 'رنگ​ها',\r
+               tools: 'ابزارها'\r
+       },\r
+       toolbars: 'نوار ابزارهای ویرایش‌گر'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/fi.js b/sources/plugins/toolbar/lang/fi.js
new file mode 100644 (file)
index 0000000..9e12ad4
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'fi', {\r
+       toolbarCollapse: 'Kutista työkalupalkki',\r
+       toolbarExpand: 'Laajenna työkalupalkki',\r
+       toolbarGroups: {\r
+               document: 'Dokumentti',\r
+               clipboard: 'Leikepöytä/Kumoa',\r
+               editing: 'Muokkaus',\r
+               forms: 'Lomakkeet',\r
+               basicstyles: 'Perustyylit',\r
+               paragraph: 'Kappale',\r
+               links: 'Linkit',\r
+               insert: 'Lisää',\r
+               styles: 'Tyylit',\r
+               colors: 'Värit',\r
+               tools: 'Työkalut'\r
+       },\r
+       toolbars: 'Editorin työkalupalkit'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/fo.js b/sources/plugins/toolbar/lang/fo.js
new file mode 100644 (file)
index 0000000..4628b5d
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'fo', {\r
+       toolbarCollapse: 'Lat Toolbar aftur',\r
+       toolbarExpand: 'Vís Toolbar',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editering',\r
+               forms: 'Formar',\r
+               basicstyles: 'Grundleggjandi Styles',\r
+               paragraph: 'Reglubrot',\r
+               links: 'Leinkjur',\r
+               insert: 'Set inn',\r
+               styles: 'Styles',\r
+               colors: 'Litir',\r
+               tools: 'Tól'\r
+       },\r
+       toolbars: 'Editor toolbars'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/fr-ca.js b/sources/plugins/toolbar/lang/fr-ca.js
new file mode 100644 (file)
index 0000000..4aae863
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'fr-ca', {\r
+       toolbarCollapse: 'Enrouler la barre d\'outils',\r
+       toolbarExpand: 'Dérouler la barre d\'outils',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Presse papier/Annuler',\r
+               editing: 'Édition',\r
+               forms: 'Formulaires',\r
+               basicstyles: 'Styles de base',\r
+               paragraph: 'Paragraphe',\r
+               links: 'Liens',\r
+               insert: 'Insérer',\r
+               styles: 'Styles',\r
+               colors: 'Couleurs',\r
+               tools: 'Outils'\r
+       },\r
+       toolbars: 'Barre d\'outils de l\'éditeur'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/fr.js b/sources/plugins/toolbar/lang/fr.js
new file mode 100644 (file)
index 0000000..9861866
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'fr', {\r
+       toolbarCollapse: 'Enrouler la barre d\'outils',\r
+       toolbarExpand: 'Dérouler la barre d\'outils',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Presse-papier/Défaire',\r
+               editing: 'Édition',\r
+               forms: 'Formulaires',\r
+               basicstyles: 'Styles de base',\r
+               paragraph: 'Paragraphe',\r
+               links: 'Liens',\r
+               insert: 'Insérer',\r
+               styles: 'Styles',\r
+               colors: 'Couleurs',\r
+               tools: 'Outils'\r
+       },\r
+       toolbars: 'Barres d\'outils de l\'éditeur'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/gl.js b/sources/plugins/toolbar/lang/gl.js
new file mode 100644 (file)
index 0000000..f81c10a
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'gl', {\r
+       toolbarCollapse: 'Contraer a barra de ferramentas',\r
+       toolbarExpand: 'Expandir a barra de ferramentas',\r
+       toolbarGroups: {\r
+               document: 'Documento',\r
+               clipboard: 'Portapapeis/desfacer',\r
+               editing: 'Edición',\r
+               forms: 'Formularios',\r
+               basicstyles: 'Estilos básicos',\r
+               paragraph: 'Paragrafo',\r
+               links: 'Ligazóns',\r
+               insert: 'Inserir',\r
+               styles: 'Estilos',\r
+               colors: 'Cores',\r
+               tools: 'Ferramentas'\r
+       },\r
+       toolbars: 'Barras de ferramentas do editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/gu.js b/sources/plugins/toolbar/lang/gu.js
new file mode 100644 (file)
index 0000000..f34879b
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'gu', {\r
+       toolbarCollapse: 'ટૂલબાર નાનું કરવું',\r
+       toolbarExpand: 'ટૂલબાર મોટું કરવું',\r
+       toolbarGroups: {\r
+               document: 'દસ્તાવેજ',\r
+               clipboard: 'ક્લિપબોર્ડ/અન',\r
+               editing: 'એડીટ કરવું',\r
+               forms: 'ફોર્મ',\r
+               basicstyles: 'બેસિક્ સ્ટાઇલ',\r
+               paragraph: 'ફકરો',\r
+               links: 'લીંક',\r
+               insert: 'ઉમેરવું',\r
+               styles: 'સ્ટાઇલ',\r
+               colors: 'રંગ',\r
+               tools: 'ટૂલ્સ'\r
+       },\r
+       toolbars: 'એડીટર ટૂલ બાર'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/he.js b/sources/plugins/toolbar/lang/he.js
new file mode 100644 (file)
index 0000000..8e6f343
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'he', {\r
+       toolbarCollapse: 'מזעור סרגל כלים',\r
+       toolbarExpand: 'הרחבת סרגל כלים',\r
+       toolbarGroups: {\r
+               document: 'מסמך',\r
+               clipboard: 'לוח הגזירים (Clipboard)/צעד אחרון',\r
+               editing: 'עריכה',\r
+               forms: 'טפסים',\r
+               basicstyles: 'עיצוב בסיסי',\r
+               paragraph: 'פסקה',\r
+               links: 'קישורים',\r
+               insert: 'הכנסה',\r
+               styles: 'עיצוב',\r
+               colors: 'צבעים',\r
+               tools: 'כלים'\r
+       },\r
+       toolbars: 'סרגלי כלים של העורך'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/hi.js b/sources/plugins/toolbar/lang/hi.js
new file mode 100644 (file)
index 0000000..7693fa1
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'hi', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'एडिटर टूलबार'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/hr.js b/sources/plugins/toolbar/lang/hr.js
new file mode 100644 (file)
index 0000000..1928251
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'hr', {\r
+       toolbarCollapse: 'Smanji alatnu traku',\r
+       toolbarExpand: 'Proširi alatnu traku',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Međuspremnik/Poništi',\r
+               editing: 'Uređivanje',\r
+               forms: 'Forme',\r
+               basicstyles: 'Osnovni stilovi',\r
+               paragraph: 'Paragraf',\r
+               links: 'Veze',\r
+               insert: 'Umetni',\r
+               styles: 'Stilovi',\r
+               colors: 'Boje',\r
+               tools: 'Alatke'\r
+       },\r
+       toolbars: 'Alatne trake uređivača teksta'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/hu.js b/sources/plugins/toolbar/lang/hu.js
new file mode 100644 (file)
index 0000000..fb67175
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'hu', {\r
+       toolbarCollapse: 'Eszköztár összecsukása',\r
+       toolbarExpand: 'Eszköztár szétnyitása',\r
+       toolbarGroups: {\r
+               document: 'Dokumentum',\r
+               clipboard: 'Vágólap/Visszavonás',\r
+               editing: 'Szerkesztés',\r
+               forms: 'Űrlapok',\r
+               basicstyles: 'Alapstílusok',\r
+               paragraph: 'Bekezdés',\r
+               links: 'Hivatkozások',\r
+               insert: 'Beszúrás',\r
+               styles: 'Stílusok',\r
+               colors: 'Színek',\r
+               tools: 'Eszközök'\r
+       },\r
+       toolbars: 'Szerkesztő Eszköztár'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/id.js b/sources/plugins/toolbar/lang/id.js
new file mode 100644 (file)
index 0000000..c993a72
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'id', {\r
+       toolbarCollapse: 'Ciutkan Toolbar',\r
+       toolbarExpand: 'Bentangkan Toolbar',\r
+       toolbarGroups: {\r
+               document: 'Dokumen',\r
+               clipboard: 'Papan klip / Kembalikan perlakuan',\r
+               editing: 'Sunting',\r
+               forms: 'Formulir',\r
+               basicstyles: 'Gaya Dasar',\r
+               paragraph: 'Paragraf',\r
+               links: 'Tautan',\r
+               insert: 'Sisip',\r
+               styles: 'Gaya',\r
+               colors: 'Warna',\r
+               tools: 'Alat'\r
+       },\r
+       toolbars: 'Toolbar Penyunting'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/is.js b/sources/plugins/toolbar/lang/is.js
new file mode 100644 (file)
index 0000000..a5fc159
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'is', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/it.js b/sources/plugins/toolbar/lang/it.js
new file mode 100644 (file)
index 0000000..42099cd
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'it', {\r
+       toolbarCollapse: 'Minimizza Toolbar',\r
+       toolbarExpand: 'Espandi Toolbar',\r
+       toolbarGroups: {\r
+               document: 'Documento',\r
+               clipboard: 'Copia negli appunti/Annulla',\r
+               editing: 'Modifica',\r
+               forms: 'Form',\r
+               basicstyles: 'Stili di base',\r
+               paragraph: 'Paragrafo',\r
+               links: 'Link',\r
+               insert: 'Inserisci',\r
+               styles: 'Stili',\r
+               colors: 'Colori',\r
+               tools: 'Strumenti'\r
+       },\r
+       toolbars: 'Editor toolbar'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ja.js b/sources/plugins/toolbar/lang/ja.js
new file mode 100644 (file)
index 0000000..49bfcd0
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ja', {\r
+       toolbarCollapse: 'ツールバーを閉じる',\r
+       toolbarExpand: 'ツールバーを開く',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: '編集ツールバー'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ka.js b/sources/plugins/toolbar/lang/ka.js
new file mode 100644 (file)
index 0000000..f1a46cb
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ka', {\r
+       toolbarCollapse: 'ხელსაწყოთა ზოლის შეწევა',\r
+       toolbarExpand: 'ხელსაწყოთა ზოლის გამოწევა',\r
+       toolbarGroups: {\r
+               document: 'დოკუმენტი',\r
+               clipboard: 'Clipboard/გაუქმება',\r
+               editing: 'რედაქტირება',\r
+               forms: 'ფორმები',\r
+               basicstyles: 'ძირითადი სტილები',\r
+               paragraph: 'აბზაცი',\r
+               links: 'ბმულები',\r
+               insert: 'ჩასმა',\r
+               styles: 'სტილები',\r
+               colors: 'ფერები',\r
+               tools: 'ხელსაწყოები'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/km.js b/sources/plugins/toolbar/lang/km.js
new file mode 100644 (file)
index 0000000..3b0eb05
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'km', {\r
+       toolbarCollapse: 'បង្រួម​របារ​ឧបករណ៍',\r
+       toolbarExpand: 'ពង្រីក​របារ​ឧបករណ៍',\r
+       toolbarGroups: {\r
+               document: 'ឯកសារ',\r
+               clipboard: 'Clipboard/មិន​ធ្វើ​វិញ',\r
+               editing: 'ការ​កែ​សម្រួល',\r
+               forms: 'បែបបទ',\r
+               basicstyles: 'រចនាបថ​មូលដ្ឋាន',\r
+               paragraph: 'កថាខណ្ឌ',\r
+               links: 'តំណ',\r
+               insert: 'បញ្ចូល',\r
+               styles: 'រចនាបថ',\r
+               colors: 'ពណ៌',\r
+               tools: 'ឧបករណ៍'\r
+       },\r
+       toolbars: 'របារ​ឧបករណ៍​កែ​សម្រួល'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ko.js b/sources/plugins/toolbar/lang/ko.js
new file mode 100644 (file)
index 0000000..dc5a674
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ko', {\r
+       toolbarCollapse: '툴바 줄이기',\r
+       toolbarExpand: '툴바 확장',\r
+       toolbarGroups: {\r
+               document: '문서',\r
+               clipboard: '클립보드/실행 취소',\r
+               editing: '편집',\r
+               forms: '폼',\r
+               basicstyles: '기본 스타일',\r
+               paragraph: '단락',\r
+               links: '링크',\r
+               insert: '삽입',\r
+               styles: '스타일',\r
+               colors: '색상',\r
+               tools: '도구'\r
+       },\r
+       toolbars: '에디터 툴바'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ku.js b/sources/plugins/toolbar/lang/ku.js
new file mode 100644 (file)
index 0000000..02f8f91
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ku', {\r
+       toolbarCollapse: 'شاردنەوی هێڵی تووڵامراز',\r
+       toolbarExpand: 'نیشاندانی هێڵی تووڵامراز',\r
+       toolbarGroups: {\r
+               document: 'پەڕه',\r
+               clipboard: 'بڕین/پووچکردنەوە',\r
+               editing: 'چاکسازی',\r
+               forms: 'داڕشتە',\r
+               basicstyles: 'شێوازی بنچینەیی',\r
+               paragraph: 'بڕگە',\r
+               links: 'بەستەر',\r
+               insert: 'خستنە ناو',\r
+               styles: 'شێواز',\r
+               colors: 'ڕەنگەکان',\r
+               tools: 'ئامرازەکان'\r
+       },\r
+       toolbars: 'تووڵامرازی دەسکاریکەر'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/lt.js b/sources/plugins/toolbar/lang/lt.js
new file mode 100644 (file)
index 0000000..b705d6f
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'lt', {\r
+       toolbarCollapse: 'Apjungti įrankių juostą',\r
+       toolbarExpand: 'Išplėsti įrankių juostą',\r
+       toolbarGroups: {\r
+               document: 'Dokumentas',\r
+               clipboard: 'Atmintinė/Atgal',\r
+               editing: 'Redagavimas',\r
+               forms: 'Formos',\r
+               basicstyles: 'Pagrindiniai stiliai',\r
+               paragraph: 'Paragrafas',\r
+               links: 'Nuorodos',\r
+               insert: 'Įterpti',\r
+               styles: 'Stiliai',\r
+               colors: 'Spalvos',\r
+               tools: 'Įrankiai'\r
+       },\r
+       toolbars: 'Redaktoriaus įrankiai'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/lv.js b/sources/plugins/toolbar/lang/lv.js
new file mode 100644 (file)
index 0000000..20dd345
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'lv', {\r
+       toolbarCollapse: 'Aizvērt rīkjoslu',\r
+       toolbarExpand: 'Atvērt rīkjoslu',\r
+       toolbarGroups: {\r
+               document: 'Dokuments',\r
+               clipboard: 'Starpliktuve/Atcelt',\r
+               editing: 'Labošana',\r
+               forms: 'Formas',\r
+               basicstyles: 'Pamata stili',\r
+               paragraph: 'Paragrāfs',\r
+               links: 'Saites',\r
+               insert: 'Ievietot',\r
+               styles: 'Stili',\r
+               colors: 'Krāsas',\r
+               tools: 'Rīki'\r
+       },\r
+       toolbars: 'Redaktora rīkjoslas'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/mk.js b/sources/plugins/toolbar/lang/mk.js
new file mode 100644 (file)
index 0000000..e85581d
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'mk', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/mn.js b/sources/plugins/toolbar/lang/mn.js
new file mode 100644 (file)
index 0000000..5aeb46b
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'mn', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Холбоосууд',\r
+               insert: 'Оруулах',\r
+               styles: 'Загварууд',\r
+               colors: 'Онгөнүүд',\r
+               tools: 'Хэрэгслүүд'\r
+       },\r
+       toolbars: 'Болосруулагчийн хэрэгслийн самбар'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ms.js b/sources/plugins/toolbar/lang/ms.js
new file mode 100644 (file)
index 0000000..7b78dc6
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ms', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/nb.js b/sources/plugins/toolbar/lang/nb.js
new file mode 100644 (file)
index 0000000..830143a
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'nb', {\r
+       toolbarCollapse: 'Skjul verktøylinje',\r
+       toolbarExpand: 'Vis verktøylinje',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Utklippstavle/Angre',\r
+               editing: 'Redigering',\r
+               forms: 'Skjema',\r
+               basicstyles: 'Basisstiler',\r
+               paragraph: 'Avsnitt',\r
+               links: 'Lenker',\r
+               insert: 'Innsetting',\r
+               styles: 'Stiler',\r
+               colors: 'Farger',\r
+               tools: 'Verktøy'\r
+       },\r
+       toolbars: 'Verktøylinjer for editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/nl.js b/sources/plugins/toolbar/lang/nl.js
new file mode 100644 (file)
index 0000000..84ac147
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'nl', {\r
+       toolbarCollapse: 'Werkbalk inklappen',\r
+       toolbarExpand: 'Werkbalk uitklappen',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Klembord/Ongedaan maken',\r
+               editing: 'Bewerken',\r
+               forms: 'Formulieren',\r
+               basicstyles: 'Basisstijlen',\r
+               paragraph: 'Paragraaf',\r
+               links: 'Links',\r
+               insert: 'Invoegen',\r
+               styles: 'Stijlen',\r
+               colors: 'Kleuren',\r
+               tools: 'Toepassingen'\r
+       },\r
+       toolbars: 'Werkbalken'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/no.js b/sources/plugins/toolbar/lang/no.js
new file mode 100644 (file)
index 0000000..c1a3445
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'no', {\r
+       toolbarCollapse: 'Skjul verktøylinje',\r
+       toolbarExpand: 'Vis verktøylinje',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Utklippstavle/Angre',\r
+               editing: 'Redigering',\r
+               forms: 'Skjema',\r
+               basicstyles: 'Basisstiler',\r
+               paragraph: 'Avsnitt',\r
+               links: 'Lenker',\r
+               insert: 'Innsetting',\r
+               styles: 'Stiler',\r
+               colors: 'Farger',\r
+               tools: 'Verktøy'\r
+       },\r
+       toolbars: 'Verktøylinjer for editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/oc.js b/sources/plugins/toolbar/lang/oc.js
new file mode 100644 (file)
index 0000000..bfd8044
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'oc', {\r
+       toolbarCollapse: 'Enrotlar la barra d\'aisinas',\r
+       toolbarExpand: 'Desenrotlar la barra d\'aisinas',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Quichapapièr/Desfar',\r
+               editing: 'Edicion',\r
+               forms: 'Formularis',\r
+               basicstyles: 'Estils de basa',\r
+               paragraph: 'Paragraf',\r
+               links: 'Ligams',\r
+               insert: 'Inserir',\r
+               styles: 'Estils',\r
+               colors: 'Colors',\r
+               tools: 'Aisinas'\r
+       },\r
+       toolbars: 'Barras d\'aisinas de l\'editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/pl.js b/sources/plugins/toolbar/lang/pl.js
new file mode 100644 (file)
index 0000000..07571c9
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'pl', {\r
+       toolbarCollapse: 'Zwiń pasek narzędzi',\r
+       toolbarExpand: 'Rozwiń pasek narzędzi',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Schowek/Wstecz',\r
+               editing: 'Edycja',\r
+               forms: 'Formularze',\r
+               basicstyles: 'Style podstawowe',\r
+               paragraph: 'Akapit',\r
+               links: 'Hiperłącza',\r
+               insert: 'Wstawianie',\r
+               styles: 'Style',\r
+               colors: 'Kolory',\r
+               tools: 'Narzędzia'\r
+       },\r
+       toolbars: 'Paski narzędzi edytora'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/pt-br.js b/sources/plugins/toolbar/lang/pt-br.js
new file mode 100644 (file)
index 0000000..c897bef
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'pt-br', {\r
+       toolbarCollapse: 'Diminuir Barra de Ferramentas',\r
+       toolbarExpand: 'Aumentar Barra de Ferramentas',\r
+       toolbarGroups: {\r
+               document: 'Documento',\r
+               clipboard: 'Clipboard/Desfazer',\r
+               editing: 'Edição',\r
+               forms: 'Formulários',\r
+               basicstyles: 'Estilos Básicos',\r
+               paragraph: 'Paragrafo',\r
+               links: 'Links',\r
+               insert: 'Inserir',\r
+               styles: 'Estilos',\r
+               colors: 'Cores',\r
+               tools: 'Ferramentas'\r
+       },\r
+       toolbars: 'Barra de Ferramentas do Editor'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/pt.js b/sources/plugins/toolbar/lang/pt.js
new file mode 100644 (file)
index 0000000..d684ede
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'pt', {\r
+       toolbarCollapse: 'Ocultar barra de ferramentas',\r
+       toolbarExpand: 'Expandir barra de ferramentas',\r
+       toolbarGroups: {\r
+               document: 'Documento',\r
+               clipboard: 'Área de transferência/Anular',\r
+               editing: 'Edição',\r
+               forms: 'Formulários',\r
+               basicstyles: 'Estilos básicos',\r
+               paragraph: 'Parágrafo',\r
+               links: 'Hiperligações',\r
+               insert: 'Inserir',\r
+               styles: 'Estilos',\r
+               colors: 'Cores',\r
+               tools: 'Ferramentas'\r
+       },\r
+       toolbars: 'Editor de barras de ferramentas'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ro.js b/sources/plugins/toolbar/lang/ro.js
new file mode 100644 (file)
index 0000000..cb1b1e1
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ro', {\r
+       toolbarCollapse: 'Micșorează Bara',\r
+       toolbarExpand: 'Mărește Bara',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Editează bara de unelte'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ru.js b/sources/plugins/toolbar/lang/ru.js
new file mode 100644 (file)
index 0000000..88f9462
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ru', {\r
+       toolbarCollapse: 'Свернуть панель инструментов',\r
+       toolbarExpand: 'Развернуть панель инструментов',\r
+       toolbarGroups: {\r
+               document: 'Документ',\r
+               clipboard: 'Буфер обмена / Отмена действий',\r
+               editing: 'Корректировка',\r
+               forms: 'Формы',\r
+               basicstyles: 'Простые стили',\r
+               paragraph: 'Абзац',\r
+               links: 'Ссылки',\r
+               insert: 'Вставка',\r
+               styles: 'Стили',\r
+               colors: 'Цвета',\r
+               tools: 'Инструменты'\r
+       },\r
+       toolbars: 'Панели инструментов редактора'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/si.js b/sources/plugins/toolbar/lang/si.js
new file mode 100644 (file)
index 0000000..b57a088
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'si', {\r
+       toolbarCollapse: 'මෙවලම් තීරුව හැකුලුම.',\r
+       toolbarExpand: 'මෙවලම් තීරුව දීගහැරුම',\r
+       toolbarGroups: {\r
+               document: 'ලිපිය',\r
+               clipboard: 'ඇමිණුම වෙනස් කිරීම',\r
+               editing: 'සංස්කරණය',\r
+               forms: 'පෝරමය',\r
+               basicstyles: 'මුලික විලාසය',\r
+               paragraph: 'චේදය',\r
+               links: 'සබැඳිය',\r
+               insert: 'ඇතුලත් කිරීම',\r
+               styles: 'විලාසය',\r
+               colors: 'වර්ණය',\r
+               tools: 'මෙවලම්'\r
+       },\r
+       toolbars: 'සංස්කරණ මෙවලම් තීරුව'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sk.js b/sources/plugins/toolbar/lang/sk.js
new file mode 100644 (file)
index 0000000..fc9f3db
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sk', {\r
+       toolbarCollapse: 'Zbaliť lištu nástrojov',\r
+       toolbarExpand: 'Rozbaliť lištu nástrojov',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Schránka pre kopírovanie/Späť',\r
+               editing: 'Upravovanie',\r
+               forms: 'Formuláre',\r
+               basicstyles: 'Základné štýly',\r
+               paragraph: 'Odsek',\r
+               links: 'Odkazy',\r
+               insert: 'Vložiť',\r
+               styles: 'Štýly',\r
+               colors: 'Farby',\r
+               tools: 'Nástroje'\r
+       },\r
+       toolbars: 'Lišty nástrojov editora'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sl.js b/sources/plugins/toolbar/lang/sl.js
new file mode 100644 (file)
index 0000000..b17eee4
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sl', {\r
+       toolbarCollapse: 'Skrči orodno vrstico',\r
+       toolbarExpand: 'Razširi orodno vrstico',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Odložišče/Razveljavi',\r
+               editing: 'Urejanje',\r
+               forms: 'Obrazci',\r
+               basicstyles: 'Osnovni slogi',\r
+               paragraph: 'Odstavek',\r
+               links: 'Povezave',\r
+               insert: 'Vstavi',\r
+               styles: 'Slogi',\r
+               colors: 'Barve',\r
+               tools: 'Orodja'\r
+       },\r
+       toolbars: 'Orodne vrstice urejevalnika'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sq.js b/sources/plugins/toolbar/lang/sq.js
new file mode 100644 (file)
index 0000000..0ca8add
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sq', {\r
+       toolbarCollapse: 'Zvogëlo Shiritin',\r
+       toolbarExpand: 'Zgjero Shiritin',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Tabela Punës/Ribëje',\r
+               editing: 'Duke Redaktuar',\r
+               forms: 'Formular',\r
+               basicstyles: 'Stili Bazë',\r
+               paragraph: 'Paragraf',\r
+               links: 'Nyjet',\r
+               insert: 'Shto',\r
+               styles: 'Stil',\r
+               colors: 'Ngjyrat',\r
+               tools: 'Mjetet'\r
+       },\r
+       toolbars: 'Shiritet e Redaktuesit'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sr-latn.js b/sources/plugins/toolbar/lang/sr-latn.js
new file mode 100644 (file)
index 0000000..d746aac
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sr-latn', {\r
+       toolbarCollapse: 'Suzi alatnu traku',\r
+       toolbarExpand: 'Proširi alatnu traku',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Alatne trake'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sr.js b/sources/plugins/toolbar/lang/sr.js
new file mode 100644 (file)
index 0000000..d02f20f
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sr', {\r
+       toolbarCollapse: 'Склопи алатну траку',\r
+       toolbarExpand: 'Прошири алатну траку',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'Едитор алатне траке'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/sv.js b/sources/plugins/toolbar/lang/sv.js
new file mode 100644 (file)
index 0000000..0a45e88
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'sv', {\r
+       toolbarCollapse: 'Dölj verktygsfält',\r
+       toolbarExpand: 'Visa verktygsfält',\r
+       toolbarGroups: {\r
+               document: 'Dokument',\r
+               clipboard: 'Urklipp/ångra',\r
+               editing: 'Redigering',\r
+               forms: 'Formulär',\r
+               basicstyles: 'Basstilar',\r
+               paragraph: 'Paragraf',\r
+               links: 'Länkar',\r
+               insert: 'Infoga',\r
+               styles: 'Stilar',\r
+               colors: 'Färger',\r
+               tools: 'Verktyg'\r
+       },\r
+       toolbars: 'Editorns verktygsfält'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/th.js b/sources/plugins/toolbar/lang/th.js
new file mode 100644 (file)
index 0000000..c4ae55e
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'th', {\r
+       toolbarCollapse: 'ซ่อนแถบเครื่องมือ',\r
+       toolbarExpand: 'เปิดแถบเครื่องมือ',\r
+       toolbarGroups: {\r
+               document: 'Document',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Editing',\r
+               forms: 'Forms',\r
+               basicstyles: 'Basic Styles',\r
+               paragraph: 'Paragraph',\r
+               links: 'Links',\r
+               insert: 'Insert',\r
+               styles: 'Styles',\r
+               colors: 'Colors',\r
+               tools: 'Tools'\r
+       },\r
+       toolbars: 'แถบเครื่องมือช่วยพิมพ์ข้อความ'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/tr.js b/sources/plugins/toolbar/lang/tr.js
new file mode 100644 (file)
index 0000000..cf7f944
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'tr', {\r
+       toolbarCollapse: 'Araç çubuklarını topla',\r
+       toolbarExpand: 'Araç çubuklarını aç',\r
+       toolbarGroups: {\r
+               document: 'Belge',\r
+               clipboard: 'Pano/Geri al',\r
+               editing: 'Düzenleme',\r
+               forms: 'Formlar',\r
+               basicstyles: 'Temel Stiller',\r
+               paragraph: 'Paragraf',\r
+               links: 'Bağlantılar',\r
+               insert: 'Ekle',\r
+               styles: 'Stiller',\r
+               colors: 'Renkler',\r
+               tools: 'Araçlar'\r
+       },\r
+       toolbars: 'Araç çubukları Editörü'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/tt.js b/sources/plugins/toolbar/lang/tt.js
new file mode 100644 (file)
index 0000000..8eb0542
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'tt', {\r
+       toolbarCollapse: 'Collapse Toolbar', // MISSING\r
+       toolbarExpand: 'Expand Toolbar', // MISSING\r
+       toolbarGroups: {\r
+               document: 'Документ',\r
+               clipboard: 'Алмашу буферы/Кайтару',\r
+               editing: 'Төзәтү',\r
+               forms: 'Формалар',\r
+               basicstyles: 'Төп стильләр',\r
+               paragraph: 'Параграф',\r
+               links: 'Сылталамалар',\r
+               insert: 'Өстәү',\r
+               styles: 'Стильләр',\r
+               colors: 'Төсләр',\r
+               tools: 'Кораллар'\r
+       },\r
+       toolbars: 'Editor toolbars' // MISSING\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/ug.js b/sources/plugins/toolbar/lang/ug.js
new file mode 100644 (file)
index 0000000..95c7c1b
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'ug', {\r
+       toolbarCollapse: 'قورال بالداقنى قاتلا',\r
+       toolbarExpand: 'قورال بالداقنى ياي',\r
+       toolbarGroups: {\r
+               document: 'پۈتۈك',\r
+               clipboard: 'چاپلاش تاختىسى/يېنىۋال',\r
+               editing: 'تەھرىر',\r
+               forms: 'جەدۋەل',\r
+               basicstyles: 'ئاساسىي ئۇسلۇب',\r
+               paragraph: 'ئابزاس',\r
+               links: 'ئۇلانما',\r
+               insert: 'قىستۇر',\r
+               styles: 'ئۇسلۇب',\r
+               colors: 'رەڭ',\r
+               tools: 'قورال'\r
+       },\r
+       toolbars: 'قورال بالداق'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/uk.js b/sources/plugins/toolbar/lang/uk.js
new file mode 100644 (file)
index 0000000..3f1f1c7
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'uk', {\r
+       toolbarCollapse: 'Згорнути панель інструментів',\r
+       toolbarExpand: 'Розгорнути панель інструментів',\r
+       toolbarGroups: {\r
+               document: 'Документ',\r
+               clipboard: 'Буфер обміну / Скасувати',\r
+               editing: 'Редагування',\r
+               forms: 'Форми',\r
+               basicstyles: 'Основний Стиль',\r
+               paragraph: 'Параграф',\r
+               links: 'Посилання',\r
+               insert: 'Вставити',\r
+               styles: 'Стилі',\r
+               colors: 'Кольори',\r
+               tools: 'Інструменти'\r
+       },\r
+       toolbars: 'Панель інструментів редактора'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/vi.js b/sources/plugins/toolbar/lang/vi.js
new file mode 100644 (file)
index 0000000..8ff76fd
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'vi', {\r
+       toolbarCollapse: 'Thu gọn thanh công cụ',\r
+       toolbarExpand: 'Mở rộng thnah công cụ',\r
+       toolbarGroups: {\r
+               document: 'Tài liệu',\r
+               clipboard: 'Clipboard/Undo',\r
+               editing: 'Chỉnh sửa',\r
+               forms: 'Bảng biểu',\r
+               basicstyles: 'Kiểu cơ bản',\r
+               paragraph: 'Đoạn',\r
+               links: 'Liên kết',\r
+               insert: 'Chèn',\r
+               styles: 'Kiểu',\r
+               colors: 'Màu sắc',\r
+               tools: 'Công cụ'\r
+       },\r
+       toolbars: 'Thanh công cụ'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/zh-cn.js b/sources/plugins/toolbar/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..6c3a5ed
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'zh-cn', {\r
+       toolbarCollapse: '折叠工具栏',\r
+       toolbarExpand: '展开工具栏',\r
+       toolbarGroups: {\r
+               document: '文档',\r
+               clipboard: '剪贴板/撤销',\r
+               editing: '编辑',\r
+               forms: '表单',\r
+               basicstyles: '基本格式',\r
+               paragraph: '段落',\r
+               links: '链接',\r
+               insert: '插入',\r
+               styles: '样式',\r
+               colors: '颜色',\r
+               tools: '工具'\r
+       },\r
+       toolbars: '工具栏'\r
+} );\r
diff --git a/sources/plugins/toolbar/lang/zh.js b/sources/plugins/toolbar/lang/zh.js
new file mode 100644 (file)
index 0000000..0a9f5de
--- /dev/null
@@ -0,0 +1,22 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+CKEDITOR.plugins.setLang( 'toolbar', 'zh', {\r
+       toolbarCollapse: '摺疊工具列',\r
+       toolbarExpand: '展開工具列',\r
+       toolbarGroups: {\r
+               document: '文件',\r
+               clipboard: '剪貼簿/復原',\r
+               editing: '編輯選項',\r
+               forms: '格式',\r
+               basicstyles: '基本樣式',\r
+               paragraph: '段落',\r
+               links: '連結',\r
+               insert: '插入',\r
+               styles: '樣式',\r
+               colors: '顏色',\r
+               tools: '工具'\r
+       },\r
+       toolbars: '編輯器工具列'\r
+} );\r
diff --git a/sources/plugins/toolbar/plugin.js b/sources/plugins/toolbar/plugin.js
new file mode 100644 (file)
index 0000000..b267b51
--- /dev/null
@@ -0,0 +1,806 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The "toolbar" plugin. Renders the default toolbar interface in\r
+ * the editor.\r
+ */\r
+\r
+( function() {\r
+       var toolbox = function() {\r
+                       this.toolbars = [];\r
+                       this.focusCommandExecuted = false;\r
+               };\r
+\r
+       toolbox.prototype.focus = function() {\r
+               for ( var t = 0, toolbar; toolbar = this.toolbars[ t++ ]; ) {\r
+                       for ( var i = 0, item; item = toolbar.items[ i++ ]; ) {\r
+                               if ( item.focus ) {\r
+                                       item.focus();\r
+                                       return;\r
+                               }\r
+                       }\r
+               }\r
+       };\r
+\r
+       var commands = {\r
+               toolbarFocus: {\r
+                       modes: { wysiwyg: 1, source: 1 },\r
+                       readOnly: 1,\r
+\r
+                       exec: function( editor ) {\r
+                               if ( editor.toolbox ) {\r
+                                       editor.toolbox.focusCommandExecuted = true;\r
+\r
+                                       // Make the first button focus accessible for IE. (#3417)\r
+                                       // Adobe AIR instead need while of delay.\r
+                                       if ( CKEDITOR.env.ie || CKEDITOR.env.air ) {\r
+                                               setTimeout( function() {\r
+                                                       editor.toolbox.focus();\r
+                                               }, 100 );\r
+                                       } else {\r
+                                               editor.toolbox.focus();\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+       };\r
+\r
+       CKEDITOR.plugins.add( 'toolbar', {\r
+               requires: 'button',\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,bn,bs,ca,cs,cy,da,de,de-ch,el,en,en-au,en-ca,en-gb,eo,es,et,eu,fa,fi,fo,fr,fr-ca,gl,gu,he,hi,hr,hu,id,is,it,ja,ka,km,ko,ku,lt,lv,mk,mn,ms,nb,nl,no,oc,pl,pt,pt-br,ro,ru,si,sk,sl,sq,sr,sr-latn,sv,th,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+\r
+               init: function( editor ) {\r
+                       var endFlag;\r
+\r
+                       var itemKeystroke = function( item, keystroke ) {\r
+                                       var next, toolbar;\r
+                                       var rtl = editor.lang.dir == 'rtl',\r
+                                               toolbarGroupCycling = editor.config.toolbarGroupCycling,\r
+                                               // Picking right/left key codes.\r
+                                               rightKeyCode = rtl ? 37 : 39,\r
+                                               leftKeyCode = rtl ? 39 : 37;\r
+\r
+                                       toolbarGroupCycling = toolbarGroupCycling === undefined || toolbarGroupCycling;\r
+\r
+                                       switch ( keystroke ) {\r
+                                               case 9: // TAB\r
+                                               case CKEDITOR.SHIFT + 9: // SHIFT + TAB\r
+                                                       // Cycle through the toolbars, starting from the one\r
+                                                       // closest to the current item.\r
+                                                       while ( !toolbar || !toolbar.items.length ) {\r
+                                                               if ( keystroke == 9 ) {\r
+                                                                       toolbar = ( ( toolbar ? toolbar.next : item.toolbar.next ) || editor.toolbox.toolbars[ 0 ] );\r
+                                                               } else {\r
+                                                                       toolbar = ( ( toolbar ? toolbar.previous : item.toolbar.previous ) || editor.toolbox.toolbars[ editor.toolbox.toolbars.length - 1 ] );\r
+                                                               }\r
+\r
+                                                               // Look for the first item that accepts focus.\r
+                                                               if ( toolbar.items.length ) {\r
+                                                                       item = toolbar.items[ endFlag ? ( toolbar.items.length - 1 ) : 0 ];\r
+                                                                       while ( item && !item.focus ) {\r
+                                                                               item = endFlag ? item.previous : item.next;\r
+\r
+                                                                               if ( !item )\r
+                                                                                       toolbar = 0;\r
+                                                                       }\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       if ( item )\r
+                                                               item.focus();\r
+\r
+                                                       return false;\r
+\r
+                                               case rightKeyCode:\r
+                                                       next = item;\r
+                                                       do {\r
+                                                               // Look for the next item in the toolbar.\r
+                                                               next = next.next;\r
+\r
+                                                               // If it's the last item, cycle to the first one.\r
+                                                               if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ 0 ];\r
+                                                       }\r
+                                                       while ( next && !next.focus );\r
+\r
+                                                       // If available, just focus it, otherwise focus the\r
+                                                       // first one.\r
+                                                       if ( next )\r
+                                                               next.focus();\r
+                                                       else\r
+                                                               // Send a TAB.\r
+                                                               itemKeystroke( item, 9 );\r
+\r
+                                                       return false;\r
+                                               case 40: // DOWN-ARROW\r
+                                                       if ( item.button && item.button.hasArrow ) {\r
+                                                               // Note: code is duplicated in plugins\richcombo\plugin.js in keyDownFn().\r
+                                                               editor.once( 'panelShow', function( evt ) {\r
+                                                                       evt.data._.panel._.currentBlock.onKeyDown( 40 );\r
+                                                               } );\r
+                                                               item.execute();\r
+                                                       } else {\r
+                                                               // Send left arrow key.\r
+                                                               itemKeystroke( item, keystroke == 40 ? rightKeyCode : leftKeyCode );\r
+                                                       }\r
+                                                       return false;\r
+                                               case leftKeyCode:\r
+                                               case 38: // UP-ARROW\r
+                                                       next = item;\r
+                                                       do {\r
+                                                               // Look for the previous item in the toolbar.\r
+                                                               next = next.previous;\r
+\r
+                                                               // If it's the first item, cycle to the last one.\r
+                                                               if ( !next && toolbarGroupCycling ) next = item.toolbar.items[ item.toolbar.items.length - 1 ];\r
+                                                       }\r
+                                                       while ( next && !next.focus );\r
+\r
+                                                       // If available, just focus it, otherwise focus the\r
+                                                       // last one.\r
+                                                       if ( next )\r
+                                                               next.focus();\r
+                                                       else {\r
+                                                               endFlag = 1;\r
+                                                               // Send a SHIFT + TAB.\r
+                                                               itemKeystroke( item, CKEDITOR.SHIFT + 9 );\r
+                                                               endFlag = 0;\r
+                                                       }\r
+\r
+                                                       return false;\r
+\r
+                                               case 27: // ESC\r
+                                                       editor.focus();\r
+                                                       return false;\r
+\r
+                                               case 13: // ENTER\r
+                                               case 32: // SPACE\r
+                                                       item.execute();\r
+                                                       return false;\r
+                                       }\r
+                                       return true;\r
+                               };\r
+\r
+                       editor.on( 'uiSpace', function( event ) {\r
+                               if ( event.data.space != editor.config.toolbarLocation )\r
+                                       return;\r
+\r
+                               // Create toolbar only once.\r
+                               event.removeListener();\r
+\r
+                               editor.toolbox = new toolbox();\r
+\r
+                               var labelId = CKEDITOR.tools.getNextId();\r
+\r
+                               var output = [\r
+                                       '<span id="', labelId, '" class="cke_voice_label">', editor.lang.toolbar.toolbars, '</span>',\r
+                                       '<span id="' + editor.ui.spaceId( 'toolbox' ) + '" class="cke_toolbox" role="group" aria-labelledby="', labelId, '" onmousedown="return false;">'\r
+                               ];\r
+\r
+                               var expanded = editor.config.toolbarStartupExpanded !== false,\r
+                                       groupStarted, pendingSeparator;\r
+\r
+                               // If the toolbar collapser will be available, we'll have\r
+                               // an additional container for all toolbars.\r
+                               if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE )\r
+                                       output.push( '<span class="cke_toolbox_main"' + ( expanded ? '>' : ' style="display:none">' ) );\r
+\r
+                               var toolbars = editor.toolbox.toolbars,\r
+                                       toolbar = getToolbarConfig( editor ),\r
+                                       toolbarLength = toolbar.length;\r
+\r
+                               for ( var r = 0; r < toolbarLength; r++ ) {\r
+                                       var toolbarId,\r
+                                               toolbarObj = 0,\r
+                                               toolbarName,\r
+                                               row = toolbar[ r ],\r
+                                               lastToolbarInRow = row !== '/' && ( toolbar[ r + 1 ] === '/' || r == toolbarLength - 1 ),\r
+                                               items;\r
+\r
+                                       // It's better to check if the row object is really\r
+                                       // available because it's a common mistake to leave\r
+                                       // an extra comma in the toolbar definition\r
+                                       // settings, which leads on the editor not loading\r
+                                       // at all in IE. (#3983)\r
+                                       if ( !row )\r
+                                               continue;\r
+\r
+                                       if ( groupStarted ) {\r
+                                               output.push( '</span>' );\r
+                                               groupStarted = 0;\r
+                                               pendingSeparator = 0;\r
+                                       }\r
+\r
+                                       if ( row === '/' ) {\r
+                                               output.push( '<span class="cke_toolbar_break"></span>' );\r
+                                               continue;\r
+                                       }\r
+\r
+                                       items = row.items || row;\r
+\r
+                                       // Create all items defined for this toolbar.\r
+                                       for ( var i = 0; i < items.length; i++ ) {\r
+                                               var item = items[ i ],\r
+                                                       canGroup;\r
+\r
+                                               if ( item ) {\r
+                                                       if ( item.type == CKEDITOR.UI_SEPARATOR ) {\r
+                                                               // Do not add the separator immediately. Just save\r
+                                                               // it be included if we already have something in\r
+                                                               // the toolbar and if a new item is to be added (later).\r
+                                                               pendingSeparator = groupStarted && item;\r
+                                                               continue;\r
+                                                       }\r
+\r
+                                                       canGroup = item.canGroup !== false;\r
+\r
+                                                       // Initialize the toolbar first, if needed.\r
+                                                       if ( !toolbarObj ) {\r
+                                                               // Create the basic toolbar object.\r
+                                                               toolbarId = CKEDITOR.tools.getNextId();\r
+                                                               toolbarObj = { id: toolbarId, items: [] };\r
+                                                               toolbarName = row.name && ( editor.lang.toolbar.toolbarGroups[ row.name ] || row.name );\r
+\r
+                                                               // Output the toolbar opener.\r
+                                                               output.push( '<span id="', toolbarId, '" class="cke_toolbar' + ( lastToolbarInRow ? ' cke_toolbar_last"' : '"' ),\r
+                                                                       ( toolbarName ? ' aria-labelledby="' + toolbarId + '_label"' : '' ), ' role="toolbar">' );\r
+\r
+                                                               // If a toolbar name is available, send the voice label.\r
+                                                               toolbarName && output.push( '<span id="', toolbarId, '_label" class="cke_voice_label">', toolbarName, '</span>' );\r
+\r
+                                                               output.push( '<span class="cke_toolbar_start"></span>' );\r
+\r
+                                                               // Add the toolbar to the "editor.toolbox.toolbars"\r
+                                                               // array.\r
+                                                               var index = toolbars.push( toolbarObj ) - 1;\r
+\r
+                                                               // Create the next/previous reference.\r
+                                                               if ( index > 0 ) {\r
+                                                                       toolbarObj.previous = toolbars[ index - 1 ];\r
+                                                                       toolbarObj.previous.next = toolbarObj;\r
+                                                               }\r
+                                                       }\r
+\r
+                                                       if ( canGroup ) {\r
+                                                               if ( !groupStarted ) {\r
+                                                                       output.push( '<span class="cke_toolgroup" role="presentation">' );\r
+                                                                       groupStarted = 1;\r
+                                                               }\r
+                                                       } else if ( groupStarted ) {\r
+                                                               output.push( '</span>' );\r
+                                                               groupStarted = 0;\r
+                                                       }\r
+\r
+                                                       function addItem( item ) { // jshint ignore:line\r
+                                                               var itemObj = item.render( editor, output );\r
+                                                               index = toolbarObj.items.push( itemObj ) - 1;\r
+\r
+                                                               if ( index > 0 ) {\r
+                                                                       itemObj.previous = toolbarObj.items[ index - 1 ];\r
+                                                                       itemObj.previous.next = itemObj;\r
+                                                               }\r
+\r
+                                                               itemObj.toolbar = toolbarObj;\r
+                                                               itemObj.onkey = itemKeystroke;\r
+\r
+                                                               // Fix for #3052:\r
+                                                               // Prevent JAWS from focusing the toolbar after document load.\r
+                                                               itemObj.onfocus = function() {\r
+                                                                       if ( !editor.toolbox.focusCommandExecuted )\r
+                                                                               editor.focus();\r
+                                                               };\r
+                                                       }\r
+\r
+                                                       if ( pendingSeparator ) {\r
+                                                               addItem( pendingSeparator );\r
+                                                               pendingSeparator = 0;\r
+                                                       }\r
+\r
+                                                       addItem( item );\r
+                                               }\r
+                                       }\r
+\r
+                                       if ( groupStarted ) {\r
+                                               output.push( '</span>' );\r
+                                               groupStarted = 0;\r
+                                               pendingSeparator = 0;\r
+                                       }\r
+\r
+                                       if ( toolbarObj )\r
+                                               output.push( '<span class="cke_toolbar_end"></span></span>' );\r
+                               }\r
+\r
+                               if ( editor.config.toolbarCanCollapse )\r
+                                       output.push( '</span>' );\r
+\r
+                               // Not toolbar collapser for inline mode.\r
+                               if ( editor.config.toolbarCanCollapse && editor.elementMode != CKEDITOR.ELEMENT_MODE_INLINE ) {\r
+                                       var collapserFn = CKEDITOR.tools.addFunction( function() {\r
+                                               editor.execCommand( 'toolbarCollapse' );\r
+                                       } );\r
+\r
+                                       editor.on( 'destroy', function() {\r
+                                               CKEDITOR.tools.removeFunction( collapserFn );\r
+                                       } );\r
+\r
+                                       editor.addCommand( 'toolbarCollapse', {\r
+                                               readOnly: 1,\r
+                                               exec: function( editor ) {\r
+                                                       var collapser = editor.ui.space( 'toolbar_collapser' ),\r
+                                                               toolbox = collapser.getPrevious(),\r
+                                                               contents = editor.ui.space( 'contents' ),\r
+                                                               toolboxContainer = toolbox.getParent(),\r
+                                                               contentHeight = parseInt( contents.$.style.height, 10 ),\r
+                                                               previousHeight = toolboxContainer.$.offsetHeight,\r
+                                                               minClass = 'cke_toolbox_collapser_min',\r
+                                                               collapsed = collapser.hasClass( minClass );\r
+\r
+                                                       if ( !collapsed ) {\r
+                                                               toolbox.hide();\r
+                                                               collapser.addClass( minClass );\r
+                                                               collapser.setAttribute( 'title', editor.lang.toolbar.toolbarExpand );\r
+                                                       } else {\r
+                                                               toolbox.show();\r
+                                                               collapser.removeClass( minClass );\r
+                                                               collapser.setAttribute( 'title', editor.lang.toolbar.toolbarCollapse );\r
+                                                       }\r
+\r
+                                                       // Update collapser symbol.\r
+                                                       collapser.getFirst().setText( collapsed ? '\u25B2' : // BLACK UP-POINTING TRIANGLE\r
+                                                       '\u25C0' ); // BLACK LEFT-POINTING TRIANGLE\r
+\r
+                                                       var dy = toolboxContainer.$.offsetHeight - previousHeight;\r
+                                                       contents.setStyle( 'height', ( contentHeight - dy ) + 'px' );\r
+\r
+                                                       editor.fire( 'resize', {\r
+                                                               outerHeight: editor.container.$.offsetHeight,\r
+                                                               contentsHeight: contents.$.offsetHeight,\r
+                                                               outerWidth: editor.container.$.offsetWidth\r
+                                                       } );\r
+                                               },\r
+\r
+                                               modes: { wysiwyg: 1, source: 1 }\r
+                                       } );\r
+\r
+                                       editor.setKeystroke( CKEDITOR.ALT + ( CKEDITOR.env.ie || CKEDITOR.env.webkit ? 189 : 109 ) /*-*/, 'toolbarCollapse' );\r
+\r
+                                       output.push( '<a title="' + ( expanded ? editor.lang.toolbar.toolbarCollapse : editor.lang.toolbar.toolbarExpand ) +\r
+                                               '" id="' + editor.ui.spaceId( 'toolbar_collapser' ) +\r
+                                               '" tabIndex="-1" class="cke_toolbox_collapser' );\r
+\r
+                                       if ( !expanded )\r
+                                               output.push( ' cke_toolbox_collapser_min' );\r
+\r
+                                       output.push( '" onclick="CKEDITOR.tools.callFunction(' + collapserFn + ')">', '<span class="cke_arrow">&#9650;</span>', // BLACK UP-POINTING TRIANGLE\r
+                                               '</a>' );\r
+                               }\r
+\r
+                               output.push( '</span>' );\r
+                               event.data.html += output.join( '' );\r
+                       } );\r
+\r
+                       editor.on( 'destroy', function() {\r
+                               if ( this.toolbox ) {\r
+                                       var toolbars,\r
+                                               index = 0,\r
+                                               i, items, instance;\r
+                                       toolbars = this.toolbox.toolbars;\r
+                                       for ( ; index < toolbars.length; index++ ) {\r
+                                               items = toolbars[ index ].items;\r
+                                               for ( i = 0; i < items.length; i++ ) {\r
+                                                       instance = items[ i ];\r
+                                                       if ( instance.clickFn )\r
+                                                               CKEDITOR.tools.removeFunction( instance.clickFn );\r
+                                                       if ( instance.keyDownFn )\r
+                                                               CKEDITOR.tools.removeFunction( instance.keyDownFn );\r
+                                               }\r
+                                       }\r
+                               }\r
+                       } );\r
+\r
+                       // Manage editor focus  when navigating the toolbar.\r
+                       editor.on( 'uiReady', function() {\r
+                               var toolbox = editor.ui.space( 'toolbox' );\r
+                               toolbox && editor.focusManager.add( toolbox, 1 );\r
+                       } );\r
+\r
+                       editor.addCommand( 'toolbarFocus', commands.toolbarFocus );\r
+                       editor.setKeystroke( CKEDITOR.ALT + 121 /*F10*/, 'toolbarFocus' );\r
+\r
+                       editor.ui.add( '-', CKEDITOR.UI_SEPARATOR, {} );\r
+                       editor.ui.addHandler( CKEDITOR.UI_SEPARATOR, {\r
+                               create: function() {\r
+                                       return {\r
+                                               render: function( editor, output ) {\r
+                                                       output.push( '<span class="cke_toolbar_separator" role="separator"></span>' );\r
+                                                       return {};\r
+                                               }\r
+                                       };\r
+                               }\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       function getToolbarConfig( editor ) {\r
+               var removeButtons = editor.config.removeButtons;\r
+\r
+               removeButtons = removeButtons && removeButtons.split( ',' );\r
+\r
+               function buildToolbarConfig() {\r
+\r
+                       // Object containing all toolbar groups used by ui items.\r
+                       var lookup = getItemDefinedGroups();\r
+\r
+                       // Take the base for the new toolbar, which is basically a toolbar\r
+                       // definition without items.\r
+                       var toolbar = CKEDITOR.tools.clone( editor.config.toolbarGroups ) || getPrivateToolbarGroups( editor );\r
+\r
+                       // Fill the toolbar groups with the available ui items.\r
+                       for ( var i = 0; i < toolbar.length; i++ ) {\r
+                               var toolbarGroup = toolbar[ i ];\r
+\r
+                               // Skip toolbar break.\r
+                               if ( toolbarGroup == '/' )\r
+                                       continue;\r
+                               // Handle simply group name item.\r
+                               else if ( typeof toolbarGroup == 'string' )\r
+                                       toolbarGroup = toolbar[ i ] = { name: toolbarGroup };\r
+\r
+                               var items, subGroups = toolbarGroup.groups;\r
+\r
+                               // Look for items that match sub groups.\r
+                               if ( subGroups ) {\r
+                                       for ( var j = 0, sub; j < subGroups.length; j++ ) {\r
+                                               sub = subGroups[ j ];\r
+\r
+                                               // If any ui item is registered for this subgroup.\r
+                                               items = lookup[ sub ];\r
+                                               items && fillGroup( toolbarGroup, items );\r
+                                       }\r
+                               }\r
+\r
+                               // Add the main group items as well.\r
+                               items = lookup[ toolbarGroup.name ];\r
+                               items && fillGroup( toolbarGroup, items );\r
+                       }\r
+\r
+                       return toolbar;\r
+               }\r
+\r
+               // Returns an object containing all toolbar groups used by ui items.\r
+               function getItemDefinedGroups() {\r
+                       var groups = {},\r
+                               itemName, item, itemToolbar, group, order;\r
+\r
+                       for ( itemName in editor.ui.items ) {\r
+                               item = editor.ui.items[ itemName ];\r
+                               itemToolbar = item.toolbar || 'others';\r
+                               if ( itemToolbar ) {\r
+                                       // Break the toolbar property into its parts: "group_name[,order]".\r
+                                       itemToolbar = itemToolbar.split( ',' );\r
+                                       group = itemToolbar[ 0 ];\r
+                                       order = parseInt( itemToolbar[ 1 ] || -1, 10 );\r
+\r
+                                       // Initialize the group, if necessary.\r
+                                       groups[ group ] || ( groups[ group ] = [] );\r
+\r
+                                       // Push the data used to build the toolbar later.\r
+                                       groups[ group ].push( { name: itemName, order: order } );\r
+                               }\r
+                       }\r
+\r
+                       // Put the items in the right order.\r
+                       for ( group in groups ) {\r
+                               groups[ group ] = groups[ group ].sort( function( a, b ) {\r
+                                       return a.order == b.order ? 0 :\r
+                                               b.order < 0 ? -1 :\r
+                                               a.order < 0 ? 1 :\r
+                                               a.order < b.order ? -1 :\r
+                                               1;\r
+                               } );\r
+                       }\r
+\r
+                       return groups;\r
+               }\r
+\r
+               function fillGroup( toolbarGroup, uiItems ) {\r
+                       if ( uiItems.length ) {\r
+                               if ( toolbarGroup.items )\r
+                                       toolbarGroup.items.push( editor.ui.create( '-' ) );\r
+                               else\r
+                                       toolbarGroup.items = [];\r
+\r
+                               var item, name;\r
+                               while ( ( item = uiItems.shift() ) ) {\r
+                                       name = typeof item == 'string' ? item : item.name;\r
+\r
+                                       // Ignore items that are configured to be removed.\r
+                                       if ( !removeButtons || CKEDITOR.tools.indexOf( removeButtons, name ) == -1 ) {\r
+                                               item = editor.ui.create( name );\r
+\r
+                                               if ( !item )\r
+                                                       continue;\r
+\r
+                                               if ( !editor.addFeature( item ) )\r
+                                                       continue;\r
+\r
+                                               toolbarGroup.items.push( item );\r
+                                       }\r
+                               }\r
+                       }\r
+               }\r
+\r
+               function populateToolbarConfig( config ) {\r
+                       var toolbar = [],\r
+                               i, group, newGroup;\r
+\r
+                       for ( i = 0; i < config.length; ++i ) {\r
+                               group = config[ i ];\r
+                               newGroup = {};\r
+\r
+                               if ( group == '/' )\r
+                                       toolbar.push( group );\r
+                               else if ( CKEDITOR.tools.isArray( group ) ) {\r
+                                       fillGroup( newGroup, CKEDITOR.tools.clone( group ) );\r
+                                       toolbar.push( newGroup );\r
+                               }\r
+                               else if ( group.items ) {\r
+                                       fillGroup( newGroup, CKEDITOR.tools.clone( group.items ) );\r
+                                       newGroup.name = group.name;\r
+                                       toolbar.push( newGroup );\r
+                               }\r
+                       }\r
+\r
+                       return toolbar;\r
+               }\r
+\r
+               var toolbar = editor.config.toolbar;\r
+\r
+               // If it is a string, return the relative "toolbar_name" config.\r
+               if ( typeof toolbar == 'string' )\r
+                       toolbar = editor.config[ 'toolbar_' + toolbar ];\r
+\r
+               return ( editor.toolbar = toolbar ? populateToolbarConfig( toolbar ) : buildToolbarConfig() );\r
+       }\r
+\r
+       /**\r
+        * Adds a toolbar group. See {@link CKEDITOR.config#toolbarGroups} for more details.\r
+        *\r
+        * **Note:** This method will not modify toolbar groups set explicitly by\r
+        * {@link CKEDITOR.config#toolbarGroups}. It will only extend the default setting.\r
+        *\r
+        * @param {String} name Toolbar group name.\r
+        * @param {Number/String} previous The name of the toolbar group after which this one\r
+        * should be added or `0` if this group should be the first one.\r
+        * @param {String} [subgroupOf] The name of the parent group.\r
+        * @member CKEDITOR.ui\r
+        */\r
+       CKEDITOR.ui.prototype.addToolbarGroup = function( name, previous, subgroupOf ) {\r
+               // The toolbarGroups from the privates is the one we gonna use for automatic toolbar creation.\r
+               var toolbarGroups = getPrivateToolbarGroups( this.editor ),\r
+                       atStart = previous === 0,\r
+                       newGroup = { name: name };\r
+\r
+               if ( subgroupOf ) {\r
+                       // Transform the subgroupOf name in the real subgroup object.\r
+                       subgroupOf = CKEDITOR.tools.search( toolbarGroups, function( group ) {\r
+                               return group.name == subgroupOf;\r
+                       } );\r
+\r
+                       if ( subgroupOf ) {\r
+                               !subgroupOf.groups && ( subgroupOf.groups = [] ) ;\r
+\r
+                               if ( previous ) {\r
+                                       // Search the "previous" item and add the new one after it.\r
+                                       previous = CKEDITOR.tools.indexOf( subgroupOf.groups, previous );\r
+                                       if ( previous >= 0 ) {\r
+                                               subgroupOf.groups.splice( previous + 1, 0, name );\r
+                                               return;\r
+                                       }\r
+                               }\r
+\r
+                               // If no previous found.\r
+\r
+                               if ( atStart )\r
+                                       subgroupOf.groups.splice( 0, 0, name );\r
+                               else\r
+                                       subgroupOf.groups.push(  name );\r
+                               return;\r
+                       } else {\r
+                               // Ignore "previous" if subgroupOf has not been found.\r
+                               previous = null;\r
+                       }\r
+               }\r
+\r
+               if ( previous ) {\r
+                       // Transform the "previous" name into its index.\r
+                       previous = CKEDITOR.tools.indexOf( toolbarGroups, function( group ) {\r
+                               return group.name == previous;\r
+                       } );\r
+               }\r
+\r
+               if ( atStart )\r
+                       toolbarGroups.splice( 0, 0, name );\r
+               else if ( typeof previous == 'number' )\r
+                       toolbarGroups.splice( previous + 1, 0, newGroup );\r
+               else\r
+                       toolbarGroups.push( name );\r
+       };\r
+\r
+       function getPrivateToolbarGroups( editor ) {\r
+               return editor._.toolbarGroups || ( editor._.toolbarGroups = [\r
+                       { name: 'document',    groups: [ 'mode', 'document', 'doctools' ] },\r
+                       { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },\r
+                       { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },\r
+                       { name: 'forms' },\r
+                       '/',\r
+                       { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },\r
+                       { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },\r
+                       { name: 'links' },\r
+                       { name: 'insert' },\r
+                       '/',\r
+                       { name: 'styles' },\r
+                       { name: 'colors' },\r
+                       { name: 'tools' },\r
+                       { name: 'others' },\r
+                       { name: 'about' }\r
+               ] );\r
+       }\r
+} )();\r
+\r
+/**\r
+ * Separator UI element.\r
+ *\r
+ * @readonly\r
+ * @property {String} [='separator']\r
+ * @member CKEDITOR\r
+ */\r
+CKEDITOR.UI_SEPARATOR = 'separator';\r
+\r
+/**\r
+ * The part of the user interface where the toolbar will be rendered. For the default\r
+ * editor implementation, the recommended options are `'top'` and `'bottom'`.\r
+ *\r
+ * Please note that this option is only applicable to [classic](#!/guide/dev_framed)\r
+ * (`iframe`-based) editor. In case of [inline](#!/guide/dev_inline) editor the toolbar\r
+ * position is set dynamically depending on the position of the editable element on the screen.\r
+ *\r
+ * Read more in the [documentation](#!/guide/dev_toolbarlocation)\r
+ * and see the [SDK sample](http://sdk.ckeditor.com/samples/toolbarlocation.html).\r
+ *\r
+ *             config.toolbarLocation = 'bottom';\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.toolbarLocation = 'top';\r
+\r
+/**\r
+ * The toolbox (alias toolbar) definition. It is a toolbar name or an array of\r
+ * toolbars (strips), each one being also an array, containing a list of UI items.\r
+ *\r
+ * If set to `null`, the toolbar will be generated automatically using all available buttons\r
+ * and {@link #toolbarGroups} as a toolbar groups layout.\r
+ *\r
+ * In CKEditor 4.5+ you can generate your toolbar customization code by using the [visual\r
+ * toolbar configurator](http://docs.ckeditor.com/#!/guide/dev_toolbar).\r
+ *\r
+ *             // Defines a toolbar with only one strip containing the "Source" button, a\r
+ *             // separator, and the "Bold" and "Italic" buttons.\r
+ *             config.toolbar = [\r
+ *                     [ 'Source', '-', 'Bold', 'Italic' ]\r
+ *             ];\r
+ *\r
+ *             // Similar to the example above, defines a "Basic" toolbar with only one strip containing three buttons.\r
+ *             // Note that this setting is composed by "toolbar_" added to the toolbar name, which in this case is called "Basic".\r
+ *             // This second part of the setting name can be anything. You must use this name in the CKEDITOR.config.toolbar setting\r
+ *             // in order to instruct the editor which `toolbar_(name)` setting should be used.\r
+ *             config.toolbar_Basic = [\r
+ *                     [ 'Source', '-', 'Bold', 'Italic' ]\r
+ *             ];\r
+ *             // Load toolbar_Name where Name = Basic.\r
+ *             config.toolbar = 'Basic';\r
+ *\r
+ * @cfg {Array/String} [toolbar=null]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The toolbar groups definition.\r
+ *\r
+ * If the toolbar layout is not explicitly defined by the {@link #toolbar} setting, then\r
+ * this setting is used to group all defined buttons (see {@link CKEDITOR.ui#addButton}).\r
+ * Buttons are associated with toolbar groups by the `toolbar` property in their definition objects.\r
+ *\r
+ * New groups may be dynamically added during the editor and plugin initialization by\r
+ * {@link CKEDITOR.ui#addToolbarGroup}. This is only possible if the default setting was used.\r
+ *\r
+ *             // Default setting.\r
+ *             config.toolbarGroups = [\r
+ *                     { name: 'document',        groups: [ 'mode', 'document', 'doctools' ] },\r
+ *                     { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },\r
+ *                     { name: 'editing',     groups: [ 'find', 'selection', 'spellchecker' ] },\r
+ *                     { name: 'forms' },\r
+ *                     '/',\r
+ *                     { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },\r
+ *                     { name: 'paragraph',   groups: [ 'list', 'indent', 'blocks', 'align', 'bidi' ] },\r
+ *                     { name: 'links' },\r
+ *                     { name: 'insert' },\r
+ *                     '/',\r
+ *                     { name: 'styles' },\r
+ *                     { name: 'colors' },\r
+ *                     { name: 'tools' },\r
+ *                     { name: 'others' },\r
+ *                     { name: 'about' }\r
+ *             ];\r
+ *\r
+ * @cfg {Array} [toolbarGroups=see example]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Whether the toolbar can be collapsed by the user. If disabled, the Collapse Toolbar\r
+ * button will not be displayed.\r
+ *\r
+ *             config.toolbarCanCollapse = true;\r
+ *\r
+ * @cfg {Boolean} [toolbarCanCollapse=false]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Whether the toolbar must start expanded when the editor is loaded.\r
+ *\r
+ * Setting this option to `false` will affect the toolbar only when\r
+ * {@link #toolbarCanCollapse} is set to `true`:\r
+ *\r
+ *             config.toolbarCanCollapse = true;\r
+ *             config.toolbarStartupExpanded = false;\r
+ *\r
+ * @cfg {Boolean} [toolbarStartupExpanded=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * When enabled, causes the *Arrow* keys navigation to cycle within the current\r
+ * toolbar group. Otherwise the *Arrow* keys will move through all items available in\r
+ * the toolbar. The *Tab* key will still be used to quickly jump among the\r
+ * toolbar groups.\r
+ *\r
+ *             config.toolbarGroupCycling = false;\r
+ *\r
+ * @since 3.6\r
+ * @cfg {Boolean} [toolbarGroupCycling=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * List of toolbar button names that must not be rendered. This will also work\r
+ * for non-button toolbar items, like the Font drop-down list.\r
+ *\r
+ *             config.removeButtons = 'Underline,JustifyCenter';\r
+ *\r
+ * This configuration option should not be overused. The recommended way is to use the\r
+ * {@link CKEDITOR.config#removePlugins} setting to remove features from the editor\r
+ * or even better, [create a custom editor build](http://ckeditor.com/builder) with\r
+ * just the features that you will use.\r
+ * In some cases though, a single plugin may define a set of toolbar buttons and\r
+ * `removeButtons` may be useful when just a few of them are to be removed.\r
+ *\r
+ * @cfg {String} [removeButtons]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The toolbar definition used by the editor. It is created from the\r
+ * {@link CKEDITOR.config#toolbar} option if it is set or automatically\r
+ * based on {@link CKEDITOR.config#toolbarGroups}.\r
+ *\r
+ * @readonly\r
+ * @property {Object} toolbar\r
+ * @member CKEDITOR.editor\r
+ */\r
diff --git a/sources/plugins/toolbar/samples/toolbar.html b/sources/plugins/toolbar/samples/toolbar.html
new file mode 100644 (file)
index 0000000..e40d2a1
--- /dev/null
@@ -0,0 +1,235 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Toolbar Configuration &mdash; CKEditor Sample</title>\r
+       <meta name="ckeditor-sample-name" content="Toolbar Configurations">\r
+       <meta name="ckeditor-sample-group" content="Advanced Samples">\r
+       <meta name="ckeditor-sample-description" content="Configuring CKEditor to display full or custom toolbar layout.">\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link href="../../../samples/old/sample.css" rel="stylesheet">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Toolbar Configuration\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out the <a href="../../../samples/toolbarconfigurator/index.html#basic">brand new CKEditor Toolbar Configurator</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample page demonstrates editor with loaded <a href="#fullToolbar">full toolbar</a> (all registered buttons) and, if\r
+                       current editor's configuration modifies default settings, also editor with <a href="#currentToolbar">modified toolbar</a>.\r
+               </p>\r
+\r
+               <p>Since CKEditor 4 there are two ways to configure toolbar buttons.</p>\r
+\r
+               <h2 class="samples">By <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbar">config.toolbar</a></h2>\r
+\r
+               <p>\r
+                       You can explicitly define which buttons are displayed in which groups and in which order.\r
+                       This is the more precise setting, but less flexible. If newly added plugin adds its\r
+                       own button you'll have to add it manually to your <code>config.toolbar</code> setting as well.\r
+               </p>\r
+\r
+               <p>To add a CKEditor instance with custom toolbar setting, insert the following JavaScript call to your code:</p>\r
+\r
+               <pre class="samples">\r
+CKEDITOR.replace( <em>'textarea_id'</em>, {\r
+       <strong>toolbar:</strong> [\r
+               { name: 'document', items: [ 'Source', '-', 'NewPage', 'Preview', '-', 'Templates' ] }, // Defines toolbar group with name (used to create voice label) and items in 3 subgroups.\r
+               [ 'Cut', 'Copy', 'Paste', 'PasteText', 'PasteFromWord', '-', 'Undo', 'Redo' ],                  // Defines toolbar group without name.\r
+               '/',                                                                                                                                                                    // Line break - next group will be placed in new line.\r
+               { name: 'basicstyles', items: [ 'Bold', 'Italic' ] }\r
+       ]\r
+});</pre>\r
+\r
+               <h2 class="samples">By <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbarGroups">config.toolbarGroups</a></h2>\r
+\r
+               <p>\r
+                       You can define which groups of buttons (like e.g. <code>basicstyles</code>, <code>clipboard</code>\r
+                       and <code>forms</code>) are displayed and in which order. Registered buttons are associated\r
+                       with toolbar groups by <code>toolbar</code> property in their definition.\r
+                       This setting's advantage is that you don't have to modify toolbar configuration\r
+                       when adding/removing plugins which register their own buttons.\r
+               </p>\r
+\r
+               <p>To add a CKEditor instance with custom toolbar groups setting, insert the following JavaScript call to your code:</p>\r
+\r
+               <pre class="samples">\r
+CKEDITOR.replace( <em>'textarea_id'</em>, {\r
+       <strong>toolbarGroups:</strong> [\r
+               { name: 'document',        groups: [ 'mode', 'document' ] },                    // Displays document group with its two subgroups.\r
+               { name: 'clipboard',   groups: [ 'clipboard', 'undo' ] },                       // Group's name will be used to create voice label.\r
+               '/',                                                                                                                            // Line break - next group will be placed in new line.\r
+               { name: 'basicstyles', groups: [ 'basicstyles', 'cleanup' ] },\r
+               { name: 'links' }\r
+       ]\r
+\r
+       // NOTE: Remember to leave 'toolbar' property with the default value (null).\r
+});</pre>\r
+       </div>\r
+\r
+       <div id="currentToolbar" style="display: none">\r
+               <h2 class="samples">Current toolbar configuration</h2>\r
+               <p>Below you can see editor with current toolbar definition.</p>\r
+               <textarea cols="80" id="editorCurrent" name="editorCurrent" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               <pre id="editorCurrentCfg" class="samples"></pre>\r
+       </div>\r
+\r
+       <div id="fullToolbar">\r
+               <h2 class="samples">Full toolbar configuration</h2>\r
+               <p>Below you can see editor with full toolbar, generated automatically by the editor.</p>\r
+               <p>\r
+                       <strong>Note</strong>: To create editor instance with full toolbar you don't have to set anything.\r
+                       Just leave <code>toolbar</code> and <code>toolbarGroups</code> with the default, <code>null</code> values.\r
+               </p>\r
+               <textarea cols="80" id="editorFull" name="editorFull" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>\r
+               <pre id="editorFullCfg" class="samples"></pre>\r
+       </div>\r
+\r
+       <script>\r
+\r
+(function() {\r
+       'use strict';\r
+\r
+       var buttonsNames;\r
+\r
+       CKEDITOR.config.extraPlugins = 'toolbar';\r
+\r
+       CKEDITOR.on( 'instanceReady', function( evt ) {\r
+               var editor = evt.editor,\r
+                       editorCurrent = editor.name == 'editorCurrent',\r
+                       defaultToolbar = !( editor.config.toolbar || editor.config.toolbarGroups || editor.config.removeButtons ),\r
+                       pre = CKEDITOR.document.getById( editor.name + 'Cfg' ),\r
+                       output = '';\r
+\r
+               if ( editorCurrent ) {\r
+                       // If default toolbar configuration has been modified, show "current toolbar" section.\r
+                       if ( !defaultToolbar )\r
+                               CKEDITOR.document.getById( 'currentToolbar' ).show();\r
+                       else\r
+                               return;\r
+               }\r
+\r
+               if ( !buttonsNames )\r
+                       buttonsNames = createButtonsNamesHash( editor.ui.items );\r
+\r
+               // Toolbar isn't set explicitly, so it was created automatically from toolbarGroups.\r
+               if ( !editor.config.toolbar ) {\r
+                       output +=\r
+                               '// Toolbar configuration generated automatically by the editor based on config.toolbarGroups.\n' +\r
+                               dumpToolbarConfiguration( editor ) +\r
+                               '\n\n' +\r
+                               '// Toolbar groups configuration.\n' +\r
+                               dumpToolbarConfiguration( editor, true )\r
+               }\r
+               // Toolbar groups doesn't count in this case - print only toolbar.\r
+               else {\r
+                       output += '// Toolbar configuration.\n' +\r
+                               dumpToolbarConfiguration( editor );\r
+               }\r
+\r
+               // Recreate to avoid old IE from loosing whitespaces on filling <pre> content.\r
+               var preOutput = pre.getOuterHtml().replace( /(?=<\/)/, output );\r
+               CKEDITOR.dom.element.createFromHtml( preOutput ).replace( pre );\r
+       } );\r
+\r
+       CKEDITOR.replace( 'editorCurrent', { height: 100 } );\r
+       CKEDITOR.replace( 'editorFull', {\r
+               // Reset toolbar settings, so full toolbar will be generated automatically.\r
+               toolbar: null,\r
+               toolbarGroups: null,\r
+               removeButtons: null,\r
+               height: 100\r
+       } );\r
+\r
+       function dumpToolbarConfiguration( editor, printGroups ) {\r
+               var output = [],\r
+                       toolbar = editor.toolbar;\r
+\r
+               for ( var i = 0; i < toolbar.length; ++i ) {\r
+                       var group = dumpToolbarGroup( toolbar[ i ], printGroups );\r
+                       if ( group )\r
+                               output.push( group );\r
+               }\r
+\r
+               return 'config.toolbar' + ( printGroups ? 'Groups' : '' ) + ' = [\n\t' + output.join( ',\n\t' ) + '\n];';\r
+       }\r
+\r
+       function dumpToolbarGroup( group, printGroups ) {\r
+               var output = [];\r
+\r
+               if ( typeof group == 'string' )\r
+                       return '\'' + group + '\'';\r
+               if ( CKEDITOR.tools.isArray( group ) )\r
+                       return dumpToolbarItems( group );\r
+               // Skip group when printing entire toolbar configuration and there are no items in this group.\r
+               if ( !printGroups && !group.items )\r
+                       return;\r
+\r
+               if ( group.name )\r
+                       output.push( 'name: \'' + group.name + '\'' );\r
+\r
+               if ( group.groups )\r
+                       output.push( 'groups: ' + dumpToolbarItems( group.groups ) );\r
+\r
+               if ( !printGroups )\r
+                       output.push( 'items: ' + dumpToolbarItems( group.items ) );\r
+\r
+               return '{ ' + output.join( ', ' ) + ' }';\r
+       }\r
+\r
+       function dumpToolbarItems( items ) {\r
+               if ( typeof items == 'string' )\r
+                       return '\'' + items + '\'';\r
+\r
+               var names = [],\r
+                       i, item;\r
+\r
+               for ( var i = 0; i < items.length; ++i ) {\r
+                       item = items[ i ];\r
+                       if ( typeof item == 'string' )\r
+                               names.push( item );\r
+                       else {\r
+                               if ( item.type == CKEDITOR.UI_SEPARATOR )\r
+                                       names.push( '-' );\r
+                               else\r
+                                       names.push( buttonsNames[ item.name ] );\r
+                       }\r
+               }\r
+\r
+               return '[ \'' + names.join( '\', \'' ) + '\' ]';\r
+       }\r
+\r
+       // Creates { 'lowercased': 'LowerCased' } buttons names hash.\r
+       function createButtonsNamesHash( items ) {\r
+               var hash = {},\r
+                       name;\r
+\r
+               for ( name in items ) {\r
+                       hash[ items[ name ].name ] = name;\r
+               }\r
+\r
+               return hash;\r
+       }\r
+\r
+})();\r
+       </script>\r
+\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/widget/dev/assets/contents.css b/sources/plugins/widget/dev/assets/contents.css
new file mode 100644 (file)
index 0000000..2cff316
--- /dev/null
@@ -0,0 +1,23 @@
+.mediumBorder {\r
+       border-width: 2px;\r
+}\r
+.thickBorder {\r
+       border-width: 5px;\r
+}\r
+img.thickBorder, img.mediumBorder {\r
+       border-style: solid;\r
+       border-color: #CCC;\r
+}\r
+.important.soMuch {\r
+       margin: 25px;\r
+       padding: 25px;\r
+       background: red;\r
+       border: none;\r
+}\r
+\r
+span.redMarker {\r
+       background-color: red;\r
+}\r
+.invisible {\r
+       opacity: 0.1;\r
+}\r
diff --git a/sources/plugins/widget/dev/assets/sample.jpg b/sources/plugins/widget/dev/assets/sample.jpg
new file mode 100644 (file)
index 0000000..a4a77fa
Binary files /dev/null and b/sources/plugins/widget/dev/assets/sample.jpg differ
diff --git a/sources/plugins/widget/dev/assets/simplebox/contents.css b/sources/plugins/widget/dev/assets/simplebox/contents.css
new file mode 100644 (file)
index 0000000..ddf3675
--- /dev/null
@@ -0,0 +1,36 @@
+.simplebox {\r
+       padding: 8px;\r
+       margin: 10px;\r
+       background: #eee;\r
+       border-radius: 8px;\r
+       border: 1px solid #ddd;\r
+       box-shadow: 0 1px 1px #fff inset, 0 -1px 0px #ccc inset;\r
+}\r
+.simplebox-title, .simplebox-content {\r
+       box-shadow: 0 1px 1px #ddd inset;\r
+       border: 1px solid #cccccc;\r
+       border-radius: 5px;\r
+       background: #fff;\r
+}\r
+.simplebox-title {\r
+       margin: 0 0 8px;\r
+       padding: 5px 8px;\r
+}\r
+.simplebox-content {\r
+       padding: 0 8px;\r
+}\r
+.simplebox-content::after {\r
+       content: '';\r
+       display: block;\r
+       clear: both;\r
+}\r
+.simplebox.align-right {\r
+       float: right;\r
+}\r
+.simplebox.align-left {\r
+       float: left;\r
+}\r
+.simplebox.align-center {\r
+       margin-left: auto;\r
+       margin-right: auto;\r
+}\r
diff --git a/sources/plugins/widget/dev/assets/simplebox/dialogs/simplebox.js b/sources/plugins/widget/dev/assets/simplebox/dialogs/simplebox.js
new file mode 100644 (file)
index 0000000..45a150c
--- /dev/null
@@ -0,0 +1,51 @@
+// Note: This automatic widget to dialog window binding (the fact that every field is set up from the widget\r
+// and is committed to the widget) is only possible when the dialog is opened by the Widgets System\r
+// (i.e. the widgetDef.dialog property is set).\r
+// When you are opening the dialog window by yourself, you need to take care of this by yourself too.\r
+\r
+CKEDITOR.dialog.add( 'simplebox', function( editor ) {\r
+       return {\r
+               title: 'Edit Simple Box',\r
+               minWidth: 200,\r
+               minHeight: 100,\r
+               contents: [\r
+                       {\r
+                               id: 'info',\r
+                               elements: [\r
+                                       {\r
+                                               id: 'align',\r
+                                               type: 'select',\r
+                                               label: 'Align',\r
+                                               items: [\r
+                                                       [ editor.lang.common.notSet, '' ],\r
+                                                       [ editor.lang.common.alignLeft, 'left' ],\r
+                                                       [ editor.lang.common.alignRight, 'right' ],\r
+                                                       [ editor.lang.common.alignCenter, 'center' ]\r
+                                               ],\r
+                                               // When setting up this field, set its value to the "align" value from widget data.\r
+                                               // Note: Align values used in the widget need to be the same as those defined in the "items" array above.\r
+                                               setup: function( widget ) {\r
+                                                       this.setValue( widget.data.align );\r
+                                               },\r
+                                               // When committing (saving) this field, set its value to the widget data.\r
+                                               commit: function( widget ) {\r
+                                                       widget.setData( 'align', this.getValue() );\r
+                                               }\r
+                                       },\r
+                                       {\r
+                                               id: 'width',\r
+                                               type: 'text',\r
+                                               label: 'Width',\r
+                                               width: '50px',\r
+                                               setup: function( widget ) {\r
+                                                       this.setValue( widget.data.width );\r
+                                               },\r
+                                               commit: function( widget ) {\r
+                                                       widget.setData( 'width', this.getValue() );\r
+                                               }\r
+                                       }\r
+                               ]\r
+                       }\r
+               ]\r
+       };\r
+} );\r
diff --git a/sources/plugins/widget/dev/assets/simplebox/icons/simplebox.png b/sources/plugins/widget/dev/assets/simplebox/icons/simplebox.png
new file mode 100644 (file)
index 0000000..6a5e313
Binary files /dev/null and b/sources/plugins/widget/dev/assets/simplebox/icons/simplebox.png differ
diff --git a/sources/plugins/widget/dev/assets/simplebox/plugin.js b/sources/plugins/widget/dev/assets/simplebox/plugin.js
new file mode 100644 (file)
index 0000000..43dbad5
--- /dev/null
@@ -0,0 +1,114 @@
+'use strict';\r
+\r
+// Register the plugin within the editor.\r
+CKEDITOR.plugins.add( 'simplebox', {\r
+       // This plugin requires the Widgets System defined in the 'widget' plugin.\r
+       requires: 'widget',\r
+\r
+       // Register the icon used for the toolbar button. It must be the same\r
+       // as the name of the widget.\r
+       icons: 'simplebox',\r
+\r
+       // The plugin initialization logic goes inside this method.\r
+       init: function( editor ) {\r
+               // Register the editing dialog.\r
+               CKEDITOR.dialog.add( 'simplebox', this.path + 'dialogs/simplebox.js' );\r
+\r
+               // Register the simplebox widget.\r
+               editor.widgets.add( 'simplebox', {\r
+                       // Allow all HTML elements, classes, and styles that this widget requires.\r
+                       // Read more about the Advanced Content Filter here:\r
+                       // * http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter\r
+                       // * http://docs.ckeditor.com/#!/guide/plugin_sdk_integration_with_acf\r
+                       allowedContent:\r
+                               'div(!simplebox,align-left,align-right,align-center){width};' +\r
+                               'div(!simplebox-content); h2(!simplebox-title)',\r
+\r
+                       // Minimum HTML which is required by this widget to work.\r
+                       requiredContent: 'div(simplebox)',\r
+\r
+                       // Define two nested editable areas.\r
+                       editables: {\r
+                               title: {\r
+                                       // Define CSS selector used for finding the element inside widget element.\r
+                                       selector: '.simplebox-title',\r
+                                       // Define content allowed in this nested editable. Its content will be\r
+                                       // filtered accordingly and the toolbar will be adjusted when this editable\r
+                                       // is focused.\r
+                                       allowedContent: 'br strong em'\r
+                               },\r
+                               content: {\r
+                                       selector: '.simplebox-content'\r
+                               }\r
+                       },\r
+\r
+                       // Define the template of a new Simple Box widget.\r
+                       // The template will be used when creating new instances of the Simple Box widget.\r
+                       template:\r
+                               '<div class="simplebox">' +\r
+                                       '<h2 class="simplebox-title">Title</h2>' +\r
+                                       '<div class="simplebox-content"><p>Content...</p></div>' +\r
+                               '</div>',\r
+\r
+                       // Define the label for a widget toolbar button which will be automatically\r
+                       // created by the Widgets System. This button will insert a new widget instance\r
+                       // created from the template defined above, or will edit selected widget\r
+                       // (see second part of this tutorial to learn about editing widgets).\r
+                       //\r
+                       // Note: In order to be able to translate your widget you should use the\r
+                       // editor.lang.simplebox.* property. A string was used directly here to simplify this tutorial.\r
+                       button: 'Create a simple box',\r
+\r
+                       // Set the widget dialog window name. This enables the automatic widget-dialog binding.\r
+                       // This dialog window will be opened when creating a new widget or editing an existing one.\r
+                       dialog: 'simplebox',\r
+\r
+                       // Check the elements that need to be converted to widgets.\r
+                       //\r
+                       // Note: The "element" argument is an instance of http://docs.ckeditor.com/#!/api/CKEDITOR.htmlParser.element\r
+                       // so it is not a real DOM element yet. This is caused by the fact that upcasting is performed\r
+                       // during data processing which is done on DOM represented by JavaScript objects.\r
+                       upcast: function( element ) {\r
+                               // Return "true" (that element needs to converted to a Simple Box widget)\r
+                               // for all <div> elements with a "simplebox" class.\r
+                               return element.name == 'div' && element.hasClass( 'simplebox' );\r
+                       },\r
+\r
+                       // When a widget is being initialized, we need to read the data ("align" and "width")\r
+                       // from DOM and set it by using the widget.setData() method.\r
+                       // More code which needs to be executed when DOM is available may go here.\r
+                       init: function() {\r
+                               var width = this.element.getStyle( 'width' );\r
+                               if ( width )\r
+                                       this.setData( 'width', width );\r
+\r
+                               if ( this.element.hasClass( 'align-left' ) )\r
+                                       this.setData( 'align', 'left' );\r
+                               if ( this.element.hasClass( 'align-right' ) )\r
+                                       this.setData( 'align', 'right' );\r
+                               if ( this.element.hasClass( 'align-center' ) )\r
+                                       this.setData( 'align', 'center' );\r
+                       },\r
+\r
+                       // Listen on the widget#data event which is fired every time the widget data changes\r
+                       // and updates the widget's view.\r
+                       // Data may be changed by using the widget.setData() method, which we use in the\r
+                       // Simple Box dialog window.\r
+                       data: function() {\r
+                               // Check whether "width" widget data is set and remove or set "width" CSS style.\r
+                               // The style is set on widget main element (div.simplebox).\r
+                               if ( !this.data.width )\r
+                                       this.element.removeStyle( 'width' );\r
+                               else\r
+                                       this.element.setStyle( 'width', this.data.width );\r
+\r
+                               // Brutally remove all align classes and set a new one if "align" widget data is set.\r
+                               this.element.removeClass( 'align-left' );\r
+                               this.element.removeClass( 'align-right' );\r
+                               this.element.removeClass( 'align-center' );\r
+                               if ( this.data.align )\r
+                                       this.element.addClass( 'align-' + this.data.align );\r
+                       }\r
+               } );\r
+       }\r
+} );\r
diff --git a/sources/plugins/widget/dev/console.js b/sources/plugins/widget/dev/console.js
new file mode 100644 (file)
index 0000000..78db0d0
--- /dev/null
@@ -0,0 +1,131 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/* global CKCONSOLE */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+\r
+       CKCONSOLE.add( 'widget', {\r
+               panels: [\r
+                       {\r
+                               type: 'box',\r
+                               content: '<ul class="ckconsole_list ckconsole_value" data-value="instances"></ul>',\r
+\r
+                               refresh: function( editor ) {\r
+                                       var instances = obj2Array( editor.widgets.instances );\r
+\r
+                                       return {\r
+                                               header: 'Instances (' + instances.length + ')',\r
+                                               instances: generateInstancesList( instances )\r
+                                       };\r
+                               },\r
+\r
+                               refreshOn: function( editor, refresh ) {\r
+                                       editor.widgets.on( 'instanceCreated', function( evt ) {\r
+                                               refresh();\r
+\r
+                                               evt.data.on( 'data', refresh );\r
+                                       } );\r
+\r
+                                       editor.widgets.on( 'instanceDestroyed', refresh );\r
+                               }\r
+                       },\r
+\r
+                       {\r
+                               type: 'box',\r
+                               content:\r
+                                       '<ul class="ckconsole_list">' +\r
+                                               '<li>focused: <span class="ckconsole_value" data-value="focused"></span></li>' +\r
+                                               '<li>selected: <span class="ckconsole_value" data-value="selected"></span></li>' +\r
+                                       '</ul>',\r
+\r
+                               refresh: function( editor ) {\r
+                                       var focused = editor.widgets.focused,\r
+                                               selected = editor.widgets.selected,\r
+                                               selectedIds = [];\r
+\r
+                                       for ( var i = 0; i < selected.length; ++i )\r
+                                               selectedIds.push( selected[ i ].id );\r
+\r
+                                       return {\r
+                                               header: 'Focus &amp; selection',\r
+                                               focused: focused ? 'id: ' + focused.id : '-',\r
+                                               selected: selectedIds.length ? 'id: ' + selectedIds.join( ', id: ' ) : '-'\r
+                                       };\r
+                               },\r
+\r
+                               refreshOn: function( editor, refresh ) {\r
+                                       editor.on( 'selectionCheck', refresh, null, null, 999 );\r
+                               }\r
+                       },\r
+\r
+                       {\r
+                               type: 'log',\r
+\r
+                               on: function( editor, log, logFn ) {\r
+                                       // Add all listeners with high priorities to log\r
+                                       // messages in the correct order when one event depends on another.\r
+                                       // E.g. selectionChange triggers widget selection - if this listener\r
+                                       // for selectionChange will be executed later than that one, then order\r
+                                       // will be incorrect.\r
+\r
+                                       editor.on( 'selectionChange', function( evt ) {\r
+                                               var msg = 'selection change',\r
+                                                       sel = evt.data.selection,\r
+                                                       el = sel.getSelectedElement(),\r
+                                                       widget;\r
+\r
+                                               if ( el && ( widget = editor.widgets.getByElement( el, true ) ) )\r
+                                                       msg += ' (id: ' + widget.id + ')';\r
+\r
+                                               log( msg );\r
+                                       }, null, null, 1 );\r
+\r
+                                       editor.widgets.on( 'instanceDestroyed', function( evt ) {\r
+                                               log( 'instance destroyed (id: ' + evt.data.id + ')' );\r
+                                       }, null, null, 1 );\r
+\r
+                                       editor.widgets.on( 'instanceCreated', function( evt ) {\r
+                                               log( 'instance created (id: ' + evt.data.id + ')' );\r
+                                       }, null, null, 1 );\r
+\r
+                                       editor.widgets.on( 'widgetFocused', function( evt ) {\r
+                                               log( 'widget focused (id: ' + evt.data.widget.id + ')' );\r
+                                       }, null, null, 1 );\r
+\r
+                                       editor.widgets.on( 'widgetBlurred', function( evt ) {\r
+                                               log( 'widget blurred (id: ' + evt.data.widget.id + ')' );\r
+                                       }, null, null, 1 );\r
+\r
+                                       editor.widgets.on( 'checkWidgets', logFn( 'checking widgets' ), null, null, 1 );\r
+                                       editor.widgets.on( 'checkSelection', logFn( 'checking selection' ), null, null, 1 );\r
+                               }\r
+                       }\r
+               ]\r
+       } );\r
+\r
+       function generateInstancesList( instances ) {\r
+               var html = '',\r
+                       instance;\r
+\r
+               for ( var i = 0; i < instances.length; ++i ) {\r
+                       instance = instances[ i ];\r
+                       html += itemTpl.output( { id: instance.id, name: instance.name, data: JSON.stringify( instance.data ) } );\r
+               }\r
+               return html;\r
+       }\r
+\r
+       function obj2Array( obj ) {\r
+               var arr = [];\r
+               for ( var id in obj )\r
+                       arr.push( obj[ id ] );\r
+\r
+               return arr;\r
+       }\r
+\r
+       var itemTpl = new CKEDITOR.template( '<li>id: <code>{id}</code>, name: <code>{name}</code>, data: <code>{data}</code></li>' );\r
+} )();\r
diff --git a/sources/plugins/widget/dev/nestedwidgets.html b/sources/plugins/widget/dev/nestedwidgets.html
new file mode 100644 (file)
index 0000000..0686d2c
--- /dev/null
@@ -0,0 +1,134 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Nested widgets &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../dev/console/console.js"></script>\r
+       <script src="../../../dev/console/focusconsole.js"></script>\r
+       <script src="console.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <link rel="stylesheet" href="../../../contents.css">\r
+       <link rel="stylesheet" href="assets/simplebox/contents.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">Nested widgets</h1>\r
+\r
+       <h2>Classic (iframe-based) Sample</h2>\r
+       <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+               <h1>Simple Box Sample</h1>\r
+\r
+               <div class="simplebox align-right" style="width: 60%">\r
+                       <h2 class="simplebox-title">Title</h2>\r
+                       <div class="simplebox-content">\r
+                               <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+                               <figure class="image" style="float: right">\r
+                                       <img alt="The Eagle" src="assets/sample.jpg" width="150" />\r
+                                       <figcaption>The Eagle in lunar orbit</figcaption>\r
+                               </figure>\r
+\r
+                               <ul>\r
+                                       <li>Foo!</li>\r
+                                       <li>Bar!</li>\r
+                               </ul>\r
+\r
+                               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+                       </div>\r
+               </div>\r
+\r
+               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+\r
+               <p>Pellentesque vitae eleifend nisl, non accumsan tellus. Maecenas nec libero non tellus tincidunt mollis porttitor sed arcu. Donec ultricies nulla vitae eros lacinia, vel congue sem auctor. Vivamus convallis, urna ac tincidunt malesuada, lectus erat convallis metus, a hendrerit massa augue accumsan magna. Nulla mattis tellus elit, nec congue magna scelerisque eget. Aliquam posuere nisi augue, posuere sodales nisi iaculis eu. Donec fermentum urna id nibh sagittis fermentum sit amet sed enim. Aliquam neque elit, pretium elementum nunc a, faucibus accumsan lorem. Etiam pulvinar odio et hendrerit tincidunt. Suspendisse tempus eros lacus, in convallis velit mollis ut. Aenean congue, justo eleifend ultricies malesuada, nunc nunc molestie mauris, eget placerat libero eros vel nisi. Quisque diam arcu, mollis ac laoreet vitae, varius et sem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis in vehicula sapien. Nunc feugiat porta elit nec volutpat.</p>\r
+\r
+               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+\r
+               <div class="simplebox align-center" style="width: 750px">\r
+                       <h2 class="simplebox-title">Title</h2>\r
+                       <div class="simplebox-content">\r
+                               <p><img alt="The Eagle" src="assets/sample.jpg" width="150" style="float: left" /><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+                               <ul>\r
+                                       <li>Foo!</li>\r
+                                       <li>Bar!</li>\r
+                               </ul>\r
+                       </div>\r
+               </div>\r
+\r
+               <p>Ut eget ipsum a sapien porta ultrices. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus mi lacus, pharetra eu bibendum blandit, tristique sit amet leo. Integer eu nulla nec magna vulputate blandit. Praesent mattis quis ante eget adipiscing. Nulla vel tempus risus, in placerat velit. Mauris sed nibh at elit posuere laoreet. Morbi non sapien sed nunc fringilla imperdiet.</p>\r
+       </textarea>\r
+\r
+       <h2>Inline Sample</h2>\r
+       <div id="editor2" contenteditable="true">\r
+               <h1>Simple Box Sample</h1>\r
+\r
+               <div class="simplebox align-right" style="width: 60%">\r
+                       <h2 class="simplebox-title">Title</h2>\r
+                       <div class="simplebox-content">\r
+                               <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+                               <figure class="image" style="float: right">\r
+                                       <img alt="The Eagle" src="assets/sample.jpg" width="150" />\r
+                                       <figcaption>The Eagle in lunar orbit</figcaption>\r
+                               </figure>\r
+\r
+                               <ul>\r
+                                       <li>Foo!</li>\r
+                                       <li>Bar!</li>\r
+                               </ul>\r
+\r
+                               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+                       </div>\r
+               </div>\r
+\r
+               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+\r
+               <p>Pellentesque vitae eleifend nisl, non accumsan tellus. Maecenas nec libero non tellus tincidunt mollis porttitor sed arcu. Donec ultricies nulla vitae eros lacinia, vel congue sem auctor. Vivamus convallis, urna ac tincidunt malesuada, lectus erat convallis metus, a hendrerit massa augue accumsan magna. Nulla mattis tellus elit, nec congue magna scelerisque eget. Aliquam posuere nisi augue, posuere sodales nisi iaculis eu. Donec fermentum urna id nibh sagittis fermentum sit amet sed enim. Aliquam neque elit, pretium elementum nunc a, faucibus accumsan lorem. Etiam pulvinar odio et hendrerit tincidunt. Suspendisse tempus eros lacus, in convallis velit mollis ut. Aenean congue, justo eleifend ultricies malesuada, nunc nunc molestie mauris, eget placerat libero eros vel nisi. Quisque diam arcu, mollis ac laoreet vitae, varius et sem. Interdum et malesuada fames ac ante ipsum primis in faucibus. Duis in vehicula sapien. Nunc feugiat porta elit nec volutpat.</p>\r
+\r
+               <p>Lorem ipsum dolor sit amet, consectetur adipiscing elit. Curabitur sit amet orci ut nisi adipiscing ultrices. Sed pellentesque iaculis malesuada. Pellentesque scelerisque, purus non porta dictum, neque urna bibendum dolor, eget tristique ipsum metus fringilla dolor. Nullam sed accumsan sapien. Vestibulum in placerat magna. Sed justo lacus, volutpat rhoncus odio luctus, ornare adipiscing mauris. Vivamus erat sem, egestas et lectus eget, varius cursus odio. Duis posuere lacus sit amet urna bibendum, id iaculis eros ultrices. Vestibulum a ultrices ante.</p>\r
+\r
+               <div class="simplebox align-center" style="width: 750px">\r
+                       <h2 class="simplebox-title">Title</h2>\r
+                       <div class="simplebox-content">\r
+                               <p><img alt="The Eagle" src="assets/sample.jpg" width="150" style="float: left" /><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+                               <ul>\r
+                                       <li>Foo!</li>\r
+                                       <li>Bar!</li>\r
+                               </ul>\r
+                       </div>\r
+               </div>\r
+\r
+               <p>Ut eget ipsum a sapien porta ultrices. Vestibulum ante ipsum primis in faucibus orci luctus et ultrices posuere cubilia Curae; Vivamus mi lacus, pharetra eu bibendum blandit, tristique sit amet leo. Integer eu nulla nec magna vulputate blandit. Praesent mattis quis ante eget adipiscing. Nulla vel tempus risus, in placerat velit. Mauris sed nibh at elit posuere laoreet. Morbi non sapien sed nunc fringilla imperdiet.</p>\r
+       </div>\r
+\r
+       <script>\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+                       CKEDITOR.tools.enableHtml5Elements( document );\r
+\r
+               CKEDITOR.plugins.addExternal( 'simplebox', 'plugins/widget/dev/assets/simplebox/' );\r
+\r
+               CKEDITOR.replace( 'editor1', {\r
+                       extraPlugins: 'simplebox,placeholder,image2',\r
+                       removePlugins: 'forms,bidi',\r
+                       contentsCss: [ '../../../contents.css', 'assets/simplebox/contents.css' ],\r
+                       height: 500\r
+               } );\r
+\r
+               CKEDITOR.inline( 'editor2', {\r
+                       extraPlugins: 'simplebox,placeholder,image2',\r
+                       removePlugins: 'forms,bidi'\r
+               } );\r
+\r
+               CKCONSOLE.create( 'widget', { editor: 'editor1' } );\r
+               CKCONSOLE.create( 'focus', { editor: 'editor1' } );\r
+               CKCONSOLE.create( 'widget', { editor: 'editor2', folded: true } );\r
+               CKCONSOLE.create( 'focus', { editor: 'editor2', folded: true } );\r
+\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/widget/dev/widgetstyles.html b/sources/plugins/widget/dev/widgetstyles.html
new file mode 100644 (file)
index 0000000..8e54b8d
--- /dev/null
@@ -0,0 +1,144 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2013, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Applying styles to widgets &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <link rel="stylesheet" href="../../../contents.css">\r
+       <link rel="stylesheet" href="assets/contents.css">\r
+</head>\r
+<body>\r
+       <h1 class="samples">Applying styles to widgets</h1>\r
+\r
+       <h2>Classic (iframe-based) Sample</h2>\r
+       <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+               <h1>Apollo 11</h1>\r
+\r
+               <figure class="image" style="float: right">\r
+                       <img alt="Saturn V" src="../../../samples/assets/sample.jpg" width="150" />\r
+                       <figcaption>Roll out of Saturn V on launch pad</figcaption>\r
+               </figure>\r
+\r
+               <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+               <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>\r
+\r
+               <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>\r
+\r
+               <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+\r
+               <blockquote>\r
+               <p>One small step for [a] man, one giant leap for mankind.</p>\r
+               </blockquote>\r
+\r
+               <p><span class="math-tex">\( \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \)</span></p>\r
+\r
+               <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>\r
+\r
+               <blockquote>\r
+               <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>\r
+               </blockquote>\r
+\r
+               <figure class="image" style="float: right">\r
+                       <img alt="The Eagle" src="../../../samples/assets/sample.jpg" width="150" />\r
+                       <figcaption>The Eagle in lunar orbit</figcaption>\r
+               </figure>\r
+\r
+               <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>\r
+\r
+               <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>\r
+\r
+               <ol>\r
+                       <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>\r
+                       <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>\r
+                       <li><strong>Lunar Module</strong> for landing on the Moon.</li>\r
+               </ol>\r
+\r
+               <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>\r
+       </textarea>\r
+\r
+       <h2>Inline Sample</h2>\r
+       <div id="editor2" contenteditable="true">\r
+               <h1>Apollo 11</h1>\r
+\r
+               <figure class="image" style="float: right">\r
+                       <img alt="Saturn V" src="../../../samples/assets/sample.jpg" width="150" />\r
+                       <figcaption>Roll out of Saturn V on launch pad</figcaption>\r
+               </figure>\r
+\r
+               <p><strong>Apollo 11</strong> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on [[July 20, 1969, at 20:18 UTC]]. Armstrong became the first to step onto the lunar surface 6 hours later on [[July 21 at 02:56 UTC]].</p>\r
+\r
+               <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>\r
+\r
+               <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>\r
+\r
+               <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>\r
+\r
+               <blockquote>\r
+               <p>One small step for [a] man, one giant leap for mankind.</p>\r
+               </blockquote>\r
+\r
+               <p><span class="math-tex">\( \left( \sum_{k=1}^n a_k b_k \right)^2 \leq \left( \sum_{k=1}^n a_k^2 \right) \left( \sum_{k=1}^n b_k^2 \right) \)</span></p>\r
+\r
+               <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>\r
+\r
+               <blockquote>\r
+               <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>\r
+               </blockquote>\r
+\r
+               <figure class="image" style="float: right">\r
+                       <img alt="The Eagle" src="../../../samples/assets/sample.jpg" width="150" />\r
+                       <figcaption>The Eagle in lunar orbit</figcaption>\r
+               </figure>\r
+\r
+               <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>\r
+\r
+               <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>\r
+\r
+               <ol>\r
+                       <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>\r
+                       <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>\r
+                       <li><strong>Lunar Module</strong> for landing on the Moon.</li>\r
+               </ol>\r
+\r
+               <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>\r
+       </div>\r
+\r
+       <script>\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )\r
+                       CKEDITOR.tools.enableHtml5Elements( document );\r
+\r
+               CKEDITOR.disableAutoInline = true;\r
+\r
+               var stylesSet = [\r
+                       { name: 'Medium border', type: 'widget', widget: 'image', attributes: { 'class': 'mediumBorder' } },\r
+                       { name: 'Thick border', type: 'widget', widget: 'image', attributes: { 'class': 'thickBorder' } },\r
+                       { name: 'So important', type: 'widget', widget: 'image', attributes: { 'class': 'important soMuch' } },\r
+\r
+                       { name: 'Red marker', type: 'widget', widget: 'placeholder', attributes: { 'class': 'redMarker' } },\r
+                       { name: 'Invisible Placeholder', type: 'widget', widget: 'placeholder', attributes: { 'class': 'invisible' } },\r
+\r
+                       { name: 'Invisible Mathjax', type: 'widget', widget: 'mathjax', attributes: { 'class': 'invisible' } }\r
+               ];\r
+\r
+               CKEDITOR.replace( 'editor1', {\r
+                       extraPlugins: 'placeholder,image2,mathjax',\r
+                       contentsCss: [ '../../../contents.css', 'assets/contents.css' ],\r
+                       stylesSet: stylesSet,\r
+                       height: 300\r
+               } );\r
+\r
+               CKEDITOR.inline( 'editor2', {\r
+                       extraPlugins: 'placeholder,image2,mathjax',\r
+                       stylesSet: stylesSet,\r
+                       height: 300\r
+               } );\r
+\r
+       </script>\r
+</body>\r
+</html>\r
diff --git a/sources/plugins/widget/images/handle.png b/sources/plugins/widget/images/handle.png
new file mode 100644 (file)
index 0000000..ba8cda5
Binary files /dev/null and b/sources/plugins/widget/images/handle.png differ
diff --git a/sources/plugins/widget/lang/af.js b/sources/plugins/widget/lang/af.js
new file mode 100644 (file)
index 0000000..e37c598
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'af', {\r
+       'move': 'Klik en trek on te beweeg',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ar.js b/sources/plugins/widget/lang/ar.js
new file mode 100644 (file)
index 0000000..0a4f8eb
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ar', {\r
+       'move': 'إضغط و إسحب للتحريك',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/az.js b/sources/plugins/widget/lang/az.js
new file mode 100644 (file)
index 0000000..24ddaf3
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'az', {\r
+       'move': 'Tıklayın və aparın',\r
+       'label': '%1 vidjet'\r
+} );\r
diff --git a/sources/plugins/widget/lang/bg.js b/sources/plugins/widget/lang/bg.js
new file mode 100644 (file)
index 0000000..9b51458
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'bg', {\r
+       'move': 'Кликни и влачи, за да преместиш',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ca.js b/sources/plugins/widget/lang/ca.js
new file mode 100644 (file)
index 0000000..f46a4f8
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ca', {\r
+       'move': 'Clicar i arrossegar per moure',\r
+       'label': '%1 widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/cs.js b/sources/plugins/widget/lang/cs.js
new file mode 100644 (file)
index 0000000..5d9590b
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'cs', {\r
+       'move': 'Klepněte a táhněte pro přesunutí',\r
+       'label': 'Ovládací prvek %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/cy.js b/sources/plugins/widget/lang/cy.js
new file mode 100644 (file)
index 0000000..29dc110
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'cy', {\r
+       'move': 'Clcio a llusgo i symud',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/da.js b/sources/plugins/widget/lang/da.js
new file mode 100644 (file)
index 0000000..8dfe785
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'da', {\r
+       'move': 'Klik og træk for at flytte',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/de-ch.js b/sources/plugins/widget/lang/de-ch.js
new file mode 100644 (file)
index 0000000..a95febb
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'de-ch', {\r
+       'move': 'Zum Verschieben anwählen und ziehen',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/de.js b/sources/plugins/widget/lang/de.js
new file mode 100644 (file)
index 0000000..838ad89
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'de', {\r
+       'move': 'Zum Verschieben anwählen und ziehen',\r
+       'label': '%1 Steuerelement'\r
+} );\r
diff --git a/sources/plugins/widget/lang/el.js b/sources/plugins/widget/lang/el.js
new file mode 100644 (file)
index 0000000..863604a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'el', {\r
+       'move': 'Κάνετε κλικ και σύρετε το ποντίκι για να μετακινήστε',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/en-gb.js b/sources/plugins/widget/lang/en-gb.js
new file mode 100644 (file)
index 0000000..ed09606
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'en-gb', {\r
+       'move': 'Click and drag to move',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/en.js b/sources/plugins/widget/lang/en.js
new file mode 100644 (file)
index 0000000..5967f4d
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'en', {\r
+       'move': 'Click and drag to move',\r
+       'label': '%1 widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/eo.js b/sources/plugins/widget/lang/eo.js
new file mode 100644 (file)
index 0000000..f4979ac
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'eo', {\r
+       'move': 'klaki kaj treni por movi',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/es.js b/sources/plugins/widget/lang/es.js
new file mode 100644 (file)
index 0000000..d8deb2c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'es', {\r
+       'move': 'Dar clic y arrastrar para mover',\r
+       'label': 'reproductor %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/eu.js b/sources/plugins/widget/lang/eu.js
new file mode 100644 (file)
index 0000000..e128dfe
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'eu', {\r
+       'move': 'Klikatu eta arrastatu lekuz aldatzeko',\r
+       'label': '%1 widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/fa.js b/sources/plugins/widget/lang/fa.js
new file mode 100644 (file)
index 0000000..57ea31f
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'fa', {\r
+       'move': 'کلیک و کشیدن برای جابجایی',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/fi.js b/sources/plugins/widget/lang/fi.js
new file mode 100644 (file)
index 0000000..759b2cf
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'fi', {\r
+       'move': 'Siirrä klikkaamalla ja raahaamalla',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/fr.js b/sources/plugins/widget/lang/fr.js
new file mode 100644 (file)
index 0000000..9decbf6
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'fr', {\r
+       'move': 'Cliquer et glisser pour déplacer',\r
+       'label': 'Élément %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/gl.js b/sources/plugins/widget/lang/gl.js
new file mode 100644 (file)
index 0000000..ef070b6
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'gl', {\r
+       'move': 'Prema e arrastre para mover',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/he.js b/sources/plugins/widget/lang/he.js
new file mode 100644 (file)
index 0000000..b8dd2cb
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'he', {\r
+       'move': 'לחץ וגרור להזזה',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/hr.js b/sources/plugins/widget/lang/hr.js
new file mode 100644 (file)
index 0000000..952d800
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'hr', {\r
+       'move': 'Klikni i povuci da pomakneš',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/hu.js b/sources/plugins/widget/lang/hu.js
new file mode 100644 (file)
index 0000000..4721305
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'hu', {\r
+       'move': 'Kattints és húzd a mozgatáshoz',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/id.js b/sources/plugins/widget/lang/id.js
new file mode 100644 (file)
index 0000000..ef19392
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'id', {\r
+       'move': 'Tekan dan geser untuk memindahkan',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/it.js b/sources/plugins/widget/lang/it.js
new file mode 100644 (file)
index 0000000..59b43f6
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'it', {\r
+       'move': 'Fare clic e trascinare per spostare',\r
+       'label': 'Widget %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/ja.js b/sources/plugins/widget/lang/ja.js
new file mode 100644 (file)
index 0000000..a742718
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ja', {\r
+       'move': 'ドラッグして移動',\r
+       'label': '%1 ウィジェット'\r
+} );\r
diff --git a/sources/plugins/widget/lang/km.js b/sources/plugins/widget/lang/km.js
new file mode 100644 (file)
index 0000000..6c61c73
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'km', {\r
+       'move': 'ចុច​ហើយ​ទាញ​ដើម្បី​ផ្លាស់​ទី',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ko.js b/sources/plugins/widget/lang/ko.js
new file mode 100644 (file)
index 0000000..0107a13
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ko', {\r
+       'move': '움직이려면 클릭 후 드래그 하세요',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ku.js b/sources/plugins/widget/lang/ku.js
new file mode 100644 (file)
index 0000000..2af50cb
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ku', {\r
+       'move': 'کرتەبکە و ڕایبکێشە بۆ جوڵاندن',\r
+       'label': '%1 ویجێت'\r
+} );\r
diff --git a/sources/plugins/widget/lang/lv.js b/sources/plugins/widget/lang/lv.js
new file mode 100644 (file)
index 0000000..e5fc3ac
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'lv', {\r
+       'move': 'Klikšķina un velc, lai pārvietotu',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/nb.js b/sources/plugins/widget/lang/nb.js
new file mode 100644 (file)
index 0000000..af46bc9
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'nb', {\r
+       'move': 'Klikk og dra for å flytte',\r
+       'label': 'Widget %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/nl.js b/sources/plugins/widget/lang/nl.js
new file mode 100644 (file)
index 0000000..56b182c
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'nl', {\r
+       'move': 'Klik en sleep om te verplaatsen',\r
+       'label': '%1 widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/no.js b/sources/plugins/widget/lang/no.js
new file mode 100644 (file)
index 0000000..b86bd7b
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'no', {\r
+       'move': 'Klikk og dra for å flytte',\r
+       'label': 'Widget %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/oc.js b/sources/plugins/widget/lang/oc.js
new file mode 100644 (file)
index 0000000..10ff842
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'oc', {\r
+       'move': 'Clicar e lisar per desplaçar',\r
+       'label': 'Element %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/pl.js b/sources/plugins/widget/lang/pl.js
new file mode 100644 (file)
index 0000000..2d90df8
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'pl', {\r
+       'move': 'Kliknij i przeciągnij, by przenieść.',\r
+       'label': 'Widget %1'\r
+} );\r
diff --git a/sources/plugins/widget/lang/pt-br.js b/sources/plugins/widget/lang/pt-br.js
new file mode 100644 (file)
index 0000000..9ce9be4
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'pt-br', {\r
+       'move': 'Click e arraste para mover',\r
+       'label': '%1 widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/pt.js b/sources/plugins/widget/lang/pt.js
new file mode 100644 (file)
index 0000000..422ef93
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'pt', {\r
+       'move': 'Clique e arraste para mover',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ru.js b/sources/plugins/widget/lang/ru.js
new file mode 100644 (file)
index 0000000..d6f36f5
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ru', {\r
+       'move': 'Нажмите и перетащите, чтобы переместить',\r
+       'label': '%1 виджет'\r
+} );\r
diff --git a/sources/plugins/widget/lang/sk.js b/sources/plugins/widget/lang/sk.js
new file mode 100644 (file)
index 0000000..05acac4
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'sk', {\r
+       'move': 'Kliknite a potiahnite pre presunutie',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/sl.js b/sources/plugins/widget/lang/sl.js
new file mode 100644 (file)
index 0000000..96ffd1e
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'sl', {\r
+       'move': 'Kliknite in povlecite, da premaknete',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/sq.js b/sources/plugins/widget/lang/sq.js
new file mode 100644 (file)
index 0000000..ad46c7d
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'sq', {\r
+       'move': 'Kliko dhe tërhiqe për ta lëvizur',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/sv.js b/sources/plugins/widget/lang/sv.js
new file mode 100644 (file)
index 0000000..7faff37
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'sv', {\r
+       'move': 'Klicka och drag för att flytta',\r
+       'label': '%1-widget'\r
+} );\r
diff --git a/sources/plugins/widget/lang/tr.js b/sources/plugins/widget/lang/tr.js
new file mode 100644 (file)
index 0000000..92fa952
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'tr', {\r
+       'move': 'Taşımak için, tıklayın ve sürükleyin',\r
+       'label': '%1 Grafik Beleşeni'\r
+} );\r
diff --git a/sources/plugins/widget/lang/tt.js b/sources/plugins/widget/lang/tt.js
new file mode 100644 (file)
index 0000000..30fb31a
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'tt', {\r
+       'move': 'Күчереп куер өчен басып шудырыгыз',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/ug.js b/sources/plugins/widget/lang/ug.js
new file mode 100644 (file)
index 0000000..fc216c4
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'ug', {\r
+       'move': 'يۆتكەشتە چېكىپ سۆرەڭ',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/uk.js b/sources/plugins/widget/lang/uk.js
new file mode 100644 (file)
index 0000000..fab6d5d
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'uk', {\r
+       'move': 'Клікніть і потягніть для переміщення',\r
+       'label': '%1 віджет'\r
+} );\r
diff --git a/sources/plugins/widget/lang/vi.js b/sources/plugins/widget/lang/vi.js
new file mode 100644 (file)
index 0000000..2bbe246
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'vi', {\r
+       'move': 'Nhấp chuột và kéo để di chuyển',\r
+       'label': '%1 widget' // MISSING\r
+} );\r
diff --git a/sources/plugins/widget/lang/zh-cn.js b/sources/plugins/widget/lang/zh-cn.js
new file mode 100644 (file)
index 0000000..2381407
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'zh-cn', {\r
+       'move': '点击并拖拽以移动',\r
+       'label': '%1 小部件'\r
+} );\r
diff --git a/sources/plugins/widget/lang/zh.js b/sources/plugins/widget/lang/zh.js
new file mode 100644 (file)
index 0000000..b6e945b
--- /dev/null
@@ -0,0 +1,8 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+CKEDITOR.plugins.setLang( 'widget', 'zh', {\r
+       'move': '拖曳以移動',\r
+       'label': '%1 小工具'\r
+} );\r
diff --git a/sources/plugins/widget/plugin.js b/sources/plugins/widget/plugin.js
new file mode 100644 (file)
index 0000000..37374ab
--- /dev/null
@@ -0,0 +1,4126 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview [Widget](http://ckeditor.com/addon/widget) plugin.\r
+ */\r
+\r
+'use strict';\r
+\r
+( function() {\r
+       var DRAG_HANDLER_SIZE = 15;\r
+\r
+       CKEDITOR.plugins.add( 'widget', {\r
+               // jscs:disable maximumLineLength\r
+               lang: 'af,ar,az,bg,ca,cs,cy,da,de,de-ch,el,en,en-gb,eo,es,eu,fa,fi,fr,gl,he,hr,hu,id,it,ja,km,ko,ku,lv,nb,nl,no,oc,pl,pt,pt-br,ru,sk,sl,sq,sv,tr,tt,ug,uk,vi,zh,zh-cn', // %REMOVE_LINE_CORE%\r
+               // jscs:enable maximumLineLength\r
+               requires: 'lineutils,clipboard,widgetselection',\r
+               onLoad: function() {\r
+                       CKEDITOR.addCss(\r
+                               '.cke_widget_wrapper{' +\r
+                                       'position:relative;' +\r
+                                       'outline:none' +\r
+                               '}' +\r
+                               '.cke_widget_inline{' +\r
+                                       'display:inline-block' +\r
+                               '}' +\r
+                               '.cke_widget_wrapper:hover>.cke_widget_element{' +\r
+                                       'outline:2px solid yellow;' +\r
+                                       'cursor:default' +\r
+                               '}' +\r
+                               '.cke_widget_wrapper:hover .cke_widget_editable{' +\r
+                                       'outline:2px solid yellow' +\r
+                               '}' +\r
+                               '.cke_widget_wrapper.cke_widget_focused>.cke_widget_element,' +\r
+                               // We need higher specificity than hover style.\r
+                               '.cke_widget_wrapper .cke_widget_editable.cke_widget_editable_focused{' +\r
+                                       'outline:2px solid #ace' +\r
+                               '}' +\r
+                               '.cke_widget_editable{' +\r
+                                       'cursor:text' +\r
+                               '}' +\r
+                               '.cke_widget_drag_handler_container{' +\r
+                                       'position:absolute;' +\r
+                                       'width:' + DRAG_HANDLER_SIZE + 'px;' +\r
+                                       'height:0;' +\r
+                                       // Initially drag handler should not be visible, until its position will be\r
+                                       // calculated (#11177).\r
+                                       // We need to hide unpositined handlers, so they don't extend\r
+                                       // widget's outline far to the left (#12024).\r
+                                       'display:none;' +\r
+                                       'opacity:0.75;' +\r
+                                       'transition:height 0s 0.2s;' + // Delay hiding drag handler.\r
+                                       // Prevent drag handler from being misplaced (#11198).\r
+                                       'line-height:0' +\r
+                               '}' +\r
+                               '.cke_widget_wrapper:hover>.cke_widget_drag_handler_container{' +\r
+                                       'height:' + DRAG_HANDLER_SIZE + 'px;' +\r
+                                       'transition:none' +\r
+                               '}' +\r
+                               '.cke_widget_drag_handler_container:hover{' +\r
+                                       'opacity:1' +\r
+                               '}' +\r
+                               'img.cke_widget_drag_handler{' +\r
+                                       'cursor:move;' +\r
+                                       'width:' + DRAG_HANDLER_SIZE + 'px;' +\r
+                                       'height:' + DRAG_HANDLER_SIZE + 'px;' +\r
+                                       'display:inline-block' +\r
+                               '}' +\r
+                               '.cke_widget_mask{' +\r
+                                       'position:absolute;' +\r
+                                       'top:0;' +\r
+                                       'left:0;' +\r
+                                       'width:100%;' +\r
+                                       'height:100%;' +\r
+                                       'display:block' +\r
+                               '}' +\r
+                               '.cke_editable.cke_widget_dragging, .cke_editable.cke_widget_dragging *{' +\r
+                                       'cursor:move !important' +\r
+                               '}'\r
+                       );\r
+               },\r
+\r
+               beforeInit: function( editor ) {\r
+                       /**\r
+                        * An instance of widget repository. It contains all\r
+                        * {@link CKEDITOR.plugins.widget.repository#registered registered widget definitions} and\r
+                        * {@link CKEDITOR.plugins.widget.repository#instances initialized instances}.\r
+                        *\r
+                        *              editor.widgets.add( 'someName', {\r
+                        *                      // Widget definition...\r
+                        *              } );\r
+                        *\r
+                        *              editor.widgets.registered.someName; // -> Widget definition\r
+                        *\r
+                        * @since 4.3\r
+                        * @readonly\r
+                        * @property {CKEDITOR.plugins.widget.repository} widgets\r
+                        * @member CKEDITOR.editor\r
+                        */\r
+                       editor.widgets = new Repository( editor );\r
+               },\r
+\r
+               afterInit: function( editor ) {\r
+                       addWidgetButtons( editor );\r
+                       setupContextMenu( editor );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * Widget repository. It keeps track of all {@link #registered registered widget definitions} and\r
+        * {@link #instances initialized instances}. An instance of the repository is available under\r
+        * the {@link CKEDITOR.editor#widgets} property.\r
+        *\r
+        * @class CKEDITOR.plugins.widget.repository\r
+        * @mixins CKEDITOR.event\r
+        * @constructor Creates a widget repository instance. Note that the widget plugin automatically\r
+        * creates a repository instance which is available under the {@link CKEDITOR.editor#widgets} property.\r
+        * @param {CKEDITOR.editor} editor The editor instance for which the repository will be created.\r
+        */\r
+       function Repository( editor ) {\r
+               /**\r
+                * The editor instance for which this repository was created.\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.editor} editor\r
+                */\r
+               this.editor = editor;\r
+\r
+               /**\r
+                * A hash of registered widget definitions (definition name => {@link CKEDITOR.plugins.widget.definition}).\r
+                *\r
+                * To register a definition use the {@link #add} method.\r
+                *\r
+                * @readonly\r
+                */\r
+               this.registered = {};\r
+\r
+               /**\r
+                * An object containing initialized widget instances (widget id => {@link CKEDITOR.plugins.widget}).\r
+                *\r
+                * @readonly\r
+                */\r
+               this.instances = {};\r
+\r
+               /**\r
+                * An array of selected widget instances.\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.plugins.widget[]} selected\r
+                */\r
+               this.selected = [];\r
+\r
+               /**\r
+                * The focused widget instance. See also {@link CKEDITOR.plugins.widget#event-focus}\r
+                * and {@link CKEDITOR.plugins.widget#event-blur} events.\r
+                *\r
+                *              editor.on( 'selectionChange', function() {\r
+                *                      if ( editor.widgets.focused ) {\r
+                *                              // Do something when a widget is focused...\r
+                *                      }\r
+                *              } );\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.plugins.widget} focused\r
+                */\r
+               this.focused = null;\r
+\r
+               /**\r
+                * The widget instance that contains the nested editable which is currently focused.\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.plugins.widget} widgetHoldingFocusedEditable\r
+                */\r
+               this.widgetHoldingFocusedEditable = null;\r
+\r
+               this._ = {\r
+                       nextId: 0,\r
+                       upcasts: [],\r
+                       upcastCallbacks: [],\r
+                       filters: {}\r
+               };\r
+\r
+               setupWidgetsLifecycle( this );\r
+               setupSelectionObserver( this );\r
+               setupMouseObserver( this );\r
+               setupKeyboardObserver( this );\r
+               setupDragAndDrop( this );\r
+               setupNativeCutAndCopy( this );\r
+       }\r
+\r
+       Repository.prototype = {\r
+               /**\r
+                * Minimum interval between selection checks.\r
+                *\r
+                * @private\r
+                */\r
+               MIN_SELECTION_CHECK_INTERVAL: 500,\r
+\r
+               /**\r
+                * Adds a widget definition to the repository. Fires the {@link CKEDITOR.editor#widgetDefinition} event\r
+                * which allows to modify the widget definition which is going to be registered.\r
+                *\r
+                * @param {String} name The name of the widget definition.\r
+                * @param {CKEDITOR.plugins.widget.definition} widgetDef Widget definition.\r
+                * @returns {CKEDITOR.plugins.widget.definition}\r
+                */\r
+               add: function( name, widgetDef ) {\r
+                       // Create prototyped copy of original widget definition, so we won't modify it.\r
+                       widgetDef = CKEDITOR.tools.prototypedCopy( widgetDef );\r
+                       widgetDef.name = name;\r
+\r
+                       widgetDef._ = widgetDef._ || {};\r
+\r
+                       this.editor.fire( 'widgetDefinition', widgetDef );\r
+\r
+                       if ( widgetDef.template )\r
+                               widgetDef.template = new CKEDITOR.template( widgetDef.template );\r
+\r
+                       addWidgetCommand( this.editor, widgetDef );\r
+                       addWidgetProcessors( this, widgetDef );\r
+\r
+                       this.registered[ name ] = widgetDef;\r
+\r
+                       return widgetDef;\r
+               },\r
+\r
+               /**\r
+                * Adds a callback for element upcasting. Each callback will be executed\r
+                * for every element which is later tested by upcast methods. If a callback\r
+                * returns `false`, the element will not be upcasted.\r
+                *\r
+                *              // Images with the "banner" class will not be upcasted (e.g. to the image widget).\r
+                *              editor.widgets.addUpcastCallback( function( element ) {\r
+                *                      if ( element.name == 'img' && element.hasClass( 'banner' ) )\r
+                *                              return false;\r
+                *              } );\r
+                *\r
+                * @param {Function} callback\r
+                * @param {CKEDITOR.htmlParser.element} callback.element\r
+                */\r
+               addUpcastCallback: function( callback ) {\r
+                       this._.upcastCallbacks.push( callback );\r
+               },\r
+\r
+               /**\r
+                * Checks the selection to update widget states (selection and focus).\r
+                *\r
+                * This method is triggered by the {@link #event-checkSelection} event.\r
+                */\r
+               checkSelection: function() {\r
+                       var sel = this.editor.getSelection(),\r
+                               selectedElement = sel.getSelectedElement(),\r
+                               updater = stateUpdater( this ),\r
+                               widget;\r
+\r
+                       // Widget is focused so commit and finish checking.\r
+                       if ( selectedElement && ( widget = this.getByElement( selectedElement, true ) ) )\r
+                               return updater.focus( widget ).select( widget ).commit();\r
+\r
+                       var range = sel.getRanges()[ 0 ];\r
+\r
+                       // No ranges or collapsed range mean that nothing is selected, so commit and finish checking.\r
+                       if ( !range || range.collapsed )\r
+                               return updater.commit();\r
+\r
+                       // Range is not empty, so create walker checking for wrappers.\r
+                       var walker = new CKEDITOR.dom.walker( range ),\r
+                               wrapper;\r
+\r
+                       walker.evaluator = Widget.isDomWidgetWrapper;\r
+\r
+                       while ( ( wrapper = walker.next() ) )\r
+                               updater.select( this.getByElement( wrapper ) );\r
+\r
+                       updater.commit();\r
+               },\r
+\r
+               /**\r
+                * Checks if all widget instances are still present in the DOM.\r
+                * Destroys those instances that are not present.\r
+                * Reinitializes widgets on widget wrappers for which widget instances\r
+                * cannot be found. Takes nested widgets into account, too.\r
+                *\r
+                * This method triggers the {@link #event-checkWidgets} event whose listeners\r
+                * can cancel the method's execution or modify its options.\r
+                *\r
+                * @param [options] The options object.\r
+                * @param {Boolean} [options.initOnlyNew] Initializes widgets only on newly wrapped\r
+                * widget elements (those which still have the `cke_widget_new` class). When this option is\r
+                * set to `true`, widgets which were invalidated (e.g. by replacing with a cloned DOM structure)\r
+                * will not be reinitialized. This makes the check faster.\r
+                * @param {Boolean} [options.focusInited] If only one widget is initialized by\r
+                * the method, it will be focused.\r
+                */\r
+               checkWidgets: function( options ) {\r
+                       this.fire( 'checkWidgets', CKEDITOR.tools.copy( options || {} ) );\r
+               },\r
+\r
+               /**\r
+                * Removes the widget from the editor and moves the selection to the closest\r
+                * editable position if the widget was focused before.\r
+                *\r
+                * @param {CKEDITOR.plugins.widget} widget The widget instance to be deleted.\r
+                */\r
+               del: function( widget ) {\r
+                       if ( this.focused === widget ) {\r
+                               var editor = widget.editor,\r
+                                       range = editor.createRange(),\r
+                                       found;\r
+\r
+                               // If haven't found place for caret on the default side,\r
+                               // try to find it on the other side.\r
+                               if ( !( found = range.moveToClosestEditablePosition( widget.wrapper, true ) ) )\r
+                                       found = range.moveToClosestEditablePosition( widget.wrapper, false );\r
+\r
+                               if ( found )\r
+                                       editor.getSelection().selectRanges( [ range ] );\r
+                       }\r
+\r
+                       widget.wrapper.remove();\r
+                       this.destroy( widget, true );\r
+               },\r
+\r
+               /**\r
+                * Destroys the widget instance and all its nested widgets (widgets inside its nested editables).\r
+                *\r
+                * @param {CKEDITOR.plugins.widget} widget The widget instance to be destroyed.\r
+                * @param {Boolean} [offline] Whether the widget is offline (detached from the DOM tree) &mdash;\r
+                * in this case the DOM (attributes, classes, etc.) will not be cleaned up.\r
+                */\r
+               destroy: function( widget, offline ) {\r
+                       if ( this.widgetHoldingFocusedEditable === widget )\r
+                               setFocusedEditable( this, widget, null, offline );\r
+\r
+                       widget.destroy( offline );\r
+                       delete this.instances[ widget.id ];\r
+                       this.fire( 'instanceDestroyed', widget );\r
+               },\r
+\r
+               /**\r
+                * Destroys all widget instances.\r
+                *\r
+                * @param {Boolean} [offline] Whether the widgets are offline (detached from the DOM tree) &mdash;\r
+                * in this case the DOM (attributes, classes, etc.) will not be cleaned up.\r
+                * @param {CKEDITOR.dom.element} [container] The container within widgets will be destroyed.\r
+                * This option will be ignored if the `offline` flag was set to `true`, because in such case\r
+                * it is not possible to find widgets within the passed block.\r
+                */\r
+               destroyAll: function( offline, container ) {\r
+                       var widget,\r
+                               id,\r
+                               instances = this.instances;\r
+\r
+                       if ( container && !offline ) {\r
+                               var wrappers = container.find( '.cke_widget_wrapper' ),\r
+                                       l = wrappers.count(),\r
+                                       i = 0;\r
+\r
+                               // Length is constant, because this is not a live node list.\r
+                               // Note: since querySelectorAll returns nodes in document order,\r
+                               // outer widgets are always placed before their nested widgets and therefore\r
+                               // are destroyed before them.\r
+                               for ( ; i < l; ++i ) {\r
+                                       widget = this.getByElement( wrappers.getItem( i ), true );\r
+                                       // Widget might not be found, because it could be a nested widget,\r
+                                       // which would be destroyed when destroying its parent.\r
+                                       if ( widget )\r
+                                               this.destroy( widget );\r
+                               }\r
+\r
+                               return;\r
+                       }\r
+\r
+                       for ( id in instances ) {\r
+                               widget = instances[ id ];\r
+                               this.destroy( widget, offline );\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Finalizes a process of widget creation. This includes:\r
+                *\r
+                * * inserting widget element into editor,\r
+                * * marking widget instance as ready (see {@link CKEDITOR.plugins.widget#event-ready}),\r
+                * * focusing widget instance.\r
+                *\r
+                * This method is used by the default widget's command and is called\r
+                * after widget's dialog (if set) is closed. It may also be used in a\r
+                * customized process of widget creation and insertion.\r
+                *\r
+                *              widget.once( 'edit', function() {\r
+                *                      // Finalize creation only of not ready widgets.\r
+                *                      if ( widget.isReady() )\r
+                *                              return;\r
+                *\r
+                *                      // Cancel edit event to prevent automatic widget insertion.\r
+                *                      evt.cancel();\r
+                *\r
+                *                      CustomDialog.open( widget.data, function saveCallback( savedData ) {\r
+                *                              // Cache the container, because widget may be destroyed while saving data,\r
+                *                              // if this process will require some deep transformations.\r
+                *                              var container = widget.wrapper.getParent();\r
+                *\r
+                *                              widget.setData( savedData );\r
+                *\r
+                *                              // Widget will be retrieved from container and inserted into editor.\r
+                *                              editor.widgets.finalizeCreation( container );\r
+                *                      } );\r
+                *              } );\r
+                *\r
+                * @param {CKEDITOR.dom.element/CKEDITOR.dom.documentFragment} container The element\r
+                * or document fragment which contains widget wrapper. The container is used, so before\r
+                * finalizing creation the widget can be freely transformed (even destroyed and reinitialized).\r
+                */\r
+               finalizeCreation: function( container ) {\r
+                       var wrapper = container.getFirst();\r
+                       if ( wrapper && Widget.isDomWidgetWrapper( wrapper ) ) {\r
+                               this.editor.insertElement( wrapper );\r
+\r
+                               var widget = this.getByElement( wrapper );\r
+                               // Fire postponed #ready event.\r
+                               widget.ready = true;\r
+                               widget.fire( 'ready' );\r
+                               widget.focus();\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Finds a widget instance which contains a given element. The element will be the {@link CKEDITOR.plugins.widget#wrapper wrapper}\r
+                * of the returned widget or a descendant of this {@link CKEDITOR.plugins.widget#wrapper wrapper}.\r
+                *\r
+                *              editor.widgets.getByElement( someWidget.wrapper ); // -> someWidget\r
+                *              editor.widgets.getByElement( someWidget.parts.caption ); // -> someWidget\r
+                *\r
+                *              // Check wrapper only:\r
+                *              editor.widgets.getByElement( someWidget.wrapper, true ); // -> someWidget\r
+                *              editor.widgets.getByElement( someWidget.parts.caption, true ); // -> null\r
+                *\r
+                * @param {CKEDITOR.dom.element} element The element to be checked.\r
+                * @param {Boolean} [checkWrapperOnly] If set to `true`, the method will not check wrappers' descendants.\r
+                * @returns {CKEDITOR.plugins.widget} The widget instance or `null`.\r
+                */\r
+               getByElement: ( function() {\r
+                       var validWrapperElements = { div: 1, span: 1 };\r
+                       function getWidgetId( element ) {\r
+                               return element.is( validWrapperElements ) && element.data( 'cke-widget-id' );\r
+                       }\r
+\r
+                       return function( element, checkWrapperOnly ) {\r
+                               if ( !element )\r
+                                       return null;\r
+\r
+                               var id = getWidgetId( element );\r
+\r
+                               // There's no need to check element parents if element is a wrapper.\r
+                               if ( !checkWrapperOnly && !id ) {\r
+                                       var limit = this.editor.editable();\r
+\r
+                                       // Try to find a closest ascendant which is a widget wrapper.\r
+                                       do {\r
+                                               element = element.getParent();\r
+                                       } while ( element && !element.equals( limit ) && !( id = getWidgetId( element ) ) );\r
+                               }\r
+\r
+                               return this.instances[ id ] || null;\r
+                       };\r
+               } )(),\r
+\r
+               /**\r
+                * Initializes a widget on a given element if the widget has not been initialized on it yet.\r
+                *\r
+                * @param {CKEDITOR.dom.element} element The future widget element.\r
+                * @param {String/CKEDITOR.plugins.widget.definition} [widgetDef] Name of a widget or a widget definition.\r
+                * The widget definition should be previously registered by using the\r
+                * {@link CKEDITOR.plugins.widget.repository#add} method.\r
+                * @param [startupData] Widget startup data (has precedence over default one).\r
+                * @returns {CKEDITOR.plugins.widget} The widget instance or `null` if a widget could not be initialized on\r
+                * a given element.\r
+                */\r
+               initOn: function( element, widgetDef, startupData ) {\r
+                       if ( !widgetDef )\r
+                               widgetDef = this.registered[ element.data( 'widget' ) ];\r
+                       else if ( typeof widgetDef == 'string' )\r
+                               widgetDef = this.registered[ widgetDef ];\r
+\r
+                       if ( !widgetDef )\r
+                               return null;\r
+\r
+                       // Wrap element if still wasn't wrapped (was added during runtime by method that skips dataProcessor).\r
+                       var wrapper = this.wrapElement( element, widgetDef.name );\r
+\r
+                       if ( wrapper ) {\r
+                               // Check if widget wrapper is new (widget hasn't been initialized on it yet).\r
+                               // This class will be removed by widget constructor to avoid locking snapshot twice.\r
+                               if ( wrapper.hasClass( 'cke_widget_new' ) ) {\r
+                                       var widget = new Widget( this, this._.nextId++, element, widgetDef, startupData );\r
+\r
+                                       // Widget could be destroyed when initializing it.\r
+                                       if ( widget.isInited() ) {\r
+                                               this.instances[ widget.id ] = widget;\r
+\r
+                                               return widget;\r
+                                       } else {\r
+                                               return null;\r
+                                       }\r
+                               }\r
+\r
+                               // Widget already has been initialized, so try to get widget by element.\r
+                               // Note - it may happen that other instance will returned than the one created above,\r
+                               // if for example widget was destroyed and reinitialized.\r
+                               return this.getByElement( element );\r
+                       }\r
+\r
+                       // No wrapper means that there's no widget for this element.\r
+                       return null;\r
+               },\r
+\r
+               /**\r
+                * Initializes widgets on all elements which were wrapped by {@link #wrapElement} and\r
+                * have not been initialized yet.\r
+                *\r
+                * @param {CKEDITOR.dom.element} [container=editor.editable()] The container which will be checked for not\r
+                * initialized widgets. Defaults to editor's {@link CKEDITOR.editor#editable editable} element.\r
+                * @returns {CKEDITOR.plugins.widget[]} Array of widget instances which have been initialized.\r
+                * Note: Only first-level widgets are returned &mdash; without nested widgets.\r
+                */\r
+               initOnAll: function( container ) {\r
+                       var newWidgets = ( container || this.editor.editable() ).find( '.cke_widget_new' ),\r
+                               newInstances = [],\r
+                               instance;\r
+\r
+                       for ( var i = newWidgets.count(); i--; ) {\r
+                               instance = this.initOn( newWidgets.getItem( i ).getFirst( Widget.isDomWidgetElement ) );\r
+                               if ( instance )\r
+                                       newInstances.push( instance );\r
+                       }\r
+\r
+                       return newInstances;\r
+               },\r
+\r
+               /**\r
+                * Allows to listen to events on specific types of widgets, even if they are not created yet.\r
+                *\r
+                * Please note that this method inherits parameters from the {@link CKEDITOR.event#method-on} method with one\r
+                * extra parameter at the beginning which is the widget name.\r
+                *\r
+                *              editor.widgets.onWidget( 'image', 'action', function( evt ) {\r
+                *                      // Event `action` occurs on `image` widget.\r
+                *              } );\r
+                *\r
+                * @since 4.5\r
+                * @param {String} widgetName\r
+                * @param {String} eventName\r
+                * @param {Function} listenerFunction\r
+                * @param {Object} [scopeObj]\r
+                * @param {Object} [listenerData]\r
+                * @param {Number} [priority=10]\r
+                */\r
+               onWidget: function( widgetName ) {\r
+                       var args = Array.prototype.slice.call( arguments );\r
+\r
+                       args.shift();\r
+\r
+                       for ( var i in this.instances ) {\r
+                               var instance = this.instances[ i ];\r
+\r
+                               if ( instance.name == widgetName ) {\r
+                                       instance.on.apply( instance, args );\r
+                               }\r
+                       }\r
+\r
+                       this.on( 'instanceCreated', function( evt ) {\r
+                               var widget = evt.data;\r
+\r
+                               if ( widget.name == widgetName ) {\r
+                                       widget.on.apply( widget, args );\r
+                               }\r
+                       } );\r
+               },\r
+\r
+               /**\r
+                * Parses element classes string and returns an object\r
+                * whose keys contain class names. Skips all `cke_*` classes.\r
+                *\r
+                * This method is used by the {@link CKEDITOR.plugins.widget#getClasses} method and\r
+                * may be used when overriding that method.\r
+                *\r
+                * @since 4.4\r
+                * @param {String} classes String (value of `class` attribute).\r
+                * @returns {Object} Object containing classes or `null` if no classes found.\r
+                */\r
+               parseElementClasses: function( classes ) {\r
+                       if ( !classes )\r
+                               return null;\r
+\r
+                       classes = CKEDITOR.tools.trim( classes ).split( /\s+/ );\r
+\r
+                       var cl,\r
+                               obj = {},\r
+                               hasClasses = 0;\r
+\r
+                       while ( ( cl = classes.pop() ) ) {\r
+                               if ( cl.indexOf( 'cke_' ) == -1 )\r
+                                       obj[ cl ] = hasClasses = 1;\r
+                       }\r
+\r
+                       return hasClasses ? obj : null;\r
+               },\r
+\r
+               /**\r
+                * Wraps an element with a widget's non-editable container.\r
+                *\r
+                * If this method is called on an {@link CKEDITOR.htmlParser.element}, then it will\r
+                * also take care of fixing the DOM after wrapping (the wrapper may not be allowed in element's parent).\r
+                *\r
+                * @param {CKEDITOR.dom.element/CKEDITOR.htmlParser.element} element The widget element to be wrapped.\r
+                * @param {String} [widgetName] The name of the widget definition. Defaults to element's `data-widget`\r
+                * attribute value.\r
+                * @returns {CKEDITOR.dom.element/CKEDITOR.htmlParser.element} The wrapper element or `null` if\r
+                * the widget definition of this name is not registered.\r
+                */\r
+               wrapElement: function( element, widgetName ) {\r
+                       var wrapper = null,\r
+                               widgetDef,\r
+                               isInline;\r
+\r
+                       if ( element instanceof CKEDITOR.dom.element ) {\r
+                               widgetName = widgetName || element.data( 'widget' );\r
+                               widgetDef = this.registered[ widgetName ];\r
+\r
+                               if ( !widgetDef )\r
+                                       return null;\r
+\r
+                               // Do not wrap already wrapped element.\r
+                               wrapper = element.getParent();\r
+                               if ( wrapper && wrapper.type == CKEDITOR.NODE_ELEMENT && wrapper.data( 'cke-widget-wrapper' ) )\r
+                                       return wrapper;\r
+\r
+                               // If attribute isn't already set (e.g. for pasted widget), set it.\r
+                               if ( !element.hasAttribute( 'data-cke-widget-keep-attr' ) )\r
+                                       element.data( 'cke-widget-keep-attr', element.data( 'widget' ) ? 1 : 0 );\r
+\r
+                               element.data( 'widget', widgetName );\r
+\r
+                               isInline = isWidgetInline( widgetDef, element.getName() );\r
+\r
+                               wrapper = new CKEDITOR.dom.element( isInline ? 'span' : 'div' );\r
+                               wrapper.setAttributes( getWrapperAttributes( isInline, widgetName ) );\r
+\r
+                               wrapper.data( 'cke-display-name', widgetDef.pathName ? widgetDef.pathName : element.getName() );\r
+\r
+                               // Replace element unless it is a detached one.\r
+                               if ( element.getParent( true ) )\r
+                                       wrapper.replace( element );\r
+                               element.appendTo( wrapper );\r
+                       }\r
+                       else if ( element instanceof CKEDITOR.htmlParser.element ) {\r
+                               widgetName = widgetName || element.attributes[ 'data-widget' ];\r
+                               widgetDef = this.registered[ widgetName ];\r
+\r
+                               if ( !widgetDef )\r
+                                       return null;\r
+\r
+                               wrapper = element.parent;\r
+                               if ( wrapper && wrapper.type == CKEDITOR.NODE_ELEMENT && wrapper.attributes[ 'data-cke-widget-wrapper' ] )\r
+                                       return wrapper;\r
+\r
+                               // If attribute isn't already set (e.g. for pasted widget), set it.\r
+                               if ( !( 'data-cke-widget-keep-attr' in element.attributes ) )\r
+                                       element.attributes[ 'data-cke-widget-keep-attr' ] = element.attributes[ 'data-widget' ] ? 1 : 0;\r
+                               if ( widgetName )\r
+                                       element.attributes[ 'data-widget' ] = widgetName;\r
+\r
+                               isInline = isWidgetInline( widgetDef, element.name );\r
+\r
+                               wrapper = new CKEDITOR.htmlParser.element( isInline ? 'span' : 'div', getWrapperAttributes( isInline, widgetName ) );\r
+                               wrapper.attributes[ 'data-cke-display-name' ] = widgetDef.pathName ? widgetDef.pathName : element.name;\r
+\r
+                               var parent = element.parent,\r
+                                       index;\r
+\r
+                               // Don't detach already detached element.\r
+                               if ( parent ) {\r
+                                       index = element.getIndex();\r
+                                       element.remove();\r
+                               }\r
+\r
+                               wrapper.add( element );\r
+\r
+                               // Insert wrapper fixing DOM (splitting parents if wrapper is not allowed inside them).\r
+                               parent && insertElement( parent, index, wrapper );\r
+                       }\r
+\r
+                       return wrapper;\r
+               },\r
+\r
+               // Expose for tests.\r
+               _tests_createEditableFilter: createEditableFilter\r
+       };\r
+\r
+       CKEDITOR.event.implementOn( Repository.prototype );\r
+\r
+       /**\r
+        * An event fired when a widget instance is created, but before it is fully initialized.\r
+        *\r
+        * @event instanceCreated\r
+        * @param {CKEDITOR.plugins.widget} data The widget instance.\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget instance was destroyed.\r
+        *\r
+        * See also {@link CKEDITOR.plugins.widget#event-destroy}.\r
+        *\r
+        * @event instanceDestroyed\r
+        * @param {CKEDITOR.plugins.widget} data The widget instance.\r
+        */\r
+\r
+       /**\r
+        * An event fired to trigger the selection check.\r
+        *\r
+        * See the {@link #method-checkSelection} method.\r
+        *\r
+        * @event checkSelection\r
+        */\r
+\r
+       /**\r
+        * An event fired by the the {@link #method-checkWidgets} method.\r
+        *\r
+        * It can be canceled in order to stop the {@link #method-checkWidgets}\r
+        * method execution or the event listener can modify the method's options.\r
+        *\r
+        * @event checkWidgets\r
+        * @param [data]\r
+        * @param {Boolean} [data.initOnlyNew] Initialize widgets only on newly wrapped\r
+        * widget elements (those which still have the `cke_widget_new` class). When this option is\r
+        * set to `true`, widgets which were invalidated (e.g. by replacing with a cloned DOM structure)\r
+        * will not be reinitialized. This makes the check faster.\r
+        * @param {Boolean} [data.focusInited] If only one widget is initialized by\r
+        * the method, it will be focused.\r
+        */\r
+\r
+\r
+       /**\r
+        * An instance of a widget. Together with {@link CKEDITOR.plugins.widget.repository} these\r
+        * two classes constitute the core of the Widget System.\r
+        *\r
+        * Note that neither the repository nor the widget instances can be created by using their constructors.\r
+        * A repository instance is automatically set up by the Widget plugin and is accessible under\r
+        * {@link CKEDITOR.editor#widgets}, while widget instances are created and destroyed by the repository.\r
+        *\r
+        * To create a widget, first you need to {@link CKEDITOR.plugins.widget.repository#add register} its\r
+        * {@link CKEDITOR.plugins.widget.definition definition}:\r
+        *\r
+        *              editor.widgets.add( 'simplebox', {\r
+        *                      upcast: function( element ) {\r
+        *                              // Defines which elements will become widgets.\r
+        *                              if ( element.hasClass( 'simplebox' ) )\r
+        *                                      return true;\r
+        *                      },\r
+        *                      init: function() {\r
+        *                              // ...\r
+        *                      }\r
+        *              } );\r
+        *\r
+        * Once the widget definition is registered, widgets will be automatically\r
+        * created when loading data:\r
+        *\r
+        *              editor.setData( '<div class="simplebox">foo</div>', function() {\r
+        *                      console.log( editor.widgets.instances ); // -> An object containing one instance.\r
+        *              } );\r
+        *\r
+        * It is also possible to create instances during runtime by using a command\r
+        * (if a {@link CKEDITOR.plugins.widget.definition#template} property was defined):\r
+        *\r
+        *              // You can execute an automatically defined command to\r
+        *              // insert a new simplebox widget or edit the one currently focused.\r
+        *              editor.execCommand( 'simplebox' );\r
+        *\r
+        * Note: Since CKEditor 4.5 widget's `startupData` can be passed as the command argument:\r
+        *\r
+        *              editor.execCommand( 'simplebox', {\r
+        *                      startupData: {\r
+        *                              align: 'left'\r
+        *                      }\r
+        *              } );\r
+        *\r
+        * A widget can also be created in a completely custom way:\r
+        *\r
+        *              var element = editor.document.createElement( 'div' );\r
+        *              editor.insertElement( element );\r
+        *              var widget = editor.widgets.initOn( element, 'simplebox' );\r
+        *\r
+        * @since 4.3\r
+        * @class CKEDITOR.plugins.widget\r
+        * @mixins CKEDITOR.event\r
+        * @extends CKEDITOR.plugins.widget.definition\r
+        * @constructor Creates an instance of the widget class. Do not use it directly, but instead initialize widgets\r
+        * by using the {@link CKEDITOR.plugins.widget.repository#initOn} method or by the upcasting system.\r
+        * @param {CKEDITOR.plugins.widget.repository} widgetsRepo\r
+        * @param {Number} id Unique ID of this widget instance.\r
+        * @param {CKEDITOR.dom.element} element The widget element.\r
+        * @param {CKEDITOR.plugins.widget.definition} widgetDef Widget's registered definition.\r
+        * @param [startupData] Initial widget data. This data object will overwrite the default data and\r
+        * the data loaded from the DOM.\r
+        */\r
+       function Widget( widgetsRepo, id, element, widgetDef, startupData ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               // Extend this widget with widgetDef-specific methods and properties.\r
+               CKEDITOR.tools.extend( this, widgetDef, {\r
+                       /**\r
+                        * The editor instance.\r
+                        *\r
+                        * @readonly\r
+                        * @property {CKEDITOR.editor}\r
+                        */\r
+                       editor: editor,\r
+\r
+                       /**\r
+                        * This widget's unique (per editor instance) ID.\r
+                        *\r
+                        * @readonly\r
+                        * @property {Number}\r
+                        */\r
+                       id: id,\r
+\r
+                       /**\r
+                        * Whether this widget is an inline widget (based on an inline element unless\r
+                        * forced otherwise by {@link CKEDITOR.plugins.widget.definition#inline}).\r
+                        *\r
+                        * **Note:** This option does not allow to turn a block element into an inline widget.\r
+                        * However, it makes it possible to turn an inline element into a block widget or to\r
+                        * force a correct type in case when automatic recognition fails.\r
+                        *\r
+                        * @readonly\r
+                        * @property {Boolean}\r
+                        */\r
+                       inline: element.getParent().getName() == 'span',\r
+\r
+                       /**\r
+                        * The widget element &mdash; the element on which the widget was initialized.\r
+                        *\r
+                        * @readonly\r
+                        * @property {CKEDITOR.dom.element} element\r
+                        */\r
+                       element: element,\r
+\r
+                       /**\r
+                        * Widget's data object.\r
+                        *\r
+                        * The data can only be set by using the {@link #setData} method.\r
+                        * Changes made to the data fire the {@link #event-data} event.\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       data: CKEDITOR.tools.extend( {}, typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults ),\r
+\r
+                       /**\r
+                        * Indicates if a widget is data-ready. Set to `true` when data from all sources\r
+                        * ({@link CKEDITOR.plugins.widget.definition#defaults}, set in the\r
+                        * {@link #init} method, loaded from the widget's element and startup data coming from the constructor)\r
+                        * are finally loaded. This is immediately followed by the first {@link #event-data}.\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       dataReady: false,\r
+\r
+                       /**\r
+                        * Whether a widget instance was initialized. This means that:\r
+                        *\r
+                        * * An instance was created,\r
+                        * * Its properties were set,\r
+                        * * The `init` method was executed.\r
+                        *\r
+                        * **Note**: The first {@link #event-data} event could not be fired yet which\r
+                        * means that the widget's DOM has not been set up yet. Wait for the {@link #event-ready}\r
+                        * event to be notified when a widget is fully initialized and ready.\r
+                        *\r
+                        * **Note**: Use the {@link #isInited} method to check whether a widget is initialized and\r
+                        * has not been destroyed.\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       inited: false,\r
+\r
+                       /**\r
+                        * Whether a widget instance is ready. This means that the widget is {@link #inited} and\r
+                        * that its DOM was finally set up.\r
+                        *\r
+                        * **Note:** Use the {@link #isReady} method to check whether a widget is ready and\r
+                        * has not been destroyed.\r
+                        *\r
+                        * @readonly\r
+                        */\r
+                       ready: false,\r
+\r
+                       // Revert what widgetDef could override (automatic #edit listener).\r
+                       edit: Widget.prototype.edit,\r
+\r
+                       /**\r
+                        * The nested editable element which is currently focused.\r
+                        *\r
+                        * @readonly\r
+                        * @property {CKEDITOR.plugins.widget.nestedEditable}\r
+                        */\r
+                       focusedEditable: null,\r
+\r
+                       /**\r
+                        * The widget definition from which this instance was created.\r
+                        *\r
+                        * @readonly\r
+                        * @property {CKEDITOR.plugins.widget.definition} definition\r
+                        */\r
+                       definition: widgetDef,\r
+\r
+                       /**\r
+                        * Link to the widget repository which created this instance.\r
+                        *\r
+                        * @readonly\r
+                        * @property {CKEDITOR.plugins.widget.repository} repository\r
+                        */\r
+                       repository: widgetsRepo,\r
+\r
+                       draggable: widgetDef.draggable !== false,\r
+\r
+                       // WAAARNING: Overwrite widgetDef's priv object, because otherwise violent unicorn's gonna visit you.\r
+                       _: {\r
+                               downcastFn: ( widgetDef.downcast && typeof widgetDef.downcast == 'string' ) ?\r
+                                       widgetDef.downcasts[ widgetDef.downcast ] : widgetDef.downcast\r
+                       }\r
+               }, true );\r
+\r
+               /**\r
+                * An object of widget component elements.\r
+                *\r
+                * For every `partName => selector` pair in {@link CKEDITOR.plugins.widget.definition#parts},\r
+                * one `partName => element` pair is added to this object during the widget initialization.\r
+                *\r
+                * @readonly\r
+                * @property {Object} parts\r
+                */\r
+\r
+               /**\r
+                * The template which will be used to create a new widget element (when the widget's command is executed).\r
+                * It will be populated with {@link #defaults default values}.\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.template} template\r
+                */\r
+\r
+               /**\r
+                * The widget wrapper &mdash; a non-editable `div` or `span` element (depending on {@link #inline})\r
+                * which is a parent of the {@link #element} and widget compontents like the drag handler and the {@link #mask}.\r
+                * It is the outermost widget element.\r
+                *\r
+                * @readonly\r
+                * @property {CKEDITOR.dom.element} wrapper\r
+                */\r
+\r
+               widgetsRepo.fire( 'instanceCreated', this );\r
+\r
+               setupWidget( this, widgetDef );\r
+\r
+               this.init && this.init();\r
+\r
+               // Finally mark widget as inited.\r
+               this.inited = true;\r
+\r
+               setupWidgetData( this, startupData );\r
+\r
+               // If at some point (e.g. in #data listener) widget hasn't been destroyed\r
+               // and widget is already attached to document then fire #ready.\r
+               if ( this.isInited() && editor.editable().contains( this.wrapper ) ) {\r
+                       this.ready = true;\r
+                       this.fire( 'ready' );\r
+               }\r
+       }\r
+\r
+       Widget.prototype = {\r
+               /**\r
+                * Adds a class to the widget element. This method is used by\r
+                * the {@link #applyStyle} method and should be overridden by widgets\r
+                * which should handle classes differently (e.g. add them to other elements).\r
+                *\r
+                * Since 4.6.0 this method also adds a corresponding class prefixed with {@link #WRAPPER_CLASS_PREFIX}\r
+                * to the widget wrapper element.\r
+                *\r
+                * **Note**: This method should not be used directly. Use the {@link #setData} method to\r
+                * set the `classes` property. Read more in the {@link #setData} documentation.\r
+                *\r
+                * See also: {@link #removeClass}, {@link #hasClass}, {@link #getClasses}.\r
+                *\r
+                * @since 4.4\r
+                * @param {String} className The class name to be added.\r
+                */\r
+               addClass: function( className ) {\r
+                       this.element.addClass( className );\r
+                       this.wrapper.addClass( Widget.WRAPPER_CLASS_PREFIX + className );\r
+               },\r
+\r
+               /**\r
+                * Applies the specified style to the widget. It is highly recommended to use the\r
+                * {@link CKEDITOR.editor#applyStyle} or {@link CKEDITOR.style#apply} methods instead of\r
+                * using this method directly, because unlike editor's and style's methods, this one\r
+                * does not perform any checks.\r
+                *\r
+                * By default this method handles only classes defined in the style. It clones existing\r
+                * classes which are stored in the {@link #property-data widget data}'s `classes` property,\r
+                * adds new classes, and calls the {@link #setData} method if at least one new class was added.\r
+                * Then, using the {@link #event-data} event listener widget applies modifications passing\r
+                * new classes to the {@link #addClass} method.\r
+                *\r
+                * If you need to handle classes differently than in the default way, you can override the\r
+                * {@link #addClass} and related methods. You can also handle other style properties than `classes`\r
+                * by overriding this method.\r
+                *\r
+                * See also: {@link #checkStyleActive}, {@link #removeStyle}.\r
+                *\r
+                * @since 4.4\r
+                * @param {CKEDITOR.style} style The custom widget style to be applied.\r
+                */\r
+               applyStyle: function( style ) {\r
+                       applyRemoveStyle( this, style, 1 );\r
+               },\r
+\r
+               /**\r
+                * Checks if the specified style is applied to this widget. It is highly recommended to use the\r
+                * {@link CKEDITOR.style#checkActive} method instead of using this method directly,\r
+                * because unlike style's method, this one does not perform any checks.\r
+                *\r
+                * By default this method handles only classes defined in the style and passes\r
+                * them to the {@link #hasClass} method. You can override these methods to handle classes\r
+                * differently or to handle more of the style properties.\r
+                *\r
+                * See also: {@link #applyStyle}, {@link #removeStyle}.\r
+                *\r
+                * @since 4.4\r
+                * @param {CKEDITOR.style} style The custom widget style to be checked.\r
+                * @returns {Boolean} Whether the style is applied to this widget.\r
+                */\r
+               checkStyleActive: function( style ) {\r
+                       var classes = getStyleClasses( style ),\r
+                               cl;\r
+\r
+                       if ( !classes )\r
+                               return false;\r
+\r
+                       while ( ( cl = classes.pop() ) ) {\r
+                               if ( !this.hasClass( cl ) )\r
+                                       return false;\r
+                       }\r
+                       return true;\r
+               },\r
+\r
+               /**\r
+                * Destroys this widget instance.\r
+                *\r
+                * Use {@link CKEDITOR.plugins.widget.repository#destroy} when possible instead of this method.\r
+                *\r
+                * This method fires the {#event-destroy} event.\r
+                *\r
+                * @param {Boolean} [offline] Whether a widget is offline (detached from the DOM tree) &mdash;\r
+                * in this case the DOM (attributes, classes, etc.) will not be cleaned up.\r
+                */\r
+               destroy: function( offline ) {\r
+                       this.fire( 'destroy' );\r
+\r
+                       if ( this.editables ) {\r
+                               for ( var name in this.editables )\r
+                                       this.destroyEditable( name, offline );\r
+                       }\r
+\r
+                       if ( !offline ) {\r
+                               if ( this.element.data( 'cke-widget-keep-attr' ) == '0' )\r
+                                       this.element.removeAttribute( 'data-widget' );\r
+                               this.element.removeAttributes( [ 'data-cke-widget-data', 'data-cke-widget-keep-attr' ] );\r
+                               this.element.removeClass( 'cke_widget_element' );\r
+                               this.element.replace( this.wrapper );\r
+                       }\r
+\r
+                       this.wrapper = null;\r
+               },\r
+\r
+               /**\r
+                * Destroys a nested editable and all nested widgets.\r
+                *\r
+                * @param {String} editableName Nested editable name.\r
+                * @param {Boolean} [offline] See {@link #method-destroy} method.\r
+                */\r
+               destroyEditable: function( editableName, offline ) {\r
+                       var editable = this.editables[ editableName ];\r
+\r
+                       editable.removeListener( 'focus', onEditableFocus );\r
+                       editable.removeListener( 'blur', onEditableBlur );\r
+                       this.editor.focusManager.remove( editable );\r
+\r
+                       if ( !offline ) {\r
+                               this.repository.destroyAll( false, editable );\r
+                               editable.removeClass( 'cke_widget_editable' );\r
+                               editable.removeClass( 'cke_widget_editable_focused' );\r
+                               editable.removeAttributes( [ 'contenteditable', 'data-cke-widget-editable', 'data-cke-enter-mode' ] );\r
+                       }\r
+\r
+                       delete this.editables[ editableName ];\r
+               },\r
+\r
+               /**\r
+                * Starts widget editing.\r
+                *\r
+                * This method fires the {@link CKEDITOR.plugins.widget#event-edit} event\r
+                * which may be canceled in order to prevent it from opening a dialog window.\r
+                *\r
+                * The dialog window name is obtained from the event's data `dialog` property or\r
+                * from {@link CKEDITOR.plugins.widget.definition#dialog}.\r
+                *\r
+                * @returns {Boolean} Returns `true` if a dialog window was opened.\r
+                */\r
+               edit: function() {\r
+                       var evtData = { dialog: this.dialog },\r
+                               that = this;\r
+\r
+                       // Edit event was blocked or there's no dialog to be automatically opened.\r
+                       if ( this.fire( 'edit', evtData ) === false || !evtData.dialog )\r
+                               return false;\r
+\r
+                       this.editor.openDialog( evtData.dialog, function( dialog ) {\r
+                               var showListener,\r
+                                       okListener;\r
+\r
+                               // Allow to add a custom dialog handler.\r
+                               if ( that.fire( 'dialog', dialog ) === false )\r
+                                       return;\r
+\r
+                               showListener = dialog.on( 'show', function() {\r
+                                       dialog.setupContent( that );\r
+                               } );\r
+\r
+                               okListener = dialog.on( 'ok', function() {\r
+                                       // Commit dialog's fields, but prevent from\r
+                                       // firing data event for every field. Fire only one,\r
+                                       // bulk event at the end.\r
+                                       var dataChanged,\r
+                                               dataListener = that.on( 'data', function( evt ) {\r
+                                                       dataChanged = 1;\r
+                                                       evt.cancel();\r
+                                               }, null, null, 0 );\r
+\r
+                                       // Create snapshot preceeding snapshot with changed widget...\r
+                                       // TODO it should not be required, but it is and I found similar\r
+                                       // code in dialog#ok listener in dialog/plugin.js.\r
+                                       that.editor.fire( 'saveSnapshot' );\r
+                                       dialog.commitContent( that );\r
+\r
+                                       dataListener.removeListener();\r
+                                       if ( dataChanged ) {\r
+                                               that.fire( 'data', that.data );\r
+                                               that.editor.fire( 'saveSnapshot' );\r
+                                       }\r
+                               } );\r
+\r
+                               dialog.once( 'hide', function() {\r
+                                       showListener.removeListener();\r
+                                       okListener.removeListener();\r
+                               } );\r
+                       } );\r
+\r
+                       return true;\r
+               },\r
+\r
+               /**\r
+                * Returns widget element classes parsed to an object. This method\r
+                * is used to populate the `classes` property of widget's {@link #property-data}.\r
+                *\r
+                * This method reuses {@link CKEDITOR.plugins.widget.repository#parseElementClasses}.\r
+                * It should be overriden if a widget should handle classes differently (e.g. on other elements).\r
+                *\r
+                * See also: {@link #removeClass}, {@link #addClass}, {@link #hasClass}.\r
+                *\r
+                * @since 4.4\r
+                * @returns {Object}\r
+                */\r
+               getClasses: function() {\r
+                       return this.repository.parseElementClasses( this.element.getAttribute( 'class' ) );\r
+               },\r
+\r
+               /**\r
+                * Checks if the widget element has specified class. This method is used by\r
+                * the {@link #checkStyleActive} method and should be overriden by widgets\r
+                * which should handle classes differently (e.g. on other elements).\r
+                *\r
+                * See also: {@link #removeClass}, {@link #addClass}, {@link #getClasses}.\r
+                *\r
+                * @since 4.4\r
+                * @param {String} className The class to be checked.\r
+                * @param {Boolean} Whether a widget has specified class.\r
+                */\r
+               hasClass: function( className ) {\r
+                       return this.element.hasClass( className );\r
+               },\r
+\r
+               /**\r
+                * Initializes a nested editable.\r
+                *\r
+                * **Note**: Only elements from {@link CKEDITOR.dtd#$editable} may become editables.\r
+                *\r
+                * @param {String} editableName The nested editable name.\r
+                * @param {CKEDITOR.plugins.widget.nestedEditable.definition} definition The definition of the nested editable.\r
+                * @returns {Boolean} Whether an editable was successfully initialized.\r
+                */\r
+               initEditable: function( editableName, definition ) {\r
+                       // Don't fetch just first element which matched selector but look for a correct one. (#13334)\r
+                       var editable = this._findOneNotNested( definition.selector );\r
+\r
+                       if ( editable && editable.is( CKEDITOR.dtd.$editable ) ) {\r
+                               editable = new NestedEditable( this.editor, editable, {\r
+                                       filter: createEditableFilter.call( this.repository, this.name, editableName, definition )\r
+                               } );\r
+                               this.editables[ editableName ] = editable;\r
+\r
+                               editable.setAttributes( {\r
+                                       contenteditable: 'true',\r
+                                       'data-cke-widget-editable': editableName,\r
+                                       'data-cke-enter-mode': editable.enterMode\r
+                               } );\r
+\r
+                               if ( editable.filter )\r
+                                       editable.data( 'cke-filter', editable.filter.id );\r
+\r
+                               editable.addClass( 'cke_widget_editable' );\r
+                               // This class may be left when d&ding widget which\r
+                               // had focused editable. Clean this class here, not in\r
+                               // cleanUpWidgetElement for performance and code size reasons.\r
+                               editable.removeClass( 'cke_widget_editable_focused' );\r
+\r
+                               if ( definition.pathName )\r
+                                       editable.data( 'cke-display-name', definition.pathName );\r
+\r
+                               this.editor.focusManager.add( editable );\r
+                               editable.on( 'focus', onEditableFocus, this );\r
+                               CKEDITOR.env.ie && editable.on( 'blur', onEditableBlur, this );\r
+\r
+                               // Finally, process editable's data. This data wasn't processed when loading\r
+                               // editor's data, becuase they need to be processed separately, with its own filters and settings.\r
+                               editable._.initialSetData = true;\r
+                               editable.setData( editable.getHtml() );\r
+\r
+                               return true;\r
+                       }\r
+\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                * Looks inside wrapper element to find a node that\r
+                * matches given selector and is not nested in other widget. (#13334)\r
+                *\r
+                * @since 4.5\r
+                * @private\r
+                * @param {String} selector Selector to match.\r
+                * @returns {CKEDITOR.dom.element} Matched element or `null` if a node has not been found.\r
+                */\r
+               _findOneNotNested: function( selector ) {\r
+                       var matchedElements = this.wrapper.find( selector ),\r
+                               match,\r
+                               closestWrapper;\r
+\r
+                       for ( var i = 0; i < matchedElements.count(); i++ ) {\r
+                               match = matchedElements.getItem( i );\r
+                               closestWrapper = match.getAscendant( Widget.isDomWidgetWrapper );\r
+\r
+                               // The closest ascendant-wrapper of this match defines to which widget\r
+                               // this match belongs. If the ascendant is this widget's wrapper\r
+                               // it means that the match is not nested in other widget.\r
+                               if ( this.wrapper.equals( closestWrapper ) ) {\r
+                                       return match;\r
+                               }\r
+                       }\r
+\r
+                       return null;\r
+               },\r
+\r
+               /**\r
+                * Checks if a widget has already been initialized and has not been destroyed yet.\r
+                *\r
+                * See {@link #inited} for more details.\r
+                *\r
+                * @returns {Boolean}\r
+                */\r
+               isInited: function() {\r
+                       return !!( this.wrapper && this.inited );\r
+               },\r
+\r
+               /**\r
+                * Checks if a widget is ready and has not been destroyed yet.\r
+                *\r
+                * See {@link #property-ready} for more details.\r
+                *\r
+                * @returns {Boolean}\r
+                */\r
+               isReady: function() {\r
+                       return this.isInited() && this.ready;\r
+               },\r
+\r
+               /**\r
+                * Focuses a widget by selecting it.\r
+                */\r
+               focus: function() {\r
+                       var sel = this.editor.getSelection();\r
+\r
+                       // Fake the selection before focusing editor, to avoid unpreventable viewports scrolling\r
+                       // on Webkit/Blink/IE which is done because there's no selection or selection was somewhere else than widget.\r
+                       if ( sel ) {\r
+                               var isDirty = this.editor.checkDirty();\r
+\r
+                               sel.fake( this.wrapper );\r
+\r
+                               !isDirty && this.editor.resetDirty();\r
+                       }\r
+\r
+                       // Always focus editor (not only when focusManger.hasFocus is false) (because of #10483).\r
+                       this.editor.focus();\r
+               },\r
+\r
+               /**\r
+                * Removes a class from the widget element. This method is used by\r
+                * the {@link #removeStyle} method and should be overriden by widgets\r
+                * which should handle classes differently (e.g. on other elements).\r
+                *\r
+                * **Note**: This method should not be used directly. Use the {@link #setData} method to\r
+                * set the `classes` property. Read more in the {@link #setData} documentation.\r
+                *\r
+                * See also: {@link #hasClass}, {@link #addClass}.\r
+                *\r
+                * @since 4.4\r
+                * @param {String} className The class to be removed.\r
+                */\r
+               removeClass: function( className ) {\r
+                       this.element.removeClass( className );\r
+                       this.wrapper.removeClass( Widget.WRAPPER_CLASS_PREFIX + className );\r
+               },\r
+\r
+               /**\r
+                * Removes the specified style from the widget. It is highly recommended to use the\r
+                * {@link CKEDITOR.editor#removeStyle} or {@link CKEDITOR.style#remove} methods instead of\r
+                * using this method directly, because unlike editor's and style's methods, this one\r
+                * does not perform any checks.\r
+                *\r
+                * Read more about how applying/removing styles works in the {@link #applyStyle} method documentation.\r
+                *\r
+                * See also {@link #checkStyleActive}, {@link #applyStyle}, {@link #getClasses}.\r
+                *\r
+                * @since 4.4\r
+                * @param {CKEDITOR.style} style The custom widget style to be removed.\r
+                */\r
+               removeStyle: function( style ) {\r
+                       applyRemoveStyle( this, style, 0 );\r
+               },\r
+\r
+               /**\r
+                * Sets widget value(s) in the {@link #property-data} object.\r
+                * If the given value(s) modifies current ones, the {@link #event-data} event is fired.\r
+                *\r
+                *              this.setData( 'align', 'left' );\r
+                *              this.data.align; // -> 'left'\r
+                *\r
+                *              this.setData( { align: 'right', opened: false } );\r
+                *              this.data.align; // -> 'right'\r
+                *              this.data.opened; // -> false\r
+                *\r
+                * Set values are stored in {@link #element}'s attribute (`data-cke-widget-data`),\r
+                * in a JSON string, therefore {@link #property-data} should contain\r
+                * only serializable data.\r
+                *\r
+                * **Note:** A special data property, `classes`, exists. It contains an object with\r
+                * classes which were returned by the {@link #getClasses} method during the widget initialization.\r
+                * This property is then used by the {@link #applyStyle} and {@link #removeStyle} methods.\r
+                * When it is changed (the reference to object must be changed!), the widget updates its classes by\r
+                * using the {@link #addClass} and {@link #removeClass} methods.\r
+                *\r
+                *              // Adding a new class.\r
+                *              var classes = CKEDITOR.tools.clone( widget.data.classes );\r
+                *              classes.newClass = 1;\r
+                *              widget.setData( 'classes', classes );\r
+                *\r
+                *              // Removing a class.\r
+                *              var classes = CKEDITOR.tools.clone( widget.data.classes );\r
+                *              delete classes.newClass;\r
+                *              widget.setData( 'classes', classes );\r
+                *\r
+                * @param {String/Object} keyOrData\r
+                * @param {Object} value\r
+                * @chainable\r
+                */\r
+               setData: function( key, value ) {\r
+                       var data = this.data,\r
+                               modified = 0;\r
+\r
+                       if ( typeof key == 'string' ) {\r
+                               if ( data[ key ] !== value ) {\r
+                                       data[ key ] = value;\r
+                                       modified = 1;\r
+                               }\r
+                       }\r
+                       else {\r
+                               var newData = key;\r
+\r
+                               for ( key in newData ) {\r
+                                       if ( data[ key ] !== newData[ key ] ) {\r
+                                               modified = 1;\r
+                                               data[ key ] = newData[ key ];\r
+                                       }\r
+                               }\r
+                       }\r
+\r
+                       // Block firing data event and overwriting data element before setupWidgetData is executed.\r
+                       if ( modified && this.dataReady ) {\r
+                               writeDataToElement( this );\r
+                               this.fire( 'data', data );\r
+                       }\r
+\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Changes the widget's focus state. This method is executed automatically after\r
+                * a widget was focused by the {@link #method-focus} method or the selection was moved\r
+                * out of the widget.\r
+                *\r
+                * This is a low-level method which is not integrated with e.g. the undo manager.\r
+                * Use the {@link #method-focus} method instead.\r
+                *\r
+                * @param {Boolean} selected Whether to select or deselect this widget.\r
+                * @chainable\r
+                */\r
+               setFocused: function( focused ) {\r
+                       this.wrapper[ focused ? 'addClass' : 'removeClass' ]( 'cke_widget_focused' );\r
+                       this.fire( focused ? 'focus' : 'blur' );\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Changes the widget's select state. This method is executed automatically after\r
+                * a widget was selected by the {@link #method-focus} method or the selection\r
+                * was moved out of the widget.\r
+                *\r
+                * This is a low-level method which is not integrated with e.g. the undo manager.\r
+                * Use the {@link #method-focus} method instead or simply change the selection.\r
+                *\r
+                * @param {Boolean} selected Whether to select or deselect this widget.\r
+                * @chainable\r
+                */\r
+               setSelected: function( selected ) {\r
+                       this.wrapper[ selected ? 'addClass' : 'removeClass' ]( 'cke_widget_selected' );\r
+                       this.fire(  selected ? 'select' : 'deselect' );\r
+                       return this;\r
+               },\r
+\r
+               /**\r
+                * Repositions drag handler according to the widget's element position. Should be called from events, like mouseover.\r
+                */\r
+               updateDragHandlerPosition: function() {\r
+                       var editor = this.editor,\r
+                               domElement = this.element.$,\r
+                               oldPos = this._.dragHandlerOffset,\r
+                               newPos = {\r
+                                       x: domElement.offsetLeft,\r
+                                       y: domElement.offsetTop - DRAG_HANDLER_SIZE\r
+                               };\r
+\r
+                       if ( oldPos && newPos.x == oldPos.x && newPos.y == oldPos.y )\r
+                               return;\r
+\r
+                       // We need to make sure that dirty state is not changed (#11487).\r
+                       var initialDirty = editor.checkDirty();\r
+\r
+                       editor.fire( 'lockSnapshot' );\r
+                       this.dragHandlerContainer.setStyles( {\r
+                               top: newPos.y + 'px',\r
+                               left: newPos.x + 'px',\r
+                               display: 'block'\r
+                       } );\r
+                       editor.fire( 'unlockSnapshot' );\r
+                       !initialDirty && editor.resetDirty();\r
+\r
+                       this._.dragHandlerOffset = newPos;\r
+               }\r
+       };\r
+\r
+       CKEDITOR.event.implementOn( Widget.prototype );\r
+\r
+       /**\r
+        * Gets the {@link #isDomNestedEditable nested editable}\r
+        * (returned as a {@link CKEDITOR.dom.element}, not as a {@link CKEDITOR.plugins.widget.nestedEditable})\r
+        * closest to the `node` or the `node` if it is a nested editable itself.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.element} guard Stop ancestor search on this node (usually editor's editable).\r
+        * @param {CKEDITOR.dom.node} node Start the search from this node.\r
+        * @returns {CKEDITOR.dom.element/null} Element or `null` if not found.\r
+        */\r
+       Widget.getNestedEditable = function( guard, node ) {\r
+               if ( !node || node.equals( guard ) )\r
+                       return null;\r
+\r
+               if ( Widget.isDomNestedEditable( node ) )\r
+                       return node;\r
+\r
+               return Widget.getNestedEditable( guard, node.getParent() );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a widget's drag handle element.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.node} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isDomDragHandler = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-drag-handler' );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a container of the widget's drag handle element.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.node} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isDomDragHandlerContainer = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.hasClass( 'cke_widget_drag_handler_container' );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a {@link CKEDITOR.plugins.widget#editables nested editable}.\r
+        * Note that this function only checks whether it is the right element, not whether\r
+        * the passed `node` is an instance of {@link CKEDITOR.plugins.widget.nestedEditable}.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.node} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isDomNestedEditable = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-editable' );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a {@link CKEDITOR.plugins.widget#element widget element}.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.node} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isDomWidgetElement = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-widget' );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a {@link CKEDITOR.plugins.widget#wrapper widget wrapper}.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.dom.element} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isDomWidgetWrapper = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && node.hasAttribute( 'data-cke-widget-wrapper' );\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a {@link CKEDITOR.plugins.widget#element widget element}.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.htmlParser.node} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isParserWidgetElement = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && !!node.attributes[ 'data-widget' ];\r
+       };\r
+\r
+       /**\r
+        * Checks whether the `node` is a {@link CKEDITOR.plugins.widget#wrapper widget wrapper}.\r
+        *\r
+        * @since 4.5\r
+        * @static\r
+        * @param {CKEDITOR.htmlParser.element} node\r
+        * @returns {Boolean}\r
+        */\r
+       Widget.isParserWidgetWrapper = function( node ) {\r
+               return node.type == CKEDITOR.NODE_ELEMENT && !!node.attributes[ 'data-cke-widget-wrapper' ];\r
+       };\r
+\r
+       /**\r
+        * Prefix added to wrapper classes. Each class added to the widget element by the {@link #addClass}\r
+        * method will also be added to the wrapper prefixed with it.\r
+        *\r
+        * @since 4.6.0\r
+        * @static\r
+        * @readonly\r
+        * @property {String} [='cke_widget_wrapper_']\r
+        */\r
+       Widget.WRAPPER_CLASS_PREFIX = 'cke_widget_wrapper_';\r
+\r
+       /**\r
+        * An event fired when a widget is ready (fully initialized). This event is fired after:\r
+        *\r
+        * * {@link #init} is called,\r
+        * * The first {@link #event-data} event is fired,\r
+        * * A widget is attached to the document.\r
+        *\r
+        * Therefore, in case of widget creation with a command which opens a dialog window, this event\r
+        * will be delayed after the dialog window is closed and the widget is finally inserted into the document.\r
+        *\r
+        * **Note**: If your widget does not use automatic dialog window binding (i.e. you open the dialog window manually)\r
+        * or another situation in which the widget wrapper is not attached to document at the time when it is\r
+        * initialized occurs, you need to take care of firing {@link #event-ready} yourself.\r
+        *\r
+        * See also {@link #property-ready} and {@link #property-inited} properties, and\r
+        * {@link #isReady} and {@link #isInited} methods.\r
+        *\r
+        * @event ready\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is about to be destroyed, but before it is\r
+        * fully torn down.\r
+        *\r
+        * @event destroy\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is focused.\r
+        *\r
+        * Widget can be focused by executing {@link #method-focus}.\r
+        *\r
+        * @event focus\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is blurred.\r
+        *\r
+        * @event blur\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is selected.\r
+        *\r
+        * @event select\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is deselected.\r
+        *\r
+        * @event deselect\r
+        */\r
+\r
+       /**\r
+        * An event fired by the {@link #method-edit} method. It can be canceled\r
+        * in order to stop the default action (opening a dialog window and/or\r
+        * {@link CKEDITOR.plugins.widget.repository#finalizeCreation finalizing widget creation}).\r
+        *\r
+        * @event edit\r
+        * @param data\r
+        * @param {String} data.dialog Defaults to {@link CKEDITOR.plugins.widget.definition#dialog}\r
+        * and can be changed or set by the listener.\r
+        */\r
+\r
+       /**\r
+        * An event fired when a dialog window for widget editing is opened.\r
+        * This event can be canceled in order to handle the editing dialog in a custom manner.\r
+        *\r
+        * @event dialog\r
+        * @param {CKEDITOR.dialog} data The opened dialog window instance.\r
+        */\r
+\r
+       /**\r
+        * An event fired when a key is pressed on a focused widget.\r
+        * This event is forwarded from the {@link CKEDITOR.editor#key} event and\r
+        * has the ability to block editor keystrokes if it is canceled.\r
+        *\r
+        * @event key\r
+        * @param data\r
+        * @param {Number} data.keyCode A number representing the key code (or combination).\r
+        */\r
+\r
+       /**\r
+        * An event fired when a widget is double clicked.\r
+        *\r
+        * **Note:** If a default editing action is executed on double click (i.e. a widget has a\r
+        * {@link CKEDITOR.plugins.widget.definition#dialog dialog} defined and the {@link #event-doubleclick} event was not\r
+        * canceled), this event will be automatically canceled, so a listener added with the default priority (10)\r
+        * will not be executed. Use a listener with low priority (e.g. 5) to be sure that it will be executed.\r
+        *\r
+        *              widget.on( 'doubleclick', function( evt ) {\r
+        *                      console.log( 'widget#doubleclick' );\r
+        *              }, null, null, 5 );\r
+        *\r
+        * If your widget handles double click in a special way (so the default editing action is not executed),\r
+        * make sure you cancel this event, because otherwise it will be propagated to {@link CKEDITOR.editor#doubleclick}\r
+        * and another feature may step in (e.g. a Link dialog window may be opened if your widget was inside a link).\r
+        *\r
+        * @event doubleclick\r
+        * @param data\r
+        * @param {CKEDITOR.dom.element} data.element The double-clicked element.\r
+        */\r
+\r
+       /**\r
+        * An event fired when the context menu is opened for a widget.\r
+        *\r
+        * @event contextMenu\r
+        * @param data The object containing context menu options to be added\r
+        * for this widget. See {@link CKEDITOR.plugins.contextMenu#addListener}.\r
+        */\r
+\r
+       /**\r
+        * An event fired when the widget data changed. See the {@link #setData} method and the {@link #property-data} property.\r
+        *\r
+        * @event data\r
+        */\r
+\r
+\r
+\r
+       /**\r
+        * The wrapper class for editable elements inside widgets.\r
+        *\r
+        * Do not use directly. Use {@link CKEDITOR.plugins.widget.definition#editables} or\r
+        * {@link CKEDITOR.plugins.widget#initEditable}.\r
+        *\r
+        * @class CKEDITOR.plugins.widget.nestedEditable\r
+        * @extends CKEDITOR.dom.element\r
+        * @constructor\r
+        * @param {CKEDITOR.editor} editor\r
+        * @param {CKEDITOR.dom.element} element\r
+        * @param config\r
+        * @param {CKEDITOR.filter} [config.filter]\r
+        */\r
+       function NestedEditable( editor, element, config ) {\r
+               // Call the base constructor.\r
+               CKEDITOR.dom.element.call( this, element.$ );\r
+               this.editor = editor;\r
+               this._ = {};\r
+               var filter = this.filter = config.filter;\r
+\r
+               // If blockless editable - always use BR mode.\r
+               if ( !CKEDITOR.dtd[ this.getName() ].p )\r
+                       this.enterMode = this.shiftEnterMode = CKEDITOR.ENTER_BR;\r
+               else {\r
+                       this.enterMode = filter ? filter.getAllowedEnterMode( editor.enterMode ) : editor.enterMode;\r
+                       this.shiftEnterMode = filter ? filter.getAllowedEnterMode( editor.shiftEnterMode, true ) : editor.shiftEnterMode;\r
+               }\r
+       }\r
+\r
+       NestedEditable.prototype = CKEDITOR.tools.extend( CKEDITOR.tools.prototypedCopy( CKEDITOR.dom.element.prototype ), {\r
+               /**\r
+                * Sets the editable data. The data will be passed through the {@link CKEDITOR.editor#dataProcessor}\r
+                * and the {@link CKEDITOR.editor#filter}. This ensures that the data was filtered and prepared to be\r
+                * edited like the {@link CKEDITOR.editor#method-setData editor data}.\r
+                *\r
+                * Before content is changed, all nested widgets are destroyed. Afterwards, after new content is loaded,\r
+                * all nested widgets are initialized.\r
+                *\r
+                * @param {String} data\r
+                */\r
+               setData: function( data ) {\r
+                       // For performance reasons don't call destroyAll when initializing a nested editable,\r
+                       // because there are no widgets inside.\r
+                       if ( !this._.initialSetData ) {\r
+                               // Destroy all nested widgets before setting data.\r
+                               this.editor.widgets.destroyAll( false, this );\r
+                       }\r
+                       this._.initialSetData = false;\r
+\r
+                       data = this.editor.dataProcessor.toHtml( data, {\r
+                               context: this.getName(),\r
+                               filter: this.filter,\r
+                               enterMode: this.enterMode\r
+                       } );\r
+                       this.setHtml( data );\r
+\r
+                       this.editor.widgets.initOnAll( this );\r
+               },\r
+\r
+               /**\r
+                * Gets the editable data. Like {@link #setData}, this method will process and filter the data.\r
+                *\r
+                * @returns {String}\r
+                */\r
+               getData: function() {\r
+                       return this.editor.dataProcessor.toDataFormat( this.getHtml(), {\r
+                               context: this.getName(),\r
+                               filter: this.filter,\r
+                               enterMode: this.enterMode\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * The editor instance.\r
+        *\r
+        * @readonly\r
+        * @property {CKEDITOR.editor} editor\r
+        */\r
+\r
+       /**\r
+        * The filter instance if allowed content rules were defined.\r
+        *\r
+        * @readonly\r
+        * @property {CKEDITOR.filter} filter\r
+        */\r
+\r
+       /**\r
+        * The enter mode active in this editable.\r
+        * It is determined from editable's name (whether it is a blockless editable),\r
+        * its allowed content rules (if defined) and the default editor's mode.\r
+        *\r
+        * @readonly\r
+        * @property {Number} enterMode\r
+        */\r
+\r
+       /**\r
+        * The shift enter move active in this editable.\r
+        *\r
+        * @readonly\r
+        * @property {Number} shiftEnterMode\r
+        */\r
+\r
+\r
+       //\r
+       // REPOSITORY helpers -----------------------------------------------------\r
+       //\r
+\r
+       function addWidgetButtons( editor ) {\r
+               var widgets = editor.widgets.registered,\r
+                       widget,\r
+                       widgetName,\r
+                       widgetButton;\r
+\r
+               for ( widgetName in widgets ) {\r
+                       widget = widgets[ widgetName ];\r
+\r
+                       // Create button if defined.\r
+                       widgetButton = widget.button;\r
+                       if ( widgetButton && editor.ui.addButton ) {\r
+                               editor.ui.addButton( CKEDITOR.tools.capitalize( widget.name, true ), {\r
+                                       label: widgetButton,\r
+                                       command: widget.name,\r
+                                       toolbar: 'insert,10'\r
+                               } );\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Create a command creating and editing widget.\r
+       //\r
+       // @param editor\r
+       // @param {CKEDITOR.plugins.widget.definition} widgetDef\r
+       function addWidgetCommand( editor, widgetDef ) {\r
+               editor.addCommand( widgetDef.name, {\r
+                       exec: function( editor, commandData ) {\r
+                               var focused = editor.widgets.focused;\r
+                               // If a widget of the same type is focused, start editing.\r
+                               if ( focused && focused.name == widgetDef.name )\r
+                                       focused.edit();\r
+                               // Otherwise...\r
+                               // ... use insert method is was defined.\r
+                               else if ( widgetDef.insert )\r
+                                       widgetDef.insert();\r
+                               // ... or create a brand-new widget from template.\r
+                               else if ( widgetDef.template ) {\r
+                                       var defaults = typeof widgetDef.defaults == 'function' ? widgetDef.defaults() : widgetDef.defaults,\r
+                                               element = CKEDITOR.dom.element.createFromHtml( widgetDef.template.output( defaults ) ),\r
+                                               instance,\r
+                                               wrapper = editor.widgets.wrapElement( element, widgetDef.name ),\r
+                                               temp = new CKEDITOR.dom.documentFragment( wrapper.getDocument() );\r
+\r
+                                       // Append wrapper to a temporary document. This will unify the environment\r
+                                       // in which #data listeners work when creating and editing widget.\r
+                                       temp.append( wrapper );\r
+                                       instance = editor.widgets.initOn( element, widgetDef, commandData && commandData.startupData );\r
+\r
+                                       // Instance could be destroyed during initialization.\r
+                                       // In this case finalize creation if some new widget\r
+                                       // was left in temporary document fragment.\r
+                                       if ( !instance ) {\r
+                                               finalizeCreation();\r
+                                               return;\r
+                                       }\r
+\r
+                                       // Listen on edit to finalize widget insertion.\r
+                                       //\r
+                                       // * If dialog was set, then insert widget after dialog was successfully saved or destroy this\r
+                                       // temporary instance.\r
+                                       // * If dialog wasn't set and edit wasn't canceled, insert widget.\r
+                                       var editListener = instance.once( 'edit', function( evt ) {\r
+                                               if ( evt.data.dialog ) {\r
+                                                       instance.once( 'dialog', function( evt ) {\r
+                                                               var dialog = evt.data,\r
+                                                                       okListener,\r
+                                                                       cancelListener;\r
+\r
+                                                               // Finalize creation AFTER (20) new data was set.\r
+                                                               okListener = dialog.once( 'ok', finalizeCreation, null, null, 20 );\r
+\r
+                                                               cancelListener = dialog.once( 'cancel', function( evt ) {\r
+                                                                       if ( !( evt.data && evt.data.hide === false ) ) {\r
+                                                                               editor.widgets.destroy( instance, true );\r
+                                                                       }\r
+                                                               } );\r
+\r
+                                                               dialog.once( 'hide', function() {\r
+                                                                       okListener.removeListener();\r
+                                                                       cancelListener.removeListener();\r
+                                                               } );\r
+                                                       } );\r
+                                               } else {\r
+                                                       // Dialog hasn't been set, so insert widget now.\r
+                                                       finalizeCreation();\r
+                                               }\r
+                                       }, null, null, 999 );\r
+\r
+                                       instance.edit();\r
+\r
+                                       // Remove listener in case someone canceled it before this\r
+                                       // listener was executed.\r
+                                       editListener.removeListener();\r
+                               }\r
+\r
+                               function finalizeCreation() {\r
+                                       editor.widgets.finalizeCreation( temp );\r
+                               }\r
+                       },\r
+\r
+                       allowedContent: widgetDef.allowedContent,\r
+                       requiredContent: widgetDef.requiredContent,\r
+                       contentForms: widgetDef.contentForms,\r
+                       contentTransformations: widgetDef.contentTransformations\r
+               } );\r
+       }\r
+\r
+       function addWidgetProcessors( widgetsRepo, widgetDef ) {\r
+               var upcast = widgetDef.upcast,\r
+                       upcasts,\r
+                       priority = widgetDef.upcastPriority || 10;\r
+\r
+               if ( !upcast )\r
+                       return;\r
+\r
+               // Multiple upcasts defined in string.\r
+               if ( typeof upcast == 'string' ) {\r
+                       upcasts = upcast.split( ',' );\r
+                       while ( upcasts.length ) {\r
+                               addUpcast( widgetDef.upcasts[ upcasts.pop() ], widgetDef.name, priority );\r
+                       }\r
+               }\r
+               // Single rule which is automatically activated.\r
+               else {\r
+                       addUpcast( upcast, widgetDef.name, priority );\r
+               }\r
+\r
+               function addUpcast( upcast, name, priority ) {\r
+                       // Find index of the first higher (in terms of value) priority upcast.\r
+                       var index = CKEDITOR.tools.getIndex( widgetsRepo._.upcasts, function( element ) {\r
+                               return element[ 2 ] > priority;\r
+                       } );\r
+                       // Add at the end if it is the highest priority so far.\r
+                       if ( index < 0 ) {\r
+                               index = widgetsRepo._.upcasts.length;\r
+                       }\r
+\r
+                       widgetsRepo._.upcasts.splice( index, 0, [ upcast, name, priority ] );\r
+               }\r
+       }\r
+\r
+       function blurWidget( widgetsRepo, widget ) {\r
+               widgetsRepo.focused = null;\r
+\r
+               if ( widget.isInited() ) {\r
+                       var isDirty = widget.editor.checkDirty();\r
+\r
+                       // Widget could be destroyed in the meantime - e.g. data could be set.\r
+                       widgetsRepo.fire( 'widgetBlurred', { widget: widget } );\r
+                       widget.setFocused( false );\r
+\r
+                       !isDirty && widget.editor.resetDirty();\r
+               }\r
+       }\r
+\r
+       function checkWidgets( evt ) {\r
+               var options = evt.data;\r
+\r
+               if ( this.editor.mode != 'wysiwyg' )\r
+                       return;\r
+\r
+               var editable = this.editor.editable(),\r
+                       instances = this.instances,\r
+                       newInstances, i, count, wrapper, notYetInitialized;\r
+\r
+               if ( !editable )\r
+                       return;\r
+\r
+               // Remove widgets which have no corresponding elements in DOM.\r
+               for ( i in instances ) {\r
+                       // #13410 Remove widgets that are ready. This prevents from destroying widgets that are during loading process.\r
+                       if ( instances[ i ].isReady() && !editable.contains( instances[ i ].wrapper ) )\r
+                               this.destroy( instances[ i ], true );\r
+               }\r
+\r
+               // Init on all (new) if initOnlyNew option was passed.\r
+               if ( options && options.initOnlyNew )\r
+                       newInstances = this.initOnAll();\r
+               else {\r
+                       var wrappers = editable.find( '.cke_widget_wrapper' );\r
+                       newInstances = [];\r
+\r
+                       // Create widgets on existing wrappers if they do not exists.\r
+                       for ( i = 0, count = wrappers.count(); i < count; i++ ) {\r
+                               wrapper = wrappers.getItem( i );\r
+                               notYetInitialized = !this.getByElement( wrapper, true );\r
+\r
+                               // Check if:\r
+                               // * there's no instance for this widget\r
+                               // * wrapper is not inside some temporary element like copybin (#11088)\r
+                               // * it was a nested widget's wrapper which has been detached from DOM,\r
+                               // when nested editable has been initialized (it overwrites its innerHTML\r
+                               // and initializes nested widgets).\r
+                               if ( notYetInitialized && !findParent( wrapper, isDomTemp ) && editable.contains( wrapper ) ) {\r
+                                       // Add cke_widget_new class because otherwise\r
+                                       // widget will not be created on such wrapper.\r
+                                       wrapper.addClass( 'cke_widget_new' );\r
+                                       newInstances.push( this.initOn( wrapper.getFirst( Widget.isDomWidgetElement ) ) );\r
+                               }\r
+                       }\r
+               }\r
+\r
+               // If only single widget was initialized and focusInited was passed, focus it.\r
+               if ( options && options.focusInited && newInstances.length == 1 )\r
+                       newInstances[ 0 ].focus();\r
+       }\r
+\r
+       // Unwraps widget element and clean up element.\r
+       //\r
+       // This function is used to clean up pasted widgets.\r
+       // It should have similar result to widget#destroy plus\r
+       // some additional adjustments, specific for pasting.\r
+       //\r
+       // @param {CKEDITOR.htmlParser.element} el\r
+       function cleanUpWidgetElement( el ) {\r
+               var parent = el.parent;\r
+               if ( parent.type == CKEDITOR.NODE_ELEMENT && parent.attributes[ 'data-cke-widget-wrapper' ] )\r
+                       parent.replaceWith( el );\r
+       }\r
+\r
+       // Similar to cleanUpWidgetElement, but works on DOM and finds\r
+       // widget elements by its own.\r
+       //\r
+       // Unlike cleanUpWidgetElement it will wrap element back.\r
+       //\r
+       // @param {CKEDITOR.dom.element} container\r
+       function cleanUpAllWidgetElements( widgetsRepo, container ) {\r
+               var wrappers = container.find( '.cke_widget_wrapper' ),\r
+                       wrapper, element,\r
+                       i = 0,\r
+                       l = wrappers.count();\r
+\r
+               for ( ; i < l; ++i ) {\r
+                       wrapper = wrappers.getItem( i );\r
+                       element = wrapper.getFirst( Widget.isDomWidgetElement );\r
+                       // If wrapper contains widget element - unwrap it and wrap again.\r
+                       if ( element.type == CKEDITOR.NODE_ELEMENT && element.data( 'widget' ) ) {\r
+                               element.replace( wrapper );\r
+                               widgetsRepo.wrapElement( element );\r
+                       } else {\r
+                               // Otherwise - something is wrong... clean this up.\r
+                               wrapper.remove();\r
+                       }\r
+               }\r
+       }\r
+\r
+       // Creates {@link CKEDITOR.filter} instance for given widget, editable and rules.\r
+       //\r
+       // Once filter for widget-editable pair is created it is cached, so the same instance\r
+       // will be returned when method is executed again.\r
+       //\r
+       // @param {String} widgetName\r
+       // @param {String} editableName\r
+       // @param {CKEDITOR.plugins.widget.nestedEditableDefinition} editableDefinition The nested editable definition.\r
+       // @returns {CKEDITOR.filter} Filter instance or `null` if rules are not defined.\r
+       // @context CKEDITOR.plugins.widget.repository\r
+       function createEditableFilter( widgetName, editableName, editableDefinition ) {\r
+               if ( !editableDefinition.allowedContent )\r
+                       return null;\r
+\r
+               var editables = this._.filters[ widgetName ];\r
+\r
+               if ( !editables )\r
+                       this._.filters[ widgetName ] = editables = {};\r
+\r
+               var filter = editables[ editableName ];\r
+\r
+               if ( !filter )\r
+                       editables[ editableName ] = filter = new CKEDITOR.filter( editableDefinition.allowedContent );\r
+\r
+               return filter;\r
+       }\r
+\r
+       // Creates an iterator function which when executed on all\r
+       // elements in DOM tree will gather elements that should be wrapped\r
+       // and initialized as widgets.\r
+       function createUpcastIterator( widgetsRepo ) {\r
+               var toBeWrapped = [],\r
+                       upcasts = widgetsRepo._.upcasts,\r
+                       upcastCallbacks = widgetsRepo._.upcastCallbacks;\r
+\r
+               return {\r
+                       toBeWrapped: toBeWrapped,\r
+\r
+                       iterator: function( element ) {\r
+                               var upcast, upcasted,\r
+                                       data,\r
+                                       i,\r
+                                       upcastsLength,\r
+                                       upcastCallbacksLength;\r
+\r
+                               // Wrapper found - find widget element, add it to be\r
+                               // cleaned up (unwrapped) and wrapped and stop iterating in this branch.\r
+                               if ( 'data-cke-widget-wrapper' in element.attributes ) {\r
+                                       element = element.getFirst( Widget.isParserWidgetElement );\r
+\r
+                                       if ( element )\r
+                                               toBeWrapped.push( [ element ] );\r
+\r
+                                       // Do not iterate over descendants.\r
+                                       return false;\r
+                               }\r
+                               // Widget element found - add it to be cleaned up (just in case)\r
+                               // and wrapped and stop iterating in this branch.\r
+                               else if ( 'data-widget' in element.attributes ) {\r
+                                       toBeWrapped.push( [ element ] );\r
+\r
+                                       // Do not iterate over descendants.\r
+                                       return false;\r
+                               }\r
+                               else if ( ( upcastsLength = upcasts.length ) ) {\r
+                                       // Ignore elements with data-cke-widget-upcasted to avoid multiple upcasts (#11533).\r
+                                       // Do not iterate over descendants.\r
+                                       if ( element.attributes[ 'data-cke-widget-upcasted' ] )\r
+                                               return false;\r
+\r
+                                       // Check element with upcast callbacks first.\r
+                                       // If any of them return false abort upcasting.\r
+                                       for ( i = 0, upcastCallbacksLength = upcastCallbacks.length; i < upcastCallbacksLength; ++i ) {\r
+                                               if ( upcastCallbacks[ i ]( element ) === false )\r
+                                                       return;\r
+                                               // Return nothing in order to continue iterating over ascendants.\r
+                                               // See http://dev.ckeditor.com/ticket/11186#comment:6\r
+                                       }\r
+\r
+                                       for ( i = 0; i < upcastsLength; ++i ) {\r
+                                               upcast = upcasts[ i ];\r
+                                               data = {};\r
+\r
+                                               if ( ( upcasted = upcast[ 0 ]( element, data ) ) ) {\r
+                                                       // If upcast function returned element, upcast this one.\r
+                                                       // It can be e.g. a new element wrapping the original one.\r
+                                                       if ( upcasted instanceof CKEDITOR.htmlParser.element )\r
+                                                               element = upcasted;\r
+\r
+                                                       // Set initial data attr with data from upcast method.\r
+                                                       element.attributes[ 'data-cke-widget-data' ] = encodeURIComponent( JSON.stringify( data ) );\r
+                                                       element.attributes[ 'data-cke-widget-upcasted' ] = 1;\r
+\r
+                                                       toBeWrapped.push( [ element, upcast[ 1 ] ] );\r
+\r
+                                                       // Do not iterate over descendants.\r
+                                                       return false;\r
+                                               }\r
+                                       }\r
+                               }\r
+                       }\r
+               };\r
+       }\r
+\r
+       // Finds a first parent that matches query.\r
+       //\r
+       // @param {CKEDITOR.dom.element} element\r
+       // @param {Function} query\r
+       function findParent( element, query ) {\r
+               var parent = element;\r
+\r
+               while ( ( parent = parent.getParent() ) ) {\r
+                       if ( query( parent ) )\r
+                               return true;\r
+               }\r
+               return false;\r
+       }\r
+\r
+       function getWrapperAttributes( inlineWidget, name ) {\r
+               return {\r
+                       // tabindex="-1" means that it can receive focus by code.\r
+                       tabindex: -1,\r
+                       contenteditable: 'false',\r
+                       'data-cke-widget-wrapper': 1,\r
+                       'data-cke-filter': 'off',\r
+                       // Class cke_widget_new marks widgets which haven't been initialized yet.\r
+                       'class': 'cke_widget_wrapper cke_widget_new cke_widget_' +\r
+                               ( inlineWidget ? 'inline' : 'block' ) +\r
+                               ( name ? ' cke_widget_' + name : '' )\r
+               };\r
+       }\r
+\r
+       // Inserts element at given index.\r
+       // It will check DTD and split ancestor elements up to the first\r
+       // that can contain this element.\r
+       //\r
+       // @param {CKEDITOR.htmlParser.element} parent\r
+       // @param {Number} index\r
+       // @param {CKEDITOR.htmlParser.element} element\r
+       function insertElement( parent, index, element ) {\r
+               // Do not split doc fragment...\r
+               if ( parent.type == CKEDITOR.NODE_ELEMENT ) {\r
+                       var parentAllows = CKEDITOR.dtd[ parent.name ];\r
+                       // Parent element is known (included in DTD) and cannot contain\r
+                       // this element.\r
+                       if ( parentAllows && !parentAllows[ element.name ] ) {\r
+                               var parent2 = parent.split( index ),\r
+                                       parentParent = parent.parent;\r
+\r
+                               // Element will now be inserted at right parent's index.\r
+                               index = parent2.getIndex();\r
+\r
+                               // If left part of split is empty - remove it.\r
+                               if ( !parent.children.length ) {\r
+                                       index -= 1;\r
+                                       parent.remove();\r
+                               }\r
+\r
+                               // If right part of split is empty - remove it.\r
+                               if ( !parent2.children.length )\r
+                                       parent2.remove();\r
+\r
+                               // Try inserting as grandpas' children.\r
+                               return insertElement( parentParent, index, element );\r
+                       }\r
+               }\r
+\r
+               // Finally we can add this element.\r
+               parent.add( element, index );\r
+       }\r
+\r
+       // Checks whether for the given widget definition and element widget should be created in inline or block mode.\r
+       //\r
+       // See also: {@link CKEDITOR.plugins.widget.definition#inline} and {@link CKEDITOR.plugins.widget#element}.\r
+       //\r
+       // @param {CKEDITOR.plugins.widget.definition} widgetDef The widget definition.\r
+       // @param {String} elementName The name of the widget element.\r
+       // @returns {Boolean}\r
+       function isWidgetInline( widgetDef, elementName ) {\r
+               return typeof widgetDef.inline == 'boolean' ? widgetDef.inline : !!CKEDITOR.dtd.$inline[ elementName ];\r
+       }\r
+\r
+       // @param {CKEDITOR.dom.element}\r
+       // @returns {Boolean}\r
+       function isDomTemp( element ) {\r
+               return element.hasAttribute( 'data-cke-temp' );\r
+       }\r
+\r
+       function onEditableKey( widget, keyCode ) {\r
+               var focusedEditable = widget.focusedEditable,\r
+                       range;\r
+\r
+               // CTRL+A.\r
+               if ( keyCode == CKEDITOR.CTRL + 65 ) {\r
+                       var bogus = focusedEditable.getBogus();\r
+\r
+                       range = widget.editor.createRange();\r
+                       range.selectNodeContents( focusedEditable );\r
+                       // Exclude bogus if exists.\r
+                       if ( bogus )\r
+                               range.setEndAt( bogus, CKEDITOR.POSITION_BEFORE_START );\r
+\r
+                       range.select();\r
+                       // Cancel event - block default.\r
+                       return false;\r
+               }\r
+               // DEL or BACKSPACE.\r
+               else if ( keyCode == 8 || keyCode == 46 ) {\r
+                       var ranges = widget.editor.getSelection().getRanges();\r
+\r
+                       range = ranges[ 0 ];\r
+\r
+                       // Block del or backspace if at editable's boundary.\r
+                       return !( ranges.length == 1 && range.collapsed &&\r
+                               range.checkBoundaryOfElement( focusedEditable, CKEDITOR[ keyCode == 8 ? 'START' : 'END' ] ) );\r
+               }\r
+       }\r
+\r
+       function setFocusedEditable( widgetsRepo, widget, editableElement, offline ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               editor.fire( 'lockSnapshot' );\r
+\r
+               if ( editableElement ) {\r
+                       var editableName = editableElement.data( 'cke-widget-editable' ),\r
+                               editableInstance = widget.editables[ editableName ];\r
+\r
+                       widgetsRepo.widgetHoldingFocusedEditable = widget;\r
+                       widget.focusedEditable = editableInstance;\r
+                       editableElement.addClass( 'cke_widget_editable_focused' );\r
+\r
+                       if ( editableInstance.filter )\r
+                               editor.setActiveFilter( editableInstance.filter );\r
+                       editor.setActiveEnterMode( editableInstance.enterMode, editableInstance.shiftEnterMode );\r
+               } else {\r
+                       if ( !offline )\r
+                               widget.focusedEditable.removeClass( 'cke_widget_editable_focused' );\r
+\r
+                       widget.focusedEditable = null;\r
+                       widgetsRepo.widgetHoldingFocusedEditable = null;\r
+                       editor.setActiveFilter( null );\r
+                       editor.setActiveEnterMode( null, null );\r
+               }\r
+\r
+               editor.fire( 'unlockSnapshot' );\r
+       }\r
+\r
+       function setupContextMenu( editor ) {\r
+               if ( !editor.contextMenu )\r
+                       return;\r
+\r
+               editor.contextMenu.addListener( function( element ) {\r
+                       var widget = editor.widgets.getByElement( element, true );\r
+\r
+                       if ( widget )\r
+                               return widget.fire( 'contextMenu', {} );\r
+               } );\r
+       }\r
+\r
+       // And now we've got two problems - original problem and RegExp.\r
+       // Some softeners:\r
+       // * FF tends to copy all blocks up to the copybin container.\r
+       // * IE tends to copy only the copybin, without its container.\r
+       // * We use spans on IE and blockless editors, but divs in other cases.\r
+       var pasteReplaceRegex = new RegExp(\r
+               '^' +\r
+               '(?:<(?:div|span)(?: data-cke-temp="1")?(?: id="cke_copybin")?(?: data-cke-temp="1")?>)?' +\r
+                       '(?:<(?:div|span)(?: style="[^"]+")?>)?' +\r
+                               '<span [^>]*data-cke-copybin-start="1"[^>]*>.?</span>([\\s\\S]+)<span [^>]*data-cke-copybin-end="1"[^>]*>.?</span>' +\r
+                       '(?:</(?:div|span)>)?' +\r
+               '(?:</(?:div|span)>)?' +\r
+               '$',\r
+               // IE8 prefers uppercase when browsers stick to lowercase HTML (#13460).\r
+               'i'\r
+       );\r
+\r
+       function pasteReplaceFn( match, wrapperHtml ) {\r
+               // Avoid polluting pasted data with any whitspaces,\r
+               // what's going to break check whether only one widget was pasted.\r
+               return CKEDITOR.tools.trim( wrapperHtml );\r
+       }\r
+\r
+       function setupDragAndDrop( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor,\r
+                       lineutils = CKEDITOR.plugins.lineutils;\r
+\r
+               // These listeners handle inline and block widgets drag and drop.\r
+               // The only thing we need to do to make block widgets custom drag and drop functionality\r
+               // is to fire those events with the right properties (like the target which must be the drag handle).\r
+               editor.on( 'dragstart', function( evt ) {\r
+                       var target = evt.data.target;\r
+\r
+                       if ( Widget.isDomDragHandler( target ) ) {\r
+                               var widget = widgetsRepo.getByElement( target );\r
+\r
+                               evt.data.dataTransfer.setData( 'cke/widget-id', widget.id );\r
+\r
+                               // IE needs focus.\r
+                               editor.focus();\r
+\r
+                               // and widget need to be focused on drag start (#12172#comment:10).\r
+                               widget.focus();\r
+                       }\r
+               } );\r
+\r
+               editor.on( 'drop', function( evt ) {\r
+                       var dataTransfer = evt.data.dataTransfer,\r
+                               id = dataTransfer.getData( 'cke/widget-id' ),\r
+                               transferType = dataTransfer.getTransferType( editor ),\r
+                               dragRange = editor.createRange(),\r
+                               sourceWidget;\r
+\r
+                       // Disable cross-editor drag & drop for widgets - #13599.\r
+                       if ( id !== '' && transferType === CKEDITOR.DATA_TRANSFER_CROSS_EDITORS ) {\r
+                               evt.cancel();\r
+                               return;\r
+                       }\r
+\r
+                       if ( id === '' || transferType != CKEDITOR.DATA_TRANSFER_INTERNAL ) {\r
+                               return;\r
+                       }\r
+\r
+                       sourceWidget = widgetsRepo.instances[ id ];\r
+                       if ( !sourceWidget ) {\r
+                               return;\r
+                       }\r
+\r
+                       dragRange.setStartBefore( sourceWidget.wrapper );\r
+                       dragRange.setEndAfter( sourceWidget.wrapper );\r
+                       evt.data.dragRange = dragRange;\r
+\r
+                       // [IE8-9] Reset state of the clipboard#fixSplitNodesAfterDrop fix because by setting evt.data.dragRange\r
+                       // (see above) after drop happened we do not need it. That fix is needed only if dragRange was created\r
+                       // before drop (before text node was split).\r
+                       delete CKEDITOR.plugins.clipboard.dragStartContainerChildCount;\r
+                       delete CKEDITOR.plugins.clipboard.dragEndContainerChildCount;\r
+\r
+                       evt.data.dataTransfer.setData( 'text/html', editor.editable().getHtmlFromRange( dragRange ).getHtml() );\r
+                       editor.widgets.destroy( sourceWidget, true );\r
+               } );\r
+\r
+               editor.on( 'contentDom', function() {\r
+                       var editable = editor.editable();\r
+\r
+                       // Register Lineutils's utilities as properties of repo.\r
+                       CKEDITOR.tools.extend( widgetsRepo, {\r
+                               finder: new lineutils.finder( editor, {\r
+                                       lookups: {\r
+                                               // Element is block but not list item and not in nested editable.\r
+                                               'default': function( el ) {\r
+                                                       if ( el.is( CKEDITOR.dtd.$listItem ) )\r
+                                                               return;\r
+\r
+                                                       if ( !el.is( CKEDITOR.dtd.$block ) )\r
+                                                               return;\r
+\r
+                                                       // Allow drop line inside, but never before or after nested editable (#12006).\r
+                                                       if ( Widget.isDomNestedEditable( el ) )\r
+                                                               return;\r
+\r
+                                                       // Do not allow droping inside the widget being dragged (#13397).\r
+                                                       if ( widgetsRepo._.draggedWidget.wrapper.contains( el ) ) {\r
+                                                               return;\r
+                                                       }\r
+\r
+                                                       // If element is nested editable, make sure widget can be dropped there (#12006).\r
+                                                       var nestedEditable = Widget.getNestedEditable( editable, el );\r
+                                                       if ( nestedEditable ) {\r
+                                                               var draggedWidget = widgetsRepo._.draggedWidget;\r
+\r
+                                                               // Don't let the widget to be dropped into its own nested editable.\r
+                                                               if ( widgetsRepo.getByElement( nestedEditable ) == draggedWidget )\r
+                                                                       return;\r
+\r
+                                                               var filter = CKEDITOR.filter.instances[ nestedEditable.data( 'cke-filter' ) ],\r
+                                                                       draggedRequiredContent = draggedWidget.requiredContent;\r
+\r
+                                                               // There will be no relation if the filter of nested editable does not allow\r
+                                                               // requiredContent of dragged widget.\r
+                                                               if ( filter && draggedRequiredContent && !filter.check( draggedRequiredContent ) )\r
+                                                                       return;\r
+                                                       }\r
+\r
+                                                       return CKEDITOR.LINEUTILS_BEFORE | CKEDITOR.LINEUTILS_AFTER;\r
+                                               }\r
+                                       }\r
+                               } ),\r
+                               locator: new lineutils.locator( editor ),\r
+                               liner: new lineutils.liner( editor, {\r
+                                       lineStyle: {\r
+                                               cursor: 'move !important',\r
+                                               'border-top-color': '#666'\r
+                                       },\r
+                                       tipLeftStyle: {\r
+                                               'border-left-color': '#666'\r
+                                       },\r
+                                       tipRightStyle: {\r
+                                               'border-right-color': '#666'\r
+                                       }\r
+                               } )\r
+                       }, true );\r
+               } );\r
+       }\r
+\r
+       // Setup mouse observer which will trigger:\r
+       // * widget focus on widget click,\r
+       // * widget#doubleclick forwarded from editor#doubleclick.\r
+       function setupMouseObserver( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               editor.on( 'contentDom', function() {\r
+                       var editable = editor.editable(),\r
+                               evtRoot = editable.isInline() ? editable : editor.document,\r
+                               widget,\r
+                               mouseDownOnDragHandler;\r
+\r
+                       editable.attachListener( evtRoot, 'mousedown', function( evt ) {\r
+                               var target = evt.data.getTarget();\r
+\r
+                               // #10887 Clicking scrollbar in IE8 will invoke event with empty target object.\r
+                               if ( !target.type )\r
+                                       return false;\r
+\r
+                               widget = widgetsRepo.getByElement( target );\r
+                               mouseDownOnDragHandler = 0; // Reset.\r
+\r
+                               // Widget was clicked, but not editable nested in it.\r
+                               if ( widget ) {\r
+                                       // Ignore mousedown on drag and drop handler if the widget is inline.\r
+                                       // Block widgets are handled by Lineutils.\r
+                                       if ( widget.inline && target.type == CKEDITOR.NODE_ELEMENT && target.hasAttribute( 'data-cke-widget-drag-handler' ) ) {\r
+                                               mouseDownOnDragHandler = 1;\r
+\r
+                                               // When drag handler is pressed we have to clear current selection if it wasn't already on this widget.\r
+                                               // Otherwise, the selection may be in a fillingChar, which prevents dragging a widget. (#13284, see comment 8 and 9.)\r
+                                               if ( widgetsRepo.focused != widget )\r
+                                                       editor.getSelection().removeAllRanges();\r
+\r
+                                               return;\r
+                                       }\r
+\r
+                                       if ( !Widget.getNestedEditable( widget.wrapper, target ) ) {\r
+                                               evt.data.preventDefault();\r
+                                               if ( !CKEDITOR.env.ie )\r
+                                                       widget.focus();\r
+                                       } else {\r
+                                               // Reset widget so mouseup listener is not confused.\r
+                                               widget = null;\r
+                                       }\r
+                               }\r
+                       } );\r
+\r
+                       // Focus widget on mouseup if mousedown was fired on drag handler.\r
+                       // Note: mouseup won't be fired at all if widget was dragged and dropped, so\r
+                       // this code will be executed only when drag handler was clicked.\r
+                       editable.attachListener( evtRoot, 'mouseup', function() {\r
+                               // Check if widget is not destroyed (if widget is destroyed the wrapper will be null).\r
+                               if ( mouseDownOnDragHandler && widget && widget.wrapper ) {\r
+                                       mouseDownOnDragHandler = 0;\r
+                                       widget.focus();\r
+                               }\r
+                       } );\r
+\r
+                       // On IE it is not enough to block mousedown. If widget wrapper (element with\r
+                       // contenteditable=false attribute) is clicked directly (it is a target),\r
+                       // then after mouseup/click IE will select that element.\r
+                       // It is not possible to prevent that default action,\r
+                       // so we force fake selection after everything happened.\r
+                       if ( CKEDITOR.env.ie ) {\r
+                               editable.attachListener( evtRoot, 'mouseup', function() {\r
+                                       setTimeout( function() {\r
+                                               // Check if widget is not destroyed (if widget is destroyed the wrapper will be null) and\r
+                                               // in editable contains widget (it could be dragged and removed).\r
+                                               if ( widget && widget.wrapper && editable.contains( widget.wrapper ) ) {\r
+                                                       widget.focus();\r
+                                                       widget = null;\r
+                                               }\r
+                                       } );\r
+                               } );\r
+                       }\r
+               } );\r
+\r
+               editor.on( 'doubleclick', function( evt ) {\r
+                       var widget = widgetsRepo.getByElement( evt.data.element );\r
+\r
+                       // Not in widget or in nested editable.\r
+                       if ( !widget || Widget.getNestedEditable( widget.wrapper, evt.data.element ) )\r
+                               return;\r
+\r
+                       return widget.fire( 'doubleclick', { element: evt.data.element } );\r
+               }, null, null, 1 );\r
+       }\r
+\r
+       // Setup editor#key observer which will forward it\r
+       // to focused widget.\r
+       function setupKeyboardObserver( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               editor.on( 'key', function( evt ) {\r
+                       var focused = widgetsRepo.focused,\r
+                               widgetHoldingFocusedEditable = widgetsRepo.widgetHoldingFocusedEditable,\r
+                               ret;\r
+\r
+                       if ( focused )\r
+                               ret = focused.fire( 'key', { keyCode: evt.data.keyCode } );\r
+                       else if ( widgetHoldingFocusedEditable )\r
+                               ret = onEditableKey( widgetHoldingFocusedEditable, evt.data.keyCode );\r
+\r
+                       return ret;\r
+               }, null, null, 1 );\r
+       }\r
+\r
+       // Setup copybin on native copy and cut events in order to handle copy and cut commands\r
+       // if user accepted security alert on IEs.\r
+       // Note: when copying or cutting using keystroke, copySingleWidget will be first executed\r
+       // by the keydown listener. Conflict between two calls will be resolved by copy_bin existence check.\r
+       function setupNativeCutAndCopy( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               editor.on( 'contentDom', function() {\r
+                       var editable = editor.editable();\r
+\r
+                       editable.attachListener( editable, 'copy', eventListener );\r
+                       editable.attachListener( editable, 'cut', eventListener );\r
+               } );\r
+\r
+               function eventListener( evt ) {\r
+                       if ( widgetsRepo.focused )\r
+                               copySingleWidget( widgetsRepo.focused, evt.name == 'cut' );\r
+               }\r
+       }\r
+\r
+       // Setup selection observer which will trigger:\r
+       // * widget select & focus on selection change,\r
+       // * nested editable focus (related properites and classes) on selection change,\r
+       // * deselecting and blurring all widgets on data,\r
+       // * blurring widget on editor blur.\r
+       function setupSelectionObserver( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor;\r
+\r
+               editor.on( 'selectionCheck', function() {\r
+                       widgetsRepo.fire( 'checkSelection' );\r
+               } );\r
+\r
+               widgetsRepo.on( 'checkSelection', widgetsRepo.checkSelection, widgetsRepo );\r
+\r
+               editor.on( 'selectionChange', function( evt ) {\r
+                       var nestedEditable = Widget.getNestedEditable( editor.editable(), evt.data.selection.getStartElement() ),\r
+                               newWidget = nestedEditable && widgetsRepo.getByElement( nestedEditable ),\r
+                               oldWidget = widgetsRepo.widgetHoldingFocusedEditable;\r
+\r
+                       if ( oldWidget ) {\r
+                               if ( oldWidget !== newWidget || !oldWidget.focusedEditable.equals( nestedEditable ) ) {\r
+                                       setFocusedEditable( widgetsRepo, oldWidget, null );\r
+\r
+                                       if ( newWidget && nestedEditable )\r
+                                               setFocusedEditable( widgetsRepo, newWidget, nestedEditable );\r
+                               }\r
+                       }\r
+                       // It may happen that there's no widget even if editable was found -\r
+                       // e.g. if selection was automatically set in editable although widget wasn't initialized yet.\r
+                       else if ( newWidget && nestedEditable ) {\r
+                               setFocusedEditable( widgetsRepo, newWidget, nestedEditable );\r
+                       }\r
+               } );\r
+\r
+               // Invalidate old widgets early - immediately on dataReady.\r
+               editor.on( 'dataReady', function() {\r
+                       // Deselect and blur all widgets.\r
+                       stateUpdater( widgetsRepo ).commit();\r
+               } );\r
+\r
+               editor.on( 'blur', function() {\r
+                       var widget;\r
+\r
+                       if ( ( widget = widgetsRepo.focused ) )\r
+                               blurWidget( widgetsRepo, widget );\r
+\r
+                       if ( ( widget = widgetsRepo.widgetHoldingFocusedEditable ) )\r
+                               setFocusedEditable( widgetsRepo, widget, null );\r
+               } );\r
+       }\r
+\r
+       // Set up actions like:\r
+       // * processing in toHtml/toDataFormat,\r
+       // * pasting handling,\r
+       // * insertion handling,\r
+       // * editable reload handling (setData, mode switch, undo/redo),\r
+       // * DOM invalidation handling,\r
+       // * widgets checks.\r
+       function setupWidgetsLifecycle( widgetsRepo ) {\r
+               setupWidgetsLifecycleStart( widgetsRepo );\r
+               setupWidgetsLifecycleEnd( widgetsRepo );\r
+\r
+               widgetsRepo.on( 'checkWidgets', checkWidgets );\r
+               widgetsRepo.editor.on( 'contentDomInvalidated', widgetsRepo.checkWidgets, widgetsRepo );\r
+       }\r
+\r
+       function setupWidgetsLifecycleEnd( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor,\r
+                       downcastingSessions = {};\r
+\r
+               // Listen before htmlDP#htmlFilter is applied to cache all widgets, because we'll\r
+               // loose data-cke-* attributes.\r
+               editor.on( 'toDataFormat', function( evt ) {\r
+                       // To avoid conflicts between htmlDP#toDF calls done at the same time\r
+                       // (e.g. nestedEditable#getData called during downcasting some widget)\r
+                       // mark every toDataFormat event chain with the downcasting session id.\r
+                       var id = CKEDITOR.tools.getNextNumber(),\r
+                               toBeDowncasted = [];\r
+                       evt.data.downcastingSessionId = id;\r
+                       downcastingSessions[ id ] = toBeDowncasted;\r
+\r
+                       evt.data.dataValue.forEach( function( element ) {\r
+                               var attrs = element.attributes,\r
+                                       widget, widgetElement;\r
+\r
+                               // Wrapper.\r
+                               // Perform first part of downcasting (cleanup) and cache widgets,\r
+                               // because after applying DP's filter all data-cke-* attributes will be gone.\r
+                               if ( 'data-cke-widget-id' in attrs ) {\r
+                                       widget = widgetsRepo.instances[ attrs[ 'data-cke-widget-id' ] ];\r
+                                       if ( widget ) {\r
+                                               widgetElement = element.getFirst( Widget.isParserWidgetElement );\r
+                                               toBeDowncasted.push( {\r
+                                                       wrapper: element,\r
+                                                       element: widgetElement,\r
+                                                       widget: widget,\r
+                                                       editables: {}\r
+                                               } );\r
+\r
+                                               // If widget did not have data-cke-widget attribute before upcasting remove it.\r
+                                               if ( widgetElement.attributes[ 'data-cke-widget-keep-attr' ] != '1' )\r
+                                                       delete widgetElement.attributes[ 'data-widget' ];\r
+                                       }\r
+                               }\r
+                               // Nested editable.\r
+                               else if ( 'data-cke-widget-editable' in attrs ) {\r
+                                       // Save the reference to this nested editable in the closest widget to be downcasted.\r
+                                       // Nested editables are downcasted in the successive toDataFormat to create an opportunity\r
+                                       // for dataFilter's "excludeNestedEditable" option to do its job (that option relies on\r
+                                       // contenteditable="true" attribute) (#11372).\r
+                                       toBeDowncasted[ toBeDowncasted.length - 1 ].editables[ attrs[ 'data-cke-widget-editable' ] ] = element;\r
+\r
+                                       // Don't check children - there won't be next wrapper or nested editable which we\r
+                                       // should process in this session.\r
+                                       return false;\r
+                               }\r
+                       }, CKEDITOR.NODE_ELEMENT, true );\r
+               }, null, null, 8 );\r
+\r
+               // Listen after dataProcessor.htmlFilter and ACF were applied\r
+               // so wrappers securing widgets' contents are removed after all filtering was done.\r
+               editor.on( 'toDataFormat', function( evt ) {\r
+                       // Ignore some unmarked sessions.\r
+                       if ( !evt.data.downcastingSessionId )\r
+                               return;\r
+\r
+                       var toBeDowncasted = downcastingSessions[ evt.data.downcastingSessionId ],\r
+                               toBe, widget, widgetElement, retElement, editableElement, e;\r
+\r
+                       while ( ( toBe = toBeDowncasted.shift() ) ) {\r
+                               widget = toBe.widget;\r
+                               widgetElement = toBe.element;\r
+                               retElement = widget._.downcastFn && widget._.downcastFn.call( widget, widgetElement );\r
+\r
+                               // Replace nested editables' content with their output data.\r
+                               for ( e in toBe.editables ) {\r
+                                       editableElement = toBe.editables[ e ];\r
+\r
+                                       delete editableElement.attributes.contenteditable;\r
+                                       editableElement.setHtml( widget.editables[ e ].getData() );\r
+                               }\r
+\r
+                               // Returned element always defaults to widgetElement.\r
+                               if ( !retElement )\r
+                                       retElement = widgetElement;\r
+\r
+                               toBe.wrapper.replaceWith( retElement );\r
+                       }\r
+               }, null, null, 13 );\r
+\r
+\r
+               editor.on( 'contentDomUnload', function() {\r
+                       widgetsRepo.destroyAll( true );\r
+               } );\r
+       }\r
+\r
+       function setupWidgetsLifecycleStart( widgetsRepo ) {\r
+               var editor = widgetsRepo.editor,\r
+                       processedWidgetOnly,\r
+                       snapshotLoaded;\r
+\r
+               // Listen after ACF (so data are filtered),\r
+               // but before dataProcessor.dataFilter was applied (so we can secure widgets' internals).\r
+               editor.on( 'toHtml', function( evt ) {\r
+                       var upcastIterator = createUpcastIterator( widgetsRepo ),\r
+                               toBeWrapped;\r
+\r
+                       evt.data.dataValue.forEach( upcastIterator.iterator, CKEDITOR.NODE_ELEMENT, true );\r
+\r
+                       // Clean up and wrap all queued elements.\r
+                       while ( ( toBeWrapped = upcastIterator.toBeWrapped.pop() ) ) {\r
+                               cleanUpWidgetElement( toBeWrapped[ 0 ] );\r
+                               widgetsRepo.wrapElement( toBeWrapped[ 0 ], toBeWrapped[ 1 ] );\r
+                       }\r
+\r
+                       // Used to determine whether only widget was pasted.\r
+                       if ( evt.data.protectedWhitespaces ) {\r
+                               // Whitespaces are protected by wrapping content with spans. Take the middle node only.\r
+                               processedWidgetOnly = evt.data.dataValue.children.length == 3 &&\r
+                                       Widget.isParserWidgetWrapper( evt.data.dataValue.children[ 1 ] );\r
+                       } else {\r
+                               processedWidgetOnly = evt.data.dataValue.children.length == 1 &&\r
+                                       Widget.isParserWidgetWrapper( evt.data.dataValue.children[ 0 ] );\r
+                       }\r
+               }, null, null, 8 );\r
+\r
+               editor.on( 'dataReady', function() {\r
+                       // Clean up all widgets loaded from snapshot.\r
+                       if ( snapshotLoaded )\r
+                               cleanUpAllWidgetElements( widgetsRepo, editor.editable() );\r
+                       snapshotLoaded = 0;\r
+\r
+                       // Some widgets were destroyed on contentDomUnload,\r
+                       // some on loadSnapshot, but that does not include\r
+                       // e.g. setHtml on inline editor or widgets removed just\r
+                       // before setting data.\r
+                       widgetsRepo.destroyAll( true );\r
+                       widgetsRepo.initOnAll();\r
+               } );\r
+\r
+               // Set flag so dataReady will know that additional\r
+               // cleanup is needed, because snapshot containing widgets was loaded.\r
+               editor.on( 'loadSnapshot', function( evt ) {\r
+                       // Primitive but sufficient check which will prevent from executing\r
+                       // heavier cleanUpAllWidgetElements if not needed.\r
+                       if ( ( /data-cke-widget/ ).test( evt.data ) )\r
+                               snapshotLoaded = 1;\r
+\r
+                       widgetsRepo.destroyAll( true );\r
+               }, null, null, 9 );\r
+\r
+               // Handle pasted single widget.\r
+               editor.on( 'paste', function( evt ) {\r
+                       var data = evt.data;\r
+\r
+                       data.dataValue = data.dataValue.replace( pasteReplaceRegex, pasteReplaceFn );\r
+\r
+                       // If drag'n'drop kind of paste into nested editable (data.range), selection is set AFTER\r
+                       // data is pasted, which means editor has no chance to change activeFilter's context.\r
+                       // As a result, pasted data is filtered with default editor's filter instead of NE's and\r
+                       // funny things get inserted. Changing the filter by analysis of the paste range below (#13186).\r
+                       if ( data.range ) {\r
+                               // Check if pasting into nested editable.\r
+                               var nestedEditable = Widget.getNestedEditable( editor.editable(), data.range.startContainer );\r
+\r
+                               if ( nestedEditable ) {\r
+                                       // Retrieve the filter from NE's data and set it active before editor.insertHtml is done\r
+                                       // in clipboard plugin.\r
+                                       var filter = CKEDITOR.filter.instances[ nestedEditable.data( 'cke-filter' ) ];\r
+\r
+                                       if ( filter ) {\r
+                                               editor.setActiveFilter( filter );\r
+                                       }\r
+                               }\r
+                       }\r
+               } );\r
+\r
+               // Listen with high priority to check widgets after data was inserted.\r
+               editor.on( 'afterInsertHtml', function( evt ) {\r
+                       if ( evt.data.intoRange ) {\r
+                               widgetsRepo.checkWidgets( { initOnlyNew: true } );\r
+                       } else {\r
+                               editor.fire( 'lockSnapshot' );\r
+                               // Init only new for performance reason.\r
+                               // Focus inited if only widget was processed.\r
+                               widgetsRepo.checkWidgets( { initOnlyNew: true, focusInited: processedWidgetOnly } );\r
+\r
+                               editor.fire( 'unlockSnapshot' );\r
+                       }\r
+               } );\r
+       }\r
+\r
+       // Helper for coordinating which widgets should be\r
+       // selected/deselected and which one should be focused/blurred.\r
+       function stateUpdater( widgetsRepo ) {\r
+               var currentlySelected = widgetsRepo.selected,\r
+                       toBeSelected = [],\r
+                       toBeDeselected = currentlySelected.slice( 0 ),\r
+                       focused = null;\r
+\r
+               return {\r
+                       select: function( widget ) {\r
+                               if ( CKEDITOR.tools.indexOf( currentlySelected, widget ) < 0 )\r
+                                       toBeSelected.push( widget );\r
+\r
+                               var index = CKEDITOR.tools.indexOf( toBeDeselected, widget );\r
+                               if ( index >= 0 )\r
+                                       toBeDeselected.splice( index, 1 );\r
+\r
+                               return this;\r
+                       },\r
+\r
+                       focus: function( widget ) {\r
+                               focused = widget;\r
+                               return this;\r
+                       },\r
+\r
+                       commit: function() {\r
+                               var focusedChanged = widgetsRepo.focused !== focused,\r
+                                       widget, isDirty;\r
+\r
+                               widgetsRepo.editor.fire( 'lockSnapshot' );\r
+\r
+                               if ( focusedChanged && ( widget = widgetsRepo.focused ) )\r
+                                       blurWidget( widgetsRepo, widget );\r
+\r
+                               while ( ( widget = toBeDeselected.pop() ) ) {\r
+                                       currentlySelected.splice( CKEDITOR.tools.indexOf( currentlySelected, widget ), 1 );\r
+                                       // Widget could be destroyed in the meantime - e.g. data could be set.\r
+                                       if ( widget.isInited() ) {\r
+                                               isDirty = widget.editor.checkDirty();\r
+\r
+                                               widget.setSelected( false );\r
+\r
+                                               !isDirty && widget.editor.resetDirty();\r
+                                       }\r
+                               }\r
+\r
+                               if ( focusedChanged && focused ) {\r
+                                       isDirty = widgetsRepo.editor.checkDirty();\r
+\r
+                                       widgetsRepo.focused = focused;\r
+                                       widgetsRepo.fire( 'widgetFocused', { widget: focused } );\r
+                                       focused.setFocused( true );\r
+\r
+                                       !isDirty && widgetsRepo.editor.resetDirty();\r
+                               }\r
+\r
+                               while ( ( widget = toBeSelected.pop() ) ) {\r
+                                       currentlySelected.push( widget );\r
+                                       widget.setSelected( true );\r
+                               }\r
+\r
+                               widgetsRepo.editor.fire( 'unlockSnapshot' );\r
+                       }\r
+               };\r
+       }\r
+\r
+\r
+       //\r
+       // WIDGET helpers ---------------------------------------------------------\r
+       //\r
+\r
+       // LEFT, RIGHT, UP, DOWN, DEL, BACKSPACE - unblock default fake sel handlers.\r
+       var keystrokesNotBlockedByWidget = { 37: 1, 38: 1, 39: 1, 40: 1, 8: 1, 46: 1 };\r
+\r
+       // Applies or removes style's classes from widget.\r
+       // @param {CKEDITOR.style} style Custom widget style.\r
+       // @param {Boolean} apply Whether to apply or remove style.\r
+       function applyRemoveStyle( widget, style, apply ) {\r
+               var changed = 0,\r
+                       classes = getStyleClasses( style ),\r
+                       updatedClasses = widget.data.classes || {},\r
+                       cl;\r
+\r
+               // Ee... Something is wrong with this style.\r
+               if ( !classes )\r
+                       return;\r
+\r
+               // Clone, because we need to break reference.\r
+               updatedClasses = CKEDITOR.tools.clone( updatedClasses );\r
+\r
+               while ( ( cl = classes.pop() ) ) {\r
+                       if ( apply ) {\r
+                               if ( !updatedClasses[ cl ] )\r
+                                       changed = updatedClasses[ cl ] = 1;\r
+                       } else {\r
+                               if ( updatedClasses[ cl ] ) {\r
+                                       delete updatedClasses[ cl ];\r
+                                       changed = 1;\r
+                               }\r
+                       }\r
+               }\r
+               if ( changed )\r
+                       widget.setData( 'classes', updatedClasses );\r
+       }\r
+\r
+       function cancel( evt ) {\r
+               evt.cancel();\r
+       }\r
+\r
+       function copySingleWidget( widget, isCut ) {\r
+               var editor = widget.editor,\r
+                       doc = editor.document;\r
+\r
+               // We're still handling previous copy/cut.\r
+               // When keystroke is used to copy/cut this will also prevent\r
+               // conflict with copySingleWidget called again for native copy/cut event.\r
+               if ( doc.getById( 'cke_copybin' ) )\r
+                       return;\r
+\r
+                       // [IE] Use span for copybin and its container to avoid bug with expanding editable height by\r
+                       // absolutely positioned element.\r
+               var copybinName = ( editor.blockless || CKEDITOR.env.ie ) ? 'span' : 'div',\r
+                       copybin = doc.createElement( copybinName ),\r
+                       copybinContainer = doc.createElement( copybinName ),\r
+                       // IE8 always jumps to the end of document.\r
+                       needsScrollHack = CKEDITOR.env.ie && CKEDITOR.env.version < 9;\r
+\r
+               copybinContainer.setAttributes( {\r
+                       id: 'cke_copybin',\r
+                       'data-cke-temp': '1'\r
+               } );\r
+\r
+               // Position copybin element outside current viewport.\r
+               copybin.setStyles( {\r
+                       position: 'absolute',\r
+                       width: '1px',\r
+                       height: '1px',\r
+                       overflow: 'hidden'\r
+               } );\r
+\r
+               copybin.setStyle( editor.config.contentsLangDirection == 'ltr' ? 'left' : 'right', '-5000px' );\r
+\r
+               var range = editor.createRange();\r
+               range.setStartBefore( widget.wrapper );\r
+               range.setEndAfter( widget.wrapper );\r
+\r
+               copybin.setHtml(\r
+                       '<span data-cke-copybin-start="1">\u200b</span>' +\r
+                       editor.editable().getHtmlFromRange( range ).getHtml() +\r
+                       '<span data-cke-copybin-end="1">\u200b</span>' );\r
+\r
+               // Save snapshot with the current state.\r
+               editor.fire( 'saveSnapshot' );\r
+\r
+               // Ignore copybin.\r
+               editor.fire( 'lockSnapshot' );\r
+\r
+               copybinContainer.append( copybin );\r
+               editor.editable().append( copybinContainer );\r
+\r
+               var listener1 = editor.on( 'selectionChange', cancel, null, null, 0 ),\r
+                       listener2 = widget.repository.on( 'checkSelection', cancel, null, null, 0 );\r
+\r
+               if ( needsScrollHack ) {\r
+                       var docElement = doc.getDocumentElement().$,\r
+                               scrollTop = docElement.scrollTop;\r
+               }\r
+\r
+               // Once the clone of the widget is inside of copybin, select\r
+               // the entire contents. This selection will be copied by the\r
+               // native browser's clipboard system.\r
+               range = editor.createRange();\r
+               range.selectNodeContents( copybin );\r
+               range.select();\r
+\r
+               if ( needsScrollHack )\r
+                       docElement.scrollTop = scrollTop;\r
+\r
+               setTimeout( function() {\r
+                       // [IE] Focus widget before removing copybin to avoid scroll jump.\r
+                       if ( !isCut )\r
+                               widget.focus();\r
+\r
+                       copybinContainer.remove();\r
+\r
+                       listener1.removeListener();\r
+                       listener2.removeListener();\r
+\r
+                       editor.fire( 'unlockSnapshot' );\r
+\r
+                       if ( isCut ) {\r
+                               widget.repository.del( widget );\r
+                               editor.fire( 'saveSnapshot' );\r
+                       }\r
+               }, 100 ); // Use 100ms, so Chrome (@Mac) will be able to grab the content.\r
+       }\r
+\r
+       // Extracts classes array from style instance.\r
+       function getStyleClasses( style ) {\r
+               var attrs = style.getDefinition().attributes,\r
+                       classes = attrs && attrs[ 'class' ];\r
+\r
+               return classes ? classes.split( /\s+/ ) : null;\r
+       }\r
+\r
+       // [IE] Force keeping focus because IE sometimes forgets to fire focus on main editable\r
+       // when blurring nested editable.\r
+       // @context widget\r
+       function onEditableBlur() {\r
+               var active = CKEDITOR.document.getActive(),\r
+                       editor = this.editor,\r
+                       editable = editor.editable();\r
+\r
+               // If focus stays within editor override blur and set currentActive because it should be\r
+               // automatically changed to editable on editable#focus but it is not fired.\r
+               if ( ( editable.isInline() ? editable : editor.document.getWindow().getFrame() ).equals( active ) )\r
+                       editor.focusManager.focus( editable );\r
+       }\r
+\r
+       // Force selectionChange when editable was focused.\r
+       // Similar to hack in selection.js#~620.\r
+       // @context widget\r
+       function onEditableFocus() {\r
+               // Gecko does not support 'DOMFocusIn' event on which we unlock selection\r
+               // in selection.js to prevent selection locking when entering nested editables.\r
+               if ( CKEDITOR.env.gecko )\r
+                       this.editor.unlockSelection();\r
+\r
+               // We don't need to force selectionCheck on Webkit, because on Webkit\r
+               // we do that on DOMFocusIn in selection.js.\r
+               if ( !CKEDITOR.env.webkit ) {\r
+                       this.editor.forceNextSelectionCheck();\r
+                       this.editor.selectionChange( 1 );\r
+               }\r
+       }\r
+\r
+       // Setup listener on widget#data which will update (remove/add) classes\r
+       // by comparing newly set classes with the old ones.\r
+       function setupDataClassesListener( widget ) {\r
+               // Note: previousClasses and newClasses may be null!\r
+               // Tip: for ( cl in null ) is correct.\r
+               var previousClasses = null;\r
+\r
+               widget.on( 'data', function() {\r
+                       var newClasses = this.data.classes,\r
+                               cl;\r
+\r
+                       // When setting new classes one need to remember\r
+                       // that he must break reference.\r
+                       if ( previousClasses == newClasses )\r
+                               return;\r
+\r
+                       for ( cl in previousClasses ) {\r
+                               // Avoid removing and adding classes again.\r
+                               if ( !( newClasses && newClasses[ cl ] ) )\r
+                                       this.removeClass( cl );\r
+                       }\r
+                       for ( cl in newClasses )\r
+                               this.addClass( cl );\r
+\r
+                       previousClasses = newClasses;\r
+               } );\r
+       }\r
+\r
+       // Add a listener to data event that will set/change widget's label (#14539).\r
+       function setupA11yListener( widget ) {\r
+               // Note, the function gets executed in a context of widget instance.\r
+               function getLabelDefault() {\r
+                       return this.editor.lang.widget.label.replace( /%1/, this.pathName || this.element.getName() );\r
+               }\r
+\r
+               // Setting a listener on data is enough, there's no need to perform it on widget initialization, as\r
+               // setupWidgetData fires this event anyway.\r
+               widget.on( 'data', function() {\r
+                       // In some cases widget might get destroyed in an earlier data listener. For instance, image2 plugin, does\r
+                       // so when changing its internal state.\r
+                       if ( !widget.wrapper ) {\r
+                               return;\r
+                       }\r
+\r
+                       var label = this.getLabel ? this.getLabel() : getLabelDefault.call( this );\r
+\r
+                       widget.wrapper.setAttribute( 'role', 'region' );\r
+                       widget.wrapper.setAttribute( 'aria-label', label );\r
+               }, null, null, 9999 );\r
+       }\r
+\r
+       function setupDragHandler( widget ) {\r
+               if ( !widget.draggable )\r
+                       return;\r
+\r
+               var editor = widget.editor,\r
+                       // Use getLast to find wrapper's direct descendant (#12022).\r
+                       container = widget.wrapper.getLast( Widget.isDomDragHandlerContainer ),\r
+                       img;\r
+\r
+               // Reuse drag handler if already exists (#11281).\r
+               if ( container )\r
+                       img = container.findOne( 'img' );\r
+               else {\r
+                       container = new CKEDITOR.dom.element( 'span', editor.document );\r
+                       container.setAttributes( {\r
+                               'class': 'cke_reset cke_widget_drag_handler_container',\r
+                               // Split background and background-image for IE8 which will break on rgba().\r
+                               style: 'background:rgba(220,220,220,0.5);background-image:url(' + editor.plugins.widget.path + 'images/handle.png)'\r
+                       } );\r
+\r
+                       img = new CKEDITOR.dom.element( 'img', editor.document );\r
+                       img.setAttributes( {\r
+                               'class': 'cke_reset cke_widget_drag_handler',\r
+                               'data-cke-widget-drag-handler': '1',\r
+                               src: CKEDITOR.tools.transparentImageData,\r
+                               width: DRAG_HANDLER_SIZE,\r
+                               title: editor.lang.widget.move,\r
+                               height: DRAG_HANDLER_SIZE,\r
+                               role: 'presentation'\r
+                       } );\r
+                       widget.inline && img.setAttribute( 'draggable', 'true' );\r
+\r
+                       container.append( img );\r
+                       widget.wrapper.append( container );\r
+               }\r
+\r
+               // Preventing page reload when dropped content on widget wrapper (#13015).\r
+               // Widget is not editable so by default drop on it isn't allowed what means that\r
+               // browser handles it (there's no editable#drop event). If there's no drop event we cannot block\r
+               // the drop, so page is reloaded. This listener enables drop on widget wrappers.\r
+               widget.wrapper.on( 'dragover', function( evt ) {\r
+                       evt.data.preventDefault();\r
+               } );\r
+\r
+               widget.wrapper.on( 'mouseenter', widget.updateDragHandlerPosition, widget );\r
+               setTimeout( function() {\r
+                       widget.on( 'data', widget.updateDragHandlerPosition, widget );\r
+               }, 50 );\r
+\r
+               if ( !widget.inline ) {\r
+                       img.on( 'mousedown', onBlockWidgetDrag, widget );\r
+\r
+                       // On IE8 'dragstart' is propagated to editable, so editor#dragstart is fired twice on block widgets.\r
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {\r
+                               img.on( 'dragstart', function( evt ) {\r
+                                       evt.data.preventDefault( true );\r
+                               } );\r
+                       }\r
+               }\r
+\r
+               widget.dragHandlerContainer = container;\r
+       }\r
+\r
+       function onBlockWidgetDrag( evt ) {\r
+               var finder = this.repository.finder,\r
+                       locator = this.repository.locator,\r
+                       liner = this.repository.liner,\r
+                       editor = this.editor,\r
+                       editable = editor.editable(),\r
+                       listeners = [],\r
+                       sorted = [],\r
+                       locations,\r
+                       y;\r
+\r
+               // Mark dragged widget for repository#finder.\r
+               this.repository._.draggedWidget = this;\r
+\r
+               // Harvest all possible relations and display some closest.\r
+               var relations = finder.greedySearch(),\r
+\r
+                       buffer = CKEDITOR.tools.eventsBuffer( 50, function() {\r
+                               locations = locator.locate( relations );\r
+\r
+                               // There's only a single line displayed for D&D.\r
+                               sorted = locator.sort( y, 1 );\r
+\r
+                               if ( sorted.length ) {\r
+                                       liner.prepare( relations, locations );\r
+                                       liner.placeLine( sorted[ 0 ] );\r
+                                       liner.cleanup();\r
+                               }\r
+                       } );\r
+\r
+               // Let's have the "dragging cursor" over entire editable.\r
+               editable.addClass( 'cke_widget_dragging' );\r
+\r
+               // Cache mouse position so it is re-used in events buffer.\r
+               listeners.push( editable.on( 'mousemove', function( evt ) {\r
+                       y = evt.data.$.clientY;\r
+                       buffer.input();\r
+               } ) );\r
+\r
+               // Fire drag start as it happens during the native D&D.\r
+               editor.fire( 'dragstart', { target: evt.sender } );\r
+\r
+               function onMouseUp() {\r
+                       var l;\r
+\r
+                       buffer.reset();\r
+\r
+                       // Stop observing events.\r
+                       while ( ( l = listeners.pop() ) )\r
+                               l.removeListener();\r
+\r
+                       onBlockWidgetDrop.call( this, sorted, evt.sender );\r
+               }\r
+\r
+               // Mouseup means "drop". This is when the widget is being detached\r
+               // from DOM and placed at range determined by the line (location).\r
+               listeners.push( editor.document.once( 'mouseup', onMouseUp, this ) );\r
+\r
+               // Prevent calling 'onBlockWidgetDrop' twice in the inline editor.\r
+               // `removeListener` does not work if it is called at the same time event is fired.\r
+               if ( !editable.isInline() ) {\r
+                       // Mouseup may occur when user hovers the line, which belongs to\r
+                       // the outer document. This is, of course, a valid listener too.\r
+                       listeners.push( CKEDITOR.document.once( 'mouseup', onMouseUp, this ) );\r
+               }\r
+       }\r
+\r
+       function onBlockWidgetDrop( sorted, dragTarget ) {\r
+               var finder = this.repository.finder,\r
+                       liner = this.repository.liner,\r
+                       editor = this.editor,\r
+                       editable = this.editor.editable();\r
+\r
+               if ( !CKEDITOR.tools.isEmpty( liner.visible ) ) {\r
+                       // Retrieve range for the closest location.\r
+                       var dropRange = finder.getRange( sorted[ 0 ] );\r
+\r
+                       // Focus widget (it could lost focus after mousedown+mouseup)\r
+                       // and save this state as the one where we want to be taken back when undoing.\r
+                       this.focus();\r
+\r
+                       // Drag range will be set in the drop listener.\r
+                       editor.fire( 'drop', {\r
+                               dropRange: dropRange,\r
+                               target: dropRange.startContainer\r
+                       } );\r
+               }\r
+\r
+               // Clean-up custom cursor for editable.\r
+               editable.removeClass( 'cke_widget_dragging' );\r
+\r
+               // Clean-up all remaining lines.\r
+               liner.hideVisible();\r
+\r
+               // Clean-up drag & drop.\r
+               editor.fire( 'dragend', { target: dragTarget } );\r
+       }\r
+\r
+       function setupEditables( widget ) {\r
+               var editableName,\r
+                       editableDef,\r
+                       definedEditables = widget.editables;\r
+\r
+               widget.editables = {};\r
+\r
+               if ( !widget.editables )\r
+                       return;\r
+\r
+               for ( editableName in definedEditables ) {\r
+                       editableDef = definedEditables[ editableName ];\r
+                       widget.initEditable( editableName, typeof editableDef == 'string' ? { selector: editableDef } : editableDef );\r
+               }\r
+       }\r
+\r
+       function setupMask( widget ) {\r
+               if ( !widget.mask )\r
+                       return;\r
+\r
+               // Reuse mask if already exists (#11281).\r
+               var img = widget.wrapper.findOne( '.cke_widget_mask' );\r
+\r
+               if ( !img ) {\r
+                       img = new CKEDITOR.dom.element( 'img', widget.editor.document );\r
+                       img.setAttributes( {\r
+                               src: CKEDITOR.tools.transparentImageData,\r
+                               'class': 'cke_reset cke_widget_mask'\r
+                       } );\r
+                       widget.wrapper.append( img );\r
+               }\r
+\r
+               widget.mask = img;\r
+       }\r
+\r
+       // Replace parts object containing:\r
+       // partName => selector pairs\r
+       // with:\r
+       // partName => element pairs\r
+       function setupParts( widget ) {\r
+               if ( widget.parts ) {\r
+                       var parts = {},\r
+                               el, partName;\r
+\r
+                       for ( partName in widget.parts ) {\r
+                               el = widget.wrapper.findOne( widget.parts[ partName ] );\r
+                               parts[ partName ] = el;\r
+                       }\r
+                       widget.parts = parts;\r
+               }\r
+       }\r
+\r
+       function setupWidget( widget, widgetDef ) {\r
+               setupWrapper( widget );\r
+               setupParts( widget );\r
+               setupEditables( widget );\r
+               setupMask( widget );\r
+               setupDragHandler( widget );\r
+               setupDataClassesListener( widget );\r
+               setupA11yListener( widget );\r
+\r
+               // #11145: [IE8] Non-editable content of widget is draggable.\r
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {\r
+                       widget.wrapper.on( 'dragstart', function( evt ) {\r
+                               var target = evt.data.getTarget();\r
+\r
+                               // Allow text dragging inside nested editables or dragging inline widget's drag handler.\r
+                               if ( !Widget.getNestedEditable( widget, target ) && !( widget.inline && Widget.isDomDragHandler( target ) ) )\r
+                                       evt.data.preventDefault();\r
+                       } );\r
+               }\r
+\r
+               widget.wrapper.removeClass( 'cke_widget_new' );\r
+               widget.element.addClass( 'cke_widget_element' );\r
+\r
+               widget.on( 'key', function( evt ) {\r
+                       var keyCode = evt.data.keyCode;\r
+\r
+                       // ENTER.\r
+                       if ( keyCode == 13 ) {\r
+                               widget.edit();\r
+                               // CTRL+C or CTRL+X.\r
+                       } else if ( keyCode == CKEDITOR.CTRL + 67 || keyCode == CKEDITOR.CTRL + 88 ) {\r
+                               copySingleWidget( widget, keyCode == CKEDITOR.CTRL + 88 );\r
+                               return; // Do not preventDefault.\r
+                       } else if ( keyCode in keystrokesNotBlockedByWidget || ( CKEDITOR.CTRL & keyCode ) || ( CKEDITOR.ALT & keyCode ) ) {\r
+                               // Pass chosen keystrokes to other plugins or default fake sel handlers.\r
+                               // Pass all CTRL/ALT keystrokes.\r
+                               return;\r
+                       }\r
+\r
+                       return false;\r
+               }, null, null, 999 );\r
+               // Listen with high priority so it's possible\r
+               // to overwrite this callback.\r
+\r
+               widget.on( 'doubleclick', function( evt ) {\r
+                       if ( widget.edit() ) {\r
+                               // We have to cancel event if edit method opens a dialog, otherwise\r
+                               // link plugin may open extra dialog (#12140).\r
+                               evt.cancel();\r
+                       }\r
+               } );\r
+\r
+               if ( widgetDef.data )\r
+                       widget.on( 'data', widgetDef.data );\r
+\r
+               if ( widgetDef.edit )\r
+                       widget.on( 'edit', widgetDef.edit );\r
+       }\r
+\r
+       function setupWidgetData( widget, startupData ) {\r
+               var widgetDataAttr = widget.element.data( 'cke-widget-data' );\r
+\r
+               if ( widgetDataAttr )\r
+                       widget.setData( JSON.parse( decodeURIComponent( widgetDataAttr ) ) );\r
+               if ( startupData )\r
+                       widget.setData( startupData );\r
+\r
+               // Populate classes if they are not preset.\r
+               if ( !widget.data.classes )\r
+                       widget.setData( 'classes', widget.getClasses() );\r
+\r
+               // Unblock data and...\r
+               widget.dataReady = true;\r
+\r
+               // Write data to element because this was blocked when data wasn't ready.\r
+               writeDataToElement( widget );\r
+\r
+               // Fire data event first time, because this was blocked when data wasn't ready.\r
+               widget.fire( 'data', widget.data );\r
+       }\r
+\r
+       function setupWrapper( widget ) {\r
+               // Retrieve widget wrapper. Assign an id to it.\r
+               var wrapper = widget.wrapper = widget.element.getParent();\r
+               wrapper.setAttribute( 'data-cke-widget-id', widget.id );\r
+       }\r
+\r
+       function writeDataToElement( widget ) {\r
+               widget.element.data( 'cke-widget-data', encodeURIComponent( JSON.stringify( widget.data ) ) );\r
+       }\r
+\r
+       //\r
+       // WIDGET STYLE HANDLER ---------------------------------------------------\r
+       //\r
+\r
+       ( function() {\r
+               // Styles categorized by group. It is used to prevent applying styles for the same group being used together.\r
+               var styleGroups = {};\r
+\r
+               /**\r
+                * The class representing a widget style. It is an {@link CKEDITOR#STYLE_OBJECT object} like\r
+                * the styles handler for widgets.\r
+                *\r
+                * **Note:** This custom style handler does not support all methods of the {@link CKEDITOR.style} class.\r
+                * Not supported methods: {@link #applyToRange}, {@link #removeFromRange}, {@link #applyToObject}.\r
+                *\r
+                * @since 4.4\r
+                * @class CKEDITOR.style.customHandlers.widget\r
+                * @extends CKEDITOR.style\r
+                */\r
+               CKEDITOR.style.addCustomHandler( {\r
+                       type: 'widget',\r
+\r
+                       setup: function( styleDefinition ) {\r
+                               /**\r
+                                * The name of widget to which this style can be applied.\r
+                                * It is extracted from style definition's `widget` property.\r
+                                *\r
+                                * @property {String} widget\r
+                                */\r
+                               this.widget = styleDefinition.widget;\r
+\r
+                               /**\r
+                                * An array of groups that this style belongs to.\r
+                                * Styles assigned to the same group cannot be combined.\r
+                                *\r
+                                * @since 4.6.2\r
+                                * @property {Array} group\r
+                                */\r
+                               this.group = typeof styleDefinition.group == 'string' ? [ styleDefinition.group ] : styleDefinition.group;\r
+\r
+                               // Store style categorized by its group.\r
+                               // It is used to prevent enabling two styles from same group.\r
+                               if ( this.group ) {\r
+                                       saveStyleGroup( this );\r
+                               }\r
+                       },\r
+\r
+                       apply: function( editor ) {\r
+                               var widget;\r
+\r
+                               // Before CKEditor 4.4 wasn't a required argument, so we need to\r
+                               // handle a case when it wasn't provided.\r
+                               if ( !( editor instanceof CKEDITOR.editor ) )\r
+                                       return;\r
+\r
+                               // Theoretically we could bypass checkApplicable, get widget from\r
+                               // widgets.focused and check its name, what would be faster, but then\r
+                               // this custom style would work differently than the default style\r
+                               // which checks if it's applicable before applying or removing itself.\r
+                               if ( this.checkApplicable( editor.elementPath(), editor ) ) {\r
+                                       widget = editor.widgets.focused;\r
+\r
+                                       // Remove other styles from the same group.\r
+                                       if ( this.group ) {\r
+                                               this.removeStylesFromSameGroup( editor );\r
+                                       }\r
+\r
+                                       widget.applyStyle( this );\r
+                               }\r
+                       },\r
+\r
+                       remove: function( editor ) {\r
+                               // Before CKEditor 4.4 wasn't a required argument, so we need to\r
+                               // handle a case when it wasn't provided.\r
+                               if ( !( editor instanceof CKEDITOR.editor ) )\r
+                                       return;\r
+\r
+                               if ( this.checkApplicable( editor.elementPath(), editor ) )\r
+                                       editor.widgets.focused.removeStyle( this );\r
+                       },\r
+\r
+                       /**\r
+                        * Removes all styles that belong to the same group as this style. This method will neither add nor remove\r
+                        * the current style.\r
+                        * Returns `true` if any style was removed, otherwise returns `false`.\r
+                        *\r
+                        * @since 4.6.2\r
+                        * @param {CKEDITOR.editor} editor\r
+                        * @returns {Boolean}\r
+                        */\r
+                       removeStylesFromSameGroup: function( editor ) {\r
+                               var stylesFromSameGroup,\r
+                                       path,\r
+                                       removed = false;\r
+\r
+                               // Before CKEditor 4.4 wasn't a required argument, so we need to\r
+                               // handle a case when it wasn't provided.\r
+                               if ( !( editor instanceof CKEDITOR.editor ) )\r
+                                       return false;\r
+\r
+                               path = editor.elementPath();\r
+                               if ( this.checkApplicable( path, editor ) ) {\r
+                                       // Iterate over each group.\r
+                                       for ( var i = 0, l = this.group.length; i < l; i++ ) {\r
+                                               stylesFromSameGroup = styleGroups[ this.widget ][ this.group[ i ] ];\r
+                                               // Iterate over each style from group.\r
+                                               for ( var j = 0; j < stylesFromSameGroup.length; j++ ) {\r
+                                                       if ( stylesFromSameGroup[ j ] !== this && stylesFromSameGroup[ j ].checkActive( path, editor ) ) {\r
+                                                               editor.widgets.focused.removeStyle( stylesFromSameGroup[ j ] );\r
+                                                               removed = true;\r
+                                                       }\r
+                                               }\r
+                                       }\r
+                               }\r
+\r
+                               return removed;\r
+                       },\r
+\r
+                       checkActive: function( elementPath, editor ) {\r
+                               return this.checkElementMatch( elementPath.lastElement, 0, editor );\r
+                       },\r
+\r
+                       checkApplicable: function( elementPath, editor ) {\r
+                               // Before CKEditor 4.4 wasn't a required argument, so we need to\r
+                               // handle a case when it wasn't provided.\r
+                               if ( !( editor instanceof CKEDITOR.editor ) )\r
+                                       return false;\r
+\r
+                               return this.checkElement( elementPath.lastElement );\r
+                       },\r
+\r
+                       checkElementMatch: checkElementMatch,\r
+\r
+                       checkElementRemovable: checkElementMatch,\r
+\r
+                       /**\r
+                        * Checks if an element is a {@link CKEDITOR.plugins.widget#wrapper wrapper} of a\r
+                        * widget whose name matches the {@link #widget widget name} specified in the style definition.\r
+                        *\r
+                        * @param {CKEDITOR.dom.element} element\r
+                        * @returns {Boolean}\r
+                        */\r
+                       checkElement: function( element ) {\r
+                               if ( !Widget.isDomWidgetWrapper( element ) )\r
+                                       return false;\r
+\r
+                               var widgetElement = element.getFirst( Widget.isDomWidgetElement );\r
+                               return widgetElement && widgetElement.data( 'widget' ) == this.widget;\r
+                       },\r
+\r
+                       buildPreview: function( label ) {\r
+                               return label || this._.definition.name;\r
+                       },\r
+\r
+                       /**\r
+                        * Returns allowed content rules which should be registered for this style.\r
+                        * Uses widget's {@link CKEDITOR.plugins.widget.definition#styleableElements} to make a rule\r
+                        * allowing classes on specified elements or use widget's\r
+                        * {@link CKEDITOR.plugins.widget.definition#styleToAllowedContentRules} method to transform a style\r
+                        * into allowed content rules.\r
+                        *\r
+                        * @param {CKEDITOR.editor} The editor instance.\r
+                        * @returns {CKEDITOR.filter.allowedContentRules}\r
+                        */\r
+                       toAllowedContentRules: function( editor ) {\r
+                               if ( !editor )\r
+                                       return null;\r
+\r
+                               var widgetDef = editor.widgets.registered[ this.widget ],\r
+                                       classes,\r
+                                       rule = {};\r
+\r
+                               if ( !widgetDef )\r
+                                       return null;\r
+\r
+                               if ( widgetDef.styleableElements ) {\r
+                                       classes = this.getClassesArray();\r
+                                       if ( !classes )\r
+                                               return null;\r
+\r
+                                       rule[ widgetDef.styleableElements ] = {\r
+                                               classes: classes,\r
+                                               propertiesOnly: true\r
+                                       };\r
+                                       return rule;\r
+                               }\r
+                               if ( widgetDef.styleToAllowedContentRules )\r
+                                       return widgetDef.styleToAllowedContentRules( this );\r
+                               return null;\r
+                       },\r
+\r
+                       /**\r
+                        * Returns classes defined in the style in form of an array.\r
+                        *\r
+                        * @returns {String[]}\r
+                        */\r
+                       getClassesArray: function() {\r
+                               var classes = this._.definition.attributes && this._.definition.attributes[ 'class' ];\r
+\r
+                               return classes ? CKEDITOR.tools.trim( classes ).split( /\s+/ ) : null;\r
+                       },\r
+\r
+                       /**\r
+                        * Not implemented.\r
+                        *\r
+                        * @method applyToRange\r
+                        */\r
+                       applyToRange: notImplemented,\r
+\r
+                       /**\r
+                        * Not implemented.\r
+                        *\r
+                        * @method removeFromRange\r
+                        */\r
+                       removeFromRange: notImplemented,\r
+\r
+                       /**\r
+                        * Not implemented.\r
+                        *\r
+                        * @method applyToObject\r
+                        */\r
+                       applyToObject: notImplemented\r
+               } );\r
+\r
+               function notImplemented() {}\r
+\r
+               // @context style\r
+               function checkElementMatch( element, fullMatch, editor ) {\r
+                       // Before CKEditor 4.4 wasn't a required argument, so we need to\r
+                       // handle a case when it wasn't provided.\r
+                       if ( !editor )\r
+                               return false;\r
+\r
+                       if ( !this.checkElement( element ) )\r
+                               return false;\r
+\r
+                       var widget = editor.widgets.getByElement( element, true );\r
+                       return widget && widget.checkStyleActive( this );\r
+               }\r
+\r
+               // Save and categorize style by its group.\r
+               function saveStyleGroup( style ) {\r
+                       var widgetName = style.widget,\r
+                               group;\r
+\r
+                       if ( !styleGroups[ widgetName ] ) {\r
+                               styleGroups[ widgetName ] = {};\r
+                       }\r
+\r
+                       for ( var i = 0, l = style.group.length; i < l; i++ ) {\r
+                               group = style.group[ i ];\r
+                               if ( !styleGroups[ widgetName ][ group ] ) {\r
+                                       styleGroups[ widgetName ][ group ] = [];\r
+                               }\r
+\r
+                               styleGroups[ widgetName ][ group ].push( style );\r
+                       }\r
+               }\r
+\r
+       } )();\r
+\r
+       //\r
+       // EXPOSE PUBLIC API ------------------------------------------------------\r
+       //\r
+\r
+       CKEDITOR.plugins.widget = Widget;\r
+       Widget.repository = Repository;\r
+       Widget.nestedEditable = NestedEditable;\r
+} )();\r
+\r
+/**\r
+ * An event fired when a widget definition is registered by the {@link CKEDITOR.plugins.widget.repository#add} method.\r
+ * It is possible to modify the definition being registered.\r
+ *\r
+ * @event widgetDefinition\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.plugins.widget.definition} data Widget definition.\r
+ */\r
+\r
+/**\r
+ * This is an abstract class that describes the definition of a widget.\r
+ * It is a type of {@link CKEDITOR.plugins.widget.repository#add} method's second argument.\r
+ *\r
+ * Widget instances inherit from registered widget definitions, although not in a prototypal way.\r
+ * They are simply extended with corresponding widget definitions. Note that not all properties of\r
+ * the widget definition become properties of a widget. Some, like {@link #data} or {@link #edit}, become\r
+ * widget's events listeners.\r
+ *\r
+ * @class CKEDITOR.plugins.widget.definition\r
+ * @abstract\r
+ * @mixins CKEDITOR.feature\r
+ */\r
+\r
+/**\r
+ * Widget definition name. It is automatically set when the definition is\r
+ * {@link CKEDITOR.plugins.widget.repository#add registered}.\r
+ *\r
+ * @property {String} name\r
+ */\r
+\r
+/**\r
+ * The method executed while initializing a widget, after a widget instance\r
+ * is created, but before it is ready. It is executed before the first\r
+ * {@link CKEDITOR.plugins.widget#event-data} is fired so it is common to\r
+ * use the `init` method to populate widget data with information loaded from\r
+ * the DOM, like for exmaple:\r
+ *\r
+ *             init: function() {\r
+ *                     this.setData( 'width', this.element.getStyle( 'width' ) );\r
+ *\r
+ *                     if ( this.parts.caption.getStyle( 'display' ) != 'none' )\r
+ *                             this.setData( 'showCaption', true );\r
+ *             }\r
+ *\r
+ * @property {Function} init\r
+ */\r
+\r
+/**\r
+ * The function to be used to upcast an element to this widget or a\r
+ * comma-separated list of upcast methods from the {@link #upcasts} object.\r
+ *\r
+ * The upcast function **is not** executed in the widget context (because the widget\r
+ * does not exist yet) and two arguments are passed:\r
+ *\r
+ * * `element` ({@link CKEDITOR.htmlParser.element}) &ndash; The element to be checked.\r
+ * * `data` (`Object`) &ndash; The object which can be extended with data which will then be passed to the widget.\r
+ *\r
+ * An element will be upcasted if a function returned `true` or an instance of\r
+ * a {@link CKEDITOR.htmlParser.element} if upcasting meant DOM structure changes\r
+ * (in this case the widget will be initialized on the returned element).\r
+ *\r
+ * @property {String/Function} upcast\r
+ */\r
+\r
+/**\r
+ * The object containing functions which can be used to upcast this widget.\r
+ * Only those pointed by the {@link #upcast} property will be used.\r
+ *\r
+ * In most cases it is appropriate to use {@link #upcast} directly,\r
+ * because majority of widgets need just one method.\r
+ * However, in some cases the widget author may want to expose more than one variant\r
+ * and then this property may be used.\r
+ *\r
+ *             upcasts: {\r
+ *                     // This function may upcast only figure elements.\r
+ *                     figure: function() {\r
+ *                             // ...\r
+ *                     },\r
+ *                     // This function may upcast only image elements.\r
+ *                     image: function() {\r
+ *                             // ...\r
+ *                     },\r
+ *                     // More variants...\r
+ *             }\r
+ *\r
+ *             // Then, widget user may choose which upcast methods will be enabled.\r
+ *             editor.on( 'widgetDefinition', function( evt ) {\r
+ *                     if ( evt.data.name == 'image' )\r
+ *                             evt.data.upcast = 'figure,image'; // Use both methods.\r
+ *             } );\r
+ *\r
+ * @property {Object} upcasts\r
+ */\r
+\r
+/**\r
+ * The {@link #upcast} method(s) priority. The upcast with a lower priority number will be called before\r
+ * the one with a higher number. The default priority is `10`.\r
+ *\r
+ * @since 4.5\r
+ * @property {Number} [upcastPriority=10]\r
+ */\r
+\r
+/**\r
+ * The function to be used to downcast this widget or\r
+ * a name of the downcast option from the {@link #downcasts} object.\r
+ *\r
+ * The downcast funciton will be executed in the {@link CKEDITOR.plugins.widget} context\r
+ * and with `widgetElement` ({@link CKEDITOR.htmlParser.element}) argument which is\r
+ * the widget's main element.\r
+ *\r
+ * The function may return an instance of the {@link CKEDITOR.htmlParser.node} class if the widget\r
+ * needs to be downcasted to a different node than the widget's main element.\r
+ *\r
+ * @property {String/Function} downcast\r
+ */\r
+\r
+/**\r
+ * The object containing functions which can be used to downcast this widget.\r
+ * Only the one pointed by the {@link #downcast} property will be used.\r
+ *\r
+ * In most cases it is appropriate to use {@link #downcast} directly,\r
+ * because majority of widgets have just one variant of downcasting (or none at all).\r
+ * However, in some cases the widget author may want to expose more than one variant\r
+ * and then this property may be used.\r
+ *\r
+ *             downcasts: {\r
+ *                     // This downcast may transform the widget into the figure element.\r
+ *                     figure: function() {\r
+ *                             // ...\r
+ *                     },\r
+ *                     // This downcast may transform the widget into the image element with data-* attributes.\r
+ *                     image: function() {\r
+ *                             // ...\r
+ *                     }\r
+ *             }\r
+ *\r
+ *             // Then, the widget user may choose one of the downcast options when setting up his editor.\r
+ *             editor.on( 'widgetDefinition', function( evt ) {\r
+ *                     if ( evt.data.name == 'image' )\r
+ *                             evt.data.downcast = 'figure';\r
+ *             } );\r
+ *\r
+ * @property downcasts\r
+ */\r
+\r
+/**\r
+ * If set, it will be added as the {@link CKEDITOR.plugins.widget#event-edit} event listener.\r
+ * This means that it will be executed when a widget is being edited.\r
+ * See the {@link CKEDITOR.plugins.widget#method-edit} method.\r
+ *\r
+ * @property {Function} edit\r
+ */\r
+\r
+/**\r
+ * If set, it will be added as the {@link CKEDITOR.plugins.widget#event-data} event listener.\r
+ * This means that it will be executed every time the {@link CKEDITOR.plugins.widget#property-data widget data} changes.\r
+ *\r
+ * @property {Function} data\r
+ */\r
+\r
+/**\r
+ * The method to be executed when the widget's command is executed in order to insert a new widget\r
+ * (widget of this type is not focused). If not defined, then the default action will be\r
+ * performed which means that:\r
+ *\r
+ * * An instance of the widget will be created in a detached {@link CKEDITOR.dom.documentFragment document fragment},\r
+ * * The {@link CKEDITOR.plugins.widget#method-edit} method will be called to trigger widget editing,\r
+ * * The widget element will be inserted into DOM.\r
+ *\r
+ * @property {Function} insert\r
+ */\r
+\r
+/**\r
+ * The name of a dialog window which will be opened on {@link CKEDITOR.plugins.widget#method-edit}.\r
+ * If not defined, then the {@link CKEDITOR.plugins.widget#method-edit} method will not perform any action and\r
+ * widget's command will insert a new widget without opening a dialog window first.\r
+ *\r
+ * @property {String} dialog\r
+ */\r
+\r
+/**\r
+ * The template which will be used to create a new widget element (when the widget's command is executed).\r
+ * This string is populated with {@link #defaults default values} by using the {@link CKEDITOR.template} format.\r
+ * Therefore it has to be a valid {@link CKEDITOR.template} argument.\r
+ *\r
+ * @property {String} template\r
+ */\r
+\r
+/**\r
+ * The data object which will be used to populate the data of a newly created widget.\r
+ * See {@link CKEDITOR.plugins.widget#property-data}.\r
+ *\r
+ *             defaults: {\r
+ *                     showCaption: true,\r
+ *                     align: 'none'\r
+ *             }\r
+ *\r
+ * @property defaults\r
+ */\r
+\r
+/**\r
+ * An object containing definitions of widget components (part name => CSS selector).\r
+ *\r
+ *             parts: {\r
+ *                     image: 'img',\r
+ *                     caption: 'div.caption'\r
+ *             }\r
+ *\r
+ * @property parts\r
+ */\r
+\r
+/**\r
+ * An object containing definitions of nested editables (editable name => {@link CKEDITOR.plugins.widget.nestedEditable.definition}).\r
+ * Note that editables *have to* be defined in the same order as they are in DOM / {@link CKEDITOR.plugins.widget.definition#template template}.\r
+ * Otherwise errors will occur when nesting widgets inside each other.\r
+ *\r
+ *             editables: {\r
+ *                     header: 'h1',\r
+ *                     content: {\r
+ *                             selector: 'div.content',\r
+ *                             allowedContent: 'p strong em; a[!href]'\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @property editables\r
+ */\r
+\r
+/**\r
+ * The function used to obtain an accessibility label for the widget. It might be used to make\r
+ * the widget labels as precise as possible, since it has access to the widget instance.\r
+ *\r
+ * If not specified, the default implementation will use the {@link #pathName} or the main\r
+ * {@link CKEDITOR.plugins.widget#element element} tag name.\r
+ *\r
+ * @property {Function} getLabel\r
+ */\r
+\r
+/**\r
+ * The widget name displayed in the elements path.\r
+ *\r
+ * @property {String} pathName\r
+ */\r
+\r
+/**\r
+ * If set to `true`, the widget's element will be covered with a transparent mask.\r
+ * This will prevent its content from being clickable, which matters in case\r
+ * of special elements like embedded Flash or iframes that generate a separate "context".\r
+ *\r
+ * @property {Boolean} mask\r
+ */\r
+\r
+/**\r
+ * If set to `true/false`, it will force the widget to be either an inline or a block widget.\r
+ * If not set, the widget type will be determined from the widget element.\r
+ *\r
+ * Widget type influences whether a block (`div`) or an inline (`span`) element is used\r
+ * for the wrapper.\r
+ *\r
+ * @property {Boolean} inline\r
+ */\r
+\r
+/**\r
+ * The label for the widget toolbar button.\r
+ *\r
+ *             editor.widgets.add( 'simplebox', {\r
+ *                     button: 'Create a simple box'\r
+ *             } );\r
+ *\r
+ *             editor.widgets.add( 'simplebox', {\r
+ *                     button: editor.lang.simplebox.title\r
+ *             } );\r
+ *\r
+ * @property {String} button\r
+ */\r
+\r
+/**\r
+ * Whether widget should be draggable. Defaults to `true`.\r
+ * If set to `false` drag handler will not be displayed when hovering widget.\r
+ *\r
+ * @property {Boolean} draggable\r
+ */\r
+\r
+/**\r
+ * Names of element(s) (separated by spaces) for which the {@link CKEDITOR.filter} should allow classes\r
+ * defined in the widget styles. For example if your widget is upcasted from a simple `<div>`\r
+ * element, then in order to make it styleable you can set:\r
+ *\r
+ *             editor.widgets.add( 'customWidget', {\r
+ *                     upcast: function( element ) {\r
+ *                             return element.name == 'div';\r
+ *                     },\r
+ *\r
+ *                     // ...\r
+ *\r
+ *                     styleableElements: 'div'\r
+ *             } );\r
+ *\r
+ * Then, when the following style is defined:\r
+ *\r
+ *             {\r
+ *                     name: 'Thick border', type: 'widget', widget: 'customWidget',\r
+ *                     attributes: { 'class': 'thickBorder' }\r
+ *             }\r
+ *\r
+ * a rule allowing the `thickBorder` class for `div` elements will be registered in the {@link CKEDITOR.filter}.\r
+ *\r
+ * If you need to have more freedom when transforming widget style to allowed content rules,\r
+ * you can use the {@link #styleToAllowedContentRules} callback.\r
+ *\r
+ * @since 4.4\r
+ * @property {String} styleableElements\r
+ */\r
+\r
+/**\r
+ * Function transforming custom widget's {@link CKEDITOR.style} instance into\r
+ * {@link CKEDITOR.filter.allowedContentRules}. It may be used when a static\r
+ * {@link #styleableElements} property is not enough to inform the {@link CKEDITOR.filter}\r
+ * what HTML features should be enabled when allowing the given style.\r
+ *\r
+ * In most cases, when style's classes just have to be added to element name(s) used by\r
+ * the widget element, it is recommended to use simpler {@link #styleableElements} property.\r
+ *\r
+ * In order to get parsed classes from the style definition you can use\r
+ * {@link CKEDITOR.style.customHandlers.widget#getClassesArray}.\r
+ *\r
+ * For example, if you want to use the [object format of allowed content rules](#!/guide/dev_allowed_content_rules-section-object-format),\r
+ * to specify `match` validator, your implementation could look like this:\r
+ *\r
+ *             editor.widgets.add( 'customWidget', {\r
+ *                     // ...\r
+ *\r
+ *                     styleToAllowedContentRules: funciton( style ) {\r
+ *                             // Retrieve classes defined in the style.\r
+ *                             var classes = style.getClassesArray();\r
+ *\r
+ *                             // Do something crazy - for example return allowed content rules in object format,\r
+ *                             // with custom match property and propertiesOnly flag.\r
+ *                             return {\r
+ *                                     h1: {\r
+ *                                             match: isWidgetElement,\r
+ *                                             propertiesOnly: true,\r
+ *                                             classes: classes\r
+ *                                     }\r
+ *                             };\r
+ *                     }\r
+ *             } );\r
+ *\r
+ * @since 4.4\r
+ * @property {Function} styleToAllowedContentRules\r
+ * @param {CKEDITOR.style.customHandlers.widget} style The style to be transformed.\r
+ * @returns {CKEDITOR.filter.allowedContentRules}\r
+ */\r
+\r
+/**\r
+ * This is an abstract class that describes the definition of a widget's nested editable.\r
+ * It is a type of values in the {@link CKEDITOR.plugins.widget.definition#editables} object.\r
+ *\r
+ * In the simplest case the definition is a string which is a CSS selector used to\r
+ * find an element that will become a nested editable inside the widget. Note that\r
+ * the widget element can be a nested editable, too.\r
+ *\r
+ * In the more advanced case a definition is an object with a required `selector` property.\r
+ *\r
+ *             editables: {\r
+ *                     header: 'h1',\r
+ *                     content: {\r
+ *                             selector: 'div.content',\r
+ *                             allowedContent: 'p strong em; a[!href]'\r
+ *                     }\r
+ *             }\r
+ *\r
+ * @class CKEDITOR.plugins.widget.nestedEditable.definition\r
+ * @abstract\r
+ */\r
+\r
+/**\r
+ * The CSS selector used to find an element which will become a nested editable.\r
+ *\r
+ * @property {String} selector\r
+ */\r
+\r
+/**\r
+ * The [Advanced Content Filter](#!/guide/dev_advanced_content_filter) rules\r
+ * which will be used to limit the content allowed in this nested editable.\r
+ * This option is similar to {@link CKEDITOR.config#allowedContent} and one can\r
+ * use it to limit the editor features available in the nested editable.\r
+ *\r
+ * @property {CKEDITOR.filter.allowedContentRules} allowedContent\r
+ */\r
+\r
+/**\r
+ * Nested editable name displayed in elements path.\r
+ *\r
+ * @property {String} pathName\r
+ */\r
diff --git a/sources/plugins/widgetselection/plugin.js b/sources/plugins/widgetselection/plugin.js
new file mode 100644 (file)
index 0000000..b7aa6a0
--- /dev/null
@@ -0,0 +1,366 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview A plugin created to handle ticket #11064. While the issue is caused by native WebKit/Blink behaviour,\r
+ * this plugin can be easily detached or modified when the issue is fixed in the browsers without changing the core.\r
+ * When Ctrl/Cmd + A is pressed to select all content it does not work due to a bug in\r
+ * Webkit/Blink if a non-editable element is at the beginning or the end of the content.\r
+ */\r
+\r
+( function() {\r
+       'use strict';\r
+\r
+       CKEDITOR.plugins.add( 'widgetselection', {\r
+\r
+               init: function( editor ) {\r
+                       if ( CKEDITOR.env.webkit ) {\r
+                               var widgetselection = CKEDITOR.plugins.widgetselection;\r
+\r
+                               editor.on( 'contentDom', function( evt ) {\r
+\r
+                                       var editor = evt.editor,\r
+                                               doc = editor.document,\r
+                                               editable = editor.editable();\r
+\r
+                                       editable.attachListener( doc, 'keydown', function( evt ) {\r
+                                               var data = evt.data.$;\r
+\r
+                                               // Ctrl/Cmd + A\r
+                                               if ( evt.data.getKey() == 65 && ( CKEDITOR.env.mac && data.metaKey || !CKEDITOR.env.mac && data.ctrlKey ) ) {\r
+\r
+                                                       // Defer the call so the selection is already changed by the pressed keys.\r
+                                                       CKEDITOR.tools.setTimeout( function() {\r
+\r
+                                                               // Manage filler elements on keydown. If there is no need\r
+                                                               // to add fillers, we need to check and clean previously used once.\r
+                                                               if ( !widgetselection.addFillers( editable ) ) {\r
+                                                                       widgetselection.removeFillers( editable );\r
+                                                               }\r
+                                                       }, 0 );\r
+                                               }\r
+                                       }, null, null, -1 );\r
+\r
+                                       // Check and clean previously used fillers.\r
+                                       editor.on( 'selectionCheck', function( evt ) {\r
+                                               widgetselection.removeFillers( evt.editor.editable() );\r
+                                       } );\r
+\r
+                                       // Remove fillers on paste before data gets inserted into editor.\r
+                                       editor.on( 'paste', function( evt ) {\r
+                                               evt.data.dataValue = widgetselection.cleanPasteData( evt.data.dataValue );\r
+                                       } );\r
+\r
+                                       if ( 'selectall' in editor.plugins ) {\r
+                                               widgetselection.addSelectAllIntegration( editor );\r
+                                       }\r
+                               } );\r
+                       }\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * A set of helper methods for the Widget Selection plugin.\r
+        *\r
+        * @property widgetselection\r
+        * @member CKEDITOR.plugins\r
+        * @since 4.6.1\r
+        */\r
+       CKEDITOR.plugins.widgetselection = {\r
+\r
+               /**\r
+                * The start filler element reference.\r
+                *\r
+                * @property {CKEDITOR.dom.element}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               startFiller: null,\r
+\r
+               /**\r
+                * The end filler element reference.\r
+                *\r
+                * @property {CKEDITOR.dom.element}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               endFiller: null,\r
+\r
+               /**\r
+                * An attribute which identifies the filler element.\r
+                *\r
+                * @property {String}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               fillerAttribute: 'data-cke-filler-webkit',\r
+\r
+               /**\r
+                * The default content of the filler element. Note: The filler needs to have `visible` content.\r
+                * Unprintable elements or empty content do not help as a workaround.\r
+                *\r
+                * @property {String}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               fillerContent: '&nbsp;',\r
+\r
+               /**\r
+                * Tag name which is used to create fillers.\r
+                *\r
+                * @property {String}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               fillerTagName: 'div',\r
+\r
+               /**\r
+                * Adds a filler before or after a non-editable element at the beginning or the end of the `editable`.\r
+                *\r
+                * @param {CKEDITOR.editable} editable\r
+                * @returns {Boolean}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                */\r
+               addFillers: function( editable ) {\r
+                       var editor = editable.editor;\r
+\r
+                       // Whole content should be selected, if not fix the selection manually.\r
+                       if ( !this.isWholeContentSelected( editable ) && editable.getChildCount() > 0 ) {\r
+\r
+                               var firstChild = editable.getFirst( filterTempElements ),\r
+                                       lastChild = editable.getLast( filterTempElements );\r
+\r
+                               // Check if first element is editable. If not prepend with filler.\r
+                               if ( firstChild && firstChild.type == CKEDITOR.NODE_ELEMENT && !firstChild.isEditable() ) {\r
+                                       this.startFiller = this.createFiller();\r
+                                       editable.append( this.startFiller, 1 );\r
+                               }\r
+\r
+                               // Check if last element is editable. If not append filler.\r
+                               if ( lastChild && lastChild.type == CKEDITOR.NODE_ELEMENT && !lastChild.isEditable() ) {\r
+                                       this.endFiller = this.createFiller( true );\r
+                                       editable.append( this.endFiller, 0 );\r
+                               }\r
+\r
+                               // Reselect whole content after any filler was added.\r
+                               if ( this.hasFiller( editable ) ) {\r
+                                       var rangeAll = editor.createRange();\r
+                                       rangeAll.selectNodeContents( editable );\r
+                                       rangeAll.select();\r
+                                       return true;\r
+                               }\r
+                       }\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                * Removes filler elements or updates their references.\r
+                *\r
+                * It will **not remove** filler elements if the whole content is selected, as it would break the\r
+                * selection.\r
+                *\r
+                * @param {CKEDITOR.editable} editable\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                */\r
+               removeFillers: function( editable ) {\r
+                       // If startFiller or endFiller exists and not entire content is selected it means the selection\r
+                       // just changed from selected all. We need to remove fillers and set proper selection/content.\r
+                       if ( this.hasFiller( editable ) && !this.isWholeContentSelected( editable ) ) {\r
+\r
+                               var startFillerContent = editable.findOne( this.fillerTagName + '[' + this.fillerAttribute + '=start]' ),\r
+                                       endFillerContent = editable.findOne( this.fillerTagName + '[' + this.fillerAttribute + '=end]' );\r
+\r
+                               if ( this.startFiller && startFillerContent && this.startFiller.equals( startFillerContent ) ) {\r
+                                       this.removeFiller( this.startFiller, editable );\r
+                               } else {\r
+                                       // The start filler is still present but it is a different element than previous one. It means the\r
+                                       // undo recreating entirely selected content was performed. We need to update filler reference.\r
+                                       this.startFiller = startFillerContent;\r
+                               }\r
+\r
+                               if ( this.endFiller && endFillerContent && this.endFiller.equals( endFillerContent ) ) {\r
+                                       this.removeFiller( this.endFiller, editable );\r
+                               } else {\r
+                                       // Same as with start filler.\r
+                                       this.endFiller = endFillerContent;\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Removes fillers from the paste data.\r
+                *\r
+                * @param {String} data\r
+                * @returns {String}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               cleanPasteData: function( data ) {\r
+                       if ( data && data.length ) {\r
+                               data = data\r
+                                       .replace( this.createFillerRegex(), '' )\r
+                                       .replace( this.createFillerRegex( true ), '' );\r
+                       }\r
+                       return data;\r
+               },\r
+\r
+               /**\r
+                * Checks if the entire content of the given editable is selected.\r
+                *\r
+                * @param {CKEDITOR.editable} editable\r
+                * @returns {Boolean}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               isWholeContentSelected: function( editable ) {\r
+\r
+                       var range = editable.editor.getSelection().getRanges()[ 0 ];\r
+                       if ( range ) {\r
+\r
+                               if ( range && range.collapsed ) {\r
+                                       return false;\r
+\r
+                               } else {\r
+                                       var rangeClone = range.clone();\r
+                                       rangeClone.enlarge( CKEDITOR.ENLARGE_ELEMENT );\r
+\r
+                                       return !!( rangeClone && editable && rangeClone.startContainer && rangeClone.endContainer &&\r
+                                               rangeClone.startOffset === 0 && rangeClone.endOffset === editable.getChildCount() &&\r
+                                               rangeClone.startContainer.equals( editable ) && rangeClone.endContainer.equals( editable ) );\r
+                               }\r
+                       }\r
+                       return false;\r
+               },\r
+\r
+               /**\r
+                *      Checks if there is any filler element in the given editable.\r
+                *\r
+                * @param {CKEDITOR.editable} editable\r
+                * @returns {Boolean}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               hasFiller: function( editable ) {\r
+                       return editable.find( this.fillerTagName + '[' + this.fillerAttribute + ']' ).count() > 0;\r
+               },\r
+\r
+               /**\r
+                * Creates a filler element.\r
+                *\r
+                * @param {Boolean} [onEnd] If filler will be placed on end or beginning of the content.\r
+                * @returns {CKEDITOR.dom.element}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               createFiller: function( onEnd ) {\r
+                       var filler = new CKEDITOR.dom.element( this.fillerTagName );\r
+                       filler.setHtml( this.fillerContent );\r
+                       filler.setAttribute( this.fillerAttribute, onEnd ? 'end' : 'start' );\r
+                       filler.setAttribute( 'data-cke-temp', 1 );\r
+                       filler.setStyles( {\r
+                               display: 'block',\r
+                               width: 0,\r
+                               height: 0,\r
+                               padding: 0,\r
+                               border: 0,\r
+                               margin: 0,\r
+                               position: 'absolute',\r
+                               top: 0,\r
+                               left: '-9999px',\r
+                               opacity: 0,\r
+                               overflow: 'hidden'\r
+                       } );\r
+\r
+                       return filler;\r
+               },\r
+\r
+               /**\r
+                * Removes the specific filler element from the given editable. If the filler contains any content (typed or pasted),\r
+                * it replaces the current editable content. If not, the caret is placed before the first or after the last editable\r
+                * element (depends if the filler was at the beginning or the end).\r
+                *\r
+                * @param {CKEDITOR.dom.element} filler\r
+                * @param {CKEDITOR.editable} editable\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               removeFiller: function( filler, editable ) {\r
+                       if ( filler ) {\r
+                               var editor = editable.editor,\r
+                                       currentRange = editable.editor.getSelection().getRanges()[ 0 ],\r
+                                       currentPath = currentRange.startPath(),\r
+                                       range = editor.createRange(),\r
+                                       insertedHtml,\r
+                                       fillerOnStart,\r
+                                       manuallyHandleCaret;\r
+\r
+                               if ( currentPath.contains( filler ) ) {\r
+                                       insertedHtml = filler.getHtml();\r
+                                       manuallyHandleCaret = true;\r
+                               }\r
+\r
+                               fillerOnStart = filler.getAttribute( this.fillerAttribute ) == 'start';\r
+                               filler.remove();\r
+                               filler = null;\r
+\r
+                               if ( insertedHtml && insertedHtml.length > 0 && insertedHtml != this.fillerContent ) {\r
+                                       editable.insertHtmlIntoRange( insertedHtml, editor.getSelection().getRanges()[ 0 ] );\r
+                                       range.setStartAt( editable.getChild( editable.getChildCount() - 1 ), CKEDITOR.POSITION_BEFORE_END );\r
+                                       editor.getSelection().selectRanges( [ range ] );\r
+\r
+                               } else if ( manuallyHandleCaret ) {\r
+                                       if ( fillerOnStart ) {\r
+                                               range.setStartAt( editable.getFirst().getNext(), CKEDITOR.POSITION_AFTER_START );\r
+                                       } else {\r
+                                               range.setEndAt( editable.getLast().getPrevious(), CKEDITOR.POSITION_BEFORE_END );\r
+                                       }\r
+                                       editable.editor.getSelection().selectRanges( [ range ] );\r
+                               }\r
+                       }\r
+               },\r
+\r
+               /**\r
+                * Creates a regular expression which will match the filler HTML in the text.\r
+                *\r
+                * @param {Boolean} [onEnd] Whether a regular expression should be created for the filler at the beginning or\r
+                * the end of the content.\r
+                * @returns {RegExp}\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                * @private\r
+                */\r
+               createFillerRegex: function( onEnd ) {\r
+                       var matcher = this.createFiller( onEnd ).getOuterHtml()\r
+                               .replace( /style="[^"]*"/gi, 'style="[^"]*"' )\r
+                               .replace( />[^<]*</gi, '>[^<]*<' );\r
+\r
+                       return new RegExp( ( !onEnd ? '^' : '' ) + matcher + ( onEnd ? '$' : '' ) );\r
+               },\r
+\r
+               /**\r
+                * Adds an integration for the [Select All](http://ckeditor.com/addon/selectall) plugin to the given `editor`.\r
+                *\r
+                * @private\r
+                * @param {CKEDITOR.editor} editor\r
+                * @member CKEDITOR.plugins.widgetselection\r
+                */\r
+               addSelectAllIntegration: function( editor ) {\r
+                       var widgetselection = this;\r
+\r
+                       editor.editable().attachListener( editor, 'beforeCommandExec', function( evt ) {\r
+                               var editable = editor.editable();\r
+\r
+                               if ( evt.data.name == 'selectAll' && editable ) {\r
+                                       widgetselection.addFillers( editable );\r
+                               }\r
+                       }, null, null, 9999 );\r
+               }\r
+       };\r
+\r
+\r
+       function filterTempElements( el ) {\r
+               return el.getName && !el.hasAttribute( 'data-cke-temp' );\r
+       }\r
+\r
+} )();\r
diff --git a/sources/plugins/wysiwygarea/plugin.js b/sources/plugins/wysiwygarea/plugin.js
new file mode 100644 (file)
index 0000000..962f31e
--- /dev/null
@@ -0,0 +1,713 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/**\r
+ * @fileOverview The WYSIWYG Area plugin. It registers the "wysiwyg" editing\r
+ *             mode, which handles the main editing area space.\r
+ */\r
+\r
+( function() {\r
+       var framedWysiwyg;\r
+\r
+       CKEDITOR.plugins.add( 'wysiwygarea', {\r
+               init: function( editor ) {\r
+                       if ( editor.config.fullPage ) {\r
+                               editor.addFeature( {\r
+                                       allowedContent: 'html head title; style [media,type]; body (*)[id]; meta link [*]',\r
+                                       requiredContent: 'body'\r
+                               } );\r
+                       }\r
+\r
+                       editor.addMode( 'wysiwyg', function( callback ) {\r
+                               var src = 'document.open();' +\r
+                                       // In IE, the document domain must be set any time we call document.open().\r
+                                       ( CKEDITOR.env.ie ? '(' + CKEDITOR.tools.fixDomain + ')();' : '' ) +\r
+                                       'document.close();';\r
+\r
+                               // With IE, the custom domain has to be taken care at first,\r
+                               // for other browers, the 'src' attribute should be left empty to\r
+                               // trigger iframe's 'load' event.\r
+                               // Microsoft Edge throws "Permission Denied" if treated like an IE (#13441).\r
+                               if ( CKEDITOR.env.air ) {\r
+                                       src = 'javascript:void(0)'; // jshint ignore:line\r
+                               } else if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {\r
+                                       src = 'javascript:void(function(){' + encodeURIComponent( src ) + '}())'; // jshint ignore:line\r
+                               } else {\r
+                                       src = '';\r
+                               }\r
+\r
+                               var iframe = CKEDITOR.dom.element.createFromHtml( '<iframe src="' + src + '" frameBorder="0"></iframe>' );\r
+                               iframe.setStyles( { width: '100%', height: '100%' } );\r
+                               iframe.addClass( 'cke_wysiwyg_frame' ).addClass( 'cke_reset' );\r
+\r
+                               var contentSpace = editor.ui.space( 'contents' );\r
+                               contentSpace.append( iframe );\r
+\r
+\r
+                               // Asynchronous iframe loading is only required in IE>8 and Gecko (other reasons probably).\r
+                               // Do not use it on WebKit as it'll break the browser-back navigation.\r
+                               var useOnloadEvent = ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) || CKEDITOR.env.gecko;\r
+                               if ( useOnloadEvent )\r
+                                       iframe.on( 'load', onLoad );\r
+\r
+                               var frameLabel = editor.title,\r
+                                       helpLabel = editor.fire( 'ariaEditorHelpLabel', {} ).label;\r
+\r
+                               if ( frameLabel ) {\r
+                                       if ( CKEDITOR.env.ie && helpLabel )\r
+                                               frameLabel += ', ' + helpLabel;\r
+\r
+                                       iframe.setAttribute( 'title', frameLabel );\r
+                               }\r
+\r
+                               if ( helpLabel ) {\r
+                                       var labelId = CKEDITOR.tools.getNextId(),\r
+                                               desc = CKEDITOR.dom.element.createFromHtml( '<span id="' + labelId + '" class="cke_voice_label">' + helpLabel + '</span>' );\r
+\r
+                                       contentSpace.append( desc, 1 );\r
+                                       iframe.setAttribute( 'aria-describedby', labelId );\r
+                               }\r
+\r
+                               // Remove the ARIA description.\r
+                               editor.on( 'beforeModeUnload', function( evt ) {\r
+                                       evt.removeListener();\r
+                                       if ( desc )\r
+                                               desc.remove();\r
+                               } );\r
+\r
+                               iframe.setAttributes( {\r
+                                       tabIndex: editor.tabIndex,\r
+                                       allowTransparency: 'true'\r
+                               } );\r
+\r
+                               // Execute onLoad manually for all non IE||Gecko browsers.\r
+                               !useOnloadEvent && onLoad();\r
+\r
+                               editor.fire( 'ariaWidget', iframe );\r
+\r
+                               function onLoad( evt ) {\r
+                                       evt && evt.removeListener();\r
+                                       editor.editable( new framedWysiwyg( editor, iframe.$.contentWindow.document.body ) );\r
+                                       editor.setData( editor.getData( 1 ), callback );\r
+                               }\r
+                       } );\r
+               }\r
+       } );\r
+\r
+       /**\r
+        * Adds the path to a stylesheet file to the exisiting {@link CKEDITOR.config#contentsCss} value.\r
+        *\r
+        * **Note:** This method is available only with the `wysiwygarea` plugin and only affects\r
+        * classic editors based on it (so it does not affect inline editors).\r
+        *\r
+        *              editor.addContentsCss( 'assets/contents.css' );\r
+        *\r
+        * @since 4.4\r
+        * @param {String} cssPath The path to the stylesheet file which should be added.\r
+        * @member CKEDITOR.editor\r
+        */\r
+       CKEDITOR.editor.prototype.addContentsCss = function( cssPath ) {\r
+               var cfg = this.config,\r
+                       curContentsCss = cfg.contentsCss;\r
+\r
+               // Convert current value into array.\r
+               if ( !CKEDITOR.tools.isArray( curContentsCss ) )\r
+                       cfg.contentsCss = curContentsCss ? [ curContentsCss ] : [];\r
+\r
+               cfg.contentsCss.push( cssPath );\r
+       };\r
+\r
+       function onDomReady( win ) {\r
+               var editor = this.editor,\r
+                       doc = win.document,\r
+                       body = doc.body;\r
+\r
+               // Remove helper scripts from the DOM.\r
+               var script = doc.getElementById( 'cke_actscrpt' );\r
+               script && script.parentNode.removeChild( script );\r
+               script = doc.getElementById( 'cke_shimscrpt' );\r
+               script && script.parentNode.removeChild( script );\r
+               script = doc.getElementById( 'cke_basetagscrpt' );\r
+               script && script.parentNode.removeChild( script );\r
+\r
+               body.contentEditable = true;\r
+\r
+               if ( CKEDITOR.env.ie ) {\r
+                       // Don't display the focus border.\r
+                       body.hideFocus = true;\r
+\r
+                       // Disable and re-enable the body to avoid IE from\r
+                       // taking the editing focus at startup. (#141 / #523)\r
+                       body.disabled = true;\r
+                       body.removeAttribute( 'disabled' );\r
+               }\r
+\r
+               delete this._.isLoadingData;\r
+\r
+               // Play the magic to alter element reference to the reloaded one.\r
+               this.$ = body;\r
+\r
+               doc = new CKEDITOR.dom.document( doc );\r
+\r
+               this.setup();\r
+               this.fixInitialSelection();\r
+\r
+               var editable = this;\r
+\r
+               // Without it IE8 has problem with removing selection in nested editable. (#13785)\r
+               if ( CKEDITOR.env.ie && !CKEDITOR.env.edge ) {\r
+                       doc.getDocumentElement().addClass( doc.$.compatMode );\r
+               }\r
+\r
+               // Prevent IE/Edge from leaving a new paragraph/div after deleting all contents in body. (#6966, #13142)\r
+               if ( CKEDITOR.env.ie && !CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_P ) {\r
+                       removeSuperfluousElement( 'p' );\r
+               } else if ( CKEDITOR.env.edge && editor.enterMode != CKEDITOR.ENTER_DIV ) {\r
+                       removeSuperfluousElement( 'div' );\r
+               }\r
+\r
+               // Fix problem with cursor not appearing in Webkit and IE11+ when clicking below the body (#10945, #10906).\r
+               // Fix for older IEs (8-10 and QM) is placed inside selection.js.\r
+               if ( CKEDITOR.env.webkit || ( CKEDITOR.env.ie && CKEDITOR.env.version > 10 ) ) {\r
+                       doc.getDocumentElement().on( 'mousedown', function( evt ) {\r
+                               if ( evt.data.getTarget().is( 'html' ) ) {\r
+                                       // IE needs this timeout. Webkit does not, but it does not cause problems too.\r
+                                       setTimeout( function() {\r
+                                               editor.editable().focus();\r
+                                       } );\r
+                               }\r
+                       } );\r
+               }\r
+\r
+               // Config props: disableObjectResizing and disableNativeTableHandles handler.\r
+               objectResizeDisabler( editor );\r
+\r
+               // Enable dragging of position:absolute elements in IE.\r
+               try {\r
+                       editor.document.$.execCommand( '2D-position', false, true );\r
+               } catch ( e ) {}\r
+\r
+               if ( CKEDITOR.env.gecko || CKEDITOR.env.ie && editor.document.$.compatMode == 'CSS1Compat' ) {\r
+                       this.attachListener( this, 'keydown', function( evt ) {\r
+                               var keyCode = evt.data.getKeystroke();\r
+\r
+                               // PageUp OR PageDown\r
+                               if ( keyCode == 33 || keyCode == 34 ) {\r
+                                       // PageUp/PageDown scrolling is broken in document\r
+                                       // with standard doctype, manually fix it. (#4736)\r
+                                       if ( CKEDITOR.env.ie ) {\r
+                                               setTimeout( function() {\r
+                                                       editor.getSelection().scrollIntoView();\r
+                                               }, 0 );\r
+                                       }\r
+                                       // Page up/down cause editor selection to leak\r
+                                       // outside of editable thus we try to intercept\r
+                                       // the behavior, while it affects only happen\r
+                                       // when editor contents are not overflowed. (#7955)\r
+                                       else if ( editor.window.$.innerHeight > this.$.offsetHeight ) {\r
+                                               var range = editor.createRange();\r
+                                               range[ keyCode == 33 ? 'moveToElementEditStart' : 'moveToElementEditEnd' ]( this );\r
+                                               range.select();\r
+                                               evt.data.preventDefault();\r
+                                       }\r
+                               }\r
+                       } );\r
+               }\r
+\r
+               if ( CKEDITOR.env.ie ) {\r
+                       // [IE] Iframe will still keep the selection when blurred, if\r
+                       // focus is moved onto a non-editing host, e.g. link or button, but\r
+                       // it becomes a problem for the object type selection, since the resizer\r
+                       // handler attached on it will mark other part of the UI, especially\r
+                       // for the dialog. (#8157)\r
+                       // [IE<8 & Opera] Even worse For old IEs, the cursor will not vanish even if\r
+                       // the selection has been moved to another text input in some cases. (#4716)\r
+                       //\r
+                       // Now the range restore is disabled, so we simply force IE to clean\r
+                       // up the selection before blur.\r
+                       this.attachListener( doc, 'blur', function() {\r
+                               // Error proof when the editor is not visible. (#6375)\r
+                               try {\r
+                                       doc.$.selection.empty();\r
+                               } catch ( er ) {}\r
+                       } );\r
+               }\r
+\r
+               if ( CKEDITOR.env.iOS ) {\r
+                       // [iOS] If touch is bound to any parent of the iframe blur happens on any touch\r
+                       // event and body becomes the focused element (#10714).\r
+                       this.attachListener( doc, 'touchend', function() {\r
+                               win.focus();\r
+                       } );\r
+               }\r
+\r
+               var title = editor.document.getElementsByTag( 'title' ).getItem( 0 );\r
+               // document.title is malfunctioning on Chrome, so get value from the element (#12402).\r
+               title.data( 'cke-title', title.getText() );\r
+\r
+               // [IE] JAWS will not recognize the aria label we used on the iframe\r
+               // unless the frame window title string is used as the voice label,\r
+               // backup the original one and restore it on output.\r
+               if ( CKEDITOR.env.ie )\r
+                       editor.document.$.title = this._.docTitle;\r
+\r
+               CKEDITOR.tools.setTimeout( function() {\r
+                       // Editable is ready after first setData.\r
+                       if ( this.status == 'unloaded' )\r
+                               this.status = 'ready';\r
+\r
+                       editor.fire( 'contentDom' );\r
+\r
+                       if ( this._.isPendingFocus ) {\r
+                               editor.focus();\r
+                               this._.isPendingFocus = false;\r
+                       }\r
+\r
+                       setTimeout( function() {\r
+                               editor.fire( 'dataReady' );\r
+                       }, 0 );\r
+               }, 0, this );\r
+\r
+               function removeSuperfluousElement( tagName ) {\r
+                       var lockRetain = false;\r
+\r
+                       // Superfluous elements appear after keydown\r
+                       // and before keyup, so the procedure is as follows:\r
+                       // 1. On first keydown mark all elements with\r
+                       // a specified tag name as non-superfluous.\r
+                       editable.attachListener( editable, 'keydown', function() {\r
+                               var body = doc.getBody(),\r
+                                       retained = body.getElementsByTag( tagName );\r
+\r
+                               if ( !lockRetain ) {\r
+                                       for ( var i = 0; i < retained.count(); i++ ) {\r
+                                               retained.getItem( i ).setCustomData( 'retain', true );\r
+                                       }\r
+                                       lockRetain = true;\r
+                               }\r
+                       }, null, null, 1 );\r
+\r
+                       // 2. On keyup remove all elements that were not marked\r
+                       // as non-superfluous (which means they must have had appeared in the meantime).\r
+                       // Also we should preserve all temporary elements inserted by editor – otherwise we'd likely\r
+                       // leak fake selection's content into editable due to removing hidden selection container (#14831).\r
+                       editable.attachListener( editable, 'keyup', function() {\r
+                               var elements = doc.getElementsByTag( tagName );\r
+                               if ( lockRetain ) {\r
+                                       if ( elements.count() == 1 && !elements.getItem( 0 ).getCustomData( 'retain' ) &&\r
+                                               !elements.getItem( 0 ).hasAttribute( 'data-cke-temp' ) ) {\r
+                                               elements.getItem( 0 ).remove( 1 );\r
+                                       }\r
+                                       lockRetain = false;\r
+                               }\r
+                       } );\r
+               }\r
+       }\r
+\r
+       framedWysiwyg = CKEDITOR.tools.createClass( {\r
+               $: function() {\r
+                       this.base.apply( this, arguments );\r
+\r
+                       this._.frameLoadedHandler = CKEDITOR.tools.addFunction( function( win ) {\r
+                               // Avoid opening design mode in a frame window thread,\r
+                               // which will cause host page scrolling.(#4397)\r
+                               CKEDITOR.tools.setTimeout( onDomReady, 0, this, win );\r
+                       }, this );\r
+\r
+                       this._.docTitle = this.getWindow().getFrame().getAttribute( 'title' );\r
+               },\r
+\r
+               base: CKEDITOR.editable,\r
+\r
+               proto: {\r
+                       setData: function( data, isSnapshot ) {\r
+                               var editor = this.editor;\r
+\r
+                               if ( isSnapshot ) {\r
+                                       this.setHtml( data );\r
+                                       this.fixInitialSelection();\r
+\r
+                                       // Fire dataReady for the consistency with inline editors\r
+                                       // and because it makes sense. (#10370)\r
+                                       editor.fire( 'dataReady' );\r
+                               }\r
+                               else {\r
+                                       this._.isLoadingData = true;\r
+                                       editor._.dataStore = { id: 1 };\r
+\r
+                                       var config = editor.config,\r
+                                               fullPage = config.fullPage,\r
+                                               docType = config.docType;\r
+\r
+                                       // Build the additional stuff to be included into <head>.\r
+                                       var headExtra = CKEDITOR.tools.buildStyleHtml( iframeCssFixes() ).replace( /<style>/, '<style data-cke-temp="1">' );\r
+\r
+                                       if ( !fullPage )\r
+                                               headExtra += CKEDITOR.tools.buildStyleHtml( editor.config.contentsCss );\r
+\r
+                                       var baseTag = config.baseHref ? '<base href="' + config.baseHref + '" data-cke-temp="1" />' : '';\r
+\r
+                                       if ( fullPage ) {\r
+                                               // Search and sweep out the doctype declaration.\r
+                                               data = data.replace( /<!DOCTYPE[^>]*>/i, function( match ) {\r
+                                                       editor.docType = docType = match;\r
+                                                       return '';\r
+                                               } ).replace( /<\?xml\s[^\?]*\?>/i, function( match ) {\r
+                                                       editor.xmlDeclaration = match;\r
+                                                       return '';\r
+                                               } );\r
+                                       }\r
+\r
+                                       // Get the HTML version of the data.\r
+                                       data = editor.dataProcessor.toHtml( data );\r
+\r
+                                       if ( fullPage ) {\r
+                                               // Check if the <body> tag is available.\r
+                                               if ( !( /<body[\s|>]/ ).test( data ) )\r
+                                                       data = '<body>' + data;\r
+\r
+                                               // Check if the <html> tag is available.\r
+                                               if ( !( /<html[\s|>]/ ).test( data ) )\r
+                                                       data = '<html>' + data + '</html>';\r
+\r
+                                               // Check if the <head> tag is available.\r
+                                               if ( !( /<head[\s|>]/ ).test( data ) )\r
+                                                       data = data.replace( /<html[^>]*>/, '$&<head><title></title></head>' );\r
+                                               else if ( !( /<title[\s|>]/ ).test( data ) )\r
+                                                       data = data.replace( /<head[^>]*>/, '$&<title></title>' );\r
+\r
+                                               // The base must be the first tag in the HEAD, e.g. to get relative\r
+                                               // links on styles.\r
+                                               baseTag && ( data = data.replace( /<head[^>]*?>/, '$&' + baseTag ) );\r
+\r
+                                               // Inject the extra stuff into <head>.\r
+                                               // Attention: do not change it before testing it well. (V2)\r
+                                               // This is tricky... if the head ends with <meta ... content type>,\r
+                                               // Firefox will break. But, it works if we place our extra stuff as\r
+                                               // the last elements in the HEAD.\r
+                                               data = data.replace( /<\/head\s*>/, headExtra + '$&' );\r
+\r
+                                               // Add the DOCTYPE back to it.\r
+                                               data = docType + data;\r
+                                       } else {\r
+                                               data = config.docType +\r
+                                                       '<html dir="' + config.contentsLangDirection + '"' +\r
+                                                               ' lang="' + ( config.contentsLanguage || editor.langCode ) + '">' +\r
+                                                       '<head>' +\r
+                                                               '<title>' + this._.docTitle + '</title>' +\r
+                                                               baseTag +\r
+                                                               headExtra +\r
+                                                       '</head>' +\r
+                                                       '<body' + ( config.bodyId ? ' id="' + config.bodyId + '"' : '' ) +\r
+                                                               ( config.bodyClass ? ' class="' + config.bodyClass + '"' : '' ) +\r
+                                                       '>' +\r
+                                                               data +\r
+                                                       '</body>' +\r
+                                                       '</html>';\r
+                                       }\r
+\r
+                                       if ( CKEDITOR.env.gecko ) {\r
+                                               // Hack to make Fx put cursor at the start of doc on fresh focus.\r
+                                               data = data.replace( /<body/, '<body contenteditable="true" ' );\r
+\r
+                                               // Another hack which is used by onDomReady to remove a leading\r
+                                               // <br> which is inserted by Firefox 3.6 when document.write is called.\r
+                                               // This additional <br> is present because of contenteditable="true"\r
+                                               if ( CKEDITOR.env.version < 20000 )\r
+                                                       data = data.replace( /<body[^>]*>/, '$&<!-- cke-content-start -->'  );\r
+                                       }\r
+\r
+                                       // The script that launches the bootstrap logic on 'domReady', so the document\r
+                                       // is fully editable even before the editing iframe is fully loaded (#4455).\r
+                                       var bootstrapCode =\r
+                                               '<script id="cke_actscrpt" type="text/javascript"' + ( CKEDITOR.env.ie ? ' defer="defer" ' : '' ) + '>' +\r
+                                                       'var wasLoaded=0;' +    // It must be always set to 0 as it remains as a window property.\r
+                                                       'function onload(){' +\r
+                                                               'if(!wasLoaded)' +      // FF3.6 calls onload twice when editor.setData. Stop that.\r
+                                                                       'window.parent.CKEDITOR.tools.callFunction(' + this._.frameLoadedHandler + ',window);' +\r
+                                                               'wasLoaded=1;' +\r
+                                                       '}' +\r
+                                                       ( CKEDITOR.env.ie ? 'onload();' : 'document.addEventListener("DOMContentLoaded", onload, false );' ) +\r
+                                               '</script>';\r
+\r
+                                       // For IE<9 add support for HTML5's elements.\r
+                                       // Note: this code must not be deferred.\r
+                                       if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 ) {\r
+                                               bootstrapCode +=\r
+                                                       '<script id="cke_shimscrpt">' +\r
+                                                               'window.parent.CKEDITOR.tools.enableHtml5Elements(document)' +\r
+                                                       '</script>';\r
+                                       }\r
+\r
+                                       // IE<10 needs this hack to properly enable <base href="...">.\r
+                                       // See: http://stackoverflow.com/a/13373180/1485219 (#11910).\r
+                                       if ( baseTag && CKEDITOR.env.ie && CKEDITOR.env.version < 10 ) {\r
+                                               bootstrapCode +=\r
+                                                       '<script id="cke_basetagscrpt">' +\r
+                                                               'var baseTag = document.querySelector( "base" );' +\r
+                                                               'baseTag.href = baseTag.href;' +\r
+                                                       '</script>';\r
+                                       }\r
+\r
+                                       data = data.replace( /(?=\s*<\/(:?head)>)/, bootstrapCode );\r
+\r
+                                       // Current DOM will be deconstructed by document.write, cleanup required.\r
+                                       this.clearCustomData();\r
+                                       this.clearListeners();\r
+\r
+                                       editor.fire( 'contentDomUnload' );\r
+\r
+                                       var doc = this.getDocument();\r
+\r
+                                       // Work around Firefox bug - error prune when called from XUL (#320),\r
+                                       // defer it thanks to the async nature of this method.\r
+                                       try {\r
+                                               doc.write( data );\r
+                                       } catch ( e ) {\r
+                                               setTimeout( function() {\r
+                                                       doc.write( data );\r
+                                               }, 0 );\r
+                                       }\r
+                               }\r
+                       },\r
+\r
+                       getData: function( isSnapshot ) {\r
+                               if ( isSnapshot )\r
+                                       return this.getHtml();\r
+                               else {\r
+                                       var editor = this.editor,\r
+                                               config = editor.config,\r
+                                               fullPage = config.fullPage,\r
+                                               docType = fullPage && editor.docType,\r
+                                               xmlDeclaration = fullPage && editor.xmlDeclaration,\r
+                                               doc = this.getDocument();\r
+\r
+                                       var data = fullPage ? doc.getDocumentElement().getOuterHtml() : doc.getBody().getHtml();\r
+\r
+                                       // BR at the end of document is bogus node for Mozilla. (#5293).\r
+                                       // Prevent BRs from disappearing from the end of the content\r
+                                       // while enterMode is ENTER_BR (#10146).\r
+                                       if ( CKEDITOR.env.gecko && config.enterMode != CKEDITOR.ENTER_BR )\r
+                                               data = data.replace( /<br>(?=\s*(:?$|<\/body>))/, '' );\r
+\r
+                                       data = editor.dataProcessor.toDataFormat( data );\r
+\r
+                                       if ( xmlDeclaration )\r
+                                               data = xmlDeclaration + '\n' + data;\r
+                                       if ( docType )\r
+                                               data = docType + '\n' + data;\r
+\r
+                                       return data;\r
+                               }\r
+                       },\r
+\r
+                       focus: function() {\r
+                               if ( this._.isLoadingData )\r
+                                       this._.isPendingFocus = true;\r
+                               else\r
+                                       framedWysiwyg.baseProto.focus.call( this );\r
+                       },\r
+\r
+                       detach: function() {\r
+                               var editor = this.editor,\r
+                                       doc = editor.document,\r
+                                       iframe,\r
+                                       onResize;\r
+\r
+                               // Trying to access window's frameElement property on Edge throws an exception\r
+                               // when frame was already removed from DOM. (#13850, #13790)\r
+                               try {\r
+                                       iframe =  editor.window.getFrame();\r
+                               } catch ( e ) {}\r
+\r
+                               framedWysiwyg.baseProto.detach.call( this );\r
+\r
+                               // Memory leak proof.\r
+                               this.clearCustomData();\r
+                               doc.getDocumentElement().clearCustomData();\r
+                               CKEDITOR.tools.removeFunction( this._.frameLoadedHandler );\r
+\r
+                               // On IE, iframe is returned even after remove() method is called on it.\r
+                               // Checking if parent is present fixes this issue. (#13850)\r
+                               if ( iframe && iframe.getParent() ) {\r
+                                       iframe.clearCustomData();\r
+                                       onResize = iframe.removeCustomData( 'onResize' );\r
+                                       onResize && onResize.removeListener();\r
+\r
+                                       // IE BUG: When destroying editor DOM with the selection remains inside\r
+                                       // editing area would break IE7/8's selection system, we have to put the editing\r
+                                       // iframe offline first. (#3812 and #5441)\r
+                                       iframe.remove();\r
+                               } else {\r
+                                       CKEDITOR.warn( 'editor-destroy-iframe' );\r
+                               }\r
+                       }\r
+               }\r
+       } );\r
+\r
+       function objectResizeDisabler( editor ) {\r
+               if ( CKEDITOR.env.gecko ) {\r
+                       // FF allows to change resizing preferences by calling execCommand.\r
+                       try {\r
+                               var doc = editor.document.$;\r
+                               doc.execCommand( 'enableObjectResizing', false, !editor.config.disableObjectResizing );\r
+                               doc.execCommand( 'enableInlineTableEditing', false, !editor.config.disableNativeTableHandles );\r
+                       } catch ( e ) {}\r
+               } else if ( CKEDITOR.env.ie && CKEDITOR.env.version < 11 && editor.config.disableObjectResizing ) {\r
+                       // It's possible to prevent resizing up to IE10.\r
+                       blockResizeStart( editor );\r
+               }\r
+\r
+               // Disables resizing by preventing default action on resizestart event.\r
+               function blockResizeStart() {\r
+                       var lastListeningElement;\r
+\r
+                       // We'll attach only one listener at a time, instead of adding it to every img, input, hr etc.\r
+                       // Listener will be attached upon selectionChange, we'll also check if there was any element that\r
+                       // got listener before (lastListeningElement) - if so we need to remove previous listener.\r
+                       editor.editable().attachListener( editor, 'selectionChange', function() {\r
+                               var selectedElement = editor.getSelection().getSelectedElement();\r
+\r
+                               if ( selectedElement ) {\r
+                                       if ( lastListeningElement ) {\r
+                                               lastListeningElement.detachEvent( 'onresizestart', resizeStartListener );\r
+                                               lastListeningElement = null;\r
+                                       }\r
+\r
+                                       // IE requires using attachEvent, because it does not work using W3C compilant addEventListener,\r
+                                       // tested with IE10.\r
+                                       selectedElement.$.attachEvent( 'onresizestart', resizeStartListener );\r
+                                       lastListeningElement = selectedElement.$;\r
+                               }\r
+                       } );\r
+               }\r
+\r
+               function resizeStartListener( evt ) {\r
+                       evt.returnValue = false;\r
+               }\r
+       }\r
+\r
+       function iframeCssFixes() {\r
+               var css = [];\r
+\r
+               // IE>=8 stricts mode doesn't have 'contentEditable' in effect\r
+               // on element unless it has layout. (#5562)\r
+               if ( CKEDITOR.document.$.documentMode >= 8 ) {\r
+                       css.push( 'html.CSS1Compat [contenteditable=false]{min-height:0 !important}' );\r
+\r
+                       var selectors = [];\r
+\r
+                       for ( var tag in CKEDITOR.dtd.$removeEmpty )\r
+                               selectors.push( 'html.CSS1Compat ' + tag + '[contenteditable=false]' );\r
+\r
+                       css.push( selectors.join( ',' ) + '{display:inline-block}' );\r
+               }\r
+               // Set the HTML style to 100% to have the text cursor in affect (#6341)\r
+               else if ( CKEDITOR.env.gecko ) {\r
+                       css.push( 'html{height:100% !important}' );\r
+                       css.push( 'img:-moz-broken{-moz-force-broken-image-icon:1;min-width:24px;min-height:24px}' );\r
+               }\r
+\r
+               // #6341: The text cursor must be set on the editor area.\r
+               // #6632: Avoid having "text" shape of cursor in IE7 scrollbars.\r
+               css.push( 'html{cursor:text;*cursor:auto}' );\r
+\r
+               // Use correct cursor for these elements\r
+               css.push( 'img,input,textarea{cursor:default}' );\r
+\r
+               return css.join( '\n' );\r
+       }\r
+} )();\r
+\r
+/**\r
+ * Disables the ability to resize objects (images and tables) in the editing area.\r
+ *\r
+ *             config.disableObjectResizing = true;\r
+ *\r
+ * **Note:** Because of incomplete implementation of editing features in browsers\r
+ * this option does not work for inline editors (see ticket [#10197](http://dev.ckeditor.com/ticket/10197)),\r
+ * does not work in Internet Explorer 11+ (see [#9317](http://dev.ckeditor.com/ticket/9317#comment:16) and\r
+ * [IE11+ issue](https://connect.microsoft.com/IE/feedback/details/742593/please-respect-execcommand-enableobjectresizing-in-contenteditable-elements)).\r
+ * In Internet Explorer 8-10 this option only blocks resizing, but it is unable to hide the resize handles.\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.disableObjectResizing = false;\r
+\r
+/**\r
+ * Disables the "table tools" offered natively by the browser (currently\r
+ * Firefox only) to perform quick table editing operations, like adding or\r
+ * deleting rows and columns.\r
+ *\r
+ *             config.disableNativeTableHandles = false;\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.disableNativeTableHandles = true;\r
+\r
+/**\r
+ * Disables the built-in spell checker if the browser provides one.\r
+ *\r
+ * **Note:** Although word suggestions provided natively by the browsers will\r
+ * not appear in CKEditor's default context menu,\r
+ * users can always reach the native context menu by holding the\r
+ * *Ctrl* key when right-clicking if {@link #browserContextMenuOnCtrl}\r
+ * is enabled or you are simply not using the\r
+ * [context menu](http://ckeditor.com/addon/contextmenu) plugin.\r
+ *\r
+ *             config.disableNativeSpellChecker = false;\r
+ *\r
+ * @cfg\r
+ * @member CKEDITOR.config\r
+ */\r
+CKEDITOR.config.disableNativeSpellChecker = true;\r
+\r
+/**\r
+ * Language code of  the writing language which is used to author the editor\r
+ * content. This option accepts one single entry value in the format defined in the\r
+ * [Tags for Identifying Languages (BCP47)](http://www.ietf.org/rfc/bcp/bcp47.txt)\r
+ * IETF document and is used in the `lang` attribute.\r
+ *\r
+ *             config.contentsLanguage = 'fr';\r
+ *\r
+ * @cfg {String} [contentsLanguage=same value with editor's UI language]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * The base href URL used to resolve relative and absolute URLs in the\r
+ * editor content.\r
+ *\r
+ *             config.baseHref = 'http://www.example.com/path/';\r
+ *\r
+ * @cfg {String} [baseHref='']\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Whether to automatically create wrapping blocks around inline content inside the document body.\r
+ * This helps to ensure the integrity of the block *Enter* mode.\r
+ *\r
+ * **Note:** This option is deprecated. Changing the default value might introduce unpredictable usability issues and is\r
+ * highly unrecommended.\r
+ *\r
+ *             config.autoParagraph = false;\r
+ *\r
+ * @deprecated\r
+ * @since 3.6\r
+ * @cfg {Boolean} [autoParagraph=true]\r
+ * @member CKEDITOR.config\r
+ */\r
+\r
+/**\r
+ * Fired when some elements are added to the document.\r
+ *\r
+ * @event ariaWidget\r
+ * @member CKEDITOR.editor\r
+ * @param {CKEDITOR.editor} editor This editor instance.\r
+ * @param {CKEDITOR.dom.element} data The element being added.\r
+ */\r
diff --git a/sources/plugins/wysiwygarea/samples/fullpage.html b/sources/plugins/wysiwygarea/samples/fullpage.html
new file mode 100644 (file)
index 0000000..bb3193a
--- /dev/null
@@ -0,0 +1,80 @@
+<!DOCTYPE html>\r
+<!--\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+-->\r
+<html>\r
+<head>\r
+       <meta charset="utf-8">\r
+       <title>Full Page Editing &mdash; CKEditor Sample</title>\r
+       <script src="../../../ckeditor.js"></script>\r
+       <script src="../../../samples/old/sample.js"></script>\r
+       <link rel="stylesheet" href="../../../samples/old/sample.css">\r
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">\r
+       <meta name="ckeditor-sample-name" content="Full page support">\r
+       <meta name="ckeditor-sample-group" content="Plugins">\r
+       <meta name="ckeditor-sample-description" content="CKEditor inserted with a JavaScript call and used to edit the whole page from &lt;html&gt; to &lt;/html&gt;.">\r
+</head>\r
+<body>\r
+       <h1 class="samples">\r
+               <a href="../../../samples/old/index.html">CKEditor Samples</a> &raquo; Full Page Editing\r
+       </h1>\r
+       <div class="warning deprecated">\r
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/fullpage.html">brand new version in CKEditor SDK</a>.\r
+       </div>\r
+       <div class="description">\r
+               <p>\r
+                       This sample shows how to configure CKEditor to edit entire HTML pages, from the\r
+                       <code>&lt;html&gt;</code> tag to the <code>&lt;/html&gt;</code> tag.\r
+               </p>\r
+               <p>\r
+                       The CKEditor instance below is inserted with a JavaScript call using the following code:\r
+               </p>\r
+<pre class="samples">\r
+CKEDITOR.replace( '<em>textarea_id</em>', {\r
+       <strong>fullPage: true</strong>,\r
+       <strong>allowedContent: true</strong>\r
+});\r
+</pre>\r
+               <p>\r
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of\r
+                       the <code>&lt;textarea&gt;</code> element to be replaced.\r
+               </p>\r
+               <p>\r
+                       The <code><em>allowedContent</em></code> in the code above is set to <code>true</code> to disable content filtering.\r
+                       Setting this option is not obligatory, but in full page mode there is a strong chance that one may want be able to freely enter any HTML content in source mode without any limitations.\r
+               </p>\r
+       </div>\r
+       <form action="../../../samples/sample_posteddata.php" method="post">\r
+               <label for="editor1">\r
+                       CKEditor output the entire page including content outside of\r
+                       <code>&lt;body&gt;</code> element, so content like meta and title can be changed:\r
+               </label>\r
+               <textarea cols="80" id="editor1" name="editor1" rows="10">\r
+                       &lt;h1&gt;&lt;img align=&quot;right&quot; alt=&quot;Saturn V carrying Apollo 11&quot; src=&quot;../../../samples/old/assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;\r
+               </textarea>\r
+               <script>\r
+\r
+                       CKEDITOR.replace( 'editor1', {\r
+                               fullPage: true,\r
+                               allowedContent: true,\r
+                               extraPlugins: 'wysiwygarea'\r
+                       });\r
+\r
+               </script>\r
+               <p>\r
+                       <input type="submit" value="Submit">\r
+               </p>\r
+       </form>\r
+       <div id="footer">\r
+               <hr>\r
+               <p>\r
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>\r
+               </p>\r
+               <p id="copy">\r
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico\r
+                       Knabben. All rights reserved.\r
+               </p>\r
+       </div>\r
+</body>\r
+</html>\r
diff --git a/sources/samples/css/samples.css b/sources/samples/css/samples.css
new file mode 100644 (file)
index 0000000..455b152
--- /dev/null
@@ -0,0 +1,1632 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+@media (max-width: 900px) {
+  .global-is-mobile-hidden {
+    display: none !important;
+  }
+}
+article,
+aside,
+details,
+figcaption,
+figure,
+footer,
+header,
+hgroup,
+main,
+menu,
+nav,
+section {
+  display: block;
+}
+body,
+html {
+  margin: 0;
+  padding: 0;
+  font: 16px / 1.8 Arial, 'Helvetica Neue', Helvetica, sans-serif;
+  font-weight: 300;
+  color: #575757;
+}
+.grid-width-10 {
+  width: 10%;
+}
+.grid-width-20 {
+  width: 20%;
+}
+.grid-width-30 {
+  width: 30%;
+}
+.grid-width-40 {
+  width: 40%;
+}
+.grid-width-50 {
+  width: 50%;
+}
+.grid-width-60 {
+  width: 60%;
+}
+.grid-width-70 {
+  width: 70%;
+}
+.grid-width-80 {
+  width: 80%;
+}
+.grid-width-90 {
+  width: 90%;
+}
+.grid-width-100 {
+  width: 100%;
+}
+@media (max-width: 900px) {
+  .grid-width-10,
+  .grid-width-20,
+  .grid-width-30,
+  .grid-width-40,
+  .grid-width-50,
+  .grid-width-60,
+  .grid-width-70,
+  .grid-width-80,
+  .grid-width-90,
+  .grid-width-100 {
+    width: 100%;
+  }
+}
+*[class*="grid-width"] {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  padding-left: 4%;
+  padding-right: 4%;
+  float: left;
+}
+*[class*="grid-width"]:after,
+.grid-container:after,
+*[class*="grid-width"]:before,
+.grid-container:before {
+  content: '';
+  display: block;
+  overflow: hidden;
+  visibility: hidden;
+  font-size: 0;
+  line-height: 0;
+  width: 0;
+  height: 0;
+}
+*[class*="grid-width"]:after,
+.grid-container:after {
+  clear: both;
+}
+.grid-container {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  margin-left: auto;
+  margin-right: auto;
+}
+.grid-container-nested *[class*="grid-width"]:first-child {
+  padding-left: 0;
+}
+.grid-container-nested *[class*="grid-width"]:last-child {
+  padding-right: 0;
+}
+@media (max-width: 900px) {
+  .grid-container-nested *[class*="grid-width"]:first-child {
+    padding-left: 4%;
+  }
+  .grid-container-nested *[class*="grid-width"]:last-child {
+    padding-right: 4%;
+  }
+}
+.header-a {
+  min-height: 140px;
+  overflow: hidden;
+}
+.header-a .header-a-logo {
+  margin: 40px 0 0;
+}
+@media (max-width: 900px) {
+  .header-a .header-a-logo {
+    text-align: center;
+  }
+}
+.header-a .header-a-logo img {
+  border: transparent;
+}
+.navigation-a {
+  height: 30px;
+  background: #3D3D3D;
+  position: absolute;
+  left: 0;
+  right: 0;
+  top: 0;
+  padding: 0;
+  overflow: hidden;
+}
+@media (max-width: 900px) {
+  .navigation-a {
+    text-align: center;
+  }
+}
+.navigation-a ul {
+  list-style: none;
+  margin: 0;
+  overflow: hidden;
+}
+.navigation-a ul li,
+.navigation-a ul li a {
+  display: inline-block;
+}
+@media (max-width: 900px) {
+  .navigation-a ul {
+    width: auto;
+    text-overflow: ellipsis;
+    white-space: nowrap;
+    display: inline-block;
+    float: none;
+  }
+  .navigation-a ul:before,
+  .navigation-a ul:after {
+    display: none;
+  }
+}
+.navigation-a ul.navigation-a-left {
+  text-align: left;
+}
+@media (max-width: 900px) {
+  .navigation-a ul.navigation-a-left {
+    padding-right: 0;
+  }
+}
+.navigation-a ul.navigation-a-right {
+  text-align: right;
+}
+@media (max-width: 900px) {
+  .navigation-a ul.navigation-a-right {
+    padding-left: 23px;
+  }
+}
+.navigation-a ul li + li {
+  margin-left: 23px;
+}
+.navigation-a ul li a {
+  font-size: 10px;
+  font-size: 0.625rem;
+  line-height: 18px;
+  line-height: 1.13rem;
+  line-height: 30px;
+  float: left;
+  color: #ddd;
+  font-weight: bold;
+  text-decoration: none;
+  text-transform: uppercase;
+}
+.navigation-a ul li a:hover {
+  cursor: pointer;
+  color: #fff;
+}
+.icon-navigation-a-github:before,
+.icon-navigation-a-github:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABMAAAATCAYAAAByUDbMAAAAAXNSR0IArs4c6QAAAa9JREFUOBGNlM8rRGEUht0pDGosjKYZpUSIkuwsiCaxUEqK2VOUBcrWv2BjxUJho6wsLLDzY2fhD5iR5NeOcJvIjOfM3O927m3mmlPPnPec835nZprvjlVVJvL5fCOjMWiDCLzCLVxZlpUj/x8saYV9+IZS8UJzFWoCt2GYgk+oJG4wJUouZDANv5VsUZ47dNSzkEYHfIDEHixDWgoiB/rTHlPPwBNInPmXHRb7hdeUDFG10AN1Th1Fd5mD6BMwMVnoUyVA3t3EkjkQlDFfmwPkc7NsQTXf0bGgJWaGb16dk18+EmLYawzkC+6Q3KdK4kiZqtGdskx/kmdlCJS86RuGrDLFZJmtGi1KB0q+VhOGsDLZsiyjGsOY4qoOkrO+YUauwCDoOKWo9xk9JfM+MPdSzqZdA8UlyDO3AvKLPsIG9LsmBHUKduEHdCy6PrpJZyKXdwKMOemaissOHJ9O9xTeh57GluMYIsehWy8STW/d8ZhkI0b9PjFasA1fsAOb0KCN1PLXYyKLGNdzj2YYArnZDyDRrA3Ua4UuDzd5QM/KaoxhmAO5Om5Qt8OI2/CJP6MVa1dvltQ5AAAAAElFTkSuQmCC");
+}
+.navigation-b {
+  text-align: right;
+  margin: 52px 0 0;
+  overflow: visible;
+}
+@media (max-width: 900px) {
+  .navigation-b {
+    text-align: center;
+    margin-top: 20px;
+    padding: 0;
+  }
+}
+.navigation-b ul {
+  padding: 0;
+  list-style: none;
+  margin: 0;
+  overflow: visible;
+}
+.navigation-b ul li,
+.navigation-b ul li a {
+  display: inline-block;
+}
+@media (max-width: 900px) {
+  .navigation-b ul {
+    display: table;
+    width: 100%;
+    padding-bottom: 1.5em;
+  }
+}
+@media (max-width: 900px) {
+  .navigation-b ul li {
+    display: table-row;
+  }
+}
+.navigation-b ul li + li {
+  margin-left: 20px;
+}
+@media (max-width: 900px) {
+  .navigation-b ul li + li {
+    margin-left: 0;
+  }
+}
+.navigation-b ul li a {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  text-transform: uppercase;
+  text-decoration: none;
+  outline: none;
+}
+@media (max-width: 900px) {
+  .navigation-b ul li a {
+    width: 100%;
+    -webkit-border-radius: 0;
+    -webkit-background-clip: padding-box;
+    -moz-border-radius: 0;
+    -moz-background-clip: padding;
+    border-radius: 0;
+    background-clip: padding-box;
+  }
+}
+.footer-a {
+  font-size: 13px;
+  font-size: 0.8125rem;
+  line-height: 23.4px;
+  line-height: 1.46rem;
+  padding-top: 2.25em;
+  padding-bottom: 2.25em;
+  overflow: hidden;
+  color: #8a8a8a;
+}
+.footer-a a {
+  color: #27C0D8;
+  text-decoration: none;
+  border-bottom: 1px dotted #27C0D8;
+}
+.footer-a a:hover {
+  color: #23adc2;
+}
+.footer-a p {
+  margin: 0;
+  display: inline-block;
+  text-align: center;
+}
+.content {
+  font-size: 14px;
+  font-size: 0.875rem;
+  line-height: 25.2px;
+  line-height: 1.57rem;
+  overflow: hidden;
+  padding-top: 1.5em;
+  padding-bottom: 1.5em;
+}
+.content p {
+  margin: 0.75em 0;
+}
+.content ul,
+.content ol,
+.content pre,
+.content blockquote,
+.content textarea:not([class^="cke"]),
+.content .cke {
+  margin: 1.875em 0;
+}
+.content code,
+.content kbd {
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  padding: 3px 4px;
+}
+.content pre,
+.content code,
+.content kbd,
+.content blockquote {
+  background: #f5f5f5;
+}
+.content blockquote,
+.content pre {
+  background: none;
+  border-left: 4px solid #27C0D8;
+  padding: 1.5em 2.25em;
+}
+.content p a,
+.content ul a,
+.content ol a,
+.content blockquote a,
+.content h1 a,
+.content h2 a,
+.content h3 a,
+.content h4 a,
+.content h5 a {
+  color: #27C0D8;
+  text-decoration: none;
+  border-bottom: 1px dotted #27C0D8;
+}
+.content p a:hover,
+.content ul a:hover,
+.content ol a:hover,
+.content blockquote a:hover,
+.content h1 a:hover,
+.content h2 a:hover,
+.content h3 a:hover,
+.content h4 a:hover,
+.content h5 a:hover {
+  color: #23adc2;
+}
+.content h1,
+.content h2,
+.content h3,
+.content h4,
+.content h5 {
+  color: #000;
+  font-weight: 100;
+}
+.content h1 code,
+.content h2 code,
+.content h3 code,
+.content h4 code,
+.content h5 code,
+.content h1 kbd,
+.content h2 kbd,
+.content h3 kbd,
+.content h4 kbd,
+.content h5 kbd {
+  font-size: inherit;
+}
+.content h1 a.content-heading-anchor,
+.content h2 a.content-heading-anchor,
+.content h3 a.content-heading-anchor,
+.content h4 a.content-heading-anchor,
+.content h5 a.content-heading-anchor {
+  font-weight: 100;
+  vertical-align: middle;
+  opacity: 0;
+  border: 0;
+}
+.content h1:hover a.content-heading-anchor,
+.content h2:hover a.content-heading-anchor,
+.content h3:hover a.content-heading-anchor,
+.content h4:hover a.content-heading-anchor,
+.content h5:hover a.content-heading-anchor {
+  opacity: 1;
+}
+.content h1:target a,
+.content h2:target a,
+.content h3:target a,
+.content h4:target a,
+.content h5:target a {
+  -webkit-animation: targetLinkOpacity 0.5s linear alternate;
+  -moz-animation: targetLinkOpacity 0.5s linear alternate;
+  -o-animation: targetLinkOpacity 0.5s linear alternate;
+  animation: targetLinkOpacity 0.5s linear alternate;
+  opacity: 1;
+}
+.content input,
+.content select,
+.content textarea:not([class^="cke"]) {
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08);
+  font: inherit;
+  color: inherit;
+  border: 1px solid #D9D9D9;
+  padding: .2em .5em;
+}
+.content input:focus,
+.content select:focus,
+.content textarea:not([class^="cke"]):focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.08), 0 0 8px #93c6ef;
+}
+.content abbr {
+  border-bottom: 1px dotted #666;
+  cursor: pointer;
+}
+.content blockquote {
+  font-style: italic;
+  font-family: Georgia, Times, "Times New Roman", serif;
+  font-size: 16px;
+  font-size: 1rem;
+  line-height: 28.8px;
+  line-height: 1.8rem;
+}
+.content em {
+  font-style: italic;
+}
+.content h1 {
+  font-size: 36px;
+  font-size: 2.25rem;
+  line-height: 64.8px;
+  line-height: 4.05rem;
+  margin: 1.125em 0 0;
+}
+.content h2 {
+  font-size: 27.2px;
+  font-size: 1.7rem;
+  line-height: 48.96px;
+  line-height: 3.06rem;
+  margin: 0.9em 0 0;
+}
+.content h3 {
+  font-size: 24px;
+  font-size: 1.5rem;
+  line-height: 43.2px;
+  line-height: 2.7rem;
+  font-weight: 500;
+  margin: 0.75em 0 0;
+}
+.content h4 {
+  font-size: 19.2px;
+  font-size: 1.2rem;
+  line-height: 34.56px;
+  line-height: 2.16rem;
+  font-weight: 500;
+  margin: 0.75em 0 0;
+}
+.content h5 {
+  font-size: 17.6px;
+  font-size: 1.1rem;
+  line-height: 31.68px;
+  line-height: 1.98rem;
+  font-weight: 500;
+  margin: 0.75em 0 0;
+}
+.content hr {
+  border: 0;
+  border-top: 4px solid #D9D9D9;
+  margin: 1.5em 0;
+}
+.content input[type="text"] {
+  height: 1.8em;
+  line-height: 1.8em;
+}
+.content input[type="button"] {
+  -webkit-appearance: button;
+  -moz-appearance: button;
+  appearance: button;
+}
+.content kbd {
+  font-size: 12px;
+  font-size: 0.75rem;
+  line-height: 21.6px;
+  line-height: 1.35rem;
+  font-family: Arial, 'Helvetica Neue', Helvetica, sans-serif;
+  padding: 2px 6px;
+  -webkit-box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;
+  -moz-box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;
+  box-shadow: 0 0 4px #fff inset, 0 2px 0 #D9D9D9;
+}
+.content p img {
+  vertical-align: middle;
+}
+.content p pre {
+  padding: 1.5em;
+}
+.content pre {
+  padding: 0;
+  border: 0;
+  tab-size: 4;
+  -o-tab-size: 4;
+  -moz-tab-size: 4;
+}
+.content pre,
+.content code {
+  font-size: 11.89px;
+  font-size: 0.743rem;
+  line-height: 21.4px;
+  line-height: 1.34rem;
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+}
+.content pre a,
+.content code a {
+  border: 0;
+}
+.content pre code {
+  padding: 0.75em;
+  display: block;
+}
+.content strong {
+  color: #000;
+}
+.content ul ul,
+.content ol ul,
+.content ul ol,
+.content ol ol {
+  margin: 0.75em 0;
+}
+.content ul li,
+.content ol li {
+  font-size: 14px;
+  font-size: 0.875rem;
+  line-height: 30.24px;
+  line-height: 1.89rem;
+}
+.content textarea:not([class^="cke"]) {
+  width: 100%;
+}
+.content div.todo {
+  border: 2px dotted #444;
+  padding: 10px;
+  margin: 60px 0 10px 0;
+  /* Remove me some day */
+}
+.content div.todo:before {
+  content: "TODO";
+  font-weight: bold;
+}
+body a.button-a,
+body button.button-a,
+body input.button-a {
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  font-size: 14px;
+  font-size: 0.875rem;
+  line-height: 25.2px;
+  line-height: 1.57rem;
+  height: 36px;
+  line-height: 36px;
+  padding: 0 1.1em;
+  font-weight: 700;
+  color: #3e3e3e;
+  white-space: nowrap;
+  text-decoration: none;
+  display: inline-block;
+  cursor: pointer;
+  border: 0;
+  vertical-align: middle;
+  margin: 1px 0;
+  background: transparent;
+}
+body a.button-a.icon-pos-left,
+body button.button-a.icon-pos-left,
+body input.button-a.icon-pos-left {
+  padding-left: .8em;
+}
+body a.button-a.icon-pos-right,
+body button.button-a.icon-pos-right,
+body input.button-a.icon-pos-right {
+  padding-right: .8em;
+}
+body a.button-a.button-a-no-text,
+body button.button-a.button-a-no-text,
+body input.button-a.button-a-no-text {
+  -webkit-border-radius: 100px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 100px;
+  -moz-background-clip: padding;
+  border-radius: 100px;
+  background-clip: padding-box;
+  width: 36px;
+  padding: 0;
+  text-indent: -999px;
+  overflow: hidden;
+  position: relative;
+  text-align: center;
+}
+body a.button-a.button-a-no-text:before,
+body button.button-a.button-a-no-text:before,
+body input.button-a.button-a-no-text:before {
+  position: absolute;
+  left: 50%;
+  top: 50%;
+  margin: -9px 0 0 -9px;
+}
+@media (max-width: 900px) {
+  body a.button-a.button-a-mobile-collapsed,
+  body button.button-a.button-a-mobile-collapsed,
+  body input.button-a.button-a-mobile-collapsed {
+    -webkit-border-radius: 100px;
+    -webkit-background-clip: padding-box;
+    -moz-border-radius: 100px;
+    -moz-background-clip: padding;
+    border-radius: 100px;
+    background-clip: padding-box;
+    width: 36px;
+    padding: 0;
+    text-indent: -999px;
+    overflow: hidden;
+    position: relative;
+    text-align: center;
+  }
+  body a.button-a.button-a-mobile-collapsed:before,
+  body button.button-a.button-a-mobile-collapsed:before,
+  body input.button-a.button-a-mobile-collapsed:before {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    margin: -9px 0 0 -9px;
+  }
+  body a.button-a.button-a-mobile-collapsed:before,
+  body button.button-a.button-a-mobile-collapsed:before,
+  body input.button-a.button-a-mobile-collapsed:before {
+    position: absolute;
+    left: 50%;
+    top: 50%;
+    margin: -9px 0 0 -9px;
+  }
+}
+body a.button-a:active,
+body button.button-a:active,
+body input.button-a:active,
+body a.button-a:hover,
+body button.button-a:hover,
+body input.button-a:hover {
+  color: #fff;
+  background: #23adc2;
+}
+body a.button-a:focus,
+body button.button-a:focus,
+body input.button-a:focus {
+  border-color: #66afe9;
+  outline: 0;
+  -webkit-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;
+  -moz-box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;
+  box-shadow: inset 0 1px 1px rgba(0, 0, 0, 0.075), 0 0 8px #93c6ef;
+}
+body a.button-a-soft,
+body button.button-a-soft,
+body input.button-a-soft {
+  background: #e7e7e7;
+}
+body a.button-a-soft:active,
+body button.button-a-soft:active,
+body input.button-a-soft:active,
+body a.button-a-soft:hover,
+body button.button-a-soft:hover,
+body input.button-a-soft:hover {
+  color: #3e3e3e;
+  background: #cecece;
+}
+body a.button-a-background,
+body button.button-a-background,
+body input.button-a-background,
+body a.navigation-b ul li a:hover,
+body button.navigation-b ul li a:hover,
+body input.navigation-b ul li a:hover {
+  color: #fff;
+  background: #27C0D8;
+}
+body a.button-a-background:active,
+body button.button-a-background:active,
+body input.button-a-background:active,
+body a.button-a-background:hover,
+body button.button-a-background:hover,
+body input.button-a-background:hover,
+body a.navigation-b ul li a:hover:active,
+body button.navigation-b ul li a:hover:active,
+body input.navigation-b ul li a:hover:active,
+body a.navigation-b ul li a:hover:hover,
+body button.navigation-b ul li a:hover:hover,
+body input.navigation-b ul li a:hover:hover {
+  color: #fff;
+  background: #23adc2;
+}
+.balloon-a {
+  font-size: 12px;
+  font-size: 0.75rem;
+  line-height: 21.6px;
+  line-height: 1.35rem;
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  border-bottom: 3px solid #d4d4d4;
+  background: #ebebeb;
+  display: inline-block;
+  white-space: nowrap;
+  padding: .4em 1.2em .2em;
+  font-weight: 700;
+  position: relative;
+  z-index: 1000;
+  text-transform: none;
+  color: #575757;
+}
+.balloon-a:hover {
+  color: #575757;
+}
+.balloon-a:before {
+  content: '';
+  width: 0;
+  height: 0;
+  border-style: solid;
+  position: absolute;
+}
+.balloon-a-ne:before,
+.balloon-a-nw:before {
+  top: -13px;
+  border-width: 0 9px 15.6px 9px;
+  border-color: transparent transparent #ebebeb transparent;
+}
+.balloon-a-se:before,
+.balloon-a-sw:before {
+  bottom: -13px;
+  border-width: 15.6px 9px 0 9px;
+  border-color: #ebebeb transparent transparent transparent;
+}
+.balloon-a-nw:before,
+.balloon-a-sw:before {
+  left: 20px;
+}
+.balloon-a-ne:before,
+.balloon-a-se:before {
+  right: 20px;
+}
+.icon-pos-left:before,
+.icon-pos-right:after {
+  content: '';
+  display: inline-block;
+  width: 18px;
+  height: 18px;
+  vertical-align: middle;
+  background-repeat: no-repeat;
+}
+.icon-pos-left:before {
+  margin-right: 10px;
+}
+.icon-pos-right:after {
+  margin-left: 10px;
+}
+.icon-download:before,
+.icon-download:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAQFJREFUOBGtVDESgjAQBGfobHwE/AIa/AN/8EEWfMWGZ+gDaG2ws8BdyY13SRgGcGducre3WQ5NSJIIxnGsES3ijhhcMCdXR7ZYCqIc0SGWQE1ud7sKjRLxXHJQfWpLYwaCk6wxET/u+U2GIngd8yRViINau28bBH/YAGqvSQPhRNQHqBqj3FY0NKq27TW7qhSTDaCOhkaRAj7Hmm8S4V+c6C+gUa+crsizuWmoc70MKbWCnqPy2GvcUJxE4a/sIajRaGkU+/sf4IuISQGePR/T/QMbHEhwPLVnMWPuOCwGnWg41dwVeaN3ccHch70idIRi/6WV0WC2/zMiZm661R+2DxyEdjTuST3mAAAAAElFTkSuQmCC");
+}
+.icon-question-mark:before,
+.icon-question-mark:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAUhJREFUOBGllLFOAkEQhjk0WthT2JFA7Czsqc7OxFLewEeAZ/AVbO0tTLTSBKhstTBUNkYLEoVAbD2//zILe5e9uwCT/JnZmX/+m83ebq0WsCRJYnANxmBhUKxcHGjJpiC1wQBUmTjtbLetKHTAT5WCVxe3kxEjoUmKRL6pvYEZyJt6VpOxCG3nmfyx+yJxBM7BFPg2SDlkTv2sxZqi4YnUvfgswI9FuHAkzz9EUTTRmqYeTifXsvoj/s9i57oi6ljz9kviFdyBCbgHe+rCn4C8jVXQ18rshuKOiTSIXwLkRZWQTurARJrE7wERpea7kD7BkcgB+yB3CFGlPmgqCNiXhEagSGif2qU1Ln8FW/tupK3pXhXZrWNDuCoikY/rHPMT5KFr2MAPTSM90rIrUjJIeq1WV0RTwN7+0rrtILb9M+LEbLq1H7Z/Ea3+RvBddl0AAAAASUVORK5CYII=");
+}
+.icon-close:before,
+.icon-close:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASCAYAAABWzo5XAAAAAXNSR0IArs4c6QAAAUlJREFUOBGllDFuwzAMRe3Cd+jYKUCzd/XkDtm9dsoVOuUqBnqBoodwgBwiW8ZsXTIWqPu+Iia0LMAoTOBbJEV+UZTkosjIMAwN6MARXCKky9dkUsYuglagB3OimNU4O1pM1OB7jsHNK7YekeFQJZ5kj/0LcnLA+RMnlHOvDMNv5wO7BFuQkn3hq0ALjKwPVeF4BSaqpLRy0T1ZIHFz75bE2BR8dBImqmBrwRplg09QmR/9GZyBSadAHauXCZkRROKURLlHEemepJIlIyhHotzLg1/N6erTxtmmvqA8muHGIbc1rTBqrEuwnqWnGbbmmz0hwaHtvM2QhWbrXZnosvnTWWPrdCY9w7cDJtf3h9VHjy5Zq9UZ08beyJh7Aicg6W/VYvgnIjJdNn9PMIOITJWcgnV9VvcnEitY/mitNFZZ/hsxsljdv39sfybRQ4R/kU0MAAAAAElFTkSuQmCC");
+}
+.ie8 .switch > * {
+  vertical-align: middle;
+}
+.ie8 .switch input[type="radio"] {
+  margin: 0 0.25em;
+  display: inline-block;
+}
+.ie8 .switch label {
+  margin-left: 0 !important;
+  margin-right: 0 !important;
+}
+.ie8 .switch label[data-for="1"] {
+  float: left;
+}
+.ie8 .switch label[data-for="2"] {
+  float: right;
+}
+.ie8 .switch .switch-inner {
+  display: none;
+}
+.switch {
+  font-size: 14px;
+  font-size: 0.875rem;
+  line-height: 25.2px;
+  line-height: 1.57rem;
+  font-weight: bold;
+  background-color: #27C0D8;
+  overflow: hidden;
+  display: inline-block;
+  padding: 0.75em 0.25em;
+  color: #fff;
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  position: relative;
+}
+.switch input[type="radio"] {
+  display: none;
+}
+.switch label {
+  position: relative;
+  z-index: 2;
+  float: left;
+  cursor: pointer;
+  padding: 0 0.75em;
+}
+.switch label:hover {
+  text-decoration: underline;
+}
+.switch .switch-inner {
+  float: left;
+  background-color: #FFF;
+  height: 1.5em;
+  width: 4.125em;
+  padding: 2px;
+  margin: 0 0.25em;
+  -webkit-border-radius: 5.5px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 5.5px;
+  -moz-background-clip: padding;
+  border-radius: 5.5px;
+  background-clip: padding-box;
+}
+.switch .switch-inner .handler {
+  overflow: hidden;
+  position: relative;
+  display: block;
+  height: 1.5em;
+  width: 1.5em;
+  background: #25b4cb;
+  -webkit-border-radius: 4.5px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 4.5px;
+  -moz-background-clip: padding;
+  border-radius: 4.5px;
+  background-clip: padding-box;
+}
+.switch .switch-inner .handler:before {
+  content: '';
+  display: block;
+  position: absolute;
+  top: 0;
+  right: 0;
+  bottom: 3px;
+  left: 0;
+  background-color: #34c4da;
+  -webkit-border-bottom-left-radius: 4.5px;
+  -moz-border-radius-bottomleft: 4.5px;
+  border-bottom-left-radius: 4.5px;
+  -webkit-border-bottom-right-radius: 4.5px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius-bottomright: 4.5px;
+  -moz-background-clip: padding;
+  border-bottom-right-radius: 4.5px;
+  background-clip: padding-box;
+}
+.switch:hover .switch-inner .handler:before {
+  background: #45c9dd;
+}
+.switch input[data-num="2"]:checked ~ .switch-inner > .handler {
+  margin-left: auto;
+}
+.switch input[data-num="2"]:checked ~ label[data-for="1"] {
+  padding-right: 5.125em;
+  margin-right: -4.375em;
+}
+.switch input[data-num="1"]:checked ~ label[data-for="2"] {
+  padding-left: 5.125em;
+  margin-left: -4.375em;
+}
+.toggler {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.toggler label {
+  cursor: pointer;
+}
+.toggler [data-collapse] {
+  display: inherit;
+}
+.toggler [data-expand] {
+  display: none;
+}
+.toggler.collapsed [data-collapse] {
+  display: none;
+}
+.toggler.collapsed [data-expand] {
+  display: inherit;
+}
+.toggler-container {
+  overflow: hidden;
+}
+.toggler-container.collapsed {
+  height: 0;
+}
+.icon-toggler-expanded:before,
+.icon-toggler-collapsed:before,
+.icon-toggler-expanded:after,
+.icon-toggler-collapsed:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAByCAYAAABeOoENAAAAAXNSR0IArs4c6QAAAbxJREFUaAXtmT1KBEEQhRdFQdBEMfQEBoaGopl3MfECXsFERLyBh/AUIuwJDEUQM//eB11Dz1A1uzotGFTBY2rr58306+kNpmazP7Z98V8Kj8JrAT4xcgttXRVXwofwFYAcNdS6RuJegOBTuBUOhc0CfGLkqKHWJeMuFDwJJ0Jk5Kihlp6esW4embuNkVgTNdTS09MMEbkDj76sUUsPvZ2xIwTRATsQuBuxGsTIYdSSo7cztpggwprdyKlJ8ImZUUuM3s48ol1lXwQjwydm5hINl2bF53KMCL82d2mR2GvqnBfg1+aKPbb9p+oGtYXbT1GTFxKiZkfEyHgy7x0y0clR454zSGpDMzaA3fzV30hNln4qkAqkAqlAKpAKpAKpQCqQCqQCqUAqkAqkAqlAKpAKpAKpQCrw3xWY/GGcz++TP9U3Gx40GWdEAxabXA33NBywRCOfdzFcCztDJv12Rz7REMpmIc9qPBNWK0J3COWNxegxIrs+KHZcyHpjsZUSXPaypcLtseJFS3tT84WwUZG4S4vEZkl3wl5FYK4rdrT9R9Y1uIbbT12TFxKiZkfEyCYfWojMJv+NGNGPr99GI9DP7P9TCgAAAABJRU5ErkJggg==");
+}
+.icon-toggler-expanded.icon-light:before,
+.icon-toggler-collapsed.icon-light:before,
+.icon-toggler-expanded.icon-light:after,
+.icon-toggler-collapsed.icon-light:after {
+  background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAByCAYAAABeOoENAAAAAXNSR0IArs4c6QAAAcVJREFUaAXtmT9KA1EQxhMlASE2SkpPkCJlStHOu3gGwRPYBAm5gYfwFBKwtrARRAh26vr7ljfx7TrLChtBcAa+zOSbPy/7vcTC6fV+04qimIArsALrBMXiJq1nUzQEc/AOmkw51QzdgUqAWyD7AEswA6MExeKUk6n2+zBInSJ7BKfuaZDKpRpcMa/UQUgTfWSd1jjEmlSTatXzpRlvJKJsacVtXrVlB72bWgjdiGwmEj8FOq1u4qapRprJVvkgXbFsZCTxomSqL4ssr0uQrY3TJ/AGjeFfVJlM8diaiCuDdlLiIfmNcP1+/wnu0hoVJ84oq7XeUhNXbE4dgPuEgU2Qh3PFbrx+Gs6E2hD/+tMJ3b+QadB2fiLZsG4/2poG3f6M5MMiDgVCgVAgFAgFQoFQIBQIBUKBUCAUCAVCgVAgFAgFQoFQIBQIBf66AiwLuv1jnAH/Zb/Go5abq/qdwvsLFhJNK583ctfg0Bnmrnwq+zVrYoDZM8E52M1yP9uvqcGmZP6O+CTl3LWYHdTm9yk4aCzilLZHe6XmAuzZEGL30ZrEpr64AUc2wDycK7a7X6P42BpzD+9fv4pIxn4tWznnwm0r/gQpiG1tFshTowAAAABJRU5ErkJggg==");
+}
+.icon-toggler-expanded:before,
+.icon-toggler-expanded:after {
+  background-position: top left;
+}
+.icon-toggler-collapsed:before,
+.icon-toggler-collapsed:after {
+  background-position: bottom left;
+}
+.modal {
+  padding: 20px;
+  border-radius: 3px;
+  background-color: white;
+  max-width: 700px;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  width: 80% !important;
+  top: 50% !important;
+  -webkit-transform: translate(-50%, -50%) !important;
+  -moz-transform: translate(-50%, -50%) !important;
+  -o-transform: translate(-50%, -50%) !important;
+  -ms-transform: translate(-50%, -50%) !important;
+  transform: translate(-50%, -50%) !important;
+}
+.modal-close {
+  -webkit-border-radius: 100px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 100px;
+  -moz-background-clip: padding;
+  border-radius: 100px;
+  background-clip: padding-box;
+  cursor: pointer;
+  height: 18px;
+  width: 18px;
+  position: absolute;
+  top: 10px;
+  right: 10px;
+  font-size: 17px;
+  text-align: center;
+  line-height: 19px;
+  background: #cccccc;
+}
+main .grid-container,
+header .grid-container,
+.navigation-a > div,
+footer > div {
+  max-width: 968px;
+}
+.header-a {
+  margin-top: 30px;
+}
+.footer-a {
+  border-top: 1px solid #D9D9D9;
+}
+.adjoined-top {
+  background-color: #27C0D8;
+  color: #fff;
+}
+.adjoined-top .content h1,
+.adjoined-top .content h2,
+.adjoined-top .content h3,
+.adjoined-top .content h4,
+.adjoined-top .content h5 {
+  color: #fff;
+}
+.adjoined-top .content p {
+  font-size: 18px;
+  font-size: 1.125rem;
+  line-height: 32.4px;
+  line-height: 2.02rem;
+  font-weight: 100;
+}
+.adjoined-top .content p a {
+  text-decoration: none;
+  border-bottom: 1px dotted #fff;
+  color: inherit;
+}
+.adjoined-top .content p a:hover {
+  color: #e6e6e6;
+}
+.adjoined-top .content button {
+  color: #fff;
+}
+.adjoined-top .content strong {
+  color: #fff;
+}
+.adjoined-top .content code {
+  font-size: inherit;
+  color: #27C0D8;
+}
+.adjoined-bottom {
+  position: relative;
+}
+.adjoined-bottom:before {
+  z-index: -1;
+  content: '';
+  background: #27C0D8;
+  position: absolute;
+  top: 0;
+  left: 0;
+  right: 0;
+  height: 50%;
+}
+main .grid-container,
+header .grid-container,
+.navigation-a > div,
+footer > div {
+  max-width: 1052px;
+}
+main .grid-container.freed-width {
+  max-width: none;
+}
+.switch {
+  background: #25b4cb;
+  float: right;
+  overflow: visible;
+}
+.switch .balloon-a {
+  position: absolute;
+  top: -40px;
+  right: 50%;
+  margin-right: -15px;
+  background: #FFEFC1;
+  border-bottom-color: #DCDCA4;
+}
+.switch .balloon-a:before {
+  border-color: #FFEFC1 transparent transparent transparent;
+}
+#toolbar .editors-container {
+  overflow: hidden;
+  height: 0;
+  transition: height 200ms;
+}
+#toolbar .editors-container.active {
+  height: auto;
+}
+#main #editor {
+  background: #FFF;
+  padding: 2% 4%;
+  border: dashed 5px #27C0D8;
+}
+#main .adjoined-top:before {
+  height: 335px;
+}
+#toolbar .adjoined-top:before {
+  height: 219px;
+}
+#toolbar .adjoined-top .grid-container-nested {
+  height: 147px;
+}
+.content .grid-switch-magic {
+  margin: 3.5em 0 0;
+}
+#info-box {
+  padding-bottom: 0;
+}
+#info-box > div {
+  width: 100%;
+  text-align: right;
+}
+#info-box > div .toggler {
+  padding-right: 0;
+}
+#info-box > div .toggler:hover {
+  background: transparent;
+  color: #000;
+}
+#info-box > div .toggler:hover > label {
+  text-decoration: underline;
+}
+#info-box > div h2 {
+  float: left;
+  margin-top: 0;
+}
+#info-box > div#instructions-container {
+  text-align: left;
+}
+#toolbarModifierWrapper {
+  overflow: hidden;
+  height: 0;
+  opacity: 0;
+  transition: height 200ms;
+}
+#toolbarModifierWrapper.active {
+  height: auto;
+  opacity: 1;
+}
+header {
+  overflow: visible;
+}
+header div.grid-container {
+  overflow: visible;
+}
+header .navigation-b {
+  overflow: visible;
+}
+header .navigation-b ul {
+  overflow: visible;
+}
+header .navigation-b a {
+  position: relative;
+}
+header .balloon-a {
+  position: absolute;
+  top: 48px;
+  left: 50%;
+  margin-left: -35px;
+}
+@media (max-width: 1140px) {
+  header .balloon-a {
+    left: auto;
+    margin-left: auto;
+    right: 50%;
+    margin-right: -35px;
+  }
+  header .balloon-a:before {
+    left: auto;
+    right: 22px;
+  }
+}
+@media (max-width: 900px) {
+  header .balloon-a {
+    display: none;
+  }
+}
+#toolbar .cke_toolbar {
+  pointer-events: none;
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+  cursor: default;
+}
+.some-toolbar-active .cke_toolbar {
+  zoom: 1;
+  filter: alpha(opacity=50);
+  -webkit-opacity: 0.5;
+  -moz-opacity: 0.5;
+  opacity: 0.5;
+}
+.cke_toolbar.active {
+  position: relative;
+  zoom: 1;
+  filter: alpha(opacity=100);
+  -webkit-opacity: 1;
+  -moz-opacity: 1;
+  opacity: 1;
+}
+.cke_toolbar.active:after {
+  content: '';
+  display: block;
+  position: absolute;
+  top: 0;
+  right: 6px;
+  bottom: 5px;
+  left: 0;
+  -webkit-border-radius: 5px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 5px;
+  -moz-background-clip: padding;
+  border-radius: 5px;
+  background-clip: padding-box;
+  -webkit-box-shadow: 0px 0px 15px 3px #fff4b0;
+  -moz-box-shadow: 0px 0px 15px 3px #fff4b0;
+  box-shadow: 0px 0px 15px 3px #fff4b0;
+}
+.cke_toolbar.active .cke_toolgroup {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+  border-color: #e3c300;
+}
+.cke_toolbar.active .cke_combo,
+.cke_toolbar.active .cke_toolgroup {
+  position: relative;
+  z-index: 2;
+}
+.cke_toolbar.active .cke_combo_button {
+  -webkit-box-shadow: none;
+  -moz-box-shadow: none;
+  box-shadow: none;
+}
+.unselectable {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  -ms-user-select: none;
+  user-select: none;
+}
+.toolbar {
+  padding: 5px 0;
+  margin-bottom: 2.4em;
+  overflow: hidden;
+  background: #fff;
+}
+.toolbar button.button-a.cke_button {
+  cursor: pointer;
+  display: inline-block;
+  padding: 4px 6px;
+  outline: 0;
+  border: 1px solid #a6a6a6;
+}
+.toolbar button.button-a.hidden {
+  display: none;
+}
+.toolbar button.button-a.left {
+  float: left;
+  margin-right: 8px;
+}
+.toolbar button.button-a.right {
+  float: right;
+  margin-left: 8px;
+}
+.toolbar button.button-a .highlight {
+  color: #ffefc1;
+}
+.configContainer.hidden,
+.toolbarModifier.hidden,
+.toolbarModifier-hints.hidden {
+  display: none;
+}
+.toolbarModifier :focus,
+.toolbar button:focus,
+.configContainer textarea.configCode:focus {
+  outline: none;
+}
+div.toolbarModifier {
+  padding: 0;
+  overflow: hidden;
+  width: 100%;
+  position: relative;
+  display: table;
+  border-collapse: collapse;
+}
+div.toolbarModifier ::-moz-focus-inner {
+  border: 0;
+}
+div.toolbarModifier .empty {
+  display: none;
+}
+div.toolbarModifier.empty-visible .empty {
+  display: table-row;
+  zoom: 1;
+  filter: alpha(opacity=60);
+  -webkit-opacity: 0.6;
+  -moz-opacity: 0.6;
+  opacity: 0.6;
+}
+div.toolbarModifier .empty > p {
+  line-height: 31px;
+}
+div.toolbarModifier > ul {
+  padding: 0;
+  margin: 0;
+  border-top: 1px solid #ccc;
+  width: 100%;
+}
+div.toolbarModifier > ul[data-type="table-header"] {
+  display: table-header-group;
+}
+div.toolbarModifier > ul[data-type="table-body"] {
+  display: table-row-group;
+}
+div.toolbarModifier > ul p {
+  padding: 0;
+  margin: 0;
+}
+div.toolbarModifier > ul > li {
+  display: table-row;
+}
+div.toolbarModifier > ul > li[data-type="header"] {
+  font-weight: bold;
+  user-select: none;
+  cursor: default;
+}
+div.toolbarModifier > ul > li[data-type="group"],
+div.toolbarModifier > ul > li[data-type="separator"] {
+  border-bottom: 1px solid #ccc;
+}
+div.toolbarModifier > ul > li[data-type="subgroup"] {
+  border-top: 1px solid #eee;
+}
+div.toolbarModifier > ul > li[data-type="subgroup"]:first-child {
+  border-top: none;
+}
+div.toolbarModifier > ul > li[data-type="group"].active,
+div.toolbarModifier > ul > li[data-type="group"]:hover,
+div.toolbarModifier > ul > li[data-type="separator"].active,
+div.toolbarModifier > ul > li[data-type="separator"]:hover {
+  overflow: hidden;
+  z-index: 2;
+}
+div.toolbarModifier > ul > li[data-type="group"].active,
+div.toolbarModifier > ul > li[data-type="separator"].active,
+div.toolbarModifier > ul > li[data-type="group"].active:hover,
+div.toolbarModifier > ul > li[data-type="separator"].active:hover {
+  background: #f0fafb;
+}
+div.toolbarModifier > ul > li[data-type="group"]:hover,
+div.toolbarModifier > ul > li[data-type="separator"]:hover {
+  background: #fffbe3;
+}
+div.toolbarModifier > ul > li[data-type="separator"] {
+  background: #f5f5f5;
+}
+div.toolbarModifier > ul > li[data-type="separator"]:after {
+  content: '';
+  width: 100%;
+}
+div.toolbarModifier > ul > li[data-type="separator"] > p {
+  padding: 2px 5px;
+}
+div.toolbarModifier > ul > li > p,
+div.toolbarModifier > ul > li > ul {
+  display: table-cell;
+  vertical-align: middle;
+}
+div.toolbarModifier > ul > li p {
+  padding-left: 5px;
+  min-width: 200px;
+}
+div.toolbarModifier > ul > li p span {
+  white-space: nowrap;
+  cursor: default;
+}
+div.toolbarModifier > ul > li p span button {
+  font-size: 12.666px;
+  margin-right: 5px;
+  cursor: pointer;
+  background: #fff;
+  -webkit-border-radius: 5px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 5px;
+  -moz-background-clip: padding;
+  border-radius: 5px;
+  background-clip: padding-box;
+  border: 1px solid #bbb;
+  padding: 0 7px;
+  line-height: 12px;
+  height: 20px;
+}
+div.toolbarModifier > ul > li p span button:not(.disabled):hover,
+div.toolbarModifier > ul > li p span button:not(.disabled):focus {
+  color: #fff;
+  background-color: #454545;
+  border-color: transparent;
+}
+div.toolbarModifier > ul > li p span button.move.disabled {
+  cursor: default;
+  zoom: 1;
+  filter: alpha(opacity=20);
+  -webkit-opacity: 0.2;
+  -moz-opacity: 0.2;
+  opacity: 0.2;
+}
+div.toolbarModifier > ul > li ul {
+  border-collapse: collapse;
+  padding: 0;
+  width: 100%;
+}
+div.toolbarModifier > ul > li ul li {
+  display: table-row;
+  list-style-type: none;
+  line-height: 1;
+}
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] {
+  border-top: 1px solid #ddd;
+}
+div.toolbarModifier > ul > li ul li[data-type="subgroup"]:first-child {
+  border-top: 0;
+}
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"] {
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  padding: 0 2px;
+}
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"]:focus {
+  background: rgba(0, 0, 0, 0.04);
+}
+div.toolbarModifier > ul > li ul li[data-type="subgroup"] [data-type="button"] input {
+  vertical-align: middle;
+}
+div.toolbarModifier > ul > li ul li > p,
+div.toolbarModifier > ul > li ul li > ul {
+  display: table-cell;
+  vertical-align: middle;
+}
+div.toolbarModifier > ul > li ul li ul {
+  padding: 0;
+}
+div.toolbarModifier > ul > li ul li ul li {
+  padding: 0;
+  display: inline-block;
+  cursor: pointer;
+  margin: 2px 5px 2px 0;
+}
+div.toolbarModifier > ul > li ul li ul li .cke_combo_text {
+  cursor: pointer;
+  white-space: nowrap;
+}
+div.toolbarModifier > ul > li ul li ul li .cke_toolgroup,
+div.toolbarModifier > ul > li ul li ul li .cke_combo_button {
+  cursor: pointer;
+  margin: 0;
+  vertical-align: middle;
+  border: 1px solid #ddd;
+  font-size: 11.41px;
+  font-size: 0.713rem;
+  line-height: 20.54px;
+  line-height: 1.28rem;
+}
+div.toolbarModifier > .codemirror-wrapper {
+  overflow-y: auto;
+}
+div.toolbarModifier-hints {
+  float: right;
+  width: 350px;
+  min-width: 150px;
+  overflow-y: auto;
+  margin-left: 1.5em;
+}
+div.toolbarModifier-hints h3 {
+  font-size: 18.08px;
+  font-size: 1.13rem;
+  line-height: 32.54px;
+  line-height: 2.03rem;
+  padding: 0.36em 1.5em;
+  background: #f5f5f5;
+  border-bottom: 1px solid #ddd;
+  margin-top: 0;
+  margin-bottom: 1.2em;
+}
+div.toolbarModifier-hints dl {
+  margin-bottom: 1.2em;
+  overflow: hidden;
+}
+div.toolbarModifier-hints dl .list-header {
+  font-weight: bold;
+  border: 0;
+  padding-bottom: 0.6em;
+}
+div.toolbarModifier-hints dl > p {
+  text-align: center;
+}
+div.toolbarModifier-hints dl dt {
+  float: left;
+  width: 9em;
+  clear: both;
+  text-align: right;
+  border-top: 1px solid #ddd;
+  padding-left: 1.5em;
+  padding-right: .1em;
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+}
+div.toolbarModifier-hints dl dt code {
+  background: none;
+  border: none;
+  vertical-align: middle;
+}
+div.toolbarModifier-hints dl dd {
+  margin-left: 10em;
+  clear: right;
+  padding-right: 1.5em;
+}
+div.toolbarModifier-hints dl dd code {
+  line-height: 2.2em;
+}
+div.toolbarModifier-hints dl dd:after {
+  content: '\00a0';
+  display: block;
+  clear: left;
+  float: right;
+  height: 0;
+  width: 0;
+}
+.toolbarModifier-hints,
+.configContainer textarea.configCode,
+.CodeMirror {
+  -webkit-border-radius: 3px;
+  -webkit-background-clip: padding-box;
+  -moz-border-radius: 3px;
+  -moz-background-clip: padding;
+  border-radius: 3px;
+  background-clip: padding-box;
+  border: 1px solid #ccc;
+  font-size: 13.01px;
+  font-size: 0.813rem;
+  line-height: 23.42px;
+  line-height: 1.46rem;
+}
+.configContainer textarea.configCode,
+.CodeMirror pre,
+.CodeMirror-linenumber {
+  font-size: 13.01px;
+  font-size: 0.813rem;
+  line-height: 23.42px;
+  line-height: 1.46rem;
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+}
+.CodeMirror pre {
+  border: none;
+  padding: 0;
+  margin: 0;
+}
+.configContainer textarea.configCode {
+  -webkit-box-sizing: border-box;
+  -moz-box-sizing: border-box;
+  box-sizing: border-box;
+  color: #575757;
+  padding: 10px;
+  width: 100%;
+  min-height: 500px;
+  margin: 0;
+  resize: none;
+  outline: none;
+  -moz-tab-size: 4;
+  tab-size: 4;
+  white-space: pre;
+  word-wrap: normal;
+  overflow: auto;
+}
+.CodeMirror-hints.toolbar-modifier {
+  padding: 0;
+  color: #575757;
+  font-size: 14px;
+  font-size: 0.875rem;
+  line-height: 25.2px;
+  line-height: 1.57rem;
+  font-family: Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+}
+.CodeMirror-hints.toolbar-modifier .CodeMirror-hint-active {
+  color: #575757;
+  background: #f0fafb;
+}
+.CodeMirror-hints.toolbar-modifier > li:hover {
+  background: #fffbe3;
+}
+/* Text modifier */
+#toolbarModifierWrapper {
+  margin-bottom: 1.2em;
+}
+#toolbarModifierWrapper .invalid .CodeMirror {
+  background: #fff8f8;
+  border-color: red;
+}
+#toolbarModifierWrapper .CodeMirror {
+  height: auto;
+  padding: 0 0.6em;
+}
+.staticContainer {
+  position: fixed;
+  top: 0;
+  width: 100%;
+  z-index: 10;
+}
+.staticContainer > .grid-container {
+  max-width: 1052px;
+}
+.staticContainer > .grid-container .inner {
+  background: #fff;
+}
+.staticContainer > .grid-container .inner .toolbar {
+  margin-bottom: 0;
+}
+#help {
+  position: relative;
+  top: -15px;
+  left: -5px;
+}
+#help-content {
+  display: none;
+}
+/*# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2dsb2JhbC9nbG9iYWwubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2NvcmUvY29yZS5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvZ3JpZC9ncmlkLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvbm9kZV9tb2R1bGVzL2xlc3NoYXQvYnVpbGQvbGVzc2hhdC5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvaGVhZGVyLWEvaGVhZGVyLWEubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL25hdmlnYXRpb24tYS9uYXZpZ2F0aW9uLWEubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL25hdmlnYXRpb24tYi9uYXZpZ2F0aW9uLWIubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Zvb3Rlci1hL2Zvb3Rlci1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9jb250ZW50L2NvbnRlbnQubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2J1dHRvbi1hL2J1dHRvbi1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9iYWxsb29uLWEvYmFsbG9vbi1hLmxlc3MiLCIuLi8uLi9ub2RlX21vZHVsZXMvY2tzb3VyY2Utc2FtcGxlcy1mcmFtZXdvcmsvY29tcG9uZW50cy9pY29uL2ljb24ubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL3N3aXRjaC9zd2l0Y2gubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL3RvZ2dsZXIvdG9nZ2xlci5sZXNzIiwiLi4vLi4vbm9kZV9tb2R1bGVzL2Nrc291cmNlLXNhbXBsZXMtZnJhbWV3b3JrL2NvbXBvbmVudHMvbW9kYWwvbW9kYWwubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Jhc2ljc2FtcGxlL2NvcmUubGVzcyIsIi4uLy4uL25vZGVfbW9kdWxlcy9ja3NvdXJjZS1zYW1wbGVzLWZyYW1ld29yay9jb21wb25lbnRzL2Jhc2ljc2FtcGxlL2Fkam9pbmVkLmxlc3MiLCIuLi8uLi9zYW1wbGVzL2xlc3MvY3VzdG9tLmxlc3MiLCIuLi8uLi9zYW1wbGVzL3Rvb2xiYXJjb25maWd1cmF0b3IvbGVzcy90b29sYmFybW9kaWZpZXIubGVzcyIsIi4uLy4uL3NhbXBsZXMvdG9vbGJhcmNvbmZpZ3VyYXRvci9sZXNzL2Jhc2UubGVzcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBc0RBLFFBSGlDO0VBeUNoQztJQUNDLHdCQUFBOzs7QUMxRkY7QUFBUztBQUFPO0FBQVM7QUFBWTtBQUFRO0FBQVE7QUFBUTtBQUFRO0FBQU07QUFBTTtBQUFLO0VBQ3JGLGNBQUE7O0FBR0Q7QUFBTTtFQUNMLFNBQUE7RUFDQSxVQUFBO0VBQ0Esd0JETitCLHVDQ00vQjtFQUNBLGdCQUFBO0VBQ0EsY0FBQTs7QUNIQSxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsVUFBQTs7QUFERCxZQUFZO0VBQ1gsV0FBQTs7QUY0Q0YsUUFIaUM7RUVqQ2hDO0VBS0MsWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0VBQVosWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0VBQVosWUFBWTtFQUFaLFlBQVk7RUFBWixZQUFZO0lBSlosV0FBQTs7O0FBYUYsQ0FBQztFQ3FSQyw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7RURyUkQsZ0JBQUE7RUFDQSxpQkFBQTtFQUNBLFdBQUE7O0FBSUEsQ0FEQSxxQkFDQztBQUFELGVBQUM7QUFBUSxDQURULHFCQUNVO0FBQUQsZUFBQztFQUNULFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxnQkFBQTtFQUNBLGtCQUFBO0VBQ0EsWUFBQTtFQUNBLGNBQUE7RUFDQSxRQUFBO0VBQ0EsU0FBQTs7QUFLRCxDQURBLHFCQUNDO0FBQUQsZUFBQztFQUNBLFdBQUE7O0FBSUY7RUMyUEUsOEJBQUE7RUFDQSwyQkFBQTtFQUNBLHNCQUFBO0VEM1BELGlCQUFBO0VBQ0Esa0JBQUE7O0FBS0Msc0JBREQsRUFBQyxxQkFDQztFQUNBLGVBQUE7O0FBR0Qsc0JBTEQsRUFBQyxxQkFLQztFQUNBLGdCQUFBOztBRmpCSCxRQUhpQztFRTBCOUIsc0JBREQsRUFBQyxxQkFDQztJQUNBLGdCQUFBOztFQUdELHNCQUxELEVBQUMscUJBS0M7SUFDQSxpQkFBQTs7O0FFN0VKO0VBQ0MsaUJBQUE7RUFHQSxnQkFBQTs7QUFKRCxTQU1DO0VBQ0MsZ0JBQUE7O0FKMENGLFFBSGlDO0VBNkNqQyxTSXJGQztJQUlFLGtCQUFBOzs7QUFWSCxTQU1DLGVBT0M7RUFDQyxtQkFBQTs7QUNWSDtFQUNDLFlBQUE7RUFDQSxtQkFBQTtFQUNBLGtCQUFBO0VBQ0EsT0FBQTtFQUNBLFFBQUE7RUFDQSxNQUFBO0VBQ0EsVUFBQTtFQUNBLGdCQUFBOztBTHFDRCxRQUhpQztFQTZDakM7SUs1RUUsa0JBQUE7OztBQVhGLGFBY0M7RUFDQyxnQkFBQTtFQUNBLFNBQUE7RUFDQSxnQkFBQTs7QUFqQkYsYUFjQyxHQUtDO0FBbkJGLGFBY0MsR0FLSyxHQUFHO0VBQ04scUJBQUE7O0FMeUJILFFBSGlDO0VBNkNqQyxhS3pFQztJQVVFLFdBQUE7SUFDQSx1QkFBQTtJQUNBLG1CQUFBO0lBQ0EscUJBQUE7SUFDQSxXQUFBOztFQUVBLGFBaEJGLEdBZ0JHO0VBQVMsYUFoQlosR0FnQmE7SUFDVixhQUFBOzs7QUFLRCxhQXRCRixHQXFCRSxhQUNDO0VBQ0EsZ0JBQUE7O0FMUUosUUFIaUM7RUE2Q2pDLGFLekVDLEdBcUJFLGFBQ0M7SUFJQyxnQkFBQTs7O0FBSUYsYUE5QkYsR0FxQkUsYUFTQztFQUNBLGlCQUFBOztBTEFKLFFBSGlDO0VBNkNqQyxhS3pFQyxHQXFCRSxhQVNDO0lBSUMsa0JBQUE7OztBQU1GLGFBeENGLEdBdUNDLEdBQ0c7RUFDRCxpQkFBQTs7QUF2REosYUFjQyxHQXVDQyxHQUtDO0VMeENGLGVBQUE7RUFDQSxtQkFBQTtFQUNBLGlCQUFBO0VBQ0Esb0JBQUE7RUt1Q0csaUJBQUE7RUFDQSxXQUFBO0VBQ0EsV0FBQTtFQUNBLGlCQUFBO0VBQ0EscUJBQUE7RUFDQSx5QkFBQTs7QUFFQSxhQXJESCxHQXVDQyxHQUtDLEVBU0U7RUFDQSxlQUFBO0VBQ0EsV0FBQTs7QUFRSix5QkFBQztBQUFTLHlCQUFDO0VBQ1Ysc0JBQWtCLHFyQkFBbEI7O0FDcEZGO0VBQ0MsaUJBQUE7RUFDQSxnQkFBQTtFQUNBLGlCQUFBOztBTmdERCxRQUhpQztFQTZDakM7SU12RkUsa0JBQUE7SUFDQSxnQkFBQTtJQUdBLFVBQUE7OztBQVZGLGFBYUM7RUFDQyxVQUFBO0VBQ0EsZ0JBQUE7RUFDQSxTQUFBO0VBQ0EsaUJBQUE7O0FBakJGLGFBYUMsR0FNQztBQW5CRixhQWFDLEdBTUssR0FBRztFQUNOLHFCQUFBOztBTitCSCxRQUhpQztFQTZDakMsYU1oRkM7SUFXRSxjQUFBO0lBQ0EsV0FBQTtJQUNBLHFCQUFBOzs7QU55QkgsUUFIaUM7RUE2Q2pDLGFNaEZDLEdBZ0JDO0lBRUUsa0JBQUE7OztBQUdELGFBckJGLEdBZ0JDLEdBS0c7RUFDRCxpQkFBQTs7QU5nQkosUUFIaUM7RUE2Q2pDLGFNaEZDLEdBZ0JDLEdBS0c7SUFJQSxjQUFBOzs7QUF0Q0wsYUFhQyxHQWdCQyxHQWFDO0VId1FELDhCQUFBO0VBQ0EsMkJBQUE7RUFDQSxzQkFBQTtFR3hRRSx5QkFBQTtFQUNBLHFCQUFBO0VBQ0EsYUFBQTs7QU5LSixRQUhpQztFQTZDakMsYU1oRkMsR0FnQkMsR0FhQztJQU9FLFdBQUE7SUhxT0gsd0JBQUE7SUFBaUMsb0NBQUE7SUFDakMscUJBQUE7SUFBOEIsNkJBQUE7SUFDOUIsZ0JBQUE7SUFBeUIsNEJBQUE7OztBSXhSM0I7RVB3QkMsZUFBQTtFQUNBLG9CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFT3hCQSxtQkFBQTtFQUNBLHNCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxjQUFBOztBQU5ELFNQNEVDO0VBQ0MsY0FBQTtFQUNBLHFCQUFBO0VBRUEsaUNBQUE7O0FBRUEsU0FORCxFQU1FO0VBQ0EsY0FBQTs7QU9uRkgsU0FRQztFQUNDLFNBQUE7RUFDQSxxQkFBQTtFQUNBLGtCQUFBOztBQ1hGO0VSd0JDLGVBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RVF6QkEsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLHFCQUFBOztBQUpELFFBU0M7RUFDQyxnQkFBQTs7QUFWRixRQWFDO0FBYkQsUUFhSztBQWJMLFFBYVM7QUFiVCxRQWFjO0FBYmQsUUFhMEIsU0FBUSxJQUFJO0FBYnRDLFFBYXdEO0VBQ3RELGlCQUFBOztBQWRGLFFBaUJDO0FBakJELFFBaUJPO0VMcVFMLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VLclF6QixnQkFBQTs7QUFuQkYsUUFzQkM7QUF0QkQsUUFzQk07QUF0Qk4sUUFzQlk7QUF0QlosUUFzQmlCO0VBQ2YsbUJBQUE7O0FBdkJGLFFBMEJDO0FBMUJELFFBMEJhO0VBQ1gsZ0JBQUE7RUFDQSw4QkFBQTtFQUNBLHFCQUFBOztBQTdCRixRQW9DQyxFUndDQTtBUTVFRCxRQW9DSSxHUndDSDtBUTVFRCxRQW9DUSxHUndDUDtBUTVFRCxRQW9DWSxXUndDWDtBUTVFRCxRQW9Dd0IsR1J3Q3ZCO0FRNUVELFFBb0M0QixHUndDM0I7QVE1RUQsUUFvQ2dDLEdSd0MvQjtBUTVFRCxRQW9Db0MsR1J3Q25DO0FRNUVELFFBb0N3QyxHUndDdkM7RUFDQyxjQUFBO0VBQ0EscUJBQUE7RUFFQSxpQ0FBQTs7QUFFQSxRUTlDRCxFUndDQSxFQU1FO0FBQUQsUVE5Q0UsR1J3Q0gsRUFNRTtBQUFELFFROUNNLEdSd0NQLEVBTUU7QUFBRCxRUTlDVSxXUndDWCxFQU1FO0FBQUQsUVE5Q3NCLEdSd0N2QixFQU1FO0FBQUQsUVE5QzBCLEdSd0MzQixFQU1FO0FBQUQsUVE5QzhCLEdSd0MvQixFQU1FO0FBQUQsUVE5Q2tDLEdSd0NuQyxFQU1FO0FBQUQsUVE5Q3NDLEdSd0N2QyxFQU1FO0VBQ0EsY0FBQTs7QVFuRkgsUUF3Q0M7QUF4Q0QsUUF3Q0s7QUF4Q0wsUUF3Q1M7QUF4Q1QsUUF3Q2E7QUF4Q2IsUUF3Q2lCO0VBQ2YsV0FBQTtFQUNBLGdCQUFBOztBQTFDRixRQXdDQyxHQUtDO0FBN0NGLFFBd0NLLEdBS0g7QUE3Q0YsUUF3Q1MsR0FLUDtBQTdDRixRQXdDYSxHQUtYO0FBN0NGLFFBd0NpQixHQUtmO0FBN0NGLFFBd0NDLEdBS087QUE3Q1IsUUF3Q0ssR0FLRztBQTdDUixRQXdDUyxHQUtEO0FBN0NSLFFBd0NhLEdBS0w7QUE3Q1IsUUF3Q2lCLEdBS1Q7RUFDTCxrQkFBQTs7QUE5Q0gsUUF3Q0MsR0FVQyxFQUFDO0FBbERILFFBd0NLLEdBVUgsRUFBQztBQWxESCxRQXdDUyxHQVVQLEVBQUM7QUFsREgsUUF3Q2EsR0FVWCxFQUFDO0FBbERILFFBd0NpQixHQVVmLEVBQUM7RUFDQSxnQkFBQTtFQUNBLHNCQUFBO0VBQ0EsVUFBQTtFQUNBLFNBQUE7O0FBR0QsUUFqQkQsR0FpQkUsTUFDQSxFQUFDO0FBREYsUUFqQkcsR0FpQkYsTUFDQSxFQUFDO0FBREYsUUFqQk8sR0FpQk4sTUFDQSxFQUFDO0FBREYsUUFqQlcsR0FpQlYsTUFDQSxFQUFDO0FBREYsUUFqQmUsR0FpQmQsTUFDQSxFQUFDO0VBQ0EsVUFBQTs7QUFJRixRQXZCRCxHQXVCRSxPQUNBO0FBREQsUUF2QkcsR0F1QkYsT0FDQTtBQURELFFBdkJPLEdBdUJOLE9BQ0E7QUFERCxRQXZCVyxHQXVCVixPQUNBO0FBREQsUUF2QmUsR0F1QmQsT0FDQTtFTDhERCwwREFBQTtFQUNBLHVEQUFBO0VBQ0EscURBQUE7RUFDQSxrREFBQTtFSy9ERSxVQUFBOztBQWxFSixRQXVFQztBQXZFRCxRQXVFUTtBQXZFUixRQXVFZ0IsU0FBUSxJQUFJO0VMK00xQiwwQkFBQTtFQUFpQyxvQ0FBQTtFQUNqQyx1QkFBQTtFQUE4Qiw2QkFBQTtFQUM5QixrQkFBQTtFQUF5Qiw0QkFBQTtFQW1CekIsdURBQUE7RUFDQSxvREFBQTtFQUNBLCtDQUFBO0VLbE9BLGFBQUE7RUFDQSxjQUFBO0VBRUEseUJBQUE7RUFDQSxrQkFBQTs7QUFFQSxRQVZELE1BVUU7QUFBRCxRQVZNLE9BVUw7QUFBRCxRQVZjLFNBQVEsSUFBSSxnQkFVekI7RUFDQSxxQkFBQTtFQUNBLFVBQUE7RUx3TkQsd0VBQUE7RUFDQSxxRUFBQTtFQUNBLGdFQUFBOztBSzdTRixRQThGQztFQUNDLDhCQUFBO0VBQ0EsZUFBQTs7QUFoR0YsUUFtR0M7RUFDQyxrQkFBQTtFQUNBLDZCUm5HMkMsd0JRbUczQztFUjdFRCxlQUFBO0VBQ0EsZUFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7O0FRM0JELFFBeUdDO0VBQ0Msa0JBQUE7O0FBMUdGLFFBNkdDO0VSckZBLGVBQUE7RUFDQSxrQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RVFvRkMsbUJBQUE7O0FBL0dGLFFBa0hDO0VSMUZBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VReUZDLGlCQUFBOztBQXBIRixRQXVIQztFUi9GQSxlQUFBO0VBQ0EsaUJBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VROEZDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBMUhGLFFBNkhDO0VSckdBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VRb0dDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBaElGLFFBbUlDO0VSM0dBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxvQkFBQTtFQUNBLG9CQUFBO0VRMEdDLGdCQUFBO0VBQ0Esa0JBQUE7O0FBdElGLFFBeUlDO0VBQ0MsU0FBQTtFQUNBLDZCQUFBO0VBQ0EsZUFBQTs7QUFJQSxRQURELE1BQ0U7RUFDQSxhQUFBO0VBQ0Esa0JBQUE7O0FBR0QsUUFORCxNQU1FO0VMaURELDBCQUFBO0VBQ0EsdUJBQUE7RUFDQSxrQkFBQTs7QUt4TUYsUUE0SkM7RVJwSUEsZUFBQTtFQUNBLGtCQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFUW1JQyxvQlI3SjhCLHVDUTZKOUI7RUFDQSxnQkFBQTtFTDRJQSx1REFBQTtFQUNBLG9EQUFBO0VBQ0EsK0NBQUE7O0FLN1NGLFFBdUtDLEVBQ0M7RUFDQyxzQkFBQTs7QUF6S0gsUUF1S0MsRUFLQztFQUNDLGNBQUE7O0FBN0tILFFBaUxDO0VBQ0MsVUFBQTtFQUNBLFNBQUE7RUFFQSxXQUFBO0VBQ0EsY0FBQTtFQUNBLGdCQUFBOztBQXZMRixRQTBMQztBQTFMRCxRQTBMTTtFUmxLTCxrQkFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFUWtLQyxnSkFBQTs7QUE3TEYsUUEwTEMsSUFLQztBQS9MRixRQTBMTSxLQUtKO0VBQ0MsU0FBQTs7QUFoTUgsUUFxTUMsSUFBSTtFQUNILGVBQUE7RUFDQSxjQUFBOztBQXZNRixRQTBNQztFQUNDLFdBQUE7O0FBM01GLFFBOE1DLEdBRUM7QUFoTkYsUUE4TUssR0FFSDtBQWhORixRQThNQyxHQUVLO0FBaE5OLFFBOE1LLEdBRUM7RUFDSCxnQkFBQTs7QUFqTkgsUUE4TUMsR0FNQztBQXBORixRQThNSyxHQU1IO0VSNUxELGVBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VBQ0Esb0JBQUE7O0FRM0JELFFBME5DLFNBQVEsSUFBSTtFQUNYLFdBQUE7O0FBM05GLFFBOE5DLElBQUc7RUFDRix1QkFBQTtFQUNBLGFBQUE7RUFDQSxxQkFBQTs7O0FBR0EsUUFORCxJQUFHLEtBTUQ7RUFDQSxTQUFTLE1BQVQ7RUFDQSxpQkFBQTs7QUNqT0QsSUFERCxFQUNFO0FBQUQsSUFERSxPQUNEO0FBQUQsSUFEVSxNQUNUO0VOaVJELDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VIaFExQixlQUFBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VTbkJFLFlBQUE7RUFDQSxpQkFBQTtFQUNBLGdCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxjQUFBO0VBQ0EsbUJBQUE7RUFDQSxxQkFBQTtFQUNBLHFCQUFBO0VBQ0EsZUFBQTtFQUNBLFNBQUE7RUFDQSxzQkFBQTtFQUlBLGFBQUE7RUFHQSx1QkFBQTs7QUFFQSxJQXZCRixFQUNFLFNBc0JDO0FBQUQsSUF2QkMsT0FDRCxTQXNCQztBQUFELElBdkJTLE1BQ1QsU0FzQkM7RUFDQSxrQkFBQTs7QUFHRCxJQTNCRixFQUNFLFNBMEJDO0FBQUQsSUEzQkMsT0FDRCxTQTBCQztBQUFELElBM0JTLE1BQ1QsU0EwQkM7RUFDQSxtQkFBQTs7QUFvQkQsSUFoREYsRUFDRSxTQStDQztBQUFELElBaERDLE9BQ0QsU0ErQ0M7QUFBRCxJQWhEUyxNQUNULFNBK0NDO0VOa09GLDRCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHlCQUFBO0VBQThCLDZCQUFBO0VBQzlCLG9CQUFBO0VBQXlCLDRCQUFBO0VNblB2QixXQUFBO0VBQ0EsVUFBQTtFQUNBLG1CQUFBO0VBQ0EsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLGtCQUFBOztBQUVBLElBeENILEVBQ0UsU0ErQ0MsaUJBUkM7QUFBRCxJQXhDQSxPQUNELFNBK0NDLGlCQVJDO0FBQUQsSUF4Q1EsTUFDVCxTQStDQyxpQkFSQztFQUNBLGtCQUFBO0VBQ0EsU0FBQTtFQUNBLFFBQUE7RUFDQSxxQkFBQTs7QVRHTCxRQUhpQztFQTZDakMsSVN6RkMsRUFDRSxTQW1EQztFVHFDSixJU3pGSSxPQUNELFNBbURDO0VUcUNKLElTekZZLE1BQ1QsU0FtREM7SU44TkYsNEJBQUE7SUFBaUMsb0NBQUE7SUFDakMseUJBQUE7SUFBOEIsNkJBQUE7SUFDOUIsb0JBQUE7SUFBeUIsNEJBQUE7SU1uUHZCLFdBQUE7SUFDQSxVQUFBO0lBQ0EsbUJBQUE7SUFDQSxnQkFBQTtJQUNBLGtCQUFBO0lBQ0Esa0JBQUE7O0VBRUEsSUF4Q0gsRUFDRSxTQW1EQywwQkFaQztFQUFELElBeENBLE9BQ0QsU0FtREMsMEJBWkM7RUFBRCxJQXhDUSxNQUNULFNBbURDLDBCQVpDO0lBQ0Esa0JBQUE7SUFDQSxTQUFBO0lBQ0EsUUFBQTtJQUNBLHFCQUFBOztFQUpELElBeENILEVBQ0UsU0FtREMsMEJBWkM7RUFBRCxJQXhDQSxPQUNELFNBbURDLDBCQVpDO0VBQUQsSUF4Q1EsTUFDVCxTQW1EQywwQkFaQztJQUNBLGtCQUFBO0lBQ0EsU0FBQTtJQUNBLFFBQUE7SUFDQSxxQkFBQTs7O0FBY0YsSUExREYsRUFDRSxTQXlEQztBQUFELElBMURDLE9BQ0QsU0F5REM7QUFBRCxJQTFEUyxNQUNULFNBeURDO0FBQ0QsSUEzREYsRUFDRSxTQTBEQztBQUFELElBM0RDLE9BQ0QsU0EwREM7QUFBRCxJQTNEUyxNQUNULFNBMERDO0VBQ0EsV0FBQTtFQUNBLG1CQUFBOztBQUdELElBaEVGLEVBQ0UsU0ErREM7QUFBRCxJQWhFQyxPQUNELFNBK0RDO0FBQUQsSUFoRVMsTUFDVCxTQStEQztFQUNBLHFCQUFBO0VBQ0EsVUFBQTtFTnFPRix5RUFBQTtFQUNBLHNFQUFBO0VBQ0EsaUVBQUE7O0FNNU5BLElBN0VELEVBNkVFO0FBQUQsSUE3RUUsT0E2RUQ7QUFBRCxJQTdFVSxNQTZFVDtFQUNBLG1CQUFBOztBQUVBLElBaEZGLEVBNkVFLGNBR0M7QUFBRCxJQWhGQyxPQTZFRCxjQUdDO0FBQUQsSUFoRlMsTUE2RVQsY0FHQztBQUNELElBakZGLEVBNkVFLGNBSUM7QUFBRCxJQWpGQyxPQTZFRCxjQUlDO0FBQUQsSUFqRlMsTUE2RVQsY0FJQztFQUNBLGNBQUE7RUFDQSxtQkFBQTs7QUFJRixJQXZGRCxFQXVGRTtBQUFELElBdkZFLE9BdUZEO0FBQUQsSUF2RlUsTUF1RlQ7QUFBRCxJQXZGRCxFSGlERyxhQXhDSCxHQWdCQyxHQWFDLEVBV0U7QUdzQ0gsSUF2RkUsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFO0FHc0NILElBdkZVLE1IaURSLGFBeENILEdBZ0JDLEdBYUMsRUFXRTtFR3VDRixXQUFBO0VBQ0EsbUJBQUE7O0FBRUEsSUEzRkYsRUF1RkUsb0JBSUM7QUFBRCxJQTNGQyxPQXVGRCxvQkFJQztBQUFELElBM0ZTLE1BdUZULG9CQUlDO0FBQ0QsSUE1RkYsRUF1RkUsb0JBS0M7QUFBRCxJQTVGQyxPQXVGRCxvQkFLQztBQUFELElBNUZTLE1BdUZULG9CQUtDO0FBREQsSUEzRkYsRUhpREcsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQUQsSUEzRkMsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQUQsSUEzRlMsTUhpRFIsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMENEO0FBQ0QsSUE1RkYsRUhpREcsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0FBQUQsSUE1RkMsT0hpREEsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0FBQUQsSUE1RlMsTUhpRFIsYUF4Q0gsR0FnQkMsR0FhQyxFQVdFLE1HMkNEO0VBQ0EsV0FBQTtFQUNBLG1CQUFBOztBQ2hHSjtFVnNCQyxlQUFBO0VBQ0Esa0JBQUE7RUFDQSxtQkFBQTtFQUNBLG9CQUFBO0VHMlBDLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VPblIxQixnQ0FBQTtFQUVBLG1CQUFBO0VBQ0EscUJBQUE7RUFDQSxtQkFBQTtFQUNBLHdCQUFBO0VBQ0EsZ0JBQUE7RUFDQSxrQkFBQTtFQUNBLGFBQUE7RUFDQSxvQkFBQTtFQUNBLGNBQUE7O0FBRUEsVUFBQztFQUNBLGNBQUE7O0FBR0QsVUFBQztFQUNBLFNBQVMsRUFBVDtFQUNBLFFBQUE7RUFDQSxTQUFBO0VBQ0EsbUJBQUE7RUFDQSxrQkFBQTs7QUFNRCxhQUFDO0FBQUQsYUFBQztFQUNBLFVBQUE7RUFDQSw4QkFBQTtFQUNBLHlEQUFBOztBQU1ELGFBQUM7QUFBRCxhQUFDO0VBQ0EsYUFBQTtFQUNBLDhCQUFBO0VBQ0EseURBQUE7O0FBTUQsYUFBQztBQUFELGFBQUM7RUFDQSxVQUFBOztBQU1ELGFBQUM7QUFBRCxhQUFDO0VBQ0EsV0FBQTs7QUN2REYsY0FBYztBQUNkLGVBQWU7RUFDZCxTQUFTLEVBQVQ7RUFDQSxxQkFBQTtFQUNBLFdBQUE7RUFDQSxZQUFBO0VBQ0Esc0JBQUE7RUFDQSw0QkFBQTs7QUFHRCxjQUFjO0VBQ2Isa0JBQUE7O0FBR0QsZUFBZTtFQUNkLGlCQUFBOztBQUlBLGNBQUM7QUFBUyxjQUFDO0VBQ1Ysc0JBQWtCLDZjQUFsQjs7QUFLRCxtQkFBQztBQUFTLG1CQUFDO0VBQ1Ysc0JBQWtCLDZpQkFBbEI7O0FBS0QsV0FBQztBQUFTLFdBQUM7RUFDVixzQkFBa0IsNmlCQUFsQjs7QUM1QkYsSUFBSyxRQUVKO0VBQ0Msc0JBQUE7O0FBSEYsSUFBSyxRQU1KLE1BQUs7RUFDSixnQkFBQTtFQUNBLHFCQUFBOztBQVJGLElBQUssUUFXSjtFQUNDLHlCQUFBO0VBQ0EsMEJBQUE7O0FBRUEsSUFmRyxRQVdKLE1BSUU7RUFDQSxXQUFBOztBQUdELElBbkJHLFFBV0osTUFRRTtFQUNBLFlBQUE7O0FBcEJILElBQUssUUF3Qko7RUFDQyxhQUFBOztBQUlGO0VaWkMsZUFBQTtFQUNBLG1CQUFBO0VBQ0EsbUJBQUE7RUFDQSxvQkFBQTtFWVdBLGlCQUFBO0VBQ0EseUJBQUE7RUFDQSxnQkFBQTtFQUNBLHFCQUFBO0VBQ0Esc0JBQUE7RUFDQSxXQUFBO0VUMk9DLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VTM08xQixrQkFBQTs7QUFURCxPQVdDLE1BQUs7RUFDSixhQUFBOztBQVpGLE9BZUM7RUFDQyxrQkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBO0VBQ0EsZUFBQTtFQUNBLGlCQUFBOztBQUVBLE9BUEQsTUFPRTtFQUNBLDBCQUFBOztBQXZCSCxPQTJCQztFQUNDLFdBQUE7RUFDQSxzQkFBQTtFQUNBLGFBQUE7RUFDQSxjQUFBO0VBQ0EsWUFBQTtFQUNBLGdCQUFBO0VUaU5BLDRCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHlCQUFBO0VBQThCLDZCQUFBO0VBQzlCLG9CQUFBO0VBQXlCLDRCQUFBOztBU3BQM0IsT0EyQkMsY0FTQztFQUNDLGdCQUFBO0VBQ0Esa0JBQUE7RUFDQSxjQUFBO0VBQ0EsYUFBQTtFQUNBLFlBQUE7RUFDQSxtQkFBQTtFVHdNRCw0QkFBQTtFQUFpQyxvQ0FBQTtFQUNqQyx5QkFBQTtFQUE4Qiw2QkFBQTtFQUM5QixvQkFBQTtFQUF5Qiw0QkFBQTs7QVN2TXhCLE9BbEJGLGNBU0MsU0FTRTtFQUNBLFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxrQkFBQTtFQUNBLE1BQUE7RUFDQSxRQUFBO0VBQ0EsV0FBQTtFQUNBLE9BQUE7RUFFQSx5QkFBQTtFVHNLRix3Q0FBQTtFQUNBLG9DQUFBO0VBQ0EsZ0NBQUE7RUFLQSx5Q0FBQTtFQUE4QyxvQ0FBQTtFQUM5QyxxQ0FBQTtFQUEwQyw2QkFBQTtFQUMxQyxpQ0FBQTtFQUFzQyw0QkFBQTs7QVN2S3ZDLE9BQUMsTUFDQSxjQUFjLFNBQVE7RUFDckIsbUJBQUE7O0FBaEVILE9Bb0VDLE1BQUssY0FBZ0IsUUFFcEIsZ0JBQWdCO0VBQ2YsaUJBQUE7O0FBdkVILE9Bb0VDLE1BQUssY0FBZ0IsUUFTcEIsUUFBTztFQUNOLHNCQUFBO0VBQ0Esc0JBQUE7O0FBL0VILE9BbUZDLE1BQUssY0FBZ0IsUUFBUyxRQUFPO0VBQ3BDLHFCQUFBO0VBQ0EscUJBQUE7O0FDekhGO0VWazNCRSx5QkFBQTtFQUNBLHNCQUFBO0VBQ0EscUJBQUE7RUFDQSxpQkFBQTs7QVVyM0JGLFFBR0M7RUFDQyxlQUFBOztBQUpGLFFBTUM7RUFDQyxnQkFBQTs7QUFQRixRQVVDO0VBQ0MsYUFBQTs7QUFHRCxRQUFDLFVBQ0E7RUFDQyxhQUFBOztBQUZGLFFBQUMsVUFLQTtFQUNDLGdCQUFBOztBQUtIO0VBQ0MsZ0JBQUE7O0FBRUEsa0JBQUM7RUFDQSxTQUFBOztBQU1ELHNCQUFDO0FBQUQsdUJBQUM7QUFBUyxzQkFBQztBQUFELHVCQUFDO0VBQ1Ysc0JBQWtCLHlzQkFBbEI7O0FBSUEsc0JBREEsV0FDQztBQUFELHVCQURBLFdBQ0M7QUFBUyxzQkFEVixXQUNXO0FBQUQsdUJBRFYsV0FDVztFQUNWLHNCQUFrQixxdEJBQWxCOztBQU1GLHNCQUFDO0FBQ0Qsc0JBQUM7RUFDQSw2QkFBQTs7QUFLRCx1QkFBQztBQUNELHVCQUFDO0VBQ0EsZ0NBQUE7O0FDdERGO0VBQ0MsYUFBQTtFQUNBLGtCQUFBO0VBQ0EsdUJBQUE7RUFDQSxnQkFBQTtFWDRTQyw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7RVd6U0QscUJBQUE7RUFDQSxtQkFBQTtFWGd2QkMsd0NBQUE7RUFDQSxxQ0FBQTtFQUNBLG1DQUFBO0VBQ0Esb0NBQUE7RUFDQSxnQ0FBQTs7QVdqdkJELE1BQUM7RVh1UUEsNEJBQUE7RUFBaUMsb0NBQUE7RUFDakMseUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsb0JBQUE7RUFBeUIsNEJBQUE7RVd2UXpCLGVBQUE7RUFDQSxZQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBO0VBQ0EsU0FBQTtFQUNBLFdBQUE7RUFDQSxlQUFBO0VBQ0Esa0JBQUE7RUFDQSxpQkFBQTtFQUNBLG1CQUFBOztBQ3pCRixJQUFLO0FBQ0wsTUFBTztBQUNQLGFBQWM7QUFDZCxNQUFPO0VBQ04sZ0JBQUE7O0FBSUQ7RUFDQyxnQkFBQTs7QUFHRDtFQUNDLDZCQUFBOztBQ1hBLFNBQUM7RUFDQSx5QkFBQTtFQUNBLFdBQUE7O0FBRkQsU0FBQyxJQUlBLFNBQ0M7QUFMRixTQUFDLElBSUEsU0FDSztBQUxOLFNBQUMsSUFJQSxTQUNTO0FBTFYsU0FBQyxJQUlBLFNBQ2E7QUFMZCxTQUFDLElBSUEsU0FDaUI7RUFDZixXQUFBOztBQU5ILFNBQUMsSUFJQSxTQUtDO0VoQllGLGVBQUE7RUFDQSxtQkFBQTtFQUNBLG1CQUFBO0VBQ0Esb0JBQUE7RWdCYkcsZ0JBQUE7O0FBWEgsU0FBQyxJQUlBLFNBS0MsRUFJQztFQUNDLHFCQUFBO0VBQ0EsOEJBQUE7RUFDQSxjQUFBOztBQUVBLFNBbEJILElBSUEsU0FLQyxFQUlDLEVBS0U7RUFDQSxjQUFBOztBQW5CTCxTQUFDLElBSUEsU0FvQkM7RUFDQyxXQUFBOztBQXpCSCxTQUFDLElBSUEsU0F3QkM7RUFDQyxXQUFBOztBQTdCSCxTQUFDLElBSUEsU0E0QkM7RUFDQyxrQkFBQTtFQUNBLGNBQUE7O0FBS0gsU0FBQztFQUNBLGtCQUFBOztBQUVBLFNBSEEsT0FHQztFQUNBLFdBQUE7RUFDQSxTQUFTLEVBQVQ7RUFDQSxtQkFBQTtFQUNBLGtCQUFBO0VBQ0EsTUFBQTtFQUNBLE9BQUE7RUFDQSxRQUFBO0VBQ0EsV0FBQTs7QUN4REgsSUFBSztBQUNMLE1BQU87QUFDUCxhQUFjO0FBQ2QsTUFBTztFQUNOLGlCQUFBOztBQUdELElBQUssZ0JBQWU7RUFDbkIsZUFBQTs7QUFHRDtFQUNDLG1CQUFBO0VBQ0EsWUFBQTtFQUNBLGlCQUFBOztBQUhELE9BTUM7RUFFQyxrQkFBQTtFQUNBLFVBQUE7RUFDQSxVQUFBO0VBQ0EsbUJBQUE7RUFHQSxtQkFBQTtFQUNBLDRCQUFBOztBQUVBLE9BWEQsV0FXRTtFQUNBLHlEQUFBOztBQUtILFFBQVM7RUFDUixnQkFBQTtFQUNBLFNBQUE7RUFDQSx3QkFBQTs7QUFFQSxRQUxRLG1CQUtQO0VBQ0EsWUFBQTs7QUFLRixLQUFNO0VBQ0wsZ0JBQUE7RUFDQSxjQUFBO0VBQ0EsMEJBQUE7O0FBR0QsS0FBTSxjQUFhO0VBQ2xCLGFBQUE7O0FBSUEsUUFEUSxjQUNQO0VBQ0EsYUFBQTs7QUFGRixRQUFTLGNBS1I7RUFDQyxhQUFBOztBQUlGLFFBQ0M7RUFDQyxpQkFBQTs7QUFJRjtFQUNDLGlCQUFBOztBQURELFNBR0M7RUFDQyxXQUFBO0VBQ0EsaUJBQUE7O0FBTEYsU0FHQyxNQUlDO0VBQ0MsZ0JBQUE7O0FBRUEsU0FQRixNQUlDLFNBR0U7RUFDQSx1QkFBQTtFQUNBLFdBQUE7O0FBRkQsU0FQRixNQUlDLFNBR0UsTUFJQTtFQUNDLDBCQUFBOztBQWZMLFNBR0MsTUFpQkM7RUFDQyxXQUFBO0VBQ0EsYUFBQTs7QUFHRCxTQXRCRCxNQXNCRTtFQUNBLGdCQUFBOztBQUtIO0VBQ0MsZ0JBQUE7RUFDQSxTQUFBO0VBQ0EsVUFBQTtFQUNBLHdCQUFBOztBQUVBLHVCQUFDO0VBQ0EsWUFBQTtFQUNBLFVBQUE7O0FBS0Y7RUFDQyxpQkFBQTs7QUFERCxNQUdDLElBQUc7RUFDRixpQkFBQTs7QUFKRixNQU9DO0VBQ0MsaUJBQUE7O0FBUkYsTUFPQyxjQUdDO0VBQ0MsaUJBQUE7O0FBWEgsTUFPQyxjQU9DO0VBRUMsa0JBQUE7O0FBaEJILE1Bb0JDO0VBQ0Msa0JBQUE7RUFDQSxTQUFBO0VBRUEsU0FBQTtFQUNBLGtCQUFBOztBakJ0RkYsUUFIaUM7RUE2Q2pDLE1pQnVDQztJQVVFLFVBQUE7SUFDQSxpQkFBQTtJQUVBLFVBQUE7SUFDQSxtQkFBQTs7RUFFQSxNQWhCRixXQWdCRztJQUNBLFVBQUE7SUFDQSxXQUFBOzs7QWpCbkdKLFFBSGlDO0VBNkNqQyxNaUJ1Q0M7SUF3QkUsYUFBQTs7O0FDOUlILFFBQVM7RUFDUixvQkFBQTtFZm0yQkMseUJBQUE7RUFDQSxzQkFBQTtFQUNBLHFCQUFBO0VBQ0EsaUJBQUE7RWVwMkJELGVBQUE7O0FBSUQsb0JBQXFCO0VmNmVsQixPQUFBO0VBQVMseUJBQUE7RUFDVixvQkFBQTtFQUNBLGlCQUFBO0VBQ0EsWUFBQTs7QWU1ZUYsWUFBWTtFQUNYLGtCQUFBO0Vmd2VFLE9BQUE7RUFBUywwQkFBQTtFQUNWLGtCQUFBO0VBQ0EsZUFBQTtFQUNBLFVBQUE7O0FldGVELFlBTlcsT0FNVjtFQUNBLFNBQVMsRUFBVDtFQUNBLGNBQUE7RUFDQSxrQkFBQTtFQUNBLE1BQUE7RUFDQSxVQUFBO0VBQ0EsV0FBQTtFQUNBLE9BQUE7RWZnUEEsMEJBQUE7RUFBaUMsb0NBQUE7RUFDakMsdUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsa0JBQUE7RUFBeUIsNEJBQUE7RUFtQnpCLDRDQUFBO0VBQ0EseUNBQUE7RUFDQSxvQ0FBQTs7QWVwUkYsWUFBWSxPQWtCWDtFZmdRQyx3QkFBQTtFQUNBLHFCQUFBO0VBQ0EsZ0JBQUE7RWVoUUEscUJBQUE7O0FBcEJGLFlBQVksT0F1Qlg7QUF2QkQsWUFBWSxPQXdCWDtFQUNDLGtCQUFBO0VBQ0EsVUFBQTs7QUExQkYsWUFBWSxPQTZCWDtFZnFQQyx3QkFBQTtFQUNBLHFCQUFBO0VBQ0EsZ0JBQUE7O0FlbFBGO0VmdXpCRSx5QkFBQTtFQUNBLHNCQUFBO0VBQ0EscUJBQUE7RUFDQSxpQkFBQTs7QWV2ekJGO0VBQ0MsY0FBQTtFQUNBLG9CQUFBO0VBQ0EsZ0JBQUE7RUFDQSxnQkFBQTs7QUFHQyxRQURELE9BQU0sU0FDSjtFQUNBLGVBQUE7RUFFQSxxQkFBQTtFQUNBLGdCQUFBO0VBQ0EsVUFBQTtFQUNBLHlCQUFBOztBQUdELFFBVkQsT0FBTSxTQVVKO0VBQ0EsYUFBQTs7QUFHRCxRQWRELE9BQU0sU0FjSjtFQUNBLFdBQUE7RUFDQSxpQkFBQTs7QUFHRCxRQW5CRCxPQUFNLFNBbUJKO0VBQ0EsWUFBQTtFQUNBLGdCQUFBOztBQTNCSCxRQU1DLE9BQU0sU0F3Qkw7RUFDQyxjQUFBOztBQU1ILGdCQUFnQjtBQUNoQixnQkFBZ0I7QUFDaEIsc0JBQXNCO0VBQ3JCLGFBQUE7O0FBR0QsZ0JBQWlCO0FBQ2pCLFFBQVMsT0FBTTtBQUNmLGdCQUFpQixTQUFRLFdBQVc7RUFDbkMsYUFBQTs7QUFHRCxHQUFHO0VBQ0YsVUFBQTtFQUNBLGdCQUFBO0VBQ0EsV0FBQTtFQUNBLGtCQUFBO0VBQ0EsY0FBQTtFQUNBLHlCQUFBOztBQU5ELEdBQUcsZ0JBUUY7RUFDQyxTQUFBOztBQVRGLEdBQUcsZ0JBWUY7RUFDQyxhQUFBOztBQUdELEdBaEJFLGdCQWdCRCxjQUFlO0VBQ2Ysa0JBQUE7RWZrWUMsT0FBQTtFQUFTLHlCQUFBO0VBQ1Ysb0JBQUE7RUFDQSxpQkFBQTtFQUNBLFlBQUE7O0FldFpGLEdBQUcsZ0JBdUJGLE9BQU87RUFDTixpQkFBQTs7QUFJRCxHQTVCRSxnQkE0QkE7RUFDRCxVQUFBO0VBQ0EsU0FBQTtFQUNBLDBCQUFBO0VBQ0EsV0FBQTs7QUFFQSxHQWxDQyxnQkE0QkEsS0FNQTtFQUNBLDJCQUFBOztBQUdELEdBdENDLGdCQTRCQSxLQVVBO0VBQ0Esd0JBQUE7O0FBWEYsR0E1QkUsZ0JBNEJBLEtBZUQ7RUFDQyxVQUFBO0VBQ0EsU0FBQTs7QUFJRCxHQWpEQyxnQkE0QkEsS0FxQkM7RUFDRCxrQkFBQTs7QUFFQSxHQXBEQSxnQkE0QkEsS0FxQkMsS0FHQTtFQUNBLGlCQUFBO0VBQ0EsaUJBQUE7RUFDQSxlQUFBOztBQUdELEdBMURBLGdCQTRCQSxLQXFCQyxLQVNBO0FBQ0QsR0EzREEsZ0JBNEJBLEtBcUJDLEtBVUE7RUFDQSw2QkFBQTs7QUFHRCxHQS9EQSxnQkE0QkEsS0FxQkMsS0FjQTtFQUNBLDBCQUFBOztBQUVBLEdBbEVELGdCQTRCQSxLQXFCQyxLQWNBLHNCQUdDO0VBQ0EsZ0JBQUE7O0FBSUYsR0F2RUEsZ0JBNEJBLEtBcUJDLEtBc0JBLG1CQUFtQjtBQUNwQixHQXhFQSxnQkE0QkEsS0FxQkMsS0F1QkEsbUJBQW1CO0FBQ3BCLEdBekVBLGdCQTRCQSxLQXFCQyxLQXdCQSx1QkFBdUI7QUFDeEIsR0ExRUEsZ0JBNEJBLEtBcUJDLEtBeUJBLHVCQUF1QjtFQUN2QixnQkFBQTtFQUNBLFVBQUE7O0FBR0QsR0EvRUEsZ0JBNEJBLEtBcUJDLEtBOEJBLG1CQUFtQjtBQUNwQixHQWhGQSxnQkE0QkEsS0FxQkMsS0ErQkEsdUJBQXVCO0FBQ3hCLEdBakZBLGdCQTRCQSxLQXFCQyxLQWdDQSxtQkFBbUIsT0FBTztBQUMzQixHQWxGQSxnQkE0QkEsS0FxQkMsS0FpQ0EsdUJBQXVCLE9BQU87RUFDOUIsbUJBQUE7O0FBR0QsR0F0RkEsZ0JBNEJBLEtBcUJDLEtBcUNBLG1CQUFtQjtBQUNwQixHQXZGQSxnQkE0QkEsS0FxQkMsS0FzQ0EsdUJBQXVCO0VBQ3ZCLG1CQUFBOztBQUdELEdBM0ZBLGdCQTRCQSxLQXFCQyxLQTBDQTtFQU1BLG1CQUFBOztBQUxBLEdBNUZELGdCQTRCQSxLQXFCQyxLQTBDQSx1QkFDQztFQUNBLFNBQVMsRUFBVDtFQUNBLFdBQUE7O0FBS0QsR0FuR0QsZ0JBNEJBLEtBcUJDLEtBMENBLHVCQVFFO0VBQ0QsZ0JBQUE7O0FBSUYsR0F4R0EsZ0JBNEJBLEtBcUJDLEtBdURDO0FBQUssR0F4R1AsZ0JBNEJBLEtBcUJDLEtBdURRO0VBQ1IsbUJBQUE7RUFDQSxzQkFBQTs7QUF6REYsR0FqREMsZ0JBNEJBLEtBcUJDLEtBNkREO0VBQ0MsaUJBQUE7RUFDQSxnQkFBQTs7QUEvREYsR0FqREMsZ0JBNEJBLEtBcUJDLEtBNkRELEVBSUM7RUFDQyxtQkFBQTtFQUNBLGVBQUE7O0FBbkVILEdBakRDLGdCQTRCQSxLQXFCQyxLQTZERCxFQUlDLEtBSUM7RUFDQyxtQkFBQTtFQUNBLGlCQUFBO0VBQ0EsZUFBQTtFQUNBLGdCQUFBO0VmNkNKLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VlN0NyQixzQkFBQTtFQUNBLGNBQUE7RUFDQSxpQkFBQTtFQUNBLFlBQUE7O0FBR0MsR0FsSUosZ0JBNEJBLEtBcUJDLEtBNkRELEVBSUMsS0FJQyxPQVdFLElBQUksV0FDSDtBQUNELEdBbklKLGdCQTRCQSxLQXFCQyxLQTZERCxFQUlDLEtBSUMsT0FXRSxJQUFJLFdBRUg7RUFDQSxXQUFBO0VBQ0EseUJBQUE7RUFDQSx5QkFBQTs7QUFJRixHQTFJSCxnQkE0QkEsS0FxQkMsS0E2REQsRUFJQyxLQUlDLE9Bb0JFLEtBQUs7RUFDTCxlQUFBO0Vmd1FKLE9BQUE7RUFBUyx5QkFBQTtFQUNWLG9CQUFBO0VBQ0EsaUJBQUE7RUFDQSxZQUFBOztBZXJXQSxHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0Q7RUFDQyx5QkFBQTtFQUNBLFVBQUE7RUFDQSxXQUFBOztBQXJHRixHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQztFQUNDLGtCQUFBO0VBQ0EscUJBQUE7RUFHQSxjQUFBOztBQUVBLEdBaEtGLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBT0U7RUFDQSwwQkFBQTs7QUFFQSxHQW5LSCxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQUdDO0VBQ0EsYUFBQTs7QUFKRixHQWhLRixnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQU9BO0VmQUosMEJBQUE7RUFBaUMsb0NBQUE7RUFDakMsdUJBQUE7RUFBOEIsNkJBQUE7RUFDOUIsa0JBQUE7RUFBeUIsNEJBQUE7RWVBcEIsY0FBQTs7QUFFQSxHQTNLSixnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQU9FLHNCQU9BLHFCQUlFO0VBQ0EsK0JBQUE7O0FBWkgsR0FoS0YsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0FPRSxzQkFPQSxxQkFRQztFQUNDLHNCQUFBOztBQUtILEdBckxGLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBNEJHO0FBQUssR0FyTFQsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0E0QlU7RUFDUixtQkFBQTtFQUNBLHNCQUFBOztBQXRJSixHQWpEQyxnQkE0QkEsS0FxQkMsS0FrR0QsR0FNQyxHQWtDQztFQUNDLFVBQUE7O0FBM0lKLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUM7RUFDQyxVQUFBO0VBQ0EscUJBQUE7RUFDQSxlQUFBO0VBQ0EscUJBQUE7O0FBbEpMLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUMsR0FPQztFQUNDLGVBQUE7RUFDQSxtQkFBQTs7QUF2Sk4sR0FqREMsZ0JBNEJBLEtBcUJDLEtBa0dELEdBTUMsR0FrQ0MsR0FJQyxHQVlDO0FBMUpMLEdBakRDLGdCQTRCQSxLQXFCQyxLQWtHRCxHQU1DLEdBa0NDLEdBSUMsR0FhQztFQUNDLGVBQUE7RUFDQSxTQUFBO0VBQ0Esc0JBQUE7RUFDQSxzQkFBQTtFQ2xTUCxrQkFBQTtFQUNBLG1CQUFBO0VBRUEsb0JBQUE7RUFDQSxvQkFBQTs7QUR3U0EsR0ExTkUsZ0JBME5BO0VBQ0QsZ0JBQUE7O0FBSUQsR0EvTkUsZ0JBK05EO0VBQ0EsWUFBQTtFQUNBLFlBQUE7RUFDQSxnQkFBQTtFQUNBLGdCQUFBO0VBQ0Esa0JBQUE7O0FBTEQsR0EvTkUsZ0JBK05ELE1BT0E7RUN4VEQsa0JBQUE7RUFDQSxrQkFBQTtFQUVBLG9CQUFBO0VBQ0Esb0JBQUE7RURzVEUscUJBQUE7RUFDQSxtQkFBQTtFQUNBLDZCQUFBO0VBQ0EsYUFBQTtFQUNBLG9CQUFBOztBQWJGLEdBL05FLGdCQStORCxNQWdCQTtFQUVDLG9CQUFBO0VBQ0EsZ0JBQUE7O0FBbkJGLEdBL05FLGdCQStORCxNQWdCQSxHQUtDO0VBQ0MsaUJBQUE7RUFDQSxTQUFBO0VBQ0EscUJBQUE7O0FBR0QsR0ExUEEsZ0JBK05ELE1BZ0JBLEdBV0c7RUFDRCxrQkFBQTs7QUE1QkgsR0EvTkUsZ0JBK05ELE1BZ0JBLEdBZUM7RUFDQyxXQUFBO0VBQ0EsVUFBQTtFQUNBLFdBQUE7RUFDQSxpQkFBQTtFQUNBLDBCQUFBO0VBQ0EsbUJBQUE7RUFDQSxtQkFBQTtFZmxFRiw4QkFBQTtFQUNBLDJCQUFBO0VBQ0Esc0JBQUE7O0FlMEJELEdBL05FLGdCQStORCxNQWdCQSxHQWVDLEdBVUM7RUFDQyxnQkFBQTtFQUNBLFlBQUE7RUFDQSxzQkFBQTs7QUE1Q0osR0EvTkUsZ0JBK05ELE1BZ0JBLEdBZ0NDO0VBQ0MsaUJBQUE7RUFDQSxZQUFBO0VBQ0Esb0JBQUE7O0FBbkRILEdBL05FLGdCQStORCxNQWdCQSxHQWdDQyxHQUtDO0VBQ0Msa0JBQUE7O0FBR0QsR0F4UkQsZ0JBK05ELE1BZ0JBLEdBZ0NDLEdBU0U7RUFDQSxTQUFTLE9BQVQ7RUFDQSxjQUFBO0VBQ0EsV0FBQTtFQUNBLFlBQUE7RUFDQSxTQUFBO0VBQ0EsUUFBQTs7QUFPTDtBQUNBLGdCQUFpQixTQUFRO0FBQ3pCO0VmaElFLDBCQUFBO0VBQWlDLG9DQUFBO0VBQ2pDLHVCQUFBO0VBQThCLDZCQUFBO0VBQzlCLGtCQUFBO0VBQXlCLDRCQUFBO0VlZ0kxQixzQkFBQTtFQzNYQSxrQkFBQTtFQUNBLG1CQUFBO0VBRUEsb0JBQUE7RUFDQSxvQkFBQTs7QUQyWEQsZ0JBQWlCLFNBQVE7QUFDekIsV0FBWTtBQUNaO0VDallDLGtCQUFBO0VBQ0EsbUJBQUE7RUFFQSxvQkFBQTtFQUNBLG9CQUFBO0VEK1hBLGdKQUFBOztBQUdELFdBQVk7RUFDWCxZQUFBO0VBQ0EsVUFBQTtFQUNBLFNBQUE7O0FBR0QsZ0JBQWlCLFNBQVE7RWZ2SHZCLDhCQUFBO0VBQ0EsMkJBQUE7RUFDQSxzQkFBQTtFZXVIRCxjQUFBO0VBQ0EsYUFBQTtFQUNBLFdBQUE7RUFDQSxpQkFBQTtFQUNBLFNBQUE7RUFDQSxZQUFBO0VBQ0EsYUFBQTtFQUNBLGdCQUFBO0VBQ0EsV0FBQTtFQUNBLGdCQUFBO0VBQ0EsaUJBQUE7RUFDQSxjQUFBOztBQUdELGlCQUFpQjtFQUNoQixVQUFBO0VBQ0EsY0FBQTtFQzlaQSxlQUFBO0VBQ0EsbUJBQUE7RUFFQSxtQkFBQTtFQUNBLG9CQUFBO0VEa2FBLGdKQUFBOztBQVZELGlCQUFpQixpQkFJaEI7RUFDQyxjQUFBO0VBQ0EsbUJBQUE7O0FBTUQsaUJBWmdCLGlCQVlkLEtBQUk7RUFDTCxtQkFBQTs7O0FBS0Y7RUFDQyxvQkFBQTs7QUFERCx1QkFHQyxTQUFTO0VBQ1IsbUJBQUE7RUFDQSxpQkFBQTs7QUFMRix1QkFRQztFQUVDLFlBQUE7RUFHQSxnQkFBQTs7QUFJRjtFQUNDLGVBQUE7RUFDQSxNQUFBO0VBQ0EsV0FBQTtFQUNBLFdBQUE7O0FBSkQsZ0JBTUM7RUFDQyxpQkFBQTs7QUFQRixnQkFNQyxrQkFHQztFQUNDLGdCQUFBOztBQVZILGdCQU1DLGtCQUdDLE9BR0M7RUFDQyxnQkFBQTs7QUFPSjtFQUNDLGtCQUFBO0VBQ0EsVUFBQTtFQUNBLFVBQUE7O0FBRUEsS0FBQztFQUNBLGFBQUEifQ== */
diff --git a/sources/samples/img/github-top.png b/sources/samples/img/github-top.png
new file mode 100644 (file)
index 0000000..7b9cbb1
Binary files /dev/null and b/sources/samples/img/github-top.png differ
diff --git a/sources/samples/img/header-bg.png b/sources/samples/img/header-bg.png
new file mode 100644 (file)
index 0000000..a14166a
Binary files /dev/null and b/sources/samples/img/header-bg.png differ
diff --git a/sources/samples/img/header-separator.png b/sources/samples/img/header-separator.png
new file mode 100644 (file)
index 0000000..8c4fb9b
Binary files /dev/null and b/sources/samples/img/header-separator.png differ
diff --git a/sources/samples/img/logo.png b/sources/samples/img/logo.png
new file mode 100644 (file)
index 0000000..96d86e2
Binary files /dev/null and b/sources/samples/img/logo.png differ
diff --git a/sources/samples/img/navigation-tip.png b/sources/samples/img/navigation-tip.png
new file mode 100644 (file)
index 0000000..2286114
Binary files /dev/null and b/sources/samples/img/navigation-tip.png differ
diff --git a/sources/samples/index.html b/sources/samples/index.html
new file mode 100644 (file)
index 0000000..3d274cf
--- /dev/null
@@ -0,0 +1,128 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>CKEditor Sample</title>
+       <script src="../ckeditor.js"></script>
+       <script src="js/sample.js"></script>
+       <link rel="stylesheet" href="css/samples.css">
+       <link rel="stylesheet" href="toolbarconfigurator/lib/codemirror/neo.css">
+</head>
+<body id="main">
+
+<nav class="navigation-a">
+       <div class="grid-container">
+               <ul class="navigation-a-left grid-width-70">
+                       <li><a href="http://ckeditor.com">Project Homepage</a></li>
+                       <li><a href="http://dev.ckeditor.com/">I found a bug</a></li>
+                       <li><a href="http://github.com/ckeditor/ckeditor-dev" class="icon-pos-right icon-navigation-a-github">Fork CKEditor on GitHub</a></li>
+               </ul>
+               <ul class="navigation-a-right grid-width-30">
+                       <li><a href="http://ckeditor.com/blog-list">CKEditor Blog</a></li>
+               </ul>
+       </div>
+</nav>
+
+<header class="header-a">
+       <div class="grid-container">
+               <h1 class="header-a-logo grid-width-30">
+                       <a href="index.html"><img src="img/logo.png" alt="CKEditor Sample"></a>
+               </h1>
+
+               <nav class="navigation-b grid-width-70">
+                       <ul>
+                               <li><a href="index.html" class="button-a button-a-background">Start</a></li>
+                               <li><a href="toolbarconfigurator/index.html" class="button-a">Toolbar configurator <span class="balloon-a balloon-a-nw">Edit your toolbar now!</span></a></li>
+                       </ul>
+               </nav>
+       </div>
+</header>
+
+<main>
+       <div class="adjoined-top">
+               <div class="grid-container">
+                       <div class="content grid-width-100">
+                               <h1>Congratulations!</h1>
+                               <p>
+                                       If you can see CKEditor below, it means that the installation succeeded.
+                                       You can now try out your new editor version, see its features, and when you are ready to move on, check some of the <a href="#sample-customize">most useful resources</a> recommended below.
+                               </p>
+                       </div>
+               </div>
+       </div>
+       <div class="adjoined-bottom">
+               <div class="grid-container">
+                       <div class="grid-width-100">
+                               <div id="editor">
+                                       <h1>Hello world!</h1>
+                                       <p>I'm an instance of <a href="http://ckeditor.com">CKEditor</a>.</p>
+                               </div>
+                       </div>
+               </div>
+       </div>
+
+       <div class="grid-container">
+               <div class="content grid-width-100">
+                       <section id="sample-customize">
+                               <h2>Customize Your Editor</h2>
+                               <p>Modular build and <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">numerous configuration options</a> give you nearly endless possibilities to customize CKEditor. Replace the content of your <code><a href="../config.js">config.js</a></code> file with the following code and refresh this page (<strong>remember to clear the browser cache</strong>)!</p>
+               <pre class="cm-s-neo CodeMirror"><code><span style="padding-right: 0.1px;"><span class="cm-variable">CKEDITOR</span>.<span class="cm-property">editorConfig</span> <span class="cm-operator">=</span> <span class="cm-keyword">function</span>( <span class="cm-def">config</span> ) {</span>
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">language</span> <span class="cm-operator">=</span> <span class="cm-string">'es'</span>;</span>
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">uiColor</span> <span class="cm-operator">=</span> <span class="cm-string">'#F7B42C'</span>;</span>
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">height</span> <span class="cm-operator">=</span> <span class="cm-number">300</span>;</span>
+<span style="padding-right: 0.1px;"><span class="cm-tab">      </span><span class="cm-variable-2">config</span>.<span class="cm-property">toolbarCanCollapse</span> <span class="cm-operator">=</span> <span class="cm-atom">true</span>;</span>
+<span style="padding-right: 0.1px;">};</span></code></pre>
+                       </section>
+
+                       <section>
+                               <h2>Toolbar Configuration</h2>
+                               <p>If you want to reorder toolbar buttons or remove some of them, check <a href="toolbarconfigurator/index.html">this handy tool</a>!</p>
+                       </section>
+
+                       <section>
+                               <h2>More Samples!</h2>
+                               <p>Visit the <a href="http://sdk.ckeditor.com">CKEditor SDK</a> for a huge collection of samples showcasing editor features, with source code readily available to copy and use in your own implementation.</p>
+                       </section>
+
+                       <section>
+                               <h2>Developer's Guide</h2>
+                               <p>The most important resource for all developers working with CKEditor, integrating it with their websites and applications, and customizing to their needs. You can start from here:</p>
+                               <ul>
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_installation">Getting Started</a> &ndash; Explains most crucial editor concepts and practices as well as the installation process and integration with your website.</li>
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_advanced_installation">Advanced Installation Concepts</a> &ndash; Describes how to upgrade, install additional components (plugins, skins), or create a custom build.</li>
+                               </ul>
+                                       <p>When you have the basics sorted out, feel free to browse some more advanced sections like:</p>
+                               <ul>
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/dev_features">Functionality Overview</a> &ndash; Descriptions and samples of various editor features.</li>
+                                       <li><a href="http://docs.ckeditor.com/#!/guide/plugin_sdk_intro">Plugin SDK</a>, <a href="http://docs.ckeditor.com/#!/guide/widget_sdk_intro">Widget SDK</a>, and <a href="http://docs.ckeditor.com/#!/guide/skin_sdk_intro">Skin SDK</a> &ndash; Useful when you want to create your own editor components.</li>
+                               </ul>
+                       </section>
+
+                       <section>
+                               <h2>CKEditor JavaScript API</h2>
+                               <p>CKEditor boasts a rich <a href="http://docs.ckeditor.com/#!/api">JavaScript API</a> that you can use to adjust the editor to your needs and integrate it with your website or application.</p>
+                       </section>
+               </div>
+       </div>
+</main>
+
+<footer class="footer-a grid-container">
+       <div class="grid-container">
+               <p class="grid-width-100">
+                       CKEditor &ndash; The text editor for the Internet &ndash; <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p class="grid-width-100" id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> &ndash; Frederico Knabben. All rights reserved.
+               </p>
+       </div>
+</footer>
+<script>
+       initSample();
+</script>
+
+</body>
+</html>
diff --git a/sources/samples/js/sample.js b/sources/samples/js/sample.js
new file mode 100644 (file)
index 0000000..70cf8d6
--- /dev/null
@@ -0,0 +1,54 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/* exported initSample */
+
+if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )
+       CKEDITOR.tools.enableHtml5Elements( document );
+
+// The trick to keep the editor in the sample quite small
+// unless user specified own height.
+CKEDITOR.config.height = 150;
+CKEDITOR.config.width = 'auto';
+
+var initSample = ( function() {
+       var wysiwygareaAvailable = isWysiwygareaAvailable(),
+               isBBCodeBuiltIn = !!CKEDITOR.plugins.get( 'bbcode' );
+
+       return function() {
+               var editorElement = CKEDITOR.document.getById( 'editor' );
+
+               // :(((
+               if ( isBBCodeBuiltIn ) {
+                       editorElement.setHtml(
+                               'Hello world!\n\n' +
+                               'I\'m an instance of [url=http://ckeditor.com]CKEditor[/url].'
+                       );
+               }
+
+               // Depending on the wysiwygare plugin availability initialize classic or inline editor.
+               if ( wysiwygareaAvailable ) {
+                       CKEDITOR.replace( 'editor' );
+               } else {
+                       editorElement.setAttribute( 'contenteditable', 'true' );
+                       CKEDITOR.inline( 'editor' );
+
+                       // TODO we can consider displaying some info box that
+                       // without wysiwygarea the classic editor may not work.
+               }
+       };
+
+       function isWysiwygareaAvailable() {
+               // If in development mode, then the wysiwygarea must be available.
+               // Split REV into two strings so builder does not replace it :D.
+               if ( CKEDITOR.revision == ( '%RE' + 'V%' ) ) {
+                       return true;
+               }
+
+               return !!CKEDITOR.plugins.get( 'wysiwygarea' );
+       }
+} )();
+
+// %LEAVE_UNMINIFIED% %REMOVE_LINE%
diff --git a/sources/samples/js/sf.js b/sources/samples/js/sf.js
new file mode 100644 (file)
index 0000000..d42dbd8
--- /dev/null
@@ -0,0 +1,673 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+/* exported SF */
+
+'use strict';
+
+var SF = ( function() {
+       var SF = {};
+
+       SF.attachListener = function( elem, evtName, callback ) {
+               if ( elem.addEventListener ) {
+                       elem.addEventListener( evtName, callback, false );
+               } else if ( elem.attachEvent ) {
+                       elem.attachEvent( 'on' + evtName , function() {
+                               callback.apply( elem, arguments );
+                       } );
+               } else {
+                       throw new Error( 'Could not attach event.' );
+               }
+       };
+
+       SF.indexOf = ( function() {
+               var indexOf = Array.prototype.indexOf;
+
+               if ( indexOf === 'function' ) {
+                       return function( arr, elem ) {
+                               return indexOf.call( arr, elem );
+                       };
+               } else {
+                       return function( arr, elem ) {
+                               var max = arr.length;
+
+                               for ( var i = 0; i < max; i++ ) {
+                                       if ( arr[ i ] === elem ) {
+                                               return i;
+                                       }
+                               }
+
+                               return -1;
+                       };
+               }
+
+       }() );
+
+       SF.accept = function( node, visitor ) {
+               var children;
+
+               // Handling node as a node and array
+               if ( node.children ) {
+                       children = node.children;
+
+                       visitor( node );
+               } else if ( typeof node.length === 'number' ) {
+                       children = node;
+               }
+
+               var i = children ? ( children.length || 0 ) : 0;
+               while ( i-- ) {
+                       SF.accept( children[ i ], visitor );
+               }
+       };
+
+       SF.getByClass = ( function(  ) {
+               var getByClass = document.getElementsByClassName;
+               if ( typeof getByClass === 'function' ) {
+                       return function( root, className ) {
+                               if ( typeof root === 'string' ) {
+                                       className = root;
+                                       root = document;
+                               }
+
+                               return getByClass.call( root, className );
+                       };
+               }
+
+               return function( root, className ) {
+                       if ( typeof root === 'string' ) {
+                               className = root;
+                               root = document.getElementsByTagName( 'html' )[ 0 ];
+                       }
+                       var results = [];
+
+                       SF.accept( root, function( elem ) {
+                               if ( SF.classList.contains( elem, className ) ) {
+                                       results.push( elem );
+                               }
+                       } );
+
+                       return results;
+               };
+       }() );
+
+       SF.classList = {};
+
+       SF.classList.add = function( elem, className ) {
+               var classes = parseClasses( elem );
+               classes.push( className );
+
+               elem.attributes.setNamedItem( createClassAttr( classes ) );
+       };
+
+       SF.classList.remove = function( elem, className ) {
+               var classes = parseClasses( elem, className ),
+                       foundAt = SF.indexOf( classes, className );
+
+               if ( foundAt === -1 ) {
+                       return;
+               }
+
+               classes.splice( foundAt, 1 );
+               elem.attributes.setNamedItem( createClassAttr( classes ) );
+       };
+
+       SF.classList.contains = function( elem, className ) {
+               return findIndex( elem, className ) !== -1;
+       };
+
+       SF.classList.toggle = function( elem, className ) {
+               this.contains( elem, className ) ? this.remove( elem, className ) : this.add( elem, className );
+       };
+
+       function findIndex( elem, className ) {
+               return SF.indexOf( parseClasses( elem ), className );
+       }
+
+       function parseClasses( elem ) {
+               var classAttr = elem.attributes ? elem.attributes.getNamedItem( 'class' ) : null;
+
+               return classAttr ? classAttr.value.split( ' ' ) : [];
+       }
+
+       function createClassAttr( classesArray ) {
+               var attr = document.createAttribute( 'class' );
+
+               attr.value = classesArray.join( ' ' );
+
+               return attr;
+       }
+
+       return SF;
+}() );
+
+/* global SF, picoModal */
+
+'use strict';
+
+( function() {
+       // Purges all styles in passed object.
+       function purgeStyles( styles ) {
+               for ( var i in styles ) {
+                       delete styles[ i ];
+               }
+       }
+
+       SF.modal = function( config ) {
+               // Modal should use the same style set as the rest of the page (.content component).
+               config.modalClass = 'modal content';
+               config.closeClass = 'modal-close';
+
+               // Purge all pre-defined pico styles. Use the lessfile instead.
+               config.modalStyles = purgeStyles;
+
+               // Close button styles are customized via lessfile.
+               config.closeStyles = purgeStyles;
+
+               var userDefinedAfterCreate = config.afterCreate,
+                       userDefinedAfterClose = config.afterClose;
+
+               // Close modal on ESC key.
+               function onKeyDown( event ) {
+                       if ( event.keyCode == 27 ) {
+                               modal.close();
+                       }
+               }
+
+               // Use afterCreate as a config option rather than function chain.
+               config.afterCreate = function( modal ) {
+                       userDefinedAfterCreate && userDefinedAfterCreate( modal );
+
+                       window.addEventListener( 'keydown', onKeyDown );
+               };
+
+               // Use afterClose as a config option rather than function chain.
+               config.afterClose = function( modal ) {
+                       userDefinedAfterClose && userDefinedAfterClose( modal );
+
+                       window.removeEventListener( 'keydown', onKeyDown );
+               };
+
+               var modal = new picoModal( config )
+                       .afterCreate( config.afterCreate )
+                       .afterClose( config.afterClose );
+
+               return modal;
+       };
+} )();
+'use strict';
+
+( function() {
+       // All .tree-a elements in DOM.
+       var expanders = SF.getByClass( 'toggler' );
+
+       var i = expanders.length;
+       while ( i-- ) {
+               var expander = expanders[ i ];
+
+               SF.attachListener( expander, 'click', function() {
+                       var containsIcon = SF.classList.contains( this, 'icon-toggler-expanded' ) || SF.classList.contains( this, 'icon-toggler-collapsed' ),
+                               related = document.getElementById( this.getAttribute( 'data-for' ) );
+
+                       SF.classList.toggle( this, 'collapsed' );
+
+                       if ( SF.classList.contains( this, 'collapsed' ) ) {
+                               SF.classList.add( related, 'collapsed' );
+                               if ( containsIcon ) {
+                                       SF.classList.remove( this, 'icon-toggler-expanded' );
+                                       SF.classList.add( this, 'icon-toggler-collapsed' );
+                               }
+                       } else {
+                               SF.classList.remove( related, 'collapsed' );
+                               if ( containsIcon ) {
+                                       SF.classList.remove( this, 'icon-toggler-collapsed' );
+                                       SF.classList.add( this, 'icon-toggler-expanded' );
+                               }
+                       }
+               } );
+       }
+} )();
+/* global SF */
+
+'use strict';
+
+( function() {
+       // All .tree-a elements in DOM.
+       var trees = SF.getByClass( 'tree-a' );
+
+       for ( var i = trees.length; i--; ) {
+               var tree = trees[ i ];
+
+               SF.attachListener( tree, 'click', function( evt ) {
+                       var target = evt.target || evt.srcElement;
+
+                       // Collapse or expand item groups.
+                       if ( target.nodeName === 'H2' && !SF.classList.contains( target, 'tree-a-no-sub' ) ) {
+                               SF.classList.toggle( target, 'tree-a-active' );
+                       }
+               } );
+       }
+} )();
+// jshint ignore:start
+// jscs:disable
+/**
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/**
+ * A self-contained modal library
+ */
+(function(window, document) {
+    "use strict";
+
+    /** Returns whether a value is a dom node */
+    function isNode(value) {
+        if ( typeof Node === "object" ) {
+            return value instanceof Node;
+        }
+        else {
+            return value &&
+                typeof value === "object" &&
+                typeof value.nodeType === "number";
+        }
+    }
+
+    /** Returns whether a value is a string */
+    function isString(value) {
+        return typeof value === "string";
+    }
+
+    /**
+     * Generates observable objects that can be watched and triggered
+     */
+    function observable() {
+        var callbacks = [];
+        return {
+            watch: callbacks.push.bind(callbacks),
+            trigger: function( modal ) {
+
+                var unprevented = true;
+                var event = {
+                    preventDefault: function preventDefault () {
+                        unprevented = false;
+                    }
+                };
+
+                for (var i = 0; i < callbacks.length; i++) {
+                    callbacks[i](modal, event);
+                }
+
+                return unprevented;
+            }
+        };
+    }
+
+
+    /**
+     * A small interface for creating and managing a dom element
+     */
+    function Elem( elem ) {
+        this.elem = elem;
+    }
+
+    /**
+     * Creates a new div
+     */
+    Elem.div = function ( parent ) {
+        var elem = document.createElement('div');
+        (parent || document.body).appendChild(elem);
+        return new Elem(elem);
+    };
+
+    Elem.prototype = {
+
+        /** Creates a child of this node */
+        child: function () {
+            return Elem.div(this.elem);
+        },
+
+        /** Applies a set of styles to an element */
+        stylize: function(styles) {
+            styles = styles || {};
+
+            if ( typeof styles.opacity !== "undefined" ) {
+                styles.filter =
+                    "alpha(opacity=" + (styles.opacity * 100) + ")";
+            }
+
+            for (var prop in styles) {
+                if (styles.hasOwnProperty(prop)) {
+                    this.elem.style[prop] = styles[prop];
+                }
+            }
+
+            return this;
+        },
+
+        /** Adds a class name */
+        clazz: function (clazz) {
+            this.elem.className += " " + clazz;
+            return this;
+        },
+
+        /** Sets the HTML */
+        html: function (content) {
+            if ( isNode(content) ) {
+                this.elem.appendChild( content );
+            }
+            else {
+                this.elem.innerHTML = content;
+            }
+            return this;
+        },
+
+        /** Adds a click handler to this element */
+        onClick: function(callback) {
+            this.elem.addEventListener('click', callback);
+            return this;
+        },
+
+        /** Removes this element from the DOM */
+        destroy: function() {
+            document.body.removeChild(this.elem);
+        },
+
+        /** Hides this element */
+        hide: function() {
+            this.elem.style.display = "none";
+        },
+
+        /** Shows this element */
+        show: function() {
+            this.elem.style.display = "block";
+        },
+
+        /** Sets an attribute on this element */
+        attr: function ( name, value ) {
+            this.elem.setAttribute(name, value);
+            return this;
+        },
+
+        /** Executes a callback on all the ancestors of an element */
+        anyAncestor: function ( predicate ) {
+            var elem = this.elem;
+            while ( elem ) {
+                if ( predicate( new Elem(elem) ) ) {
+                    return true;
+                }
+                else {
+                    elem = elem.parentNode;
+                }
+            }
+            return false;
+        }
+    };
+
+
+    /** Generates the grey-out effect */
+    function buildOverlay( getOption, close ) {
+        return Elem.div()
+            .clazz("pico-overlay")
+            .clazz( getOption("overlayClass", "") )
+            .stylize({
+                display: "block",
+                position: "fixed",
+                top: "0px",
+                left: "0px",
+                height: "100%",
+                width: "100%",
+                zIndex: 10000
+            })
+            .stylize(getOption('overlayStyles', {
+                opacity: 0.5,
+                background: "#000"
+            }))
+            .onClick(function () {
+                if ( getOption('overlayClose', true) ) {
+                    close();
+                }
+            });
+    }
+
+    /** Builds the content of a modal */
+    function buildModal( getOption, close ) {
+        var width = getOption('width', 'auto');
+        if ( typeof width === "number" ) {
+            width = "" + width + "px";
+        }
+
+        var elem = Elem.div()
+            .clazz("pico-content")
+            .clazz( getOption("modalClass", "") )
+            .stylize({
+                display: 'block',
+                position: 'fixed',
+                zIndex: 10001,
+                left: "50%",
+                top: "50px",
+                width: width,
+                '-ms-transform': 'translateX(-50%)',
+                '-moz-transform': 'translateX(-50%)',
+                '-webkit-transform': 'translateX(-50%)',
+                '-o-transform': 'translateX(-50%)',
+                'transform': 'translateX(-50%)'
+            })
+            .stylize(getOption('modalStyles', {
+                backgroundColor: "white",
+                padding: "20px",
+                borderRadius: "5px"
+            }))
+            .html( getOption('content') )
+            .attr("role", "dialog")
+            .onClick(function (event) {
+                var isCloseClick = new Elem(event.target)
+                    .anyAncestor(function (elem) {
+                        return /\bpico-close\b/.test(elem.elem.className);
+                    });
+                if ( isCloseClick ) {
+                    close();
+                }
+            });
+
+        return elem;
+    }
+
+    /** Builds the close button */
+    function buildClose ( elem, getOption ) {
+        if ( getOption('closeButton', true) ) {
+            return elem.child()
+                .html( getOption('closeHtml', "&#xD7;") )
+                .clazz("pico-close")
+                .clazz( getOption("closeClass") )
+                .stylize( getOption('closeStyles', {
+                    borderRadius: "2px",
+                    cursor: "pointer",
+                    height: "15px",
+                    width: "15px",
+                    position: "absolute",
+                    top: "5px",
+                    right: "5px",
+                    fontSize: "16px",
+                    textAlign: "center",
+                    lineHeight: "15px",
+                    background: "#CCC"
+                }) );
+        }
+    }
+
+    /** Builds a method that calls a method and returns an element */
+    function buildElemAccessor( builder ) {
+        return function () {
+            return builder().elem;
+        };
+    }
+
+
+    /**
+     * Displays a modal
+     */
+    function picoModal(options) {
+
+        if ( isString(options) || isNode(options) ) {
+            options = { content: options };
+        }
+
+        var afterCreateEvent = observable();
+        var beforeShowEvent = observable();
+        var afterShowEvent = observable();
+        var beforeCloseEvent = observable();
+        var afterCloseEvent = observable();
+
+        /**
+         * Returns a named option if it has been explicitly defined. Otherwise,
+         * it returns the given default value
+         */
+        function getOption ( opt, defaultValue ) {
+            var value = options[opt];
+            if ( typeof value === "function" ) {
+                value = value( defaultValue );
+            }
+            return value === undefined ? defaultValue : value;
+        }
+
+        /** Hides this modal */
+        function forceClose () {
+            shadowElem().hide();
+            modalElem().hide();
+            afterCloseEvent.trigger(iface);
+        }
+
+        /** Gracefully hides this modal */
+        function close () {
+            if ( beforeCloseEvent.trigger(iface) ) {
+                forceClose();
+            }
+        }
+
+        /** Wraps a method so it returns the modal interface */
+        function returnIface ( callback ) {
+            return function () {
+                callback.apply(this, arguments);
+                return iface;
+            };
+        }
+
+
+        // The constructed dom nodes
+        var built;
+
+        /** Builds a method that calls a method and returns an element */
+        function build ( name ) {
+            if ( !built ) {
+                var modal = buildModal(getOption, close);
+                built = {
+                    modal: modal,
+                    overlay: buildOverlay(getOption, close),
+                    close: buildClose(modal, getOption)
+                };
+                afterCreateEvent.trigger(iface);
+            }
+            return built[name];
+        }
+
+        var modalElem = build.bind(window, 'modal');
+        var shadowElem = build.bind(window, 'overlay');
+        var closeElem = build.bind(window, 'close');
+
+
+        var iface = {
+
+            /** Returns the wrapping modal element */
+            modalElem: buildElemAccessor(modalElem),
+
+            /** Returns the close button element */
+            closeElem: buildElemAccessor(closeElem),
+
+            /** Returns the overlay element */
+            overlayElem: buildElemAccessor(shadowElem),
+
+            /** Shows this modal */
+            show: function () {
+                if ( beforeShowEvent.trigger(iface) ) {
+                    shadowElem().show();
+                    closeElem();
+                    modalElem().show();
+                    afterShowEvent.trigger(iface);
+                }
+                return this;
+            },
+
+            /** Hides this modal */
+            close: returnIface(close),
+
+            /**
+             * Force closes this modal. This will not call beforeClose
+             * events and will just immediately hide the modal
+             */
+            forceClose: returnIface(forceClose),
+
+            /** Destroys this modal */
+            destroy: function () {
+                modalElem = modalElem().destroy();
+                shadowElem = shadowElem().destroy();
+                closeElem = undefined;
+            },
+
+            /**
+             * Updates the options for this modal. This will only let you
+             * change options that are re-evaluted regularly, such as
+             * `overlayClose`.
+             */
+            options: function ( opts ) {
+                options = opts;
+            },
+
+            /** Executes after the DOM nodes are created */
+            afterCreate: returnIface(afterCreateEvent.watch),
+
+            /** Executes a callback before this modal is closed */
+            beforeShow: returnIface(beforeShowEvent.watch),
+
+            /** Executes a callback after this modal is shown */
+            afterShow: returnIface(afterShowEvent.watch),
+
+            /** Executes a callback before this modal is closed */
+            beforeClose: returnIface(beforeCloseEvent.watch),
+
+            /** Executes a callback after this modal is closed */
+            afterClose: returnIface(afterCloseEvent.watch)
+        };
+
+        return iface;
+    }
+
+    if ( typeof window.define === "function" && window.define.amd ) {
+        window.define(function () {
+            return picoModal;
+        });
+    }
+    else {
+        window.picoModal = picoModal;
+    }
+
+}(window, document));
+
+// jscs:enable
+// jshint ignore:end
diff --git a/sources/samples/old/ajax.html b/sources/samples/old/ajax.html
new file mode 100644 (file)
index 0000000..852a086
--- /dev/null
@@ -0,0 +1,85 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Ajax &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+       <script>
+
+               var editor, html = '';
+
+               function createEditor() {
+                       if ( editor )
+                               return;
+
+                       // Create a new editor inside the <div id="editor">, setting its value to html
+                       var config = {};
+                       editor = CKEDITOR.appendTo( 'editor', config, html );
+               }
+
+               function removeEditor() {
+                       if ( !editor )
+                               return;
+
+                       // Retrieve the editor contents. In an Ajax application, this data would be
+                       // sent to the server or used in any other way.
+                       document.getElementById( 'editorcontents' ).innerHTML = html = editor.getData();
+                       document.getElementById( 'contents' ).style.display = '';
+
+                       // Destroy the editor.
+                       editor.destroy();
+                       editor = null;
+               }
+
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Create and Destroy Editor Instances for Ajax Applications
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/saveajax.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to create and destroy CKEditor instances on the fly. After the removal of CKEditor the content created inside the editing
+                       area will be displayed in a <code>&lt;div&gt;</code> element.
+               </p>
+               <p>
+                       For details of how to create this setup check the source code of this sample page
+                       for JavaScript code responsible for the creation and destruction of a CKEditor instance.
+               </p>
+       </div>
+       <p>Click the buttons to create and remove a CKEditor instance.</p>
+       <p>
+               <input onclick="createEditor();" type="button" value="Create Editor">
+               <input onclick="removeEditor();" type="button" value="Remove Editor">
+       </p>
+       <!-- This div will hold the editor. -->
+       <div id="editor">
+       </div>
+       <div id="contents" style="display: none">
+               <p>
+                       Edited Contents:
+               </p>
+               <!-- This div will be used to display the editor contents. -->
+               <div id="editorcontents">
+               </div>
+       </div>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/api.html b/sources/samples/old/api.html
new file mode 100644 (file)
index 0000000..682a719
--- /dev/null
@@ -0,0 +1,210 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>API Usage &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <script>
+
+// The instanceReady event is fired, when an instance of CKEditor has finished
+// its initialization.
+CKEDITOR.on( 'instanceReady', function( ev ) {
+       // Show the editor name and description in the browser status bar.
+       document.getElementById( 'eMessage' ).innerHTML = 'Instance <code>' + ev.editor.name + '<\/code> loaded.';
+
+       // Show this sample buttons.
+       document.getElementById( 'eButtons' ).style.display = 'block';
+});
+
+function InsertHTML() {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+       var value = document.getElementById( 'htmlArea' ).value;
+
+       // Check the active editing mode.
+       if ( editor.mode == 'wysiwyg' )
+       {
+               // Insert HTML code.
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertHtml
+               editor.insertHtml( value );
+       }
+       else
+               alert( 'You must be in WYSIWYG mode!' );
+}
+
+function InsertText() {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+       var value = document.getElementById( 'txtArea' ).value;
+
+       // Check the active editing mode.
+       if ( editor.mode == 'wysiwyg' )
+       {
+               // Insert as plain text.
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-insertText
+               editor.insertText( value );
+       }
+       else
+               alert( 'You must be in WYSIWYG mode!' );
+}
+
+function SetContents() {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+       var value = document.getElementById( 'htmlArea' ).value;
+
+       // Set editor contents (replace current contents).
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setData
+       editor.setData( value );
+}
+
+function GetContents() {
+       // Get the editor instance that you want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+
+       // Get editor contents
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-getData
+       alert( editor.getData() );
+}
+
+function ExecuteCommand( commandName ) {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+
+       // Check the active editing mode.
+       if ( editor.mode == 'wysiwyg' )
+       {
+               // Execute the command.
+               // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-execCommand
+               editor.execCommand( commandName );
+       }
+       else
+               alert( 'You must be in WYSIWYG mode!' );
+}
+
+function CheckDirty() {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+       // Checks whether the current editor contents present changes when compared
+       // to the contents loaded into the editor at startup
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-checkDirty
+       alert( editor.checkDirty() );
+}
+
+function ResetDirty() {
+       // Get the editor instance that we want to interact with.
+       var editor = CKEDITOR.instances.editor1;
+       // Resets the "dirty state" of the editor (see CheckDirty())
+       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-resetDirty
+       editor.resetDirty();
+       alert( 'The "IsDirty" status has been reset' );
+}
+
+function Focus() {
+       CKEDITOR.instances.editor1.focus();
+}
+
+function onFocus() {
+       document.getElementById( 'eMessage' ).innerHTML = '<b>' + this.name + ' is focused </b>';
+}
+
+function onBlur() {
+       document.getElementById( 'eMessage' ).innerHTML = this.name + ' lost focus';
+}
+
+       </script>
+
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Using CKEditor JavaScript API
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/api.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+       <p>
+               This sample shows how to use the
+               <a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.editor">CKEditor JavaScript API</a>
+               to interact with the editor at runtime.
+       </p>
+       <p>
+               For details on how to create this setup check the source code of this sample page.
+       </p>
+       </div>
+
+       <!-- This <div> holds alert messages to be display in the sample page. -->
+       <div id="alerts">
+               <noscript>
+                       <p>
+                               <strong>CKEditor requires JavaScript to run</strong>. In a browser with no JavaScript
+                               support, like yours, you should still see the contents (HTML data) and you should
+                               be able to edit it normally, without a rich editor interface.
+                       </p>
+               </noscript>
+       </div>
+       <form action="../../../samples/sample_posteddata.php" method="post">
+               <textarea cols="100" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+
+               <script>
+                       // Replace the <textarea id="editor1"> with an CKEditor instance.
+                       CKEDITOR.replace( 'editor1', {
+                               on: {
+                                       focus: onFocus,
+                                       blur: onBlur,
+
+                                       // Check for availability of corresponding plugins.
+                                       pluginsLoaded: function( evt ) {
+                                               var doc = CKEDITOR.document, ed = evt.editor;
+                                               if ( !ed.getCommand( 'bold' ) )
+                                                       doc.getById( 'exec-bold' ).hide();
+                                               if ( !ed.getCommand( 'link' ) )
+                                                       doc.getById( 'exec-link' ).hide();
+                                       }
+                               }
+                       });
+               </script>
+
+               <p id="eMessage">
+               </p>
+
+               <div id="eButtons" style="display: none">
+                       <input id="exec-bold" onclick="ExecuteCommand('bold');" type="button" value="Execute &quot;bold&quot; Command">
+                       <input id="exec-link" onclick="ExecuteCommand('link');" type="button" value="Execute &quot;link&quot; Command">
+                       <input onclick="Focus();" type="button" value="Focus">
+                       <br><br>
+                       <input onclick="InsertHTML();" type="button" value="Insert HTML">
+                       <input onclick="SetContents();" type="button" value="Set Editor Contents">
+                       <input onclick="GetContents();" type="button" value="Get Editor Contents (HTML)">
+                       <br>
+                       <textarea cols="100" id="htmlArea" rows="3">&lt;h2&gt;Test&lt;/h2&gt;&lt;p&gt;This is some &lt;a href="/Test1.html"&gt;sample&lt;/a&gt; HTML code.&lt;/p&gt;</textarea>
+                       <br>
+                       <br>
+                       <input onclick="InsertText();" type="button" value="Insert Text">
+                       <br>
+                       <textarea cols="100" id="txtArea" rows="3">   First line with some leading whitespaces.
+
+Second line of text preceded by two line breaks.</textarea>
+                       <br>
+                       <br>
+                       <input onclick="CheckDirty();" type="button" value="checkDirty()">
+                       <input onclick="ResetDirty();" type="button" value="resetDirty()">
+               </div>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/appendto.html b/sources/samples/old/appendto.html
new file mode 100644 (file)
index 0000000..a984704
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Append To Page Element Using JavaScript Code &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Append To Page Element Using JavaScript Code
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.
+       </div>
+       <div id="section1">
+               <div class="description">
+                       <p>
+                               The <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR-method-appendTo">CKEDITOR.appendTo()</a></code> method serves to to place editors inside existing DOM elements. Unlike <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR-method-replace">CKEDITOR.replace()</a></code>,
+                               a target container to be replaced is no longer necessary. A new editor
+                               instance is inserted directly wherever it is desired.
+                       </p>
+<pre class="samples">CKEDITOR.appendTo( '<em>container_id</em>',
+       { /* Configuration options to be used. */ }
+       'Editor content to be used.'
+);</pre>
+               </div>
+               <script>
+
+                       // This call can be placed at any point after the
+                       // DOM element to append CKEditor to or inside the <head><script>
+                       // in a window.onload event handler.
+
+                       // Append a CKEditor instance using the default configuration and the
+                       // provided content to the <div> element of ID "section1".
+                       CKEDITOR.appendTo( 'section1',
+                               null,
+                               '<p>This is some <strong>sample text</strong>. You are using <a href="http://ckeditor.com/">CKEditor</a>.</p>'
+                       );
+
+               </script>
+       </div>
+       <br>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/assets/inlineall/logo.png b/sources/samples/old/assets/inlineall/logo.png
new file mode 100644 (file)
index 0000000..b4d5979
Binary files /dev/null and b/sources/samples/old/assets/inlineall/logo.png differ
diff --git a/sources/samples/old/assets/outputxhtml/outputxhtml.css b/sources/samples/old/assets/outputxhtml/outputxhtml.css
new file mode 100644 (file)
index 0000000..b81e1d7
--- /dev/null
@@ -0,0 +1,204 @@
+/*
+ * Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ *
+ * Styles used by the XHTML 1.1 sample page (xhtml.html).
+ */
+
+/**
+ * Basic definitions for the editing area.
+ */
+body
+{
+       font-family: Arial, Verdana, sans-serif;
+       font-size: 80%;
+       color: #000000;
+       background-color: #ffffff;
+       padding: 5px;
+       margin: 0px;
+}
+
+/**
+ * Core styles.
+ */
+
+.Bold
+{
+       font-weight: bold;
+}
+
+.Italic
+{
+       font-style: italic;
+}
+
+.Underline
+{
+       text-decoration: underline;
+}
+
+.StrikeThrough
+{
+       text-decoration: line-through;
+}
+
+.Subscript
+{
+       vertical-align: sub;
+       font-size: smaller;
+}
+
+.Superscript
+{
+       vertical-align: super;
+       font-size: smaller;
+}
+
+/**
+ * Font faces.
+ */
+
+.FontComic
+{
+       font-family: 'Comic Sans MS';
+}
+
+.FontCourier
+{
+       font-family: 'Courier New';
+}
+
+.FontTimes
+{
+       font-family: 'Times New Roman';
+}
+
+/**
+ * Font sizes.
+ */
+
+.FontSmaller
+{
+       font-size: smaller;
+}
+
+.FontLarger
+{
+       font-size: larger;
+}
+
+.FontSmall
+{
+       font-size: 8pt;
+}
+
+.FontBig
+{
+       font-size: 14pt;
+}
+
+.FontDouble
+{
+       font-size: 200%;
+}
+
+/**
+ * Font colors.
+ */
+.FontColor1
+{
+       color: #ff9900;
+}
+
+.FontColor2
+{
+       color: #0066cc;
+}
+
+.FontColor3
+{
+       color: #ff0000;
+}
+
+.FontColor1BG
+{
+       background-color: #ff9900;
+}
+
+.FontColor2BG
+{
+       background-color: #0066cc;
+}
+
+.FontColor3BG
+{
+       background-color: #ff0000;
+}
+
+/**
+ * Indentation.
+ */
+
+.Indent1
+{
+       margin-left: 40px;
+}
+
+.Indent2
+{
+       margin-left: 80px;
+}
+
+.Indent3
+{
+       margin-left: 120px;
+}
+
+/**
+ * Alignment.
+ */
+
+.JustifyLeft
+{
+       text-align: left;
+}
+
+.JustifyRight
+{
+       text-align: right;
+}
+
+.JustifyCenter
+{
+       text-align: center;
+}
+
+.JustifyFull
+{
+       text-align: justify;
+}
+
+/**
+ * Other.
+ */
+
+code
+{
+       font-family: courier, monospace;
+       background-color: #eeeeee;
+       padding-left: 1px;
+       padding-right: 1px;
+       border: #c0c0c0 1px solid;
+}
+
+kbd
+{
+       padding: 0px 1px 0px 1px;
+       border-width: 1px 2px 2px 1px;
+       border-style: solid;
+}
+
+blockquote
+{
+       color: #808080;
+}
diff --git a/sources/samples/old/assets/posteddata.php b/sources/samples/old/assets/posteddata.php
new file mode 100644 (file)
index 0000000..ca43cc9
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<?php
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+?>
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Sample &mdash; CKEditor</title>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               CKEditor &mdash; Posted Data
+       </h1>
+       <table border="1" cellspacing="0" id="outputSample">
+               <colgroup><col width="120"></colgroup>
+               <thead>
+                       <tr>
+                               <th>Field&nbsp;Name</th>
+                               <th>Value</th>
+                       </tr>
+               </thead>
+<?php
+
+if (!empty($_POST))
+{
+       foreach ( $_POST as $key => $value )
+       {
+               if ( ( !is_string($value) && !is_numeric($value) ) || !is_string($key) )
+                       continue;
+
+               if ( get_magic_quotes_gpc() )
+                       $value = htmlspecialchars( stripslashes((string)$value) );
+               else
+                       $value = htmlspecialchars( (string)$value );
+?>
+               <tr>
+                       <th style="vertical-align: top"><?php echo htmlspecialchars( (string)$key ); ?></th>
+                       <td><pre class="samples"><?php echo $value; ?></pre></td>
+               </tr>
+       <?php
+       }
+}
+?>
+       </table>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/assets/sample.jpg b/sources/samples/old/assets/sample.jpg
new file mode 100644 (file)
index 0000000..9498271
Binary files /dev/null and b/sources/samples/old/assets/sample.jpg differ
diff --git a/sources/samples/old/assets/uilanguages/languages.js b/sources/samples/old/assets/uilanguages/languages.js
new file mode 100644 (file)
index 0000000..df6b2dc
--- /dev/null
@@ -0,0 +1,92 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+/* exported CKEDITOR_LANGS */
+
+var CKEDITOR_LANGS = ( function() {
+       var langs = {
+               af: 'Afrikaans',
+               ar: 'Arabic',
+               az: 'Azerbaijani',
+               bg: 'Bulgarian',
+               bn: 'Bengali/Bangla',
+               bs: 'Bosnian',
+               ca: 'Catalan',
+               cs: 'Czech',
+               cy: 'Welsh',
+               da: 'Danish',
+               de: 'German',
+               'de-ch': 'German (Switzerland)',
+               el: 'Greek',
+               en: 'English',
+               'en-au': 'English (Australia)',
+               'en-ca': 'English (Canadian)',
+               'en-gb': 'English (United Kingdom)',
+               eo: 'Esperanto',
+               es: 'Spanish',
+               et: 'Estonian',
+               eu: 'Basque',
+               fa: 'Persian',
+               fi: 'Finnish',
+               fo: 'Faroese',
+               fr: 'French',
+               'fr-ca': 'French (Canada)',
+               gl: 'Galician',
+               gu: 'Gujarati',
+               he: 'Hebrew',
+               hi: 'Hindi',
+               hr: 'Croatian',
+               hu: 'Hungarian',
+               id: 'Indonesian',
+               is: 'Icelandic',
+               it: 'Italian',
+               ja: 'Japanese',
+               ka: 'Georgian',
+               km: 'Khmer',
+               ko: 'Korean',
+               ku: 'Kurdish',
+               lt: 'Lithuanian',
+               lv: 'Latvian',
+               mk: 'Macedonian',
+               mn: 'Mongolian',
+               ms: 'Malay',
+               nb: 'Norwegian Bokmal',
+               nl: 'Dutch',
+               no: 'Norwegian',
+               oc: 'Occitan',
+               pl: 'Polish',
+               pt: 'Portuguese (Portugal)',
+               'pt-br': 'Portuguese (Brazil)',
+               ro: 'Romanian',
+               ru: 'Russian',
+               si: 'Sinhala',
+               sk: 'Slovak',
+               sq: 'Albanian',
+               sl: 'Slovenian',
+               sr: 'Serbian (Cyrillic)',
+               'sr-latn': 'Serbian (Latin)',
+               sv: 'Swedish',
+               th: 'Thai',
+               tr: 'Turkish',
+               tt: 'Tatar',
+               ug: 'Uighur',
+               uk: 'Ukrainian',
+               vi: 'Vietnamese',
+               zh: 'Chinese Traditional',
+               'zh-cn': 'Chinese Simplified'
+       };
+
+       var langsArray = [];
+
+       for ( var code in CKEDITOR.lang.languages ) {
+               langsArray.push( { code: code, name: ( langs[ code ] || code ) } );
+       }
+
+       langsArray.sort( function( a, b ) {
+               return ( a.name < b.name ) ? -1 : 1;
+       } );
+
+       return langsArray;
+} )();
diff --git a/sources/samples/old/datafiltering.html b/sources/samples/old/datafiltering.html
new file mode 100644 (file)
index 0000000..dd78ba5
--- /dev/null
@@ -0,0 +1,508 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Data Filtering &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+       <script>
+               // Remove advanced tabs for all editors.
+               CKEDITOR.config.removeDialogTabs = 'image:advanced;link:advanced;flash:advanced;creatediv:advanced;editdiv:advanced';
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Data Filtering and Features Activation
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/acf.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample page demonstrates the idea of Advanced Content Filter
+                       (<abbr title="Advanced Content Filter">ACF</abbr>), a sophisticated
+                       tool that takes control over what kind of data is accepted by the editor and what
+                       kind of output is produced.
+               </p>
+               <h2>When and what is being filtered?</h2>
+               <p>
+                       <abbr title="Advanced Content Filter">ACF</abbr> controls
+                       <strong>every single source of data</strong> that comes to the editor.
+                       It process both HTML that is inserted manually (i.e. pasted by the user)
+                       and programmatically like:
+               </p>
+<pre class="samples">
+editor.setData( '&lt;p&gt;Hello world!&lt;/p&gt;' );
+</pre>
+               <p>
+                       <abbr title="Advanced Content Filter">ACF</abbr> discards invalid,
+                       useless HTML tags and attributes so the editor remains "clean" during
+                       runtime. <abbr title="Advanced Content Filter">ACF</abbr> behaviour
+                       can be configured and adjusted for a particular case to prevent the
+                       output HTML (i.e. in CMS systems) from being polluted.
+
+                       This kind of filtering is a first, client-side line of defense
+                       against "<a href="http://en.wikipedia.org/wiki/Tag_soup">tag soups</a>",
+                       the tool that precisely restricts which tags, attributes and styles
+                       are allowed (desired). When properly configured, <abbr title="Advanced Content Filter">ACF</abbr>
+                       is an easy and fast way to produce a high-quality, intentionally filtered HTML.
+               </p>
+
+               <h3>How to configure or disable ACF?</h3>
+               <p>
+                       Advanced Content Filter is enabled by default, working in "automatic mode", yet
+                       it provides a set of easy rules that allow adjusting filtering rules
+                       and disabling the entire feature when necessary. The config property
+                       responsible for this feature is <code><a class="samples"
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">config.allowedContent</a></code>.
+               </p>
+               <p>
+                       By "automatic mode" is meant that loaded plugins decide which kind
+                       of content is enabled and which is not. For example, if the link
+                       plugin is loaded it implies that <code>&lt;a&gt;</code> tag is
+                       automatically allowed. Each plugin is given a set
+                       of predefined <abbr title="Advanced Content Filter">ACF</abbr> rules
+                       that control the editor until <code><a class="samples"
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">
+                       config.allowedContent</a></code>
+                       is defined manually.
+               </p>
+               <p>
+                       Let's assume our intention is to restrict the editor to accept (produce) <strong>paragraphs
+                       only: no attributes, no styles, no other tags</strong>.
+                       With <abbr title="Advanced Content Filter">ACF</abbr>
+                       this is very simple. Basically set <code><a class="samples"
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">
+                       config.allowedContent</a></code> to <code>'p'</code>:
+               </p>
+<pre class="samples">
+var editor = CKEDITOR.replace( <em>textarea_id</em>, {
+       <strong>allowedContent: 'p'</strong>
+} );
+</pre>
+               <p>
+                       Now try to play with allowed content:
+               </p>
+<pre class="samples">
+// Trying to insert disallowed tag and attribute.
+editor.setData( '&lt;p <strong>style="color: red"</strong>&gt;Hello <strong>&lt;em&gt;world&lt;/em&gt;</strong>!&lt;/p&gt;' );
+alert( editor.getData() );
+
+// Filtered data is returned.
+"&lt;p&gt;Hello world!&lt;/p&gt;"
+</pre>
+               <p>
+                       What happened? Since <code>config.allowedContent: 'p'</code> is set the editor assumes
+                       that only plain <code>&lt;p&gt;</code> are accepted. Nothing more. This is why
+                       <code>style</code> attribute and <code>&lt;em&gt;</code> tag are gone. The same
+                       filtering would happen if we pasted disallowed HTML into this editor.
+               </p>
+               <p>
+                       This is just a small sample of what <abbr title="Advanced Content Filter">ACF</abbr>
+                       can do. To know more, please refer to the sample section below and
+                       <a href="http://docs.ckeditor.com/#!/guide/dev_advanced_content_filter">the official Advanced Content Filter guide</a>.
+               </p>
+               <p>
+                       You may, of course, want CKEditor to avoid filtering of any kind.
+                       To get rid of <abbr title="Advanced Content Filter">ACF</abbr>,
+                       basically set <code><a class="samples"
+                       href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">
+                       config.allowedContent</a></code> to <code>true</code> like this:
+               </p>
+<pre class="samples">
+CKEDITOR.replace( <em>textarea_id</em>, {
+       <strong>allowedContent: true</strong>
+} );
+</pre>
+
+               <h2>Beyond data flow: Features activation</h2>
+               <p>
+                       <abbr title="Advanced Content Filter">ACF</abbr> is far more than
+                       <abbr title="Input/Output">I/O</abbr> control: the entire
+                       <abbr title="User Interface">UI</abbr> of the editor is adjusted to what
+                       filters restrict. For example: if <code>&lt;a&gt;</code> tag is
+                       <strong>disallowed</strong>
+                       by <abbr title="Advanced Content Filter">ACF</abbr>,
+                       then accordingly <code>link</code> command, toolbar button and link dialog
+                       are also disabled. Editor is smart: it knows which features must be
+                       removed from the interface to match filtering rules.
+               </p>
+               <p>
+                       CKEditor can be far more specific. If <code>&lt;a&gt;</code> tag is
+                       <strong>allowed</strong> by filtering rules to be used but it is restricted
+                       to have only one attribute (<code>href</code>)
+                       <code>config.allowedContent = 'a[!href]'</code>, then
+                       "Target" tab of the link dialog is automatically disabled as <code>target</code>
+                       attribute isn't included in <abbr title="Advanced Content Filter">ACF</abbr> rules
+                       for <code>&lt;a&gt;</code>. This behaviour applies to dialog fields, context
+                       menus and toolbar buttons.
+               </p>
+
+               <h2>Sample configurations</h2>
+               <p>
+                       There are several editor instances below that present different
+                       <abbr title="Advanced Content Filter">ACF</abbr> setups. <strong>All of them,
+                       except the inline instance, share the same HTML content</strong> to visualize
+                       how different filtering rules affect the same input data.
+               </p>
+       </div>
+
+       <div>
+               <label for="editor1">
+                       Editor 1:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using default configuration ("automatic mode"). It means that
+                               <code><a class="samples"
+                               href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">
+                               config.allowedContent</a></code> is defined by loaded plugins.
+                               Each plugin extends filtering rules to make it's own associated content
+                               available for the user.
+                       </p>
+               </div>
+               <textarea cols="80" id="editor1" name="editor1" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+
+               <script>
+
+                       CKEDITOR.replace( 'editor1' );
+
+               </script>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor2">
+                       Editor 2:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using a custom configuration for
+                               <abbr title="Advanced Content Filter">ACF</abbr>:
+                       </p>
+<pre class="samples">
+CKEDITOR.replace( 'editor2', {
+       allowedContent:
+               'h1 h2 h3 p blockquote strong em;' +
+               'a[!href];' +
+               'img(left,right)[!src,alt,width,height];' +
+               'table tr th td caption;' +
+               'span{!font-family};' +'
+               'span{!color};' +
+               'span(!marker);' +
+               'del ins'
+} );
+</pre>
+                       <p>
+                               The following rules may require additional explanation:
+                       </p>
+                       <ul>
+                               <li>
+                                       <code>h1 h2 h3 p blockquote strong em</code> - These tags
+                                       are accepted by the editor. Any tag attributes will be discarded.
+                               </li>
+                               <li>
+                                       <code>a[!href]</code> - <code>href</code> attribute is obligatory
+                                       for <code>&lt;a&gt;</code> tag. Tags without this attribute
+                                       are disarded. No other attribute will be accepted.
+                               </li>
+                               <li>
+                                       <code>img(left,right)[!src,alt,width,height]</code> - <code>src</code>
+                                       attribute is obligatory for <code>&lt;img&gt;</code> tag.
+                                       <code>alt</code>, <code>width</code>, <code>height</code>
+                                       and <code>class</code> attributes are accepted but
+                                       <code>class</code> must be either <code>class="left"</code>
+                                       or <code>class="right"</code>
+                               </li>
+                               <li>
+                                       <code>table tr th td caption</code> - These tags
+                                       are accepted by the editor. Any tag attributes will be discarded.
+                               </li>
+                               <li>
+                                       <code>span{!font-family}</code>, <code>span{!color}</code>,
+                                       <code>span(!marker)</code> - <code>&lt;span&gt;</code> tags
+                                       will be accepted if either <code>font-family</code> or
+                                       <code>color</code> style is set or <code>class="marker"</code>
+                                       is present.
+                               </li>
+                               <li>
+                                       <code>del ins</code> - These tags
+                                       are accepted by the editor. Any tag attributes will be discarded.
+                               </li>
+                       </ul>
+                       <p>
+                               Please note that <strong><abbr title="User Interface">UI</abbr> of the
+                               editor is different</strong>. It's a response to what happened to the filters.
+                               Since <code>text-align</code> isn't allowed, the align toolbar is gone.
+                               The same thing happened to subscript/superscript, strike, underline
+                               (<code>&lt;u&gt;</code>, <code>&lt;sub&gt;</code>, <code>&lt;sup&gt;</code>
+                               are disallowed by <code><a class="samples"
+                               href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-allowedContent">
+                               config.allowedContent</a></code>) and many other buttons.
+                       </p>
+               </div>
+               <textarea cols="80" id="editor2" name="editor2" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       CKEDITOR.replace( 'editor2', {
+                               allowedContent:
+                                       'h1 h2 h3 p blockquote strong em;' +
+                                       'a[!href];' +
+                                       'img(left,right)[!src,alt,width,height];' +
+                                       'table tr th td caption;' +
+                                       'span{!font-family};' +
+                                       'span{!color};' +
+                                       'span(!marker);' +
+                                       'del ins'
+                       } );
+
+               </script>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor3">
+                       Editor 3:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using a custom configuration for
+                               <abbr title="Advanced Content Filter">ACF</abbr>.
+                               Note that filters can be configured as an object literal
+                               as an alternative to a string-based definition.
+                       </p>
+<pre class="samples">
+CKEDITOR.replace( 'editor3', {
+       allowedContent: {
+               'b i ul ol big small': true,
+               'h1 h2 h3 p blockquote li': {
+                       styles: 'text-align'
+               },
+               a: { attributes: '!href,target' },
+               img: {
+                       attributes: '!src,alt',
+                       styles: 'width,height',
+                       classes: 'left,right'
+               }
+       }
+} );
+</pre>
+               </div>
+               <textarea cols="80" id="editor3" name="editor3" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       CKEDITOR.replace( 'editor3', {
+                               allowedContent: {
+                                       'b i ul ol big small': true,
+                                       'h1 h2 h3 p blockquote li': {
+                                               styles: 'text-align'
+                                       },
+                                       a: { attributes: '!href,target' },
+                                       img: {
+                                               attributes: '!src,alt',
+                                               styles: 'width,height',
+                                               classes: 'left,right'
+                                       }
+                               }
+                       } );
+
+               </script>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor4">
+                       Editor 4:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using a custom set of plugins and buttons.
+                       </p>
+<pre class="samples">
+CKEDITOR.replace( 'editor4', {
+       removePlugins: 'bidi,font,forms,flash,horizontalrule,iframe,justify,table,tabletools,smiley',
+       removeButtons: 'Anchor,Underline,Strike,Subscript,Superscript,Image',
+       format_tags: 'p;h1;h2;h3;pre;address'
+} );
+</pre>
+                       <p>
+                               As you can see, removing plugins and buttons implies filtering.
+                               Several tags are not allowed in the editor because there's no
+                               plugin/button that is responsible for creating and editing this
+                               kind of content (for example: the image is missing because
+                               of <code>removeButtons: 'Image'</code>). The conclusion is that
+                               <abbr title="Advanced Content Filter">ACF</abbr> works "backwards"
+                               as well: <strong>modifying <abbr title="User Interface">UI</abbr>
+                               elements is changing allowed content rules</strong>.
+                       </p>
+               </div>
+               <textarea cols="80" id="editor4" name="editor4" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       CKEDITOR.replace( 'editor4', {
+                               removePlugins: 'bidi,div,font,forms,flash,horizontalrule,iframe,justify,table,tabletools,smiley',
+                               removeButtons: 'Anchor,Underline,Strike,Subscript,Superscript,Image',
+                               format_tags: 'p;h1;h2;h3;pre;address'
+                       } );
+
+               </script>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor5">
+                       Editor 5:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is built on editable <code>&lt;h1&gt;</code> element.
+                               <abbr title="Advanced Content Filter">ACF</abbr> takes care of
+                               what can be included in <code>&lt;h1&gt;</code>. Note that there
+                               are no block styles in Styles combo. Also why lists, indentation,
+                               blockquote, div, form and other buttons are missing.
+                       </p>
+                       <p>
+                               <abbr title="Advanced Content Filter">ACF</abbr> makes sure that
+                               no disallowed tags will come to <code>&lt;h1&gt;</code> so the final
+                               markup is valid. If the user tried to paste some invalid HTML
+                               into this editor (let's say a list), it would be automatically
+                               converted into plain text.
+                       </p>
+               </div>
+               <h1 id="editor5" contenteditable="true">
+                       <em>Apollo 11</em> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC.
+               </h1>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor3">
+                       Editor 6:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using a custom configuration for <abbr title="Advanced Content Filter">ACF</abbr>.
+                               It's using the <a href="http://docs.ckeditor.com/#!/guide/dev_disallowed_content" rel="noopener noreferrer" target="_blank">
+                               Disallowed Content</a> property of the filter to eliminate all <code>title</code> attributes.
+                       </p>
+
+<pre class="samples">
+CKEDITOR.replace( 'editor6', {
+       allowedContent: {
+               'b i ul ol big small': true,
+               'h1 h2 h3 p blockquote li': {
+                       styles: 'text-align'
+               },
+               a: {attributes: '!href,target'},
+               img: {
+                       attributes: '!src,alt',
+                       styles: 'width,height',
+                       classes: 'left,right'
+               }
+       },
+       disallowedContent: '*{title*}'
+} );
+</pre>
+               </div>
+               <textarea cols="80" id="editor6" name="editor6" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       CKEDITOR.replace( 'editor6', {
+                               allowedContent: {
+                                       'b i ul ol big small': true,
+                                       'h1 h2 h3 p blockquote li': {
+                                               styles: 'text-align'
+                                       },
+                                       a: {attributes: '!href,target'},
+                                       img: {
+                                               attributes: '!src,alt',
+                                               styles: 'width,height',
+                                               classes: 'left,right'
+                                       }
+                               },
+                               disallowedContent: '*{title*}'
+                       } );
+
+               </script>
+       </div>
+
+       <br>
+
+       <div>
+               <label for="editor7">
+                       Editor 7:
+               </label>
+               <div class="description">
+                       <p>
+                               This editor is using a custom configuration for <abbr title="Advanced Content Filter">ACF</abbr>.
+                               It's using the <a href="http://docs.ckeditor.com/#!/guide/dev_disallowed_content" rel="noopener noreferrer" target="_blank">
+                               Disallowed Content</a> property of the filter to eliminate all <code>a</code> and <code>img</code> tags,
+                               while allowing all other tags.
+                       </p>
+<pre class="samples">
+CKEDITOR.replace( 'editor7', {
+       allowedContent: {
+               // Allow all content.
+               $1: {
+                       elements: CKEDITOR.dtd,
+                       attributes: true,
+                       styles: true,
+                       classes: true
+               }
+       },
+       disallowedContent: 'img a'
+} );
+</pre>
+               </div>
+               <textarea cols="80" id="editor7" name="editor7" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       CKEDITOR.replace( 'editor7', {
+                               allowedContent: {
+                                       // allow all content
+                                       $1: {
+                                               elements: CKEDITOR.dtd,
+                                               attributes: true,
+                                               styles: true,
+                                               classes: true
+                                       }
+                               },
+                               disallowedContent: 'img a'
+                       } );
+
+               </script>
+       </div>
+
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/divreplace.html b/sources/samples/old/divreplace.html
new file mode 100644 (file)
index 0000000..e882b22
--- /dev/null
@@ -0,0 +1,144 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Replace DIV &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               div.editable
+               {
+                       border: solid 2px transparent;
+                       padding-left: 15px;
+                       padding-right: 15px;
+               }
+
+               div.editable:hover
+               {
+                       border-color: black;
+               }
+
+       </style>
+       <script>
+
+               // Uncomment the following code to test the "Timeout Loading Method".
+               // CKEDITOR.loadFullCoreTimeout = 5;
+
+               window.onload = function() {
+                       // Listen to the double click event.
+                       if ( window.addEventListener )
+                               document.body.addEventListener( 'dblclick', onDoubleClick, false );
+                       else if ( window.attachEvent )
+                               document.body.attachEvent( 'ondblclick', onDoubleClick );
+
+               };
+
+               function onDoubleClick( ev ) {
+                       // Get the element which fired the event. This is not necessarily the
+                       // element to which the event has been attached.
+                       var element = ev.target || ev.srcElement;
+
+                       // Find out the div that holds this element.
+                       var name;
+
+                       do {
+                               element = element.parentNode;
+                       }
+                       while ( element && ( name = element.nodeName.toLowerCase() ) &&
+                               ( name != 'div' || element.className.indexOf( 'editable' ) == -1 ) && name != 'body' );
+
+                       if ( name == 'div' && element.className.indexOf( 'editable' ) != -1 )
+                               replaceDiv( element );
+               }
+
+               var editor;
+
+               function replaceDiv( div ) {
+                       if ( editor )
+                               editor.destroy();
+
+                       editor = CKEDITOR.replace( div );
+               }
+
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace DIV with CKEditor on the Fly
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to automatically replace <code>&lt;div&gt;</code> elements
+                       with a CKEditor instance on the fly, following user's doubleclick. The content
+                       that was previously placed inside the <code>&lt;div&gt;</code> element will now
+                       be moved into CKEditor editing area.
+               </p>
+               <p>
+                       For details on how to create this setup check the source code of this sample page.
+               </p>
+       </div>
+       <p>
+               Double-click any of the following <code>&lt;div&gt;</code> elements to transform them into
+               editor instances.
+       </p>
+       <div class="editable">
+               <h3>
+                       Part 1
+               </h3>
+               <p>
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.
+               </p>
+       </div>
+       <div class="editable">
+               <h3>
+                       Part 2
+               </h3>
+               <p>
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.
+               </p>
+               <p>
+                       Donec velit. Mauris massa. Vestibulum non nulla. Nam suscipit arcu nec elit. Phasellus
+                       sollicitudin iaculis ante. Ut non mauris et sapien tincidunt adipiscing. Vestibulum
+                       vitae leo. Suspendisse nec mi tristique nulla laoreet vulputate.
+               </p>
+       </div>
+       <div class="editable">
+               <h3>
+                       Part 3
+               </h3>
+               <p>
+                       Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Cras et ipsum quis mi
+                       semper accumsan. Integer pretium dui id massa. Suspendisse in nisl sit amet urna
+                       rutrum imperdiet. Nulla eu tellus. Donec ante nisi, ullamcorper quis, fringilla
+                       nec, sagittis eleifend, pede. Nulla commodo interdum massa. Donec id metus. Fusce
+                       eu ipsum. Suspendisse auctor. Phasellus fermentum porttitor risus.
+               </p>
+       </div>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/index.html b/sources/samples/old/index.html
new file mode 100644 (file)
index 0000000..999d110
--- /dev/null
@@ -0,0 +1,111 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>CKEditor Samples</title>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               CKEditor Samples
+       </h1>
+       <div class="warning deprecated">
+               These samples are not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.
+       </div>
+       <div class="twoColumns">
+               <div class="twoColumnsLeft">
+                       <h2 class="samples">
+                               Basic Samples
+                       </h2>
+                       <dl class="samples">
+                               <dt><a class="samples" href="replacebyclass.html">Replace textarea elements by class name</a></dt>
+                               <dd>Automatic replacement of all textarea elements of a given class with a CKEditor instance.</dd>
+
+                               <dt><a class="samples" href="replacebycode.html">Replace textarea elements by code</a></dt>
+                               <dd>Replacement of textarea elements with CKEditor instances by using a JavaScript call.</dd>
+
+                               <dt><a class="samples" href="jquery.html">Create editors with jQuery</a></dt>
+                               <dd>Creating standard and inline CKEditor instances with jQuery adapter.</dd>
+                       </dl>
+
+                       <h2 class="samples">
+                               Basic Customization
+                       </h2>
+                       <dl class="samples">
+                               <dt><a class="samples" href="uicolor.html">User Interface color</a></dt>
+                               <dd>Changing CKEditor User Interface color and adding a toolbar button that lets the user set the UI color.</dd>
+
+                               <dt><a class="samples" href="uilanguages.html">User Interface languages</a></dt>
+                               <dd>Changing CKEditor User Interface language and adding a drop-down list that lets the user choose the UI language.</dd>
+                       </dl>
+
+
+
+                       <!-- PLUGINS_SAMPLES -->
+               </div>
+               <div class="twoColumnsRight">
+                       <h2 class="samples">
+                               Inline Editing
+                       </h2>
+                       <dl class="samples">
+                               <dt><a class="samples" href="inlineall.html">Massive inline editor creation</a></dt>
+                               <dd>Turn all elements with <code>contentEditable = true</code> attribute into inline editors.</dd>
+
+                               <dt><a class="samples" href="inlinebycode.html">Convert element into an inline editor by code</a></dt>
+                               <dd>Conversion of DOM elements into inline CKEditor instances by using a JavaScript call.</dd>
+
+                               <dt><a class="samples" href="inlinetextarea.html">Replace textarea with inline editor</a> <span class="new">New!</span></dt>
+                               <dd>A form with a textarea that is replaced by an inline editor at runtime.</dd>
+
+                               <!-- INLINE_EDITING_SAMPLES -->
+                       </dl>
+
+                       <h2 class="samples">
+                               Advanced Samples
+                       </h2>
+                       <dl class="samples">
+                               <dt><a class="samples" href="datafiltering.html">Data filtering and features activation</a> <span class="new">New!</span></dt>
+                               <dd>Data filtering and automatic features activation basing on configuration.</dd>
+
+                               <dt><a class="samples" href="divreplace.html">Replace DIV elements on the fly</a></dt>
+                               <dd>Transforming a <code>div</code> element into an instance of CKEditor with a mouse click.</dd>
+
+                               <dt><a class="samples" href="appendto.html">Append editor instances</a></dt>
+                               <dd>Appending editor instances to existing DOM elements.</dd>
+
+                               <dt><a class="samples" href="ajax.html">Create and destroy editor instances for Ajax applications</a></dt>
+                               <dd>Creating and destroying CKEditor instances on the fly and saving the contents entered into the editor window.</dd>
+
+                               <dt><a class="samples" href="api.html">Basic usage of the API</a></dt>
+                               <dd>Using the CKEditor JavaScript API to interact with the editor at runtime.</dd>
+
+                               <dt><a class="samples" href="xhtmlstyle.html">XHTML-compliant style</a></dt>
+                               <dd>Configuring CKEditor to produce XHTML 1.1 compliant attributes and styles.</dd>
+
+                               <dt><a class="samples" href="readonly.html">Read-only mode</a></dt>
+                               <dd>Using the readOnly API to block introducing changes to the editor contents.</dd>
+
+                               <dt><a class="samples" href="tabindex.html">"Tab" key-based navigation</a></dt>
+                               <dd>Navigating among editor instances with tab key.</dd>
+
+
+
+                               <!-- ADVANCED_SAMPLES -->
+                       </dl>
+               </div>
+       </div>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/inlineall.html b/sources/samples/old/inlineall.html
new file mode 100644 (file)
index 0000000..8220ea5
--- /dev/null
@@ -0,0 +1,314 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Massive inline editing &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <script>
+
+               // This code is generally not necessary, but it is here to demonstrate
+               // how to customize specific editor instances on the fly. This fits well
+               // this demo because we have editable elements (like headers) that
+               // require less features.
+
+               // The "instanceCreated" event is fired for every editor instance created.
+               CKEDITOR.on( 'instanceCreated', function( event ) {
+                       var editor = event.editor,
+                               element = editor.element;
+
+                       // Customize editors for headers and tag list.
+                       // These editors don't need features like smileys, templates, iframes etc.
+                       if ( element.is( 'h1', 'h2', 'h3' ) || element.getAttribute( 'id' ) == 'taglist' ) {
+                               // Customize the editor configurations on "configLoaded" event,
+                               // which is fired after the configuration file loading and
+                               // execution. This makes it possible to change the
+                               // configurations before the editor initialization takes place.
+                               editor.on( 'configLoaded', function() {
+
+                                       // Remove unnecessary plugins to make the editor simpler.
+                                       editor.config.removePlugins = 'colorbutton,find,flash,font,' +
+                                               'forms,iframe,image,newpage,removeformat,' +
+                                               'smiley,specialchar,stylescombo,templates';
+
+                                       // Rearrange the layout of the toolbar.
+                                       editor.config.toolbarGroups = [
+                                               { name: 'editing',              groups: [ 'basicstyles', 'links' ] },
+                                               { name: 'undo' },
+                                               { name: 'clipboard',    groups: [ 'selection', 'clipboard' ] },
+                                               { name: 'about' }
+                                       ];
+                               });
+                       }
+               });
+
+       </script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               /* The following styles are just to make the page look nice. */
+
+               /* Workaround to show Arial Black in Firefox. */
+               @font-face
+               {
+                       font-family: 'arial-black';
+                       src: local('Arial Black');
+               }
+
+               *[contenteditable="true"]
+               {
+                       padding: 10px;
+               }
+
+               #container
+               {
+                       width: 960px;
+                       margin: 30px auto 0;
+               }
+
+               #header
+               {
+                       overflow: hidden;
+                       padding: 0 0 30px;
+                       border-bottom: 5px solid #05B2D2;
+                       position: relative;
+               }
+
+               #headerLeft,
+               #headerRight
+               {
+                       width: 49%;
+                       overflow: hidden;
+               }
+
+               #headerLeft
+               {
+                       float: left;
+                       padding: 10px 1px 1px;
+               }
+
+               #headerLeft h2,
+               #headerLeft h3
+               {
+                       text-align: right;
+                       margin: 0;
+                       overflow: hidden;
+                       font-weight: normal;
+               }
+
+               #headerLeft h2
+               {
+                       font-family: "Arial Black",arial-black;
+                       font-size: 4.6em;
+                       line-height: 1.1;
+                       text-transform: uppercase;
+               }
+
+               #headerLeft h3
+               {
+                       font-size: 2.3em;
+                       line-height: 1.1;
+                       margin: .2em 0 0;
+                       color: #666;
+               }
+
+               #headerRight
+               {
+                       float: right;
+                       padding: 1px;
+               }
+
+               #headerRight p
+               {
+                       line-height: 1.8;
+                       text-align: justify;
+                       margin: 0;
+               }
+
+               #headerRight p + p
+               {
+                       margin-top: 20px;
+               }
+
+               #headerRight > div
+               {
+                       padding: 20px;
+                       margin: 0 0 0 30px;
+                       font-size: 1.4em;
+                       color: #666;
+               }
+
+               #columns
+               {
+                       color: #333;
+                       overflow: hidden;
+                       padding: 20px 0;
+               }
+
+               #columns > div
+               {
+                       float: left;
+                       width: 33.3%;
+               }
+
+               #columns #column1 > div
+               {
+                       margin-left: 1px;
+               }
+
+               #columns #column3 > div
+               {
+                       margin-right: 1px;
+               }
+
+               #columns > div > div
+               {
+                       margin: 0px 10px;
+                       padding: 10px 20px;
+               }
+
+               #columns blockquote
+               {
+                       margin-left: 15px;
+               }
+
+               #tagLine
+               {
+                       border-top: 5px solid #05B2D2;
+                       padding-top: 20px;
+               }
+
+               #taglist {
+                       display: inline-block;
+                       margin-left: 20px;
+                       font-weight: bold;
+                       margin: 0 0 0 20px;
+               }
+
+       </style>
+</head>
+<body>
+<div>
+       <h1 class="samples"><a href="index.html">CKEditor Samples</a> &raquo; Massive inline editing</h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>This sample page demonstrates the inline editing feature - CKEditor instances will be created automatically from page elements with <strong>contentEditable</strong> attribute set to value <strong>true</strong>:</p>
+               <pre class="samples">&lt;div <strong>contenteditable="true</strong>" &gt; ... &lt;/div&gt;</pre>
+               <p>Click inside of any element below to start editing.</p>
+       </div>
+</div>
+<div id="container">
+       <div id="header">
+               <div id="headerLeft">
+                       <h2 id="sampleTitle" contenteditable="true">
+                               CKEditor<br> Goes Inline!
+                       </h2>
+                       <h3 contenteditable="true">
+                               Lorem ipsum dolor sit amet dolor duis blandit vestibulum faucibus a, tortor.
+                       </h3>
+               </div>
+               <div id="headerRight">
+                       <div contenteditable="true">
+                               <p>
+                                       Lorem ipsum dolor sit amet enim. Etiam ullamcorper. Suspendisse a pellentesque dui, non felis. Maecenas malesuada elit lectus felis, malesuada ultricies.
+                               </p>
+                               <p>
+                                       Curabitur et ligula. Ut molestie a, ultricies porta urna. Vestibulum commodo volutpat a, convallis ac, laoreet enim. Phasellus fermentum in, dolor. Pellentesque facilisis. Nulla imperdiet sit amet magna. Vestibulum dapibus, mauris nec malesuada fames ac.
+                               </p>
+                       </div>
+               </div>
+       </div>
+       <div id="columns">
+               <div id="column1">
+                       <div contenteditable="true">
+                               <h3>
+                                       Fusce vitae porttitor
+                               </h3>
+                               <p>
+                                       <strong>
+                                               Lorem ipsum dolor sit amet dolor. Duis blandit vestibulum faucibus a, tortor.
+                                       </strong>
+                               </p>
+                               <p>
+                                       Proin nunc justo felis mollis tincidunt, risus risus pede, posuere cubilia Curae, Nullam euismod, enim. Etiam nibh ultricies dolor ac dignissim erat volutpat. Vivamus fermentum <a href="http://ckeditor.com/">nisl nulla sem in</a> metus. Maecenas wisi. Donec nec erat volutpat.
+                               </p>
+                               <blockquote>
+                                       <p>
+                                               Fusce vitae porttitor a, euismod convallis nisl, blandit risus tortor, pretium.
+                                               Vehicula vitae, imperdiet vel, ornare enim vel sodales rutrum
+                                       </p>
+                               </blockquote>
+                               <blockquote>
+                                       <p>
+                                               Libero nunc, rhoncus ante ipsum non ipsum. Nunc eleifend pede turpis id sollicitudin fringilla. Phasellus ultrices, velit ac arcu.
+                                       </p>
+                               </blockquote>
+                               <p>Pellentesque nunc. Donec suscipit erat. Pellentesque habitant morbi tristique ullamcorper.</p>
+                               <p><s>Mauris mattis feugiat lectus nec mauris. Nullam vitae ante.</s></p>
+                       </div>
+               </div>
+               <div id="column2">
+                       <div contenteditable="true">
+                               <h3>
+                                       Integer condimentum sit amet
+                               </h3>
+                               <p>
+                                       <strong>Aenean nonummy a, mattis varius. Cras aliquet.</strong>
+                                       Praesent <a href="http://ckeditor.com/">magna non mattis ac, rhoncus nunc</a>, rhoncus eget, cursus pulvinar mollis.</p>
+                               <p>Proin id nibh. Sed eu libero posuere sed, lectus. Phasellus dui gravida gravida feugiat mattis ac, felis.</p>
+                               <p>Integer condimentum sit amet, tempor elit odio, a dolor non ante at sapien. Sed ac lectus. Nulla ligula quis eleifend mi, id leo velit pede cursus arcu id nulla ac lectus. Phasellus vestibulum. Nunc viverra enim quis diam.</p>
+                       </div>
+                       <div contenteditable="true">
+                               <h3>
+                                       Praesent wisi accumsan sit amet nibh
+                               </h3>
+                               <p>Donec ullamcorper, risus tortor, pretium porttitor. Morbi quam quis lectus non leo.</p>
+                               <p style="margin-left: 40px; ">Integer faucibus scelerisque. Proin faucibus at, aliquet vulputate, odio at eros. Fusce <a href="http://ckeditor.com/">gravida, erat vitae augue</a>. Fusce urna fringilla gravida.</p>
+                               <p>In hac habitasse platea dictumst. Praesent wisi accumsan sit amet nibh. Maecenas orci luctus a, lacinia quam sem, posuere commodo, odio condimentum tempor, pede semper risus. Suspendisse pede. In hac habitasse platea dictumst. Nam sed laoreet sit amet erat. Integer.</p>
+                       </div>
+               </div>
+               <div id="column3">
+                       <div contenteditable="true">
+                               <p>
+                                       <img src="assets/inlineall/logo.png" alt="CKEditor logo" style="float:left">
+                               </p>
+                               <p>Quisque justo neque, mattis sed, fermentum ultrices <strong>posuere cubilia Curae</strong>, Vestibulum elit metus, quis placerat ut, lectus. Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis. Fusce porttitor, nulla quis turpis. Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi. Donec odio nec velit ac nunc sit amet, accumsan cursus aliquet. Vestibulum ante sit amet sagittis mi.</p>
+                               <h3>
+                                       Nullam laoreet vel consectetuer tellus suscipit
+                               </h3>
+                               <ul>
+                                       <li>Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis.</li>
+                                       <li>Fusce porttitor, nulla quis turpis. Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi.</li>
+                                       <li>Mauris eget tellus. Donec non felis. Nam eget dolor. Vestibulum enim. Donec.</li>
+                               </ul>
+                               <p>Quisque justo neque, mattis sed, <a href="http://ckeditor.com/">fermentum ultrices posuere cubilia</a> Curae, Vestibulum elit metus, quis placerat ut, lectus.</p>
+                               <p>Nullam laoreet vel, consectetuer tellus suscipit ultricies, hendrerit wisi. Ut sagittis, nunc libero, egestas consequat lobortis velit rutrum ut, faucibus turpis. Fusce porttitor, nulla quis turpis.</p>
+                               <p>Donec odio nec velit ac nunc sit amet, accumsan cursus aliquet. Vestibulum ante sit amet sagittis mi. Sed in nonummy faucibus turpis. Mauris eget tellus. Donec non felis. Nam eget dolor. Vestibulum enim. Donec.</p>
+                       </div>
+               </div>
+       </div>
+       <div id="tagLine">
+               Tags of this article:
+               <p id="taglist" contenteditable="true">
+                       inline, editing, floating, CKEditor
+               </p>
+       </div>
+</div>
+<div id="footer">
+       <hr>
+       <p>
+               CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">
+                       http://ckeditor.com</a>
+       </p>
+       <p id="copy">
+               Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>
+               - Frederico Knabben. All rights reserved.
+       </p>
+</div>
+</body>
+</html>
diff --git a/sources/samples/old/inlinebycode.html b/sources/samples/old/inlinebycode.html
new file mode 100644 (file)
index 0000000..eea2723
--- /dev/null
@@ -0,0 +1,124 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Inline Editing by Code &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               #editable
+               {
+                       padding: 10px;
+                       float: left;
+               }
+
+       </style>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Inline Editing by Code
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to create an inline editor instance of CKEditor. It is created
+                       with a JavaScript call using the following code:
+               </p>
+<pre class="samples">
+// This property tells CKEditor to not activate every element with contenteditable=true element.
+CKEDITOR.disableAutoInline = true;
+
+var editor = CKEDITOR.inline( document.getElementById( 'editable' ) );
+</pre>
+               <p>
+                       Note that <code>editable</code> in the code above is the <code>id</code>
+                       attribute of the <code>&lt;div&gt;</code> element to be converted into an inline instance.
+               </p>
+       </div>
+       <div id="editable" contenteditable="true">
+               <h1><img alt="Saturn V carrying Apollo 11" class="right" src="assets/sample.jpg" /> Apollo 11</h1>
+
+               <p><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>
+
+               <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.</p>
+
+               <h2>Broadcasting and <em>quotes</em> <a id="quotes" name="quotes"></a></h2>
+
+               <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>
+
+               <blockquote>
+                       <p>One small step for [a] man, one giant leap for mankind.</p>
+               </blockquote>
+
+               <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p>
+
+               <blockquote>
+                       <p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p>
+               </blockquote>
+
+               <h2>Technical details <a id="tech-details" name="tech-details"></a></h2>
+
+               <table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;">
+                       <caption><strong>Mission crew</strong></caption>
+                       <thead>
+                       <tr>
+                               <th scope="col">Position</th>
+                               <th scope="col">Astronaut</th>
+                       </tr>
+                       </thead>
+                       <tbody>
+                       <tr>
+                               <td>Commander</td>
+                               <td>Neil A. Armstrong</td>
+                       </tr>
+                       <tr>
+                               <td>Command Module Pilot</td>
+                               <td>Michael Collins</td>
+                       </tr>
+                       <tr>
+                               <td>Lunar Module Pilot</td>
+                               <td>Edwin &quot;Buzz&quot; E. Aldrin, Jr.</td>
+                       </tr>
+                       </tbody>
+               </table>
+
+               <p>Launched by a <strong>Saturn V</strong> rocket from <a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center">Kennedy Space Center</a> in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of <a href="http://en.wikipedia.org/wiki/NASA" title="NASA">NASA</a>&#39;s Apollo program. The Apollo spacecraft had three parts:</p>
+
+               <ol>
+                       <li><strong>Command Module</strong> with a cabin for the three astronauts which was the only part which landed back on Earth</li>
+                       <li><strong>Service Module</strong> which supported the Command Module with propulsion, electrical power, oxygen and water</li>
+                       <li><strong>Lunar Module</strong> for landing on the Moon.</li>
+               </ol>
+
+               <p>After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the <a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis">Sea of Tranquility</a>. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the <a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean">Pacific Ocean</a> on July 24.</p>
+
+               <hr />
+               <p style="text-align: right;"><small>Source: <a href="http://en.wikipedia.org/wiki/Apollo_11">Wikipedia.org</a></small></p>
+       </div>
+
+       <script>
+               // We need to turn off the automatic editor creation first.
+               CKEDITOR.disableAutoInline = true;
+
+               var editor = CKEDITOR.inline( 'editable' );
+       </script>
+       <div id="footer">
+               <hr>
+               <p contenteditable="true">
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">
+                               http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>
+                       - Frederico Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/inlinetextarea.html b/sources/samples/old/inlinetextarea.html
new file mode 100644 (file)
index 0000000..57e664e
--- /dev/null
@@ -0,0 +1,113 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Replace Textarea with Inline Editor &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               /* Style the CKEditor element to look like a textfield */
+               .cke_textarea_inline
+               {
+                       padding: 10px;
+                       height: 200px;
+                       overflow: auto;
+
+                       border: 1px solid gray;
+                       -webkit-appearance: textfield;
+               }
+
+       </style>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea with Inline Editor
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/inline.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       You can also create an inline editor from a <code>textarea</code>
+                       element. In this case the <code>textarea</code> will be replaced
+                       by a <code>div</code> element with inline editing enabled.
+               </p>
+<pre class="samples">
+// "article-body" is the name of a textarea element.
+var editor = CKEDITOR.inline( 'article-body' );
+</pre>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <h2>This is a sample form with some fields</h2>
+               <p>
+                       Title:<br>
+                       <input type="text" name="title" value="Sample Form"></p>
+               <p>
+                       Article Body (Textarea converted to CKEditor):<br>
+                       <textarea name="article-body" style="height: 200px">
+                               &lt;h2&gt;Technical details &lt;a id="tech-details" name="tech-details"&gt;&lt;/a&gt;&lt;/h2&gt;
+
+                               &lt;table align="right" border="1" bordercolor="#ccc" cellpadding="5" cellspacing="0" style="border-collapse:collapse;margin:10px 0 10px 15px;"&gt;
+                                       &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt;
+                                       &lt;thead&gt;
+                                       &lt;tr&gt;
+                                               &lt;th scope="col"&gt;Position&lt;/th&gt;
+                                               &lt;th scope="col"&gt;Astronaut&lt;/th&gt;
+                                       &lt;/tr&gt;
+                                       &lt;/thead&gt;
+                                       &lt;tbody&gt;
+                                       &lt;tr&gt;
+                                               &lt;td&gt;Commander&lt;/td&gt;
+                                               &lt;td&gt;Neil A. Armstrong&lt;/td&gt;
+                                       &lt;/tr&gt;
+                                       &lt;tr&gt;
+                                               &lt;td&gt;Command Module Pilot&lt;/td&gt;
+                                               &lt;td&gt;Michael Collins&lt;/td&gt;
+                                       &lt;/tr&gt;
+                                       &lt;tr&gt;
+                                               &lt;td&gt;Lunar Module Pilot&lt;/td&gt;
+                                               &lt;td&gt;Edwin &quot;Buzz&quot; E. Aldrin, Jr.&lt;/td&gt;
+                                       &lt;/tr&gt;
+                                       &lt;/tbody&gt;
+                               &lt;/table&gt;
+
+                               &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href="http://en.wikipedia.org/wiki/Kennedy_Space_Center" title="Kennedy Space Center"&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href="http://en.wikipedia.org/wiki/NASA" title="NASA"&gt;NASA&lt;/a&gt;&#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt;
+
+                               &lt;ol&gt;
+                                       &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt;
+                                       &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt;
+                                       &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt;
+                               &lt;/ol&gt;
+
+                               &lt;p&gt;After being sent to the Moon by the Saturn V&#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href="http://en.wikipedia.org/wiki/Mare_Tranquillitatis" title="Mare Tranquillitatis"&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href="http://en.wikipedia.org/wiki/Pacific_Ocean" title="Pacific Ocean"&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt;
+
+                               &lt;hr /&gt;
+                               &lt;p style="text-align: right;"&gt;&lt;small&gt;Source: &lt;a href="http://en.wikipedia.org/wiki/Apollo_11"&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+                       </textarea>
+               </p>
+               <p>
+                       <input type="submit" value="Submit">
+               </p>
+       </form>
+
+       <script>
+               CKEDITOR.inline( 'article-body' );
+       </script>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">
+                               http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a>
+                       - Frederico Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/jquery.html b/sources/samples/old/jquery.html
new file mode 100644 (file)
index 0000000..2f6d958
--- /dev/null
@@ -0,0 +1,103 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>jQuery Adapter &mdash; CKEditor Sample</title>
+       <script src="http://code.jquery.com/jquery-1.11.0.min.js"></script>
+       <script src="../../ckeditor.js"></script>
+       <script src="../../adapters/jquery.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               #editable
+               {
+                       padding: 10px;
+                       float: left;
+               }
+
+       </style>
+       <script>
+
+               CKEDITOR.disableAutoInline = true;
+
+               $( document ).ready( function() {
+                       $( '#editor1' ).ckeditor(); // Use CKEDITOR.replace() if element is <textarea>.
+                       $( '#editable' ).ckeditor(); // Use CKEDITOR.inline().
+               } );
+
+               function setValue() {
+                       $( '#editor1' ).val( $( 'input#val' ).val() );
+               }
+
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html" id="a-test">CKEditor Samples</a> &raquo; Create Editors with jQuery
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <div class="description">
+                       <p>
+                               This sample shows how to use the <a href="http://docs.ckeditor.com/#!/guide/dev_jquery">jQuery adapter</a>.
+                               Note that you have to include both CKEditor and jQuery scripts before including the adapter.
+                       </p>
+
+<pre class="samples">
+&lt;script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.1/jquery.min.js"&gt;&lt;/script&gt;
+&lt;script src="/ckedit../../ckeditor.js"&gt;&lt;/script&gt;
+&lt;script src="/ckeditor/adapters/jquery.js"&gt;&lt;/script&gt;
+</pre>
+
+                       <p>Then you can replace HTML elements with a CKEditor instance using the <code>ckeditor()</code> method.</p>
+
+<pre class="samples">
+$( document ).ready( function() {
+       $( 'textarea#editor1' ).ckeditor();
+} );
+</pre>
+               </div>
+
+               <h2 class="samples">Inline Example</h2>
+
+               <div id="editable" contenteditable="true">
+                       <p><img alt="Saturn V carrying Apollo 11" class="right" src="assets/sample.jpg"/><b>Apollo 11</b> was the spaceflight that landed the first humans, Americans <a href="http://en.wikipedia.org/wiki/Neil_Armstrong" title="Neil Armstrong">Neil Armstrong</a> and <a href="http://en.wikipedia.org/wiki/Buzz_Aldrin" title="Buzz Aldrin">Buzz Aldrin</a>, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.</p>
+                       <p>Armstrong spent about <s>three and a half</s> two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&nbsp;kg) of lunar material for return to Earth. A third member of the mission, <a href="http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)" title="Michael Collins (astronaut)">Michael Collins</a>, piloted the <a href="http://en.wikipedia.org/wiki/Apollo_Command/Service_Module" title="Apollo Command/Service Module">command</a> spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.
+                       <p>Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:</p>
+                       <blockquote><p>One small step for [a] man, one giant leap for mankind.</p></blockquote> <p>Apollo 11 effectively ended the <a href="http://en.wikipedia.org/wiki/Space_Race" title="Space Race">Space Race</a> and fulfilled a national goal proposed in 1961 by the late U.S. President <a href="http://en.wikipedia.org/wiki/John_F._Kennedy" title="John F. Kennedy">John F. Kennedy</a> in a speech before the United States Congress:</p> <blockquote><p>[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.</p></blockquote>
+               </div>
+
+               <br style="clear: both">
+
+               <h2 class="samples">Classic (iframe-based) Example</h2>
+
+               <textarea cols="80" id="editor1" name="editor1" rows="10">
+                       &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+
+               <p style="overflow: hidden">
+                       <input style="float: left" type="submit" value="Submit">
+                       <span style="float: right">
+                               <input type="text" id="val" value="I'm using jQuery val()!" size="30">
+                               <input onclick="setValue();" type="button" value="Set value">
+                       </span>
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/readonly.html b/sources/samples/old/readonly.html
new file mode 100644 (file)
index 0000000..084d6af
--- /dev/null
@@ -0,0 +1,76 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Using the CKEditor Read-Only API &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+       <script>
+
+               var editor;
+
+               // The instanceReady event is fired, when an instance of CKEditor has finished
+               // its initialization.
+               CKEDITOR.on( 'instanceReady', function( ev ) {
+                       editor = ev.editor;
+
+                       // Show this "on" button.
+                       document.getElementById( 'readOnlyOn' ).style.display = '';
+
+                       // Event fired when the readOnly property changes.
+                       editor.on( 'readOnly', function() {
+                               document.getElementById( 'readOnlyOn' ).style.display = this.readOnly ? 'none' : '';
+                               document.getElementById( 'readOnlyOff' ).style.display = this.readOnly ? '' : 'none';
+                       });
+               });
+
+               function toggleReadOnly( isReadOnly ) {
+                       // Change the read-only state of the editor.
+                       // http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly
+                       editor.setReadOnly( isReadOnly );
+               }
+
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Using the CKEditor Read-Only API
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/readonly.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to use the
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.editor-method-setReadOnly">setReadOnly</a></code>
+                       API to put editor into the read-only state that makes it impossible for users to change the editor contents.
+               </p>
+               <p>
+                       For details on how to create this setup check the source code of this sample page.
+               </p>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <p>
+                       <textarea class="ckeditor" id="editor1" name="editor1" cols="100" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+               </p>
+               <p>
+                       <input id="readOnlyOn" onclick="toggleReadOnly();" type="button" value="Make it read-only" style="display:none">
+                       <input id="readOnlyOff" onclick="toggleReadOnly( false );" type="button" value="Make it editable again" style="display:none">
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/replacebyclass.html b/sources/samples/old/replacebyclass.html
new file mode 100644 (file)
index 0000000..23652d6
--- /dev/null
@@ -0,0 +1,60 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Replace Textareas by Class Name &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea Elements by Class Name
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out the <a href="http://sdk.ckeditor.com/">brand new samples in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to automatically replace all <code>&lt;textarea&gt;</code> elements
+                       of a given class with a CKEditor instance.
+               </p>
+               <p>
+                       To replace a <code>&lt;textarea&gt;</code> element, simply assign it the <code>ckeditor</code>
+                       class, as in the code below:
+               </p>
+<pre class="samples">
+&lt;textarea <strong>class="ckeditor</strong>" name="editor1"&gt;&lt;/textarea&gt;
+</pre>
+               <p>
+                       Note that other <code>&lt;textarea&gt;</code> attributes (like <code>id</code> or <code>name</code>) need to be adjusted to your document.
+               </p>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <p>
+                       <label for="editor1">
+                               Editor 1:
+                       </label>
+                       <textarea class="ckeditor" cols="80" id="editor1" name="editor1" rows="10">
+                               &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+                       </textarea>
+               </p>
+               <p>
+                       <input type="submit" value="Submit">
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/replacebycode.html b/sources/samples/old/replacebycode.html
new file mode 100644 (file)
index 0000000..a4f4395
--- /dev/null
@@ -0,0 +1,59 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>Replace Textarea by Code &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Replace Textarea Elements Using JavaScript Code
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/classic.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <div class="description">
+                       <p>
+                               This editor is using an <code>&lt;iframe&gt;</code> element-based editing area, provided by the <strong>Wysiwygarea</strong> plugin.
+                       </p>
+<pre class="samples">
+CKEDITOR.replace( '<em>textarea_id</em>' )
+</pre>
+               </div>
+               <textarea cols="80" id="editor1" name="editor1" rows="10">
+                       &lt;h1&gt;&lt;img alt=&quot;Saturn V carrying Apollo 11&quot; class=&quot;right&quot; src=&quot;assets/sample.jpg&quot;/&gt; Apollo 11&lt;/h1&gt; &lt;p&gt;&lt;b&gt;Apollo 11&lt;/b&gt; was the spaceflight that landed the first humans, Americans &lt;a href=&quot;http://en.wikipedia.org/wiki/Neil_Armstrong&quot; title=&quot;Neil Armstrong&quot;&gt;Neil Armstrong&lt;/a&gt; and &lt;a href=&quot;http://en.wikipedia.org/wiki/Buzz_Aldrin&quot; title=&quot;Buzz Aldrin&quot;&gt;Buzz Aldrin&lt;/a&gt;, on the Moon on July 20, 1969, at 20:18 UTC. Armstrong became the first to step onto the lunar surface 6 hours later on July 21 at 02:56 UTC.&lt;/p&gt; &lt;p&gt;Armstrong spent about &lt;s&gt;three and a half&lt;/s&gt; two and a half hours outside the spacecraft, Aldrin slightly less; and together they collected 47.5 pounds (21.5&amp;nbsp;kg) of lunar material for return to Earth. A third member of the mission, &lt;a href=&quot;http://en.wikipedia.org/wiki/Michael_Collins_(astronaut)&quot; title=&quot;Michael Collins (astronaut)&quot;&gt;Michael Collins&lt;/a&gt;, piloted the &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_Command/Service_Module&quot; title=&quot;Apollo Command/Service Module&quot;&gt;command&lt;/a&gt; spacecraft alone in lunar orbit until Armstrong and Aldrin returned to it for the trip back to Earth.&lt;/p&gt; &lt;h2&gt;Broadcasting and &lt;em&gt;quotes&lt;/em&gt; &lt;a id=&quot;quotes&quot; name=&quot;quotes&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;p&gt;Broadcast on live TV to a world-wide audience, Armstrong stepped onto the lunar surface and described the event as:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;One small step for [a] man, one giant leap for mankind.&lt;/p&gt;&lt;/blockquote&gt; &lt;p&gt;Apollo 11 effectively ended the &lt;a href=&quot;http://en.wikipedia.org/wiki/Space_Race&quot; title=&quot;Space Race&quot;&gt;Space Race&lt;/a&gt; and fulfilled a national goal proposed in 1961 by the late U.S. President &lt;a href=&quot;http://en.wikipedia.org/wiki/John_F._Kennedy&quot; title=&quot;John F. Kennedy&quot;&gt;John F. Kennedy&lt;/a&gt; in a speech before the United States Congress:&lt;/p&gt; &lt;blockquote&gt;&lt;p&gt;[...] before this decade is out, of landing a man on the Moon and returning him safely to the Earth.&lt;/p&gt;&lt;/blockquote&gt; &lt;h2&gt;Technical details &lt;a id=&quot;tech-details&quot; name=&quot;tech-details&quot;&gt;&lt;/a&gt;&lt;/h2&gt; &lt;table align=&quot;right&quot; border=&quot;1&quot; bordercolor=&quot;#ccc&quot; cellpadding=&quot;5&quot; cellspacing=&quot;0&quot; style=&quot;border-collapse:collapse;margin:10px 0 10px 15px;&quot;&gt; &lt;caption&gt;&lt;strong&gt;Mission crew&lt;/strong&gt;&lt;/caption&gt; &lt;thead&gt; &lt;tr&gt; &lt;th scope=&quot;col&quot;&gt;Position&lt;/th&gt; &lt;th scope=&quot;col&quot;&gt;Astronaut&lt;/th&gt; &lt;/tr&gt; &lt;/thead&gt; &lt;tbody&gt; &lt;tr&gt; &lt;td&gt;Commander&lt;/td&gt; &lt;td&gt;Neil A. Armstrong&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Command Module Pilot&lt;/td&gt; &lt;td&gt;Michael Collins&lt;/td&gt; &lt;/tr&gt; &lt;tr&gt; &lt;td&gt;Lunar Module Pilot&lt;/td&gt; &lt;td&gt;Edwin &amp;quot;Buzz&amp;quot; E. Aldrin, Jr.&lt;/td&gt; &lt;/tr&gt; &lt;/tbody&gt; &lt;/table&gt; &lt;p&gt;Launched by a &lt;strong&gt;Saturn V&lt;/strong&gt; rocket from &lt;a href=&quot;http://en.wikipedia.org/wiki/Kennedy_Space_Center&quot; title=&quot;Kennedy Space Center&quot;&gt;Kennedy Space Center&lt;/a&gt; in Merritt Island, Florida on July 16, Apollo 11 was the fifth manned mission of &lt;a href=&quot;http://en.wikipedia.org/wiki/NASA&quot; title=&quot;NASA&quot;&gt;NASA&lt;/a&gt;&amp;#39;s Apollo program. The Apollo spacecraft had three parts:&lt;/p&gt; &lt;ol&gt; &lt;li&gt;&lt;strong&gt;Command Module&lt;/strong&gt; with a cabin for the three astronauts which was the only part which landed back on Earth&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Service Module&lt;/strong&gt; which supported the Command Module with propulsion, electrical power, oxygen and water&lt;/li&gt; &lt;li&gt;&lt;strong&gt;Lunar Module&lt;/strong&gt; for landing on the Moon.&lt;/li&gt; &lt;/ol&gt; &lt;p&gt;After being sent to the Moon by the Saturn V&amp;#39;s upper stage, the astronauts separated the spacecraft from it and travelled for three days until they entered into lunar orbit. Armstrong and Aldrin then moved into the Lunar Module and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Mare_Tranquillitatis&quot; title=&quot;Mare Tranquillitatis&quot;&gt;Sea of Tranquility&lt;/a&gt;. They stayed a total of about 21 and a half hours on the lunar surface. After lifting off in the upper part of the Lunar Module and rejoining Collins in the Command Module, they returned to Earth and landed in the &lt;a href=&quot;http://en.wikipedia.org/wiki/Pacific_Ocean&quot; title=&quot;Pacific Ocean&quot;&gt;Pacific Ocean&lt;/a&gt; on July 24.&lt;/p&gt; &lt;hr/&gt; &lt;p style=&quot;text-align: right;&quot;&gt;&lt;small&gt;Source: &lt;a href=&quot;http://en.wikipedia.org/wiki/Apollo_11&quot;&gt;Wikipedia.org&lt;/a&gt;&lt;/small&gt;&lt;/p&gt;
+               </textarea>
+               <script>
+
+                       // This call can be placed at any point after the
+                       // <textarea>, or inside a <head><script> in a
+                       // window.onload event handler.
+
+                       // Replace the <textarea id="editor"> with an CKEditor
+                       // instance, using default configurations.
+
+                       CKEDITOR.replace( 'editor1' );
+
+               </script>
+               <p>
+                       <input type="submit" value="Submit">
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/sample.css b/sources/samples/old/sample.css
new file mode 100644 (file)
index 0000000..3304111
--- /dev/null
@@ -0,0 +1,357 @@
+/*
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+*/
+
+html, body, h1, h2, h3, h4, h5, h6, div, span, blockquote, p, address, form, fieldset, img, ul, ol, dl, dt, dd, li, hr, table, td, th, strong, em, sup, sub, dfn, ins, del, q, cite, var, samp, code, kbd, tt, pre
+{
+       line-height: 1.5;
+}
+
+body
+{
+       padding: 10px 30px;
+}
+
+input, textarea, select, option, optgroup, button, td, th
+{
+       font-size: 100%;
+}
+
+pre
+{
+       -moz-tab-size: 4;
+       tab-size: 4;
+}
+
+pre, code, kbd, samp, tt
+{
+       font-family: monospace,monospace;
+       font-size: 1em;
+}
+
+body {
+       width: 960px;
+       margin: 0 auto;
+}
+
+code
+{
+       background: #f3f3f3;
+       border: 1px solid #ddd;
+       padding: 1px 4px;
+       border-radius: 3px;
+}
+
+abbr
+{
+       border-bottom: 1px dotted #555;
+       cursor: pointer;
+}
+
+.new, .beta
+{
+       text-transform: uppercase;
+       font-size: 10px;
+       font-weight: bold;
+       padding: 1px 4px;
+       margin: 0 0 0 5px;
+       color: #fff;
+       float: right;
+       border-radius: 3px;
+}
+
+.new
+{
+       background: #FF7E00;
+       border: 1px solid #DA8028;
+       text-shadow: 0 1px 0 #C97626;
+
+       box-shadow: 0 2px 3px 0 #FFA54E inset;
+}
+
+.beta
+{
+       background: #18C0DF;
+       border: 1px solid #19AAD8;
+       text-shadow: 0 1px 0 #048CAD;
+       font-style: italic;
+
+       box-shadow: 0 2px 3px 0 #50D4FD inset;
+}
+
+h1.samples
+{
+       color: #0782C1;
+       font-size: 200%;
+       font-weight: normal;
+       margin: 0;
+       padding: 0;
+}
+
+h1.samples a
+{
+       color: #0782C1;
+       text-decoration: none;
+       border-bottom: 1px dotted #0782C1;
+}
+
+.samples a:hover
+{
+       border-bottom: 1px dotted #0782C1;
+}
+
+h2.samples
+{
+       color: #000000;
+       font-size: 130%;
+       margin: 15px 0 0 0;
+       padding: 0;
+}
+
+p, blockquote, address, form, pre, dl, h1.samples, h2.samples
+{
+       margin-bottom: 15px;
+}
+
+ul.samples
+{
+       margin-bottom: 15px;
+}
+
+.clear
+{
+       clear: both;
+}
+
+fieldset
+{
+       margin: 0;
+       padding: 10px;
+}
+
+body, input, textarea
+{
+       color: #333333;
+       font-family: Arial, Helvetica, sans-serif;
+}
+
+body
+{
+       font-size: 75%;
+}
+
+a.samples
+{
+       color: #189DE1;
+       text-decoration: none;
+}
+
+form
+{
+       margin: 0;
+       padding: 0;
+}
+
+pre.samples
+{
+       background-color: #F7F7F7;
+       border: 1px solid #D7D7D7;
+       overflow: auto;
+       padding: 0.25em;
+       white-space: pre-wrap; /* CSS 2.1 */
+       word-wrap: break-word; /* IE7 */
+}
+
+#footer
+{
+       clear: both;
+       padding-top: 10px;
+}
+
+#footer hr
+{
+       margin: 10px 0 15px 0;
+       height: 1px;
+       border: solid 1px gray;
+       border-bottom: none;
+}
+
+#footer p
+{
+       margin: 0 10px 10px 10px;
+       float: left;
+}
+
+#footer #copy
+{
+       float: right;
+}
+
+#outputSample
+{
+       width: 100%;
+       table-layout: fixed;
+}
+
+#outputSample thead th
+{
+       color: #dddddd;
+       background-color: #999999;
+       padding: 4px;
+       white-space: nowrap;
+}
+
+#outputSample tbody th
+{
+       vertical-align: top;
+       text-align: left;
+}
+
+#outputSample pre
+{
+       margin: 0;
+       padding: 0;
+}
+
+.description
+{
+       border: 1px dotted #B7B7B7;
+       margin-bottom: 10px;
+       padding: 10px 10px 0;
+       overflow: hidden;
+}
+
+label
+{
+       display: block;
+       margin-bottom: 6px;
+}
+
+/**
+ *     CKEditor editables are automatically set with the "cke_editable" class
+ *     plus cke_editable_(inline|themed) depending on the editor type.
+ */
+
+/* Style a bit the inline editables. */
+.cke_editable.cke_editable_inline
+{
+       cursor: pointer;
+}
+
+/* Once an editable element gets focused, the "cke_focus" class is
+   added to it, so we can style it differently. */
+.cke_editable.cke_editable_inline.cke_focus
+{
+       box-shadow: inset 0px 0px 20px 3px #ddd, inset 0 0 1px #000;
+       outline: none;
+       background: #eee;
+       cursor: text;
+}
+
+/* Avoid pre-formatted overflows inline editable. */
+.cke_editable_inline pre
+{
+       white-space: pre-wrap;
+       word-wrap: break-word;
+}
+
+/**
+ *     Samples index styles.
+ */
+
+.twoColumns,
+.twoColumnsLeft,
+.twoColumnsRight
+{
+       overflow: hidden;
+}
+
+.twoColumnsLeft,
+.twoColumnsRight
+{
+       width: 45%;
+}
+
+.twoColumnsLeft
+{
+       float: left;
+}
+
+.twoColumnsRight
+{
+       float: right;
+}
+
+dl.samples
+{
+       padding: 0 0 0 40px;
+}
+dl.samples > dt
+{
+       display: list-item;
+       list-style-type: disc;
+       list-style-position: outside;
+       margin: 0 0 3px;
+}
+dl.samples > dd
+{
+       margin: 0 0 3px;
+}
+.warning
+{
+       color: #ff0000;
+       background-color: #FFCCBA;
+       border: 2px dotted #ff0000;
+       padding: 15px 10px;
+       margin: 10px 0;
+}
+
+.warning.deprecated {
+       font-size: 1.3em;
+}
+
+/* Used on inline samples */
+
+blockquote
+{
+       font-style: italic;
+       font-family: Georgia, Times, "Times New Roman", serif;
+       padding: 2px 0;
+       border-style: solid;
+       border-color: #ccc;
+       border-width: 0;
+}
+
+.cke_contents_ltr blockquote
+{
+       padding-left: 20px;
+       padding-right: 8px;
+       border-left-width: 5px;
+}
+
+.cke_contents_rtl blockquote
+{
+       padding-left: 8px;
+       padding-right: 20px;
+       border-right-width: 5px;
+}
+
+img.right {
+       border: 1px solid #ccc;
+       float: right;
+       margin-left: 15px;
+       padding: 5px;
+}
+
+img.left {
+       border: 1px solid #ccc;
+       float: left;
+       margin-right: 15px;
+       padding: 5px;
+}
+
+.marker
+{
+       background-color: Yellow;
+}
diff --git a/sources/samples/old/sample.js b/sources/samples/old/sample.js
new file mode 100644 (file)
index 0000000..7d4c74e
--- /dev/null
@@ -0,0 +1,51 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+// Tool scripts for the sample pages.
+// This file can be ignored and is not required to make use of CKEditor.
+
+( function() {
+       CKEDITOR.on( 'instanceReady', function( ev ) {
+               // Check for sample compliance.
+               var editor = ev.editor,
+                       meta = CKEDITOR.document.$.getElementsByName( 'ckeditor-sample-required-plugins' ),
+                       requires = meta.length ? CKEDITOR.dom.element.get( meta[ 0 ] ).getAttribute( 'content' ).split( ',' ) : [],
+                       missing = [],
+                       i;
+
+               if ( requires.length ) {
+                       for ( i = 0; i < requires.length; i++ ) {
+                               if ( !editor.plugins[ requires[ i ] ] )
+                                       missing.push( '<code>' + requires[ i ] + '</code>' );
+                       }
+
+                       if ( missing.length ) {
+                               var warn = CKEDITOR.dom.element.createFromHtml(
+                                       '<div class="warning">' +
+                                               '<span>To fully experience this demo, the ' + missing.join( ', ' ) + ' plugin' + ( missing.length > 1 ? 's are' : ' is' ) + ' required.</span>' +
+                                       '</div>'
+                               );
+                               warn.insertBefore( editor.container );
+                       }
+               }
+
+               // Set icons.
+               var doc = new CKEDITOR.dom.document( document ),
+                       icons = doc.find( '.button_icon' );
+
+               for ( i = 0; i < icons.count(); i++ ) {
+                       var icon = icons.getItem( i ),
+                               name = icon.getAttribute( 'data-icon' ),
+                               style = CKEDITOR.skin.getIconStyle( name, ( CKEDITOR.lang.dir == 'rtl' ) );
+
+                       icon.addClass( 'cke_button_icon' );
+                       icon.addClass( 'cke_button__' + name + '_icon' );
+                       icon.setAttribute( 'style', style );
+                       icon.setStyle( 'float', 'none' );
+
+               }
+       } );
+} )();
+// %LEAVE_UNMINIFIED% %REMOVE_LINE%
diff --git a/sources/samples/old/sample_posteddata.php b/sources/samples/old/sample_posteddata.php
new file mode 100644 (file)
index 0000000..54e9b7c
--- /dev/null
@@ -0,0 +1,16 @@
+<?php /* <body><pre>
+
+-------------------------------------------------------------------------------------------
+  CKEditor - Posted Data
+
+  We are sorry, but your Web server does not support the PHP language used in this script.
+
+  Please note that CKEditor can be used with any other server-side language than just PHP.
+  To save the content created with CKEditor you need to read the POST data on the server
+  side and write it to a file or the database.
+
+  Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+  For licensing, see LICENSE.md or http://ckeditor.com/license
+-------------------------------------------------------------------------------------------
+
+</pre><div style="display:none"></body> */ include "assets/posteddata.php"; ?>
diff --git a/sources/samples/old/tabindex.html b/sources/samples/old/tabindex.html
new file mode 100644 (file)
index 0000000..4238f33
--- /dev/null
@@ -0,0 +1,78 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>TAB Key-Based Navigation &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link href="sample.css" rel="stylesheet">
+       <style>
+
+               .cke_focused,
+               .cke_editable.cke_focused
+               {
+                       outline: 3px dotted blue !important;
+                       *border: 3px dotted blue !important;    /* For IE7 */
+               }
+
+       </style>
+       <script>
+
+               CKEDITOR.on( 'instanceReady', function( evt ) {
+                       var editor = evt.editor;
+                       editor.setData( 'This editor has it\'s tabIndex set to <strong>' + editor.tabIndex + '</strong>' );
+
+                       // Apply focus class name.
+                       editor.on( 'focus', function() {
+                               editor.container.addClass( 'cke_focused' );
+                       });
+                       editor.on( 'blur', function() {
+                               editor.container.removeClass( 'cke_focused' );
+                       });
+
+                       // Put startup focus on the first editor in tab order.
+                       if ( editor.tabIndex == 1 )
+                               editor.focus();
+               });
+
+       </script>
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; TAB Key-Based Navigation
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/tabindex.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how tab key navigation among editor instances is
+                       affected by the <code>tabIndex</code> attribute from
+                       the original page element. Use TAB key to move between the editors.
+               </p>
+       </div>
+       <p>
+               <textarea class="ckeditor" cols="80" id="editor4" rows="10" tabindex="1"></textarea>
+       </p>
+       <div class="ckeditor" contenteditable="true" id="editor1" tabindex="4"></div>
+       <p>
+               <textarea class="ckeditor" cols="80" id="editor2" rows="10" tabindex="2"></textarea>
+       </p>
+       <p>
+               <textarea class="ckeditor" cols="80" id="editor3" rows="10" tabindex="3"></textarea>
+       </p>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/uicolor.html b/sources/samples/old/uicolor.html
new file mode 100644 (file)
index 0000000..fb61b1f
--- /dev/null
@@ -0,0 +1,72 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>UI Color Picker &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; UI Color
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/uicolor.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to automatically replace <code>&lt;textarea&gt;</code> elements
+                       with a CKEditor instance with an option to change the color of its user interface.<br>
+                       <strong>Note:</strong>The UI skin color feature depends on the CKEditor skin
+                       compatibility. The Moono and Kama skins are examples of skins that work with it.
+               </p>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+       <p>
+               This editor instance has a UI color value defined in configuration to change the skin color,
+               To specify the color of the user interface, set the <code>uiColor</code> property:
+       </p>
+       <pre class="samples">
+CKEDITOR.replace( '<em>textarea_id</em>', {
+       <strong>uiColor: '#14B8C4'</strong>
+});</pre>
+       <p>
+               Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of
+               the <code>&lt;textarea&gt;</code> element to be replaced.
+       </p>
+       <p>
+               <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+               <script>
+
+                       // Replace the <textarea id="editor"> with an CKEditor
+                       // instance, using default configurations.
+                       CKEDITOR.replace( 'editor1', {
+                               uiColor: '#14B8C4',
+                               toolbar: [
+                                       [ 'Bold', 'Italic', '-', 'NumberedList', 'BulletedList', '-', 'Link', 'Unlink' ],
+                                       [ 'FontSize', 'TextColor', 'BGColor' ]
+                               ]
+                       });
+
+               </script>
+       </p>
+       <p>
+               <input type="submit" value="Submit">
+       </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/uilanguages.html b/sources/samples/old/uilanguages.html
new file mode 100644 (file)
index 0000000..76749cb
--- /dev/null
@@ -0,0 +1,122 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>User Interface Globalization &mdash; CKEditor Sample</title>
+       <script src="../../ckeditor.js"></script>
+       <script src="assets/uilanguages/languages.js"></script>
+       <link rel="stylesheet" href="sample.css">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; User Interface Languages
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/uilanguages.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to automatically replace <code>&lt;textarea&gt;</code> elements
+                       with a CKEditor instance with an option to change the language of its user interface.
+               </p>
+               <p>
+                       It pulls the language list from CKEditor <code>_languages.js</code> file that contains the list of supported languages and creates
+                       a drop-down list that lets the user change the UI language.
+               </p>
+               <p>
+                       By default, CKEditor automatically localizes the editor to the language of the user.
+                       The UI language can be controlled with two configuration options:
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-language">language</a></code> and
+                       <code><a class="samples" href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-defaultLanguage">
+                       defaultLanguage</a></code>. The <code>defaultLanguage</code> setting specifies the
+                       default CKEditor language to be used when a localization suitable for user's settings is not available.
+               </p>
+               <p>
+                       To specify the user interface language that will be used no matter what language is
+                       specified in user's browser or operating system, set the <code>language</code> property:
+               </p>
+<pre class="samples">
+CKEDITOR.replace( '<em>textarea_id</em>', {
+       // Load the German interface.
+       <strong>language: 'de'</strong>
+});</pre>
+               <p>
+                       Note that <code><em>textarea_id</em></code> in the code above is the <code>id</code> attribute of
+                       the <code>&lt;textarea&gt;</code> element to be replaced.
+               </p>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <p>
+                       Available languages (<span id="count"> </span> languages!):<br>
+                       <script>
+
+                               document.write( '<select disabled="disabled" id="languages" onchange="createEditor( this.value );">' );
+
+                               // Get the language list from the _languages.js file.
+                               for ( var i = 0 ; i < window.CKEDITOR_LANGS.length ; i++ ) {
+                                       document.write(
+                                               '<option value="' + window.CKEDITOR_LANGS[i].code + '">' +
+                                                       window.CKEDITOR_LANGS[i].name +
+                                               '</option>' );
+                               }
+
+                               document.write( '</select>' );
+
+                       </script>
+                       <br>
+                       <span style="color: #888888">
+                               (You may see strange characters if your system does not support the selected language)
+                       </span>
+               </p>
+               <p>
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+                       <script>
+
+                               // Set the number of languages.
+                               document.getElementById( 'count' ).innerHTML = window.CKEDITOR_LANGS.length;
+
+                               var editor;
+
+                               function createEditor( languageCode ) {
+                                       if ( editor )
+                                               editor.destroy();
+
+                                       // Replace the <textarea id="editor"> with an CKEditor
+                                       // instance, using default configurations.
+                                       editor = CKEDITOR.replace( 'editor1', {
+                                               language: languageCode,
+
+                                               on: {
+                                                       instanceReady: function() {
+                                                               // Wait for the editor to be ready to set
+                                                               // the language combo.
+                                                               var languages = document.getElementById( 'languages' );
+                                                               languages.value = this.langCode;
+                                                               languages.disabled = false;
+                                                       }
+                                               }
+                                       });
+                               }
+
+                               // At page startup, load the default language:
+                               createEditor( '' );
+
+                       </script>
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/old/xhtmlstyle.html b/sources/samples/old/xhtmlstyle.html
new file mode 100644 (file)
index 0000000..c918766
--- /dev/null
@@ -0,0 +1,234 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<html>
+<head>
+       <meta charset="utf-8">
+       <title>XHTML Compliant Output &mdash; CKEditor Sample</title>
+       <meta name="ckeditor-sample-required-plugins" content="sourcearea">
+       <script src="../../ckeditor.js"></script>
+       <script src="sample.js"></script>
+       <link href="sample.css" rel="stylesheet">
+</head>
+<body>
+       <h1 class="samples">
+               <a href="index.html">CKEditor Samples</a> &raquo; Producing XHTML Compliant Output
+       </h1>
+       <div class="warning deprecated">
+               This sample is not maintained anymore. Check out its <a href="http://sdk.ckeditor.com/samples/basicstyles.html">brand new version in CKEditor SDK</a>.
+       </div>
+       <div class="description">
+               <p>
+                       This sample shows how to configure CKEditor to output valid
+                       <a class="samples" href="http://www.w3.org/TR/xhtml11/">XHTML 1.1</a> code.
+                       Deprecated elements (<code>&lt;font&gt;</code>, <code>&lt;u&gt;</code>) or attributes
+                       (<code>size</code>, <code>face</code>) will be replaced with XHTML compliant code.
+               </p>
+               <p>
+                       To add a CKEditor instance outputting valid XHTML code, load the editor using a standard
+                       JavaScript call and define CKEditor features to use the XHTML compliant elements and styles.
+               </p>
+               <p>
+                       A snippet of the configuration code can be seen below; check the source of this page for
+                       full definition:
+               </p>
+<pre class="samples">
+CKEDITOR.replace( '<em>textarea_id</em>', {
+       contentsCss: 'assets/outputxhtml.css',
+
+       coreStyles_bold: {
+               element: 'span',
+               attributes: { 'class': 'Bold' }
+       },
+       coreStyles_italic: {
+               element: 'span',
+               attributes: { 'class': 'Italic' }
+       },
+
+       ...
+});</pre>
+       </div>
+       <form action="sample_posteddata.php" method="post">
+               <p>
+                       <label for="editor1">
+                               Editor 1:
+                       </label>
+                       <textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;span class="Bold"&gt;sample text&lt;/span&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+                       <script>
+
+                               CKEDITOR.replace( 'editor1', {
+                                       /*
+                                        * Style sheet for the contents
+                                        */
+                                       contentsCss: 'assets/outputxhtml/outputxhtml.css',
+
+                                       /*
+                                        * Special allowed content rules for spans used by
+                                        * font face, size, and color buttons.
+                                        *
+                                        * Note: all rules have been written separately so
+                                        * it was possible to specify required classes.
+                                        */
+                                       extraAllowedContent: 'span(!FontColor1);span(!FontColor2);span(!FontColor3);' +
+                                               'span(!FontColor1BG);span(!FontColor2BG);span(!FontColor3BG);' +
+                                               'span(!FontComic);span(!FontCourier);span(!FontTimes);' +
+                                               'span(!FontSmaller);span(!FontLarger);span(!FontSmall);span(!FontBig);span(!FontDouble)',
+
+                                       /*
+                                        * Core styles.
+                                        */
+                                       coreStyles_bold: {
+                                               element: 'span',
+                                               attributes: { 'class': 'Bold' }
+                                       },
+                                       coreStyles_italic: {
+                                               element: 'span',
+                                               attributes: { 'class': 'Italic' }
+                                       },
+                                       coreStyles_underline: {
+                                               element: 'span',
+                                               attributes: { 'class': 'Underline' }
+                                       },
+                                       coreStyles_strike: {
+                                               element: 'span',
+                                               attributes: { 'class': 'StrikeThrough' },
+                                               overrides: 'strike'
+                                       },
+                                       coreStyles_subscript: {
+                                               element: 'span',
+                                               attributes: { 'class': 'Subscript' },
+                                               overrides: 'sub'
+                                       },
+                                       coreStyles_superscript: {
+                                               element: 'span',
+                                               attributes: { 'class': 'Superscript' },
+                                               overrides: 'sup'
+                                       },
+
+                                       /*
+                                        * Font face.
+                                        */
+
+                                       // List of fonts available in the toolbar combo. Each font definition is
+                                       // separated by a semi-colon (;). We are using class names here, so each font
+                                       // is defined by {Combo Label}/{Class Name}.
+                                       font_names: 'Comic Sans MS/FontComic;Courier New/FontCourier;Times New Roman/FontTimes',
+
+                                       // Define the way font elements will be applied to the document. The "span"
+                                       // element will be used. When a font is selected, the font name defined in the
+                                       // above list is passed to this definition with the name "Font", being it
+                                       // injected in the "class" attribute.
+                                       // We must also instruct the editor to replace span elements that are used to
+                                       // set the font (Overrides).
+                                       font_style: {
+                                               element: 'span',
+                                               attributes: { 'class': '#(family)' },
+                                               overrides: [
+                                                       {
+                                                               element: 'span',
+                                                               attributes: {
+                                                                       'class': /^Font(?:Comic|Courier|Times)$/
+                                                               }
+                                                       }
+                                               ]
+                                       },
+
+                                       /*
+                                        * Font sizes.
+                                        */
+                                       fontSize_sizes: 'Smaller/FontSmaller;Larger/FontLarger;8pt/FontSmall;14pt/FontBig;Double Size/FontDouble',
+                                       fontSize_style: {
+                                               element: 'span',
+                                               attributes: { 'class': '#(size)' },
+                                               overrides: [
+                                                       {
+                                                               element: 'span',
+                                                               attributes: {
+                                                                       'class': /^Font(?:Smaller|Larger|Small|Big|Double)$/
+                                                               }
+                                                       }
+                                               ]
+                                       } ,
+
+                                       /*
+                                        * Font colors.
+                                        */
+                                       colorButton_enableMore: false,
+
+                                       colorButton_colors: 'FontColor1/FF9900,FontColor2/0066CC,FontColor3/F00',
+                                       colorButton_foreStyle: {
+                                               element: 'span',
+                                               attributes: { 'class': '#(color)' },
+                                               overrides: [
+                                                       {
+                                                               element: 'span',
+                                                               attributes: {
+                                                                       'class': /^FontColor(?:1|2|3)$/
+                                                               }
+                                                       }
+                                               ]
+                                       },
+
+                                       colorButton_backStyle: {
+                                               element: 'span',
+                                               attributes: { 'class': '#(color)BG' },
+                                               overrides: [
+                                                       {
+                                                               element: 'span',
+                                                               attributes: {
+                                                                       'class': /^FontColor(?:1|2|3)BG$/
+                                                               }
+                                                       }
+                                               ]
+                                       },
+
+                                       /*
+                                        * Indentation.
+                                        */
+                                       indentClasses: [ 'Indent1', 'Indent2', 'Indent3' ],
+
+                                       /*
+                                        * Paragraph justification.
+                                        */
+                                       justifyClasses: [ 'JustifyLeft', 'JustifyCenter', 'JustifyRight', 'JustifyFull' ],
+
+                                       /*
+                                        * Styles combo.
+                                        */
+                                       stylesSet: [
+                                               { name: 'Strong Emphasis', element: 'strong' },
+                                               { name: 'Emphasis', element: 'em' },
+
+                                               { name: 'Computer Code', element: 'code' },
+                                               { name: 'Keyboard Phrase', element: 'kbd' },
+                                               { name: 'Sample Text', element: 'samp' },
+                                               { name: 'Variable', element: 'var' },
+
+                                               { name: 'Deleted Text', element: 'del' },
+                                               { name: 'Inserted Text', element: 'ins' },
+
+                                               { name: 'Cited Work', element: 'cite' },
+                                               { name: 'Inline Quotation', element: 'q' }
+                                       ]
+                               });
+
+                       </script>
+               </p>
+               <p>
+                       <input type="submit" value="Submit">
+               </p>
+       </form>
+       <div id="footer">
+               <hr>
+               <p>
+                       CKEditor - The text editor for the Internet - <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+               </p>
+               <p id="copy">
+                       Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> - Frederico
+                       Knabben. All rights reserved.
+               </p>
+       </div>
+</body>
+</html>
diff --git a/sources/samples/toolbarconfigurator/bender.js b/sources/samples/toolbarconfigurator/bender.js
new file mode 100644 (file)
index 0000000..d592866
--- /dev/null
@@ -0,0 +1,52 @@
+/* jshint browser: false, node: true */
+
+'use strict';
+
+var config = {
+
+       applications: {
+               ckeditor: {
+                       path: '../../',
+                       files: [
+                               'ckeditor.js'
+                       ]
+               },
+
+               codemirror: {
+                       path: '.',
+                       files: [
+                               'js/lib/codemirror/codemirror.js'
+                       ]
+               },
+
+               toolbartool: {
+                       path: '.',
+                       files: [
+                               'js/fulltoolbareditor.js',
+                               'js/abstracttoolbarmodifier.js',
+                               'js/toolbarmodifier.js',
+                               'js/toolbartextmodifier.js'
+                       ]
+               }
+       },
+
+       plugins: [
+               'node_modules/benderjs-mocha',
+               'node_modules/benderjs-chai'
+       ],
+
+       framework: 'mocha',
+
+       tests: {
+               'main': {
+                       applications: [ 'ckeditor', 'codemirror', 'toolbartool' ],
+                       basePath: 'tests/',
+                       paths: [
+                               '**',
+                               '!**/_*/**'
+                       ]
+               }
+       }
+};
+
+module.exports = config;
diff --git a/sources/samples/toolbarconfigurator/css/fontello.css b/sources/samples/toolbarconfigurator/css/fontello.css
new file mode 100644 (file)
index 0000000..bb32199
--- /dev/null
@@ -0,0 +1,55 @@
+@font-face {
+  font-family: 'fontello';
+  src: url('../font/fontello.eot?89024372');
+  src: url('../font/fontello.eot?89024372#iefix') format('embedded-opentype'),
+       url('../font/fontello.woff?89024372') format('woff'),
+       url('../font/fontello.ttf?89024372') format('truetype'),
+       url('../font/fontello.svg?89024372#fontello') format('svg');
+  font-weight: normal;
+  font-style: normal;
+}
+/* Chrome hack: SVG is rendered more smooth in Windozze. 100% magic, uncomment if you need it. */
+/* Note, that will break hinting! In other OS-es font will be not as sharp as it could be */
+/*
+@media screen and (-webkit-min-device-pixel-ratio:0) {
+  @font-face {
+    font-family: 'fontello';
+    src: url('../font/fontello.svg?89024372#fontello') format('svg');
+  }
+}
+*/
+ [class^="icon-"]:before, [class*=" icon-"]:before {
+  font-family: "fontello";
+  font-style: normal;
+  font-weight: normal;
+  speak: none;
+  display: inline-block;
+  text-decoration: inherit;
+  width: 1em;
+  margin-right: .2em;
+  text-align: center;
+  /* opacity: .8; */
+  /* For safety - reset parent styles, that can break glyph codes*/
+  font-variant: normal;
+  text-transform: none;
+     
+  /* fix buttons height, for twitter bootstrap */
+  line-height: 1em;
+  /* Animation center compensation - margins should be symmetric */
+  /* remove if not needed */
+  margin-left: .2em;
+  /* you can be more comfortable with increased icons size */
+  /* font-size: 120%; */
+  /* Uncomment for 3D effect */
+  /* text-shadow: 1px 1px 1px rgba(127, 127, 127, 0.3); */
+}
+.icon-trash:before { content: '\e802'; } /* '' */
+.icon-down-big:before { content: '\e800'; } /* '' */
+.icon-up-big:before { content: '\e801'; } /* '' */
\ No newline at end of file
diff --git a/sources/samples/toolbarconfigurator/font/LICENSE.txt b/sources/samples/toolbarconfigurator/font/LICENSE.txt
new file mode 100644 (file)
index 0000000..b511054
--- /dev/null
@@ -0,0 +1,12 @@
+Font license info
+
+
+## Font Awesome
+
+   Copyright (C) 2012 by Dave Gandy
+
+   Author:    Dave Gandy
+   License:   SIL ()
+   Homepage:  http://fortawesome.github.com/Font-Awesome/
+
+
diff --git a/sources/samples/toolbarconfigurator/font/config.json b/sources/samples/toolbarconfigurator/font/config.json
new file mode 100644 (file)
index 0000000..94809d7
--- /dev/null
@@ -0,0 +1,28 @@
+{
+  "name": "",
+  "css_prefix_text": "icon-",
+  "css_use_suffix": false,
+  "hinting": true,
+  "units_per_em": 1000,
+  "ascent": 850,
+  "glyphs": [
+    {
+      "uid": "f48ae54adfb27d8ada53d0fd9e34ee10",
+      "css": "trash-empty",
+      "code": 59392,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "1c4068ed75209e21af36017df8871802",
+      "css": "down-big",
+      "code": 59393,
+      "src": "fontawesome"
+    },
+    {
+      "uid": "95376bf082bfec6ce06ea1cda7bd7ead",
+      "css": "up-big",
+      "code": 59394,
+      "src": "fontawesome"
+    }
+  ]
+}
\ No newline at end of file
diff --git a/sources/samples/toolbarconfigurator/font/fontello.eot b/sources/samples/toolbarconfigurator/font/fontello.eot
new file mode 100644 (file)
index 0000000..2732fad
Binary files /dev/null and b/sources/samples/toolbarconfigurator/font/fontello.eot differ
diff --git a/sources/samples/toolbarconfigurator/font/fontello.svg b/sources/samples/toolbarconfigurator/font/fontello.svg
new file mode 100644 (file)
index 0000000..33d14ac
--- /dev/null
@@ -0,0 +1,14 @@
+<?xml version="1.0" standalone="no"?>
+<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
+<svg xmlns="http://www.w3.org/2000/svg">
+<metadata>Copyright (C) 2014 by original authors @ fontello.com</metadata>
+<defs>
+<font id="fontello" horiz-adv-x="1000" >
+<font-face font-family="fontello" font-weight="400" font-stretch="normal" units-per-em="1000" ascent="850" descent="-150" />
+<missing-glyph horiz-adv-x="1000" />
+<glyph glyph-name="trash" unicode="&#xe802;" d="m286 439v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m143 0v-321q0-8-5-13t-13-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q8 0 13-5t5-13z m142 0v-321q0-8-5-13t-12-5h-36q-8 0-13 5t-5 13v321q0 8 5 13t13 5h36q7 0 12-5t5-13z m72-404v529h-500v-529q0-12 4-22t8-15t6-5h464q2 0 6 5t8 15t4 22z m-375 601h250l-27 65q-4 5-9 6h-177q-6-1-10-6z m518-18v-36q0-8-5-13t-13-5h-54v-529q0-46-26-80t-63-34h-464q-37 0-63 33t-27 79v531h-53q-8 0-13 5t-5 13v36q0 8 5 13t13 5h172l39 93q9 21 31 35t44 15h178q22 0 44-15t30-35l39-93h173q8 0 13-5t5-13z" horiz-adv-x="785.7" />
+<glyph glyph-name="down-big" unicode="&#xe800;" d="m899 386q0-30-21-50l-363-364q-22-21-51-21q-29 0-50 21l-363 364q-21 20-21 50q0 29 21 51l41 41q22 21 51 21q29 0 50-21l164-164v393q0 29 21 50t51 22h71q29 0 50-22t21-50v-393l164 164q21 21 51 21q29 0 50-21l42-42q21-21 21-50z" horiz-adv-x="928.6" />
+<glyph glyph-name="up-big" unicode="&#xe801;" d="m899 308q0-28-21-50l-42-42q-21-21-50-21q-30 0-51 21l-164 164v-393q0-29-20-47t-51-19h-71q-30 0-51 19t-21 47v393l-164-164q-20-21-50-21t-50 21l-42 42q-21 21-21 50q0 30 21 51l363 363q20 21 50 21q30 0 51-21l363-363q21-22 21-51z" horiz-adv-x="928.6" />
+</font>
+</defs>
+</svg>
\ No newline at end of file
diff --git a/sources/samples/toolbarconfigurator/font/fontello.ttf b/sources/samples/toolbarconfigurator/font/fontello.ttf
new file mode 100644 (file)
index 0000000..fbcbf06
Binary files /dev/null and b/sources/samples/toolbarconfigurator/font/fontello.ttf differ
diff --git a/sources/samples/toolbarconfigurator/font/fontello.woff b/sources/samples/toolbarconfigurator/font/fontello.woff
new file mode 100644 (file)
index 0000000..e1d5647
Binary files /dev/null and b/sources/samples/toolbarconfigurator/font/fontello.woff differ
diff --git a/sources/samples/toolbarconfigurator/index.html b/sources/samples/toolbarconfigurator/index.html
new file mode 100644 (file)
index 0000000..4d31289
--- /dev/null
@@ -0,0 +1,446 @@
+<!DOCTYPE html>
+<!--
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.md or http://ckeditor.com/license
+-->
+<!--[if IE 8]><html class="ie8"><![endif]-->
+<!--[if gt IE 8]><html><![endif]-->
+<!--[if !IE]><!--><html><!--<![endif]-->
+<head>
+       <meta charset="utf-8">
+       <title>Toolbar Configurator</title>
+       <script src="../../ckeditor.js"></script>
+       <script>
+               if ( CKEDITOR.env.ie && CKEDITOR.env.version < 9 )
+                       CKEDITOR.tools.enableHtml5Elements( document );
+       </script>
+       <link rel="stylesheet" href="lib/codemirror/codemirror.css">
+       <link rel="stylesheet" href="lib/codemirror/show-hint.css">
+       <link rel="stylesheet" href="lib/codemirror/neo.css">
+       <link rel="stylesheet" href="css/fontello.css">
+       <link rel="stylesheet" href="../css/samples.css">
+</head>
+<body id="toolbar">
+
+<nav class="navigation-a">
+       <div class="grid-container">
+               <ul class="navigation-a-left grid-width-70">
+                       <li><a href="http://ckeditor.com">Project Homepage</a></li>
+                       <li><a href="http://dev.ckeditor.com/">I found a bug</a></li>
+                       <li><a href="http://github.com/ckeditor/ckeditor-dev" class="icon-pos-right icon-navigation-a-github">Fork CKEditor on GitHub</a></li>
+               </ul>
+               <ul class="navigation-a-right grid-width-30">
+                       <li><a href="http://ckeditor.com/blog-list">CKEditor Blog</a></li>
+               </ul>
+       </div>
+</nav>
+
+<header class="header-a">
+       <div class="grid-container">
+               <h1 class="header-a-logo grid-width-30">
+                       <a href="../index.html"><img src="../img/logo.png" alt="CKEditor Logo"></a>
+               </h1>
+               <nav class="navigation-b grid-width-70">
+                       <ul>
+                               <li><a href="../index.html"  class="button-a">Start</a></li>
+                               <li><a href="index.html"  class="button-a button-a-background">Toolbar configurator</a></li>
+                       </ul>
+               </nav>
+       </div>
+</header>
+
+<main>
+       <div class="adjoined-top">
+               <div class="grid-container">
+                       <div class="content grid-width-100">
+                               <div class="grid-container-nested">
+                                       <h1 class="grid-width-60">
+                                               Toolbar Configurator
+                                               <a href="#help-content" type="button" title="Configurator help" id="help" class="button-a button-a-background button-a-no-text icon-pos-left icon-question-mark">Help</a>
+                                       </h1>
+
+                                       <div class="grid-width-40 grid-switch-magic">
+                                               <div class="switch">
+                                                       <span class="balloon-a balloon-a-se">Select configurator type</span>
+                                                       <input type="radio" name="radio" data-num="1" id="radio-basic" />
+                                                       <input type="radio" name="radio" data-num="2" id="radio-advanced" />
+                                                       <label data-for="1" for="radio-basic">Basic</label>
+                                                       <span class="switch-inner">
+                                                               <span class="handler"></span>
+                                                       </span>
+                                                       <label data-for="2" for="radio-advanced">Advanced</label>
+                                               </div>
+                                       </div>
+                               </div>
+                       </div>
+               </div>
+       </div>
+       <div class="adjoined-bottom">
+               <div class="grid-container">
+                       <div class="grid-width-100">
+                               <div class="editors-container">
+                                       <div id="editor-basic"></div>
+                                       <div id="editor-advanced"></div>
+                               </div>
+                       </div>
+               </div>
+       </div>
+
+       <div class="grid-container configurator">
+               <div class="content grid-width-100">
+                       <div class="configurator">
+                               <div>
+                                       <div id="toolbarModifierWrapper"></div>
+                               </div>
+                       </div>
+               </div>
+       </div>
+
+       <div id="help-content">
+               <div class="grid-container">
+                       <div class="grid-width-100">
+                               <h2>What Am I Doing Here?</h2>
+
+                               <div class="grid-container grid-container-nested">
+                                       <div class="basic">
+                                               <div class="grid-width-50">
+                                                       <p>Arrange <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbarGroups">toolbar groups</a>, toggle <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-removeButtons">button visibility</a> according to your needs and get your toolbar configuration.</p>
+                                                       <p>You can replace the content of the <a href="../../config.js"><code>config.js</code></a> file with the generated configuration. If you already set some configuration options you will need to merge both configurations.</p>
+                                               </div>
+                                               <div class="grid-width-50">
+                                                       <p>Read more about different ways of <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">setting configuration</a> and do not forget about <strong>clearing browser cache</strong>.</p>
+                                                       <p>Arranging toolbar groups is the recommended way of configuring the toolbar, but if you need more freedom you can use the <a href="#advanced">advanced configurator</a>.</p>
+                                               </div>
+                                       </div>
+                                       <div class="advanced" style="display: none;">
+                                               <div class="grid-width-50">
+                                                       <p>With this code editor you can edit your <a href="http://docs.ckeditor.com/#!/api/CKEDITOR.config-cfg-toolbar">toolbar configuration</a> live.</p>
+                                                       <p>You can replace the content of the <a href="../../config.js"><code>config.js</code></a> file with the generated configuration. If you already set some configuration options you will need to merge both configurations.</p>
+                                               </div>
+                                               <div class="grid-width-50">
+                                                       <p>Read more about different ways of <a href="http://docs.ckeditor.com/#!/guide/dev_configuration">setting configuration</a> and do not forget about <strong>clearing browser cache</strong>.</p>
+                                               </div>
+                                       </div>
+                               </div>
+
+                               <p class="grid-container grid-container-nested">
+                                       <button type="button" class="help-content-close grid-width-100 button-a button-a-background">Got it. Let's play!</button>
+                               </p>
+                       </div>
+               </div>
+       </div>
+</main>
+
+<footer class="footer-a grid-container">
+       <p class="grid-width-100">
+               CKEditor &ndash; The text editor for the Internet &ndash; <a class="samples" href="http://ckeditor.com/">http://ckeditor.com</a>
+       </p>
+       <p class="grid-width-100" id="copy">
+               Copyright &copy; 2003-2017, <a class="samples" href="http://cksource.com/">CKSource</a> &ndash; Frederico Knabben. All rights reserved.
+       </p>
+</footer>
+
+<script src="lib/codemirror/codemirror.js"></script>
+<script src="lib/codemirror/javascript.js"></script>
+<script src="lib/codemirror/show-hint.js"></script>
+
+<script src="js/fulltoolbareditor.js"></script>
+<script src="js/abstracttoolbarmodifier.js"></script>
+<script src="js/toolbarmodifier.js"></script>
+<script src="js/toolbartextmodifier.js"></script>
+<script src="../js/sf.js"></script>
+
+<script>
+       ( function() {
+               'use strict';
+
+               var mode = ( window.location.hash.substr( 1 ) === 'advanced' ) ? 'advanced' : 'basic',
+                       configuratorSection = CKEDITOR.document.findOne( 'main > .grid-container.configurator' ),
+                       basicInstruction = CKEDITOR.document.findOne( '#help-content .basic' ),
+                       advancedInstruction = CKEDITOR.document.findOne( '#help-content .advanced' ),
+
+                       // Configurator mode switcher.
+                       modeSwitchBasic = CKEDITOR.document.getById( 'radio-basic' ),
+                       modeSwitchAdvanced = CKEDITOR.document.getById( 'radio-advanced' );
+
+               // Initial setup
+               function updateSwitcher() {
+                       if ( mode === 'advanced' ) {
+                               modeSwitchAdvanced.$.checked = true;
+                       } else {
+                               modeSwitchBasic.$.checked = true;
+                       }
+               }
+
+               updateSwitcher();
+
+               CKEDITOR.document.getWindow().on( 'hashchange', function( e ) {
+                       var hash = window.location.hash.substr( 1 );
+                       if ( !( hash === 'advanced' || hash === 'basic' ) ) {
+                               return;
+                       }
+                       mode = hash;
+                       onToolbarsDone( mode );
+               } );
+
+               CKEDITOR.document.getWindow().on( 'resize', function() {
+                       updateToolbar( ( mode === 'basic' ? toolbarModifier : toolbarTextModifier )[ 'editorInstance' ] );
+               } );
+
+               function onRefresh( modifier ) {
+                       modifier = modifier || this;
+
+                       if ( mode === 'basic' && modifier instanceof ToolbarConfigurator.ToolbarTextModifier ) {
+                               return;
+                       }
+
+                       // CodeMirror container becomes visible, so we need to refresh and to avoid rendering problems.
+                       if ( mode === 'advanced' && modifier instanceof ToolbarConfigurator.ToolbarTextModifier ) {
+                               modifier.codeContainer.refresh();
+                       }
+
+                       updateToolbar( modifier.editorInstance );
+               }
+
+               function updateToolbar( editor ) {
+                       var editorContainer = editor.container;
+
+                       // Not always editor is loaded.
+                       if ( !editorContainer ) {
+                               return;
+                       }
+
+                       var displayStyle = editorContainer.getStyle( 'display' );
+
+                       editorContainer.setStyle( 'display', 'block' );
+
+                       var newHeight = editorContainer.getSize( 'height' );
+
+                       var newMarginTop = parseInt( editorContainer.getComputedStyle( 'margin-top' ), 10 );
+                       newMarginTop = ( isNaN( newMarginTop ) ? 0 : Number( newMarginTop ) );
+
+                       var newMarginBottom = parseInt( editorContainer.getComputedStyle( 'margin-bottom' ), 10 );
+                       newMarginBottom = ( isNaN( newMarginBottom ) ? 0 : Number( newMarginBottom ) );
+
+                       var result = newHeight + newMarginTop + newMarginBottom;
+
+                       editorContainer.setStyle( 'display', displayStyle );
+
+                       editor.container.getAscendant( 'div' ).setStyle( 'height', result + 'px' );
+               }
+
+               var toolbarModifier = new ToolbarConfigurator.ToolbarModifier( 'editor-basic' );
+
+               var done = 0;
+               toolbarModifier.init( onToolbarInit );
+               toolbarModifier.onRefresh = onRefresh;
+
+               CKEDITOR.document.getById( 'toolbarModifierWrapper' ).append( toolbarModifier.mainContainer );
+
+               var toolbarTextModifier = new ToolbarConfigurator.ToolbarTextModifier( 'editor-advanced' );
+               toolbarTextModifier.init( onToolbarInit );
+               toolbarTextModifier.onRefresh = onRefresh;
+
+               function onToolbarInit() {
+                       if ( ++done === 2 ) {
+                               onToolbarsDone();
+
+                               positionSticky.watch( CKEDITOR.document.findOne( '.toolbar' ), function() {
+                                       return mode === 'advanced';
+                               } );
+                       }
+               }
+
+               function onToolbarsDone() {
+                       if ( mode === 'basic' ) {
+                               toggleModeBasic( false );
+                       } else {
+                               toggleModeAdvanced( false );
+                       }
+
+                       updateSwitcher();
+
+                       setTimeout( function() {
+                               CKEDITOR.document.findOne( '.editors-container' ).addClass( 'active' );
+                               CKEDITOR.document.findOne( '#toolbarModifierWrapper' ).addClass( 'active' );
+                       }, 200 );
+               }
+
+               CKEDITOR.document.getById( 'toolbarModifierWrapper' ).append( toolbarTextModifier.mainContainer );
+
+               function toogleModeSwitch( onElement, offElement, onModifier, offModifier ) {
+                       onElement.addClass( 'fancy-button-active' );
+                       offElement.removeClass( 'fancy-button-active' );
+
+                       onModifier.showUI();
+                       offModifier.hideUI();
+               }
+
+               function toggleModeBasic( callOnRefresh ) {
+                       callOnRefresh = ( callOnRefresh !== false );
+                       mode = 'basic';
+                       window.location.hash = '#basic';
+                       toogleModeSwitch( modeSwitchBasic, modeSwitchAdvanced, toolbarModifier, toolbarTextModifier );
+
+                       configuratorSection.removeClass( 'freed-width' );
+                       basicInstruction.show();
+                       advancedInstruction.hide();
+
+                       callOnRefresh && onRefresh( toolbarModifier );
+               }
+
+               function toggleModeAdvanced( callOnRefresh ) {
+                       callOnRefresh = ( callOnRefresh !== false );
+                       mode = 'advanced';
+                       window.location.hash = '#advanced';
+                       toogleModeSwitch( modeSwitchAdvanced, modeSwitchBasic, toolbarTextModifier, toolbarModifier );
+
+                       configuratorSection.addClass( 'freed-width' );
+                       advancedInstruction.show();
+                       basicInstruction.hide();
+
+                       callOnRefresh && onRefresh( toolbarTextModifier );
+               }
+
+               modeSwitchBasic.on( 'click', toggleModeBasic );
+               modeSwitchAdvanced.on( 'click', toggleModeAdvanced );
+
+               //
+               // Position:sticky for the toolbar.
+               //
+
+               // Will make elements behave like they were styled with position:sticky.
+               var positionSticky = {
+                       // Store object: {
+                       //              element: CKEDITOR.dom.element, // Element which will float.
+                       //              placeholder: CKEDITOR.dom.element, // Placeholder which is place to prevent page bounce.
+                       //              isFixed: boolean // Whether element float now.
+                       // }
+                       watched: [],
+
+                       active: [],
+
+                       staticContainer: null,
+
+                       init: function() {
+                               var element = CKEDITOR.dom.element.createFromHtml(
+                                       '<div class="staticContainer">' +
+                                               '<div class="grid-container" >' +
+                                                       '<div class="grid-width-100">' +
+                                                               '<div class="inner"></div>' +
+                                                       '</div>' +
+                                               '</div>' +
+                                       '</div>' );
+
+                               this.staticContainer = element.findOne( '.inner' );
+
+                               CKEDITOR.document.getBody().append( element );
+                       },
+
+                       watch: function( element, preventFunc ) {
+                               this.watched.push( {
+                                       element: element,
+                                       placeholder: new CKEDITOR.dom.element( 'div' ),
+                                       isFixed: false,
+                                       preventFunc: preventFunc
+                               } );
+                       },
+
+                       checkAll: function() {
+                               for ( var i = 0; i < this.watched.length; i++ ) {
+                                       this.check( this.watched[ i ] );
+                               }
+                       },
+
+                       check: function( element ) {
+                               var isFixed = element.isFixed;
+                               var shouldBeFixed = this.shouldBeFixed( element );
+
+                               // Nothing to be done.
+                               if ( isFixed === shouldBeFixed ) {
+                                       return;
+                               }
+
+                               var placeholder = element.placeholder;
+
+                               if ( isFixed ) {
+                                       // Unfixing.
+
+                                       element.element.insertBefore( placeholder );
+                                       placeholder.remove();
+
+                                       element.element.removeStyle( 'margin' );
+
+                                       this.active.splice( CKEDITOR.tools.indexOf( this.active, element ), 1 );
+
+                               } else {
+                                       // Fixing.
+                                       placeholder.setStyle( 'width', element.element.getSize( 'width' ) + 'px' );
+                                       placeholder.setStyle( 'height', element.element.getSize( 'height' ) + 'px' );
+                                       placeholder.setStyle( 'margin-bottom', element.element.getComputedStyle( 'margin-bottom' ) );
+                                       placeholder.setStyle( 'display', element.element.getComputedStyle( 'display' ) );
+                                       placeholder.insertAfter( element.element );
+
+                                       this.staticContainer.append( element.element );
+
+                                       this.active.push( element );
+                               }
+
+                               element.isFixed = !element.isFixed;
+                       },
+
+                       shouldBeFixed: function( element ) {
+                               if ( element.preventFunc && element.preventFunc() ) {
+                                       return false;
+                               }
+
+                               // If element is already fixed we are checking it's placeholder.
+                               var related = ( element.isFixed ? element.placeholder : element.element ),
+                                       clientRect = related.$.getBoundingClientRect(),
+                                       staticHeight = this.staticContainer.getSize('height' ),
+                                       elemHeight = element.element.getSize( 'height' );
+
+                               if ( element.isFixed ) {
+                                       return ( clientRect.top + elemHeight < staticHeight );
+                               } else {
+                                       return ( clientRect.top < staticHeight );
+                               }
+                       }
+               };
+
+               positionSticky.init();
+
+               CKEDITOR.document.getWindow().on( 'scroll',
+                       new CKEDITOR.tools.eventsBuffer( 100, positionSticky.checkAll, positionSticky ).input
+               );
+
+               // Make the toolbar sticky.
+               positionSticky.watch( CKEDITOR.document.findOne( '.editors-container' ) );
+
+               // Help button and help-content.
+               ( function() {
+                       var helpButton = CKEDITOR.document.getById( 'help' ),
+                               helpContent = CKEDITOR.document.getById( 'help-content' );
+
+                       // Don't show help button on IE8 because it's unsupported by Pico Modal.
+                       if ( CKEDITOR.env.ie && CKEDITOR.env.version == 8 ) {
+                               helpButton.hide();
+                       } else {
+                               // Display help modal when the button is clicked.
+                               helpButton.on( 'click', function( evt ) {
+                                       SF.modal( {
+                                               // Clone modal content from DOM.
+                                               content: helpContent.getHtml(),
+
+                                               afterCreate: function( modal ) {
+                                                       // Enable modal content button to close the modal.
+                                                       new CKEDITOR.dom.element( modal.modalElem() ).findOne( '.help-content-close' ).once( 'click', modal.close );
+                                               }
+                                       } ).show();
+                               } );
+                       }
+               } )();
+       } )();
+</script>
+</body>
+</html>
diff --git a/sources/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js b/sources/samples/toolbarconfigurator/js/abstracttoolbarmodifier.js
new file mode 100644 (file)
index 0000000..af6cd62
--- /dev/null
@@ -0,0 +1,566 @@
+/* global ToolbarConfigurator */
+
+'use strict';
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/create
+if ( typeof Object.create != 'function' ) {
+       ( function() {
+               var F = function() {};
+               Object.create = function( o ) {
+                       if ( arguments.length > 1 ) {
+                               throw Error( 'Second argument not supported' );
+                       }
+                       if ( o === null ) {
+                               throw Error( 'Cannot set a null [[Prototype]]' );
+                       }
+                       if ( typeof o != 'object' ) {
+                               throw TypeError( 'Argument must be an object' );
+                       }
+                       F.prototype = o;
+                       return new F();
+               };
+       } )();
+}
+
+// Copy of the divarea plugin (with some enhancements), so we always have some editable mode, regardless of the build's config.
+CKEDITOR.plugins.add( 'toolbarconfiguratorarea', {
+       // Use afterInit to override wysiwygarea's mode. May still fail to override divarea, but divarea is nice.
+       afterInit: function( editor ) {
+               editor.addMode( 'wysiwyg', function( callback ) {
+                       var editingBlock = CKEDITOR.dom.element.createFromHtml( '<div class="cke_wysiwyg_div cke_reset" hidefocus="true"></div>' );
+
+                       var contentSpace = editor.ui.space( 'contents' );
+                       contentSpace.append( editingBlock );
+
+                       editingBlock = editor.editable( editingBlock );
+
+                       editingBlock.detach = CKEDITOR.tools.override( editingBlock.detach,
+                               function( org ) {
+                                       return function() {
+                                               org.apply( this, arguments );
+                                               this.remove();
+                                       };
+                               } );
+
+                       editor.setData( editor.getData( 1 ), callback );
+                       editor.fire( 'contentDom' );
+               } );
+
+               // Additions to the divarea.
+
+               // Speed up data processing.
+               editor.dataProcessor.toHtml = function( html ) {
+                       return html;
+               };
+               editor.dataProcessor.toDataFormat = function( html ) {
+                       return html;
+               };
+
+               // End of the additions.
+       }
+} );
+
+// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/keys
+if ( !Object.keys ) {
+       Object.keys = ( function() {
+               var hasOwnProperty = Object.prototype.hasOwnProperty,
+                       hasDontEnumBug = !( { toString: null } ).propertyIsEnumerable( 'toString' ),
+                       dontEnums = [
+                               'toString',
+                               'toLocaleString',
+                               'valueOf',
+                               'hasOwnProperty',
+                               'isPrototypeOf',
+                               'propertyIsEnumerable',
+                               'constructor'
+                       ],
+                       dontEnumsLength = dontEnums.length;
+
+               return function( obj ) {
+                       if ( typeof obj !== 'object' && ( typeof obj !== 'function' || obj === null ) )
+                               throw new TypeError( 'Object.keys called on non-object' );
+
+                       var result = [], prop, i;
+
+                       for ( prop in obj ) {
+                               if ( hasOwnProperty.call( obj, prop ) )
+                                       result.push( prop );
+
+                       }
+
+                       if ( hasDontEnumBug ) {
+                               for ( i = 0; i < dontEnumsLength; i++ ) {
+                                       if ( hasOwnProperty.call( obj, dontEnums[ i ] ) )
+                                               result.push( dontEnums[ i ] );
+
+                               }
+                       }
+                       return result;
+               };
+       }() );
+}
+
+( function() {
+       /**
+        * @class ToolbarConfigurator.AbstractToolbarModifier
+        * @param {String} editorId An id of modified editor
+        * @constructor
+        */
+       function AbstractToolbarModifier( editorId, cfg ) {
+               this.cfg = cfg || {};
+               this.hidden = false;
+               this.editorId = editorId;
+               this.fullToolbarEditor = new ToolbarConfigurator.FullToolbarEditor();
+
+               this.mainContainer = null;
+
+               this.originalConfig = null;
+               this.actualConfig = null;
+
+               this.waitForReady = false;
+               this.isEditableVisible = false;
+
+               this.toolbarContainer = null;
+               this.toolbarButtons = [];
+       }
+
+       // Expose the class.
+       ToolbarConfigurator.AbstractToolbarModifier = AbstractToolbarModifier;
+
+       /**
+        * @param {String} config
+        */
+       AbstractToolbarModifier.prototype.setConfig = function( config ) {
+               this._onInit( undefined, config, true );
+       };
+
+       /**
+        * @param {Function} [callback]
+        */
+       AbstractToolbarModifier.prototype.init = function( callback ) {
+               var that = this;
+
+               this.mainContainer = new CKEDITOR.dom.element( 'div' );
+
+               if ( this.fullToolbarEditor.editorInstance !== null ) {
+                       throw 'Only one instance of ToolbarModifier is allowed';
+               }
+
+               if ( !this.editorInstance ) {
+                       // Do not refresh yet, let's wait for the full toolbar editor (see below).
+                       this._createEditor( false );
+               }
+
+               this.editorInstance.once( 'loaded', function() {
+                       that.fullToolbarEditor.init( function() {
+                               that._onInit( callback );
+
+                               if ( typeof that.onRefresh == 'function' ) {
+                                       that.onRefresh();
+                               }
+                       }, that.editorInstance.config );
+               } );
+
+               return this.mainContainer;
+       };
+
+       /**
+        * Called editor initialization finished.
+        *
+        * @param {Function} callback
+        * @param {String} [actualConfig]
+        * @private
+        */
+       AbstractToolbarModifier.prototype._onInit = function( callback, actualConfig ) {
+               this.originalConfig = this.editorInstance.config;
+
+               if ( !actualConfig ) {
+                       this.actualConfig = JSON.parse( JSON.stringify( this.originalConfig ) );
+               } else {
+                       this.actualConfig = JSON.parse( actualConfig );
+               }
+
+               if ( !this.actualConfig.toolbarGroups && !this.actualConfig.toolbar ) {
+                       this.actualConfig.toolbarGroups = getDefaultToolbarGroups( this.editorInstance );
+               }
+
+               if ( typeof callback === 'function' )
+                       callback( this.mainContainer );
+
+               // Here we are going to keep only `name` and `groups` data from editor `toolbar` property.
+               function getDefaultToolbarGroups( editor ) {
+                       var toolbarGroups = editor.toolbar,
+                               copy = [];
+
+                       var max = toolbarGroups.length;
+                       for ( var i = 0; i < max; i++ ) {
+                               var group = toolbarGroups[ i ];
+
+                               if ( typeof group == 'string' ) {
+                                       copy.push( group ); // separator
+                               } else {
+                                       copy.push( {
+                                               name: group.name,
+                                               groups: group.groups ? group.groups.slice() : []
+                                       } );
+                               }
+                       }
+
+                       return copy;
+               }
+       };
+
+       /**
+        * Creates DOM structure of tool.
+        *
+        * @returns {CKEDITOR.dom.element}
+        * @private
+        */
+       AbstractToolbarModifier.prototype._createModifier = function() {
+               this.mainContainer.addClass( 'unselectable' );
+
+               if ( this.modifyContainer ) {
+                       this.modifyContainer.remove();
+               }
+
+               this.modifyContainer = new CKEDITOR.dom.element( 'div' );
+               this.modifyContainer.addClass( 'toolbarModifier' );
+
+               this.mainContainer.append( this.modifyContainer );
+
+               return this.mainContainer;
+       };
+
+       /**
+        * Find editable area in CKEditor instance DOM container
+        *
+        * @returns {CKEDITOR.dom.element}
+        */
+       AbstractToolbarModifier.prototype.getEditableArea = function() {
+               var selector = ( '#' + this.editorInstance.id + '_contents' );
+
+               return this.editorInstance.container.findOne( selector );
+       };
+
+       /**
+        * Hide editable area in modified editor by sets its height to 0.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._hideEditable = function() {
+               var area = this.getEditableArea();
+
+               this.isEditableVisible = false;
+
+               this.lastEditableAreaHeight = area.getStyle( 'height' );
+               area.setStyle( 'height', '0' );
+       };
+
+       /**
+        * Show editable area in modified editor.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._showEditable = function() {
+               this.isEditableVisible = true;
+
+               this.getEditableArea().setStyle( 'height', this.lastEditableAreaHeight || 'auto' );
+       };
+
+       /**
+        * Toggle editable area visibility.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._toggleEditable = function() {
+               if ( this.isEditableVisible )
+                       this._hideEditable();
+               else
+                       this._showEditable();
+       };
+
+       /**
+        * Usually called when configuration changes.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._refreshEditor = function() {
+               var that = this,
+                       status = this.editorInstance.status;
+
+               // Wait for ready only once.
+               if ( this.waitForReady )
+                       return;
+
+               // Not ready.
+               if ( status == 'unloaded' || status == 'loaded' ) {
+                       this.waitForReady = true;
+
+                       this.editorInstance.once( 'instanceReady', function() {
+                               refresh();
+                       }, this );
+                       // Ready or destroyed.
+               } else {
+                       refresh();
+               }
+
+               function refresh() {
+                       that.editorInstance.destroy();
+                       that._createEditor( true, that.getActualConfig() );
+                       that.waitForReady = false;
+               }
+       };
+
+       /**
+        * Creates editor that can be used to present the toolbar configuration.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._createEditor = function( doRefresh, configOverrides ) {
+               var that = this;
+
+               this.editorInstance = CKEDITOR.replace( this.editorId );
+
+               this.editorInstance.on( 'configLoaded', function() {
+                       var config = that.editorInstance.config;
+
+                       if ( configOverrides ) {
+                               CKEDITOR.tools.extend( config, configOverrides, true );
+                       }
+
+                       AbstractToolbarModifier.extendPluginsConfig( config );
+               } );
+
+               // Prevent creating any other space than the top one.
+               this.editorInstance.on( 'uiSpace', function( evt ) {
+                       if ( evt.data.space != 'top' ) {
+                               evt.stop();
+                       }
+               }, null, null, -999 );
+
+               this.editorInstance.once( 'loaded', function() {
+                       var btns = that.editorInstance.ui.instances;
+
+                       for ( var i in btns ) {
+                               if ( btns[ i ] ) {
+                                       btns[ i ].click = empty;
+                                       btns[ i ].onClick = empty;
+                               }
+                       }
+
+                       if ( !that.isEditableVisible ) {
+                               that._hideEditable();
+                       }
+
+                       if ( that.currentActive && that.currentActive.name ) {
+                               that._highlightGroup( that.currentActive.name );
+                       }
+
+                       if ( that.hidden ) {
+                               that.hideUI();
+                       } else {
+                               that.showUI();
+                       }
+
+                       if ( doRefresh && ( typeof that.onRefresh === 'function' ) ) {
+                               that.onRefresh();
+                       }
+               } );
+
+               function empty() {}
+       };
+
+       /**
+        * Always returns copy of config.
+        *
+        * @returns {Object}
+        */
+       AbstractToolbarModifier.prototype.getActualConfig = function() {
+               return JSON.parse( JSON.stringify( this.actualConfig ) );
+       };
+
+       /**
+        * Creates toolbar in tool.
+        *
+        * @private
+        */
+       AbstractToolbarModifier.prototype._createToolbar = function() {
+               if ( !this.toolbarButtons.length ) {
+                       return;
+               }
+
+               this.toolbarContainer = new CKEDITOR.dom.element( 'div' );
+               this.toolbarContainer.addClass( 'toolbar' );
+
+               var max = this.toolbarButtons.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       this._createToolbarBtn( this.toolbarButtons[ i ] );
+               }
+       };
+
+       /**
+        * Create toolbar button and add it to toolbar container
+        *
+        * @param {Object} cfg
+        * @returns {CKEDITOR.dom.element}
+        * @private
+        */
+       AbstractToolbarModifier.prototype._createToolbarBtn = function( cfg ) {
+               var btnText = ( typeof cfg.text === 'string' ? cfg.text : cfg.text.inactive ),
+                       btn = ToolbarConfigurator.FullToolbarEditor.createButton( btnText, cfg.cssClass );
+
+               this.toolbarContainer.append( btn );
+               btn.data( 'group', cfg.group );
+               btn.addClass( cfg.position );
+               btn.on( 'click', function() {
+                       cfg.clickCallback.call( this, btn, cfg );
+               }, this );
+
+               return btn;
+       };
+
+       /**
+        * @private
+        * @param {Object} config
+        */
+       AbstractToolbarModifier.prototype._fixGroups = function( config ) {
+               var groups = config.toolbarGroups || [];
+
+               var max = groups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentGroup = groups[ i ];
+
+                       // separator, in config, is in raw format
+                       // need to make it more sophisticated to keep unique id
+                       // for each one
+                       if ( currentGroup == '/' ) {
+                               currentGroup = groups[ i ] = {};
+                               currentGroup.type = 'separator';
+                               currentGroup.name = ( 'separator' + CKEDITOR.tools.getNextNumber() );
+                               continue;
+                       }
+
+                       // sometimes subgroups are not set (basic package), so need to
+                       // create them artifically
+                       currentGroup.groups = currentGroup.groups || [];
+
+                       // when there is no subgroup with same name like its parent name
+                       // then it have to be added artificially
+                       // in order to maintain consistency between user interface and config
+                       if ( CKEDITOR.tools.indexOf( currentGroup.groups, currentGroup.name ) == -1 ) {
+                               this.editorInstance.ui.addToolbarGroup( currentGroup.name, currentGroup.groups[ currentGroup.groups.length - 1 ], currentGroup.name );
+                               currentGroup.groups.push( currentGroup.name );
+                       }
+
+                       this._fixSubgroups( currentGroup );
+               }
+       };
+
+       /**
+        * Transform subgroup string to object literal
+        * with keys: {String} name and {Number} totalBtns
+        * Please note: this method modify Object provided in first argument
+        *
+        * input:
+        * [
+        *   { groups: [ 'nameOne', 'nameTwo' ] }
+        * ]
+        *
+        * output:
+        * [
+        *   { groups: [ { name: 'nameOne', totalBtns: 3 }, { name: 'nameTwo', totalBtns: 5 } ] }
+        * ]
+        *
+        * @param {Object} group
+        * @private
+        */
+       AbstractToolbarModifier.prototype._fixSubgroups = function( group ) {
+               var subGroups = group.groups;
+
+               var max = subGroups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var subgroupName = subGroups[ i ];
+
+                       subGroups[ i ] = {
+                               name: subgroupName,
+                               totalBtns: ToolbarConfigurator.ToolbarModifier.getTotalSubGroupButtonsNumber( subgroupName, this.fullToolbarEditor )
+                       };
+               }
+       };
+
+       /**
+        * Same as JSON.stringify method but returned string is in one line
+        *
+        * @param {Object} json
+        * @param {Object} opts
+        * @param {Boolean} opts.addSpaces
+        * @param {Boolean} opts.noQuotesOnKey
+        * @param {Boolean} opts.singleQuotes
+        * @returns {Object}
+        */
+       AbstractToolbarModifier.stringifyJSONintoOneLine = function( json, opts ) {
+               opts = opts || {};
+               var stringJSON = JSON.stringify( json, null, '' );
+
+               // IE8 make new line characters
+               stringJSON = stringJSON.replace( /\n/g, '' );
+
+               if ( opts.addSpaces ) {
+                       stringJSON = stringJSON.replace( /(\{|:|,|\[|\])/g, function( sentence ) {
+                               return sentence + ' ';
+                       } );
+
+                       stringJSON = stringJSON.replace( /(\])/g, function( sentence ) {
+                               return ' ' + sentence;
+                       } );
+               }
+
+               if ( opts.noQuotesOnKey ) {
+                       stringJSON = stringJSON.replace( /"(\w*)":/g, function( sentence, word ) {
+                               return word + ':';
+                       } );
+               }
+
+               if ( opts.singleQuotes ) {
+                       stringJSON = stringJSON.replace( /\"/g, '\'' );
+               }
+
+               return stringJSON;
+       };
+
+       /**
+        * Hide toolbar configurator
+        */
+       AbstractToolbarModifier.prototype.hideUI = function() {
+               this.hidden = true;
+               this.mainContainer.hide();
+               if ( this.editorInstance.container ) {
+                       this.editorInstance.container.hide();
+               }
+       };
+
+       /**
+        * Show toolbar configurator
+        */
+       AbstractToolbarModifier.prototype.showUI = function() {
+               this.hidden = false;
+               this.mainContainer.show();
+               if ( this.editorInstance.container ) {
+                       this.editorInstance.container.show();
+               }
+       };
+
+
+       /**
+        * Extends plugins setttings in the specified config with settings useful for
+        * the toolbar configurator.
+        *
+        * @static
+        */
+       AbstractToolbarModifier.extendPluginsConfig = function( config ) {
+               var extraPlugins = config.extraPlugins;
+
+               // Enable the special, lightweight area to replace wysiwygarea.
+               config.extraPlugins = ( extraPlugins ? extraPlugins + ',' : '' ) + 'toolbarconfiguratorarea';
+       };
+} )();
diff --git a/sources/samples/toolbarconfigurator/js/fulltoolbareditor.js b/sources/samples/toolbarconfigurator/js/fulltoolbareditor.js
new file mode 100644 (file)
index 0000000..2b9f15f
--- /dev/null
@@ -0,0 +1,365 @@
+/* exported ToolbarConfigurator */
+/* global ToolbarConfigurator */
+
+'use strict';
+
+window.ToolbarConfigurator = {};
+
+( function() {
+       /**
+        * @class ToolbarConfigurator.FullToolbarEditor
+        * @constructor
+        */
+       function FullToolbarEditor() {
+               this.instanceid = 'fte' + CKEDITOR.tools.getNextId();
+               this.textarea = new CKEDITOR.dom.element( 'textarea' );
+               this.textarea.setAttributes( {
+                       id: this.instanceid,
+                       name: this.instanceid,
+                       contentEditable: true
+               } );
+
+               this.buttons = null;
+               this.editorInstance = null;
+       }
+
+       // Expose the class.
+       ToolbarConfigurator.FullToolbarEditor = FullToolbarEditor;
+
+       /**
+        * @param {Function} callback
+        * @param {Object} cfg
+        */
+       FullToolbarEditor.prototype.init = function( callback ) {
+               var that = this;
+
+               document.body.appendChild( this.textarea.$ );
+
+               CKEDITOR.replace( this.instanceid );
+
+               this.editorInstance = CKEDITOR.instances[ this.instanceid ];
+
+               this.editorInstance.once( 'configLoaded', function( e ) {
+                       var cfg = e.editor.config;
+
+                       // We want all the buttons.
+                       delete cfg.removeButtons;
+                       delete cfg.toolbarGroups;
+                       delete cfg.toolbar;
+                       ToolbarConfigurator.AbstractToolbarModifier.extendPluginsConfig( cfg );
+
+                       e.editor.once( 'loaded', function() {
+                               that.buttons = FullToolbarEditor.toolbarToButtons( that.editorInstance.toolbar );
+
+                               that.buttonsByGroup = FullToolbarEditor.groupButtons( that.buttons );
+
+                               that.buttonNamesByGroup = that.groupButtonNamesByGroup( that.buttons );
+
+                               e.editor.container.hide();
+
+                               if ( typeof callback === 'function' )
+                                       callback( that.buttons );
+                       } );
+               } );
+       };
+
+       /**
+        * Group array of button names by their group parents.
+        *
+        * @param {Array} buttons
+        * @returns {Object}
+        */
+       FullToolbarEditor.prototype.groupButtonNamesByGroup = function( buttons ) {
+               var that = this,
+                       groups = FullToolbarEditor.groupButtons( buttons );
+
+               for ( var groupName in groups ) {
+                       var currGroup = groups[ groupName ];
+
+                       groups[ groupName ] = FullToolbarEditor.map( currGroup, function( button ) {
+                               return that.getCamelCasedButtonName( button.name );
+                       } );
+               }
+
+               return groups;
+       };
+
+       /**
+        * Returns group literal.
+        *
+        * @param {String} name
+        * @returns {Object}
+        */
+       FullToolbarEditor.prototype.getGroupByName = function( name ) {
+               var groups = this.editorInstance.config.toolbarGroups || this.getFullToolbarGroupsConfig();
+
+               var max = groups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       if ( groups[ i ].name === name )
+                               return groups[ i ];
+               }
+
+               return null;
+       };
+
+       /**
+        * @param {String} name
+        * @returns {String | null}
+        */
+       FullToolbarEditor.prototype.getCamelCasedButtonName = function( name ) {
+               var items = this.editorInstance.ui.items;
+
+               for ( var key in items ) {
+                       if ( items[ key ].name == name )
+                               return key;
+               }
+
+               return null;
+       };
+
+       /**
+        * Returns full toolbarGroups config value which is used when
+        * there is no toolbarGroups field in config.
+        *
+        * @param {Boolean} [pickSeparators=false]
+        * @returns {Array}
+        */
+       FullToolbarEditor.prototype.getFullToolbarGroupsConfig = function( pickSeparators ) {
+               pickSeparators = ( pickSeparators === true ? true : false );
+
+               var result = [],
+                       toolbarGroups = this.editorInstance.toolbar;
+
+               var max = toolbarGroups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentGroup = toolbarGroups[ i ],
+                               copiedGroup = {};
+
+                       if ( typeof currentGroup.name != 'string' ) {
+                               // this is not a group
+                               if ( pickSeparators ) {
+                                       result.push( '/' );
+                               }
+                               continue;
+                       }
+
+                       copiedGroup.name = currentGroup.name;
+                       if ( currentGroup.groups )
+                               copiedGroup.groups = Array.prototype.slice.call( currentGroup.groups );
+
+                       result.push( copiedGroup );
+               }
+
+               return result;
+       };
+
+       /**
+        * Filters array items based on checker provided in second argument.
+        * Returns new array.
+        *
+        * @param {Array} arr
+        * @param {Function} checker
+        * @returns {Array}
+        */
+       FullToolbarEditor.filter = function( arr, checker ) {
+               var max = ( arr && arr.length ? arr.length : 0 ),
+                       result = [];
+
+               for ( var i = 0; i < max; i += 1 ) {
+                       if ( checker( arr[ i ] ) )
+                               result.push( arr[ i ] );
+               }
+
+               return result;
+       };
+
+       /**
+        * Simplified http://underscorejs.org/#map functionality
+        *
+        * @param {Array | Object} enumerable
+        * @param {Function} modifier
+        * @returns {Array | Object}
+        */
+       FullToolbarEditor.map = function( enumerable, modifier ) {
+               var result;
+
+               if ( CKEDITOR.tools.isArray( enumerable ) ) {
+                       result = [];
+
+                       var max = enumerable.length;
+                       for ( var i = 0; i < max; i += 1 )
+                               result.push( modifier( enumerable[ i ] ) );
+               } else {
+                       result = {};
+
+                       for ( var key in enumerable )
+                               result[ key ] = modifier( enumerable[ key ] );
+               }
+
+               return result;
+       };
+
+       /**
+        * Group buttons by their parent names.
+        *
+        * @static
+        * @param {Array} buttons
+        * @returns {Object} The object (`name => group`) representing CKEDITOR.ui.button or CKEDITOR.ui.richCombo
+        */
+       FullToolbarEditor.groupButtons = function( buttons ) {
+               var groups = {};
+
+               var max = buttons.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currBtn = buttons[ i ],
+                               currBtnGroupName = currBtn.toolbar.split( ',' )[ 0 ];
+
+                       groups[ currBtnGroupName ] = groups[ currBtnGroupName ] || [];
+
+                       groups[ currBtnGroupName ].push( currBtn );
+               }
+
+               return groups;
+       };
+
+       /**
+        * Pick all buttons from toolbar.
+        *
+        * @static
+        * @param {Array} groups
+        * @returns {Array}
+        */
+       FullToolbarEditor.toolbarToButtons = function( groups ) {
+               var buttons = [];
+
+               var max = groups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentGroup = groups[ i ];
+
+                       if ( typeof currentGroup == 'object' )
+                               buttons = buttons.concat( FullToolbarEditor.groupToButtons( groups[ i ] ) );
+               }
+
+               return buttons;
+       };
+
+       /**
+        * Creates HTML button representation for view.
+        *
+        * @static
+        * @param {CKEDITOR.ui.button | CKEDITOR.ui.richCombo} button
+        * @returns {CKEDITOR.dom.element}
+        */
+       FullToolbarEditor.createToolbarButton = function( button ) {
+               var $button = new CKEDITOR.dom.element( 'a' ),
+                       icon = FullToolbarEditor.createIcon( button.name, button.icon, button.command );
+
+               $button.setStyle( 'float', 'none' );
+
+               $button.addClass( 'cke_' + ( CKEDITOR.lang.dir == 'rtl' ? 'rtl' : 'ltr' ) );
+
+               if ( button instanceof CKEDITOR.ui.button ) {
+                       $button.addClass( 'cke_button' );
+                       $button.addClass( 'cke_toolgroup' );
+
+                       $button.append( icon );
+               } else if ( CKEDITOR.ui.richCombo && button instanceof CKEDITOR.ui.richCombo ) {
+                       var comboLabel = new CKEDITOR.dom.element( 'span' ),
+                               comboOpen = new CKEDITOR.dom.element( 'span' ),
+                               comboArrow = new CKEDITOR.dom.element( 'span' );
+
+                       $button.addClass( 'cke_combo_button' );
+
+                       comboLabel.addClass( 'cke_combo_text' );
+                       comboLabel.addClass( 'cke_combo_inlinelabel' );
+                       comboLabel.setText( button.label );
+
+                       comboOpen.addClass( 'cke_combo_open' );
+                       comboArrow.addClass( 'cke_combo_arrow' );
+                       comboOpen.append( comboArrow );
+
+                       $button.append( comboLabel );
+                       $button.append( comboOpen );
+               }
+
+               return $button;
+       };
+
+       /**
+        * Create and return icon element.
+        *
+        * @param {String} name
+        * @param {String} icon
+        * @param {String} command
+        * @static
+        * @returns {CKEDITOR.dom.element}
+        */
+       FullToolbarEditor.createIcon = function( name, icon, command ) {
+               var iconStyle = CKEDITOR.skin.getIconStyle( name, ( CKEDITOR.lang.dir == 'rtl' ) );
+
+               // We don't know exactly how to get icon style. Especially for extra plugins,
+               // Which definition may vary.
+               iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( icon, ( CKEDITOR.lang.dir == 'rtl' ) );
+               iconStyle = iconStyle || CKEDITOR.skin.getIconStyle( command, ( CKEDITOR.lang.dir == 'rtl' ) );
+
+               var iconElement = new CKEDITOR.dom.element( 'span' );
+
+               iconElement.addClass( 'cke_button_icon' );
+               iconElement.addClass( 'cke_button__' + name + '_icon' );
+               iconElement.setAttribute( 'style', iconStyle );
+               iconElement.setStyle( 'float', 'none' );
+
+               return iconElement;
+       };
+
+       /**
+        * Create and return button element
+        *
+        * @param {String} text
+        * @param {String} cssClasses
+        * @returns {CKEDITOR.dom.element}
+        */
+       FullToolbarEditor.createButton = function( text, cssClasses ) {
+               var $button = new CKEDITOR.dom.element( 'button' );
+
+               $button.addClass( 'button-a' );
+
+               $button.setAttribute( 'type', 'button' );
+
+               if ( typeof cssClasses == 'string' ) {
+                       cssClasses = cssClasses.split( ' ' );
+
+                       var i = cssClasses.length;
+                       while ( i-- ) {
+                               $button.addClass( cssClasses[ i ] );
+                       }
+               }
+
+               $button.setHtml( text );
+
+               return $button;
+       };
+
+       /**
+        * @static
+        * @param {Object} group
+        * @returns {Array} representing HTML buttons for view
+        */
+       FullToolbarEditor.groupToButtons = function( group ) {
+               var buttons = [],
+                       items = group.items;
+
+               var max = items ? items.length : 0;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var item = items[ i ];
+
+                       if ( item instanceof CKEDITOR.ui.button || CKEDITOR.ui.richCombo && item instanceof CKEDITOR.ui.richCombo ) {
+                               item.$ = FullToolbarEditor.createToolbarButton( item );
+                               buttons.push( item );
+                       }
+               }
+
+               return buttons;
+       };
+
+} )();
diff --git a/sources/samples/toolbarconfigurator/js/toolbarmodifier.js b/sources/samples/toolbarconfigurator/js/toolbarmodifier.js
new file mode 100644 (file)
index 0000000..bd33d24
--- /dev/null
@@ -0,0 +1,1366 @@
+/* global ToolbarConfigurator, alert */
+
+'use strict';
+
+( function() {
+       var AbstractToolbarModifier = ToolbarConfigurator.AbstractToolbarModifier;
+
+       /**
+        * @class ToolbarConfigurator.ToolbarModifier
+        * @param {String} editorId An id of modified editor
+        * @param {Object} cfg
+        * @extends AbstractToolbarModifier
+        * @constructor
+        */
+       function ToolbarModifier( editorId, cfg ) {
+               AbstractToolbarModifier.call( this, editorId, cfg );
+
+               this.removedButtons = null;
+               this.originalConfig = null;
+               this.actualConfig = null;
+               this.emptyVisible = false;
+
+               // edit, paste, config
+               this.state = 'edit';
+
+               this.toolbarButtons = [
+                       {
+                               text: {
+                                       active: 'Hide empty toolbar groups',
+                                       inactive: 'Show empty toolbar groups'
+                               },
+                               group: 'edit',
+                               position: 'left',
+                               cssClass: 'button-a-soft',
+                               clickCallback: function( button, buttonDefinition ) {
+                                       var className = 'button-a-background';
+
+                                       button[ button.hasClass( className ) ? 'removeClass' : 'addClass' ]( className );
+
+                                       this._toggleVisibilityEmptyElements();
+
+                                       if ( this.emptyVisible ) {
+                                               button.setText( buttonDefinition.text.active );
+                                       } else {
+                                               button.setText( buttonDefinition.text.inactive );
+                                       }
+                               }
+                       },
+                       {
+                               text: 'Add row separator',
+                               group: 'edit',
+                               position: 'left',
+                               cssClass: 'button-a-soft',
+                               clickCallback: function() {
+                                       this._addSeparator();
+                               }
+                       },
+                       /*{
+                               text: 'Paste config',
+                               group: 'edit',
+                               position: 'left',
+                               clickCallback: function() {
+                                       this.state = 'paste';
+
+                                       this.modifyContainer.addClass( 'hidden' );
+                                       this.configContainer.removeClass( 'hidden' );
+                                       this.configContainer.setHtml( '<textarea></textarea>' );
+                                       this.showToolbarBtnsByGroupName( 'config' );
+                               }
+                       },*/
+                       {
+                               text: 'Select config',
+                               group: 'config',
+                               position: 'left',
+                               cssClass: 'button-a-soft',
+                               clickCallback: function() {
+                                       this.configContainer.findOne( 'textarea' ).$.select();
+                               }
+                       },
+                       {
+                               text: 'Back to configurator',
+                               group: 'config',
+                               position: 'right',
+                               cssClass: 'button-a-background',
+                               clickCallback: function() {
+                                       if ( this.state === 'paste' ) {
+                                               var cfg = this.configContainer.findOne( 'textarea' ).getValue();
+                                               cfg = ToolbarModifier.evaluateToolbarGroupsConfig( cfg );
+
+                                               if ( cfg ) {
+                                                       this.setConfig( cfg );
+                                               } else {
+                                                       alert( 'Your pasted config is wrong.' );
+                                               }
+                                       }
+
+                                       this.state = 'edit';
+                                       this._showConfigurationTool();
+                                       this.showToolbarBtnsByGroupName( this.state );
+                               }
+                       },
+                       {
+                               text: 'Get toolbar <span class="highlight">config</span>',
+                               group: 'edit',
+                               position: 'right',
+                               cssClass: 'button-a-background icon-pos-left icon-download',
+                               clickCallback: function() {
+                                       this.state = 'config';
+                                       this._showConfig();
+                                       this.showToolbarBtnsByGroupName( this.state );
+                               }
+                       }
+               ];
+
+               this.cachedActiveElement = null;
+       }
+
+       // Expose the class.
+       ToolbarConfigurator.ToolbarModifier = ToolbarModifier;
+
+       ToolbarModifier.prototype = Object.create( ToolbarConfigurator.AbstractToolbarModifier.prototype );
+
+       /**
+        * @returns {Object}
+        */
+       ToolbarModifier.prototype.getActualConfig = function() {
+               var copy = AbstractToolbarModifier.prototype.getActualConfig.call( this );
+
+               if ( copy.toolbarGroups ) {
+
+                       var max = copy.toolbarGroups.length;
+                       for ( var i = 0; i < max; i += 1 ) {
+                               var currentGroup = copy.toolbarGroups[ i ];
+
+                               copy.toolbarGroups[ i ] = ToolbarModifier.parseGroupToConfigValue( currentGroup );
+                       }
+
+               }
+
+               return copy;
+       };
+
+       /**
+        * @param {Function} callback
+        * @param {String} [config]
+        * @param {Boolean} [forceKeepRemoveButtons=false]
+        * @private
+        */
+       ToolbarModifier.prototype._onInit = function( callback, config, forceKeepRemoveButtons ) {
+               forceKeepRemoveButtons = ( forceKeepRemoveButtons === true );
+               AbstractToolbarModifier.prototype._onInit.call( this, undefined, config );
+
+               this.removedButtons = [];
+
+               if ( forceKeepRemoveButtons ) {
+                       if ( this.actualConfig.removeButtons ) {
+                               this.removedButtons = this.actualConfig.removeButtons.split( ',' );
+                       } else {
+                               this.removedButtons = [];
+                       }
+               } else {
+                       if ( !( 'removeButtons' in this.originalConfig ) ) {
+                               this.originalConfig.removeButtons = '';
+                               this.removedButtons = [];
+                       } else {
+                               this.removedButtons = this.originalConfig.removeButtons ? this.originalConfig.removeButtons.split( ',' ) : [];
+                       }
+               }
+
+               if ( !this.actualConfig.toolbarGroups )
+                       this.actualConfig.toolbarGroups = this.fullToolbarEditor.getFullToolbarGroupsConfig();
+
+               this._fixGroups( this.actualConfig );
+               this._calculateTotalBtns();
+
+               this._createModifier();
+               this._refreshMoveBtnsAvalibility();
+               this._refreshBtnTabIndexes();
+
+               if ( typeof callback === 'function' )
+                       callback( this.mainContainer );
+       };
+
+       /**
+        * @private
+        */
+       ToolbarModifier.prototype._showConfigurationTool = function() {
+               this.configContainer.addClass( 'hidden' );
+               this.modifyContainer.removeClass( 'hidden' );
+       };
+
+       /**
+        * Show configuration file in tool
+        *
+        * @private
+        */
+       ToolbarModifier.prototype._showConfig = function() {
+               var that = this,
+                       actualConfig = this.getActualConfig(),
+                       cfg = {};
+               if ( actualConfig.toolbarGroups ) {
+                       cfg.toolbarGroups = actualConfig.toolbarGroups;
+
+                       var groups = prepareGroups( actualConfig.toolbarGroups, this.cfg.trimEmptyGroups );
+
+                       cfg.toolbarGroups = '\n\t\t' + groups.join( ',\n\t\t' );
+               }
+
+               function prepareGroups( toolbarGroups, trimEmptyGroups ) {
+                       var groups = [],
+                               max = toolbarGroups.length;
+
+                       for ( var i = 0; i < max; i++ ) {
+                               var group = toolbarGroups[ i ];
+
+                               if ( group === '/' ) {
+                                       groups.push( '\'/\'' );
+                                       continue;
+                               }
+
+                               if ( trimEmptyGroups ) {
+                                       var max2 = group.groups.length;
+                                       while ( max2-- ) {
+                                               var subgroup = group.groups[ max2 ];
+
+                                               if ( ToolbarModifier.getTotalSubGroupButtonsNumber( subgroup, that.fullToolbarEditor ) === 0 ) {
+                                                       group.groups.splice( max2, 1 );
+                                               }
+                                       }
+                               }
+
+                               if ( !( trimEmptyGroups && group.groups.length === 0 ) ) {
+                                       groups.push( AbstractToolbarModifier.stringifyJSONintoOneLine( group, {
+                                               addSpaces: true,
+                                               noQuotesOnKey: true,
+                                               singleQuotes: true
+                                       } ) );
+                               }
+                       }
+
+                       return groups;
+               }
+
+               if ( actualConfig.removeButtons ) {
+                       cfg.removeButtons = actualConfig.removeButtons;
+               }
+
+               var content = [
+                       '<textarea class="configCode" readonly>',
+                       'CKEDITOR.editorConfig = function( config ) {\n',
+                       ( cfg.toolbarGroups ? '\tconfig.toolbarGroups = [' + cfg.toolbarGroups + '\n\t];' : '' ),
+                       ( cfg.removeButtons ? '\n\n' : '' ),
+                       ( cfg.removeButtons ? '\tconfig.removeButtons = \'' + cfg.removeButtons + '\';' : '' ),
+                       '\n};',
+                       '</textarea>'
+               ].join( '' );
+
+
+
+               this.modifyContainer.addClass( 'hidden' );
+               this.configContainer.removeClass( 'hidden' );
+
+               this.configContainer.setHtml( content );
+       };
+
+       /**
+        * Toggle empty groups and subgroups visibility.
+        *
+        * @private
+        */
+       ToolbarModifier.prototype._toggleVisibilityEmptyElements = function() {
+               if ( this.modifyContainer.hasClass( 'empty-visible' ) ) {
+                       this.modifyContainer.removeClass( 'empty-visible' );
+                       this.emptyVisible = false;
+               } else {
+                       this.modifyContainer.addClass( 'empty-visible' );
+                       this.emptyVisible = true;
+               }
+
+               this._refreshMoveBtnsAvalibility();
+       };
+
+       /**
+        * Creates HTML main container of modifier.
+        *
+        * @returns {CKEDITOR.dom.element}
+        * @private
+        */
+       ToolbarModifier.prototype._createModifier = function() {
+               var that = this;
+
+               AbstractToolbarModifier.prototype._createModifier.call( this );
+
+               this.modifyContainer.setHtml( this._toolbarConfigToListString() );
+
+               var groupLi = this.modifyContainer.find( 'li[data-type="group"]' );
+
+               this.modifyContainer.on( 'mouseleave', function() {
+                       this._dehighlightActiveToolGroup();
+               }, this );
+
+               var max = groupLi.count();
+               for ( var i = 0; i < max; i += 1 ) {
+                       groupLi.getItem( i ).on( 'mouseenter', onGroupHover );
+               }
+
+               function onGroupHover() {
+                       that._highlightGroup( this.data( 'name' ) );
+               }
+
+               CKEDITOR.document.on( 'keypress', function( e ) {
+                       var nativeEvent = e.data.$,
+                               keyCode = nativeEvent.keyCode,
+                               spaceOrEnter = ( keyCode === 32 || keyCode === 13 ),
+                               active = new CKEDITOR.dom.element( CKEDITOR.document.$.activeElement );
+
+                       var mainContainer = active.getAscendant( function( node ) {
+                               return node.$ === that.mainContainer.$;
+                       } );
+
+                       if ( !mainContainer || !spaceOrEnter ) {
+                               return;
+                       }
+
+                       if ( active.data( 'type' ) === 'button' ) {
+                               active.findOne( 'input' ).$.click();
+                       }
+               } );
+
+               this.modifyContainer.on( 'click', function( e ) {
+                       var origEvent = e.data.$,
+                               target = new CKEDITOR.dom.element( ( origEvent.target || origEvent.srcElement ) ),
+                               relativeGroupOrSeparatorLi = ToolbarModifier.getGroupOrSeparatorLiAncestor( target );
+
+                       if ( !relativeGroupOrSeparatorLi ) {
+                               return;
+                       }
+
+                       that.cachedActiveElement = document.activeElement;
+
+                       // checkbox clicked
+                       if ( target.$ instanceof HTMLInputElement )
+                               that._handleCheckboxClicked( target );
+
+                       // link clicked
+                       else if ( target.$ instanceof HTMLButtonElement ) {
+                               if ( origEvent.preventDefault )
+                                       origEvent.preventDefault();
+                               else
+                                       origEvent.returnValue = false;
+
+                               var result = that._handleAnchorClicked( target.$ );
+
+                               if ( result && result.action == 'remove' )
+                                       return;
+
+                       }
+
+                       var elementType = relativeGroupOrSeparatorLi.data( 'type' ),
+                               elementName = relativeGroupOrSeparatorLi.data( 'name' );
+
+                       that._setActiveElement( elementType, elementName );
+
+                       if ( that.cachedActiveElement )
+                               that.cachedActiveElement.focus();
+               } );
+
+               if ( !this.toolbarContainer ) {
+                       this._createToolbar();
+                       this.toolbarContainer.insertBefore( this.mainContainer.getChildren().getItem( 0 ) );
+               }
+
+               this.showToolbarBtnsByGroupName( 'edit' );
+
+               if ( !this.configContainer ) {
+                       this.configContainer = new CKEDITOR.dom.element( 'div' );
+                       this.configContainer.addClass( 'configContainer' );
+                       this.configContainer.addClass( 'hidden' );
+
+                       this.mainContainer.append( this.configContainer );
+               }
+
+               return this.mainContainer;
+       };
+
+       /**
+        * Show toolbar buttons related to group name provided in argument
+        * and hide other buttons
+        * Please note: this method works on toolbar in tool, which is located
+        * on top of the tool
+        *
+        * @param {String} groupName
+        */
+       ToolbarModifier.prototype.showToolbarBtnsByGroupName = function( groupName ) {
+               if ( !this.toolbarContainer ) {
+                       return;
+               }
+
+               var allButtons = this.toolbarContainer.find( 'button' );
+
+               var max = allButtons.count();
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentBtn = allButtons.getItem( i );
+
+                       if ( currentBtn.data( 'group' ) == groupName )
+                               currentBtn.removeClass( 'hidden' );
+                       else
+                               currentBtn.addClass( 'hidden' );
+
+               }
+       };
+
+       /**
+        * Parse group "model" to configuration value
+        *
+        * @param {Object} group
+        * @returns {Object}
+        * @private
+        */
+       ToolbarModifier.parseGroupToConfigValue = function( group ) {
+               if ( group.type == 'separator' ) {
+                       return '/';
+               }
+
+               var groups = group.groups,
+                       max = groups.length;
+
+               delete group.totalBtns;
+               for ( var i = 0; i < max; i += 1 ) {
+                       groups[ i ] = groups[ i ].name;
+               }
+
+               return group;
+       };
+
+       /**
+        * Find closest Li ancestor in DOM tree which is group or separator element
+        *
+        * @param {CKEDITOR.dom.element} element
+        * @returns {CKEDITOR.dom.element}
+        */
+       ToolbarModifier.getGroupOrSeparatorLiAncestor = function( element ) {
+               if ( element.$ instanceof HTMLLIElement && element.data( 'type' ) == 'group' )
+                       return element;
+               else {
+                       return ToolbarModifier.getFirstAncestor( element, function( ancestor ) {
+                               var type = ancestor.data( 'type' );
+
+                               return ( type == 'group' || type == 'separator' );
+                       } );
+               }
+       };
+
+       /**
+        * Set active element in tool by provided type and name.
+        *
+        * @param {String} type
+        * @param {String} name
+        */
+       ToolbarModifier.prototype._setActiveElement = function( type, name ) {
+               // clear current active element
+               if ( this.currentActive )
+                       this.currentActive.elem.removeClass( 'active' );
+
+               if ( type === null ) {
+                       this._dehighlightActiveToolGroup();
+                       this.currentActive = null;
+                       return;
+               }
+
+               var liElem = this.mainContainer.findOne( 'ul[data-type=table-body] li[data-type="' + type + '"][data-name="' + name + '"]' );
+
+               liElem.addClass( 'active' );
+
+               // setup model
+               this.currentActive = {
+                       type: type,
+                       name: name,
+                       elem: liElem
+               };
+
+               // highlight group in toolbar
+               if ( type == 'group' )
+                       this._highlightGroup( name );
+
+               if ( type == 'separator' )
+                       this._dehighlightActiveToolGroup();
+       };
+
+       /**
+        * @returns {CKEDITOR.dom.element|null}
+        */
+       ToolbarModifier.prototype.getActiveToolGroup = function() {
+               if ( this.editorInstance.container )
+                       return this.editorInstance.container.findOne( '.cke_toolgroup.active, .cke_toolbar.active' );
+               else
+                       return null;
+       };
+
+       /**
+        * @private
+        */
+       ToolbarModifier.prototype._dehighlightActiveToolGroup = function() {
+               var currentActive = this.getActiveToolGroup();
+
+               if ( currentActive )
+                       currentActive.removeClass( 'active' );
+
+               // @see ToolbarModifier.prototype._highlightGroup.
+               if ( this.editorInstance.container ) {
+                       this.editorInstance.container.removeClass( 'some-toolbar-active' );
+               }
+       };
+
+       /**
+        * Highlight group by its name, and dehighlight current group.
+        *
+        * @param {String} name
+        */
+       ToolbarModifier.prototype._highlightGroup = function( name ) {
+               if ( !this.editorInstance.container )
+                       return;
+
+               var foundBtnName = this.getFirstEnabledButtonInGroup( name ),
+                       foundBtn = this.editorInstance.container.findOne( '.cke_button__' + foundBtnName + ', .cke_combo__' + foundBtnName );
+
+               this._dehighlightActiveToolGroup();
+
+               // Helpful to dim other toolbar groups if one is highlighted.
+               if ( this.editorInstance.container ) {
+                       this.editorInstance.container.addClass( 'some-toolbar-active' );
+               }
+
+               if ( foundBtn ) {
+                       var btnToolbar = ToolbarModifier.getFirstAncestor( foundBtn, function( ancestor ) {
+                               return ancestor.hasClass( 'cke_toolbar' );
+                       } );
+
+                       if ( btnToolbar )
+                               btnToolbar.addClass( 'active' );
+               }
+       };
+
+       /**
+        * @param {String} groupName
+        * @return {String|null}
+        */
+       ToolbarModifier.prototype.getFirstEnabledButtonInGroup = function( groupName ) {
+               var groups = this.actualConfig.toolbarGroups,
+                       groupIndex = this.getGroupIndex( groupName ),
+                       group = groups[ groupIndex ];
+
+               if ( groupIndex === -1 ) {
+                       return null;
+               }
+
+               var max = group.groups ? group.groups.length : 0;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currSubgroupName = group.groups[ i ].name,
+                               firstEnabled = this.getFirstEnabledButtonInSubgroup( currSubgroupName );
+
+                       if ( firstEnabled )
+                               return firstEnabled;
+               }
+               return null;
+       };
+
+       /**
+        * @param {String} subgroupName
+        * @returns {String|null}
+        */
+       ToolbarModifier.prototype.getFirstEnabledButtonInSubgroup = function( subgroupName ) {
+               var subgroupBtns = this.fullToolbarEditor.buttonsByGroup[ subgroupName ];
+
+               var max = subgroupBtns ? subgroupBtns.length : 0;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currBtnName = subgroupBtns[ i ].name;
+                       if ( !this.isButtonRemoved( currBtnName ) )
+                               return currBtnName;
+               }
+
+               return null;
+       };
+
+       /**
+        * Sets up parameters and call adequate action.
+        *
+        * @param {CKEDITOR.dom.element} checkbox
+        * @private
+        */
+       ToolbarModifier.prototype._handleCheckboxClicked = function( checkbox ) {
+               var closestLi = checkbox.getAscendant( 'li' ),
+                       elementName = closestLi.data( 'name' ),
+                       aboutToAddToRemoved = !checkbox.$.checked;
+
+               if ( aboutToAddToRemoved )
+                       this._addButtonToRemoved( elementName );
+               else
+                       this._removeButtonFromRemoved( elementName );
+       };
+
+       /**
+        * Sets up parameters and call adequate action.
+        *
+        * @param {HTMLAnchorElement} anchor
+        * @private
+        */
+       ToolbarModifier.prototype._handleAnchorClicked = function( anchor ) {
+               var anchorDOM = new CKEDITOR.dom.element( anchor ),
+                       relativeLi = anchorDOM.getAscendant( 'li' ),
+                       relativeUl = relativeLi.getAscendant( 'ul' ),
+                       elementType = relativeLi.data( 'type' ),
+                       elementName = relativeLi.data( 'name' ),
+                       direction = anchorDOM.data( 'direction' ),
+                       nearestLi = ( direction === 'up' ? relativeLi.getPrevious() : relativeLi.getNext() ),
+                       groupName,
+                       subgroupName,
+                       newIndex;
+
+               // nothing to do
+               if ( anchorDOM.hasClass( 'disabled' ) )
+                       return null;
+
+               // remove separator and nothing else
+               if ( anchorDOM.hasClass( 'remove' ) ) {
+                       relativeLi.remove();
+                       this._removeSeparator( relativeLi.data( 'name' ) );
+                       this._setActiveElement( null );
+                       return { action: 'remove' };
+               }
+
+               if ( !anchorDOM.hasClass( 'move' ) || !nearestLi )
+                       return { action: null };
+
+               // move group or separator
+               if ( elementType === 'group' || elementType === 'separator' ) {
+                       groupName = elementName;
+                       newIndex = this._moveGroup( direction, groupName );
+               }
+
+               // move subgroup
+               if ( elementType === 'subgroup' ) {
+                       subgroupName = elementName;
+                       groupName = relativeLi.getAscendant( 'li' ).data( 'name' );
+                       newIndex = this._moveSubgroup( direction, groupName, subgroupName );
+               }
+
+               // Visual effect
+               if ( direction === 'up' )
+                       relativeLi.insertBefore( relativeUl.getChild( newIndex ) );
+
+               if ( direction === 'down' )
+                       relativeLi.insertAfter( relativeUl.getChild( newIndex ) );
+
+               // Should know whether there is next li element after modifications.
+               var nextLi = relativeLi;
+
+               // We are looking for next li element in list (to check whether current one is the last one)
+               var found;
+               while ( nextLi = ( direction === 'up' ? nextLi.getPrevious() : nextLi.getNext() ) ) {
+                       if ( !this.emptyVisible && nextLi.hasClass( 'empty' ) ) {
+                               continue;
+                       }
+
+                       found = nextLi;
+                       break;
+               }
+
+               // If not found, it means that we reached end.
+               if ( !found ) {
+                       var selector = ( '[data-direction="' + ( direction === 'up' ? 'down' : 'up' ) + '"]' );
+
+                       // Shifting direction.
+                       this.cachedActiveElement = anchorDOM.getParent().findOne( selector );
+               }
+
+               this._refreshMoveBtnsAvalibility();
+               this._refreshBtnTabIndexes();
+
+               return {
+                       action: 'move'
+               };
+       };
+
+       /**
+        * First element can not be moved up, and last element can not be moved down,
+        * so they are disabled.
+        */
+       ToolbarModifier.prototype._refreshMoveBtnsAvalibility = function() {
+               var that = this,
+                       disabledBtns = this.mainContainer.find( 'ul[data-type=table-body] li > p > span > button.move.disabled' );
+
+               // enabling all disabled buttons
+               var max = disabledBtns.count();
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentBtn = disabledBtns.getItem( i );
+                       currentBtn.removeClass( 'disabled' );
+               }
+
+
+               function disableElementsInLists( ulList ) {
+                       var max = ulList.count();
+                       for ( i = 0; i < max; i += 1 ) {
+                               that._disableElementsInList( ulList.getItem( i ) );
+                       }
+               }
+
+               // Disable buttons in toolbars.
+               disableElementsInLists( this.mainContainer.find( 'ul[data-type=table-body]' ) );
+
+               // Disable buttons in toolbar groups.
+               disableElementsInLists( this.mainContainer.find( 'ul[data-type=table-body] > li > ul' ) );
+       };
+
+       /**
+        * @private
+        */
+       ToolbarModifier.prototype._refreshBtnTabIndexes = function() {
+               var tabindexed = this.mainContainer.find( '[data-tab="true"]' );
+
+               var max = tabindexed.count();
+               for ( var i = 0; i < max; i++ ) {
+                       var item = tabindexed.getItem( i ),
+                               disabled = item.hasClass( 'disabled' );
+
+                       item.setAttribute( 'tabindex', disabled ? -1 : i );
+               }
+       };
+
+       /**
+        * Disable buttons to move elements up and down which should be disabled.
+        *
+        * @param {CKEDITOR.dom.element} ul
+        * @private
+        */
+       ToolbarModifier.prototype._disableElementsInList = function( ul ) {
+               var liList = ul.getChildren();
+
+               if ( !liList.count() )
+                       return;
+
+               var firstDisabled, lastDisabled;
+               if ( this.emptyVisible ) {
+                       firstDisabled = ul.getFirst();
+                       lastDisabled = ul.getLast();
+               } else {
+                       firstDisabled = ul.getFirst( isNotEmptyChecker );
+                       lastDisabled = ul.getLast( isNotEmptyChecker );
+               }
+
+               function isNotEmptyChecker( element ) {
+                       return !element.hasClass( 'empty' );
+               }
+
+               if ( firstDisabled )
+                       var firstDisabledBtn = firstDisabled.findOne( 'p button[data-direction="up"]' );
+
+               if ( lastDisabled )
+                       var lastDisabledBtn = lastDisabled.findOne( 'p button[data-direction="down"]' );
+
+               if ( firstDisabledBtn ) {
+                       firstDisabledBtn.addClass( 'disabled' );
+                       firstDisabledBtn.setAttribute( 'tabindex', '-1' );
+               }
+
+               if ( lastDisabledBtn ) {
+                       lastDisabledBtn.addClass( 'disabled' );
+                       lastDisabledBtn.setAttribute( 'tabindex', '-1' );
+               }
+       };
+
+       /**
+        * Gets group index in actual config toolbarGroups
+        *
+        * @param {String} name
+        * @returns {Number}
+        */
+       ToolbarModifier.prototype.getGroupIndex = function( name ) {
+               var groups = this.actualConfig.toolbarGroups;
+
+               var max = groups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       if ( groups[ i ].name === name )
+                               return i;
+               }
+
+               return -1;
+       };
+
+       /**
+        * Handle adding separator.
+        *
+        * @private
+        */
+       ToolbarModifier.prototype._addSeparator = function() {
+               var separatorIndex = this._determineSeparatorToAddIndex(),
+                       separator = ToolbarModifier.createSeparatorLiteral(),
+                       domSeparator = CKEDITOR.dom.element.createFromHtml( ToolbarModifier.getToolbarSeparatorString( separator ) );
+
+               this.actualConfig.toolbarGroups.splice( separatorIndex, 0, separator );
+
+               domSeparator.insertBefore( this.modifyContainer.findOne( 'ul[data-type=table-body]' ).getChild( separatorIndex ) );
+
+               this._setActiveElement( 'separator', separator.name );
+               this._refreshMoveBtnsAvalibility();
+               this._refreshBtnTabIndexes();
+               this._refreshEditor();
+       };
+
+       /**
+        * Handle removing separator.
+        *
+        * @param {String} name
+        */
+       ToolbarModifier.prototype._removeSeparator = function( name ) {
+               var separatorIndex = CKEDITOR.tools.indexOf( this.actualConfig.toolbarGroups, function( group ) {
+                       return group.type == 'separator' && group.name == name;
+               } );
+
+               this.actualConfig.toolbarGroups.splice( separatorIndex, 1 );
+
+               this._refreshMoveBtnsAvalibility();
+               this._refreshBtnTabIndexes();
+               this._refreshEditor();
+       };
+
+       /**
+        * Determine index where separator should be added, based on currently selected element.
+        *
+        * @returns {Number}
+        * @private
+        */
+       ToolbarModifier.prototype._determineSeparatorToAddIndex = function() {
+               if ( !this.currentActive )
+                       return 0;
+
+               var groupLi;
+               if ( this.currentActive.elem.data( 'type' ) == 'group' || this.currentActive.elem.data( 'type' ) == 'separator' )
+                       groupLi = this.currentActive.elem;
+               else
+                       groupLi = this.currentActive.elem.getAscendant( 'li' );
+
+               return groupLi.getIndex();
+       };
+
+       /**
+        * @param {Array} elementsArray
+        * @param {Number} elementIndex
+        * @param {String} direction
+        * @returns {Number}
+        * @private
+        */
+       ToolbarModifier.prototype._moveElement = function( elementsArray, elementIndex, direction ) {
+               var nextIndex;
+
+               if ( this.emptyVisible )
+                       nextIndex = ( direction == 'down' ? elementIndex + 1 : elementIndex - 1 );
+               else {
+                       // When empty elements are not visible, there is need to skip them.
+                       nextIndex = ToolbarModifier.getFirstElementIndexWith( elementsArray, elementIndex, direction, isEmptyOrSeparatorChecker );
+               }
+
+               function isEmptyOrSeparatorChecker( element ) {
+                       return element.totalBtns || element.type == 'separator';
+               }
+
+               var offset = nextIndex - elementIndex;
+
+               return ToolbarModifier.moveTo( offset, elementsArray, elementIndex );
+       };
+
+       /**
+        * Moves group located in config level up or down and refresh editor.
+        *
+        * @param {String} direction
+        * @param {String} groupName
+        * @returns {Number}
+        */
+       ToolbarModifier.prototype._moveGroup = function( direction, groupName ) {
+               var groupIndex = this.getGroupIndex( groupName ),
+                       groups = this.actualConfig.toolbarGroups,
+                       newIndex = this._moveElement( groups, groupIndex, direction );
+
+               this._refreshMoveBtnsAvalibility();
+               this._refreshBtnTabIndexes();
+               this._refreshEditor();
+
+               return newIndex;
+       };
+
+       /**
+        * Moves subgroup located in config level up or down and refresh editor.
+        *
+        * @param {String} direction
+        * @param {String} groupName
+        * @param {String} subgroupName
+        * @private
+        */
+       ToolbarModifier.prototype._moveSubgroup = function( direction, groupName, subgroupName ) {
+               var groupIndex = this.getGroupIndex( groupName ),
+                       groups = this.actualConfig.toolbarGroups,
+                       group = groups[ groupIndex ],
+                       subgroupIndex = CKEDITOR.tools.indexOf( group.groups, function( subgroup ) {
+                               return subgroup.name == subgroupName;
+                       } ),
+                       newIndex = this._moveElement( group.groups, subgroupIndex, direction );
+
+               this._refreshEditor();
+
+               return newIndex;
+       };
+
+       /**
+        * Set `totalBtns` property in `actualConfig.toolbarGroups` elements.
+        *
+        * @private
+        */
+       ToolbarModifier.prototype._calculateTotalBtns = function() {
+               var groups = this.actualConfig.toolbarGroups;
+
+               var i = groups.length;
+               // from the end
+               while ( i-- ) {
+                       var currentGroup = groups[ i ],
+                               totalBtns = ToolbarModifier.getTotalGroupButtonsNumber( currentGroup, this.fullToolbarEditor );
+
+                       if ( currentGroup.type == 'separator' ) {
+                               // nothing to do with separator
+                               continue;
+                       }
+
+                       currentGroup.totalBtns = totalBtns;
+               }
+       };
+
+       /**
+        * Add button to removeButtons field in config and refresh editor.
+        *
+        * @param {String} buttonName
+        * @private
+        */
+       ToolbarModifier.prototype._addButtonToRemoved = function( buttonName ) {
+               if ( CKEDITOR.tools.indexOf( this.removedButtons, buttonName ) != -1 )
+                       throw 'Button already added to removed';
+
+               this.removedButtons.push( buttonName );
+               this.actualConfig.removeButtons = this.removedButtons.join( ',' );
+               this._refreshEditor();
+       };
+
+       /**
+        * Remove button from removeButtons field in config and refresh editor.
+        *
+        * @param {String} buttonName
+        * @private
+        */
+       ToolbarModifier.prototype._removeButtonFromRemoved = function( buttonName ) {
+               var foundAtIndex =  CKEDITOR.tools.indexOf( this.removedButtons, buttonName );
+
+               if ( foundAtIndex === -1 )
+                       throw 'Trying to remove button from removed, but not found';
+
+               this.removedButtons.splice( foundAtIndex, 1 );
+               this.actualConfig.removeButtons = this.removedButtons.join( ',' );
+               this._refreshEditor();
+       };
+
+       /**
+        * Parse group "model" to configuration value
+        *
+        * @param {Object} group
+        * @returns {Object}
+        * @static
+        */
+       ToolbarModifier.parseGroupToConfigValue = function( group ) {
+               if ( group.type == 'separator' ) {
+                       return '/';
+               }
+
+               var groups = group.groups,
+                       max = groups.length;
+
+               delete group.totalBtns;
+               for ( var i = 0; i < max; i += 1 ) {
+                       groups[ i ] = groups[ i ].name;
+               }
+
+               return group;
+       };
+
+       /**
+        * Find closest Li ancestor in DOM tree which is group or separator element
+        *
+        * @param {CKEDITOR.dom.element} element
+        * @returns {CKEDITOR.dom.element}
+        * @static
+        */
+       ToolbarModifier.getGroupOrSeparatorLiAncestor = function( element ) {
+               if ( element.$ instanceof HTMLLIElement && element.data( 'type' ) == 'group' )
+                       return element;
+               else {
+                       return ToolbarModifier.getFirstAncestor( element, function( ancestor ) {
+                               var type = ancestor.data( 'type' );
+
+                               return ( type == 'group' || type == 'separator' );
+                       } );
+               }
+       };
+
+       /**
+        * Create separator literal with unique id.
+        *
+        * @public
+        * @static
+        * @return {Object}
+        */
+       ToolbarModifier.createSeparatorLiteral = function() {
+               return {
+                       type: 'separator',
+                       name: ( 'separator' + CKEDITOR.tools.getNextNumber() )
+               };
+       };
+
+       /**
+        * Creates HTML unordered list string based on toolbarGroups field in config.
+        *
+        * @returns {String}
+        * @static
+        */
+       ToolbarModifier.prototype._toolbarConfigToListString = function() {
+               var groups = this.actualConfig.toolbarGroups || [],
+                       listString = '<ul data-type="table-body">';
+
+               var max = groups.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentGroup = groups[ i ];
+
+                       if ( currentGroup.type === 'separator' )
+                               listString += ToolbarModifier.getToolbarSeparatorString( currentGroup );
+                       else
+                               listString += this._getToolbarGroupString( currentGroup );
+               }
+
+               listString += '</ul>';
+
+               var headerString = ToolbarModifier.getToolbarHeaderString();
+
+               return headerString + listString;
+       };
+
+       /**
+        * Created HTML group list element based on group field in config.
+        *
+        * @param {Object} group
+        * @returns {String}
+        * @private
+        */
+       ToolbarModifier.prototype._getToolbarGroupString = function( group ) {
+               var subgroups = group.groups,
+                       groupString = '';
+
+               groupString += [
+                       '<li ',
+                               'data-type="group" ',
+                               'data-name="', group.name, '" ',
+                               ( group.totalBtns ? '' : 'class="empty"' ),
+                       '>'
+               ].join( '' );
+               groupString += ToolbarModifier.getToolbarElementPreString( group ) + '<ul>';
+
+               var max = subgroups.length;
+
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currentSubgroup = subgroups[ i ],
+                               subgroupBtns = this.fullToolbarEditor.buttonsByGroup[ currentSubgroup.name ];
+
+                       groupString += this._getToolbarSubgroupString( currentSubgroup, subgroupBtns );
+               }
+               groupString += '</ul></li>';
+
+               return groupString;
+       };
+
+       /**
+        * @param {Object} separator
+        * @returns {String}
+        * @static
+        */
+       ToolbarModifier.getToolbarSeparatorString = function( separator ) {
+               return [
+                       '<li ',
+                       'data-type="', separator.type , '" ',
+                       'data-name="', separator.name , '"',
+                       '>',
+                       ToolbarModifier.getToolbarElementPreString( 'row separator' ),
+                       '</li>'
+               ].join( '' );
+       };
+
+       /**
+        * @returns {string}
+        */
+       ToolbarModifier.getToolbarHeaderString = function() {
+               return '<ul data-type="table-header">' +
+                       '<li data-type="header">' +
+                               '<p>Toolbars</p>' +
+                               '<ul>' +
+                                       '<li>' +
+                                               '<p>Toolbar groups</p>' +
+                                               '<p>Toolbar group items</p>' +
+                                       '</li>' +
+                               '</ul>' +
+                       '</li>' +
+               '</ul>';
+       };
+
+       /**
+        * Find and return first ancestor of element provided in first argument
+        * which match the criteria checked in function provided in second argument.
+        *
+        * @param {CKEDITOR.dom.element} element
+        * @param {Function} checker
+        * @returns {CKEDITOR.dom.element|null}
+        */
+       ToolbarModifier.getFirstAncestor = function( element, checker ) {
+               var ancestors = element.getParents(),
+                       i = ancestors.length;
+
+               while ( i-- ) {
+                       if ( checker( ancestors[ i ] ) )
+                               return ancestors[ i ];
+               }
+
+               return null;
+       };
+
+       /**
+        * Looking through array elements start from index provided in second argument
+        * and go 'up' or 'down' in array
+        * last argument is condition checker which should return Boolean value
+        *
+        * User cases:
+        *
+        * ToolbarModifier.getFirstElementIndexWith( [3, 4, 8, 1, 4], 2, 'down', function( elem ) { return elem == 4; } ); // 4
+        * ToolbarModifier.getFirstElementIndexWith( [3, 4, 8, 1, 4], 2, 'up', function( elem ) { return elem == 4; } ); // 1
+        *
+        * @param {Array} array
+        * @param {Number} i
+        * @param {String} direction 'up' or 'down'
+        * @param {Function} conditionChecker
+        * @static
+        * @returns {Number} index of found element
+        */
+       ToolbarModifier.getFirstElementIndexWith = function( array, i, direction, conditionChecker ) {
+               function whileChecker() {
+                       var result;
+                       if ( direction === 'up' )
+                               result = i--;
+                       else
+                               result = ( ++i < array.length );
+
+                       return result;
+               }
+
+               while ( whileChecker() ) {
+                       if ( conditionChecker( array[ i ] ) )
+                               return i;
+
+               }
+
+               return -1;
+       };
+
+       /**
+        * Moves array element at index level up or down.
+        *
+        * @static
+        * @param {String} direction
+        * @param {Array} array
+        * @param {Number} index
+        * @returns {Number}
+        */
+       ToolbarModifier.moveTo = function( offset, array, index ) {
+               var element, newIndex;
+
+               if ( index !== -1 )
+                       element = array.splice( index, 1 )[ 0 ];
+
+               newIndex = index + offset;
+
+               array.splice( newIndex, 0, element );
+
+               return newIndex;
+       };
+
+       /**
+        * @static
+        * @param {Object} subgroup
+        * @returns {Number}
+        */
+       ToolbarModifier.getTotalSubGroupButtonsNumber = function( subgroup, fullToolbarEditor ) {
+               var subgroupName = ( typeof subgroup == 'string' ? subgroup : subgroup.name ),
+                       subgroupBtns = fullToolbarEditor.buttonsByGroup[ subgroupName ];
+
+               return ( subgroupBtns ? subgroupBtns.length : 0 );
+       };
+
+       /**
+        * Returns all buttons number in group which are nested in subgroups also.
+        *
+        * @param {Object} group
+        * @param {ToolbarModifier.FullToolbarEditor}
+        * @static
+        * @returns {Number}
+        */
+       ToolbarModifier.getTotalGroupButtonsNumber = function( group, fullToolbarEditor ) {
+               var total = 0,
+                       subgroups = group.groups;
+
+               var max = subgroups ? subgroups.length : 0;
+               for ( var i = 0; i < max; i += 1 )
+                       total += ToolbarModifier.getTotalSubGroupButtonsNumber( subgroups[ i ], fullToolbarEditor );
+
+               return total;
+       };
+
+       /**
+        * Creates HTML subgroup list element based on subgroup field in config.
+        *
+        * @param {Object} subgroup
+        * @param {Array} groupBtns
+        * @returns {String}
+        * @private
+        */
+       ToolbarModifier.prototype._getToolbarSubgroupString = function( subgroup, groupBtns ) {
+               var subgroupString = '';
+
+               subgroupString += [
+                       '<li ',
+                               'data-type="subgroup" ',
+                               'data-name="', subgroup.name, '" ',
+                               ( subgroup.totalBtns ? '' : 'class="empty" ' ),
+                       '>'
+               ].join( '' );
+               subgroupString += ToolbarModifier.getToolbarElementPreString( subgroup.name );
+               subgroupString += '<ul>';
+
+               var max = groupBtns ? groupBtns.length : 0;
+               for ( var i = 0; i < max; i += 1 )
+                       subgroupString += this.getButtonString( groupBtns[ i ] );
+
+               subgroupString += '</ul>';
+
+               subgroupString += '</li>';
+
+               return subgroupString;
+       };
+
+       /**
+        * @param {String} buttonName
+        * @returns {String|null}
+        * @private
+        */
+       ToolbarModifier.prototype._getConfigButtonName = function( buttonName ) {
+               var items = this.fullToolbarEditor.editorInstance.ui.items;
+
+               var name;
+               for ( name in items ) {
+                       if ( items[ name ].name == buttonName )
+                               return name;
+               }
+
+               return null;
+       };
+
+       /**
+        * @param {String} buttonName
+        * @returns {Boolean}
+        */
+       ToolbarModifier.prototype.isButtonRemoved = function( buttonName ) {
+               return CKEDITOR.tools.indexOf( this.removedButtons, this._getConfigButtonName( buttonName ) ) != -1;
+       };
+
+       /**
+        * @param {CKEDITOR.ui.button/CKEDITOR.ui.richCombo} button
+        * @returns {String}
+        * @public
+        */
+       ToolbarModifier.prototype.getButtonString = function( button ) {
+               var checked = ( this.isButtonRemoved( button.name ) ? '' : 'checked="checked"' );
+
+               return [
+                       '<li data-tab="true" data-type="button" data-name="', this._getConfigButtonName( button.name ), '">',
+                               '<label title="', button.label, '" >',
+                                       '<input ',
+                                               'tabindex="-1"',
+                                               'type="checkbox"',
+                                               checked,
+                                       '/>',
+                                       button.$.getOuterHtml(),
+                               '</label>',
+                       '</li>'
+               ].join( '' );
+       };
+
+       /**
+        * Creates group header string.
+        *
+        * @param {Object|String} group
+        * @returns {String}
+        * @static
+        */
+       ToolbarModifier.getToolbarElementPreString = function( group ) {
+               var name = ( group.name ? group.name : group );
+
+               return [
+                       '<p>',
+                               '<span>',
+                                       '<button title="Move element upward" data-tab="true" data-direction="up" class="move icon-up-big"></button>',
+                                       '<button title="Move element downward" data-tab="true" data-direction="down" class="move icon-down-big"></button>',
+                                       ( name == 'row separator' ? '<button title="Remove element" data-tab="true" class="remove icon-trash"></button>' : '' ),
+                                       name,
+                               '</span>',
+                       '</p>'
+               ].join( '' );
+       };
+
+       /**
+        * @static
+        * @param {String} cfg
+        * @returns {String}
+        */
+       ToolbarModifier.evaluateToolbarGroupsConfig = function( cfg ) {
+               cfg = ( function( cfg ) {
+                       var config = {}, result;
+
+                       /*jshint -W002 */
+                       try {
+                               result = eval( '(' + cfg + ')' );
+                       } catch ( e ) {
+                               try {
+                                       result = eval( cfg );
+                               } catch ( e ) {
+                                       return null;
+                               }
+                       }
+                       /*jshint +W002 */
+
+                       if ( config.toolbarGroups && typeof config.toolbarGroups.length === 'number' ) {
+                               return JSON.stringify( config );
+                       } else if ( result && typeof result.length === 'number' ) {
+                               return JSON.stringify( { toolbarGroups: result } );
+                       } else if ( result && result.toolbarGroups ) {
+                               return JSON.stringify( result );
+                       } else {
+                               return null;
+                       }
+
+               }( cfg ) );
+
+               return cfg;
+       };
+
+       return ToolbarModifier;
+} )();
+
diff --git a/sources/samples/toolbarconfigurator/js/toolbartextmodifier.js b/sources/samples/toolbarconfigurator/js/toolbartextmodifier.js
new file mode 100644 (file)
index 0000000..4c14dd2
--- /dev/null
@@ -0,0 +1,623 @@
+/* global CodeMirror, ToolbarConfigurator */
+
+'use strict';
+
+( function() {
+       var AbstractToolbarModifier = ToolbarConfigurator.AbstractToolbarModifier,
+               FullToolbarEditor = ToolbarConfigurator.FullToolbarEditor;
+
+       /**
+        * @class ToolbarConfigurator.ToolbarTextModifier
+        * @param {String} editorId An id of modified editor
+        * @extends AbstractToolbarModifier
+        * @constructor
+        */
+       function ToolbarTextModifier( editorId ) {
+               AbstractToolbarModifier.call( this, editorId );
+
+               this.codeContainer = null;
+               this.hintContainer = null;
+       }
+
+       // Expose the class.
+       ToolbarConfigurator.ToolbarTextModifier = ToolbarTextModifier;
+
+       ToolbarTextModifier.prototype = Object.create( AbstractToolbarModifier.prototype );
+
+       /**
+        * @param {Function} callback
+        * @param {String} [config]
+        * @private
+        */
+       ToolbarTextModifier.prototype._onInit = function( callback, config ) {
+               AbstractToolbarModifier.prototype._onInit.call( this, undefined, config );
+
+               this._createModifier( config ? this.actualConfig : undefined );
+
+               if ( typeof callback === 'function' )
+                       callback( this.mainContainer );
+       };
+
+       /**
+        * Creates HTML main container of modifier.
+        *
+        * @param {String} cfg
+        * @returns {CKEDITOR.dom.element}
+        * @private
+        */
+       ToolbarTextModifier.prototype._createModifier = function( cfg ) {
+               var that = this;
+
+               this._createToolbar();
+
+               if ( this.toolbarContainer ) {
+                       this.mainContainer.append( this.toolbarContainer );
+               }
+
+               AbstractToolbarModifier.prototype._createModifier.call( this );
+
+               this._setupActualConfig( cfg );
+
+               var toolbarCfg = this.actualConfig.toolbar,
+                       cfgValue;
+
+               if ( CKEDITOR.tools.isArray( toolbarCfg ) ) {
+                       var stringifiedToolbar = '[\n\t\t' + FullToolbarEditor.map( toolbarCfg, function( json ) {
+                                       return AbstractToolbarModifier.stringifyJSONintoOneLine( json, {
+                                               addSpaces: true,
+                                               noQuotesOnKey: true,
+                                               singleQuotes: true
+                                       } );
+                               } ).join( ',\n\t\t' ) + '\n\t]';
+
+                       cfgValue = '\tconfig.toolbar = ' + stringifiedToolbar + ';';
+               } else {
+                       cfgValue = 'config.toolbar = [];';
+               }
+
+               cfgValue = [
+                       'CKEDITOR.editorConfig = function( config ) {\n',
+                               cfgValue,
+                       '\n};'
+               ].join( '' );
+
+               function hint( cm ) {
+                       var data = setupData( cm );
+
+                       if ( data.charsBetween === null ) {
+                               return;
+                       }
+
+                       var unused = that.getUnusedButtonsArray( that.actualConfig.toolbar, true, data.charsBetween ),
+                               to = cm.getCursor(),
+                               from = CodeMirror.Pos( to.line, ( to.ch - ( data.charsBetween.length ) ) ),
+                               token = cm.getTokenAt( to ),
+                               prevToken = cm.getTokenAt( { line: to.line, ch: token.start } );
+
+                       // determine that we are at beginning of group,
+                       // so first key is "name"
+                       if ( prevToken.string === '{' )
+                               unused = [ 'name' ];
+
+                       // preventing close with special character and move cursor forward
+                       // when no autocomplete
+                       if ( unused.length === 0 )
+                               return;
+
+                       return new HintData( from, to, unused );
+               }
+
+               function HintData( from, to, list ) {
+                       this.from = from;
+                       this.to = to;
+                       this.list = list;
+                       this._handlers = [];
+               }
+
+               function setupData( cm, character ) {
+                       var result = {};
+
+                       result.cur = cm.getCursor();
+                       result.tok = cm.getTokenAt( result.cur );
+
+                       result[ 'char' ] = character || result.tok.string.charAt( result.tok.string.length - 1 );
+
+                       // Getting string between begin of line and cursor.
+                       var curLineTillCur = cm.getRange( CodeMirror.Pos( result.cur.line, 0 ), result.cur );
+
+                       // Reverse string.
+                       var currLineTillCurReversed = curLineTillCur.split( '' ).reverse().join( '' );
+
+                       // Removing proper string definitions :
+                       // FROM:
+                       // R' ,'odeR' ,'odnU' [ :smeti{
+                       //     ^^^^^^  ^^^^^^
+                       // TO:
+                       // R' , [ :smeti{
+                       currLineTillCurReversed = currLineTillCurReversed.replace( /(['|"]\w*['|"])/g, '' );
+
+                       // Matching letters till ' or " character and end string char.
+                       // R' , [ :smeti{
+                       // ^
+                       result.charsBetween = currLineTillCurReversed.match( /(^\w*)(['|"])/ );
+
+                       if ( result.charsBetween ) {
+                               result.endChar = result.charsBetween[ 2 ];
+
+                               // And reverse string (bring to original state).
+                               result.charsBetween = result.charsBetween[ 1 ].split( '' ).reverse().join( '' );
+                       }
+
+                       return result;
+               }
+
+               function complete( cm ) {
+                       setTimeout( function() {
+                               if ( !cm.state.completionActive ) {
+                                       CodeMirror.showHint( cm, hint, {
+                                               hintsClass: 'toolbar-modifier',
+                                               completeSingle: false
+                                       } );
+                               }
+                       }, 100 );
+
+                       return CodeMirror.Pass;
+               }
+
+               var codeMirrorWrapper = new CKEDITOR.dom.element( 'div' );
+               codeMirrorWrapper.addClass( 'codemirror-wrapper' );
+               this.modifyContainer.append( codeMirrorWrapper );
+               this.codeContainer = CodeMirror( codeMirrorWrapper.$, {
+                       mode: { name: 'javascript', json: true },
+                       // For some reason (most likely CM's bug) gutter breaks CM's height.
+                       // Refreshing CM does not help.
+                       lineNumbers: false,
+                       lineWrapping: true,
+                       // Trick to make CM autogrow. http://codemirror.net/demo/resize.html
+                       viewportMargin: Infinity,
+                       value: cfgValue,
+                       smartIndent: false,
+                       indentWithTabs: true,
+                       indentUnit: 4,
+                       tabSize: 4,
+                       theme: 'neo',
+                       extraKeys: {
+                               'Left': complete,
+                               'Right': complete,
+                               "'''": complete,
+                               "'\"'": complete,
+                               Backspace: complete,
+                               Delete: complete,
+                               'Shift-Tab': 'indentLess'
+                       }
+               } );
+
+               this.codeContainer.on( 'endCompletion', function( cm, completionData ) {
+                       var data = setupData( cm );
+
+                       // preventing close with special character and move cursor forward
+                       // when no autocomplete
+                       if ( completionData === undefined )
+                               return;
+
+                       cm.replaceSelection( data.endChar );
+               } );
+
+               this.codeContainer.on( 'change', function() {
+                       var value = that.codeContainer.getValue();
+
+                       value =  that._evaluateValue( value );
+
+                       if ( value !== null ) {
+                               that.actualConfig.toolbar = ( value.toolbar ? value.toolbar : that.actualConfig.toolbar );
+
+                               that._fillHintByUnusedElements();
+                               that._refreshEditor();
+
+                               that.mainContainer.removeClass( 'invalid' );
+                       } else {
+                               that.mainContainer.addClass( 'invalid' );
+                       }
+               } );
+
+               this.hintContainer = new CKEDITOR.dom.element( 'div' );
+               this.hintContainer.addClass( 'toolbarModifier-hints' );
+
+               this._fillHintByUnusedElements();
+               this.hintContainer.insertBefore( codeMirrorWrapper );
+       };
+
+       /**
+        * Create DOM string and set to hint container,
+        * show proper information when no unused element left.
+        *
+        * @private
+        */
+       ToolbarTextModifier.prototype._fillHintByUnusedElements = function() {
+               var unused = this.getUnusedButtonsArray( this.actualConfig.toolbar, true );
+               unused = this.groupButtonNamesByGroup( unused );
+
+               var unusedElements = FullToolbarEditor.map( unused, function( elem ) {
+                       var buttonsList = FullToolbarEditor.map( elem.buttons, function( buttonName ) {
+                               return '<code>' + buttonName + '</code> ';
+                       } ).join( '' );
+
+                       return [
+                               '<dt>',
+                                       '<code>', elem.name, '</code>',
+                               '</dt>',
+                               '<dd>',
+                                       buttonsList,
+                               '</dd>'
+                       ].join( '' );
+               } ).join( ' ' );
+
+               var listHeader = [
+                       '<dt class="list-header">Toolbar group</dt>',
+                       '<dd class="list-header">Unused items</dd>'
+               ].join( '' );
+
+               var header = '<h3>Unused toolbar items</h3>';
+
+               if ( !unused.length ) {
+                       listHeader = '<p>All items are in use.</p>';
+               }
+
+               this.codeContainer.refresh();
+
+               this.hintContainer.setHtml( header + '<dl>' + listHeader + unusedElements + '</dl>' );
+       };
+
+       /**
+        * @param {String} buttonName
+        * @returns {String}
+        */
+       ToolbarTextModifier.prototype.getToolbarGroupByButtonName = function( buttonName ) {
+               var buttonNames = this.fullToolbarEditor.buttonNamesByGroup;
+
+               for ( var groupName in  buttonNames ) {
+                       var buttons = buttonNames[ groupName ];
+
+                       var i = buttons.length;
+                       while ( i-- ) {
+                               if ( buttonName === buttons[ i ] ) {
+                                       return groupName;
+                               }
+                       }
+
+               }
+
+               return null;
+       };
+
+       /**
+        * Filter all available toolbar elements by array of elements provided in first argument.
+        * Returns elements which are not used.
+        *
+        * @param {Object} toolbar
+        * @param {Boolean} [sorted=false]
+        * @param {String} prefix
+        * @returns {Array}
+        */
+       ToolbarTextModifier.prototype.getUnusedButtonsArray = function( toolbar, sorted, prefix ) {
+               sorted = ( sorted === true ? true : false );
+               var providedElements = ToolbarTextModifier.mapToolbarCfgToElementsList( toolbar ),
+                       allElements = Object.keys( this.fullToolbarEditor.editorInstance.ui.items );
+
+               // get rid of "-" elements
+               allElements = FullToolbarEditor.filter( allElements, function( elem ) {
+                       var isSeparator = ( elem === '-' ),
+                               matchPrefix = ( prefix === undefined || elem.toLowerCase().indexOf( prefix.toLowerCase() ) === 0 );
+
+                       return !isSeparator && matchPrefix;
+               } );
+
+               var elementsNotUsed = FullToolbarEditor.filter( allElements, function( elem ) {
+                       return CKEDITOR.tools.indexOf( providedElements, elem ) == -1;
+               } );
+
+               if ( sorted )
+                       elementsNotUsed.sort();
+
+               return elementsNotUsed;
+       };
+
+       /**
+        *
+        * @param {Array} buttons
+        * @returns {Array}
+        */
+       ToolbarTextModifier.prototype.groupButtonNamesByGroup = function( buttons ) {
+               var result = [],
+                       groupedBtns = JSON.parse( JSON.stringify( this.fullToolbarEditor.buttonNamesByGroup ) );
+
+               for ( var groupName in groupedBtns ) {
+                       var currGroup = groupedBtns[ groupName ];
+                       currGroup = FullToolbarEditor.filter( currGroup, function( btnName ) {
+                               return CKEDITOR.tools.indexOf( buttons, btnName ) !== -1;
+                       } );
+
+                       if ( currGroup.length ) {
+                               result.push( {
+                                       name: groupName,
+                                       buttons: currGroup
+                               } );
+                       }
+
+               }
+
+               return result;
+       };
+
+       /**
+        * Map toolbar config value to flat items list.
+        *
+        * input:
+        * [
+        *   { name: "basicstyles", items: ["Bold", "Italic"] },
+        *   { name: "advancedstyles", items: ["Bold", "Outdent", "Indent"] }
+        * ]
+        *
+        * output:
+        * ["Bold", "Italic", "Outdent", "Indent"]
+        *
+        * @param {Object} toolbar
+        * @returns {Array}
+        */
+       ToolbarTextModifier.mapToolbarCfgToElementsList = function( toolbar ) {
+               var elements = [];
+
+               var max = toolbar.length;
+               for ( var i = 0; i < max; i += 1 ) {
+                       if ( !toolbar[ i ] || typeof toolbar[ i ] === 'string' )
+                               continue;
+
+                       elements = elements.concat( FullToolbarEditor.filter( toolbar[ i ].items, checker ) );
+               }
+
+               function checker( elem ) {
+                       return elem !== '-';
+               }
+
+               return elements;
+       };
+
+       /**
+        * @param {String} cfg
+        * @private
+        */
+       ToolbarTextModifier.prototype._setupActualConfig = function( cfg ) {
+               cfg = cfg || this.editorInstance.config;
+
+               // if toolbar already exists in config, there is nothing to do
+               if ( CKEDITOR.tools.isArray( cfg.toolbar ) )
+                       return;
+
+               // if toolbar group not present, we need to pick them from full toolbar instance
+               if ( !cfg.toolbarGroups )
+                       cfg.toolbarGroups = this.fullToolbarEditor.getFullToolbarGroupsConfig( true );
+
+               this._fixGroups( cfg );
+
+               cfg.toolbar = this._mapToolbarGroupsToToolbar( cfg.toolbarGroups, this.actualConfig.removeButtons );
+
+               this.actualConfig.toolbar = cfg.toolbar;
+               this.actualConfig.removeButtons = '';
+       };
+
+       /**
+        * **Please note:** This method modify element provided in first argument.
+        *
+        * @param {Array} toolbarGroups
+        * @returns {Array}
+        * @private
+        */
+       ToolbarTextModifier.prototype._mapToolbarGroupsToToolbar = function( toolbarGroups, removedBtns ) {
+               removedBtns = removedBtns || this.editorInstance.config.removedBtns;
+               removedBtns = typeof removedBtns == 'string' ? removedBtns.split( ',' ) : [];
+
+               // from the end, because array indexes may change
+               var i = toolbarGroups.length;
+               while ( i-- ) {
+                       var mappedSubgroup = this._mapToolbarSubgroup( toolbarGroups[ i ], removedBtns );
+
+                       if ( toolbarGroups[ i ].type === 'separator' ) {
+                               toolbarGroups[ i ] = '/';
+                               continue;
+                       }
+
+                       // don't want empty groups
+                       if ( CKEDITOR.tools.isArray( mappedSubgroup ) && mappedSubgroup.length === 0 ) {
+                               toolbarGroups.splice( i, 1 );
+                               continue;
+                       }
+
+                       if ( typeof mappedSubgroup == 'string' )
+                               toolbarGroups[ i ] = mappedSubgroup;
+                       else {
+                               toolbarGroups[ i ] = {
+                                       name: toolbarGroups[ i ].name,
+                                       items: mappedSubgroup
+                               };
+                       }
+               }
+
+               return toolbarGroups;
+       };
+
+       /**
+        *
+        * @param {String|Object} group
+        * @param {Array} removedBtns
+        * @returns {Array}
+        * @private
+        */
+       ToolbarTextModifier.prototype._mapToolbarSubgroup = function( group, removedBtns ) {
+               var totalBtns = 0;
+               if ( typeof group == 'string' )
+                       return group;
+
+               var max = group.groups ? group.groups.length : 0,
+                       result = [];
+               for ( var i = 0; i < max; i += 1 ) {
+                       var currSubgroup = group.groups[ i ];
+
+                       var buttons = this.fullToolbarEditor.buttonsByGroup[ typeof currSubgroup === 'string' ? currSubgroup : currSubgroup.name ] || [];
+                       buttons = this._mapButtonsToButtonsNames( buttons, removedBtns );
+                       var currTotalBtns = buttons.length;
+                       totalBtns += currTotalBtns;
+                       result = result.concat( buttons );
+
+                       if ( currTotalBtns )
+                               result.push( '-' );
+               }
+
+               if ( result[ result.length - 1 ] == '-' )
+                       result.pop();
+
+               return result;
+       };
+
+       /**
+        *
+        * @param {Array} buttons
+        * @param {Array} removedBtns
+        * @returns {Array}
+        * @private
+        */
+       ToolbarTextModifier.prototype._mapButtonsToButtonsNames = function( buttons, removedBtns ) {
+               var i = buttons.length;
+               while ( i-- ) {
+                       var currBtn = buttons[ i ],
+                               camelCasedName;
+
+                       if ( typeof currBtn === 'string' ) {
+                               camelCasedName = currBtn;
+                       } else {
+                               camelCasedName = this.fullToolbarEditor.getCamelCasedButtonName( currBtn.name );
+                       }
+
+                       if ( CKEDITOR.tools.indexOf( removedBtns, camelCasedName ) !== -1 ) {
+                               buttons.splice( i, 1 );
+                               continue;
+                       }
+
+                       buttons[ i ] = camelCasedName;
+               }
+
+               return buttons;
+       };
+
+       /**
+        * @param {String} val
+        * @returns {Object}
+        * @private
+        */
+       ToolbarTextModifier.prototype._evaluateValue = function( val ) {
+               var parsed;
+
+               try {
+                       var config = {};
+                       ( function() {
+                               var CKEDITOR = Function( 'var CKEDITOR = {}; ' + val + '; return CKEDITOR;' )();
+
+                               CKEDITOR.editorConfig( config );
+                               parsed = config;
+                       } )();
+
+                       // CKEditor does not handle empty arrays in configuration files
+                       // on IE8
+                       var i = parsed.toolbar.length;
+                       while ( i-- )
+                               if ( !parsed.toolbar[ i ] ) parsed.toolbar.splice( i, 1 );
+
+               } catch ( e ) {
+                       parsed = null;
+               }
+
+               return parsed;
+       };
+
+       /**
+        * @param {Array} toolbar
+        * @returns {{toolbarGroups: Array, removeButtons: string}}
+        */
+       ToolbarTextModifier.prototype.mapToolbarToToolbarGroups = function( toolbar ) {
+               var usedGroups = {},
+                       removeButtons = [],
+                       toolbarGroups = [];
+
+               var max = toolbar.length;
+               for ( var i = 0; i < max; i++ ) {
+                       if ( toolbar[ i ] === '/' ) {
+                               toolbarGroups.push( '/' );
+                               continue;
+                       }
+
+                       var items = toolbar[ i ].items;
+
+                       var toolbarGroup = {};
+                       toolbarGroup.name = toolbar[ i ].name;
+                       toolbarGroup.groups = [];
+
+                       var max2 = items.length;
+                       for ( var j = 0; j < max2; j++ ) {
+                               var item = items[ j ];
+
+                               if ( item === '-' ) {
+                                       continue;
+                               }
+
+                               var groupName = this.getToolbarGroupByButtonName( item );
+
+                               var groupIndex = toolbarGroup.groups.indexOf( groupName );
+                               if ( groupIndex === -1 ) {
+                                       toolbarGroup.groups.push( groupName );
+                               }
+
+                               usedGroups[ groupName ] = usedGroups[ groupName ] || {};
+
+                               var buttons = ( usedGroups[ groupName ].buttons = usedGroups[ groupName ].buttons || {} );
+
+                               buttons[ item ] = buttons[ item ] || { used: 0, origin: toolbarGroup.name };
+                               buttons[ item ].used++;
+                       }
+
+                       toolbarGroups.push( toolbarGroup );
+               }
+
+               // Handling removed buttons
+               removeButtons = prepareRemovedButtons( usedGroups, this.fullToolbarEditor.buttonNamesByGroup );
+
+               function prepareRemovedButtons( usedGroups, buttonNames ) {
+                       var removed = [];
+
+                       for ( var groupName in usedGroups ) {
+                               var group = usedGroups[ groupName ];
+                               var allButtonsInGroup = buttonNames[ groupName ].slice();
+
+                               removed = removed.concat( removeStuffFromArray( allButtonsInGroup, Object.keys( group.buttons ) ) );
+                       }
+
+                       return removed;
+               }
+
+               function removeStuffFromArray( array, stuff ) {
+                       array = array.slice();
+                       var i = stuff.length;
+
+                       while ( i-- ) {
+                               var atIndex = array.indexOf( stuff[ i ] );
+                               if ( atIndex !== -1 ) {
+                                       array.splice( atIndex, 1 );
+                               }
+                       }
+
+                       return array;
+               }
+
+               return { toolbarGroups: toolbarGroups, removeButtons: removeButtons.join( ',' ) };
+       };
+
+       return ToolbarTextModifier;
+} )();
diff --git a/sources/samples/toolbarconfigurator/less/base.less b/sources/samples/toolbarconfigurator/less/base.less
new file mode 100644 (file)
index 0000000..0a212ff
--- /dev/null
@@ -0,0 +1,38 @@
+// Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+// For licensing, see LICENSE.html or http://cksource.com/ckeditor/license
+
+@base-font-size:                               16px;
+@base-line-height:                             24px;
+@base-line-ratio:                              1.8;
+
+@sample-font-stack:                            Arial, Helvetica, sans-serif;
+@sample-font-stack-monospace:  Consolas, Menlo, Monaco, Lucida Console, Liberation Mono, DejaVu Sans Mono, Bitstream Vera Sans Mono, Courier New, monospace, serif;
+@sample-font-maven:                            "Maven Pro";
+@sample-font-indie:                            "Indie Flower";
+@sample-text-color:                            #575757;
+
+@sample-link-color:                            #cf5d4e;
+@sample-link-color-hover:              lighten( @sample-link-color, -10% );
+
+@sample-box-background-color:  #f5f5f5;
+@sample-box-border-color:              #ddd;
+
+@sample-top-navigation-background: #454545;
+
+// Standard gaps
+@sample-standard-vgap:                         1.2em;
+@sample-standard-hgap:                         1.5em;
+
+// Generic font-size/line-height mixin.
+.font-size( @remSize ) {
+       @pxSize: round( @remSize * @base-font-size, 2 );
+
+       @remHeight: round( @remSize * @base-line-ratio, 2 );
+       @pxHeight: round( @pxSize * @base-line-ratio, 2 );
+
+       font-size: ~"@{pxSize}";
+       font-size: ~"@{remSize}rem";
+
+       line-height: ~"@{pxHeight}";
+       line-height: ~"@{remHeight}rem";
+}
diff --git a/sources/samples/toolbarconfigurator/less/toolbarmodifier.less b/sources/samples/toolbarconfigurator/less/toolbarmodifier.less
new file mode 100644 (file)
index 0000000..8aa5d08
--- /dev/null
@@ -0,0 +1,508 @@
+// Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+// For licensing, see LICENSE.html or http://cksource.com/ckeditor/license
+
+@import "base.less";
+
+@modifier-group-hover-color: #fffbe3;
+@modifier-group-active-color: #f0fafb;
+
+@modifier-active-toolbar-color: darken( @modifier-group-hover-color, 10% );
+
+@modifier-toolbar-border-color: #ccc;
+@modifier-toolbar-group-border-color: #ddd;
+@modifier-toolbar-group-vpadding: 2px;
+@modifier-toolbar-hgap: 5px;
+
+@modifier-toolbar-button-color: #e7e7e7;
+
+#toolbar .cke_toolbar {
+       pointer-events: none;
+       .user-select( none );
+       cursor: default;
+}
+
+// Dim all but active toolbars if some is active.
+.some-toolbar-active .cke_toolbar {
+       .opacity( .5 );
+}
+
+.cke_toolbar.active {
+       position: relative;
+
+       // Active toolbar is always highlighted.
+       .opacity( 1 );
+
+       &:after {
+               content: '';
+               display: block;
+               position: absolute;
+               top: 0;
+               right: 6px;
+               bottom: 5px;
+               left: 0;
+               .border-radius( 5px );
+               .box-shadow( 0px 0px 15px 3px @modifier-active-toolbar-color );
+       }
+
+       .cke_toolgroup {
+               .box-shadow( none );
+               border-color: darken( @modifier-active-toolbar-color, 40% );
+       }
+
+       .cke_combo,
+       .cke_toolgroup {
+               position: relative;
+               z-index: 2;
+       }
+
+       .cke_combo_button {
+               .box-shadow( none );
+       }
+}
+
+.unselectable {
+       .user-select( none );
+}
+.toolbar {
+       padding: 5px 0;
+       margin-bottom: 2 * @sample-standard-vgap;
+       overflow: hidden;
+       background: #fff;
+
+       button.button-a {
+               &.cke_button {
+                       cursor: pointer;
+
+                       display: inline-block;
+                       padding: 4px 6px;
+                       outline: 0;
+                       border: 1px solid #a6a6a6;
+               }
+
+               &.hidden {
+                       display: none;
+               }
+
+               &.left {
+                       float: left;
+                       margin-right: 8px;
+               }
+
+               &.right {
+                       float: right;
+                       margin-left: 8px;
+               }
+
+               .highlight {
+                       color: #ffefc1;
+               }
+       }
+}
+
+// Styles applied when configurator is hidden and code is being displayed (and vice-versa).
+.configContainer.hidden,
+.toolbarModifier.hidden,
+.toolbarModifier-hints.hidden {
+       display: none;
+}
+
+.toolbarModifier :focus,
+.toolbar button:focus,
+.configContainer textarea.configCode:focus {
+       outline: none;
+}
+
+div.toolbarModifier {
+       padding: 0;
+       overflow: hidden;
+       width: 100%;
+       position: relative;
+       display: table;
+       border-collapse: collapse;
+
+       ::-moz-focus-inner {
+               border: 0;
+       }
+
+       .empty {
+               display: none;
+       }
+
+       &.empty-visible .empty {
+               display: table-row;
+               .opacity( 0.6 );
+       }
+
+       // Give empty toolbar groups height similar to height of non empty groups.
+       // Non empty groups are stretched by contained toolbar buttons.
+       .empty > p {
+               line-height: 31px;
+       }
+
+       // List of toolbars.
+       & > ul {
+               padding: 0;
+               margin: 0;
+               border-top: 1px solid @modifier-toolbar-border-color;
+               width: 100%;
+
+               &[data-type="table-header"] {
+                       display: table-header-group;
+               }
+
+               &[data-type="table-body"] {
+                       display: table-row-group;
+               }
+
+               // Override global margins and paddings.
+               p {
+                       padding: 0;
+                       margin: 0;
+               }
+
+               // A single toolbar.
+               & > li {
+                       display: table-row;
+
+                       &[data-type="header"] {
+                               font-weight: bold;
+                               user-select: none;
+                               cursor: default;
+                       }
+
+                       &[data-type="group"],
+                       &[data-type="separator"] {
+                               border-bottom: 1px solid @modifier-toolbar-border-color;
+                       }
+
+                       &[data-type="subgroup"] {
+                               border-top: 1px solid #eee;
+
+                               &:first-child {
+                                       border-top: none;
+                               }
+                       }
+
+                       &[data-type="group"].active,
+                       &[data-type="group"]:hover,
+                       &[data-type="separator"].active,
+                       &[data-type="separator"]:hover {
+                               overflow: hidden;
+                               z-index: 2;
+                       }
+
+                       &[data-type="group"].active,
+                       &[data-type="separator"].active,
+                       &[data-type="group"].active:hover,
+                       &[data-type="separator"].active:hover {
+                               background: @modifier-group-active-color;
+                       }
+
+                       &[data-type="group"]:hover,
+                       &[data-type="separator"]:hover {
+                               background: @modifier-group-hover-color;
+                       }
+
+                       &[data-type="separator"] {
+                               &:after {
+                                       content: '';
+                                       width: 100%;
+                               }
+
+                               background: #f5f5f5;
+
+                               & > p {
+                                       padding: @modifier-toolbar-group-vpadding @modifier-toolbar-hgap;
+                               }
+                       }
+
+                       & > p, & > ul {
+                               display: table-cell;
+                               vertical-align: middle;
+                       }
+
+                       // Note: this also controls the list of toolbar groups.
+                       p {
+                               padding-left: @modifier-toolbar-hgap;
+                               min-width: 200px;
+
+                               span {
+                                       white-space: nowrap;
+                                       cursor: default;
+
+                                       button {
+                                               font-size: 12.666px;
+                                               margin-right: 5px;
+                                               cursor: pointer;
+                                               background: #fff;
+                                               .border-radius( 5px );
+                                               border: 1px solid #bbb;
+                                               padding: 0 7px;
+                                               line-height: 12px;
+                                               height: 20px;
+
+                                               &:not(.disabled) {
+                                                       &:hover,
+                                                       &:focus {
+                                                               color: #fff;
+                                                               background-color: @sample-top-navigation-background;
+                                                               border-color: transparent;
+                                                       }
+                                               }
+
+                                               &.move.disabled {
+                                                       cursor: default;
+                                                       .opacity( 0.2 );
+                                               }
+                                       }
+                               }
+                       }
+
+                       // List of toolbar groups.
+                       ul {
+                               border-collapse: collapse;
+                               padding: 0;
+                               width: 100%;
+
+                               // A single toolbar group.
+                               li {
+                                       display: table-row;
+                                       list-style-type: none;
+                                       // Resets slightly increased lists' lh which is bigger than button's height
+                                       // so it stretches columns.
+                                       line-height: 1;
+
+                                       &[data-type="subgroup"] {
+                                               border-top: 1px solid @modifier-toolbar-group-border-color;
+
+                                               &:first-child {
+                                                       border-top: 0;
+                                               }
+
+                                               [data-type="button"] {
+                                                       .border-radius( 3px );
+                                                       padding: 0 2px;
+
+                                                       &:focus {
+                                                               background: rgba(0, 0, 0, 0.04);
+                                                       }
+
+                                                       input {
+                                                               vertical-align: middle;
+                                                       }
+                                               }
+                                       }
+
+                                       & > p, & > ul {
+                                               display: table-cell;
+                                               vertical-align: middle;
+                                       }
+
+                                       // List of buttons in a group.
+                                       ul {
+                                               padding: 0;
+
+                                               // A single button in a group.
+                                               li {
+                                                       padding: 0;
+                                                       display: inline-block;
+                                                       cursor: pointer;
+                                                       margin: @modifier-toolbar-group-vpadding 5px @modifier-toolbar-group-vpadding 0;
+
+                                                       // Enforce styles to save space.
+                                                       .cke_combo_text {
+                                                               cursor: pointer;
+                                                               white-space: nowrap;
+                                                       }
+
+                                                       .cke_toolgroup,
+                                                       .cke_combo_button {
+                                                               cursor: pointer;
+                                                               margin: 0;
+                                                               vertical-align: middle;
+                                                               border: 1px solid #ddd;
+                                                               .font-size( .713 );
+                                                       }
+                                               }
+                                       }
+                               }
+                       }
+               }
+       }
+
+       & > .codemirror-wrapper {
+               overflow-y: auto;
+       }
+
+       // Advanced configurator: list of unused elements.
+       &-hints {
+               float: right;
+               width: 350px;
+               min-width: 150px;
+               overflow-y: auto;
+               margin-left: @sample-standard-hgap;
+
+               h3 {
+                       .font-size( 1.13 );
+                       padding: .3*@sample-standard-vgap @sample-standard-hgap;
+                       background: @sample-box-background-color;
+                       border-bottom: 1px solid @sample-box-border-color;
+                       margin-top: 0;
+                       margin-bottom: @sample-standard-vgap;
+               }
+
+               dl {
+                       //margin-top: 0;
+                       margin-bottom: @sample-standard-vgap;
+                       overflow: hidden;
+
+                       .list-header {
+                               font-weight: bold;
+                               border: 0;
+                               padding-bottom: .5*@sample-standard-vgap;
+                       }
+
+                       & > p {
+                               text-align: center;
+                       }
+
+                       dt {
+                               float: left;
+                               width: 9em;
+                               clear: both;
+                               text-align: right;
+                               border-top: 1px solid @sample-box-border-color;
+                               padding-left: @sample-standard-hgap;
+                               padding-right: .1em;
+                               .box-sizing( border-box );
+
+                               code {
+                                       background: none;
+                                       border: none;
+                                       vertical-align: middle;
+                               }
+                       }
+
+                       dd {
+                               margin-left: 10em;
+                               clear: right;
+                               padding-right: @sample-standard-hgap;
+
+                               code {
+                                       line-height: 2.2em;
+                               }
+
+                               &:after {
+                                       content: '\00a0';
+                                       display: block;
+                                       clear: left;
+                                       float: right;
+                                       height: 0;
+                                       width: 0;
+                               }
+                       }
+               }
+       }
+}
+
+.toolbarModifier-hints,
+.configContainer textarea.configCode,
+.CodeMirror {
+       .border-radius( 3px );
+       border: 1px solid #ccc;
+       .font-size( .813 );
+}
+
+.configContainer textarea.configCode,
+.CodeMirror pre,
+.CodeMirror-linenumber {
+       .font-size( .813 );
+       font-family: @sample-font-stack-monospace;
+}
+
+.CodeMirror pre {
+       border: none;
+       padding: 0;
+       margin: 0;
+}
+
+.configContainer textarea.configCode {
+       .box-sizing( border-box );
+       color: @sample-text-color;
+       padding: 10px;
+       width: 100%;
+       min-height: 500px;
+       margin: 0;
+       resize: none;
+       outline: none;
+       -moz-tab-size: 4;
+       tab-size: 4;
+       white-space: pre;
+       word-wrap: normal;
+       overflow: auto;
+}
+
+.CodeMirror-hints.toolbar-modifier {
+       padding: 0;
+       color: @sample-text-color;
+
+       .CodeMirror-hint-active {
+               color: @sample-text-color;
+               background: @modifier-group-active-color;
+       }
+
+       .font-size( .875 );
+       font-family: @sample-font-stack-monospace;
+
+       & > li:hover {
+               background: @modifier-group-hover-color;
+       }
+}
+
+/* Text modifier */
+#toolbarModifierWrapper {
+       margin-bottom: @sample-standard-vgap;
+
+       .invalid .CodeMirror {
+               background: #fff8f8;
+               border-color: red;
+       }
+
+       .CodeMirror {
+               // Autogrow. http://codemirror.net/demo/resize.html
+               height: auto;
+               // Complementory with std's CodeMirror-lines vertical padding.
+               // Not needed when we use lines number, but we can't due to a bug in CM.
+               padding: 0 @sample-standard-vgap/2;
+       }
+}
+
+.staticContainer {
+       position: fixed;
+       top: 0;
+       width: 100%;
+       z-index: 10;
+
+       > .grid-container {
+               max-width: 1044px + 2 * @grid-gutter-width;
+
+               .inner {
+                       background: #fff;
+
+                       .toolbar {
+                               margin-bottom: 0;
+                       }
+               }
+       }
+}
+
+// Help button to display information about configurator.
+#help {
+       position: relative;
+       top: -15px;
+       left: -5px;
+
+       &-content {
+               display: none;
+       }
+}
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/LICENSE b/sources/samples/toolbarconfigurator/lib/codemirror/LICENSE
new file mode 100644 (file)
index 0000000..d21bbea
--- /dev/null
@@ -0,0 +1,19 @@
+Copyright (C) 2014 by Marijn Haverbeke <marijnh@gmail.com> and others
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/README.md b/sources/samples/toolbarconfigurator/lib/codemirror/README.md
new file mode 100644 (file)
index 0000000..38156a7
--- /dev/null
@@ -0,0 +1,12 @@
+# CodeMirror
+[![Build Status](https://travis-ci.org/codemirror/CodeMirror.svg)](https://travis-ci.org/codemirror/CodeMirror)
+[![NPM version](https://img.shields.io/npm/v/codemirror.svg)](https://www.npmjs.org/package/codemirror)  
+[Funding status: ![maintainer happiness](https://marijnhaverbeke.nl/fund/status_s.png?again)](https://marijnhaverbeke.nl/fund/)
+
+CodeMirror is a JavaScript component that provides a code editor in
+the browser. When a mode is available for the language you are coding
+in, it will color your code, and optionally help with indentation.
+
+The project page is http://codemirror.net  
+The manual is at http://codemirror.net/doc/manual.html  
+The contributing guidelines are in [CONTRIBUTING.md](https://github.com/codemirror/CodeMirror/blob/master/CONTRIBUTING.md)
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/codemirror.css b/sources/samples/toolbarconfigurator/lib/codemirror/codemirror.css
new file mode 100644 (file)
index 0000000..ceacd13
--- /dev/null
@@ -0,0 +1,325 @@
+/* BASICS */
+
+.CodeMirror {
+  /* Set height, width, borders, and global font properties here */
+  font-family: monospace;
+  height: 300px;
+  color: black;
+}
+
+/* PADDING */
+
+.CodeMirror-lines {
+  padding: 4px 0; /* Vertical padding around content */
+}
+.CodeMirror pre {
+  padding: 0 4px; /* Horizontal padding of content */
+}
+
+.CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  background-color: white; /* The little square between H and V scrollbars */
+}
+
+/* GUTTER */
+
+.CodeMirror-gutters {
+  border-right: 1px solid #ddd;
+  background-color: #f7f7f7;
+  white-space: nowrap;
+}
+.CodeMirror-linenumbers {}
+.CodeMirror-linenumber {
+  padding: 0 3px 0 5px;
+  min-width: 20px;
+  text-align: right;
+  color: #999;
+  white-space: nowrap;
+}
+
+.CodeMirror-guttermarker { color: black; }
+.CodeMirror-guttermarker-subtle { color: #999; }
+
+/* CURSOR */
+
+.CodeMirror div.CodeMirror-cursor {
+  border-left: 1px solid black;
+}
+/* Shown when moving in bi-directional text */
+.CodeMirror div.CodeMirror-secondarycursor {
+  border-left: 1px solid silver;
+}
+.CodeMirror.cm-fat-cursor div.CodeMirror-cursor {
+  width: auto;
+  border: 0;
+  background: #7e7;
+}
+.CodeMirror.cm-fat-cursor div.CodeMirror-cursors {
+  z-index: 1;
+}
+
+.cm-animate-fat-cursor {
+  width: auto;
+  border: 0;
+  -webkit-animation: blink 1.06s steps(1) infinite;
+  -moz-animation: blink 1.06s steps(1) infinite;
+  animation: blink 1.06s steps(1) infinite;
+}
+@-moz-keyframes blink {
+  0% { background: #7e7; }
+  50% { background: none; }
+  100% { background: #7e7; }
+}
+@-webkit-keyframes blink {
+  0% { background: #7e7; }
+  50% { background: none; }
+  100% { background: #7e7; }
+}
+@keyframes blink {
+  0% { background: #7e7; }
+  50% { background: none; }
+  100% { background: #7e7; }
+}
+
+/* Can style cursor different in overwrite (non-insert) mode */
+div.CodeMirror-overwrite div.CodeMirror-cursor {}
+
+.cm-tab { display: inline-block; text-decoration: inherit; }
+
+.CodeMirror-ruler {
+  border-left: 1px solid #ccc;
+  position: absolute;
+}
+
+/* DEFAULT THEME */
+
+.cm-s-default .cm-keyword {color: #708;}
+.cm-s-default .cm-atom {color: #219;}
+.cm-s-default .cm-number {color: #164;}
+.cm-s-default .cm-def {color: #00f;}
+.cm-s-default .cm-variable,
+.cm-s-default .cm-punctuation,
+.cm-s-default .cm-property,
+.cm-s-default .cm-operator {}
+.cm-s-default .cm-variable-2 {color: #05a;}
+.cm-s-default .cm-variable-3 {color: #085;}
+.cm-s-default .cm-comment {color: #a50;}
+.cm-s-default .cm-string {color: #a11;}
+.cm-s-default .cm-string-2 {color: #f50;}
+.cm-s-default .cm-meta {color: #555;}
+.cm-s-default .cm-qualifier {color: #555;}
+.cm-s-default .cm-builtin {color: #30a;}
+.cm-s-default .cm-bracket {color: #997;}
+.cm-s-default .cm-tag {color: #170;}
+.cm-s-default .cm-attribute {color: #00c;}
+.cm-s-default .cm-header {color: blue;}
+.cm-s-default .cm-quote {color: #090;}
+.cm-s-default .cm-hr {color: #999;}
+.cm-s-default .cm-link {color: #00c;}
+
+.cm-negative {color: #d44;}
+.cm-positive {color: #292;}
+.cm-header, .cm-strong {font-weight: bold;}
+.cm-em {font-style: italic;}
+.cm-link {text-decoration: underline;}
+.cm-strikethrough {text-decoration: line-through;}
+
+.cm-s-default .cm-error {color: #f00;}
+.cm-invalidchar {color: #f00;}
+
+.CodeMirror-composing { border-bottom: 2px solid; }
+
+/* Default styles for common addons */
+
+div.CodeMirror span.CodeMirror-matchingbracket {color: #0f0;}
+div.CodeMirror span.CodeMirror-nonmatchingbracket {color: #f22;}
+.CodeMirror-matchingtag { background: rgba(255, 150, 0, .3); }
+.CodeMirror-activeline-background {background: #e8f2ff;}
+
+/* STOP */
+
+/* The rest of this file contains styles related to the mechanics of
+   the editor. You probably shouldn't touch them. */
+
+.CodeMirror {
+  position: relative;
+  overflow: hidden;
+  background: white;
+}
+
+.CodeMirror-scroll {
+  overflow: scroll !important; /* Things will break if this is overridden */
+  /* 30px is the magic margin used to hide the element's real scrollbars */
+  /* See overflow: hidden in .CodeMirror */
+  margin-bottom: -30px; margin-right: -30px;
+  padding-bottom: 30px;
+  height: 100%;
+  outline: none; /* Prevent dragging from highlighting the element */
+  position: relative;
+}
+.CodeMirror-sizer {
+  position: relative;
+  border-right: 30px solid transparent;
+}
+
+/* The fake, visible scrollbars. Used to force redraw during scrolling
+   before actuall scrolling happens, thus preventing shaking and
+   flickering artifacts. */
+.CodeMirror-vscrollbar, .CodeMirror-hscrollbar, .CodeMirror-scrollbar-filler, .CodeMirror-gutter-filler {
+  position: absolute;
+  z-index: 6;
+  display: none;
+}
+.CodeMirror-vscrollbar {
+  right: 0; top: 0;
+  overflow-x: hidden;
+  overflow-y: scroll;
+}
+.CodeMirror-hscrollbar {
+  bottom: 0; left: 0;
+  overflow-y: hidden;
+  overflow-x: scroll;
+}
+.CodeMirror-scrollbar-filler {
+  right: 0; bottom: 0;
+}
+.CodeMirror-gutter-filler {
+  left: 0; bottom: 0;
+}
+
+.CodeMirror-gutters {
+  position: absolute; left: 0; top: 0;
+  z-index: 3;
+}
+.CodeMirror-gutter {
+  white-space: normal;
+  height: 100%;
+  display: inline-block;
+  margin-bottom: -30px;
+  /* Hack to make IE7 behave */
+  *zoom:1;
+  *display:inline;
+}
+.CodeMirror-gutter-wrapper {
+  position: absolute;
+  z-index: 4;
+  height: 100%;
+}
+.CodeMirror-gutter-elt {
+  position: absolute;
+  cursor: default;
+  z-index: 4;
+}
+.CodeMirror-gutter-wrapper {
+  -webkit-user-select: none;
+  -moz-user-select: none;
+  user-select: none;
+}
+
+.CodeMirror-lines {
+  cursor: text;
+  min-height: 1px; /* prevents collapsing before first draw */
+}
+.CodeMirror pre {
+  /* Reset some styles that the rest of the page might have set */
+  -moz-border-radius: 0; -webkit-border-radius: 0; border-radius: 0;
+  border-width: 0;
+  background: transparent;
+  font-family: inherit;
+  font-size: inherit;
+  margin: 0;
+  white-space: pre;
+  word-wrap: normal;
+  line-height: inherit;
+  color: inherit;
+  z-index: 2;
+  position: relative;
+  overflow: visible;
+  -webkit-tap-highlight-color: transparent;
+}
+.CodeMirror-wrap pre {
+  word-wrap: break-word;
+  white-space: pre-wrap;
+  word-break: normal;
+}
+
+.CodeMirror-linebackground {
+  position: absolute;
+  left: 0; right: 0; top: 0; bottom: 0;
+  z-index: 0;
+}
+
+.CodeMirror-linewidget {
+  position: relative;
+  z-index: 2;
+  overflow: auto;
+}
+
+.CodeMirror-widget {}
+
+.CodeMirror-code {
+  outline: none;
+}
+
+/* Force content-box sizing for the elements where we expect it */
+.CodeMirror-scroll,
+.CodeMirror-sizer,
+.CodeMirror-gutter,
+.CodeMirror-gutters,
+.CodeMirror-linenumber {
+  -moz-box-sizing: content-box;
+  box-sizing: content-box;
+}
+
+.CodeMirror-measure {
+  position: absolute;
+  width: 100%;
+  height: 0;
+  overflow: hidden;
+  visibility: hidden;
+}
+.CodeMirror-measure pre { position: static; }
+
+.CodeMirror div.CodeMirror-cursor {
+  position: absolute;
+  border-right: none;
+  width: 0;
+}
+
+div.CodeMirror-cursors {
+  visibility: hidden;
+  position: relative;
+  z-index: 3;
+}
+.CodeMirror-focused div.CodeMirror-cursors {
+  visibility: visible;
+}
+
+.CodeMirror-selected { background: #d9d9d9; }
+.CodeMirror-focused .CodeMirror-selected { background: #d7d4f0; }
+.CodeMirror-crosshair { cursor: crosshair; }
+.CodeMirror ::selection { background: #d7d4f0; }
+.CodeMirror ::-moz-selection { background: #d7d4f0; }
+
+.cm-searching {
+  background: #ffa;
+  background: rgba(255, 255, 0, .4);
+}
+
+/* IE7 hack to prevent it from returning funny offsetTops on the spans */
+.CodeMirror span { *vertical-align: text-bottom; }
+
+/* Used to force a border model for a node */
+.cm-force-border { padding-right: .1px; }
+
+@media print {
+  /* Hide the cursor when printing */
+  .CodeMirror div.CodeMirror-cursors {
+    visibility: hidden;
+  }
+}
+
+/* See issue #2901 */
+.cm-tab-wrap-hack:after { content: ''; }
+
+/* Help users use markselection to safely style text background */
+span.CodeMirror-selectedtext { background: none; }
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/codemirror.js b/sources/samples/toolbarconfigurator/lib/codemirror/codemirror.js
new file mode 100644 (file)
index 0000000..37e2685
--- /dev/null
@@ -0,0 +1,8738 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// This is CodeMirror (http://codemirror.net), a code editor
+// implemented in JavaScript on top of the browser's DOM.
+//
+// You can find some technical background for some of the code below
+// at http://marijnhaverbeke.nl/blog/#cm-internals .
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    module.exports = mod();
+  else if (typeof define == "function" && define.amd) // AMD
+    return define([], mod);
+  else // Plain browser env
+    this.CodeMirror = mod();
+})(function() {
+  "use strict";
+
+  // BROWSER SNIFFING
+
+  // Kludges for bugs and behavior differences that can't be feature
+  // detected are enabled based on userAgent etc sniffing.
+
+  var gecko = /gecko\/\d/i.test(navigator.userAgent);
+  var ie_upto10 = /MSIE \d/.test(navigator.userAgent);
+  var ie_11up = /Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent);
+  var ie = ie_upto10 || ie_11up;
+  var ie_version = ie && (ie_upto10 ? document.documentMode || 6 : ie_11up[1]);
+  var webkit = /WebKit\//.test(navigator.userAgent);
+  var qtwebkit = webkit && /Qt\/\d+\.\d+/.test(navigator.userAgent);
+  var chrome = /Chrome\//.test(navigator.userAgent);
+  var presto = /Opera\//.test(navigator.userAgent);
+  var safari = /Apple Computer/.test(navigator.vendor);
+  var mac_geMountainLion = /Mac OS X 1\d\D([8-9]|\d\d)\D/.test(navigator.userAgent);
+  var phantom = /PhantomJS/.test(navigator.userAgent);
+
+  var ios = /AppleWebKit/.test(navigator.userAgent) && /Mobile\/\w+/.test(navigator.userAgent);
+  // This is woefully incomplete. Suggestions for alternative methods welcome.
+  var mobile = ios || /Android|webOS|BlackBerry|Opera Mini|Opera Mobi|IEMobile/i.test(navigator.userAgent);
+  var mac = ios || /Mac/.test(navigator.platform);
+  var windows = /win/i.test(navigator.platform);
+
+  var presto_version = presto && navigator.userAgent.match(/Version\/(\d*\.\d*)/);
+  if (presto_version) presto_version = Number(presto_version[1]);
+  if (presto_version && presto_version >= 15) { presto = false; webkit = true; }
+  // Some browsers use the wrong event properties to signal cmd/ctrl on OS X
+  var flipCtrlCmd = mac && (qtwebkit || presto && (presto_version == null || presto_version < 12.11));
+  var captureRightClick = gecko || (ie && ie_version >= 9);
+
+  // Optimize some code when these features are not used.
+  var sawReadOnlySpans = false, sawCollapsedSpans = false;
+
+  // EDITOR CONSTRUCTOR
+
+  // A CodeMirror instance represents an editor. This is the object
+  // that user code is usually dealing with.
+
+  function CodeMirror(place, options) {
+    if (!(this instanceof CodeMirror)) return new CodeMirror(place, options);
+
+    this.options = options = options ? copyObj(options) : {};
+    // Determine effective options based on given values and defaults.
+    copyObj(defaults, options, false);
+    setGuttersForLineNumbers(options);
+
+    var doc = options.value;
+    if (typeof doc == "string") doc = new Doc(doc, options.mode);
+    this.doc = doc;
+
+    var input = new CodeMirror.inputStyles[options.inputStyle](this);
+    var display = this.display = new Display(place, doc, input);
+    display.wrapper.CodeMirror = this;
+    updateGutters(this);
+    themeChanged(this);
+    if (options.lineWrapping)
+      this.display.wrapper.className += " CodeMirror-wrap";
+    if (options.autofocus && !mobile) display.input.focus();
+    initScrollbars(this);
+
+    this.state = {
+      keyMaps: [],  // stores maps added by addKeyMap
+      overlays: [], // highlighting overlays, as added by addOverlay
+      modeGen: 0,   // bumped when mode/overlay changes, used to invalidate highlighting info
+      overwrite: false,
+      delayingBlurEvent: false,
+      focused: false,
+      suppressEdits: false, // used to disable editing during key handlers when in readOnly mode
+      pasteIncoming: false, cutIncoming: false, // help recognize paste/cut edits in input.poll
+      draggingText: false,
+      highlight: new Delayed(), // stores highlight worker timeout
+      keySeq: null,  // Unfinished key sequence
+      specialChars: null
+    };
+
+    var cm = this;
+
+    // Override magic textarea content restore that IE sometimes does
+    // on our hidden textarea on reload
+    if (ie && ie_version < 11) setTimeout(function() { cm.display.input.reset(true); }, 20);
+
+    registerEventHandlers(this);
+    ensureGlobalHandlers();
+
+    startOperation(this);
+    this.curOp.forceUpdate = true;
+    attachDoc(this, doc);
+
+    if ((options.autofocus && !mobile) || cm.hasFocus())
+      setTimeout(bind(onFocus, this), 20);
+    else
+      onBlur(this);
+
+    for (var opt in optionHandlers) if (optionHandlers.hasOwnProperty(opt))
+      optionHandlers[opt](this, options[opt], Init);
+    maybeUpdateLineNumberWidth(this);
+    if (options.finishInit) options.finishInit(this);
+    for (var i = 0; i < initHooks.length; ++i) initHooks[i](this);
+    endOperation(this);
+    // Suppress optimizelegibility in Webkit, since it breaks text
+    // measuring on line wrapping boundaries.
+    if (webkit && options.lineWrapping &&
+        getComputedStyle(display.lineDiv).textRendering == "optimizelegibility")
+      display.lineDiv.style.textRendering = "auto";
+  }
+
+  // DISPLAY CONSTRUCTOR
+
+  // The display handles the DOM integration, both for input reading
+  // and content drawing. It holds references to DOM nodes and
+  // display-related state.
+
+  function Display(place, doc, input) {
+    var d = this;
+    this.input = input;
+
+    // Covers bottom-right square when both scrollbars are present.
+    d.scrollbarFiller = elt("div", null, "CodeMirror-scrollbar-filler");
+    d.scrollbarFiller.setAttribute("cm-not-content", "true");
+    // Covers bottom of gutter when coverGutterNextToScrollbar is on
+    // and h scrollbar is present.
+    d.gutterFiller = elt("div", null, "CodeMirror-gutter-filler");
+    d.gutterFiller.setAttribute("cm-not-content", "true");
+    // Will contain the actual code, positioned to cover the viewport.
+    d.lineDiv = elt("div", null, "CodeMirror-code");
+    // Elements are added to these to represent selection and cursors.
+    d.selectionDiv = elt("div", null, null, "position: relative; z-index: 1");
+    d.cursorDiv = elt("div", null, "CodeMirror-cursors");
+    // A visibility: hidden element used to find the size of things.
+    d.measure = elt("div", null, "CodeMirror-measure");
+    // When lines outside of the viewport are measured, they are drawn in this.
+    d.lineMeasure = elt("div", null, "CodeMirror-measure");
+    // Wraps everything that needs to exist inside the vertically-padded coordinate system
+    d.lineSpace = elt("div", [d.measure, d.lineMeasure, d.selectionDiv, d.cursorDiv, d.lineDiv],
+                      null, "position: relative; outline: none");
+    // Moved around its parent to cover visible view.
+    d.mover = elt("div", [elt("div", [d.lineSpace], "CodeMirror-lines")], null, "position: relative");
+    // Set to the height of the document, allowing scrolling.
+    d.sizer = elt("div", [d.mover], "CodeMirror-sizer");
+    d.sizerWidth = null;
+    // Behavior of elts with overflow: auto and padding is
+    // inconsistent across browsers. This is used to ensure the
+    // scrollable area is big enough.
+    d.heightForcer = elt("div", null, null, "position: absolute; height: " + scrollerGap + "px; width: 1px;");
+    // Will contain the gutters, if any.
+    d.gutters = elt("div", null, "CodeMirror-gutters");
+    d.lineGutter = null;
+    // Actual scrollable element.
+    d.scroller = elt("div", [d.sizer, d.heightForcer, d.gutters], "CodeMirror-scroll");
+    d.scroller.setAttribute("tabIndex", "-1");
+    // The element in which the editor lives.
+    d.wrapper = elt("div", [d.scrollbarFiller, d.gutterFiller, d.scroller], "CodeMirror");
+
+    // Work around IE7 z-index bug (not perfect, hence IE7 not really being supported)
+    if (ie && ie_version < 8) { d.gutters.style.zIndex = -1; d.scroller.style.paddingRight = 0; }
+    if (!webkit && !(gecko && mobile)) d.scroller.draggable = true;
+
+    if (place) {
+      if (place.appendChild) place.appendChild(d.wrapper);
+      else place(d.wrapper);
+    }
+
+    // Current rendered range (may be bigger than the view window).
+    d.viewFrom = d.viewTo = doc.first;
+    d.reportedViewFrom = d.reportedViewTo = doc.first;
+    // Information about the rendered lines.
+    d.view = [];
+    d.renderedView = null;
+    // Holds info about a single rendered line when it was rendered
+    // for measurement, while not in view.
+    d.externalMeasured = null;
+    // Empty space (in pixels) above the view
+    d.viewOffset = 0;
+    d.lastWrapHeight = d.lastWrapWidth = 0;
+    d.updateLineNumbers = null;
+
+    d.nativeBarWidth = d.barHeight = d.barWidth = 0;
+    d.scrollbarsClipped = false;
+
+    // Used to only resize the line number gutter when necessary (when
+    // the amount of lines crosses a boundary that makes its width change)
+    d.lineNumWidth = d.lineNumInnerWidth = d.lineNumChars = null;
+    // Set to true when a non-horizontal-scrolling line widget is
+    // added. As an optimization, line widget aligning is skipped when
+    // this is false.
+    d.alignWidgets = false;
+
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+
+    // Tracks the maximum line length so that the horizontal scrollbar
+    // can be kept static when scrolling.
+    d.maxLine = null;
+    d.maxLineLength = 0;
+    d.maxLineChanged = false;
+
+    // Used for measuring wheel scrolling granularity
+    d.wheelDX = d.wheelDY = d.wheelStartX = d.wheelStartY = null;
+
+    // True when shift is held down.
+    d.shift = false;
+
+    // Used to track whether anything happened since the context menu
+    // was opened.
+    d.selForContextMenu = null;
+
+    d.activeTouch = null;
+
+    input.init(d);
+  }
+
+  // STATE UPDATES
+
+  // Used to get the editor into a consistent state again when options change.
+
+  function loadMode(cm) {
+    cm.doc.mode = CodeMirror.getMode(cm.options, cm.doc.modeOption);
+    resetModeState(cm);
+  }
+
+  function resetModeState(cm) {
+    cm.doc.iter(function(line) {
+      if (line.stateAfter) line.stateAfter = null;
+      if (line.styles) line.styles = null;
+    });
+    cm.doc.frontier = cm.doc.first;
+    startWorker(cm, 100);
+    cm.state.modeGen++;
+    if (cm.curOp) regChange(cm);
+  }
+
+  function wrappingChanged(cm) {
+    if (cm.options.lineWrapping) {
+      addClass(cm.display.wrapper, "CodeMirror-wrap");
+      cm.display.sizer.style.minWidth = "";
+      cm.display.sizerWidth = null;
+    } else {
+      rmClass(cm.display.wrapper, "CodeMirror-wrap");
+      findMaxLine(cm);
+    }
+    estimateLineHeights(cm);
+    regChange(cm);
+    clearCaches(cm);
+    setTimeout(function(){updateScrollbars(cm);}, 100);
+  }
+
+  // Returns a function that estimates the height of a line, to use as
+  // first approximation until the line becomes visible (and is thus
+  // properly measurable).
+  function estimateHeight(cm) {
+    var th = textHeight(cm.display), wrapping = cm.options.lineWrapping;
+    var perLine = wrapping && Math.max(5, cm.display.scroller.clientWidth / charWidth(cm.display) - 3);
+    return function(line) {
+      if (lineIsHidden(cm.doc, line)) return 0;
+
+      var widgetsHeight = 0;
+      if (line.widgets) for (var i = 0; i < line.widgets.length; i++) {
+        if (line.widgets[i].height) widgetsHeight += line.widgets[i].height;
+      }
+
+      if (wrapping)
+        return widgetsHeight + (Math.ceil(line.text.length / perLine) || 1) * th;
+      else
+        return widgetsHeight + th;
+    };
+  }
+
+  function estimateLineHeights(cm) {
+    var doc = cm.doc, est = estimateHeight(cm);
+    doc.iter(function(line) {
+      var estHeight = est(line);
+      if (estHeight != line.height) updateLineHeight(line, estHeight);
+    });
+  }
+
+  function themeChanged(cm) {
+    cm.display.wrapper.className = cm.display.wrapper.className.replace(/\s*cm-s-\S+/g, "") +
+      cm.options.theme.replace(/(^|\s)\s*/g, " cm-s-");
+    clearCaches(cm);
+  }
+
+  function guttersChanged(cm) {
+    updateGutters(cm);
+    regChange(cm);
+    setTimeout(function(){alignHorizontally(cm);}, 20);
+  }
+
+  // Rebuild the gutter elements, ensure the margin to the left of the
+  // code matches their width.
+  function updateGutters(cm) {
+    var gutters = cm.display.gutters, specs = cm.options.gutters;
+    removeChildren(gutters);
+    for (var i = 0; i < specs.length; ++i) {
+      var gutterClass = specs[i];
+      var gElt = gutters.appendChild(elt("div", null, "CodeMirror-gutter " + gutterClass));
+      if (gutterClass == "CodeMirror-linenumbers") {
+        cm.display.lineGutter = gElt;
+        gElt.style.width = (cm.display.lineNumWidth || 1) + "px";
+      }
+    }
+    gutters.style.display = i ? "" : "none";
+    updateGutterSpace(cm);
+  }
+
+  function updateGutterSpace(cm) {
+    var width = cm.display.gutters.offsetWidth;
+    cm.display.sizer.style.marginLeft = width + "px";
+  }
+
+  // Compute the character length of a line, taking into account
+  // collapsed ranges (see markText) that might hide parts, and join
+  // other lines onto it.
+  function lineLength(line) {
+    if (line.height == 0) return 0;
+    var len = line.text.length, merged, cur = line;
+    while (merged = collapsedSpanAtStart(cur)) {
+      var found = merged.find(0, true);
+      cur = found.from.line;
+      len += found.from.ch - found.to.ch;
+    }
+    cur = line;
+    while (merged = collapsedSpanAtEnd(cur)) {
+      var found = merged.find(0, true);
+      len -= cur.text.length - found.from.ch;
+      cur = found.to.line;
+      len += cur.text.length - found.to.ch;
+    }
+    return len;
+  }
+
+  // Find the longest line in the document.
+  function findMaxLine(cm) {
+    var d = cm.display, doc = cm.doc;
+    d.maxLine = getLine(doc, doc.first);
+    d.maxLineLength = lineLength(d.maxLine);
+    d.maxLineChanged = true;
+    doc.iter(function(line) {
+      var len = lineLength(line);
+      if (len > d.maxLineLength) {
+        d.maxLineLength = len;
+        d.maxLine = line;
+      }
+    });
+  }
+
+  // Make sure the gutters options contains the element
+  // "CodeMirror-linenumbers" when the lineNumbers option is true.
+  function setGuttersForLineNumbers(options) {
+    var found = indexOf(options.gutters, "CodeMirror-linenumbers");
+    if (found == -1 && options.lineNumbers) {
+      options.gutters = options.gutters.concat(["CodeMirror-linenumbers"]);
+    } else if (found > -1 && !options.lineNumbers) {
+      options.gutters = options.gutters.slice(0);
+      options.gutters.splice(found, 1);
+    }
+  }
+
+  // SCROLLBARS
+
+  // Prepare DOM reads needed to update the scrollbars. Done in one
+  // shot to minimize update/measure roundtrips.
+  function measureForScrollbars(cm) {
+    var d = cm.display, gutterW = d.gutters.offsetWidth;
+    var docH = Math.round(cm.doc.height + paddingVert(cm.display));
+    return {
+      clientHeight: d.scroller.clientHeight,
+      viewHeight: d.wrapper.clientHeight,
+      scrollWidth: d.scroller.scrollWidth, clientWidth: d.scroller.clientWidth,
+      viewWidth: d.wrapper.clientWidth,
+      barLeft: cm.options.fixedGutter ? gutterW : 0,
+      docHeight: docH,
+      scrollHeight: docH + scrollGap(cm) + d.barHeight,
+      nativeBarWidth: d.nativeBarWidth,
+      gutterWidth: gutterW
+    };
+  }
+
+  function NativeScrollbars(place, scroll, cm) {
+    this.cm = cm;
+    var vert = this.vert = elt("div", [elt("div", null, null, "min-width: 1px")], "CodeMirror-vscrollbar");
+    var horiz = this.horiz = elt("div", [elt("div", null, null, "height: 100%; min-height: 1px")], "CodeMirror-hscrollbar");
+    place(vert); place(horiz);
+
+    on(vert, "scroll", function() {
+      if (vert.clientHeight) scroll(vert.scrollTop, "vertical");
+    });
+    on(horiz, "scroll", function() {
+      if (horiz.clientWidth) scroll(horiz.scrollLeft, "horizontal");
+    });
+
+    this.checkedOverlay = false;
+    // Need to set a minimum width to see the scrollbar on IE7 (but must not set it on IE8).
+    if (ie && ie_version < 8) this.horiz.style.minHeight = this.vert.style.minWidth = "18px";
+  }
+
+  NativeScrollbars.prototype = copyObj({
+    update: function(measure) {
+      var needsH = measure.scrollWidth > measure.clientWidth + 1;
+      var needsV = measure.scrollHeight > measure.clientHeight + 1;
+      var sWidth = measure.nativeBarWidth;
+
+      if (needsV) {
+        this.vert.style.display = "block";
+        this.vert.style.bottom = needsH ? sWidth + "px" : "0";
+        var totalHeight = measure.viewHeight - (needsH ? sWidth : 0);
+        // A bug in IE8 can cause this value to be negative, so guard it.
+        this.vert.firstChild.style.height =
+          Math.max(0, measure.scrollHeight - measure.clientHeight + totalHeight) + "px";
+      } else {
+        this.vert.style.display = "";
+        this.vert.firstChild.style.height = "0";
+      }
+
+      if (needsH) {
+        this.horiz.style.display = "block";
+        this.horiz.style.right = needsV ? sWidth + "px" : "0";
+        this.horiz.style.left = measure.barLeft + "px";
+        var totalWidth = measure.viewWidth - measure.barLeft - (needsV ? sWidth : 0);
+        this.horiz.firstChild.style.width =
+          (measure.scrollWidth - measure.clientWidth + totalWidth) + "px";
+      } else {
+        this.horiz.style.display = "";
+        this.horiz.firstChild.style.width = "0";
+      }
+
+      if (!this.checkedOverlay && measure.clientHeight > 0) {
+        if (sWidth == 0) this.overlayHack();
+        this.checkedOverlay = true;
+      }
+
+      return {right: needsV ? sWidth : 0, bottom: needsH ? sWidth : 0};
+    },
+    setScrollLeft: function(pos) {
+      if (this.horiz.scrollLeft != pos) this.horiz.scrollLeft = pos;
+    },
+    setScrollTop: function(pos) {
+      if (this.vert.scrollTop != pos) this.vert.scrollTop = pos;
+    },
+    overlayHack: function() {
+      var w = mac && !mac_geMountainLion ? "12px" : "18px";
+      this.horiz.style.minHeight = this.vert.style.minWidth = w;
+      var self = this;
+      var barMouseDown = function(e) {
+        if (e_target(e) != self.vert && e_target(e) != self.horiz)
+          operation(self.cm, onMouseDown)(e);
+      };
+      on(this.vert, "mousedown", barMouseDown);
+      on(this.horiz, "mousedown", barMouseDown);
+    },
+    clear: function() {
+      var parent = this.horiz.parentNode;
+      parent.removeChild(this.horiz);
+      parent.removeChild(this.vert);
+    }
+  }, NativeScrollbars.prototype);
+
+  function NullScrollbars() {}
+
+  NullScrollbars.prototype = copyObj({
+    update: function() { return {bottom: 0, right: 0}; },
+    setScrollLeft: function() {},
+    setScrollTop: function() {},
+    clear: function() {}
+  }, NullScrollbars.prototype);
+
+  CodeMirror.scrollbarModel = {"native": NativeScrollbars, "null": NullScrollbars};
+
+  function initScrollbars(cm) {
+    if (cm.display.scrollbars) {
+      cm.display.scrollbars.clear();
+      if (cm.display.scrollbars.addClass)
+        rmClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+    }
+
+    cm.display.scrollbars = new CodeMirror.scrollbarModel[cm.options.scrollbarStyle](function(node) {
+      cm.display.wrapper.insertBefore(node, cm.display.scrollbarFiller);
+      // Prevent clicks in the scrollbars from killing focus
+      on(node, "mousedown", function() {
+        if (cm.state.focused) setTimeout(function() { cm.display.input.focus(); }, 0);
+      });
+      node.setAttribute("cm-not-content", "true");
+    }, function(pos, axis) {
+      if (axis == "horizontal") setScrollLeft(cm, pos);
+      else setScrollTop(cm, pos);
+    }, cm);
+    if (cm.display.scrollbars.addClass)
+      addClass(cm.display.wrapper, cm.display.scrollbars.addClass);
+  }
+
+  function updateScrollbars(cm, measure) {
+    if (!measure) measure = measureForScrollbars(cm);
+    var startWidth = cm.display.barWidth, startHeight = cm.display.barHeight;
+    updateScrollbarsInner(cm, measure);
+    for (var i = 0; i < 4 && startWidth != cm.display.barWidth || startHeight != cm.display.barHeight; i++) {
+      if (startWidth != cm.display.barWidth && cm.options.lineWrapping)
+        updateHeightsInViewport(cm);
+      updateScrollbarsInner(cm, measureForScrollbars(cm));
+      startWidth = cm.display.barWidth; startHeight = cm.display.barHeight;
+    }
+  }
+
+  // Re-synchronize the fake scrollbars with the actual size of the
+  // content.
+  function updateScrollbarsInner(cm, measure) {
+    var d = cm.display;
+    var sizes = d.scrollbars.update(measure);
+
+    d.sizer.style.paddingRight = (d.barWidth = sizes.right) + "px";
+    d.sizer.style.paddingBottom = (d.barHeight = sizes.bottom) + "px";
+
+    if (sizes.right && sizes.bottom) {
+      d.scrollbarFiller.style.display = "block";
+      d.scrollbarFiller.style.height = sizes.bottom + "px";
+      d.scrollbarFiller.style.width = sizes.right + "px";
+    } else d.scrollbarFiller.style.display = "";
+    if (sizes.bottom && cm.options.coverGutterNextToScrollbar && cm.options.fixedGutter) {
+      d.gutterFiller.style.display = "block";
+      d.gutterFiller.style.height = sizes.bottom + "px";
+      d.gutterFiller.style.width = measure.gutterWidth + "px";
+    } else d.gutterFiller.style.display = "";
+  }
+
+  // Compute the lines that are visible in a given viewport (defaults
+  // the the current scroll position). viewport may contain top,
+  // height, and ensure (see op.scrollToPos) properties.
+  function visibleLines(display, doc, viewport) {
+    var top = viewport && viewport.top != null ? Math.max(0, viewport.top) : display.scroller.scrollTop;
+    top = Math.floor(top - paddingTop(display));
+    var bottom = viewport && viewport.bottom != null ? viewport.bottom : top + display.wrapper.clientHeight;
+
+    var from = lineAtHeight(doc, top), to = lineAtHeight(doc, bottom);
+    // Ensure is a {from: {line, ch}, to: {line, ch}} object, and
+    // forces those lines into the viewport (if possible).
+    if (viewport && viewport.ensure) {
+      var ensureFrom = viewport.ensure.from.line, ensureTo = viewport.ensure.to.line;
+      if (ensureFrom < from) {
+        from = ensureFrom;
+        to = lineAtHeight(doc, heightAtLine(getLine(doc, ensureFrom)) + display.wrapper.clientHeight);
+      } else if (Math.min(ensureTo, doc.lastLine()) >= to) {
+        from = lineAtHeight(doc, heightAtLine(getLine(doc, ensureTo)) - display.wrapper.clientHeight);
+        to = ensureTo;
+      }
+    }
+    return {from: from, to: Math.max(to, from + 1)};
+  }
+
+  // LINE NUMBERS
+
+  // Re-align line numbers and gutter marks to compensate for
+  // horizontal scrolling.
+  function alignHorizontally(cm) {
+    var display = cm.display, view = display.view;
+    if (!display.alignWidgets && (!display.gutters.firstChild || !cm.options.fixedGutter)) return;
+    var comp = compensateForHScroll(display) - display.scroller.scrollLeft + cm.doc.scrollLeft;
+    var gutterW = display.gutters.offsetWidth, left = comp + "px";
+    for (var i = 0; i < view.length; i++) if (!view[i].hidden) {
+      if (cm.options.fixedGutter && view[i].gutter)
+        view[i].gutter.style.left = left;
+      var align = view[i].alignable;
+      if (align) for (var j = 0; j < align.length; j++)
+        align[j].style.left = left;
+    }
+    if (cm.options.fixedGutter)
+      display.gutters.style.left = (comp + gutterW) + "px";
+  }
+
+  // Used to ensure that the line number gutter is still the right
+  // size for the current document size. Returns true when an update
+  // is needed.
+  function maybeUpdateLineNumberWidth(cm) {
+    if (!cm.options.lineNumbers) return false;
+    var doc = cm.doc, last = lineNumberFor(cm.options, doc.first + doc.size - 1), display = cm.display;
+    if (last.length != display.lineNumChars) {
+      var test = display.measure.appendChild(elt("div", [elt("div", last)],
+                                                 "CodeMirror-linenumber CodeMirror-gutter-elt"));
+      var innerW = test.firstChild.offsetWidth, padding = test.offsetWidth - innerW;
+      display.lineGutter.style.width = "";
+      display.lineNumInnerWidth = Math.max(innerW, display.lineGutter.offsetWidth - padding) + 1;
+      display.lineNumWidth = display.lineNumInnerWidth + padding;
+      display.lineNumChars = display.lineNumInnerWidth ? last.length : -1;
+      display.lineGutter.style.width = display.lineNumWidth + "px";
+      updateGutterSpace(cm);
+      return true;
+    }
+    return false;
+  }
+
+  function lineNumberFor(options, i) {
+    return String(options.lineNumberFormatter(i + options.firstLineNumber));
+  }
+
+  // Computes display.scroller.scrollLeft + display.gutters.offsetWidth,
+  // but using getBoundingClientRect to get a sub-pixel-accurate
+  // result.
+  function compensateForHScroll(display) {
+    return display.scroller.getBoundingClientRect().left - display.sizer.getBoundingClientRect().left;
+  }
+
+  // DISPLAY DRAWING
+
+  function DisplayUpdate(cm, viewport, force) {
+    var display = cm.display;
+
+    this.viewport = viewport;
+    // Store some values that we'll need later (but don't want to force a relayout for)
+    this.visible = visibleLines(display, cm.doc, viewport);
+    this.editorIsHidden = !display.wrapper.offsetWidth;
+    this.wrapperHeight = display.wrapper.clientHeight;
+    this.wrapperWidth = display.wrapper.clientWidth;
+    this.oldDisplayWidth = displayWidth(cm);
+    this.force = force;
+    this.dims = getDimensions(cm);
+    this.events = [];
+  }
+
+  DisplayUpdate.prototype.signal = function(emitter, type) {
+    if (hasHandler(emitter, type))
+      this.events.push(arguments);
+  };
+  DisplayUpdate.prototype.finish = function() {
+    for (var i = 0; i < this.events.length; i++)
+      signal.apply(null, this.events[i]);
+  };
+
+  function maybeClipScrollbars(cm) {
+    var display = cm.display;
+    if (!display.scrollbarsClipped && display.scroller.offsetWidth) {
+      display.nativeBarWidth = display.scroller.offsetWidth - display.scroller.clientWidth;
+      display.heightForcer.style.height = scrollGap(cm) + "px";
+      display.sizer.style.marginBottom = -display.nativeBarWidth + "px";
+      display.sizer.style.borderRightWidth = scrollGap(cm) + "px";
+      display.scrollbarsClipped = true;
+    }
+  }
+
+  // Does the actual updating of the line display. Bails out
+  // (returning false) when there is nothing to be done and forced is
+  // false.
+  function updateDisplayIfNeeded(cm, update) {
+    var display = cm.display, doc = cm.doc;
+
+    if (update.editorIsHidden) {
+      resetView(cm);
+      return false;
+    }
+
+    // Bail out if the visible area is already rendered and nothing changed.
+    if (!update.force &&
+        update.visible.from >= display.viewFrom && update.visible.to <= display.viewTo &&
+        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo) &&
+        display.renderedView == display.view && countDirtyView(cm) == 0)
+      return false;
+
+    if (maybeUpdateLineNumberWidth(cm)) {
+      resetView(cm);
+      update.dims = getDimensions(cm);
+    }
+
+    // Compute a suitable new viewport (from & to)
+    var end = doc.first + doc.size;
+    var from = Math.max(update.visible.from - cm.options.viewportMargin, doc.first);
+    var to = Math.min(end, update.visible.to + cm.options.viewportMargin);
+    if (display.viewFrom < from && from - display.viewFrom < 20) from = Math.max(doc.first, display.viewFrom);
+    if (display.viewTo > to && display.viewTo - to < 20) to = Math.min(end, display.viewTo);
+    if (sawCollapsedSpans) {
+      from = visualLineNo(cm.doc, from);
+      to = visualLineEndNo(cm.doc, to);
+    }
+
+    var different = from != display.viewFrom || to != display.viewTo ||
+      display.lastWrapHeight != update.wrapperHeight || display.lastWrapWidth != update.wrapperWidth;
+    adjustView(cm, from, to);
+
+    display.viewOffset = heightAtLine(getLine(cm.doc, display.viewFrom));
+    // Position the mover div to align with the current scroll position
+    cm.display.mover.style.top = display.viewOffset + "px";
+
+    var toUpdate = countDirtyView(cm);
+    if (!different && toUpdate == 0 && !update.force && display.renderedView == display.view &&
+        (display.updateLineNumbers == null || display.updateLineNumbers >= display.viewTo))
+      return false;
+
+    // For big changes, we hide the enclosing element during the
+    // update, since that speeds up the operations on most browsers.
+    var focused = activeElt();
+    if (toUpdate > 4) display.lineDiv.style.display = "none";
+    patchDisplay(cm, display.updateLineNumbers, update.dims);
+    if (toUpdate > 4) display.lineDiv.style.display = "";
+    display.renderedView = display.view;
+    // There might have been a widget with a focused element that got
+    // hidden or updated, if so re-focus it.
+    if (focused && activeElt() != focused && focused.offsetHeight) focused.focus();
+
+    // Prevent selection and cursors from interfering with the scroll
+    // width and height.
+    removeChildren(display.cursorDiv);
+    removeChildren(display.selectionDiv);
+    display.gutters.style.height = 0;
+
+    if (different) {
+      display.lastWrapHeight = update.wrapperHeight;
+      display.lastWrapWidth = update.wrapperWidth;
+      startWorker(cm, 400);
+    }
+
+    display.updateLineNumbers = null;
+
+    return true;
+  }
+
+  function postUpdateDisplay(cm, update) {
+    var force = update.force, viewport = update.viewport;
+    for (var first = true;; first = false) {
+      if (first && cm.options.lineWrapping && update.oldDisplayWidth != displayWidth(cm)) {
+        force = true;
+      } else {
+        force = false;
+        // Clip forced viewport to actual scrollable area.
+        if (viewport && viewport.top != null)
+          viewport = {top: Math.min(cm.doc.height + paddingVert(cm.display) - displayHeight(cm), viewport.top)};
+        // Updated line heights might result in the drawn area not
+        // actually covering the viewport. Keep looping until it does.
+        update.visible = visibleLines(cm.display, cm.doc, viewport);
+        if (update.visible.from >= cm.display.viewFrom && update.visible.to <= cm.display.viewTo)
+          break;
+      }
+      if (!updateDisplayIfNeeded(cm, update)) break;
+      updateHeightsInViewport(cm);
+      var barMeasure = measureForScrollbars(cm);
+      updateSelection(cm);
+      setDocumentHeight(cm, barMeasure);
+      updateScrollbars(cm, barMeasure);
+    }
+
+    update.signal(cm, "update", cm);
+    if (cm.display.viewFrom != cm.display.reportedViewFrom || cm.display.viewTo != cm.display.reportedViewTo) {
+      update.signal(cm, "viewportChange", cm, cm.display.viewFrom, cm.display.viewTo);
+      cm.display.reportedViewFrom = cm.display.viewFrom; cm.display.reportedViewTo = cm.display.viewTo;
+    }
+  }
+
+  function updateDisplaySimple(cm, viewport) {
+    var update = new DisplayUpdate(cm, viewport);
+    if (updateDisplayIfNeeded(cm, update)) {
+      updateHeightsInViewport(cm);
+      postUpdateDisplay(cm, update);
+      var barMeasure = measureForScrollbars(cm);
+      updateSelection(cm);
+      setDocumentHeight(cm, barMeasure);
+      updateScrollbars(cm, barMeasure);
+      update.finish();
+    }
+  }
+
+  function setDocumentHeight(cm, measure) {
+    cm.display.sizer.style.minHeight = measure.docHeight + "px";
+    var total = measure.docHeight + cm.display.barHeight;
+    cm.display.heightForcer.style.top = total + "px";
+    cm.display.gutters.style.height = Math.max(total + scrollGap(cm), measure.clientHeight) + "px";
+  }
+
+  // Read the actual heights of the rendered lines, and update their
+  // stored heights to match.
+  function updateHeightsInViewport(cm) {
+    var display = cm.display;
+    var prevBottom = display.lineDiv.offsetTop;
+    for (var i = 0; i < display.view.length; i++) {
+      var cur = display.view[i], height;
+      if (cur.hidden) continue;
+      if (ie && ie_version < 8) {
+        var bot = cur.node.offsetTop + cur.node.offsetHeight;
+        height = bot - prevBottom;
+        prevBottom = bot;
+      } else {
+        var box = cur.node.getBoundingClientRect();
+        height = box.bottom - box.top;
+      }
+      var diff = cur.line.height - height;
+      if (height < 2) height = textHeight(display);
+      if (diff > .001 || diff < -.001) {
+        updateLineHeight(cur.line, height);
+        updateWidgetHeight(cur.line);
+        if (cur.rest) for (var j = 0; j < cur.rest.length; j++)
+          updateWidgetHeight(cur.rest[j]);
+      }
+    }
+  }
+
+  // Read and store the height of line widgets associated with the
+  // given line.
+  function updateWidgetHeight(line) {
+    if (line.widgets) for (var i = 0; i < line.widgets.length; ++i)
+      line.widgets[i].height = line.widgets[i].node.offsetHeight;
+  }
+
+  // Do a bulk-read of the DOM positions and sizes needed to draw the
+  // view, so that we don't interleave reading and writing to the DOM.
+  function getDimensions(cm) {
+    var d = cm.display, left = {}, width = {};
+    var gutterLeft = d.gutters.clientLeft;
+    for (var n = d.gutters.firstChild, i = 0; n; n = n.nextSibling, ++i) {
+      left[cm.options.gutters[i]] = n.offsetLeft + n.clientLeft + gutterLeft;
+      width[cm.options.gutters[i]] = n.clientWidth;
+    }
+    return {fixedPos: compensateForHScroll(d),
+            gutterTotalWidth: d.gutters.offsetWidth,
+            gutterLeft: left,
+            gutterWidth: width,
+            wrapperWidth: d.wrapper.clientWidth};
+  }
+
+  // Sync the actual display DOM structure with display.view, removing
+  // nodes for lines that are no longer in view, and creating the ones
+  // that are not there yet, and updating the ones that are out of
+  // date.
+  function patchDisplay(cm, updateNumbersFrom, dims) {
+    var display = cm.display, lineNumbers = cm.options.lineNumbers;
+    var container = display.lineDiv, cur = container.firstChild;
+
+    function rm(node) {
+      var next = node.nextSibling;
+      // Works around a throw-scroll bug in OS X Webkit
+      if (webkit && mac && cm.display.currentWheelTarget == node)
+        node.style.display = "none";
+      else
+        node.parentNode.removeChild(node);
+      return next;
+    }
+
+    var view = display.view, lineN = display.viewFrom;
+    // Loop over the elements in the view, syncing cur (the DOM nodes
+    // in display.lineDiv) with the view as we go.
+    for (var i = 0; i < view.length; i++) {
+      var lineView = view[i];
+      if (lineView.hidden) {
+      } else if (!lineView.node || lineView.node.parentNode != container) { // Not drawn yet
+        var node = buildLineElement(cm, lineView, lineN, dims);
+        container.insertBefore(node, cur);
+      } else { // Already drawn
+        while (cur != lineView.node) cur = rm(cur);
+        var updateNumber = lineNumbers && updateNumbersFrom != null &&
+          updateNumbersFrom <= lineN && lineView.lineNumber;
+        if (lineView.changes) {
+          if (indexOf(lineView.changes, "gutter") > -1) updateNumber = false;
+          updateLineForChanges(cm, lineView, lineN, dims);
+        }
+        if (updateNumber) {
+          removeChildren(lineView.lineNumber);
+          lineView.lineNumber.appendChild(document.createTextNode(lineNumberFor(cm.options, lineN)));
+        }
+        cur = lineView.node.nextSibling;
+      }
+      lineN += lineView.size;
+    }
+    while (cur) cur = rm(cur);
+  }
+
+  // When an aspect of a line changes, a string is added to
+  // lineView.changes. This updates the relevant part of the line's
+  // DOM structure.
+  function updateLineForChanges(cm, lineView, lineN, dims) {
+    for (var j = 0; j < lineView.changes.length; j++) {
+      var type = lineView.changes[j];
+      if (type == "text") updateLineText(cm, lineView);
+      else if (type == "gutter") updateLineGutter(cm, lineView, lineN, dims);
+      else if (type == "class") updateLineClasses(lineView);
+      else if (type == "widget") updateLineWidgets(cm, lineView, dims);
+    }
+    lineView.changes = null;
+  }
+
+  // Lines with gutter elements, widgets or a background class need to
+  // be wrapped, and have the extra elements added to the wrapper div
+  function ensureLineWrapped(lineView) {
+    if (lineView.node == lineView.text) {
+      lineView.node = elt("div", null, null, "position: relative");
+      if (lineView.text.parentNode)
+        lineView.text.parentNode.replaceChild(lineView.node, lineView.text);
+      lineView.node.appendChild(lineView.text);
+      if (ie && ie_version < 8) lineView.node.style.zIndex = 2;
+    }
+    return lineView.node;
+  }
+
+  function updateLineBackground(lineView) {
+    var cls = lineView.bgClass ? lineView.bgClass + " " + (lineView.line.bgClass || "") : lineView.line.bgClass;
+    if (cls) cls += " CodeMirror-linebackground";
+    if (lineView.background) {
+      if (cls) lineView.background.className = cls;
+      else { lineView.background.parentNode.removeChild(lineView.background); lineView.background = null; }
+    } else if (cls) {
+      var wrap = ensureLineWrapped(lineView);
+      lineView.background = wrap.insertBefore(elt("div", null, cls), wrap.firstChild);
+    }
+  }
+
+  // Wrapper around buildLineContent which will reuse the structure
+  // in display.externalMeasured when possible.
+  function getLineContent(cm, lineView) {
+    var ext = cm.display.externalMeasured;
+    if (ext && ext.line == lineView.line) {
+      cm.display.externalMeasured = null;
+      lineView.measure = ext.measure;
+      return ext.built;
+    }
+    return buildLineContent(cm, lineView);
+  }
+
+  // Redraw the line's text. Interacts with the background and text
+  // classes because the mode may output tokens that influence these
+  // classes.
+  function updateLineText(cm, lineView) {
+    var cls = lineView.text.className;
+    var built = getLineContent(cm, lineView);
+    if (lineView.text == lineView.node) lineView.node = built.pre;
+    lineView.text.parentNode.replaceChild(built.pre, lineView.text);
+    lineView.text = built.pre;
+    if (built.bgClass != lineView.bgClass || built.textClass != lineView.textClass) {
+      lineView.bgClass = built.bgClass;
+      lineView.textClass = built.textClass;
+      updateLineClasses(lineView);
+    } else if (cls) {
+      lineView.text.className = cls;
+    }
+  }
+
+  function updateLineClasses(lineView) {
+    updateLineBackground(lineView);
+    if (lineView.line.wrapClass)
+      ensureLineWrapped(lineView).className = lineView.line.wrapClass;
+    else if (lineView.node != lineView.text)
+      lineView.node.className = "";
+    var textClass = lineView.textClass ? lineView.textClass + " " + (lineView.line.textClass || "") : lineView.line.textClass;
+    lineView.text.className = textClass || "";
+  }
+
+  function updateLineGutter(cm, lineView, lineN, dims) {
+    if (lineView.gutter) {
+      lineView.node.removeChild(lineView.gutter);
+      lineView.gutter = null;
+    }
+    var markers = lineView.line.gutterMarkers;
+    if (cm.options.lineNumbers || markers) {
+      var wrap = ensureLineWrapped(lineView);
+      var gutterWrap = lineView.gutter = elt("div", null, "CodeMirror-gutter-wrapper", "left: " +
+                                             (cm.options.fixedGutter ? dims.fixedPos : -dims.gutterTotalWidth) +
+                                             "px; width: " + dims.gutterTotalWidth + "px");
+      cm.display.input.setUneditable(gutterWrap);
+      wrap.insertBefore(gutterWrap, lineView.text);
+      if (lineView.line.gutterClass)
+        gutterWrap.className += " " + lineView.line.gutterClass;
+      if (cm.options.lineNumbers && (!markers || !markers["CodeMirror-linenumbers"]))
+        lineView.lineNumber = gutterWrap.appendChild(
+          elt("div", lineNumberFor(cm.options, lineN),
+              "CodeMirror-linenumber CodeMirror-gutter-elt",
+              "left: " + dims.gutterLeft["CodeMirror-linenumbers"] + "px; width: "
+              + cm.display.lineNumInnerWidth + "px"));
+      if (markers) for (var k = 0; k < cm.options.gutters.length; ++k) {
+        var id = cm.options.gutters[k], found = markers.hasOwnProperty(id) && markers[id];
+        if (found)
+          gutterWrap.appendChild(elt("div", [found], "CodeMirror-gutter-elt", "left: " +
+                                     dims.gutterLeft[id] + "px; width: " + dims.gutterWidth[id] + "px"));
+      }
+    }
+  }
+
+  function updateLineWidgets(cm, lineView, dims) {
+    if (lineView.alignable) lineView.alignable = null;
+    for (var node = lineView.node.firstChild, next; node; node = next) {
+      var next = node.nextSibling;
+      if (node.className == "CodeMirror-linewidget")
+        lineView.node.removeChild(node);
+    }
+    insertLineWidgets(cm, lineView, dims);
+  }
+
+  // Build a line's DOM representation from scratch
+  function buildLineElement(cm, lineView, lineN, dims) {
+    var built = getLineContent(cm, lineView);
+    lineView.text = lineView.node = built.pre;
+    if (built.bgClass) lineView.bgClass = built.bgClass;
+    if (built.textClass) lineView.textClass = built.textClass;
+
+    updateLineClasses(lineView);
+    updateLineGutter(cm, lineView, lineN, dims);
+    insertLineWidgets(cm, lineView, dims);
+    return lineView.node;
+  }
+
+  // A lineView may contain multiple logical lines (when merged by
+  // collapsed spans). The widgets for all of them need to be drawn.
+  function insertLineWidgets(cm, lineView, dims) {
+    insertLineWidgetsFor(cm, lineView.line, lineView, dims, true);
+    if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+      insertLineWidgetsFor(cm, lineView.rest[i], lineView, dims, false);
+  }
+
+  function insertLineWidgetsFor(cm, line, lineView, dims, allowAbove) {
+    if (!line.widgets) return;
+    var wrap = ensureLineWrapped(lineView);
+    for (var i = 0, ws = line.widgets; i < ws.length; ++i) {
+      var widget = ws[i], node = elt("div", [widget.node], "CodeMirror-linewidget");
+      if (!widget.handleMouseEvents) node.setAttribute("cm-ignore-events", "true");
+      positionLineWidget(widget, node, lineView, dims);
+      cm.display.input.setUneditable(node);
+      if (allowAbove && widget.above)
+        wrap.insertBefore(node, lineView.gutter || lineView.text);
+      else
+        wrap.appendChild(node);
+      signalLater(widget, "redraw");
+    }
+  }
+
+  function positionLineWidget(widget, node, lineView, dims) {
+    if (widget.noHScroll) {
+      (lineView.alignable || (lineView.alignable = [])).push(node);
+      var width = dims.wrapperWidth;
+      node.style.left = dims.fixedPos + "px";
+      if (!widget.coverGutter) {
+        width -= dims.gutterTotalWidth;
+        node.style.paddingLeft = dims.gutterTotalWidth + "px";
+      }
+      node.style.width = width + "px";
+    }
+    if (widget.coverGutter) {
+      node.style.zIndex = 5;
+      node.style.position = "relative";
+      if (!widget.noHScroll) node.style.marginLeft = -dims.gutterTotalWidth + "px";
+    }
+  }
+
+  // POSITION OBJECT
+
+  // A Pos instance represents a position within the text.
+  var Pos = CodeMirror.Pos = function(line, ch) {
+    if (!(this instanceof Pos)) return new Pos(line, ch);
+    this.line = line; this.ch = ch;
+  };
+
+  // Compare two positions, return 0 if they are the same, a negative
+  // number when a is less, and a positive number otherwise.
+  var cmp = CodeMirror.cmpPos = function(a, b) { return a.line - b.line || a.ch - b.ch; };
+
+  function copyPos(x) {return Pos(x.line, x.ch);}
+  function maxPos(a, b) { return cmp(a, b) < 0 ? b : a; }
+  function minPos(a, b) { return cmp(a, b) < 0 ? a : b; }
+
+  // INPUT HANDLING
+
+  function ensureFocus(cm) {
+    if (!cm.state.focused) { cm.display.input.focus(); onFocus(cm); }
+  }
+
+  function isReadOnly(cm) {
+    return cm.options.readOnly || cm.doc.cantEdit;
+  }
+
+  // This will be set to an array of strings when copying, so that,
+  // when pasting, we know what kind of selections the copied text
+  // was made out of.
+  var lastCopied = null;
+
+  function applyTextInput(cm, inserted, deleted, sel, origin) {
+    var doc = cm.doc;
+    cm.display.shift = false;
+    if (!sel) sel = doc.sel;
+
+    var textLines = splitLines(inserted), multiPaste = null;
+    // When pasing N lines into N selections, insert one line per selection
+    if (cm.state.pasteIncoming && sel.ranges.length > 1) {
+      if (lastCopied && lastCopied.join("\n") == inserted)
+        multiPaste = sel.ranges.length % lastCopied.length == 0 && map(lastCopied, splitLines);
+      else if (textLines.length == sel.ranges.length)
+        multiPaste = map(textLines, function(l) { return [l]; });
+    }
+
+    // Normal behavior is to insert the new text into every selection
+    for (var i = sel.ranges.length - 1; i >= 0; i--) {
+      var range = sel.ranges[i];
+      var from = range.from(), to = range.to();
+      if (range.empty()) {
+        if (deleted && deleted > 0) // Handle deletion
+          from = Pos(from.line, from.ch - deleted);
+        else if (cm.state.overwrite && !cm.state.pasteIncoming) // Handle overwrite
+          to = Pos(to.line, Math.min(getLine(doc, to.line).text.length, to.ch + lst(textLines).length));
+      }
+      var updateInput = cm.curOp.updateInput;
+      var changeEvent = {from: from, to: to, text: multiPaste ? multiPaste[i % multiPaste.length] : textLines,
+                         origin: origin || (cm.state.pasteIncoming ? "paste" : cm.state.cutIncoming ? "cut" : "+input")};
+      makeChange(cm.doc, changeEvent);
+      signalLater(cm, "inputRead", cm, changeEvent);
+      // When an 'electric' character is inserted, immediately trigger a reindent
+      if (inserted && !cm.state.pasteIncoming && cm.options.electricChars &&
+          cm.options.smartIndent && range.head.ch < 100 &&
+          (!i || sel.ranges[i - 1].head.line != range.head.line)) {
+        var mode = cm.getModeAt(range.head);
+        var end = changeEnd(changeEvent);
+        var indented = false;
+        if (mode.electricChars) {
+          for (var j = 0; j < mode.electricChars.length; j++)
+            if (inserted.indexOf(mode.electricChars.charAt(j)) > -1) {
+              indented = indentLine(cm, end.line, "smart");
+              break;
+            }
+        } else if (mode.electricInput) {
+          if (mode.electricInput.test(getLine(doc, end.line).text.slice(0, end.ch)))
+            indented = indentLine(cm, end.line, "smart");
+        }
+        if (indented) signalLater(cm, "electricInput", cm, end.line);
+      }
+    }
+    ensureCursorVisible(cm);
+    cm.curOp.updateInput = updateInput;
+    cm.curOp.typing = true;
+    cm.state.pasteIncoming = cm.state.cutIncoming = false;
+  }
+
+  function copyableRanges(cm) {
+    var text = [], ranges = [];
+    for (var i = 0; i < cm.doc.sel.ranges.length; i++) {
+      var line = cm.doc.sel.ranges[i].head.line;
+      var lineRange = {anchor: Pos(line, 0), head: Pos(line + 1, 0)};
+      ranges.push(lineRange);
+      text.push(cm.getRange(lineRange.anchor, lineRange.head));
+    }
+    return {text: text, ranges: ranges};
+  }
+
+  function disableBrowserMagic(field) {
+    field.setAttribute("autocorrect", "off");
+    field.setAttribute("autocapitalize", "off");
+    field.setAttribute("spellcheck", "false");
+  }
+
+  // TEXTAREA INPUT STYLE
+
+  function TextareaInput(cm) {
+    this.cm = cm;
+    // See input.poll and input.reset
+    this.prevInput = "";
+
+    // Flag that indicates whether we expect input to appear real soon
+    // now (after some event like 'keypress' or 'input') and are
+    // polling intensively.
+    this.pollingFast = false;
+    // Self-resetting timeout for the poller
+    this.polling = new Delayed();
+    // Tracks when input.reset has punted to just putting a short
+    // string into the textarea instead of the full selection.
+    this.inaccurateSelection = false;
+    // Used to work around IE issue with selection being forgotten when focus moves away from textarea
+    this.hasSelection = false;
+    this.composing = null;
+  };
+
+  function hiddenTextarea() {
+    var te = elt("textarea", null, null, "position: absolute; padding: 0; width: 1px; height: 1em; outline: none");
+    var div = elt("div", [te], null, "overflow: hidden; position: relative; width: 3px; height: 0px;");
+    // The textarea is kept positioned near the cursor to prevent the
+    // fact that it'll be scrolled into view on input from scrolling
+    // our fake cursor out of view. On webkit, when wrap=off, paste is
+    // very slow. So make the area wide instead.
+    if (webkit) te.style.width = "1000px";
+    else te.setAttribute("wrap", "off");
+    // If border: 0; -- iOS fails to open keyboard (issue #1287)
+    if (ios) te.style.border = "1px solid black";
+    disableBrowserMagic(te);
+    return div;
+  }
+
+  TextareaInput.prototype = copyObj({
+    init: function(display) {
+      var input = this, cm = this.cm;
+
+      // Wraps and hides input textarea
+      var div = this.wrapper = hiddenTextarea();
+      // The semihidden textarea that is focused when the editor is
+      // focused, and receives input.
+      var te = this.textarea = div.firstChild;
+      display.wrapper.insertBefore(div, display.wrapper.firstChild);
+
+      // Needed to hide big blue blinking cursor on Mobile Safari (doesn't seem to work in iOS 8 anymore)
+      if (ios) te.style.width = "0px";
+
+      on(te, "input", function() {
+        if (ie && ie_version >= 9 && input.hasSelection) input.hasSelection = null;
+        input.poll();
+      });
+
+      on(te, "paste", function() {
+        // Workaround for webkit bug https://bugs.webkit.org/show_bug.cgi?id=90206
+        // Add a char to the end of textarea before paste occur so that
+        // selection doesn't span to the end of textarea.
+        if (webkit && !cm.state.fakedLastChar && !(new Date - cm.state.lastMiddleDown < 200)) {
+          var start = te.selectionStart, end = te.selectionEnd;
+          te.value += "$";
+          // The selection end needs to be set before the start, otherwise there
+          // can be an intermediate non-empty selection between the two, which
+          // can override the middle-click paste buffer on linux and cause the
+          // wrong thing to get pasted.
+          te.selectionEnd = end;
+          te.selectionStart = start;
+          cm.state.fakedLastChar = true;
+        }
+        cm.state.pasteIncoming = true;
+        input.fastPoll();
+      });
+
+      function prepareCopyCut(e) {
+        if (cm.somethingSelected()) {
+          lastCopied = cm.getSelections();
+          if (input.inaccurateSelection) {
+            input.prevInput = "";
+            input.inaccurateSelection = false;
+            te.value = lastCopied.join("\n");
+            selectInput(te);
+          }
+        } else if (!cm.options.lineWiseCopyCut) {
+          return;
+        } else {
+          var ranges = copyableRanges(cm);
+          lastCopied = ranges.text;
+          if (e.type == "cut") {
+            cm.setSelections(ranges.ranges, null, sel_dontScroll);
+          } else {
+            input.prevInput = "";
+            te.value = ranges.text.join("\n");
+            selectInput(te);
+          }
+        }
+        if (e.type == "cut") cm.state.cutIncoming = true;
+      }
+      on(te, "cut", prepareCopyCut);
+      on(te, "copy", prepareCopyCut);
+
+      on(display.scroller, "paste", function(e) {
+        if (eventInWidget(display, e)) return;
+        cm.state.pasteIncoming = true;
+        input.focus();
+      });
+
+      // Prevent normal selection in the editor (we handle our own)
+      on(display.lineSpace, "selectstart", function(e) {
+        if (!eventInWidget(display, e)) e_preventDefault(e);
+      });
+
+      on(te, "compositionstart", function() {
+        var start = cm.getCursor("from");
+        input.composing = {
+          start: start,
+          range: cm.markText(start, cm.getCursor("to"), {className: "CodeMirror-composing"})
+        };
+      });
+      on(te, "compositionend", function() {
+        if (input.composing) {
+          input.poll();
+          input.composing.range.clear();
+          input.composing = null;
+        }
+      });
+    },
+
+    prepareSelection: function() {
+      // Redraw the selection and/or cursor
+      var cm = this.cm, display = cm.display, doc = cm.doc;
+      var result = prepareSelection(cm);
+
+      // Move the hidden textarea near the cursor to prevent scrolling artifacts
+      if (cm.options.moveInputWithCursor) {
+        var headPos = cursorCoords(cm, doc.sel.primary().head, "div");
+        var wrapOff = display.wrapper.getBoundingClientRect(), lineOff = display.lineDiv.getBoundingClientRect();
+        result.teTop = Math.max(0, Math.min(display.wrapper.clientHeight - 10,
+                                            headPos.top + lineOff.top - wrapOff.top));
+        result.teLeft = Math.max(0, Math.min(display.wrapper.clientWidth - 10,
+                                             headPos.left + lineOff.left - wrapOff.left));
+      }
+
+      return result;
+    },
+
+    showSelection: function(drawn) {
+      var cm = this.cm, display = cm.display;
+      removeChildrenAndAdd(display.cursorDiv, drawn.cursors);
+      removeChildrenAndAdd(display.selectionDiv, drawn.selection);
+      if (drawn.teTop != null) {
+        this.wrapper.style.top = drawn.teTop + "px";
+        this.wrapper.style.left = drawn.teLeft + "px";
+      }
+    },
+
+    // Reset the input to correspond to the selection (or to be empty,
+    // when not typing and nothing is selected)
+    reset: function(typing) {
+      if (this.contextMenuPending) return;
+      var minimal, selected, cm = this.cm, doc = cm.doc;
+      if (cm.somethingSelected()) {
+        this.prevInput = "";
+        var range = doc.sel.primary();
+        minimal = hasCopyEvent &&
+          (range.to().line - range.from().line > 100 || (selected = cm.getSelection()).length > 1000);
+        var content = minimal ? "-" : selected || cm.getSelection();
+        this.textarea.value = content;
+        if (cm.state.focused) selectInput(this.textarea);
+        if (ie && ie_version >= 9) this.hasSelection = content;
+      } else if (!typing) {
+        this.prevInput = this.textarea.value = "";
+        if (ie && ie_version >= 9) this.hasSelection = null;
+      }
+      this.inaccurateSelection = minimal;
+    },
+
+    getField: function() { return this.textarea; },
+
+    supportsTouch: function() { return false; },
+
+    focus: function() {
+      if (this.cm.options.readOnly != "nocursor" && (!mobile || activeElt() != this.textarea)) {
+        try { this.textarea.focus(); }
+        catch (e) {} // IE8 will throw if the textarea is display: none or not in DOM
+      }
+    },
+
+    blur: function() { this.textarea.blur(); },
+
+    resetPosition: function() {
+      this.wrapper.style.top = this.wrapper.style.left = 0;
+    },
+
+    receivedFocus: function() { this.slowPoll(); },
+
+    // Poll for input changes, using the normal rate of polling. This
+    // runs as long as the editor is focused.
+    slowPoll: function() {
+      var input = this;
+      if (input.pollingFast) return;
+      input.polling.set(this.cm.options.pollInterval, function() {
+        input.poll();
+        if (input.cm.state.focused) input.slowPoll();
+      });
+    },
+
+    // When an event has just come in that is likely to add or change
+    // something in the input textarea, we poll faster, to ensure that
+    // the change appears on the screen quickly.
+    fastPoll: function() {
+      var missed = false, input = this;
+      input.pollingFast = true;
+      function p() {
+        var changed = input.poll();
+        if (!changed && !missed) {missed = true; input.polling.set(60, p);}
+        else {input.pollingFast = false; input.slowPoll();}
+      }
+      input.polling.set(20, p);
+    },
+
+    // Read input from the textarea, and update the document to match.
+    // When something is selected, it is present in the textarea, and
+    // selected (unless it is huge, in which case a placeholder is
+    // used). When nothing is selected, the cursor sits after previously
+    // seen text (can be empty), which is stored in prevInput (we must
+    // not reset the textarea when typing, because that breaks IME).
+    poll: function() {
+      var cm = this.cm, input = this.textarea, prevInput = this.prevInput;
+      // Since this is called a *lot*, try to bail out as cheaply as
+      // possible when it is clear that nothing happened. hasSelection
+      // will be the case when there is a lot of text in the textarea,
+      // in which case reading its value would be expensive.
+      if (!cm.state.focused || (hasSelection(input) && !prevInput) ||
+          isReadOnly(cm) || cm.options.disableInput || cm.state.keySeq)
+        return false;
+      // See paste handler for more on the fakedLastChar kludge
+      if (cm.state.pasteIncoming && cm.state.fakedLastChar) {
+        input.value = input.value.substring(0, input.value.length - 1);
+        cm.state.fakedLastChar = false;
+      }
+      var text = input.value;
+      // If nothing changed, bail.
+      if (text == prevInput && !cm.somethingSelected()) return false;
+      // Work around nonsensical selection resetting in IE9/10, and
+      // inexplicable appearance of private area unicode characters on
+      // some key combos in Mac (#2689).
+      if (ie && ie_version >= 9 && this.hasSelection === text ||
+          mac && /[\uf700-\uf7ff]/.test(text)) {
+        cm.display.input.reset();
+        return false;
+      }
+
+      if (cm.doc.sel == cm.display.selForContextMenu) {
+        var first = text.charCodeAt(0);
+        if (first == 0x200b && !prevInput) prevInput = "\u200b";
+        if (first == 0x21da) { this.reset(); return this.cm.execCommand("undo"); }
+      }
+      // Find the part of the input that is actually new
+      var same = 0, l = Math.min(prevInput.length, text.length);
+      while (same < l && prevInput.charCodeAt(same) == text.charCodeAt(same)) ++same;
+
+      var self = this;
+      runInOp(cm, function() {
+        applyTextInput(cm, text.slice(same), prevInput.length - same,
+                       null, self.composing ? "*compose" : null);
+
+        // Don't leave long text in the textarea, since it makes further polling slow
+        if (text.length > 1000 || text.indexOf("\n") > -1) input.value = self.prevInput = "";
+        else self.prevInput = text;
+
+        if (self.composing) {
+          self.composing.range.clear();
+          self.composing.range = cm.markText(self.composing.start, cm.getCursor("to"),
+                                             {className: "CodeMirror-composing"});
+        }
+      });
+      return true;
+    },
+
+    ensurePolled: function() {
+      if (this.pollingFast && this.poll()) this.pollingFast = false;
+    },
+
+    onKeyPress: function() {
+      if (ie && ie_version >= 9) this.hasSelection = null;
+      this.fastPoll();
+    },
+
+    onContextMenu: function(e) {
+      var input = this, cm = input.cm, display = cm.display, te = input.textarea;
+      var pos = posFromMouse(cm, e), scrollPos = display.scroller.scrollTop;
+      if (!pos || presto) return; // Opera is difficult.
+
+      // Reset the current text selection only if the click is done outside of the selection
+      // and 'resetSelectionOnContextMenu' option is true.
+      var reset = cm.options.resetSelectionOnContextMenu;
+      if (reset && cm.doc.sel.contains(pos) == -1)
+        operation(cm, setSelection)(cm.doc, simpleSelection(pos), sel_dontScroll);
+
+      var oldCSS = te.style.cssText;
+      input.wrapper.style.position = "absolute";
+      te.style.cssText = "position: fixed; width: 30px; height: 30px; top: " + (e.clientY - 5) +
+        "px; left: " + (e.clientX - 5) + "px; z-index: 1000; background: " +
+        (ie ? "rgba(255, 255, 255, .05)" : "transparent") +
+        "; outline: none; border-width: 0; outline: none; overflow: hidden; opacity: .05; filter: alpha(opacity=5);";
+      if (webkit) var oldScrollY = window.scrollY; // Work around Chrome issue (#2712)
+      display.input.focus();
+      if (webkit) window.scrollTo(null, oldScrollY);
+      display.input.reset();
+      // Adds "Select all" to context menu in FF
+      if (!cm.somethingSelected()) te.value = input.prevInput = " ";
+      input.contextMenuPending = true;
+      display.selForContextMenu = cm.doc.sel;
+      clearTimeout(display.detectingSelectAll);
+
+      // Select-all will be greyed out if there's nothing to select, so
+      // this adds a zero-width space so that we can later check whether
+      // it got selected.
+      function prepareSelectAllHack() {
+        if (te.selectionStart != null) {
+          var selected = cm.somethingSelected();
+          var extval = "\u200b" + (selected ? te.value : "");
+          te.value = "\u21da"; // Used to catch context-menu undo
+          te.value = extval;
+          input.prevInput = selected ? "" : "\u200b";
+          te.selectionStart = 1; te.selectionEnd = extval.length;
+          // Re-set this, in case some other handler touched the
+          // selection in the meantime.
+          display.selForContextMenu = cm.doc.sel;
+        }
+      }
+      function rehide() {
+        input.contextMenuPending = false;
+        input.wrapper.style.position = "relative";
+        te.style.cssText = oldCSS;
+        if (ie && ie_version < 9) display.scrollbars.setScrollTop(display.scroller.scrollTop = scrollPos);
+
+        // Try to detect the user choosing select-all
+        if (te.selectionStart != null) {
+          if (!ie || (ie && ie_version < 9)) prepareSelectAllHack();
+          var i = 0, poll = function() {
+            if (display.selForContextMenu == cm.doc.sel && te.selectionStart == 0 &&
+                te.selectionEnd > 0 && input.prevInput == "\u200b")
+              operation(cm, commands.selectAll)(cm);
+            else if (i++ < 10) display.detectingSelectAll = setTimeout(poll, 500);
+            else display.input.reset();
+          };
+          display.detectingSelectAll = setTimeout(poll, 200);
+        }
+      }
+
+      if (ie && ie_version >= 9) prepareSelectAllHack();
+      if (captureRightClick) {
+        e_stop(e);
+        var mouseup = function() {
+          off(window, "mouseup", mouseup);
+          setTimeout(rehide, 20);
+        };
+        on(window, "mouseup", mouseup);
+      } else {
+        setTimeout(rehide, 50);
+      }
+    },
+
+    setUneditable: nothing,
+
+    needsContentAttribute: false
+  }, TextareaInput.prototype);
+
+  // CONTENTEDITABLE INPUT STYLE
+
+  function ContentEditableInput(cm) {
+    this.cm = cm;
+    this.lastAnchorNode = this.lastAnchorOffset = this.lastFocusNode = this.lastFocusOffset = null;
+    this.polling = new Delayed();
+    this.gracePeriod = false;
+  }
+
+  ContentEditableInput.prototype = copyObj({
+    init: function(display) {
+      var input = this, cm = input.cm;
+      var div = input.div = display.lineDiv;
+      div.contentEditable = "true";
+      disableBrowserMagic(div);
+
+      on(div, "paste", function(e) {
+        var pasted = e.clipboardData && e.clipboardData.getData("text/plain");
+        if (pasted) {
+          e.preventDefault();
+          cm.replaceSelection(pasted, null, "paste");
+        }
+      });
+
+      on(div, "compositionstart", function(e) {
+        var data = e.data;
+        input.composing = {sel: cm.doc.sel, data: data, startData: data};
+        if (!data) return;
+        var prim = cm.doc.sel.primary();
+        var line = cm.getLine(prim.head.line);
+        var found = line.indexOf(data, Math.max(0, prim.head.ch - data.length));
+        if (found > -1 && found <= prim.head.ch)
+          input.composing.sel = simpleSelection(Pos(prim.head.line, found),
+                                                Pos(prim.head.line, found + data.length));
+      });
+      on(div, "compositionupdate", function(e) {
+        input.composing.data = e.data;
+      });
+      on(div, "compositionend", function(e) {
+        var ours = input.composing;
+        if (!ours) return;
+        if (e.data != ours.startData && !/\u200b/.test(e.data))
+          ours.data = e.data;
+        // Need a small delay to prevent other code (input event,
+        // selection polling) from doing damage when fired right after
+        // compositionend.
+        setTimeout(function() {
+          if (!ours.handled)
+            input.applyComposition(ours);
+          if (input.composing == ours)
+            input.composing = null;
+        }, 50);
+      });
+
+      on(div, "touchstart", function() {
+        input.forceCompositionEnd();
+      });
+
+      on(div, "input", function() {
+        if (input.composing) return;
+        if (!input.pollContent())
+          runInOp(input.cm, function() {regChange(cm);});
+      });
+
+      function onCopyCut(e) {
+        if (cm.somethingSelected()) {
+          lastCopied = cm.getSelections();
+          if (e.type == "cut") cm.replaceSelection("", null, "cut");
+        } else if (!cm.options.lineWiseCopyCut) {
+          return;
+        } else {
+          var ranges = copyableRanges(cm);
+          lastCopied = ranges.text;
+          if (e.type == "cut") {
+            cm.operation(function() {
+              cm.setSelections(ranges.ranges, 0, sel_dontScroll);
+              cm.replaceSelection("", null, "cut");
+            });
+          }
+        }
+        // iOS exposes the clipboard API, but seems to discard content inserted into it
+        if (e.clipboardData && !ios) {
+          e.preventDefault();
+          e.clipboardData.clearData();
+          e.clipboardData.setData("text/plain", lastCopied.join("\n"));
+        } else {
+          // Old-fashioned briefly-focus-a-textarea hack
+          var kludge = hiddenTextarea(), te = kludge.firstChild;
+          cm.display.lineSpace.insertBefore(kludge, cm.display.lineSpace.firstChild);
+          te.value = lastCopied.join("\n");
+          var hadFocus = document.activeElement;
+          selectInput(te);
+          setTimeout(function() {
+            cm.display.lineSpace.removeChild(kludge);
+            hadFocus.focus();
+          }, 50);
+        }
+      }
+      on(div, "copy", onCopyCut);
+      on(div, "cut", onCopyCut);
+    },
+
+    prepareSelection: function() {
+      var result = prepareSelection(this.cm, false);
+      result.focus = this.cm.state.focused;
+      return result;
+    },
+
+    showSelection: function(info) {
+      if (!info || !this.cm.display.view.length) return;
+      if (info.focus) this.showPrimarySelection();
+      this.showMultipleSelections(info);
+    },
+
+    showPrimarySelection: function() {
+      var sel = window.getSelection(), prim = this.cm.doc.sel.primary();
+      var curAnchor = domToPos(this.cm, sel.anchorNode, sel.anchorOffset);
+      var curFocus = domToPos(this.cm, sel.focusNode, sel.focusOffset);
+      if (curAnchor && !curAnchor.bad && curFocus && !curFocus.bad &&
+          cmp(minPos(curAnchor, curFocus), prim.from()) == 0 &&
+          cmp(maxPos(curAnchor, curFocus), prim.to()) == 0)
+        return;
+
+      var start = posToDOM(this.cm, prim.from());
+      var end = posToDOM(this.cm, prim.to());
+      if (!start && !end) return;
+
+      var view = this.cm.display.view;
+      var old = sel.rangeCount && sel.getRangeAt(0);
+      if (!start) {
+        start = {node: view[0].measure.map[2], offset: 0};
+      } else if (!end) { // FIXME dangerously hacky
+        var measure = view[view.length - 1].measure;
+        var map = measure.maps ? measure.maps[measure.maps.length - 1] : measure.map;
+        end = {node: map[map.length - 1], offset: map[map.length - 2] - map[map.length - 3]};
+      }
+
+      try { var rng = range(start.node, start.offset, end.offset, end.node); }
+      catch(e) {} // Our model of the DOM might be outdated, in which case the range we try to set can be impossible
+      if (rng) {
+        sel.removeAllRanges();
+        sel.addRange(rng);
+        if (old && sel.anchorNode == null) sel.addRange(old);
+        else if (gecko) this.startGracePeriod();
+      }
+      this.rememberSelection();
+    },
+
+    startGracePeriod: function() {
+      var input = this;
+      clearTimeout(this.gracePeriod);
+      this.gracePeriod = setTimeout(function() {
+        input.gracePeriod = false;
+        if (input.selectionChanged())
+          input.cm.operation(function() { input.cm.curOp.selectionChanged = true; });
+      }, 20);
+    },
+
+    showMultipleSelections: function(info) {
+      removeChildrenAndAdd(this.cm.display.cursorDiv, info.cursors);
+      removeChildrenAndAdd(this.cm.display.selectionDiv, info.selection);
+    },
+
+    rememberSelection: function() {
+      var sel = window.getSelection();
+      this.lastAnchorNode = sel.anchorNode; this.lastAnchorOffset = sel.anchorOffset;
+      this.lastFocusNode = sel.focusNode; this.lastFocusOffset = sel.focusOffset;
+    },
+
+    selectionInEditor: function() {
+      var sel = window.getSelection();
+      if (!sel.rangeCount) return false;
+      var node = sel.getRangeAt(0).commonAncestorContainer;
+      return contains(this.div, node);
+    },
+
+    focus: function() {
+      if (this.cm.options.readOnly != "nocursor") this.div.focus();
+    },
+    blur: function() { this.div.blur(); },
+    getField: function() { return this.div; },
+
+    supportsTouch: function() { return true; },
+
+    receivedFocus: function() {
+      var input = this;
+      if (this.selectionInEditor())
+        this.pollSelection();
+      else
+        runInOp(this.cm, function() { input.cm.curOp.selectionChanged = true; });
+
+      function poll() {
+        if (input.cm.state.focused) {
+          input.pollSelection();
+          input.polling.set(input.cm.options.pollInterval, poll);
+        }
+      }
+      this.polling.set(this.cm.options.pollInterval, poll);
+    },
+
+    selectionChanged: function() {
+      var sel = window.getSelection();
+      return sel.anchorNode != this.lastAnchorNode || sel.anchorOffset != this.lastAnchorOffset ||
+        sel.focusNode != this.lastFocusNode || sel.focusOffset != this.lastFocusOffset;
+    },
+
+    pollSelection: function() {
+      if (!this.composing && !this.gracePeriod && this.selectionChanged()) {
+        var sel = window.getSelection(), cm = this.cm;
+        this.rememberSelection();
+        var anchor = domToPos(cm, sel.anchorNode, sel.anchorOffset);
+        var head = domToPos(cm, sel.focusNode, sel.focusOffset);
+        if (anchor && head) runInOp(cm, function() {
+          setSelection(cm.doc, simpleSelection(anchor, head), sel_dontScroll);
+          if (anchor.bad || head.bad) cm.curOp.selectionChanged = true;
+        });
+      }
+    },
+
+    pollContent: function() {
+      var cm = this.cm, display = cm.display, sel = cm.doc.sel.primary();
+      var from = sel.from(), to = sel.to();
+      if (from.line < display.viewFrom || to.line > display.viewTo - 1) return false;
+
+      var fromIndex;
+      if (from.line == display.viewFrom || (fromIndex = findViewIndex(cm, from.line)) == 0) {
+        var fromLine = lineNo(display.view[0].line);
+        var fromNode = display.view[0].node;
+      } else {
+        var fromLine = lineNo(display.view[fromIndex].line);
+        var fromNode = display.view[fromIndex - 1].node.nextSibling;
+      }
+      var toIndex = findViewIndex(cm, to.line);
+      if (toIndex == display.view.length - 1) {
+        var toLine = display.viewTo - 1;
+        var toNode = display.view[toIndex].node;
+      } else {
+        var toLine = lineNo(display.view[toIndex + 1].line) - 1;
+        var toNode = display.view[toIndex + 1].node.previousSibling;
+      }
+
+      var newText = splitLines(domTextBetween(cm, fromNode, toNode, fromLine, toLine));
+      var oldText = getBetween(cm.doc, Pos(fromLine, 0), Pos(toLine, getLine(cm.doc, toLine).text.length));
+      while (newText.length > 1 && oldText.length > 1) {
+        if (lst(newText) == lst(oldText)) { newText.pop(); oldText.pop(); toLine--; }
+        else if (newText[0] == oldText[0]) { newText.shift(); oldText.shift(); fromLine++; }
+        else break;
+      }
+
+      var cutFront = 0, cutEnd = 0;
+      var newTop = newText[0], oldTop = oldText[0], maxCutFront = Math.min(newTop.length, oldTop.length);
+      while (cutFront < maxCutFront && newTop.charCodeAt(cutFront) == oldTop.charCodeAt(cutFront))
+        ++cutFront;
+      var newBot = lst(newText), oldBot = lst(oldText);
+      var maxCutEnd = Math.min(newBot.length - (newText.length == 1 ? cutFront : 0),
+                               oldBot.length - (oldText.length == 1 ? cutFront : 0));
+      while (cutEnd < maxCutEnd &&
+             newBot.charCodeAt(newBot.length - cutEnd - 1) == oldBot.charCodeAt(oldBot.length - cutEnd - 1))
+        ++cutEnd;
+
+      newText[newText.length - 1] = newBot.slice(0, newBot.length - cutEnd);
+      newText[0] = newText[0].slice(cutFront);
+
+      var chFrom = Pos(fromLine, cutFront);
+      var chTo = Pos(toLine, oldText.length ? lst(oldText).length - cutEnd : 0);
+      if (newText.length > 1 || newText[0] || cmp(chFrom, chTo)) {
+        replaceRange(cm.doc, newText, chFrom, chTo, "+input");
+        return true;
+      }
+    },
+
+    ensurePolled: function() {
+      this.forceCompositionEnd();
+    },
+    reset: function() {
+      this.forceCompositionEnd();
+    },
+    forceCompositionEnd: function() {
+      if (!this.composing || this.composing.handled) return;
+      this.applyComposition(this.composing);
+      this.composing.handled = true;
+      this.div.blur();
+      this.div.focus();
+    },
+    applyComposition: function(composing) {
+      if (composing.data && composing.data != composing.startData)
+        operation(this.cm, applyTextInput)(this.cm, composing.data, 0, composing.sel);
+    },
+
+    setUneditable: function(node) {
+      node.setAttribute("contenteditable", "false");
+    },
+
+    onKeyPress: function(e) {
+      e.preventDefault();
+      operation(this.cm, applyTextInput)(this.cm, String.fromCharCode(e.charCode == null ? e.keyCode : e.charCode), 0);
+    },
+
+    onContextMenu: nothing,
+    resetPosition: nothing,
+
+    needsContentAttribute: true
+  }, ContentEditableInput.prototype);
+
+  function posToDOM(cm, pos) {
+    var view = findViewForLine(cm, pos.line);
+    if (!view || view.hidden) return null;
+    var line = getLine(cm.doc, pos.line);
+    var info = mapFromLineView(view, line, pos.line);
+
+    var order = getOrder(line), side = "left";
+    if (order) {
+      var partPos = getBidiPartAt(order, pos.ch);
+      side = partPos % 2 ? "right" : "left";
+    }
+    var result = nodeAndOffsetInLineMap(info.map, pos.ch, "left");
+    result.offset = result.collapse == "right" ? result.end : result.start;
+    return result;
+  }
+
+  function badPos(pos, bad) { if (bad) pos.bad = true; return pos; }
+
+  function domToPos(cm, node, offset) {
+    var lineNode;
+    if (node == cm.display.lineDiv) {
+      lineNode = cm.display.lineDiv.childNodes[offset];
+      if (!lineNode) return badPos(cm.clipPos(Pos(cm.display.viewTo - 1)), true);
+      node = null; offset = 0;
+    } else {
+      for (lineNode = node;; lineNode = lineNode.parentNode) {
+        if (!lineNode || lineNode == cm.display.lineDiv) return null;
+        if (lineNode.parentNode && lineNode.parentNode == cm.display.lineDiv) break;
+      }
+    }
+    for (var i = 0; i < cm.display.view.length; i++) {
+      var lineView = cm.display.view[i];
+      if (lineView.node == lineNode)
+        return locateNodeInLineView(lineView, node, offset);
+    }
+  }
+
+  function locateNodeInLineView(lineView, node, offset) {
+    var wrapper = lineView.text.firstChild, bad = false;
+    if (!node || !contains(wrapper, node)) return badPos(Pos(lineNo(lineView.line), 0), true);
+    if (node == wrapper) {
+      bad = true;
+      node = wrapper.childNodes[offset];
+      offset = 0;
+      if (!node) {
+        var line = lineView.rest ? lst(lineView.rest) : lineView.line;
+        return badPos(Pos(lineNo(line), line.text.length), bad);
+      }
+    }
+
+    var textNode = node.nodeType == 3 ? node : null, topNode = node;
+    if (!textNode && node.childNodes.length == 1 && node.firstChild.nodeType == 3) {
+      textNode = node.firstChild;
+      if (offset) offset = textNode.nodeValue.length;
+    }
+    while (topNode.parentNode != wrapper) topNode = topNode.parentNode;
+    var measure = lineView.measure, maps = measure.maps;
+
+    function find(textNode, topNode, offset) {
+      for (var i = -1; i < (maps ? maps.length : 0); i++) {
+        var map = i < 0 ? measure.map : maps[i];
+        for (var j = 0; j < map.length; j += 3) {
+          var curNode = map[j + 2];
+          if (curNode == textNode || curNode == topNode) {
+            var line = lineNo(i < 0 ? lineView.line : lineView.rest[i]);
+            var ch = map[j] + offset;
+            if (offset < 0 || curNode != textNode) ch = map[j + (offset ? 1 : 0)];
+            return Pos(line, ch);
+          }
+        }
+      }
+    }
+    var found = find(textNode, topNode, offset);
+    if (found) return badPos(found, bad);
+
+    // FIXME this is all really shaky. might handle the few cases it needs to handle, but likely to cause problems
+    for (var after = topNode.nextSibling, dist = textNode ? textNode.nodeValue.length - offset : 0; after; after = after.nextSibling) {
+      found = find(after, after.firstChild, 0);
+      if (found)
+        return badPos(Pos(found.line, found.ch - dist), bad);
+      else
+        dist += after.textContent.length;
+    }
+    for (var before = topNode.previousSibling, dist = offset; before; before = before.previousSibling) {
+      found = find(before, before.firstChild, -1);
+      if (found)
+        return badPos(Pos(found.line, found.ch + dist), bad);
+      else
+        dist += after.textContent.length;
+    }
+  }
+
+  function domTextBetween(cm, from, to, fromLine, toLine) {
+    var text = "", closing = false;
+    function recognizeMarker(id) { return function(marker) { return marker.id == id; }; }
+    function walk(node) {
+      if (node.nodeType == 1) {
+        var cmText = node.getAttribute("cm-text");
+        if (cmText != null) {
+          if (cmText == "") cmText = node.textContent.replace(/\u200b/g, "");
+          text += cmText;
+          return;
+        }
+        var markerID = node.getAttribute("cm-marker"), range;
+        if (markerID) {
+          var found = cm.findMarks(Pos(fromLine, 0), Pos(toLine + 1, 0), recognizeMarker(+markerID));
+          if (found.length && (range = found[0].find()))
+            text += getBetween(cm.doc, range.from, range.to).join("\n");
+          return;
+        }
+        if (node.getAttribute("contenteditable") == "false") return;
+        for (var i = 0; i < node.childNodes.length; i++)
+          walk(node.childNodes[i]);
+        if (/^(pre|div|p)$/i.test(node.nodeName))
+          closing = true;
+      } else if (node.nodeType == 3) {
+        var val = node.nodeValue;
+        if (!val) return;
+        if (closing) {
+          text += "\n";
+          closing = false;
+        }
+        text += val;
+      }
+    }
+    for (;;) {
+      walk(from);
+      if (from == to) break;
+      from = from.nextSibling;
+    }
+    return text;
+  }
+
+  CodeMirror.inputStyles = {"textarea": TextareaInput, "contenteditable": ContentEditableInput};
+
+  // SELECTION / CURSOR
+
+  // Selection objects are immutable. A new one is created every time
+  // the selection changes. A selection is one or more non-overlapping
+  // (and non-touching) ranges, sorted, and an integer that indicates
+  // which one is the primary selection (the one that's scrolled into
+  // view, that getCursor returns, etc).
+  function Selection(ranges, primIndex) {
+    this.ranges = ranges;
+    this.primIndex = primIndex;
+  }
+
+  Selection.prototype = {
+    primary: function() { return this.ranges[this.primIndex]; },
+    equals: function(other) {
+      if (other == this) return true;
+      if (other.primIndex != this.primIndex || other.ranges.length != this.ranges.length) return false;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var here = this.ranges[i], there = other.ranges[i];
+        if (cmp(here.anchor, there.anchor) != 0 || cmp(here.head, there.head) != 0) return false;
+      }
+      return true;
+    },
+    deepCopy: function() {
+      for (var out = [], i = 0; i < this.ranges.length; i++)
+        out[i] = new Range(copyPos(this.ranges[i].anchor), copyPos(this.ranges[i].head));
+      return new Selection(out, this.primIndex);
+    },
+    somethingSelected: function() {
+      for (var i = 0; i < this.ranges.length; i++)
+        if (!this.ranges[i].empty()) return true;
+      return false;
+    },
+    contains: function(pos, end) {
+      if (!end) end = pos;
+      for (var i = 0; i < this.ranges.length; i++) {
+        var range = this.ranges[i];
+        if (cmp(end, range.from()) >= 0 && cmp(pos, range.to()) <= 0)
+          return i;
+      }
+      return -1;
+    }
+  };
+
+  function Range(anchor, head) {
+    this.anchor = anchor; this.head = head;
+  }
+
+  Range.prototype = {
+    from: function() { return minPos(this.anchor, this.head); },
+    to: function() { return maxPos(this.anchor, this.head); },
+    empty: function() {
+      return this.head.line == this.anchor.line && this.head.ch == this.anchor.ch;
+    }
+  };
+
+  // Take an unsorted, potentially overlapping set of ranges, and
+  // build a selection out of it. 'Consumes' ranges array (modifying
+  // it).
+  function normalizeSelection(ranges, primIndex) {
+    var prim = ranges[primIndex];
+    ranges.sort(function(a, b) { return cmp(a.from(), b.from()); });
+    primIndex = indexOf(ranges, prim);
+    for (var i = 1; i < ranges.length; i++) {
+      var cur = ranges[i], prev = ranges[i - 1];
+      if (cmp(prev.to(), cur.from()) >= 0) {
+        var from = minPos(prev.from(), cur.from()), to = maxPos(prev.to(), cur.to());
+        var inv = prev.empty() ? cur.from() == cur.head : prev.from() == prev.head;
+        if (i <= primIndex) --primIndex;
+        ranges.splice(--i, 2, new Range(inv ? to : from, inv ? from : to));
+      }
+    }
+    return new Selection(ranges, primIndex);
+  }
+
+  function simpleSelection(anchor, head) {
+    return new Selection([new Range(anchor, head || anchor)], 0);
+  }
+
+  // Most of the external API clips given positions to make sure they
+  // actually exist within the document.
+  function clipLine(doc, n) {return Math.max(doc.first, Math.min(n, doc.first + doc.size - 1));}
+  function clipPos(doc, pos) {
+    if (pos.line < doc.first) return Pos(doc.first, 0);
+    var last = doc.first + doc.size - 1;
+    if (pos.line > last) return Pos(last, getLine(doc, last).text.length);
+    return clipToLen(pos, getLine(doc, pos.line).text.length);
+  }
+  function clipToLen(pos, linelen) {
+    var ch = pos.ch;
+    if (ch == null || ch > linelen) return Pos(pos.line, linelen);
+    else if (ch < 0) return Pos(pos.line, 0);
+    else return pos;
+  }
+  function isLine(doc, l) {return l >= doc.first && l < doc.first + doc.size;}
+  function clipPosArray(doc, array) {
+    for (var out = [], i = 0; i < array.length; i++) out[i] = clipPos(doc, array[i]);
+    return out;
+  }
+
+  // SELECTION UPDATES
+
+  // The 'scroll' parameter given to many of these indicated whether
+  // the new cursor position should be scrolled into view after
+  // modifying the selection.
+
+  // If shift is held or the extend flag is set, extends a range to
+  // include a given position (and optionally a second position).
+  // Otherwise, simply returns the range between the given positions.
+  // Used for cursor motion and such.
+  function extendRange(doc, range, head, other) {
+    if (doc.cm && doc.cm.display.shift || doc.extend) {
+      var anchor = range.anchor;
+      if (other) {
+        var posBefore = cmp(head, anchor) < 0;
+        if (posBefore != (cmp(other, anchor) < 0)) {
+          anchor = head;
+          head = other;
+        } else if (posBefore != (cmp(head, other) < 0)) {
+          head = other;
+        }
+      }
+      return new Range(anchor, head);
+    } else {
+      return new Range(other || head, head);
+    }
+  }
+
+  // Extend the primary selection range, discard the rest.
+  function extendSelection(doc, head, other, options) {
+    setSelection(doc, new Selection([extendRange(doc, doc.sel.primary(), head, other)], 0), options);
+  }
+
+  // Extend all selections (pos is an array of selections with length
+  // equal the number of selections)
+  function extendSelections(doc, heads, options) {
+    for (var out = [], i = 0; i < doc.sel.ranges.length; i++)
+      out[i] = extendRange(doc, doc.sel.ranges[i], heads[i], null);
+    var newSel = normalizeSelection(out, doc.sel.primIndex);
+    setSelection(doc, newSel, options);
+  }
+
+  // Updates a single range in the selection.
+  function replaceOneSelection(doc, i, range, options) {
+    var ranges = doc.sel.ranges.slice(0);
+    ranges[i] = range;
+    setSelection(doc, normalizeSelection(ranges, doc.sel.primIndex), options);
+  }
+
+  // Reset the selection to a single range.
+  function setSimpleSelection(doc, anchor, head, options) {
+    setSelection(doc, simpleSelection(anchor, head), options);
+  }
+
+  // Give beforeSelectionChange handlers a change to influence a
+  // selection update.
+  function filterSelectionChange(doc, sel) {
+    var obj = {
+      ranges: sel.ranges,
+      update: function(ranges) {
+        this.ranges = [];
+        for (var i = 0; i < ranges.length; i++)
+          this.ranges[i] = new Range(clipPos(doc, ranges[i].anchor),
+                                     clipPos(doc, ranges[i].head));
+      }
+    };
+    signal(doc, "beforeSelectionChange", doc, obj);
+    if (doc.cm) signal(doc.cm, "beforeSelectionChange", doc.cm, obj);
+    if (obj.ranges != sel.ranges) return normalizeSelection(obj.ranges, obj.ranges.length - 1);
+    else return sel;
+  }
+
+  function setSelectionReplaceHistory(doc, sel, options) {
+    var done = doc.history.done, last = lst(done);
+    if (last && last.ranges) {
+      done[done.length - 1] = sel;
+      setSelectionNoUndo(doc, sel, options);
+    } else {
+      setSelection(doc, sel, options);
+    }
+  }
+
+  // Set a new selection.
+  function setSelection(doc, sel, options) {
+    setSelectionNoUndo(doc, sel, options);
+    addSelectionToHistory(doc, doc.sel, doc.cm ? doc.cm.curOp.id : NaN, options);
+  }
+
+  function setSelectionNoUndo(doc, sel, options) {
+    if (hasHandler(doc, "beforeSelectionChange") || doc.cm && hasHandler(doc.cm, "beforeSelectionChange"))
+      sel = filterSelectionChange(doc, sel);
+
+    var bias = options && options.bias ||
+      (cmp(sel.primary().head, doc.sel.primary().head) < 0 ? -1 : 1);
+    setSelectionInner(doc, skipAtomicInSelection(doc, sel, bias, true));
+
+    if (!(options && options.scroll === false) && doc.cm)
+      ensureCursorVisible(doc.cm);
+  }
+
+  function setSelectionInner(doc, sel) {
+    if (sel.equals(doc.sel)) return;
+
+    doc.sel = sel;
+
+    if (doc.cm) {
+      doc.cm.curOp.updateInput = doc.cm.curOp.selectionChanged = true;
+      signalCursorActivity(doc.cm);
+    }
+    signalLater(doc, "cursorActivity", doc);
+  }
+
+  // Verify that the selection does not partially select any atomic
+  // marked ranges.
+  function reCheckSelection(doc) {
+    setSelectionInner(doc, skipAtomicInSelection(doc, doc.sel, null, false), sel_dontScroll);
+  }
+
+  // Return a selection that does not partially select any atomic
+  // ranges.
+  function skipAtomicInSelection(doc, sel, bias, mayClear) {
+    var out;
+    for (var i = 0; i < sel.ranges.length; i++) {
+      var range = sel.ranges[i];
+      var newAnchor = skipAtomic(doc, range.anchor, bias, mayClear);
+      var newHead = skipAtomic(doc, range.head, bias, mayClear);
+      if (out || newAnchor != range.anchor || newHead != range.head) {
+        if (!out) out = sel.ranges.slice(0, i);
+        out[i] = new Range(newAnchor, newHead);
+      }
+    }
+    return out ? normalizeSelection(out, sel.primIndex) : sel;
+  }
+
+  // Ensure a given position is not inside an atomic range.
+  function skipAtomic(doc, pos, bias, mayClear) {
+    var flipped = false, curPos = pos;
+    var dir = bias || 1;
+    doc.cantEdit = false;
+    search: for (;;) {
+      var line = getLine(doc, curPos.line);
+      if (line.markedSpans) {
+        for (var i = 0; i < line.markedSpans.length; ++i) {
+          var sp = line.markedSpans[i], m = sp.marker;
+          if ((sp.from == null || (m.inclusiveLeft ? sp.from <= curPos.ch : sp.from < curPos.ch)) &&
+              (sp.to == null || (m.inclusiveRight ? sp.to >= curPos.ch : sp.to > curPos.ch))) {
+            if (mayClear) {
+              signal(m, "beforeCursorEnter");
+              if (m.explicitlyCleared) {
+                if (!line.markedSpans) break;
+                else {--i; continue;}
+              }
+            }
+            if (!m.atomic) continue;
+            var newPos = m.find(dir < 0 ? -1 : 1);
+            if (cmp(newPos, curPos) == 0) {
+              newPos.ch += dir;
+              if (newPos.ch < 0) {
+                if (newPos.line > doc.first) newPos = clipPos(doc, Pos(newPos.line - 1));
+                else newPos = null;
+              } else if (newPos.ch > line.text.length) {
+                if (newPos.line < doc.first + doc.size - 1) newPos = Pos(newPos.line + 1, 0);
+                else newPos = null;
+              }
+              if (!newPos) {
+                if (flipped) {
+                  // Driven in a corner -- no valid cursor position found at all
+                  // -- try again *with* clearing, if we didn't already
+                  if (!mayClear) return skipAtomic(doc, pos, bias, true);
+                  // Otherwise, turn off editing until further notice, and return the start of the doc
+                  doc.cantEdit = true;
+                  return Pos(doc.first, 0);
+                }
+                flipped = true; newPos = pos; dir = -dir;
+              }
+            }
+            curPos = newPos;
+            continue search;
+          }
+        }
+      }
+      return curPos;
+    }
+  }
+
+  // SELECTION DRAWING
+
+  function updateSelection(cm) {
+    cm.display.input.showSelection(cm.display.input.prepareSelection());
+  }
+
+  function prepareSelection(cm, primary) {
+    var doc = cm.doc, result = {};
+    var curFragment = result.cursors = document.createDocumentFragment();
+    var selFragment = result.selection = document.createDocumentFragment();
+
+    for (var i = 0; i < doc.sel.ranges.length; i++) {
+      if (primary === false && i == doc.sel.primIndex) continue;
+      var range = doc.sel.ranges[i];
+      var collapsed = range.empty();
+      if (collapsed || cm.options.showCursorWhenSelecting)
+        drawSelectionCursor(cm, range, curFragment);
+      if (!collapsed)
+        drawSelectionRange(cm, range, selFragment);
+    }
+    return result;
+  }
+
+  // Draws a cursor for the given range
+  function drawSelectionCursor(cm, range, output) {
+    var pos = cursorCoords(cm, range.head, "div", null, null, !cm.options.singleCursorHeightPerLine);
+
+    var cursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor"));
+    cursor.style.left = pos.left + "px";
+    cursor.style.top = pos.top + "px";
+    cursor.style.height = Math.max(0, pos.bottom - pos.top) * cm.options.cursorHeight + "px";
+
+    if (pos.other) {
+      // Secondary cursor, shown when on a 'jump' in bi-directional text
+      var otherCursor = output.appendChild(elt("div", "\u00a0", "CodeMirror-cursor CodeMirror-secondarycursor"));
+      otherCursor.style.display = "";
+      otherCursor.style.left = pos.other.left + "px";
+      otherCursor.style.top = pos.other.top + "px";
+      otherCursor.style.height = (pos.other.bottom - pos.other.top) * .85 + "px";
+    }
+  }
+
+  // Draws the given range as a highlighted selection
+  function drawSelectionRange(cm, range, output) {
+    var display = cm.display, doc = cm.doc;
+    var fragment = document.createDocumentFragment();
+    var padding = paddingH(cm.display), leftSide = padding.left;
+    var rightSide = Math.max(display.sizerWidth, displayWidth(cm) - display.sizer.offsetLeft) - padding.right;
+
+    function add(left, top, width, bottom) {
+      if (top < 0) top = 0;
+      top = Math.round(top);
+      bottom = Math.round(bottom);
+      fragment.appendChild(elt("div", null, "CodeMirror-selected", "position: absolute; left: " + left +
+                               "px; top: " + top + "px; width: " + (width == null ? rightSide - left : width) +
+                               "px; height: " + (bottom - top) + "px"));
+    }
+
+    function drawForLine(line, fromArg, toArg) {
+      var lineObj = getLine(doc, line);
+      var lineLen = lineObj.text.length;
+      var start, end;
+      function coords(ch, bias) {
+        return charCoords(cm, Pos(line, ch), "div", lineObj, bias);
+      }
+
+      iterateBidiSections(getOrder(lineObj), fromArg || 0, toArg == null ? lineLen : toArg, function(from, to, dir) {
+        var leftPos = coords(from, "left"), rightPos, left, right;
+        if (from == to) {
+          rightPos = leftPos;
+          left = right = leftPos.left;
+        } else {
+          rightPos = coords(to - 1, "right");
+          if (dir == "rtl") { var tmp = leftPos; leftPos = rightPos; rightPos = tmp; }
+          left = leftPos.left;
+          right = rightPos.right;
+        }
+        if (fromArg == null && from == 0) left = leftSide;
+        if (rightPos.top - leftPos.top > 3) { // Different lines, draw top part
+          add(left, leftPos.top, null, leftPos.bottom);
+          left = leftSide;
+          if (leftPos.bottom < rightPos.top) add(left, leftPos.bottom, null, rightPos.top);
+        }
+        if (toArg == null && to == lineLen) right = rightSide;
+        if (!start || leftPos.top < start.top || leftPos.top == start.top && leftPos.left < start.left)
+          start = leftPos;
+        if (!end || rightPos.bottom > end.bottom || rightPos.bottom == end.bottom && rightPos.right > end.right)
+          end = rightPos;
+        if (left < leftSide + 1) left = leftSide;
+        add(left, rightPos.top, right - left, rightPos.bottom);
+      });
+      return {start: start, end: end};
+    }
+
+    var sFrom = range.from(), sTo = range.to();
+    if (sFrom.line == sTo.line) {
+      drawForLine(sFrom.line, sFrom.ch, sTo.ch);
+    } else {
+      var fromLine = getLine(doc, sFrom.line), toLine = getLine(doc, sTo.line);
+      var singleVLine = visualLine(fromLine) == visualLine(toLine);
+      var leftEnd = drawForLine(sFrom.line, sFrom.ch, singleVLine ? fromLine.text.length + 1 : null).end;
+      var rightStart = drawForLine(sTo.line, singleVLine ? 0 : null, sTo.ch).start;
+      if (singleVLine) {
+        if (leftEnd.top < rightStart.top - 2) {
+          add(leftEnd.right, leftEnd.top, null, leftEnd.bottom);
+          add(leftSide, rightStart.top, rightStart.left, rightStart.bottom);
+        } else {
+          add(leftEnd.right, leftEnd.top, rightStart.left - leftEnd.right, leftEnd.bottom);
+        }
+      }
+      if (leftEnd.bottom < rightStart.top)
+        add(leftSide, leftEnd.bottom, null, rightStart.top);
+    }
+
+    output.appendChild(fragment);
+  }
+
+  // Cursor-blinking
+  function restartBlink(cm) {
+    if (!cm.state.focused) return;
+    var display = cm.display;
+    clearInterval(display.blinker);
+    var on = true;
+    display.cursorDiv.style.visibility = "";
+    if (cm.options.cursorBlinkRate > 0)
+      display.blinker = setInterval(function() {
+        display.cursorDiv.style.visibility = (on = !on) ? "" : "hidden";
+      }, cm.options.cursorBlinkRate);
+    else if (cm.options.cursorBlinkRate < 0)
+      display.cursorDiv.style.visibility = "hidden";
+  }
+
+  // HIGHLIGHT WORKER
+
+  function startWorker(cm, time) {
+    if (cm.doc.mode.startState && cm.doc.frontier < cm.display.viewTo)
+      cm.state.highlight.set(time, bind(highlightWorker, cm));
+  }
+
+  function highlightWorker(cm) {
+    var doc = cm.doc;
+    if (doc.frontier < doc.first) doc.frontier = doc.first;
+    if (doc.frontier >= cm.display.viewTo) return;
+    var end = +new Date + cm.options.workTime;
+    var state = copyState(doc.mode, getStateBefore(cm, doc.frontier));
+    var changedLines = [];
+
+    doc.iter(doc.frontier, Math.min(doc.first + doc.size, cm.display.viewTo + 500), function(line) {
+      if (doc.frontier >= cm.display.viewFrom) { // Visible
+        var oldStyles = line.styles;
+        var highlighted = highlightLine(cm, line, state, true);
+        line.styles = highlighted.styles;
+        var oldCls = line.styleClasses, newCls = highlighted.classes;
+        if (newCls) line.styleClasses = newCls;
+        else if (oldCls) line.styleClasses = null;
+        var ischange = !oldStyles || oldStyles.length != line.styles.length ||
+          oldCls != newCls && (!oldCls || !newCls || oldCls.bgClass != newCls.bgClass || oldCls.textClass != newCls.textClass);
+        for (var i = 0; !ischange && i < oldStyles.length; ++i) ischange = oldStyles[i] != line.styles[i];
+        if (ischange) changedLines.push(doc.frontier);
+        line.stateAfter = copyState(doc.mode, state);
+      } else {
+        processLine(cm, line.text, state);
+        line.stateAfter = doc.frontier % 5 == 0 ? copyState(doc.mode, state) : null;
+      }
+      ++doc.frontier;
+      if (+new Date > end) {
+        startWorker(cm, cm.options.workDelay);
+        return true;
+      }
+    });
+    if (changedLines.length) runInOp(cm, function() {
+      for (var i = 0; i < changedLines.length; i++)
+        regLineChange(cm, changedLines[i], "text");
+    });
+  }
+
+  // Finds the line to start with when starting a parse. Tries to
+  // find a line with a stateAfter, so that it can start with a
+  // valid state. If that fails, it returns the line with the
+  // smallest indentation, which tends to need the least context to
+  // parse correctly.
+  function findStartLine(cm, n, precise) {
+    var minindent, minline, doc = cm.doc;
+    var lim = precise ? -1 : n - (cm.doc.mode.innerMode ? 1000 : 100);
+    for (var search = n; search > lim; --search) {
+      if (search <= doc.first) return doc.first;
+      var line = getLine(doc, search - 1);
+      if (line.stateAfter && (!precise || search <= doc.frontier)) return search;
+      var indented = countColumn(line.text, null, cm.options.tabSize);
+      if (minline == null || minindent > indented) {
+        minline = search - 1;
+        minindent = indented;
+      }
+    }
+    return minline;
+  }
+
+  function getStateBefore(cm, n, precise) {
+    var doc = cm.doc, display = cm.display;
+    if (!doc.mode.startState) return true;
+    var pos = findStartLine(cm, n, precise), state = pos > doc.first && getLine(doc, pos-1).stateAfter;
+    if (!state) state = startState(doc.mode);
+    else state = copyState(doc.mode, state);
+    doc.iter(pos, n, function(line) {
+      processLine(cm, line.text, state);
+      var save = pos == n - 1 || pos % 5 == 0 || pos >= display.viewFrom && pos < display.viewTo;
+      line.stateAfter = save ? copyState(doc.mode, state) : null;
+      ++pos;
+    });
+    if (precise) doc.frontier = pos;
+    return state;
+  }
+
+  // POSITION MEASUREMENT
+
+  function paddingTop(display) {return display.lineSpace.offsetTop;}
+  function paddingVert(display) {return display.mover.offsetHeight - display.lineSpace.offsetHeight;}
+  function paddingH(display) {
+    if (display.cachedPaddingH) return display.cachedPaddingH;
+    var e = removeChildrenAndAdd(display.measure, elt("pre", "x"));
+    var style = window.getComputedStyle ? window.getComputedStyle(e) : e.currentStyle;
+    var data = {left: parseInt(style.paddingLeft), right: parseInt(style.paddingRight)};
+    if (!isNaN(data.left) && !isNaN(data.right)) display.cachedPaddingH = data;
+    return data;
+  }
+
+  function scrollGap(cm) { return scrollerGap - cm.display.nativeBarWidth; }
+  function displayWidth(cm) {
+    return cm.display.scroller.clientWidth - scrollGap(cm) - cm.display.barWidth;
+  }
+  function displayHeight(cm) {
+    return cm.display.scroller.clientHeight - scrollGap(cm) - cm.display.barHeight;
+  }
+
+  // Ensure the lineView.wrapping.heights array is populated. This is
+  // an array of bottom offsets for the lines that make up a drawn
+  // line. When lineWrapping is on, there might be more than one
+  // height.
+  function ensureLineHeights(cm, lineView, rect) {
+    var wrapping = cm.options.lineWrapping;
+    var curWidth = wrapping && displayWidth(cm);
+    if (!lineView.measure.heights || wrapping && lineView.measure.width != curWidth) {
+      var heights = lineView.measure.heights = [];
+      if (wrapping) {
+        lineView.measure.width = curWidth;
+        var rects = lineView.text.firstChild.getClientRects();
+        for (var i = 0; i < rects.length - 1; i++) {
+          var cur = rects[i], next = rects[i + 1];
+          if (Math.abs(cur.bottom - next.bottom) > 2)
+            heights.push((cur.bottom + next.top) / 2 - rect.top);
+        }
+      }
+      heights.push(rect.bottom - rect.top);
+    }
+  }
+
+  // Find a line map (mapping character offsets to text nodes) and a
+  // measurement cache for the given line number. (A line view might
+  // contain multiple lines when collapsed ranges are present.)
+  function mapFromLineView(lineView, line, lineN) {
+    if (lineView.line == line)
+      return {map: lineView.measure.map, cache: lineView.measure.cache};
+    for (var i = 0; i < lineView.rest.length; i++)
+      if (lineView.rest[i] == line)
+        return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i]};
+    for (var i = 0; i < lineView.rest.length; i++)
+      if (lineNo(lineView.rest[i]) > lineN)
+        return {map: lineView.measure.maps[i], cache: lineView.measure.caches[i], before: true};
+  }
+
+  // Render a line into the hidden node display.externalMeasured. Used
+  // when measurement is needed for a line that's not in the viewport.
+  function updateExternalMeasurement(cm, line) {
+    line = visualLine(line);
+    var lineN = lineNo(line);
+    var view = cm.display.externalMeasured = new LineView(cm.doc, line, lineN);
+    view.lineN = lineN;
+    var built = view.built = buildLineContent(cm, view);
+    view.text = built.pre;
+    removeChildrenAndAdd(cm.display.lineMeasure, built.pre);
+    return view;
+  }
+
+  // Get a {top, bottom, left, right} box (in line-local coordinates)
+  // for a given character.
+  function measureChar(cm, line, ch, bias) {
+    return measureCharPrepared(cm, prepareMeasureForLine(cm, line), ch, bias);
+  }
+
+  // Find a line view that corresponds to the given line number.
+  function findViewForLine(cm, lineN) {
+    if (lineN >= cm.display.viewFrom && lineN < cm.display.viewTo)
+      return cm.display.view[findViewIndex(cm, lineN)];
+    var ext = cm.display.externalMeasured;
+    if (ext && lineN >= ext.lineN && lineN < ext.lineN + ext.size)
+      return ext;
+  }
+
+  // Measurement can be split in two steps, the set-up work that
+  // applies to the whole line, and the measurement of the actual
+  // character. Functions like coordsChar, that need to do a lot of
+  // measurements in a row, can thus ensure that the set-up work is
+  // only done once.
+  function prepareMeasureForLine(cm, line) {
+    var lineN = lineNo(line);
+    var view = findViewForLine(cm, lineN);
+    if (view && !view.text)
+      view = null;
+    else if (view && view.changes)
+      updateLineForChanges(cm, view, lineN, getDimensions(cm));
+    if (!view)
+      view = updateExternalMeasurement(cm, line);
+
+    var info = mapFromLineView(view, line, lineN);
+    return {
+      line: line, view: view, rect: null,
+      map: info.map, cache: info.cache, before: info.before,
+      hasHeights: false
+    };
+  }
+
+  // Given a prepared measurement object, measures the position of an
+  // actual character (or fetches it from the cache).
+  function measureCharPrepared(cm, prepared, ch, bias, varHeight) {
+    if (prepared.before) ch = -1;
+    var key = ch + (bias || ""), found;
+    if (prepared.cache.hasOwnProperty(key)) {
+      found = prepared.cache[key];
+    } else {
+      if (!prepared.rect)
+        prepared.rect = prepared.view.text.getBoundingClientRect();
+      if (!prepared.hasHeights) {
+        ensureLineHeights(cm, prepared.view, prepared.rect);
+        prepared.hasHeights = true;
+      }
+      found = measureCharInner(cm, prepared, ch, bias);
+      if (!found.bogus) prepared.cache[key] = found;
+    }
+    return {left: found.left, right: found.right,
+            top: varHeight ? found.rtop : found.top,
+            bottom: varHeight ? found.rbottom : found.bottom};
+  }
+
+  var nullRect = {left: 0, right: 0, top: 0, bottom: 0};
+
+  function nodeAndOffsetInLineMap(map, ch, bias) {
+    var node, start, end, collapse;
+    // First, search the line map for the text node corresponding to,
+    // or closest to, the target character.
+    for (var i = 0; i < map.length; i += 3) {
+      var mStart = map[i], mEnd = map[i + 1];
+      if (ch < mStart) {
+        start = 0; end = 1;
+        collapse = "left";
+      } else if (ch < mEnd) {
+        start = ch - mStart;
+        end = start + 1;
+      } else if (i == map.length - 3 || ch == mEnd && map[i + 3] > ch) {
+        end = mEnd - mStart;
+        start = end - 1;
+        if (ch >= mEnd) collapse = "right";
+      }
+      if (start != null) {
+        node = map[i + 2];
+        if (mStart == mEnd && bias == (node.insertLeft ? "left" : "right"))
+          collapse = bias;
+        if (bias == "left" && start == 0)
+          while (i && map[i - 2] == map[i - 3] && map[i - 1].insertLeft) {
+            node = map[(i -= 3) + 2];
+            collapse = "left";
+          }
+        if (bias == "right" && start == mEnd - mStart)
+          while (i < map.length - 3 && map[i + 3] == map[i + 4] && !map[i + 5].insertLeft) {
+            node = map[(i += 3) + 2];
+            collapse = "right";
+          }
+        break;
+      }
+    }
+    return {node: node, start: start, end: end, collapse: collapse, coverStart: mStart, coverEnd: mEnd};
+  }
+
+  function measureCharInner(cm, prepared, ch, bias) {
+    var place = nodeAndOffsetInLineMap(prepared.map, ch, bias);
+    var node = place.node, start = place.start, end = place.end, collapse = place.collapse;
+
+    var rect;
+    if (node.nodeType == 3) { // If it is a text node, use a range to retrieve the coordinates.
+      for (var i = 0; i < 4; i++) { // Retry a maximum of 4 times when nonsense rectangles are returned
+        while (start && isExtendingChar(prepared.line.text.charAt(place.coverStart + start))) --start;
+        while (place.coverStart + end < place.coverEnd && isExtendingChar(prepared.line.text.charAt(place.coverStart + end))) ++end;
+        if (ie && ie_version < 9 && start == 0 && end == place.coverEnd - place.coverStart) {
+          rect = node.parentNode.getBoundingClientRect();
+        } else if (ie && cm.options.lineWrapping) {
+          var rects = range(node, start, end).getClientRects();
+          if (rects.length)
+            rect = rects[bias == "right" ? rects.length - 1 : 0];
+          else
+            rect = nullRect;
+        } else {
+          rect = range(node, start, end).getBoundingClientRect() || nullRect;
+        }
+        if (rect.left || rect.right || start == 0) break;
+        end = start;
+        start = start - 1;
+        collapse = "right";
+      }
+      if (ie && ie_version < 11) rect = maybeUpdateRectForZooming(cm.display.measure, rect);
+    } else { // If it is a widget, simply get the box for the whole widget.
+      if (start > 0) collapse = bias = "right";
+      var rects;
+      if (cm.options.lineWrapping && (rects = node.getClientRects()).length > 1)
+        rect = rects[bias == "right" ? rects.length - 1 : 0];
+      else
+        rect = node.getBoundingClientRect();
+    }
+    if (ie && ie_version < 9 && !start && (!rect || !rect.left && !rect.right)) {
+      var rSpan = node.parentNode.getClientRects()[0];
+      if (rSpan)
+        rect = {left: rSpan.left, right: rSpan.left + charWidth(cm.display), top: rSpan.top, bottom: rSpan.bottom};
+      else
+        rect = nullRect;
+    }
+
+    var rtop = rect.top - prepared.rect.top, rbot = rect.bottom - prepared.rect.top;
+    var mid = (rtop + rbot) / 2;
+    var heights = prepared.view.measure.heights;
+    for (var i = 0; i < heights.length - 1; i++)
+      if (mid < heights[i]) break;
+    var top = i ? heights[i - 1] : 0, bot = heights[i];
+    var result = {left: (collapse == "right" ? rect.right : rect.left) - prepared.rect.left,
+                  right: (collapse == "left" ? rect.left : rect.right) - prepared.rect.left,
+                  top: top, bottom: bot};
+    if (!rect.left && !rect.right) result.bogus = true;
+    if (!cm.options.singleCursorHeightPerLine) { result.rtop = rtop; result.rbottom = rbot; }
+
+    return result;
+  }
+
+  // Work around problem with bounding client rects on ranges being
+  // returned incorrectly when zoomed on IE10 and below.
+  function maybeUpdateRectForZooming(measure, rect) {
+    if (!window.screen || screen.logicalXDPI == null ||
+        screen.logicalXDPI == screen.deviceXDPI || !hasBadZoomedRects(measure))
+      return rect;
+    var scaleX = screen.logicalXDPI / screen.deviceXDPI;
+    var scaleY = screen.logicalYDPI / screen.deviceYDPI;
+    return {left: rect.left * scaleX, right: rect.right * scaleX,
+            top: rect.top * scaleY, bottom: rect.bottom * scaleY};
+  }
+
+  function clearLineMeasurementCacheFor(lineView) {
+    if (lineView.measure) {
+      lineView.measure.cache = {};
+      lineView.measure.heights = null;
+      if (lineView.rest) for (var i = 0; i < lineView.rest.length; i++)
+        lineView.measure.caches[i] = {};
+    }
+  }
+
+  function clearLineMeasurementCache(cm) {
+    cm.display.externalMeasure = null;
+    removeChildren(cm.display.lineMeasure);
+    for (var i = 0; i < cm.display.view.length; i++)
+      clearLineMeasurementCacheFor(cm.display.view[i]);
+  }
+
+  function clearCaches(cm) {
+    clearLineMeasurementCache(cm);
+    cm.display.cachedCharWidth = cm.display.cachedTextHeight = cm.display.cachedPaddingH = null;
+    if (!cm.options.lineWrapping) cm.display.maxLineChanged = true;
+    cm.display.lineNumChars = null;
+  }
+
+  function pageScrollX() { return window.pageXOffset || (document.documentElement || document.body).scrollLeft; }
+  function pageScrollY() { return window.pageYOffset || (document.documentElement || document.body).scrollTop; }
+
+  // Converts a {top, bottom, left, right} box from line-local
+  // coordinates into another coordinate system. Context may be one of
+  // "line", "div" (display.lineDiv), "local"/null (editor), "window",
+  // or "page".
+  function intoCoordSystem(cm, lineObj, rect, context) {
+    if (lineObj.widgets) for (var i = 0; i < lineObj.widgets.length; ++i) if (lineObj.widgets[i].above) {
+      var size = widgetHeight(lineObj.widgets[i]);
+      rect.top += size; rect.bottom += size;
+    }
+    if (context == "line") return rect;
+    if (!context) context = "local";
+    var yOff = heightAtLine(lineObj);
+    if (context == "local") yOff += paddingTop(cm.display);
+    else yOff -= cm.display.viewOffset;
+    if (context == "page" || context == "window") {
+      var lOff = cm.display.lineSpace.getBoundingClientRect();
+      yOff += lOff.top + (context == "window" ? 0 : pageScrollY());
+      var xOff = lOff.left + (context == "window" ? 0 : pageScrollX());
+      rect.left += xOff; rect.right += xOff;
+    }
+    rect.top += yOff; rect.bottom += yOff;
+    return rect;
+  }
+
+  // Coverts a box from "div" coords to another coordinate system.
+  // Context may be "window", "page", "div", or "local"/null.
+  function fromCoordSystem(cm, coords, context) {
+    if (context == "div") return coords;
+    var left = coords.left, top = coords.top;
+    // First move into "page" coordinate system
+    if (context == "page") {
+      left -= pageScrollX();
+      top -= pageScrollY();
+    } else if (context == "local" || !context) {
+      var localBox = cm.display.sizer.getBoundingClientRect();
+      left += localBox.left;
+      top += localBox.top;
+    }
+
+    var lineSpaceBox = cm.display.lineSpace.getBoundingClientRect();
+    return {left: left - lineSpaceBox.left, top: top - lineSpaceBox.top};
+  }
+
+  function charCoords(cm, pos, context, lineObj, bias) {
+    if (!lineObj) lineObj = getLine(cm.doc, pos.line);
+    return intoCoordSystem(cm, lineObj, measureChar(cm, lineObj, pos.ch, bias), context);
+  }
+
+  // Returns a box for a given cursor position, which may have an
+  // 'other' property containing the position of the secondary cursor
+  // on a bidi boundary.
+  function cursorCoords(cm, pos, context, lineObj, preparedMeasure, varHeight) {
+    lineObj = lineObj || getLine(cm.doc, pos.line);
+    if (!preparedMeasure) preparedMeasure = prepareMeasureForLine(cm, lineObj);
+    function get(ch, right) {
+      var m = measureCharPrepared(cm, preparedMeasure, ch, right ? "right" : "left", varHeight);
+      if (right) m.left = m.right; else m.right = m.left;
+      return intoCoordSystem(cm, lineObj, m, context);
+    }
+    function getBidi(ch, partPos) {
+      var part = order[partPos], right = part.level % 2;
+      if (ch == bidiLeft(part) && partPos && part.level < order[partPos - 1].level) {
+        part = order[--partPos];
+        ch = bidiRight(part) - (part.level % 2 ? 0 : 1);
+        right = true;
+      } else if (ch == bidiRight(part) && partPos < order.length - 1 && part.level < order[partPos + 1].level) {
+        part = order[++partPos];
+        ch = bidiLeft(part) - part.level % 2;
+        right = false;
+      }
+      if (right && ch == part.to && ch > part.from) return get(ch - 1);
+      return get(ch, right);
+    }
+    var order = getOrder(lineObj), ch = pos.ch;
+    if (!order) return get(ch);
+    var partPos = getBidiPartAt(order, ch);
+    var val = getBidi(ch, partPos);
+    if (bidiOther != null) val.other = getBidi(ch, bidiOther);
+    return val;
+  }
+
+  // Used to cheaply estimate the coordinates for a position. Used for
+  // intermediate scroll updates.
+  function estimateCoords(cm, pos) {
+    var left = 0, pos = clipPos(cm.doc, pos);
+    if (!cm.options.lineWrapping) left = charWidth(cm.display) * pos.ch;
+    var lineObj = getLine(cm.doc, pos.line);
+    var top = heightAtLine(lineObj) + paddingTop(cm.display);
+    return {left: left, right: left, top: top, bottom: top + lineObj.height};
+  }
+
+  // Positions returned by coordsChar contain some extra information.
+  // xRel is the relative x position of the input coordinates compared
+  // to the found position (so xRel > 0 means the coordinates are to
+  // the right of the character position, for example). When outside
+  // is true, that means the coordinates lie outside the line's
+  // vertical range.
+  function PosWithInfo(line, ch, outside, xRel) {
+    var pos = Pos(line, ch);
+    pos.xRel = xRel;
+    if (outside) pos.outside = true;
+    return pos;
+  }
+
+  // Compute the character position closest to the given coordinates.
+  // Input must be lineSpace-local ("div" coordinate system).
+  function coordsChar(cm, x, y) {
+    var doc = cm.doc;
+    y += cm.display.viewOffset;
+    if (y < 0) return PosWithInfo(doc.first, 0, true, -1);
+    var lineN = lineAtHeight(doc, y), last = doc.first + doc.size - 1;
+    if (lineN > last)
+      return PosWithInfo(doc.first + doc.size - 1, getLine(doc, last).text.length, true, 1);
+    if (x < 0) x = 0;
+
+    var lineObj = getLine(doc, lineN);
+    for (;;) {
+      var found = coordsCharInner(cm, lineObj, lineN, x, y);
+      var merged = collapsedSpanAtEnd(lineObj);
+      var mergedPos = merged && merged.find(0, true);
+      if (merged && (found.ch > mergedPos.from.ch || found.ch == mergedPos.from.ch && found.xRel > 0))
+        lineN = lineNo(lineObj = mergedPos.to.line);
+      else
+        return found;
+    }
+  }
+
+  function coordsCharInner(cm, lineObj, lineNo, x, y) {
+    var innerOff = y - heightAtLine(lineObj);
+    var wrongLine = false, adjust = 2 * cm.display.wrapper.clientWidth;
+    var preparedMeasure = prepareMeasureForLine(cm, lineObj);
+
+    function getX(ch) {
+      var sp = cursorCoords(cm, Pos(lineNo, ch), "line", lineObj, preparedMeasure);
+      wrongLine = true;
+      if (innerOff > sp.bottom) return sp.left - adjust;
+      else if (innerOff < sp.top) return sp.left + adjust;
+      else wrongLine = false;
+      return sp.left;
+    }
+
+    var bidi = getOrder(lineObj), dist = lineObj.text.length;
+    var from = lineLeft(lineObj), to = lineRight(lineObj);
+    var fromX = getX(from), fromOutside = wrongLine, toX = getX(to), toOutside = wrongLine;
+
+    if (x > toX) return PosWithInfo(lineNo, to, toOutside, 1);
+    // Do a binary search between these bounds.
+    for (;;) {
+      if (bidi ? to == from || to == moveVisually(lineObj, from, 1) : to - from <= 1) {
+        var ch = x < fromX || x - fromX <= toX - x ? from : to;
+        var xDiff = x - (ch == from ? fromX : toX);
+        while (isExtendingChar(lineObj.text.charAt(ch))) ++ch;
+        var pos = PosWithInfo(lineNo, ch, ch == from ? fromOutside : toOutside,
+                              xDiff < -1 ? -1 : xDiff > 1 ? 1 : 0);
+        return pos;
+      }
+      var step = Math.ceil(dist / 2), middle = from + step;
+      if (bidi) {
+        middle = from;
+        for (var i = 0; i < step; ++i) middle = moveVisually(lineObj, middle, 1);
+      }
+      var middleX = getX(middle);
+      if (middleX > x) {to = middle; toX = middleX; if (toOutside = wrongLine) toX += 1000; dist = step;}
+      else {from = middle; fromX = middleX; fromOutside = wrongLine; dist -= step;}
+    }
+  }
+
+  var measureText;
+  // Compute the default text height.
+  function textHeight(display) {
+    if (display.cachedTextHeight != null) return display.cachedTextHeight;
+    if (measureText == null) {
+      measureText = elt("pre");
+      // Measure a bunch of lines, for browsers that compute
+      // fractional heights.
+      for (var i = 0; i < 49; ++i) {
+        measureText.appendChild(document.createTextNode("x"));
+        measureText.appendChild(elt("br"));
+      }
+      measureText.appendChild(document.createTextNode("x"));
+    }
+    removeChildrenAndAdd(display.measure, measureText);
+    var height = measureText.offsetHeight / 50;
+    if (height > 3) display.cachedTextHeight = height;
+    removeChildren(display.measure);
+    return height || 1;
+  }
+
+  // Compute the default character width.
+  function charWidth(display) {
+    if (display.cachedCharWidth != null) return display.cachedCharWidth;
+    var anchor = elt("span", "xxxxxxxxxx");
+    var pre = elt("pre", [anchor]);
+    removeChildrenAndAdd(display.measure, pre);
+    var rect = anchor.getBoundingClientRect(), width = (rect.right - rect.left) / 10;
+    if (width > 2) display.cachedCharWidth = width;
+    return width || 10;
+  }
+
+  // OPERATIONS
+
+  // Operations are used to wrap a series of changes to the editor
+  // state in such a way that each change won't have to update the
+  // cursor and display (which would be awkward, slow, and
+  // error-prone). Instead, display updates are batched and then all
+  // combined and executed at once.
+
+  var operationGroup = null;
+
+  var nextOpId = 0;
+  // Start a new operation.
+  function startOperation(cm) {
+    cm.curOp = {
+      cm: cm,
+      viewChanged: false,      // Flag that indicates that lines might need to be redrawn
+      startHeight: cm.doc.height, // Used to detect need to update scrollbar
+      forceUpdate: false,      // Used to force a redraw
+      updateInput: null,       // Whether to reset the input textarea
+      typing: false,           // Whether this reset should be careful to leave existing text (for compositing)
+      changeObjs: null,        // Accumulated changes, for firing change events
+      cursorActivityHandlers: null, // Set of handlers to fire cursorActivity on
+      cursorActivityCalled: 0, // Tracks which cursorActivity handlers have been called already
+      selectionChanged: false, // Whether the selection needs to be redrawn
+      updateMaxLine: false,    // Set when the widest line needs to be determined anew
+      scrollLeft: null, scrollTop: null, // Intermediate scroll position, not pushed to DOM yet
+      scrollToPos: null,       // Used to scroll to a specific position
+      focus: false,
+      id: ++nextOpId           // Unique ID
+    };
+    if (operationGroup) {
+      operationGroup.ops.push(cm.curOp);
+    } else {
+      cm.curOp.ownsGroup = operationGroup = {
+        ops: [cm.curOp],
+        delayedCallbacks: []
+      };
+    }
+  }
+
+  function fireCallbacksForOps(group) {
+    // Calls delayed callbacks and cursorActivity handlers until no
+    // new ones appear
+    var callbacks = group.delayedCallbacks, i = 0;
+    do {
+      for (; i < callbacks.length; i++)
+        callbacks[i]();
+      for (var j = 0; j < group.ops.length; j++) {
+        var op = group.ops[j];
+        if (op.cursorActivityHandlers)
+          while (op.cursorActivityCalled < op.cursorActivityHandlers.length)
+            op.cursorActivityHandlers[op.cursorActivityCalled++](op.cm);
+      }
+    } while (i < callbacks.length);
+  }
+
+  // Finish an operation, updating the display and signalling delayed events
+  function endOperation(cm) {
+    var op = cm.curOp, group = op.ownsGroup;
+    if (!group) return;
+
+    try { fireCallbacksForOps(group); }
+    finally {
+      operationGroup = null;
+      for (var i = 0; i < group.ops.length; i++)
+        group.ops[i].cm.curOp = null;
+      endOperations(group);
+    }
+  }
+
+  // The DOM updates done when an operation finishes are batched so
+  // that the minimum number of relayouts are required.
+  function endOperations(group) {
+    var ops = group.ops;
+    for (var i = 0; i < ops.length; i++) // Read DOM
+      endOperation_R1(ops[i]);
+    for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
+      endOperation_W1(ops[i]);
+    for (var i = 0; i < ops.length; i++) // Read DOM
+      endOperation_R2(ops[i]);
+    for (var i = 0; i < ops.length; i++) // Write DOM (maybe)
+      endOperation_W2(ops[i]);
+    for (var i = 0; i < ops.length; i++) // Read DOM
+      endOperation_finish(ops[i]);
+  }
+
+  function endOperation_R1(op) {
+    var cm = op.cm, display = cm.display;
+    maybeClipScrollbars(cm);
+    if (op.updateMaxLine) findMaxLine(cm);
+
+    op.mustUpdate = op.viewChanged || op.forceUpdate || op.scrollTop != null ||
+      op.scrollToPos && (op.scrollToPos.from.line < display.viewFrom ||
+                         op.scrollToPos.to.line >= display.viewTo) ||
+      display.maxLineChanged && cm.options.lineWrapping;
+    op.update = op.mustUpdate &&
+      new DisplayUpdate(cm, op.mustUpdate && {top: op.scrollTop, ensure: op.scrollToPos}, op.forceUpdate);
+  }
+
+  function endOperation_W1(op) {
+    op.updatedDisplay = op.mustUpdate && updateDisplayIfNeeded(op.cm, op.update);
+  }
+
+  function endOperation_R2(op) {
+    var cm = op.cm, display = cm.display;
+    if (op.updatedDisplay) updateHeightsInViewport(cm);
+
+    op.barMeasure = measureForScrollbars(cm);
+
+    // If the max line changed since it was last measured, measure it,
+    // and ensure the document's width matches it.
+    // updateDisplay_W2 will use these properties to do the actual resizing
+    if (display.maxLineChanged && !cm.options.lineWrapping) {
+      op.adjustWidthTo = measureChar(cm, display.maxLine, display.maxLine.text.length).left + 3;
+      cm.display.sizerWidth = op.adjustWidthTo;
+      op.barMeasure.scrollWidth =
+        Math.max(display.scroller.clientWidth, display.sizer.offsetLeft + op.adjustWidthTo + scrollGap(cm) + cm.display.barWidth);
+      op.maxScrollLeft = Math.max(0, display.sizer.offsetLeft + op.adjustWidthTo - displayWidth(cm));
+    }
+
+    if (op.updatedDisplay || op.selectionChanged)
+      op.preparedSelection = display.input.prepareSelection();
+  }
+
+  function endOperation_W2(op) {
+    var cm = op.cm;
+
+    if (op.adjustWidthTo != null) {
+      cm.display.sizer.style.minWidth = op.adjustWidthTo + "px";
+      if (op.maxScrollLeft < cm.doc.scrollLeft)
+        setScrollLeft(cm, Math.min(cm.display.scroller.scrollLeft, op.maxScrollLeft), true);
+      cm.display.maxLineChanged = false;
+    }
+
+    if (op.preparedSelection)
+      cm.display.input.showSelection(op.preparedSelection);
+    if (op.updatedDisplay)
+      setDocumentHeight(cm, op.barMeasure);
+    if (op.updatedDisplay || op.startHeight != cm.doc.height)
+      updateScrollbars(cm, op.barMeasure);
+
+    if (op.selectionChanged) restartBlink(cm);
+
+    if (cm.state.focused && op.updateInput)
+      cm.display.input.reset(op.typing);
+    if (op.focus && op.focus == activeElt()) ensureFocus(op.cm);
+  }
+
+  function endOperation_finish(op) {
+    var cm = op.cm, display = cm.display, doc = cm.doc;
+
+    if (op.updatedDisplay) postUpdateDisplay(cm, op.update);
+
+    // Abort mouse wheel delta measurement, when scrolling explicitly
+    if (display.wheelStartX != null && (op.scrollTop != null || op.scrollLeft != null || op.scrollToPos))
+      display.wheelStartX = display.wheelStartY = null;
+
+    // Propagate the scroll position to the actual DOM scroller
+    if (op.scrollTop != null && (display.scroller.scrollTop != op.scrollTop || op.forceScroll)) {
+      doc.scrollTop = Math.max(0, Math.min(display.scroller.scrollHeight - display.scroller.clientHeight, op.scrollTop));
+      display.scrollbars.setScrollTop(doc.scrollTop);
+      display.scroller.scrollTop = doc.scrollTop;
+    }
+    if (op.scrollLeft != null && (display.scroller.scrollLeft != op.scrollLeft || op.forceScroll)) {
+      doc.scrollLeft = Math.max(0, Math.min(display.scroller.scrollWidth - displayWidth(cm), op.scrollLeft));
+      display.scrollbars.setScrollLeft(doc.scrollLeft);
+      display.scroller.scrollLeft = doc.scrollLeft;
+      alignHorizontally(cm);
+    }
+    // If we need to scroll a specific position into view, do so.
+    if (op.scrollToPos) {
+      var coords = scrollPosIntoView(cm, clipPos(doc, op.scrollToPos.from),
+                                     clipPos(doc, op.scrollToPos.to), op.scrollToPos.margin);
+      if (op.scrollToPos.isCursor && cm.state.focused) maybeScrollWindow(cm, coords);
+    }
+
+    // Fire events for markers that are hidden/unidden by editing or
+    // undoing
+    var hidden = op.maybeHiddenMarkers, unhidden = op.maybeUnhiddenMarkers;
+    if (hidden) for (var i = 0; i < hidden.length; ++i)
+      if (!hidden[i].lines.length) signal(hidden[i], "hide");
+    if (unhidden) for (var i = 0; i < unhidden.length; ++i)
+      if (unhidden[i].lines.length) signal(unhidden[i], "unhide");
+
+    if (display.wrapper.offsetHeight)
+      doc.scrollTop = cm.display.scroller.scrollTop;
+
+    // Fire change events, and delayed event handlers
+    if (op.changeObjs)
+      signal(cm, "changes", cm, op.changeObjs);
+    if (op.update)
+      op.update.finish();
+  }
+
+  // Run the given function in an operation
+  function runInOp(cm, f) {
+    if (cm.curOp) return f();
+    startOperation(cm);
+    try { return f(); }
+    finally { endOperation(cm); }
+  }
+  // Wraps a function in an operation. Returns the wrapped function.
+  function operation(cm, f) {
+    return function() {
+      if (cm.curOp) return f.apply(cm, arguments);
+      startOperation(cm);
+      try { return f.apply(cm, arguments); }
+      finally { endOperation(cm); }
+    };
+  }
+  // Used to add methods to editor and doc instances, wrapping them in
+  // operations.
+  function methodOp(f) {
+    return function() {
+      if (this.curOp) return f.apply(this, arguments);
+      startOperation(this);
+      try { return f.apply(this, arguments); }
+      finally { endOperation(this); }
+    };
+  }
+  function docMethodOp(f) {
+    return function() {
+      var cm = this.cm;
+      if (!cm || cm.curOp) return f.apply(this, arguments);
+      startOperation(cm);
+      try { return f.apply(this, arguments); }
+      finally { endOperation(cm); }
+    };
+  }
+
+  // VIEW TRACKING
+
+  // These objects are used to represent the visible (currently drawn)
+  // part of the document. A LineView may correspond to multiple
+  // logical lines, if those are connected by collapsed ranges.
+  function LineView(doc, line, lineN) {
+    // The starting line
+    this.line = line;
+    // Continuing lines, if any
+    this.rest = visualLineContinued(line);
+    // Number of logical lines in this visual line
+    this.size = this.rest ? lineNo(lst(this.rest)) - lineN + 1 : 1;
+    this.node = this.text = null;
+    this.hidden = lineIsHidden(doc, line);
+  }
+
+  // Create a range of LineView objects for the given lines.
+  function buildViewArray(cm, from, to) {
+    var array = [], nextPos;
+    for (var pos = from; pos < to; pos = nextPos) {
+      var view = new LineView(cm.doc, getLine(cm.doc, pos), pos);
+      nextPos = pos + view.size;
+      array.push(view);
+    }
+    return array;
+  }
+
+  // Updates the display.view data structure for a given change to the
+  // document. From and to are in pre-change coordinates. Lendiff is
+  // the amount of lines added or subtracted by the change. This is
+  // used for changes that span multiple lines, or change the way
+  // lines are divided into visual lines. regLineChange (below)
+  // registers single-line changes.
+  function regChange(cm, from, to, lendiff) {
+    if (from == null) from = cm.doc.first;
+    if (to == null) to = cm.doc.first + cm.doc.size;
+    if (!lendiff) lendiff = 0;
+
+    var display = cm.display;
+    if (lendiff && to < display.viewTo &&
+        (display.updateLineNumbers == null || display.updateLineNumbers > from))
+      display.updateLineNumbers = from;
+
+    cm.curOp.viewChanged = true;
+
+    if (from >= display.viewTo) { // Change after
+      if (sawCollapsedSpans && visualLineNo(cm.doc, from) < display.viewTo)
+        resetView(cm);
+    } else if (to <= display.viewFrom) { // Change before
+      if (sawCollapsedSpans && visualLineEndNo(cm.doc, to + lendiff) > display.viewFrom) {
+        resetView(cm);
+      } else {
+        display.viewFrom += lendiff;
+        display.viewTo += lendiff;
+      }
+    } else if (from <= display.viewFrom && to >= display.viewTo) { // Full overlap
+      resetView(cm);
+    } else if (from <= display.viewFrom) { // Top overlap
+      var cut = viewCuttingPoint(cm, to, to + lendiff, 1);
+      if (cut) {
+        display.view = display.view.slice(cut.index);
+        display.viewFrom = cut.lineN;
+        display.viewTo += lendiff;
+      } else {
+        resetView(cm);
+      }
+    } else if (to >= display.viewTo) { // Bottom overlap
+      var cut = viewCuttingPoint(cm, from, from, -1);
+      if (cut) {
+        display.view = display.view.slice(0, cut.index);
+        display.viewTo = cut.lineN;
+      } else {
+        resetView(cm);
+      }
+    } else { // Gap in the middle
+      var cutTop = viewCuttingPoint(cm, from, from, -1);
+      var cutBot = viewCuttingPoint(cm, to, to + lendiff, 1);
+      if (cutTop && cutBot) {
+        display.view = display.view.slice(0, cutTop.index)
+          .concat(buildViewArray(cm, cutTop.lineN, cutBot.lineN))
+          .concat(display.view.slice(cutBot.index));
+        display.viewTo += lendiff;
+      } else {
+        resetView(cm);
+      }
+    }
+
+    var ext = display.externalMeasured;
+    if (ext) {
+      if (to < ext.lineN)
+        ext.lineN += lendiff;
+      else if (from < ext.lineN + ext.size)
+        display.externalMeasured = null;
+    }
+  }
+
+  // Register a change to a single line. Type must be one of "text",
+  // "gutter", "class", "widget"
+  function regLineChange(cm, line, type) {
+    cm.curOp.viewChanged = true;
+    var display = cm.display, ext = cm.display.externalMeasured;
+    if (ext && line >= ext.lineN && line < ext.lineN + ext.size)
+      display.externalMeasured = null;
+
+    if (line < display.viewFrom || line >= display.viewTo) return;
+    var lineView = display.view[findViewIndex(cm, line)];
+    if (lineView.node == null) return;
+    var arr = lineView.changes || (lineView.changes = []);
+    if (indexOf(arr, type) == -1) arr.push(type);
+  }
+
+  // Clear the view.
+  function resetView(cm) {
+    cm.display.viewFrom = cm.display.viewTo = cm.doc.first;
+    cm.display.view = [];
+    cm.display.viewOffset = 0;
+  }
+
+  // Find the view element corresponding to a given line. Return null
+  // when the line isn't visible.
+  function findViewIndex(cm, n) {
+    if (n >= cm.display.viewTo) return null;
+    n -= cm.display.viewFrom;
+    if (n < 0) return null;
+    var view = cm.display.view;
+    for (var i = 0; i < view.length; i++) {
+      n -= view[i].size;
+      if (n < 0) return i;
+    }
+  }
+
+  function viewCuttingPoint(cm, oldN, newN, dir) {
+    var index = findViewIndex(cm, oldN), diff, view = cm.display.view;
+    if (!sawCollapsedSpans || newN == cm.doc.first + cm.doc.size)
+      return {index: index, lineN: newN};
+    for (var i = 0, n = cm.display.viewFrom; i < index; i++)
+      n += view[i].size;
+    if (n != oldN) {
+      if (dir > 0) {
+        if (index == view.length - 1) return null;
+        diff = (n + view[index].size) - oldN;
+        index++;
+      } else {
+        diff = n - oldN;
+      }
+      oldN += diff; newN += diff;
+    }
+    while (visualLineNo(cm.doc, newN) != newN) {
+      if (index == (dir < 0 ? 0 : view.length - 1)) return null;
+      newN += dir * view[index - (dir < 0 ? 1 : 0)].size;
+      index += dir;
+    }
+    return {index: index, lineN: newN};
+  }
+
+  // Force the view to cover a given range, adding empty view element
+  // or clipping off existing ones as needed.
+  function adjustView(cm, from, to) {
+    var display = cm.display, view = display.view;
+    if (view.length == 0 || from >= display.viewTo || to <= display.viewFrom) {
+      display.view = buildViewArray(cm, from, to);
+      display.viewFrom = from;
+    } else {
+      if (display.viewFrom > from)
+        display.view = buildViewArray(cm, from, display.viewFrom).concat(display.view);
+      else if (display.viewFrom < from)
+        display.view = display.view.slice(findViewIndex(cm, from));
+      display.viewFrom = from;
+      if (display.viewTo < to)
+        display.view = display.view.concat(buildViewArray(cm, display.viewTo, to));
+      else if (display.viewTo > to)
+        display.view = display.view.slice(0, findViewIndex(cm, to));
+    }
+    display.viewTo = to;
+  }
+
+  // Count the number of lines in the view whose DOM representation is
+  // out of date (or nonexistent).
+  function countDirtyView(cm) {
+    var view = cm.display.view, dirty = 0;
+    for (var i = 0; i < view.length; i++) {
+      var lineView = view[i];
+      if (!lineView.hidden && (!lineView.node || lineView.changes)) ++dirty;
+    }
+    return dirty;
+  }
+
+  // EVENT HANDLERS
+
+  // Attach the necessary event handlers when initializing the editor
+  function registerEventHandlers(cm) {
+    var d = cm.display;
+    on(d.scroller, "mousedown", operation(cm, onMouseDown));
+    // Older IE's will not fire a second mousedown for a double click
+    if (ie && ie_version < 11)
+      on(d.scroller, "dblclick", operation(cm, function(e) {
+        if (signalDOMEvent(cm, e)) return;
+        var pos = posFromMouse(cm, e);
+        if (!pos || clickInGutter(cm, e) || eventInWidget(cm.display, e)) return;
+        e_preventDefault(e);
+        var word = cm.findWordAt(pos);
+        extendSelection(cm.doc, word.anchor, word.head);
+      }));
+    else
+      on(d.scroller, "dblclick", function(e) { signalDOMEvent(cm, e) || e_preventDefault(e); });
+    // Some browsers fire contextmenu *after* opening the menu, at
+    // which point we can't mess with it anymore. Context menu is
+    // handled in onMouseDown for these browsers.
+    if (!captureRightClick) on(d.scroller, "contextmenu", function(e) {onContextMenu(cm, e);});
+
+    // Used to suppress mouse event handling when a touch happens
+    var touchFinished, prevTouch = {end: 0};
+    function finishTouch() {
+      if (d.activeTouch) {
+        touchFinished = setTimeout(function() {d.activeTouch = null;}, 1000);
+        prevTouch = d.activeTouch;
+        prevTouch.end = +new Date;
+      }
+    };
+    function isMouseLikeTouchEvent(e) {
+      if (e.touches.length != 1) return false;
+      var touch = e.touches[0];
+      return touch.radiusX <= 1 && touch.radiusY <= 1;
+    }
+    function farAway(touch, other) {
+      if (other.left == null) return true;
+      var dx = other.left - touch.left, dy = other.top - touch.top;
+      return dx * dx + dy * dy > 20 * 20;
+    }
+    on(d.scroller, "touchstart", function(e) {
+      if (!isMouseLikeTouchEvent(e)) {
+        clearTimeout(touchFinished);
+        var now = +new Date;
+        d.activeTouch = {start: now, moved: false,
+                         prev: now - prevTouch.end <= 300 ? prevTouch : null};
+        if (e.touches.length == 1) {
+          d.activeTouch.left = e.touches[0].pageX;
+          d.activeTouch.top = e.touches[0].pageY;
+        }
+      }
+    });
+    on(d.scroller, "touchmove", function() {
+      if (d.activeTouch) d.activeTouch.moved = true;
+    });
+    on(d.scroller, "touchend", function(e) {
+      var touch = d.activeTouch;
+      if (touch && !eventInWidget(d, e) && touch.left != null &&
+          !touch.moved && new Date - touch.start < 300) {
+        var pos = cm.coordsChar(d.activeTouch, "page"), range;
+        if (!touch.prev || farAway(touch, touch.prev)) // Single tap
+          range = new Range(pos, pos);
+        else if (!touch.prev.prev || farAway(touch, touch.prev.prev)) // Double tap
+          range = cm.findWordAt(pos);
+        else // Triple tap
+          range = new Range(Pos(pos.line, 0), clipPos(cm.doc, Pos(pos.line + 1, 0)));
+        cm.setSelection(range.anchor, range.head);
+        cm.focus();
+        e_preventDefault(e);
+      }
+      finishTouch();
+    });
+    on(d.scroller, "touchcancel", finishTouch);
+
+    // Sync scrolling between fake scrollbars and real scrollable
+    // area, ensure viewport is updated when scrolling.
+    on(d.scroller, "scroll", function() {
+      if (d.scroller.clientHeight) {
+        setScrollTop(cm, d.scroller.scrollTop);
+        setScrollLeft(cm, d.scroller.scrollLeft, true);
+        signal(cm, "scroll", cm);
+      }
+    });
+
+    // Listen to wheel events in order to try and update the viewport on time.
+    on(d.scroller, "mousewheel", function(e){onScrollWheel(cm, e);});
+    on(d.scroller, "DOMMouseScroll", function(e){onScrollWheel(cm, e);});
+
+    // Prevent wrapper from ever scrolling
+    on(d.wrapper, "scroll", function() { d.wrapper.scrollTop = d.wrapper.scrollLeft = 0; });
+
+    d.dragFunctions = {
+      simple: function(e) {if (!signalDOMEvent(cm, e)) e_stop(e);},
+      start: function(e){onDragStart(cm, e);},
+      drop: operation(cm, onDrop)
+    };
+
+    var inp = d.input.getField();
+    on(inp, "keyup", function(e) { onKeyUp.call(cm, e); });
+    on(inp, "keydown", operation(cm, onKeyDown));
+    on(inp, "keypress", operation(cm, onKeyPress));
+    on(inp, "focus", bind(onFocus, cm));
+    on(inp, "blur", bind(onBlur, cm));
+  }
+
+  function dragDropChanged(cm, value, old) {
+    var wasOn = old && old != CodeMirror.Init;
+    if (!value != !wasOn) {
+      var funcs = cm.display.dragFunctions;
+      var toggle = value ? on : off;
+      toggle(cm.display.scroller, "dragstart", funcs.start);
+      toggle(cm.display.scroller, "dragenter", funcs.simple);
+      toggle(cm.display.scroller, "dragover", funcs.simple);
+      toggle(cm.display.scroller, "drop", funcs.drop);
+    }
+  }
+
+  // Called when the window resizes
+  function onResize(cm) {
+    var d = cm.display;
+    if (d.lastWrapHeight == d.wrapper.clientHeight && d.lastWrapWidth == d.wrapper.clientWidth)
+      return;
+    // Might be a text scaling operation, clear size caches.
+    d.cachedCharWidth = d.cachedTextHeight = d.cachedPaddingH = null;
+    d.scrollbarsClipped = false;
+    cm.setSize();
+  }
+
+  // MOUSE EVENTS
+
+  // Return true when the given mouse event happened in a widget
+  function eventInWidget(display, e) {
+    for (var n = e_target(e); n != display.wrapper; n = n.parentNode) {
+      if (!n || (n.nodeType == 1 && n.getAttribute("cm-ignore-events") == "true") ||
+          (n.parentNode == display.sizer && n != display.mover))
+        return true;
+    }
+  }
+
+  // Given a mouse event, find the corresponding position. If liberal
+  // is false, it checks whether a gutter or scrollbar was clicked,
+  // and returns null if it was. forRect is used by rectangular
+  // selections, and tries to estimate a character position even for
+  // coordinates beyond the right of the text.
+  function posFromMouse(cm, e, liberal, forRect) {
+    var display = cm.display;
+    if (!liberal && e_target(e).getAttribute("cm-not-content") == "true") return null;
+
+    var x, y, space = display.lineSpace.getBoundingClientRect();
+    // Fails unpredictably on IE[67] when mouse is dragged around quickly.
+    try { x = e.clientX - space.left; y = e.clientY - space.top; }
+    catch (e) { return null; }
+    var coords = coordsChar(cm, x, y), line;
+    if (forRect && coords.xRel == 1 && (line = getLine(cm.doc, coords.line).text).length == coords.ch) {
+      var colDiff = countColumn(line, line.length, cm.options.tabSize) - line.length;
+      coords = Pos(coords.line, Math.max(0, Math.round((x - paddingH(cm.display).left) / charWidth(cm.display)) - colDiff));
+    }
+    return coords;
+  }
+
+  // A mouse down can be a single click, double click, triple click,
+  // start of selection drag, start of text drag, new cursor
+  // (ctrl-click), rectangle drag (alt-drag), or xwin
+  // middle-click-paste. Or it might be a click on something we should
+  // not interfere with, such as a scrollbar or widget.
+  function onMouseDown(e) {
+    var cm = this, display = cm.display;
+    if (display.activeTouch && display.input.supportsTouch() || signalDOMEvent(cm, e)) return;
+    display.shift = e.shiftKey;
+
+    if (eventInWidget(display, e)) {
+      if (!webkit) {
+        // Briefly turn off draggability, to allow widgets to do
+        // normal dragging things.
+        display.scroller.draggable = false;
+        setTimeout(function(){display.scroller.draggable = true;}, 100);
+      }
+      return;
+    }
+    if (clickInGutter(cm, e)) return;
+    var start = posFromMouse(cm, e);
+    window.focus();
+
+    switch (e_button(e)) {
+    case 1:
+      if (start)
+        leftButtonDown(cm, e, start);
+      else if (e_target(e) == display.scroller)
+        e_preventDefault(e);
+      break;
+    case 2:
+      if (webkit) cm.state.lastMiddleDown = +new Date;
+      if (start) extendSelection(cm.doc, start);
+      setTimeout(function() {display.input.focus();}, 20);
+      e_preventDefault(e);
+      break;
+    case 3:
+      if (captureRightClick) onContextMenu(cm, e);
+      else delayBlurEvent(cm);
+      break;
+    }
+  }
+
+  var lastClick, lastDoubleClick;
+  function leftButtonDown(cm, e, start) {
+    if (ie) setTimeout(bind(ensureFocus, cm), 0);
+    else cm.curOp.focus = activeElt();
+
+    var now = +new Date, type;
+    if (lastDoubleClick && lastDoubleClick.time > now - 400 && cmp(lastDoubleClick.pos, start) == 0) {
+      type = "triple";
+    } else if (lastClick && lastClick.time > now - 400 && cmp(lastClick.pos, start) == 0) {
+      type = "double";
+      lastDoubleClick = {time: now, pos: start};
+    } else {
+      type = "single";
+      lastClick = {time: now, pos: start};
+    }
+
+    var sel = cm.doc.sel, modifier = mac ? e.metaKey : e.ctrlKey, contained;
+    if (cm.options.dragDrop && dragAndDrop && !isReadOnly(cm) &&
+        type == "single" && (contained = sel.contains(start)) > -1 &&
+        !sel.ranges[contained].empty())
+      leftButtonStartDrag(cm, e, start, modifier);
+    else
+      leftButtonSelect(cm, e, start, type, modifier);
+  }
+
+  // Start a text drag. When it ends, see if any dragging actually
+  // happen, and treat as a click if it didn't.
+  function leftButtonStartDrag(cm, e, start, modifier) {
+    var display = cm.display, startTime = +new Date;
+    var dragEnd = operation(cm, function(e2) {
+      if (webkit) display.scroller.draggable = false;
+      cm.state.draggingText = false;
+      off(document, "mouseup", dragEnd);
+      off(display.scroller, "drop", dragEnd);
+      if (Math.abs(e.clientX - e2.clientX) + Math.abs(e.clientY - e2.clientY) < 10) {
+        e_preventDefault(e2);
+        if (!modifier && +new Date - 200 < startTime)
+          extendSelection(cm.doc, start);
+        // Work around unexplainable focus problem in IE9 (#2127) and Chrome (#3081)
+        if (webkit || ie && ie_version == 9)
+          setTimeout(function() {document.body.focus(); display.input.focus();}, 20);
+        else
+          display.input.focus();
+      }
+    });
+    // Let the drag handler handle this.
+    if (webkit) display.scroller.draggable = true;
+    cm.state.draggingText = dragEnd;
+    // IE's approach to draggable
+    if (display.scroller.dragDrop) display.scroller.dragDrop();
+    on(document, "mouseup", dragEnd);
+    on(display.scroller, "drop", dragEnd);
+  }
+
+  // Normal selection, as opposed to text dragging.
+  function leftButtonSelect(cm, e, start, type, addNew) {
+    var display = cm.display, doc = cm.doc;
+    e_preventDefault(e);
+
+    var ourRange, ourIndex, startSel = doc.sel, ranges = startSel.ranges;
+    if (addNew && !e.shiftKey) {
+      ourIndex = doc.sel.contains(start);
+      if (ourIndex > -1)
+        ourRange = ranges[ourIndex];
+      else
+        ourRange = new Range(start, start);
+    } else {
+      ourRange = doc.sel.primary();
+      ourIndex = doc.sel.primIndex;
+    }
+
+    if (e.altKey) {
+      type = "rect";
+      if (!addNew) ourRange = new Range(start, start);
+      start = posFromMouse(cm, e, true, true);
+      ourIndex = -1;
+    } else if (type == "double") {
+      var word = cm.findWordAt(start);
+      if (cm.display.shift || doc.extend)
+        ourRange = extendRange(doc, ourRange, word.anchor, word.head);
+      else
+        ourRange = word;
+    } else if (type == "triple") {
+      var line = new Range(Pos(start.line, 0), clipPos(doc, Pos(start.line + 1, 0)));
+      if (cm.display.shift || doc.extend)
+        ourRange = extendRange(doc, ourRange, line.anchor, line.head);
+      else
+        ourRange = line;
+    } else {
+      ourRange = extendRange(doc, ourRange, start);
+    }
+
+    if (!addNew) {
+      ourIndex = 0;
+      setSelection(doc, new Selection([ourRange], 0), sel_mouse);
+      startSel = doc.sel;
+    } else if (ourIndex == -1) {
+      ourIndex = ranges.length;
+      setSelection(doc, normalizeSelection(ranges.concat([ourRange]), ourIndex),
+                   {scroll: false, origin: "*mouse"});
+    } else if (ranges.length > 1 && ranges[ourIndex].empty() && type == "single" && !e.shiftKey) {
+      setSelection(doc, normalizeSelection(ranges.slice(0, ourIndex).concat(ranges.slice(ourIndex + 1)), 0));
+      startSel = doc.sel;
+    } else {
+      replaceOneSelection(doc, ourIndex, ourRange, sel_mouse);
+    }
+
+    var lastPos = start;
+    function extendTo(pos) {
+      if (cmp(lastPos, pos) == 0) return;
+      lastPos = pos;
+
+      if (type == "rect") {
+        var ranges = [], tabSize = cm.options.tabSize;
+        var startCol = countColumn(getLine(doc, start.line).text, start.ch, tabSize);
+        var posCol = countColumn(getLine(doc, pos.line).text, pos.ch, tabSize);
+        var left = Math.min(startCol, posCol), right = Math.max(startCol, posCol);
+        for (var line = Math.min(start.line, pos.line), end = Math.min(cm.lastLine(), Math.max(start.line, pos.line));
+             line <= end; line++) {
+          var text = getLine(doc, line).text, leftPos = findColumn(text, left, tabSize);
+          if (left == right)
+            ranges.push(new Range(Pos(line, leftPos), Pos(line, leftPos)));
+          else if (text.length > leftPos)
+            ranges.push(new Range(Pos(line, leftPos), Pos(line, findColumn(text, right, tabSize))));
+        }
+        if (!ranges.length) ranges.push(new Range(start, start));
+        setSelection(doc, normalizeSelection(startSel.ranges.slice(0, ourIndex).concat(ranges), ourIndex),
+                     {origin: "*mouse", scroll: false});
+        cm.scrollIntoView(pos);
+      } else {
+        var oldRange = ourRange;
+        var anchor = oldRange.anchor, head = pos;
+        if (type != "single") {
+          if (type == "double")
+            var range = cm.findWordAt(pos);
+          else
+            var range = new Range(Pos(pos.line, 0), clipPos(doc, Pos(pos.line + 1, 0)));
+          if (cmp(range.anchor, anchor) > 0) {
+            head = range.head;
+            anchor = minPos(oldRange.from(), range.anchor);
+          } else {
+            head = range.anchor;
+            anchor = maxPos(oldRange.to(), range.head);
+          }
+        }
+        var ranges = startSel.ranges.slice(0);
+        ranges[ourIndex] = new Range(clipPos(doc, anchor), head);
+        setSelection(doc, normalizeSelection(ranges, ourIndex), sel_mouse);
+      }
+    }
+
+    var editorSize = display.wrapper.getBoundingClientRect();
+    // Used to ensure timeout re-tries don't fire when another extend
+    // happened in the meantime (clearTimeout isn't reliable -- at
+    // least on Chrome, the timeouts still happen even when cleared,
+    // if the clear happens after their scheduled firing time).
+    var counter = 0;
+
+    function extend(e) {
+      var curCount = ++counter;
+      var cur = posFromMouse(cm, e, true, type == "rect");
+      if (!cur) return;
+      if (cmp(cur, lastPos) != 0) {
+        cm.curOp.focus = activeElt();
+        extendTo(cur);
+        var visible = visibleLines(display, doc);
+        if (cur.line >= visible.to || cur.line < visible.from)
+          setTimeout(operation(cm, function(){if (counter == curCount) extend(e);}), 150);
+      } else {
+        var outside = e.clientY < editorSize.top ? -20 : e.clientY > editorSize.bottom ? 20 : 0;
+        if (outside) setTimeout(operation(cm, function() {
+          if (counter != curCount) return;
+          display.scroller.scrollTop += outside;
+          extend(e);
+        }), 50);
+      }
+    }
+
+    function done(e) {
+      counter = Infinity;
+      e_preventDefault(e);
+      display.input.focus();
+      off(document, "mousemove", move);
+      off(document, "mouseup", up);
+      doc.history.lastSelOrigin = null;
+    }
+
+    var move = operation(cm, function(e) {
+      if (!e_button(e)) done(e);
+      else extend(e);
+    });
+    var up = operation(cm, done);
+    on(document, "mousemove", move);
+    on(document, "mouseup", up);
+  }
+
+  // Determines whether an event happened in the gutter, and fires the
+  // handlers for the corresponding event.
+  function gutterEvent(cm, e, type, prevent, signalfn) {
+    try { var mX = e.clientX, mY = e.clientY; }
+    catch(e) { return false; }
+    if (mX >= Math.floor(cm.display.gutters.getBoundingClientRect().right)) return false;
+    if (prevent) e_preventDefault(e);
+
+    var display = cm.display;
+    var lineBox = display.lineDiv.getBoundingClientRect();
+
+    if (mY > lineBox.bottom || !hasHandler(cm, type)) return e_defaultPrevented(e);
+    mY -= lineBox.top - display.viewOffset;
+
+    for (var i = 0; i < cm.options.gutters.length; ++i) {
+      var g = display.gutters.childNodes[i];
+      if (g && g.getBoundingClientRect().right >= mX) {
+        var line = lineAtHeight(cm.doc, mY);
+        var gutter = cm.options.gutters[i];
+        signalfn(cm, type, cm, line, gutter, e);
+        return e_defaultPrevented(e);
+      }
+    }
+  }
+
+  function clickInGutter(cm, e) {
+    return gutterEvent(cm, e, "gutterClick", true, signalLater);
+  }
+
+  // Kludge to work around strange IE behavior where it'll sometimes
+  // re-fire a series of drag-related events right after the drop (#1551)
+  var lastDrop = 0;
+
+  function onDrop(e) {
+    var cm = this;
+    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e))
+      return;
+    e_preventDefault(e);
+    if (ie) lastDrop = +new Date;
+    var pos = posFromMouse(cm, e, true), files = e.dataTransfer.files;
+    if (!pos || isReadOnly(cm)) return;
+    // Might be a file drop, in which case we simply extract the text
+    // and insert it.
+    if (files && files.length && window.FileReader && window.File) {
+      var n = files.length, text = Array(n), read = 0;
+      var loadFile = function(file, i) {
+        var reader = new FileReader;
+        reader.onload = operation(cm, function() {
+          text[i] = reader.result;
+          if (++read == n) {
+            pos = clipPos(cm.doc, pos);
+            var change = {from: pos, to: pos, text: splitLines(text.join("\n")), origin: "paste"};
+            makeChange(cm.doc, change);
+            setSelectionReplaceHistory(cm.doc, simpleSelection(pos, changeEnd(change)));
+          }
+        });
+        reader.readAsText(file);
+      };
+      for (var i = 0; i < n; ++i) loadFile(files[i], i);
+    } else { // Normal drop
+      // Don't do a replace if the drop happened inside of the selected text.
+      if (cm.state.draggingText && cm.doc.sel.contains(pos) > -1) {
+        cm.state.draggingText(e);
+        // Ensure the editor is re-focused
+        setTimeout(function() {cm.display.input.focus();}, 20);
+        return;
+      }
+      try {
+        var text = e.dataTransfer.getData("Text");
+        if (text) {
+          if (cm.state.draggingText && !(mac ? e.altKey : e.ctrlKey))
+            var selected = cm.listSelections();
+          setSelectionNoUndo(cm.doc, simpleSelection(pos, pos));
+          if (selected) for (var i = 0; i < selected.length; ++i)
+            replaceRange(cm.doc, "", selected[i].anchor, selected[i].head, "drag");
+          cm.replaceSelection(text, "around", "paste");
+          cm.display.input.focus();
+        }
+      }
+      catch(e){}
+    }
+  }
+
+  function onDragStart(cm, e) {
+    if (ie && (!cm.state.draggingText || +new Date - lastDrop < 100)) { e_stop(e); return; }
+    if (signalDOMEvent(cm, e) || eventInWidget(cm.display, e)) return;
+
+    e.dataTransfer.setData("Text", cm.getSelection());
+
+    // Use dummy image instead of default browsers image.
+    // Recent Safari (~6.0.2) have a tendency to segfault when this happens, so we don't do it there.
+    if (e.dataTransfer.setDragImage && !safari) {
+      var img = elt("img", null, null, "position: fixed; left: 0; top: 0;");
+      img.src = "data:image/gif;base64,R0lGODlhAQABAAAAACH5BAEKAAEALAAAAAABAAEAAAICTAEAOw==";
+      if (presto) {
+        img.width = img.height = 1;
+        cm.display.wrapper.appendChild(img);
+        // Force a relayout, or Opera won't use our image for some obscure reason
+        img._top = img.offsetTop;
+      }
+      e.dataTransfer.setDragImage(img, 0, 0);
+      if (presto) img.parentNode.removeChild(img);
+    }
+  }
+
+  // SCROLL EVENTS
+
+  // Sync the scrollable area and scrollbars, ensure the viewport
+  // covers the visible area.
+  function setScrollTop(cm, val) {
+    if (Math.abs(cm.doc.scrollTop - val) < 2) return;
+    cm.doc.scrollTop = val;
+    if (!gecko) updateDisplaySimple(cm, {top: val});
+    if (cm.display.scroller.scrollTop != val) cm.display.scroller.scrollTop = val;
+    cm.display.scrollbars.setScrollTop(val);
+    if (gecko) updateDisplaySimple(cm);
+    startWorker(cm, 100);
+  }
+  // Sync scroller and scrollbar, ensure the gutter elements are
+  // aligned.
+  function setScrollLeft(cm, val, isScroller) {
+    if (isScroller ? val == cm.doc.scrollLeft : Math.abs(cm.doc.scrollLeft - val) < 2) return;
+    val = Math.min(val, cm.display.scroller.scrollWidth - cm.display.scroller.clientWidth);
+    cm.doc.scrollLeft = val;
+    alignHorizontally(cm);
+    if (cm.display.scroller.scrollLeft != val) cm.display.scroller.scrollLeft = val;
+    cm.display.scrollbars.setScrollLeft(val);
+  }
+
+  // Since the delta values reported on mouse wheel events are
+  // unstandardized between browsers and even browser versions, and
+  // generally horribly unpredictable, this code starts by measuring
+  // the scroll effect that the first few mouse wheel events have,
+  // and, from that, detects the way it can convert deltas to pixel
+  // offsets afterwards.
+  //
+  // The reason we want to know the amount a wheel event will scroll
+  // is that it gives us a chance to update the display before the
+  // actual scrolling happens, reducing flickering.
+
+  var wheelSamples = 0, wheelPixelsPerUnit = null;
+  // Fill in a browser-detected starting value on browsers where we
+  // know one. These don't have to be accurate -- the result of them
+  // being wrong would just be a slight flicker on the first wheel
+  // scroll (if it is large enough).
+  if (ie) wheelPixelsPerUnit = -.53;
+  else if (gecko) wheelPixelsPerUnit = 15;
+  else if (chrome) wheelPixelsPerUnit = -.7;
+  else if (safari) wheelPixelsPerUnit = -1/3;
+
+  var wheelEventDelta = function(e) {
+    var dx = e.wheelDeltaX, dy = e.wheelDeltaY;
+    if (dx == null && e.detail && e.axis == e.HORIZONTAL_AXIS) dx = e.detail;
+    if (dy == null && e.detail && e.axis == e.VERTICAL_AXIS) dy = e.detail;
+    else if (dy == null) dy = e.wheelDelta;
+    return {x: dx, y: dy};
+  };
+  CodeMirror.wheelEventPixels = function(e) {
+    var delta = wheelEventDelta(e);
+    delta.x *= wheelPixelsPerUnit;
+    delta.y *= wheelPixelsPerUnit;
+    return delta;
+  };
+
+  function onScrollWheel(cm, e) {
+    var delta = wheelEventDelta(e), dx = delta.x, dy = delta.y;
+
+    var display = cm.display, scroll = display.scroller;
+    // Quit if there's nothing to scroll here
+    if (!(dx && scroll.scrollWidth > scroll.clientWidth ||
+          dy && scroll.scrollHeight > scroll.clientHeight)) return;
+
+    // Webkit browsers on OS X abort momentum scrolls when the target
+    // of the scroll event is removed from the scrollable element.
+    // This hack (see related code in patchDisplay) makes sure the
+    // element is kept around.
+    if (dy && mac && webkit) {
+      outer: for (var cur = e.target, view = display.view; cur != scroll; cur = cur.parentNode) {
+        for (var i = 0; i < view.length; i++) {
+          if (view[i].node == cur) {
+            cm.display.currentWheelTarget = cur;
+            break outer;
+          }
+        }
+      }
+    }
+
+    // On some browsers, horizontal scrolling will cause redraws to
+    // happen before the gutter has been realigned, causing it to
+    // wriggle around in a most unseemly way. When we have an
+    // estimated pixels/delta value, we just handle horizontal
+    // scrolling entirely here. It'll be slightly off from native, but
+    // better than glitching out.
+    if (dx && !gecko && !presto && wheelPixelsPerUnit != null) {
+      if (dy)
+        setScrollTop(cm, Math.max(0, Math.min(scroll.scrollTop + dy * wheelPixelsPerUnit, scroll.scrollHeight - scroll.clientHeight)));
+      setScrollLeft(cm, Math.max(0, Math.min(scroll.scrollLeft + dx * wheelPixelsPerUnit, scroll.scrollWidth - scroll.clientWidth)));
+      e_preventDefault(e);
+      display.wheelStartX = null; // Abort measurement, if in progress
+      return;
+    }
+
+    // 'Project' the visible viewport to cover the area that is being
+    // scrolled into view (if we know enough to estimate it).
+    if (dy && wheelPixelsPerUnit != null) {
+      var pixels = dy * wheelPixelsPerUnit;
+      var top = cm.doc.scrollTop, bot = top + display.wrapper.clientHeight;
+      if (pixels < 0) top = Math.max(0, top + pixels - 50);
+      else bot = Math.min(cm.doc.height, bot + pixels + 50);
+      updateDisplaySimple(cm, {top: top, bottom: bot});
+    }
+
+    if (wheelSamples < 20) {
+      if (display.wheelStartX == null) {
+        display.wheelStartX = scroll.scrollLeft; display.wheelStartY = scroll.scrollTop;
+        display.wheelDX = dx; display.wheelDY = dy;
+        setTimeout(function() {
+          if (display.wheelStartX == null) return;
+          var movedX = scroll.scrollLeft - display.wheelStartX;
+          var movedY = scroll.scrollTop - display.wheelStartY;
+          var sample = (movedY && display.wheelDY && movedY / display.wheelDY) ||
+            (movedX && display.wheelDX && movedX / display.wheelDX);
+          display.wheelStartX = display.wheelStartY = null;
+          if (!sample) return;
+          wheelPixelsPerUnit = (wheelPixelsPerUnit * wheelSamples + sample) / (wheelSamples + 1);
+          ++wheelSamples;
+        }, 200);
+      } else {
+        display.wheelDX += dx; display.wheelDY += dy;
+      }
+    }
+  }
+
+  // KEY EVENTS
+
+  // Run a handler that was bound to a key.
+  function doHandleBinding(cm, bound, dropShift) {
+    if (typeof bound == "string") {
+      bound = commands[bound];
+      if (!bound) return false;
+    }
+    // Ensure previous input has been read, so that the handler sees a
+    // consistent view of the document
+    cm.display.input.ensurePolled();
+    var prevShift = cm.display.shift, done = false;
+    try {
+      if (isReadOnly(cm)) cm.state.suppressEdits = true;
+      if (dropShift) cm.display.shift = false;
+      done = bound(cm) != Pass;
+    } finally {
+      cm.display.shift = prevShift;
+      cm.state.suppressEdits = false;
+    }
+    return done;
+  }
+
+  function lookupKeyForEditor(cm, name, handle) {
+    for (var i = 0; i < cm.state.keyMaps.length; i++) {
+      var result = lookupKey(name, cm.state.keyMaps[i], handle, cm);
+      if (result) return result;
+    }
+    return (cm.options.extraKeys && lookupKey(name, cm.options.extraKeys, handle, cm))
+      || lookupKey(name, cm.options.keyMap, handle, cm);
+  }
+
+  var stopSeq = new Delayed;
+  function dispatchKey(cm, name, e, handle) {
+    var seq = cm.state.keySeq;
+    if (seq) {
+      if (isModifierKey(name)) return "handled";
+      stopSeq.set(50, function() {
+        if (cm.state.keySeq == seq) {
+          cm.state.keySeq = null;
+          cm.display.input.reset();
+        }
+      });
+      name = seq + " " + name;
+    }
+    var result = lookupKeyForEditor(cm, name, handle);
+
+    if (result == "multi")
+      cm.state.keySeq = name;
+    if (result == "handled")
+      signalLater(cm, "keyHandled", cm, name, e);
+
+    if (result == "handled" || result == "multi") {
+      e_preventDefault(e);
+      restartBlink(cm);
+    }
+
+    if (seq && !result && /\'$/.test(name)) {
+      e_preventDefault(e);
+      return true;
+    }
+    return !!result;
+  }
+
+  // Handle a key from the keydown event.
+  function handleKeyBinding(cm, e) {
+    var name = keyName(e, true);
+    if (!name) return false;
+
+    if (e.shiftKey && !cm.state.keySeq) {
+      // First try to resolve full name (including 'Shift-'). Failing
+      // that, see if there is a cursor-motion command (starting with
+      // 'go') bound to the keyname without 'Shift-'.
+      return dispatchKey(cm, "Shift-" + name, e, function(b) {return doHandleBinding(cm, b, true);})
+          || dispatchKey(cm, name, e, function(b) {
+               if (typeof b == "string" ? /^go[A-Z]/.test(b) : b.motion)
+                 return doHandleBinding(cm, b);
+             });
+    } else {
+      return dispatchKey(cm, name, e, function(b) { return doHandleBinding(cm, b); });
+    }
+  }
+
+  // Handle a key from the keypress event
+  function handleCharBinding(cm, e, ch) {
+    return dispatchKey(cm, "'" + ch + "'", e,
+                       function(b) { return doHandleBinding(cm, b, true); });
+  }
+
+  var lastStoppedKey = null;
+  function onKeyDown(e) {
+    var cm = this;
+    cm.curOp.focus = activeElt();
+    if (signalDOMEvent(cm, e)) return;
+    // IE does strange things with escape.
+    if (ie && ie_version < 11 && e.keyCode == 27) e.returnValue = false;
+    var code = e.keyCode;
+    cm.display.shift = code == 16 || e.shiftKey;
+    var handled = handleKeyBinding(cm, e);
+    if (presto) {
+      lastStoppedKey = handled ? code : null;
+      // Opera has no cut event... we try to at least catch the key combo
+      if (!handled && code == 88 && !hasCopyEvent && (mac ? e.metaKey : e.ctrlKey))
+        cm.replaceSelection("", null, "cut");
+    }
+
+    // Turn mouse into crosshair when Alt is held on Mac.
+    if (code == 18 && !/\bCodeMirror-crosshair\b/.test(cm.display.lineDiv.className))
+      showCrossHair(cm);
+  }
+
+  function showCrossHair(cm) {
+    var lineDiv = cm.display.lineDiv;
+    addClass(lineDiv, "CodeMirror-crosshair");
+
+    function up(e) {
+      if (e.keyCode == 18 || !e.altKey) {
+        rmClass(lineDiv, "CodeMirror-crosshair");
+        off(document, "keyup", up);
+        off(document, "mouseover", up);
+      }
+    }
+    on(document, "keyup", up);
+    on(document, "mouseover", up);
+  }
+
+  function onKeyUp(e) {
+    if (e.keyCode == 16) this.doc.sel.shift = false;
+    signalDOMEvent(this, e);
+  }
+
+  function onKeyPress(e) {
+    var cm = this;
+    if (eventInWidget(cm.display, e) || signalDOMEvent(cm, e) || e.ctrlKey && !e.altKey || mac && e.metaKey) return;
+    var keyCode = e.keyCode, charCode = e.charCode;
+    if (presto && keyCode == lastStoppedKey) {lastStoppedKey = null; e_preventDefault(e); return;}
+    if ((presto && (!e.which || e.which < 10)) && handleKeyBinding(cm, e)) return;
+    var ch = String.fromCharCode(charCode == null ? keyCode : charCode);
+    if (handleCharBinding(cm, e, ch)) return;
+    cm.display.input.onKeyPress(e);
+  }
+
+  // FOCUS/BLUR EVENTS
+
+  function delayBlurEvent(cm) {
+    cm.state.delayingBlurEvent = true;
+    setTimeout(function() {
+      if (cm.state.delayingBlurEvent) {
+        cm.state.delayingBlurEvent = false;
+        onBlur(cm);
+      }
+    }, 100);
+  }
+
+  function onFocus(cm) {
+    if (cm.state.delayingBlurEvent) cm.state.delayingBlurEvent = false;
+
+    if (cm.options.readOnly == "nocursor") return;
+    if (!cm.state.focused) {
+      signal(cm, "focus", cm);
+      cm.state.focused = true;
+      addClass(cm.display.wrapper, "CodeMirror-focused");
+      // This test prevents this from firing when a context
+      // menu is closed (since the input reset would kill the
+      // select-all detection hack)
+      if (!cm.curOp && cm.display.selForContextMenu != cm.doc.sel) {
+        cm.display.input.reset();
+        if (webkit) setTimeout(function() { cm.display.input.reset(true); }, 20); // Issue #1730
+      }
+      cm.display.input.receivedFocus();
+    }
+    restartBlink(cm);
+  }
+  function onBlur(cm) {
+    if (cm.state.delayingBlurEvent) return;
+
+    if (cm.state.focused) {
+      signal(cm, "blur", cm);
+      cm.state.focused = false;
+      rmClass(cm.display.wrapper, "CodeMirror-focused");
+    }
+    clearInterval(cm.display.blinker);
+    setTimeout(function() {if (!cm.state.focused) cm.display.shift = false;}, 150);
+  }
+
+  // CONTEXT MENU HANDLING
+
+  // To make the context menu work, we need to briefly unhide the
+  // textarea (making it as unobtrusive as possible) to let the
+  // right-click take effect on it.
+  function onContextMenu(cm, e) {
+    if (eventInWidget(cm.display, e) || contextMenuInGutter(cm, e)) return;
+    cm.display.input.onContextMenu(e);
+  }
+
+  function contextMenuInGutter(cm, e) {
+    if (!hasHandler(cm, "gutterContextMenu")) return false;
+    return gutterEvent(cm, e, "gutterContextMenu", false, signal);
+  }
+
+  // UPDATING
+
+  // Compute the position of the end of a change (its 'to' property
+  // refers to the pre-change end).
+  var changeEnd = CodeMirror.changeEnd = function(change) {
+    if (!change.text) return change.to;
+    return Pos(change.from.line + change.text.length - 1,
+               lst(change.text).length + (change.text.length == 1 ? change.from.ch : 0));
+  };
+
+  // Adjust a position to refer to the post-change position of the
+  // same text, or the end of the change if the change covers it.
+  function adjustForChange(pos, change) {
+    if (cmp(pos, change.from) < 0) return pos;
+    if (cmp(pos, change.to) <= 0) return changeEnd(change);
+
+    var line = pos.line + change.text.length - (change.to.line - change.from.line) - 1, ch = pos.ch;
+    if (pos.line == change.to.line) ch += changeEnd(change).ch - change.to.ch;
+    return Pos(line, ch);
+  }
+
+  function computeSelAfterChange(doc, change) {
+    var out = [];
+    for (var i = 0; i < doc.sel.ranges.length; i++) {
+      var range = doc.sel.ranges[i];
+      out.push(new Range(adjustForChange(range.anchor, change),
+                         adjustForChange(range.head, change)));
+    }
+    return normalizeSelection(out, doc.sel.primIndex);
+  }
+
+  function offsetPos(pos, old, nw) {
+    if (pos.line == old.line)
+      return Pos(nw.line, pos.ch - old.ch + nw.ch);
+    else
+      return Pos(nw.line + (pos.line - old.line), pos.ch);
+  }
+
+  // Used by replaceSelections to allow moving the selection to the
+  // start or around the replaced test. Hint may be "start" or "around".
+  function computeReplacedSel(doc, changes, hint) {
+    var out = [];
+    var oldPrev = Pos(doc.first, 0), newPrev = oldPrev;
+    for (var i = 0; i < changes.length; i++) {
+      var change = changes[i];
+      var from = offsetPos(change.from, oldPrev, newPrev);
+      var to = offsetPos(changeEnd(change), oldPrev, newPrev);
+      oldPrev = change.to;
+      newPrev = to;
+      if (hint == "around") {
+        var range = doc.sel.ranges[i], inv = cmp(range.head, range.anchor) < 0;
+        out[i] = new Range(inv ? to : from, inv ? from : to);
+      } else {
+        out[i] = new Range(from, from);
+      }
+    }
+    return new Selection(out, doc.sel.primIndex);
+  }
+
+  // Allow "beforeChange" event handlers to influence a change
+  function filterChange(doc, change, update) {
+    var obj = {
+      canceled: false,
+      from: change.from,
+      to: change.to,
+      text: change.text,
+      origin: change.origin,
+      cancel: function() { this.canceled = true; }
+    };
+    if (update) obj.update = function(from, to, text, origin) {
+      if (from) this.from = clipPos(doc, from);
+      if (to) this.to = clipPos(doc, to);
+      if (text) this.text = text;
+      if (origin !== undefined) this.origin = origin;
+    };
+    signal(doc, "beforeChange", doc, obj);
+    if (doc.cm) signal(doc.cm, "beforeChange", doc.cm, obj);
+
+    if (obj.canceled) return null;
+    return {from: obj.from, to: obj.to, text: obj.text, origin: obj.origin};
+  }
+
+  // Apply a change to a document, and add it to the document's
+  // history, and propagating it to all linked documents.
+  function makeChange(doc, change, ignoreReadOnly) {
+    if (doc.cm) {
+      if (!doc.cm.curOp) return operation(doc.cm, makeChange)(doc, change, ignoreReadOnly);
+      if (doc.cm.state.suppressEdits) return;
+    }
+
+    if (hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange")) {
+      change = filterChange(doc, change, true);
+      if (!change) return;
+    }
+
+    // Possibly split or suppress the update based on the presence
+    // of read-only spans in its range.
+    var split = sawReadOnlySpans && !ignoreReadOnly && removeReadOnlyRanges(doc, change.from, change.to);
+    if (split) {
+      for (var i = split.length - 1; i >= 0; --i)
+        makeChangeInner(doc, {from: split[i].from, to: split[i].to, text: i ? [""] : change.text});
+    } else {
+      makeChangeInner(doc, change);
+    }
+  }
+
+  function makeChangeInner(doc, change) {
+    if (change.text.length == 1 && change.text[0] == "" && cmp(change.from, change.to) == 0) return;
+    var selAfter = computeSelAfterChange(doc, change);
+    addChangeToHistory(doc, change, selAfter, doc.cm ? doc.cm.curOp.id : NaN);
+
+    makeChangeSingleDoc(doc, change, selAfter, stretchSpansOverChange(doc, change));
+    var rebased = [];
+
+    linkedDocs(doc, function(doc, sharedHist) {
+      if (!sharedHist && indexOf(rebased, doc.history) == -1) {
+        rebaseHist(doc.history, change);
+        rebased.push(doc.history);
+      }
+      makeChangeSingleDoc(doc, change, null, stretchSpansOverChange(doc, change));
+    });
+  }
+
+  // Revert a change stored in a document's history.
+  function makeChangeFromHistory(doc, type, allowSelectionOnly) {
+    if (doc.cm && doc.cm.state.suppressEdits) return;
+
+    var hist = doc.history, event, selAfter = doc.sel;
+    var source = type == "undo" ? hist.done : hist.undone, dest = type == "undo" ? hist.undone : hist.done;
+
+    // Verify that there is a useable event (so that ctrl-z won't
+    // needlessly clear selection events)
+    for (var i = 0; i < source.length; i++) {
+      event = source[i];
+      if (allowSelectionOnly ? event.ranges && !event.equals(doc.sel) : !event.ranges)
+        break;
+    }
+    if (i == source.length) return;
+    hist.lastOrigin = hist.lastSelOrigin = null;
+
+    for (;;) {
+      event = source.pop();
+      if (event.ranges) {
+        pushSelectionToHistory(event, dest);
+        if (allowSelectionOnly && !event.equals(doc.sel)) {
+          setSelection(doc, event, {clearRedo: false});
+          return;
+        }
+        selAfter = event;
+      }
+      else break;
+    }
+
+    // Build up a reverse change object to add to the opposite history
+    // stack (redo when undoing, and vice versa).
+    var antiChanges = [];
+    pushSelectionToHistory(selAfter, dest);
+    dest.push({changes: antiChanges, generation: hist.generation});
+    hist.generation = event.generation || ++hist.maxGeneration;
+
+    var filter = hasHandler(doc, "beforeChange") || doc.cm && hasHandler(doc.cm, "beforeChange");
+
+    for (var i = event.changes.length - 1; i >= 0; --i) {
+      var change = event.changes[i];
+      change.origin = type;
+      if (filter && !filterChange(doc, change, false)) {
+        source.length = 0;
+        return;
+      }
+
+      antiChanges.push(historyChangeFromChange(doc, change));
+
+      var after = i ? computeSelAfterChange(doc, change) : lst(source);
+      makeChangeSingleDoc(doc, change, after, mergeOldSpans(doc, change));
+      if (!i && doc.cm) doc.cm.scrollIntoView({from: change.from, to: changeEnd(change)});
+      var rebased = [];
+
+      // Propagate to the linked documents
+      linkedDocs(doc, function(doc, sharedHist) {
+        if (!sharedHist && indexOf(rebased, doc.history) == -1) {
+          rebaseHist(doc.history, change);
+          rebased.push(doc.history);
+        }
+        makeChangeSingleDoc(doc, change, null, mergeOldSpans(doc, change));
+      });
+    }
+  }
+
+  // Sub-views need their line numbers shifted when text is added
+  // above or below them in the parent document.
+  function shiftDoc(doc, distance) {
+    if (distance == 0) return;
+    doc.first += distance;
+    doc.sel = new Selection(map(doc.sel.ranges, function(range) {
+      return new Range(Pos(range.anchor.line + distance, range.anchor.ch),
+                       Pos(range.head.line + distance, range.head.ch));
+    }), doc.sel.primIndex);
+    if (doc.cm) {
+      regChange(doc.cm, doc.first, doc.first - distance, distance);
+      for (var d = doc.cm.display, l = d.viewFrom; l < d.viewTo; l++)
+        regLineChange(doc.cm, l, "gutter");
+    }
+  }
+
+  // More lower-level change function, handling only a single document
+  // (not linked ones).
+  function makeChangeSingleDoc(doc, change, selAfter, spans) {
+    if (doc.cm && !doc.cm.curOp)
+      return operation(doc.cm, makeChangeSingleDoc)(doc, change, selAfter, spans);
+
+    if (change.to.line < doc.first) {
+      shiftDoc(doc, change.text.length - 1 - (change.to.line - change.from.line));
+      return;
+    }
+    if (change.from.line > doc.lastLine()) return;
+
+    // Clip the change to the size of this doc
+    if (change.from.line < doc.first) {
+      var shift = change.text.length - 1 - (doc.first - change.from.line);
+      shiftDoc(doc, shift);
+      change = {from: Pos(doc.first, 0), to: Pos(change.to.line + shift, change.to.ch),
+                text: [lst(change.text)], origin: change.origin};
+    }
+    var last = doc.lastLine();
+    if (change.to.line > last) {
+      change = {from: change.from, to: Pos(last, getLine(doc, last).text.length),
+                text: [change.text[0]], origin: change.origin};
+    }
+
+    change.removed = getBetween(doc, change.from, change.to);
+
+    if (!selAfter) selAfter = computeSelAfterChange(doc, change);
+    if (doc.cm) makeChangeSingleDocInEditor(doc.cm, change, spans);
+    else updateDoc(doc, change, spans);
+    setSelectionNoUndo(doc, selAfter, sel_dontScroll);
+  }
+
+  // Handle the interaction of a change to a document with the editor
+  // that this document is part of.
+  function makeChangeSingleDocInEditor(cm, change, spans) {
+    var doc = cm.doc, display = cm.display, from = change.from, to = change.to;
+
+    var recomputeMaxLength = false, checkWidthStart = from.line;
+    if (!cm.options.lineWrapping) {
+      checkWidthStart = lineNo(visualLine(getLine(doc, from.line)));
+      doc.iter(checkWidthStart, to.line + 1, function(line) {
+        if (line == display.maxLine) {
+          recomputeMaxLength = true;
+          return true;
+        }
+      });
+    }
+
+    if (doc.sel.contains(change.from, change.to) > -1)
+      signalCursorActivity(cm);
+
+    updateDoc(doc, change, spans, estimateHeight(cm));
+
+    if (!cm.options.lineWrapping) {
+      doc.iter(checkWidthStart, from.line + change.text.length, function(line) {
+        var len = lineLength(line);
+        if (len > display.maxLineLength) {
+          display.maxLine = line;
+          display.maxLineLength = len;
+          display.maxLineChanged = true;
+          recomputeMaxLength = false;
+        }
+      });
+      if (recomputeMaxLength) cm.curOp.updateMaxLine = true;
+    }
+
+    // Adjust frontier, schedule worker
+    doc.frontier = Math.min(doc.frontier, from.line);
+    startWorker(cm, 400);
+
+    var lendiff = change.text.length - (to.line - from.line) - 1;
+    // Remember that these lines changed, for updating the display
+    if (change.full)
+      regChange(cm);
+    else if (from.line == to.line && change.text.length == 1 && !isWholeLineUpdate(cm.doc, change))
+      regLineChange(cm, from.line, "text");
+    else
+      regChange(cm, from.line, to.line + 1, lendiff);
+
+    var changesHandler = hasHandler(cm, "changes"), changeHandler = hasHandler(cm, "change");
+    if (changeHandler || changesHandler) {
+      var obj = {
+        from: from, to: to,
+        text: change.text,
+        removed: change.removed,
+        origin: change.origin
+      };
+      if (changeHandler) signalLater(cm, "change", cm, obj);
+      if (changesHandler) (cm.curOp.changeObjs || (cm.curOp.changeObjs = [])).push(obj);
+    }
+    cm.display.selForContextMenu = null;
+  }
+
+  function replaceRange(doc, code, from, to, origin) {
+    if (!to) to = from;
+    if (cmp(to, from) < 0) { var tmp = to; to = from; from = tmp; }
+    if (typeof code == "string") code = splitLines(code);
+    makeChange(doc, {from: from, to: to, text: code, origin: origin});
+  }
+
+  // SCROLLING THINGS INTO VIEW
+
+  // If an editor sits on the top or bottom of the window, partially
+  // scrolled out of view, this ensures that the cursor is visible.
+  function maybeScrollWindow(cm, coords) {
+    if (signalDOMEvent(cm, "scrollCursorIntoView")) return;
+
+    var display = cm.display, box = display.sizer.getBoundingClientRect(), doScroll = null;
+    if (coords.top + box.top < 0) doScroll = true;
+    else if (coords.bottom + box.top > (window.innerHeight || document.documentElement.clientHeight)) doScroll = false;
+    if (doScroll != null && !phantom) {
+      var scrollNode = elt("div", "\u200b", null, "position: absolute; top: " +
+                           (coords.top - display.viewOffset - paddingTop(cm.display)) + "px; height: " +
+                           (coords.bottom - coords.top + scrollGap(cm) + display.barHeight) + "px; left: " +
+                           coords.left + "px; width: 2px;");
+      cm.display.lineSpace.appendChild(scrollNode);
+      scrollNode.scrollIntoView(doScroll);
+      cm.display.lineSpace.removeChild(scrollNode);
+    }
+  }
+
+  // Scroll a given position into view (immediately), verifying that
+  // it actually became visible (as line heights are accurately
+  // measured, the position of something may 'drift' during drawing).
+  function scrollPosIntoView(cm, pos, end, margin) {
+    if (margin == null) margin = 0;
+    for (var limit = 0; limit < 5; limit++) {
+      var changed = false, coords = cursorCoords(cm, pos);
+      var endCoords = !end || end == pos ? coords : cursorCoords(cm, end);
+      var scrollPos = calculateScrollPos(cm, Math.min(coords.left, endCoords.left),
+                                         Math.min(coords.top, endCoords.top) - margin,
+                                         Math.max(coords.left, endCoords.left),
+                                         Math.max(coords.bottom, endCoords.bottom) + margin);
+      var startTop = cm.doc.scrollTop, startLeft = cm.doc.scrollLeft;
+      if (scrollPos.scrollTop != null) {
+        setScrollTop(cm, scrollPos.scrollTop);
+        if (Math.abs(cm.doc.scrollTop - startTop) > 1) changed = true;
+      }
+      if (scrollPos.scrollLeft != null) {
+        setScrollLeft(cm, scrollPos.scrollLeft);
+        if (Math.abs(cm.doc.scrollLeft - startLeft) > 1) changed = true;
+      }
+      if (!changed) break;
+    }
+    return coords;
+  }
+
+  // Scroll a given set of coordinates into view (immediately).
+  function scrollIntoView(cm, x1, y1, x2, y2) {
+    var scrollPos = calculateScrollPos(cm, x1, y1, x2, y2);
+    if (scrollPos.scrollTop != null) setScrollTop(cm, scrollPos.scrollTop);
+    if (scrollPos.scrollLeft != null) setScrollLeft(cm, scrollPos.scrollLeft);
+  }
+
+  // Calculate a new scroll position needed to scroll the given
+  // rectangle into view. Returns an object with scrollTop and
+  // scrollLeft properties. When these are undefined, the
+  // vertical/horizontal position does not need to be adjusted.
+  function calculateScrollPos(cm, x1, y1, x2, y2) {
+    var display = cm.display, snapMargin = textHeight(cm.display);
+    if (y1 < 0) y1 = 0;
+    var screentop = cm.curOp && cm.curOp.scrollTop != null ? cm.curOp.scrollTop : display.scroller.scrollTop;
+    var screen = displayHeight(cm), result = {};
+    if (y2 - y1 > screen) y2 = y1 + screen;
+    var docBottom = cm.doc.height + paddingVert(display);
+    var atTop = y1 < snapMargin, atBottom = y2 > docBottom - snapMargin;
+    if (y1 < screentop) {
+      result.scrollTop = atTop ? 0 : y1;
+    } else if (y2 > screentop + screen) {
+      var newTop = Math.min(y1, (atBottom ? docBottom : y2) - screen);
+      if (newTop != screentop) result.scrollTop = newTop;
+    }
+
+    var screenleft = cm.curOp && cm.curOp.scrollLeft != null ? cm.curOp.scrollLeft : display.scroller.scrollLeft;
+    var screenw = displayWidth(cm) - (cm.options.fixedGutter ? display.gutters.offsetWidth : 0);
+    var tooWide = x2 - x1 > screenw;
+    if (tooWide) x2 = x1 + screenw;
+    if (x1 < 10)
+      result.scrollLeft = 0;
+    else if (x1 < screenleft)
+      result.scrollLeft = Math.max(0, x1 - (tooWide ? 0 : 10));
+    else if (x2 > screenw + screenleft - 3)
+      result.scrollLeft = x2 + (tooWide ? 0 : 10) - screenw;
+    return result;
+  }
+
+  // Store a relative adjustment to the scroll position in the current
+  // operation (to be applied when the operation finishes).
+  function addToScrollPos(cm, left, top) {
+    if (left != null || top != null) resolveScrollToPos(cm);
+    if (left != null)
+      cm.curOp.scrollLeft = (cm.curOp.scrollLeft == null ? cm.doc.scrollLeft : cm.curOp.scrollLeft) + left;
+    if (top != null)
+      cm.curOp.scrollTop = (cm.curOp.scrollTop == null ? cm.doc.scrollTop : cm.curOp.scrollTop) + top;
+  }
+
+  // Make sure that at the end of the operation the current cursor is
+  // shown.
+  function ensureCursorVisible(cm) {
+    resolveScrollToPos(cm);
+    var cur = cm.getCursor(), from = cur, to = cur;
+    if (!cm.options.lineWrapping) {
+      from = cur.ch ? Pos(cur.line, cur.ch - 1) : cur;
+      to = Pos(cur.line, cur.ch + 1);
+    }
+    cm.curOp.scrollToPos = {from: from, to: to, margin: cm.options.cursorScrollMargin, isCursor: true};
+  }
+
+  // When an operation has its scrollToPos property set, and another
+  // scroll action is applied before the end of the operation, this
+  // 'simulates' scrolling that position into view in a cheap way, so
+  // that the effect of intermediate scroll commands is not ignored.
+  function resolveScrollToPos(cm) {
+    var range = cm.curOp.scrollToPos;
+    if (range) {
+      cm.curOp.scrollToPos = null;
+      var from = estimateCoords(cm, range.from), to = estimateCoords(cm, range.to);
+      var sPos = calculateScrollPos(cm, Math.min(from.left, to.left),
+                                    Math.min(from.top, to.top) - range.margin,
+                                    Math.max(from.right, to.right),
+                                    Math.max(from.bottom, to.bottom) + range.margin);
+      cm.scrollTo(sPos.scrollLeft, sPos.scrollTop);
+    }
+  }
+
+  // API UTILITIES
+
+  // Indent the given line. The how parameter can be "smart",
+  // "add"/null, "subtract", or "prev". When aggressive is false
+  // (typically set to true for forced single-line indents), empty
+  // lines are not indented, and places where the mode returns Pass
+  // are left alone.
+  function indentLine(cm, n, how, aggressive) {
+    var doc = cm.doc, state;
+    if (how == null) how = "add";
+    if (how == "smart") {
+      // Fall back to "prev" when the mode doesn't have an indentation
+      // method.
+      if (!doc.mode.indent) how = "prev";
+      else state = getStateBefore(cm, n);
+    }
+
+    var tabSize = cm.options.tabSize;
+    var line = getLine(doc, n), curSpace = countColumn(line.text, null, tabSize);
+    if (line.stateAfter) line.stateAfter = null;
+    var curSpaceString = line.text.match(/^\s*/)[0], indentation;
+    if (!aggressive && !/\S/.test(line.text)) {
+      indentation = 0;
+      how = "not";
+    } else if (how == "smart") {
+      indentation = doc.mode.indent(state, line.text.slice(curSpaceString.length), line.text);
+      if (indentation == Pass || indentation > 150) {
+        if (!aggressive) return;
+        how = "prev";
+      }
+    }
+    if (how == "prev") {
+      if (n > doc.first) indentation = countColumn(getLine(doc, n-1).text, null, tabSize);
+      else indentation = 0;
+    } else if (how == "add") {
+      indentation = curSpace + cm.options.indentUnit;
+    } else if (how == "subtract") {
+      indentation = curSpace - cm.options.indentUnit;
+    } else if (typeof how == "number") {
+      indentation = curSpace + how;
+    }
+    indentation = Math.max(0, indentation);
+
+    var indentString = "", pos = 0;
+    if (cm.options.indentWithTabs)
+      for (var i = Math.floor(indentation / tabSize); i; --i) {pos += tabSize; indentString += "\t";}
+    if (pos < indentation) indentString += spaceStr(indentation - pos);
+
+    if (indentString != curSpaceString) {
+      replaceRange(doc, indentString, Pos(n, 0), Pos(n, curSpaceString.length), "+input");
+      line.stateAfter = null;
+      return true;
+    } else {
+      // Ensure that, if the cursor was in the whitespace at the start
+      // of the line, it is moved to the end of that space.
+      for (var i = 0; i < doc.sel.ranges.length; i++) {
+        var range = doc.sel.ranges[i];
+        if (range.head.line == n && range.head.ch < curSpaceString.length) {
+          var pos = Pos(n, curSpaceString.length);
+          replaceOneSelection(doc, i, new Range(pos, pos));
+          break;
+        }
+      }
+    }
+  }
+
+  // Utility for applying a change to a line by handle or number,
+  // returning the number and optionally registering the line as
+  // changed.
+  function changeLine(doc, handle, changeType, op) {
+    var no = handle, line = handle;
+    if (typeof handle == "number") line = getLine(doc, clipLine(doc, handle));
+    else no = lineNo(handle);
+    if (no == null) return null;
+    if (op(line, no) && doc.cm) regLineChange(doc.cm, no, changeType);
+    return line;
+  }
+
+  // Helper for deleting text near the selection(s), used to implement
+  // backspace, delete, and similar functionality.
+  function deleteNearSelection(cm, compute) {
+    var ranges = cm.doc.sel.ranges, kill = [];
+    // Build up a set of ranges to kill first, merging overlapping
+    // ranges.
+    for (var i = 0; i < ranges.length; i++) {
+      var toKill = compute(ranges[i]);
+      while (kill.length && cmp(toKill.from, lst(kill).to) <= 0) {
+        var replaced = kill.pop();
+        if (cmp(replaced.from, toKill.from) < 0) {
+          toKill.from = replaced.from;
+          break;
+        }
+      }
+      kill.push(toKill);
+    }
+    // Next, remove those actual ranges.
+    runInOp(cm, function() {
+      for (var i = kill.length - 1; i >= 0; i--)
+        replaceRange(cm.doc, "", kill[i].from, kill[i].to, "+delete");
+      ensureCursorVisible(cm);
+    });
+  }
+
+  // Used for horizontal relative motion. Dir is -1 or 1 (left or
+  // right), unit can be "char", "column" (like char, but doesn't
+  // cross line boundaries), "word" (across next word), or "group" (to
+  // the start of next group of word or non-word-non-whitespace
+  // chars). The visually param controls whether, in right-to-left
+  // text, direction 1 means to move towards the next index in the
+  // string, or towards the character to the right of the current
+  // position. The resulting position will have a hitSide=true
+  // property if it reached the end of the document.
+  function findPosH(doc, pos, dir, unit, visually) {
+    var line = pos.line, ch = pos.ch, origDir = dir;
+    var lineObj = getLine(doc, line);
+    var possible = true;
+    function findNextLine() {
+      var l = line + dir;
+      if (l < doc.first || l >= doc.first + doc.size) return (possible = false);
+      line = l;
+      return lineObj = getLine(doc, l);
+    }
+    function moveOnce(boundToLine) {
+      var next = (visually ? moveVisually : moveLogically)(lineObj, ch, dir, true);
+      if (next == null) {
+        if (!boundToLine && findNextLine()) {
+          if (visually) ch = (dir < 0 ? lineRight : lineLeft)(lineObj);
+          else ch = dir < 0 ? lineObj.text.length : 0;
+        } else return (possible = false);
+      } else ch = next;
+      return true;
+    }
+
+    if (unit == "char") moveOnce();
+    else if (unit == "column") moveOnce(true);
+    else if (unit == "word" || unit == "group") {
+      var sawType = null, group = unit == "group";
+      var helper = doc.cm && doc.cm.getHelper(pos, "wordChars");
+      for (var first = true;; first = false) {
+        if (dir < 0 && !moveOnce(!first)) break;
+        var cur = lineObj.text.charAt(ch) || "\n";
+        var type = isWordChar(cur, helper) ? "w"
+          : group && cur == "\n" ? "n"
+          : !group || /\s/.test(cur) ? null
+          : "p";
+        if (group && !first && !type) type = "s";
+        if (sawType && sawType != type) {
+          if (dir < 0) {dir = 1; moveOnce();}
+          break;
+        }
+
+        if (type) sawType = type;
+        if (dir > 0 && !moveOnce(!first)) break;
+      }
+    }
+    var result = skipAtomic(doc, Pos(line, ch), origDir, true);
+    if (!possible) result.hitSide = true;
+    return result;
+  }
+
+  // For relative vertical movement. Dir may be -1 or 1. Unit can be
+  // "page" or "line". The resulting position will have a hitSide=true
+  // property if it reached the end of the document.
+  function findPosV(cm, pos, dir, unit) {
+    var doc = cm.doc, x = pos.left, y;
+    if (unit == "page") {
+      var pageSize = Math.min(cm.display.wrapper.clientHeight, window.innerHeight || document.documentElement.clientHeight);
+      y = pos.top + dir * (pageSize - (dir < 0 ? 1.5 : .5) * textHeight(cm.display));
+    } else if (unit == "line") {
+      y = dir > 0 ? pos.bottom + 3 : pos.top - 3;
+    }
+    for (;;) {
+      var target = coordsChar(cm, x, y);
+      if (!target.outside) break;
+      if (dir < 0 ? y <= 0 : y >= doc.height) { target.hitSide = true; break; }
+      y += dir * 5;
+    }
+    return target;
+  }
+
+  // EDITOR METHODS
+
+  // The publicly visible API. Note that methodOp(f) means
+  // 'wrap f in an operation, performed on its `this` parameter'.
+
+  // This is not the complete set of editor methods. Most of the
+  // methods defined on the Doc type are also injected into
+  // CodeMirror.prototype, for backwards compatibility and
+  // convenience.
+
+  CodeMirror.prototype = {
+    constructor: CodeMirror,
+    focus: function(){window.focus(); this.display.input.focus();},
+
+    setOption: function(option, value) {
+      var options = this.options, old = options[option];
+      if (options[option] == value && option != "mode") return;
+      options[option] = value;
+      if (optionHandlers.hasOwnProperty(option))
+        operation(this, optionHandlers[option])(this, value, old);
+    },
+
+    getOption: function(option) {return this.options[option];},
+    getDoc: function() {return this.doc;},
+
+    addKeyMap: function(map, bottom) {
+      this.state.keyMaps[bottom ? "push" : "unshift"](getKeyMap(map));
+    },
+    removeKeyMap: function(map) {
+      var maps = this.state.keyMaps;
+      for (var i = 0; i < maps.length; ++i)
+        if (maps[i] == map || maps[i].name == map) {
+          maps.splice(i, 1);
+          return true;
+        }
+    },
+
+    addOverlay: methodOp(function(spec, options) {
+      var mode = spec.token ? spec : CodeMirror.getMode(this.options, spec);
+      if (mode.startState) throw new Error("Overlays may not be stateful.");
+      this.state.overlays.push({mode: mode, modeSpec: spec, opaque: options && options.opaque});
+      this.state.modeGen++;
+      regChange(this);
+    }),
+    removeOverlay: methodOp(function(spec) {
+      var overlays = this.state.overlays;
+      for (var i = 0; i < overlays.length; ++i) {
+        var cur = overlays[i].modeSpec;
+        if (cur == spec || typeof spec == "string" && cur.name == spec) {
+          overlays.splice(i, 1);
+          this.state.modeGen++;
+          regChange(this);
+          return;
+        }
+      }
+    }),
+
+    indentLine: methodOp(function(n, dir, aggressive) {
+      if (typeof dir != "string" && typeof dir != "number") {
+        if (dir == null) dir = this.options.smartIndent ? "smart" : "prev";
+        else dir = dir ? "add" : "subtract";
+      }
+      if (isLine(this.doc, n)) indentLine(this, n, dir, aggressive);
+    }),
+    indentSelection: methodOp(function(how) {
+      var ranges = this.doc.sel.ranges, end = -1;
+      for (var i = 0; i < ranges.length; i++) {
+        var range = ranges[i];
+        if (!range.empty()) {
+          var from = range.from(), to = range.to();
+          var start = Math.max(end, from.line);
+          end = Math.min(this.lastLine(), to.line - (to.ch ? 0 : 1)) + 1;
+          for (var j = start; j < end; ++j)
+            indentLine(this, j, how);
+          var newRanges = this.doc.sel.ranges;
+          if (from.ch == 0 && ranges.length == newRanges.length && newRanges[i].from().ch > 0)
+            replaceOneSelection(this.doc, i, new Range(from, newRanges[i].to()), sel_dontScroll);
+        } else if (range.head.line > end) {
+          indentLine(this, range.head.line, how, true);
+          end = range.head.line;
+          if (i == this.doc.sel.primIndex) ensureCursorVisible(this);
+        }
+      }
+    }),
+
+    // Fetch the parser token for a given character. Useful for hacks
+    // that want to inspect the mode state (say, for completion).
+    getTokenAt: function(pos, precise) {
+      return takeToken(this, pos, precise);
+    },
+
+    getLineTokens: function(line, precise) {
+      return takeToken(this, Pos(line), precise, true);
+    },
+
+    getTokenTypeAt: function(pos) {
+      pos = clipPos(this.doc, pos);
+      var styles = getLineStyles(this, getLine(this.doc, pos.line));
+      var before = 0, after = (styles.length - 1) / 2, ch = pos.ch;
+      var type;
+      if (ch == 0) type = styles[2];
+      else for (;;) {
+        var mid = (before + after) >> 1;
+        if ((mid ? styles[mid * 2 - 1] : 0) >= ch) after = mid;
+        else if (styles[mid * 2 + 1] < ch) before = mid + 1;
+        else { type = styles[mid * 2 + 2]; break; }
+      }
+      var cut = type ? type.indexOf("cm-overlay ") : -1;
+      return cut < 0 ? type : cut == 0 ? null : type.slice(0, cut - 1);
+    },
+
+    getModeAt: function(pos) {
+      var mode = this.doc.mode;
+      if (!mode.innerMode) return mode;
+      return CodeMirror.innerMode(mode, this.getTokenAt(pos).state).mode;
+    },
+
+    getHelper: function(pos, type) {
+      return this.getHelpers(pos, type)[0];
+    },
+
+    getHelpers: function(pos, type) {
+      var found = [];
+      if (!helpers.hasOwnProperty(type)) return found;
+      var help = helpers[type], mode = this.getModeAt(pos);
+      if (typeof mode[type] == "string") {
+        if (help[mode[type]]) found.push(help[mode[type]]);
+      } else if (mode[type]) {
+        for (var i = 0; i < mode[type].length; i++) {
+          var val = help[mode[type][i]];
+          if (val) found.push(val);
+        }
+      } else if (mode.helperType && help[mode.helperType]) {
+        found.push(help[mode.helperType]);
+      } else if (help[mode.name]) {
+        found.push(help[mode.name]);
+      }
+      for (var i = 0; i < help._global.length; i++) {
+        var cur = help._global[i];
+        if (cur.pred(mode, this) && indexOf(found, cur.val) == -1)
+          found.push(cur.val);
+      }
+      return found;
+    },
+
+    getStateAfter: function(line, precise) {
+      var doc = this.doc;
+      line = clipLine(doc, line == null ? doc.first + doc.size - 1: line);
+      return getStateBefore(this, line + 1, precise);
+    },
+
+    cursorCoords: function(start, mode) {
+      var pos, range = this.doc.sel.primary();
+      if (start == null) pos = range.head;
+      else if (typeof start == "object") pos = clipPos(this.doc, start);
+      else pos = start ? range.from() : range.to();
+      return cursorCoords(this, pos, mode || "page");
+    },
+
+    charCoords: function(pos, mode) {
+      return charCoords(this, clipPos(this.doc, pos), mode || "page");
+    },
+
+    coordsChar: function(coords, mode) {
+      coords = fromCoordSystem(this, coords, mode || "page");
+      return coordsChar(this, coords.left, coords.top);
+    },
+
+    lineAtHeight: function(height, mode) {
+      height = fromCoordSystem(this, {top: height, left: 0}, mode || "page").top;
+      return lineAtHeight(this.doc, height + this.display.viewOffset);
+    },
+    heightAtLine: function(line, mode) {
+      var end = false, lineObj;
+      if (typeof line == "number") {
+        var last = this.doc.first + this.doc.size - 1;
+        if (line < this.doc.first) line = this.doc.first;
+        else if (line > last) { line = last; end = true; }
+        lineObj = getLine(this.doc, line);
+      } else {
+        lineObj = line;
+      }
+      return intoCoordSystem(this, lineObj, {top: 0, left: 0}, mode || "page").top +
+        (end ? this.doc.height - heightAtLine(lineObj) : 0);
+    },
+
+    defaultTextHeight: function() { return textHeight(this.display); },
+    defaultCharWidth: function() { return charWidth(this.display); },
+
+    setGutterMarker: methodOp(function(line, gutterID, value) {
+      return changeLine(this.doc, line, "gutter", function(line) {
+        var markers = line.gutterMarkers || (line.gutterMarkers = {});
+        markers[gutterID] = value;
+        if (!value && isEmpty(markers)) line.gutterMarkers = null;
+        return true;
+      });
+    }),
+
+    clearGutter: methodOp(function(gutterID) {
+      var cm = this, doc = cm.doc, i = doc.first;
+      doc.iter(function(line) {
+        if (line.gutterMarkers && line.gutterMarkers[gutterID]) {
+          line.gutterMarkers[gutterID] = null;
+          regLineChange(cm, i, "gutter");
+          if (isEmpty(line.gutterMarkers)) line.gutterMarkers = null;
+        }
+        ++i;
+      });
+    }),
+
+    lineInfo: function(line) {
+      if (typeof line == "number") {
+        if (!isLine(this.doc, line)) return null;
+        var n = line;
+        line = getLine(this.doc, line);
+        if (!line) return null;
+      } else {
+        var n = lineNo(line);
+        if (n == null) return null;
+      }
+      return {line: n, handle: line, text: line.text, gutterMarkers: line.gutterMarkers,
+              textClass: line.textClass, bgClass: line.bgClass, wrapClass: line.wrapClass,
+              widgets: line.widgets};
+    },
+
+    getViewport: function() { return {from: this.display.viewFrom, to: this.display.viewTo};},
+
+    addWidget: function(pos, node, scroll, vert, horiz) {
+      var display = this.display;
+      pos = cursorCoords(this, clipPos(this.doc, pos));
+      var top = pos.bottom, left = pos.left;
+      node.style.position = "absolute";
+      node.setAttribute("cm-ignore-events", "true");
+      this.display.input.setUneditable(node);
+      display.sizer.appendChild(node);
+      if (vert == "over") {
+        top = pos.top;
+      } else if (vert == "above" || vert == "near") {
+        var vspace = Math.max(display.wrapper.clientHeight, this.doc.height),
+        hspace = Math.max(display.sizer.clientWidth, display.lineSpace.clientWidth);
+        // Default to positioning above (if specified and possible); otherwise default to positioning below
+        if ((vert == 'above' || pos.bottom + node.offsetHeight > vspace) && pos.top > node.offsetHeight)
+          top = pos.top - node.offsetHeight;
+        else if (pos.bottom + node.offsetHeight <= vspace)
+          top = pos.bottom;
+        if (left + node.offsetWidth > hspace)
+          left = hspace - node.offsetWidth;
+      }
+      node.style.top = top + "px";
+      node.style.left = node.style.right = "";
+      if (horiz == "right") {
+        left = display.sizer.clientWidth - node.offsetWidth;
+        node.style.right = "0px";
+      } else {
+        if (horiz == "left") left = 0;
+        else if (horiz == "middle") left = (display.sizer.clientWidth - node.offsetWidth) / 2;
+        node.style.left = left + "px";
+      }
+      if (scroll)
+        scrollIntoView(this, left, top, left + node.offsetWidth, top + node.offsetHeight);
+    },
+
+    triggerOnKeyDown: methodOp(onKeyDown),
+    triggerOnKeyPress: methodOp(onKeyPress),
+    triggerOnKeyUp: onKeyUp,
+
+    execCommand: function(cmd) {
+      if (commands.hasOwnProperty(cmd))
+        return commands[cmd](this);
+    },
+
+    findPosH: function(from, amount, unit, visually) {
+      var dir = 1;
+      if (amount < 0) { dir = -1; amount = -amount; }
+      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
+        cur = findPosH(this.doc, cur, dir, unit, visually);
+        if (cur.hitSide) break;
+      }
+      return cur;
+    },
+
+    moveH: methodOp(function(dir, unit) {
+      var cm = this;
+      cm.extendSelectionsBy(function(range) {
+        if (cm.display.shift || cm.doc.extend || range.empty())
+          return findPosH(cm.doc, range.head, dir, unit, cm.options.rtlMoveVisually);
+        else
+          return dir < 0 ? range.from() : range.to();
+      }, sel_move);
+    }),
+
+    deleteH: methodOp(function(dir, unit) {
+      var sel = this.doc.sel, doc = this.doc;
+      if (sel.somethingSelected())
+        doc.replaceSelection("", null, "+delete");
+      else
+        deleteNearSelection(this, function(range) {
+          var other = findPosH(doc, range.head, dir, unit, false);
+          return dir < 0 ? {from: other, to: range.head} : {from: range.head, to: other};
+        });
+    }),
+
+    findPosV: function(from, amount, unit, goalColumn) {
+      var dir = 1, x = goalColumn;
+      if (amount < 0) { dir = -1; amount = -amount; }
+      for (var i = 0, cur = clipPos(this.doc, from); i < amount; ++i) {
+        var coords = cursorCoords(this, cur, "div");
+        if (x == null) x = coords.left;
+        else coords.left = x;
+        cur = findPosV(this, coords, dir, unit);
+        if (cur.hitSide) break;
+      }
+      return cur;
+    },
+
+    moveV: methodOp(function(dir, unit) {
+      var cm = this, doc = this.doc, goals = [];
+      var collapse = !cm.display.shift && !doc.extend && doc.sel.somethingSelected();
+      doc.extendSelectionsBy(function(range) {
+        if (collapse)
+          return dir < 0 ? range.from() : range.to();
+        var headPos = cursorCoords(cm, range.head, "div");
+        if (range.goalColumn != null) headPos.left = range.goalColumn;
+        goals.push(headPos.left);
+        var pos = findPosV(cm, headPos, dir, unit);
+        if (unit == "page" && range == doc.sel.primary())
+          addToScrollPos(cm, null, charCoords(cm, pos, "div").top - headPos.top);
+        return pos;
+      }, sel_move);
+      if (goals.length) for (var i = 0; i < doc.sel.ranges.length; i++)
+        doc.sel.ranges[i].goalColumn = goals[i];
+    }),
+
+    // Find the word at the given position (as returned by coordsChar).
+    findWordAt: function(pos) {
+      var doc = this.doc, line = getLine(doc, pos.line).text;
+      var start = pos.ch, end = pos.ch;
+      if (line) {
+        var helper = this.getHelper(pos, "wordChars");
+        if ((pos.xRel < 0 || end == line.length) && start) --start; else ++end;
+        var startChar = line.charAt(start);
+        var check = isWordChar(startChar, helper)
+          ? function(ch) { return isWordChar(ch, helper); }
+          : /\s/.test(startChar) ? function(ch) {return /\s/.test(ch);}
+          : function(ch) {return !/\s/.test(ch) && !isWordChar(ch);};
+        while (start > 0 && check(line.charAt(start - 1))) --start;
+        while (end < line.length && check(line.charAt(end))) ++end;
+      }
+      return new Range(Pos(pos.line, start), Pos(pos.line, end));
+    },
+
+    toggleOverwrite: function(value) {
+      if (value != null && value == this.state.overwrite) return;
+      if (this.state.overwrite = !this.state.overwrite)
+        addClass(this.display.cursorDiv, "CodeMirror-overwrite");
+      else
+        rmClass(this.display.cursorDiv, "CodeMirror-overwrite");
+
+      signal(this, "overwriteToggle", this, this.state.overwrite);
+    },
+    hasFocus: function() { return this.display.input.getField() == activeElt(); },
+
+    scrollTo: methodOp(function(x, y) {
+      if (x != null || y != null) resolveScrollToPos(this);
+      if (x != null) this.curOp.scrollLeft = x;
+      if (y != null) this.curOp.scrollTop = y;
+    }),
+    getScrollInfo: function() {
+      var scroller = this.display.scroller;
+      return {left: scroller.scrollLeft, top: scroller.scrollTop,
+              height: scroller.scrollHeight - scrollGap(this) - this.display.barHeight,
+              width: scroller.scrollWidth - scrollGap(this) - this.display.barWidth,
+              clientHeight: displayHeight(this), clientWidth: displayWidth(this)};
+    },
+
+    scrollIntoView: methodOp(function(range, margin) {
+      if (range == null) {
+        range = {from: this.doc.sel.primary().head, to: null};
+        if (margin == null) margin = this.options.cursorScrollMargin;
+      } else if (typeof range == "number") {
+        range = {from: Pos(range, 0), to: null};
+      } else if (range.from == null) {
+        range = {from: range, to: null};
+      }
+      if (!range.to) range.to = range.from;
+      range.margin = margin || 0;
+
+      if (range.from.line != null) {
+        resolveScrollToPos(this);
+        this.curOp.scrollToPos = range;
+      } else {
+        var sPos = calculateScrollPos(this, Math.min(range.from.left, range.to.left),
+                                      Math.min(range.from.top, range.to.top) - range.margin,
+                                      Math.max(range.from.right, range.to.right),
+                                      Math.max(range.from.bottom, range.to.bottom) + range.margin);
+        this.scrollTo(sPos.scrollLeft, sPos.scrollTop);
+      }
+    }),
+
+    setSize: methodOp(function(width, height) {
+      var cm = this;
+      function interpret(val) {
+        return typeof val == "number" || /^\d+$/.test(String(val)) ? val + "px" : val;
+      }
+      if (width != null) cm.display.wrapper.style.width = interpret(width);
+      if (height != null) cm.display.wrapper.style.height = interpret(height);
+      if (cm.options.lineWrapping) clearLineMeasurementCache(this);
+      var lineNo = cm.display.viewFrom;
+      cm.doc.iter(lineNo, cm.display.viewTo, function(line) {
+        if (line.widgets) for (var i = 0; i < line.widgets.length; i++)
+          if (line.widgets[i].noHScroll) { regLineChange(cm, lineNo, "widget"); break; }
+        ++lineNo;
+      });
+      cm.curOp.forceUpdate = true;
+      signal(cm, "refresh", this);
+    }),
+
+    operation: function(f){return runInOp(this, f);},
+
+    refresh: methodOp(function() {
+      var oldHeight = this.display.cachedTextHeight;
+      regChange(this);
+      this.curOp.forceUpdate = true;
+      clearCaches(this);
+      this.scrollTo(this.doc.scrollLeft, this.doc.scrollTop);
+      updateGutterSpace(this);
+      if (oldHeight == null || Math.abs(oldHeight - textHeight(this.display)) > .5)
+        estimateLineHeights(this);
+      signal(this, "refresh", this);
+    }),
+
+    swapDoc: methodOp(function(doc) {
+      var old = this.doc;
+      old.cm = null;
+      attachDoc(this, doc);
+      clearCaches(this);
+      this.display.input.reset();
+      this.scrollTo(doc.scrollLeft, doc.scrollTop);
+      this.curOp.forceScroll = true;
+      signalLater(this, "swapDoc", this, old);
+      return old;
+    }),
+
+    getInputField: function(){return this.display.input.getField();},
+    getWrapperElement: function(){return this.display.wrapper;},
+    getScrollerElement: function(){return this.display.scroller;},
+    getGutterElement: function(){return this.display.gutters;}
+  };
+  eventMixin(CodeMirror);
+
+  // OPTION DEFAULTS
+
+  // The default configuration options.
+  var defaults = CodeMirror.defaults = {};
+  // Functions to run when options are changed.
+  var optionHandlers = CodeMirror.optionHandlers = {};
+
+  function option(name, deflt, handle, notOnInit) {
+    CodeMirror.defaults[name] = deflt;
+    if (handle) optionHandlers[name] =
+      notOnInit ? function(cm, val, old) {if (old != Init) handle(cm, val, old);} : handle;
+  }
+
+  // Passed to option handlers when there is no old value.
+  var Init = CodeMirror.Init = {toString: function(){return "CodeMirror.Init";}};
+
+  // These two are, on init, called from the constructor because they
+  // have to be initialized before the editor can start at all.
+  option("value", "", function(cm, val) {
+    cm.setValue(val);
+  }, true);
+  option("mode", null, function(cm, val) {
+    cm.doc.modeOption = val;
+    loadMode(cm);
+  }, true);
+
+  option("indentUnit", 2, loadMode, true);
+  option("indentWithTabs", false);
+  option("smartIndent", true);
+  option("tabSize", 4, function(cm) {
+    resetModeState(cm);
+    clearCaches(cm);
+    regChange(cm);
+  }, true);
+  option("specialChars", /[\t\u0000-\u0019\u00ad\u200b-\u200f\u2028\u2029\ufeff]/g, function(cm, val, old) {
+    cm.state.specialChars = new RegExp(val.source + (val.test("\t") ? "" : "|\t"), "g");
+    if (old != CodeMirror.Init) cm.refresh();
+  });
+  option("specialCharPlaceholder", defaultSpecialCharPlaceholder, function(cm) {cm.refresh();}, true);
+  option("electricChars", true);
+  option("inputStyle", mobile ? "contenteditable" : "textarea", function() {
+    throw new Error("inputStyle can not (yet) be changed in a running editor"); // FIXME
+  }, true);
+  option("rtlMoveVisually", !windows);
+  option("wholeLineUpdateBefore", true);
+
+  option("theme", "default", function(cm) {
+    themeChanged(cm);
+    guttersChanged(cm);
+  }, true);
+  option("keyMap", "default", function(cm, val, old) {
+    var next = getKeyMap(val);
+    var prev = old != CodeMirror.Init && getKeyMap(old);
+    if (prev && prev.detach) prev.detach(cm, next);
+    if (next.attach) next.attach(cm, prev || null);
+  });
+  option("extraKeys", null);
+
+  option("lineWrapping", false, wrappingChanged, true);
+  option("gutters", [], function(cm) {
+    setGuttersForLineNumbers(cm.options);
+    guttersChanged(cm);
+  }, true);
+  option("fixedGutter", true, function(cm, val) {
+    cm.display.gutters.style.left = val ? compensateForHScroll(cm.display) + "px" : "0";
+    cm.refresh();
+  }, true);
+  option("coverGutterNextToScrollbar", false, function(cm) {updateScrollbars(cm);}, true);
+  option("scrollbarStyle", "native", function(cm) {
+    initScrollbars(cm);
+    updateScrollbars(cm);
+    cm.display.scrollbars.setScrollTop(cm.doc.scrollTop);
+    cm.display.scrollbars.setScrollLeft(cm.doc.scrollLeft);
+  }, true);
+  option("lineNumbers", false, function(cm) {
+    setGuttersForLineNumbers(cm.options);
+    guttersChanged(cm);
+  }, true);
+  option("firstLineNumber", 1, guttersChanged, true);
+  option("lineNumberFormatter", function(integer) {return integer;}, guttersChanged, true);
+  option("showCursorWhenSelecting", false, updateSelection, true);
+
+  option("resetSelectionOnContextMenu", true);
+  option("lineWiseCopyCut", true);
+
+  option("readOnly", false, function(cm, val) {
+    if (val == "nocursor") {
+      onBlur(cm);
+      cm.display.input.blur();
+      cm.display.disabled = true;
+    } else {
+      cm.display.disabled = false;
+      if (!val) cm.display.input.reset();
+    }
+  });
+  option("disableInput", false, function(cm, val) {if (!val) cm.display.input.reset();}, true);
+  option("dragDrop", true, dragDropChanged);
+
+  option("cursorBlinkRate", 530);
+  option("cursorScrollMargin", 0);
+  option("cursorHeight", 1, updateSelection, true);
+  option("singleCursorHeightPerLine", true, updateSelection, true);
+  option("workTime", 100);
+  option("workDelay", 100);
+  option("flattenSpans", true, resetModeState, true);
+  option("addModeClass", false, resetModeState, true);
+  option("pollInterval", 100);
+  option("undoDepth", 200, function(cm, val){cm.doc.history.undoDepth = val;});
+  option("historyEventDelay", 1250);
+  option("viewportMargin", 10, function(cm){cm.refresh();}, true);
+  option("maxHighlightLength", 10000, resetModeState, true);
+  option("moveInputWithCursor", true, function(cm, val) {
+    if (!val) cm.display.input.resetPosition();
+  });
+
+  option("tabindex", null, function(cm, val) {
+    cm.display.input.getField().tabIndex = val || "";
+  });
+  option("autofocus", null);
+
+  // MODE DEFINITION AND QUERYING
+
+  // Known modes, by name and by MIME
+  var modes = CodeMirror.modes = {}, mimeModes = CodeMirror.mimeModes = {};
+
+  // Extra arguments are stored as the mode's dependencies, which is
+  // used by (legacy) mechanisms like loadmode.js to automatically
+  // load a mode. (Preferred mechanism is the require/define calls.)
+  CodeMirror.defineMode = function(name, mode) {
+    if (!CodeMirror.defaults.mode && name != "null") CodeMirror.defaults.mode = name;
+    if (arguments.length > 2)
+      mode.dependencies = Array.prototype.slice.call(arguments, 2);
+    modes[name] = mode;
+  };
+
+  CodeMirror.defineMIME = function(mime, spec) {
+    mimeModes[mime] = spec;
+  };
+
+  // Given a MIME type, a {name, ...options} config object, or a name
+  // string, return a mode config object.
+  CodeMirror.resolveMode = function(spec) {
+    if (typeof spec == "string" && mimeModes.hasOwnProperty(spec)) {
+      spec = mimeModes[spec];
+    } else if (spec && typeof spec.name == "string" && mimeModes.hasOwnProperty(spec.name)) {
+      var found = mimeModes[spec.name];
+      if (typeof found == "string") found = {name: found};
+      spec = createObj(found, spec);
+      spec.name = found.name;
+    } else if (typeof spec == "string" && /^[\w\-]+\/[\w\-]+\+xml$/.test(spec)) {
+      return CodeMirror.resolveMode("application/xml");
+    }
+    if (typeof spec == "string") return {name: spec};
+    else return spec || {name: "null"};
+  };
+
+  // Given a mode spec (anything that resolveMode accepts), find and
+  // initialize an actual mode object.
+  CodeMirror.getMode = function(options, spec) {
+    var spec = CodeMirror.resolveMode(spec);
+    var mfactory = modes[spec.name];
+    if (!mfactory) return CodeMirror.getMode(options, "text/plain");
+    var modeObj = mfactory(options, spec);
+    if (modeExtensions.hasOwnProperty(spec.name)) {
+      var exts = modeExtensions[spec.name];
+      for (var prop in exts) {
+        if (!exts.hasOwnProperty(prop)) continue;
+        if (modeObj.hasOwnProperty(prop)) modeObj["_" + prop] = modeObj[prop];
+        modeObj[prop] = exts[prop];
+      }
+    }
+    modeObj.name = spec.name;
+    if (spec.helperType) modeObj.helperType = spec.helperType;
+    if (spec.modeProps) for (var prop in spec.modeProps)
+      modeObj[prop] = spec.modeProps[prop];
+
+    return modeObj;
+  };
+
+  // Minimal default mode.
+  CodeMirror.defineMode("null", function() {
+    return {token: function(stream) {stream.skipToEnd();}};
+  });
+  CodeMirror.defineMIME("text/plain", "null");
+
+  // This can be used to attach properties to mode objects from
+  // outside the actual mode definition.
+  var modeExtensions = CodeMirror.modeExtensions = {};
+  CodeMirror.extendMode = function(mode, properties) {
+    var exts = modeExtensions.hasOwnProperty(mode) ? modeExtensions[mode] : (modeExtensions[mode] = {});
+    copyObj(properties, exts);
+  };
+
+  // EXTENSIONS
+
+  CodeMirror.defineExtension = function(name, func) {
+    CodeMirror.prototype[name] = func;
+  };
+  CodeMirror.defineDocExtension = function(name, func) {
+    Doc.prototype[name] = func;
+  };
+  CodeMirror.defineOption = option;
+
+  var initHooks = [];
+  CodeMirror.defineInitHook = function(f) {initHooks.push(f);};
+
+  var helpers = CodeMirror.helpers = {};
+  CodeMirror.registerHelper = function(type, name, value) {
+    if (!helpers.hasOwnProperty(type)) helpers[type] = CodeMirror[type] = {_global: []};
+    helpers[type][name] = value;
+  };
+  CodeMirror.registerGlobalHelper = function(type, name, predicate, value) {
+    CodeMirror.registerHelper(type, name, value);
+    helpers[type]._global.push({pred: predicate, val: value});
+  };
+
+  // MODE STATE HANDLING
+
+  // Utility functions for working with state. Exported because nested
+  // modes need to do this for their inner modes.
+
+  var copyState = CodeMirror.copyState = function(mode, state) {
+    if (state === true) return state;
+    if (mode.copyState) return mode.copyState(state);
+    var nstate = {};
+    for (var n in state) {
+      var val = state[n];
+      if (val instanceof Array) val = val.concat([]);
+      nstate[n] = val;
+    }
+    return nstate;
+  };
+
+  var startState = CodeMirror.startState = function(mode, a1, a2) {
+    return mode.startState ? mode.startState(a1, a2) : true;
+  };
+
+  // Given a mode and a state (for that mode), find the inner mode and
+  // state at the position that the state refers to.
+  CodeMirror.innerMode = function(mode, state) {
+    while (mode.innerMode) {
+      var info = mode.innerMode(state);
+      if (!info || info.mode == mode) break;
+      state = info.state;
+      mode = info.mode;
+    }
+    return info || {mode: mode, state: state};
+  };
+
+  // STANDARD COMMANDS
+
+  // Commands are parameter-less actions that can be performed on an
+  // editor, mostly used for keybindings.
+  var commands = CodeMirror.commands = {
+    selectAll: function(cm) {cm.setSelection(Pos(cm.firstLine(), 0), Pos(cm.lastLine()), sel_dontScroll);},
+    singleSelection: function(cm) {
+      cm.setSelection(cm.getCursor("anchor"), cm.getCursor("head"), sel_dontScroll);
+    },
+    killLine: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        if (range.empty()) {
+          var len = getLine(cm.doc, range.head.line).text.length;
+          if (range.head.ch == len && range.head.line < cm.lastLine())
+            return {from: range.head, to: Pos(range.head.line + 1, 0)};
+          else
+            return {from: range.head, to: Pos(range.head.line, len)};
+        } else {
+          return {from: range.from(), to: range.to()};
+        }
+      });
+    },
+    deleteLine: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        return {from: Pos(range.from().line, 0),
+                to: clipPos(cm.doc, Pos(range.to().line + 1, 0))};
+      });
+    },
+    delLineLeft: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        return {from: Pos(range.from().line, 0), to: range.from()};
+      });
+    },
+    delWrappedLineLeft: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        var leftPos = cm.coordsChar({left: 0, top: top}, "div");
+        return {from: leftPos, to: range.from()};
+      });
+    },
+    delWrappedLineRight: function(cm) {
+      deleteNearSelection(cm, function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        var rightPos = cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
+        return {from: range.from(), to: rightPos };
+      });
+    },
+    undo: function(cm) {cm.undo();},
+    redo: function(cm) {cm.redo();},
+    undoSelection: function(cm) {cm.undoSelection();},
+    redoSelection: function(cm) {cm.redoSelection();},
+    goDocStart: function(cm) {cm.extendSelection(Pos(cm.firstLine(), 0));},
+    goDocEnd: function(cm) {cm.extendSelection(Pos(cm.lastLine()));},
+    goLineStart: function(cm) {
+      cm.extendSelectionsBy(function(range) { return lineStart(cm, range.head.line); },
+                            {origin: "+move", bias: 1});
+    },
+    goLineStartSmart: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        return lineStartSmart(cm, range.head);
+      }, {origin: "+move", bias: 1});
+    },
+    goLineEnd: function(cm) {
+      cm.extendSelectionsBy(function(range) { return lineEnd(cm, range.head.line); },
+                            {origin: "+move", bias: -1});
+    },
+    goLineRight: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        return cm.coordsChar({left: cm.display.lineDiv.offsetWidth + 100, top: top}, "div");
+      }, sel_move);
+    },
+    goLineLeft: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        return cm.coordsChar({left: 0, top: top}, "div");
+      }, sel_move);
+    },
+    goLineLeftSmart: function(cm) {
+      cm.extendSelectionsBy(function(range) {
+        var top = cm.charCoords(range.head, "div").top + 5;
+        var pos = cm.coordsChar({left: 0, top: top}, "div");
+        if (pos.ch < cm.getLine(pos.line).search(/\S/)) return lineStartSmart(cm, range.head);
+        return pos;
+      }, sel_move);
+    },
+    goLineUp: function(cm) {cm.moveV(-1, "line");},
+    goLineDown: function(cm) {cm.moveV(1, "line");},
+    goPageUp: function(cm) {cm.moveV(-1, "page");},
+    goPageDown: function(cm) {cm.moveV(1, "page");},
+    goCharLeft: function(cm) {cm.moveH(-1, "char");},
+    goCharRight: function(cm) {cm.moveH(1, "char");},
+    goColumnLeft: function(cm) {cm.moveH(-1, "column");},
+    goColumnRight: function(cm) {cm.moveH(1, "column");},
+    goWordLeft: function(cm) {cm.moveH(-1, "word");},
+    goGroupRight: function(cm) {cm.moveH(1, "group");},
+    goGroupLeft: function(cm) {cm.moveH(-1, "group");},
+    goWordRight: function(cm) {cm.moveH(1, "word");},
+    delCharBefore: function(cm) {cm.deleteH(-1, "char");},
+    delCharAfter: function(cm) {cm.deleteH(1, "char");},
+    delWordBefore: function(cm) {cm.deleteH(-1, "word");},
+    delWordAfter: function(cm) {cm.deleteH(1, "word");},
+    delGroupBefore: function(cm) {cm.deleteH(-1, "group");},
+    delGroupAfter: function(cm) {cm.deleteH(1, "group");},
+    indentAuto: function(cm) {cm.indentSelection("smart");},
+    indentMore: function(cm) {cm.indentSelection("add");},
+    indentLess: function(cm) {cm.indentSelection("subtract");},
+    insertTab: function(cm) {cm.replaceSelection("\t");},
+    insertSoftTab: function(cm) {
+      var spaces = [], ranges = cm.listSelections(), tabSize = cm.options.tabSize;
+      for (var i = 0; i < ranges.length; i++) {
+        var pos = ranges[i].from();
+        var col = countColumn(cm.getLine(pos.line), pos.ch, tabSize);
+        spaces.push(new Array(tabSize - col % tabSize + 1).join(" "));
+      }
+      cm.replaceSelections(spaces);
+    },
+    defaultTab: function(cm) {
+      if (cm.somethingSelected()) cm.indentSelection("add");
+      else cm.execCommand("insertTab");
+    },
+    transposeChars: function(cm) {
+      runInOp(cm, function() {
+        var ranges = cm.listSelections(), newSel = [];
+        for (var i = 0; i < ranges.length; i++) {
+          var cur = ranges[i].head, line = getLine(cm.doc, cur.line).text;
+          if (line) {
+            if (cur.ch == line.length) cur = new Pos(cur.line, cur.ch - 1);
+            if (cur.ch > 0) {
+              cur = new Pos(cur.line, cur.ch + 1);
+              cm.replaceRange(line.charAt(cur.ch - 1) + line.charAt(cur.ch - 2),
+                              Pos(cur.line, cur.ch - 2), cur, "+transpose");
+            } else if (cur.line > cm.doc.first) {
+              var prev = getLine(cm.doc, cur.line - 1).text;
+              if (prev)
+                cm.replaceRange(line.charAt(0) + "\n" + prev.charAt(prev.length - 1),
+                                Pos(cur.line - 1, prev.length - 1), Pos(cur.line, 1), "+transpose");
+            }
+          }
+          newSel.push(new Range(cur, cur));
+        }
+        cm.setSelections(newSel);
+      });
+    },
+    newlineAndIndent: function(cm) {
+      runInOp(cm, function() {
+        var len = cm.listSelections().length;
+        for (var i = 0; i < len; i++) {
+          var range = cm.listSelections()[i];
+          cm.replaceRange("\n", range.anchor, range.head, "+input");
+          cm.indentLine(range.from().line + 1, null, true);
+          ensureCursorVisible(cm);
+        }
+      });
+    },
+    toggleOverwrite: function(cm) {cm.toggleOverwrite();}
+  };
+
+
+  // STANDARD KEYMAPS
+
+  var keyMap = CodeMirror.keyMap = {};
+
+  keyMap.basic = {
+    "Left": "goCharLeft", "Right": "goCharRight", "Up": "goLineUp", "Down": "goLineDown",
+    "End": "goLineEnd", "Home": "goLineStartSmart", "PageUp": "goPageUp", "PageDown": "goPageDown",
+    "Delete": "delCharAfter", "Backspace": "delCharBefore", "Shift-Backspace": "delCharBefore",
+    "Tab": "defaultTab", "Shift-Tab": "indentAuto",
+    "Enter": "newlineAndIndent", "Insert": "toggleOverwrite",
+    "Esc": "singleSelection"
+  };
+  // Note that the save and find-related commands aren't defined by
+  // default. User code or addons can define them. Unknown commands
+  // are simply ignored.
+  keyMap.pcDefault = {
+    "Ctrl-A": "selectAll", "Ctrl-D": "deleteLine", "Ctrl-Z": "undo", "Shift-Ctrl-Z": "redo", "Ctrl-Y": "redo",
+    "Ctrl-Home": "goDocStart", "Ctrl-End": "goDocEnd", "Ctrl-Up": "goLineUp", "Ctrl-Down": "goLineDown",
+    "Ctrl-Left": "goGroupLeft", "Ctrl-Right": "goGroupRight", "Alt-Left": "goLineStart", "Alt-Right": "goLineEnd",
+    "Ctrl-Backspace": "delGroupBefore", "Ctrl-Delete": "delGroupAfter", "Ctrl-S": "save", "Ctrl-F": "find",
+    "Ctrl-G": "findNext", "Shift-Ctrl-G": "findPrev", "Shift-Ctrl-F": "replace", "Shift-Ctrl-R": "replaceAll",
+    "Ctrl-[": "indentLess", "Ctrl-]": "indentMore",
+    "Ctrl-U": "undoSelection", "Shift-Ctrl-U": "redoSelection", "Alt-U": "redoSelection",
+    fallthrough: "basic"
+  };
+  // Very basic readline/emacs-style bindings, which are standard on Mac.
+  keyMap.emacsy = {
+    "Ctrl-F": "goCharRight", "Ctrl-B": "goCharLeft", "Ctrl-P": "goLineUp", "Ctrl-N": "goLineDown",
+    "Alt-F": "goWordRight", "Alt-B": "goWordLeft", "Ctrl-A": "goLineStart", "Ctrl-E": "goLineEnd",
+    "Ctrl-V": "goPageDown", "Shift-Ctrl-V": "goPageUp", "Ctrl-D": "delCharAfter", "Ctrl-H": "delCharBefore",
+    "Alt-D": "delWordAfter", "Alt-Backspace": "delWordBefore", "Ctrl-K": "killLine", "Ctrl-T": "transposeChars"
+  };
+  keyMap.macDefault = {
+    "Cmd-A": "selectAll", "Cmd-D": "deleteLine", "Cmd-Z": "undo", "Shift-Cmd-Z": "redo", "Cmd-Y": "redo",
+    "Cmd-Home": "goDocStart", "Cmd-Up": "goDocStart", "Cmd-End": "goDocEnd", "Cmd-Down": "goDocEnd", "Alt-Left": "goGroupLeft",
+    "Alt-Right": "goGroupRight", "Cmd-Left": "goLineLeft", "Cmd-Right": "goLineRight", "Alt-Backspace": "delGroupBefore",
+    "Ctrl-Alt-Backspace": "delGroupAfter", "Alt-Delete": "delGroupAfter", "Cmd-S": "save", "Cmd-F": "find",
+    "Cmd-G": "findNext", "Shift-Cmd-G": "findPrev", "Cmd-Alt-F": "replace", "Shift-Cmd-Alt-F": "replaceAll",
+    "Cmd-[": "indentLess", "Cmd-]": "indentMore", "Cmd-Backspace": "delWrappedLineLeft", "Cmd-Delete": "delWrappedLineRight",
+    "Cmd-U": "undoSelection", "Shift-Cmd-U": "redoSelection", "Ctrl-Up": "goDocStart", "Ctrl-Down": "goDocEnd",
+    fallthrough: ["basic", "emacsy"]
+  };
+  keyMap["default"] = mac ? keyMap.macDefault : keyMap.pcDefault;
+
+  // KEYMAP DISPATCH
+
+  function normalizeKeyName(name) {
+    var parts = name.split(/-(?!$)/), name = parts[parts.length - 1];
+    var alt, ctrl, shift, cmd;
+    for (var i = 0; i < parts.length - 1; i++) {
+      var mod = parts[i];
+      if (/^(cmd|meta|m)$/i.test(mod)) cmd = true;
+      else if (/^a(lt)?$/i.test(mod)) alt = true;
+      else if (/^(c|ctrl|control)$/i.test(mod)) ctrl = true;
+      else if (/^s(hift)$/i.test(mod)) shift = true;
+      else throw new Error("Unrecognized modifier name: " + mod);
+    }
+    if (alt) name = "Alt-" + name;
+    if (ctrl) name = "Ctrl-" + name;
+    if (cmd) name = "Cmd-" + name;
+    if (shift) name = "Shift-" + name;
+    return name;
+  }
+
+  // This is a kludge to keep keymaps mostly working as raw objects
+  // (backwards compatibility) while at the same time support features
+  // like normalization and multi-stroke key bindings. It compiles a
+  // new normalized keymap, and then updates the old object to reflect
+  // this.
+  CodeMirror.normalizeKeyMap = function(keymap) {
+    var copy = {};
+    for (var keyname in keymap) if (keymap.hasOwnProperty(keyname)) {
+      var value = keymap[keyname];
+      if (/^(name|fallthrough|(de|at)tach)$/.test(keyname)) continue;
+      if (value == "...") { delete keymap[keyname]; continue; }
+
+      var keys = map(keyname.split(" "), normalizeKeyName);
+      for (var i = 0; i < keys.length; i++) {
+        var val, name;
+        if (i == keys.length - 1) {
+          name = keyname;
+          val = value;
+        } else {
+          name = keys.slice(0, i + 1).join(" ");
+          val = "...";
+        }
+        var prev = copy[name];
+        if (!prev) copy[name] = val;
+        else if (prev != val) throw new Error("Inconsistent bindings for " + name);
+      }
+      delete keymap[keyname];
+    }
+    for (var prop in copy) keymap[prop] = copy[prop];
+    return keymap;
+  };
+
+  var lookupKey = CodeMirror.lookupKey = function(key, map, handle, context) {
+    map = getKeyMap(map);
+    var found = map.call ? map.call(key, context) : map[key];
+    if (found === false) return "nothing";
+    if (found === "...") return "multi";
+    if (found != null && handle(found)) return "handled";
+
+    if (map.fallthrough) {
+      if (Object.prototype.toString.call(map.fallthrough) != "[object Array]")
+        return lookupKey(key, map.fallthrough, handle, context);
+      for (var i = 0; i < map.fallthrough.length; i++) {
+        var result = lookupKey(key, map.fallthrough[i], handle, context);
+        if (result) return result;
+      }
+    }
+  };
+
+  // Modifier key presses don't count as 'real' key presses for the
+  // purpose of keymap fallthrough.
+  var isModifierKey = CodeMirror.isModifierKey = function(value) {
+    var name = typeof value == "string" ? value : keyNames[value.keyCode];
+    return name == "Ctrl" || name == "Alt" || name == "Shift" || name == "Mod";
+  };
+
+  // Look up the name of a key as indicated by an event object.
+  var keyName = CodeMirror.keyName = function(event, noShift) {
+    if (presto && event.keyCode == 34 && event["char"]) return false;
+    var base = keyNames[event.keyCode], name = base;
+    if (name == null || event.altGraphKey) return false;
+    if (event.altKey && base != "Alt") name = "Alt-" + name;
+    if ((flipCtrlCmd ? event.metaKey : event.ctrlKey) && base != "Ctrl") name = "Ctrl-" + name;
+    if ((flipCtrlCmd ? event.ctrlKey : event.metaKey) && base != "Cmd") name = "Cmd-" + name;
+    if (!noShift && event.shiftKey && base != "Shift") name = "Shift-" + name;
+    return name;
+  };
+
+  function getKeyMap(val) {
+    return typeof val == "string" ? keyMap[val] : val;
+  }
+
+  // FROMTEXTAREA
+
+  CodeMirror.fromTextArea = function(textarea, options) {
+    options = options ? copyObj(options) : {};
+    options.value = textarea.value;
+    if (!options.tabindex && textarea.tabIndex)
+      options.tabindex = textarea.tabIndex;
+    if (!options.placeholder && textarea.placeholder)
+      options.placeholder = textarea.placeholder;
+    // Set autofocus to true if this textarea is focused, or if it has
+    // autofocus and no other element is focused.
+    if (options.autofocus == null) {
+      var hasFocus = activeElt();
+      options.autofocus = hasFocus == textarea ||
+        textarea.getAttribute("autofocus") != null && hasFocus == document.body;
+    }
+
+    function save() {textarea.value = cm.getValue();}
+    if (textarea.form) {
+      on(textarea.form, "submit", save);
+      // Deplorable hack to make the submit method do the right thing.
+      if (!options.leaveSubmitMethodAlone) {
+        var form = textarea.form, realSubmit = form.submit;
+        try {
+          var wrappedSubmit = form.submit = function() {
+            save();
+            form.submit = realSubmit;
+            form.submit();
+            form.submit = wrappedSubmit;
+          };
+        } catch(e) {}
+      }
+    }
+
+    options.finishInit = function(cm) {
+      cm.save = save;
+      cm.getTextArea = function() { return textarea; };
+      cm.toTextArea = function() {
+        cm.toTextArea = isNaN; // Prevent this from being ran twice
+        save();
+        textarea.parentNode.removeChild(cm.getWrapperElement());
+        textarea.style.display = "";
+        if (textarea.form) {
+          off(textarea.form, "submit", save);
+          if (typeof textarea.form.submit == "function")
+            textarea.form.submit = realSubmit;
+        }
+      };
+    };
+
+    textarea.style.display = "none";
+    var cm = CodeMirror(function(node) {
+      textarea.parentNode.insertBefore(node, textarea.nextSibling);
+    }, options);
+    return cm;
+  };
+
+  // STRING STREAM
+
+  // Fed to the mode parsers, provides helper functions to make
+  // parsers more succinct.
+
+  var StringStream = CodeMirror.StringStream = function(string, tabSize) {
+    this.pos = this.start = 0;
+    this.string = string;
+    this.tabSize = tabSize || 8;
+    this.lastColumnPos = this.lastColumnValue = 0;
+    this.lineStart = 0;
+  };
+
+  StringStream.prototype = {
+    eol: function() {return this.pos >= this.string.length;},
+    sol: function() {return this.pos == this.lineStart;},
+    peek: function() {return this.string.charAt(this.pos) || undefined;},
+    next: function() {
+      if (this.pos < this.string.length)
+        return this.string.charAt(this.pos++);
+    },
+    eat: function(match) {
+      var ch = this.string.charAt(this.pos);
+      if (typeof match == "string") var ok = ch == match;
+      else var ok = ch && (match.test ? match.test(ch) : match(ch));
+      if (ok) {++this.pos; return ch;}
+    },
+    eatWhile: function(match) {
+      var start = this.pos;
+      while (this.eat(match)){}
+      return this.pos > start;
+    },
+    eatSpace: function() {
+      var start = this.pos;
+      while (/[\s\u00a0]/.test(this.string.charAt(this.pos))) ++this.pos;
+      return this.pos > start;
+    },
+    skipToEnd: function() {this.pos = this.string.length;},
+    skipTo: function(ch) {
+      var found = this.string.indexOf(ch, this.pos);
+      if (found > -1) {this.pos = found; return true;}
+    },
+    backUp: function(n) {this.pos -= n;},
+    column: function() {
+      if (this.lastColumnPos < this.start) {
+        this.lastColumnValue = countColumn(this.string, this.start, this.tabSize, this.lastColumnPos, this.lastColumnValue);
+        this.lastColumnPos = this.start;
+      }
+      return this.lastColumnValue - (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+    },
+    indentation: function() {
+      return countColumn(this.string, null, this.tabSize) -
+        (this.lineStart ? countColumn(this.string, this.lineStart, this.tabSize) : 0);
+    },
+    match: function(pattern, consume, caseInsensitive) {
+      if (typeof pattern == "string") {
+        var cased = function(str) {return caseInsensitive ? str.toLowerCase() : str;};
+        var substr = this.string.substr(this.pos, pattern.length);
+        if (cased(substr) == cased(pattern)) {
+          if (consume !== false) this.pos += pattern.length;
+          return true;
+        }
+      } else {
+        var match = this.string.slice(this.pos).match(pattern);
+        if (match && match.index > 0) return null;
+        if (match && consume !== false) this.pos += match[0].length;
+        return match;
+      }
+    },
+    current: function(){return this.string.slice(this.start, this.pos);},
+    hideFirstChars: function(n, inner) {
+      this.lineStart += n;
+      try { return inner(); }
+      finally { this.lineStart -= n; }
+    }
+  };
+
+  // TEXTMARKERS
+
+  // Created with markText and setBookmark methods. A TextMarker is a
+  // handle that can be used to clear or find a marked position in the
+  // document. Line objects hold arrays (markedSpans) containing
+  // {from, to, marker} object pointing to such marker objects, and
+  // indicating that such a marker is present on that line. Multiple
+  // lines may point to the same marker when it spans across lines.
+  // The spans will have null for their from/to properties when the
+  // marker continues beyond the start/end of the line. Markers have
+  // links back to the lines they currently touch.
+
+  var nextMarkerId = 0;
+
+  var TextMarker = CodeMirror.TextMarker = function(doc, type) {
+    this.lines = [];
+    this.type = type;
+    this.doc = doc;
+    this.id = ++nextMarkerId;
+  };
+  eventMixin(TextMarker);
+
+  // Clear the marker.
+  TextMarker.prototype.clear = function() {
+    if (this.explicitlyCleared) return;
+    var cm = this.doc.cm, withOp = cm && !cm.curOp;
+    if (withOp) startOperation(cm);
+    if (hasHandler(this, "clear")) {
+      var found = this.find();
+      if (found) signalLater(this, "clear", found.from, found.to);
+    }
+    var min = null, max = null;
+    for (var i = 0; i < this.lines.length; ++i) {
+      var line = this.lines[i];
+      var span = getMarkedSpanFor(line.markedSpans, this);
+      if (cm && !this.collapsed) regLineChange(cm, lineNo(line), "text");
+      else if (cm) {
+        if (span.to != null) max = lineNo(line);
+        if (span.from != null) min = lineNo(line);
+      }
+      line.markedSpans = removeMarkedSpan(line.markedSpans, span);
+      if (span.from == null && this.collapsed && !lineIsHidden(this.doc, line) && cm)
+        updateLineHeight(line, textHeight(cm.display));
+    }
+    if (cm && this.collapsed && !cm.options.lineWrapping) for (var i = 0; i < this.lines.length; ++i) {
+      var visual = visualLine(this.lines[i]), len = lineLength(visual);
+      if (len > cm.display.maxLineLength) {
+        cm.display.maxLine = visual;
+        cm.display.maxLineLength = len;
+        cm.display.maxLineChanged = true;
+      }
+    }
+
+    if (min != null && cm && this.collapsed) regChange(cm, min, max + 1);
+    this.lines.length = 0;
+    this.explicitlyCleared = true;
+    if (this.atomic && this.doc.cantEdit) {
+      this.doc.cantEdit = false;
+      if (cm) reCheckSelection(cm.doc);
+    }
+    if (cm) signalLater(cm, "markerCleared", cm, this);
+    if (withOp) endOperation(cm);
+    if (this.parent) this.parent.clear();
+  };
+
+  // Find the position of the marker in the document. Returns a {from,
+  // to} object by default. Side can be passed to get a specific side
+  // -- 0 (both), -1 (left), or 1 (right). When lineObj is true, the
+  // Pos objects returned contain a line object, rather than a line
+  // number (used to prevent looking up the same line twice).
+  TextMarker.prototype.find = function(side, lineObj) {
+    if (side == null && this.type == "bookmark") side = 1;
+    var from, to;
+    for (var i = 0; i < this.lines.length; ++i) {
+      var line = this.lines[i];
+      var span = getMarkedSpanFor(line.markedSpans, this);
+      if (span.from != null) {
+        from = Pos(lineObj ? line : lineNo(line), span.from);
+        if (side == -1) return from;
+      }
+      if (span.to != null) {
+        to = Pos(lineObj ? line : lineNo(line), span.to);
+        if (side == 1) return to;
+      }
+    }
+    return from && {from: from, to: to};
+  };
+
+  // Signals that the marker's widget changed, and surrounding layout
+  // should be recomputed.
+  TextMarker.prototype.changed = function() {
+    var pos = this.find(-1, true), widget = this, cm = this.doc.cm;
+    if (!pos || !cm) return;
+    runInOp(cm, function() {
+      var line = pos.line, lineN = lineNo(pos.line);
+      var view = findViewForLine(cm, lineN);
+      if (view) {
+        clearLineMeasurementCacheFor(view);
+        cm.curOp.selectionChanged = cm.curOp.forceUpdate = true;
+      }
+      cm.curOp.updateMaxLine = true;
+      if (!lineIsHidden(widget.doc, line) && widget.height != null) {
+        var oldHeight = widget.height;
+        widget.height = null;
+        var dHeight = widgetHeight(widget) - oldHeight;
+        if (dHeight)
+          updateLineHeight(line, line.height + dHeight);
+      }
+    });
+  };
+
+  TextMarker.prototype.attachLine = function(line) {
+    if (!this.lines.length && this.doc.cm) {
+      var op = this.doc.cm.curOp;
+      if (!op.maybeHiddenMarkers || indexOf(op.maybeHiddenMarkers, this) == -1)
+        (op.maybeUnhiddenMarkers || (op.maybeUnhiddenMarkers = [])).push(this);
+    }
+    this.lines.push(line);
+  };
+  TextMarker.prototype.detachLine = function(line) {
+    this.lines.splice(indexOf(this.lines, line), 1);
+    if (!this.lines.length && this.doc.cm) {
+      var op = this.doc.cm.curOp;
+      (op.maybeHiddenMarkers || (op.maybeHiddenMarkers = [])).push(this);
+    }
+  };
+
+  // Collapsed markers have unique ids, in order to be able to order
+  // them, which is needed for uniquely determining an outer marker
+  // when they overlap (they may nest, but not partially overlap).
+  var nextMarkerId = 0;
+
+  // Create a marker, wire it up to the right lines, and
+  function markText(doc, from, to, options, type) {
+    // Shared markers (across linked documents) are handled separately
+    // (markTextShared will call out to this again, once per
+    // document).
+    if (options && options.shared) return markTextShared(doc, from, to, options, type);
+    // Ensure we are in an operation.
+    if (doc.cm && !doc.cm.curOp) return operation(doc.cm, markText)(doc, from, to, options, type);
+
+    var marker = new TextMarker(doc, type), diff = cmp(from, to);
+    if (options) copyObj(options, marker, false);
+    // Don't connect empty markers unless clearWhenEmpty is false
+    if (diff > 0 || diff == 0 && marker.clearWhenEmpty !== false)
+      return marker;
+    if (marker.replacedWith) {
+      // Showing up as a widget implies collapsed (widget replaces text)
+      marker.collapsed = true;
+      marker.widgetNode = elt("span", [marker.replacedWith], "CodeMirror-widget");
+      if (!options.handleMouseEvents) marker.widgetNode.setAttribute("cm-ignore-events", "true");
+      if (options.insertLeft) marker.widgetNode.insertLeft = true;
+    }
+    if (marker.collapsed) {
+      if (conflictingCollapsedRange(doc, from.line, from, to, marker) ||
+          from.line != to.line && conflictingCollapsedRange(doc, to.line, from, to, marker))
+        throw new Error("Inserting collapsed marker partially overlapping an existing one");
+      sawCollapsedSpans = true;
+    }
+
+    if (marker.addToHistory)
+      addChangeToHistory(doc, {from: from, to: to, origin: "markText"}, doc.sel, NaN);
+
+    var curLine = from.line, cm = doc.cm, updateMaxLine;
+    doc.iter(curLine, to.line + 1, function(line) {
+      if (cm && marker.collapsed && !cm.options.lineWrapping && visualLine(line) == cm.display.maxLine)
+        updateMaxLine = true;
+      if (marker.collapsed && curLine != from.line) updateLineHeight(line, 0);
+      addMarkedSpan(line, new MarkedSpan(marker,
+                                         curLine == from.line ? from.ch : null,
+                                         curLine == to.line ? to.ch : null));
+      ++curLine;
+    });
+    // lineIsHidden depends on the presence of the spans, so needs a second pass
+    if (marker.collapsed) doc.iter(from.line, to.line + 1, function(line) {
+      if (lineIsHidden(doc, line)) updateLineHeight(line, 0);
+    });
+
+    if (marker.clearOnEnter) on(marker, "beforeCursorEnter", function() { marker.clear(); });
+
+    if (marker.readOnly) {
+      sawReadOnlySpans = true;
+      if (doc.history.done.length || doc.history.undone.length)
+        doc.clearHistory();
+    }
+    if (marker.collapsed) {
+      marker.id = ++nextMarkerId;
+      marker.atomic = true;
+    }
+    if (cm) {
+      // Sync editor state
+      if (updateMaxLine) cm.curOp.updateMaxLine = true;
+      if (marker.collapsed)
+        regChange(cm, from.line, to.line + 1);
+      else if (marker.className || marker.title || marker.startStyle || marker.endStyle || marker.css)
+        for (var i = from.line; i <= to.line; i++) regLineChange(cm, i, "text");
+      if (marker.atomic) reCheckSelection(cm.doc);
+      signalLater(cm, "markerAdded", cm, marker);
+    }
+    return marker;
+  }
+
+  // SHARED TEXTMARKERS
+
+  // A shared marker spans multiple linked documents. It is
+  // implemented as a meta-marker-object controlling multiple normal
+  // markers.
+  var SharedTextMarker = CodeMirror.SharedTextMarker = function(markers, primary) {
+    this.markers = markers;
+    this.primary = primary;
+    for (var i = 0; i < markers.length; ++i)
+      markers[i].parent = this;
+  };
+  eventMixin(SharedTextMarker);
+
+  SharedTextMarker.prototype.clear = function() {
+    if (this.explicitlyCleared) return;
+    this.explicitlyCleared = true;
+    for (var i = 0; i < this.markers.length; ++i)
+      this.markers[i].clear();
+    signalLater(this, "clear");
+  };
+  SharedTextMarker.prototype.find = function(side, lineObj) {
+    return this.primary.find(side, lineObj);
+  };
+
+  function markTextShared(doc, from, to, options, type) {
+    options = copyObj(options);
+    options.shared = false;
+    var markers = [markText(doc, from, to, options, type)], primary = markers[0];
+    var widget = options.widgetNode;
+    linkedDocs(doc, function(doc) {
+      if (widget) options.widgetNode = widget.cloneNode(true);
+      markers.push(markText(doc, clipPos(doc, from), clipPos(doc, to), options, type));
+      for (var i = 0; i < doc.linked.length; ++i)
+        if (doc.linked[i].isParent) return;
+      primary = lst(markers);
+    });
+    return new SharedTextMarker(markers, primary);
+  }
+
+  function findSharedMarkers(doc) {
+    return doc.findMarks(Pos(doc.first, 0), doc.clipPos(Pos(doc.lastLine())),
+                         function(m) { return m.parent; });
+  }
+
+  function copySharedMarkers(doc, markers) {
+    for (var i = 0; i < markers.length; i++) {
+      var marker = markers[i], pos = marker.find();
+      var mFrom = doc.clipPos(pos.from), mTo = doc.clipPos(pos.to);
+      if (cmp(mFrom, mTo)) {
+        var subMark = markText(doc, mFrom, mTo, marker.primary, marker.primary.type);
+        marker.markers.push(subMark);
+        subMark.parent = marker;
+      }
+    }
+  }
+
+  function detachSharedMarkers(markers) {
+    for (var i = 0; i < markers.length; i++) {
+      var marker = markers[i], linked = [marker.primary.doc];;
+      linkedDocs(marker.primary.doc, function(d) { linked.push(d); });
+      for (var j = 0; j < marker.markers.length; j++) {
+        var subMarker = marker.markers[j];
+        if (indexOf(linked, subMarker.doc) == -1) {
+          subMarker.parent = null;
+          marker.markers.splice(j--, 1);
+        }
+      }
+    }
+  }
+
+  // TEXTMARKER SPANS
+
+  function MarkedSpan(marker, from, to) {
+    this.marker = marker;
+    this.from = from; this.to = to;
+  }
+
+  // Search an array of spans for a span matching the given marker.
+  function getMarkedSpanFor(spans, marker) {
+    if (spans) for (var i = 0; i < spans.length; ++i) {
+      var span = spans[i];
+      if (span.marker == marker) return span;
+    }
+  }
+  // Remove a span from an array, returning undefined if no spans are
+  // left (we don't store arrays for lines without spans).
+  function removeMarkedSpan(spans, span) {
+    for (var r, i = 0; i < spans.length; ++i)
+      if (spans[i] != span) (r || (r = [])).push(spans[i]);
+    return r;
+  }
+  // Add a span to a line.
+  function addMarkedSpan(line, span) {
+    line.markedSpans = line.markedSpans ? line.markedSpans.concat([span]) : [span];
+    span.marker.attachLine(line);
+  }
+
+  // Used for the algorithm that adjusts markers for a change in the
+  // document. These functions cut an array of spans at a given
+  // character position, returning an array of remaining chunks (or
+  // undefined if nothing remains).
+  function markedSpansBefore(old, startCh, isInsert) {
+    if (old) for (var i = 0, nw; i < old.length; ++i) {
+      var span = old[i], marker = span.marker;
+      var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= startCh : span.from < startCh);
+      if (startsBefore || span.from == startCh && marker.type == "bookmark" && (!isInsert || !span.marker.insertLeft)) {
+        var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= startCh : span.to > startCh);
+        (nw || (nw = [])).push(new MarkedSpan(marker, span.from, endsAfter ? null : span.to));
+      }
+    }
+    return nw;
+  }
+  function markedSpansAfter(old, endCh, isInsert) {
+    if (old) for (var i = 0, nw; i < old.length; ++i) {
+      var span = old[i], marker = span.marker;
+      var endsAfter = span.to == null || (marker.inclusiveRight ? span.to >= endCh : span.to > endCh);
+      if (endsAfter || span.from == endCh && marker.type == "bookmark" && (!isInsert || span.marker.insertLeft)) {
+        var startsBefore = span.from == null || (marker.inclusiveLeft ? span.from <= endCh : span.from < endCh);
+        (nw || (nw = [])).push(new MarkedSpan(marker, startsBefore ? null : span.from - endCh,
+                                              span.to == null ? null : span.to - endCh));
+      }
+    }
+    return nw;
+  }
+
+  // Given a change object, compute the new set of marker spans that
+  // cover the line in which the change took place. Removes spans
+  // entirely within the change, reconnects spans belonging to the
+  // same marker that appear on both sides of the change, and cuts off
+  // spans partially within the change. Returns an array of span
+  // arrays with one element for each line in (after) the change.
+  function stretchSpansOverChange(doc, change) {
+    if (change.full) return null;
+    var oldFirst = isLine(doc, change.from.line) && getLine(doc, change.from.line).markedSpans;
+    var oldLast = isLine(doc, change.to.line) && getLine(doc, change.to.line).markedSpans;
+    if (!oldFirst && !oldLast) return null;
+
+    var startCh = change.from.ch, endCh = change.to.ch, isInsert = cmp(change.from, change.to) == 0;
+    // Get the spans that 'stick out' on both sides
+    var first = markedSpansBefore(oldFirst, startCh, isInsert);
+    var last = markedSpansAfter(oldLast, endCh, isInsert);
+
+    // Next, merge those two ends
+    var sameLine = change.text.length == 1, offset = lst(change.text).length + (sameLine ? startCh : 0);
+    if (first) {
+      // Fix up .to properties of first
+      for (var i = 0; i < first.length; ++i) {
+        var span = first[i];
+        if (span.to == null) {
+          var found = getMarkedSpanFor(last, span.marker);
+          if (!found) span.to = startCh;
+          else if (sameLine) span.to = found.to == null ? null : found.to + offset;
+        }
+      }
+    }
+    if (last) {
+      // Fix up .from in last (or move them into first in case of sameLine)
+      for (var i = 0; i < last.length; ++i) {
+        var span = last[i];
+        if (span.to != null) span.to += offset;
+        if (span.from == null) {
+          var found = getMarkedSpanFor(first, span.marker);
+          if (!found) {
+            span.from = offset;
+            if (sameLine) (first || (first = [])).push(span);
+          }
+        } else {
+          span.from += offset;
+          if (sameLine) (first || (first = [])).push(span);
+        }
+      }
+    }
+    // Make sure we didn't create any zero-length spans
+    if (first) first = clearEmptySpans(first);
+    if (last && last != first) last = clearEmptySpans(last);
+
+    var newMarkers = [first];
+    if (!sameLine) {
+      // Fill gap with whole-line-spans
+      var gap = change.text.length - 2, gapMarkers;
+      if (gap > 0 && first)
+        for (var i = 0; i < first.length; ++i)
+          if (first[i].to == null)
+            (gapMarkers || (gapMarkers = [])).push(new MarkedSpan(first[i].marker, null, null));
+      for (var i = 0; i < gap; ++i)
+        newMarkers.push(gapMarkers);
+      newMarkers.push(last);
+    }
+    return newMarkers;
+  }
+
+  // Remove spans that are empty and don't have a clearWhenEmpty
+  // option of false.
+  function clearEmptySpans(spans) {
+    for (var i = 0; i < spans.length; ++i) {
+      var span = spans[i];
+      if (span.from != null && span.from == span.to && span.marker.clearWhenEmpty !== false)
+        spans.splice(i--, 1);
+    }
+    if (!spans.length) return null;
+    return spans;
+  }
+
+  // Used for un/re-doing changes from the history. Combines the
+  // result of computing the existing spans with the set of spans that
+  // existed in the history (so that deleting around a span and then
+  // undoing brings back the span).
+  function mergeOldSpans(doc, change) {
+    var old = getOldSpans(doc, change);
+    var stretched = stretchSpansOverChange(doc, change);
+    if (!old) return stretched;
+    if (!stretched) return old;
+
+    for (var i = 0; i < old.length; ++i) {
+      var oldCur = old[i], stretchCur = stretched[i];
+      if (oldCur && stretchCur) {
+        spans: for (var j = 0; j < stretchCur.length; ++j) {
+          var span = stretchCur[j];
+          for (var k = 0; k < oldCur.length; ++k)
+            if (oldCur[k].marker == span.marker) continue spans;
+          oldCur.push(span);
+        }
+      } else if (stretchCur) {
+        old[i] = stretchCur;
+      }
+    }
+    return old;
+  }
+
+  // Used to 'clip' out readOnly ranges when making a change.
+  function removeReadOnlyRanges(doc, from, to) {
+    var markers = null;
+    doc.iter(from.line, to.line + 1, function(line) {
+      if (line.markedSpans) for (var i = 0; i < line.markedSpans.length; ++i) {
+        var mark = line.markedSpans[i].marker;
+        if (mark.readOnly && (!markers || indexOf(markers, mark) == -1))
+          (markers || (markers = [])).push(mark);
+      }
+    });
+    if (!markers) return null;
+    var parts = [{from: from, to: to}];
+    for (var i = 0; i < markers.length; ++i) {
+      var mk = markers[i], m = mk.find(0);
+      for (var j = 0; j < parts.length; ++j) {
+        var p = parts[j];
+        if (cmp(p.to, m.from) < 0 || cmp(p.from, m.to) > 0) continue;
+        var newParts = [j, 1], dfrom = cmp(p.from, m.from), dto = cmp(p.to, m.to);
+        if (dfrom < 0 || !mk.inclusiveLeft && !dfrom)
+          newParts.push({from: p.from, to: m.from});
+        if (dto > 0 || !mk.inclusiveRight && !dto)
+          newParts.push({from: m.to, to: p.to});
+        parts.splice.apply(parts, newParts);
+        j += newParts.length - 1;
+      }
+    }
+    return parts;
+  }
+
+  // Connect or disconnect spans from a line.
+  function detachMarkedSpans(line) {
+    var spans = line.markedSpans;
+    if (!spans) return;
+    for (var i = 0; i < spans.length; ++i)
+      spans[i].marker.detachLine(line);
+    line.markedSpans = null;
+  }
+  function attachMarkedSpans(line, spans) {
+    if (!spans) return;
+    for (var i = 0; i < spans.length; ++i)
+      spans[i].marker.attachLine(line);
+    line.markedSpans = spans;
+  }
+
+  // Helpers used when computing which overlapping collapsed span
+  // counts as the larger one.
+  function extraLeft(marker) { return marker.inclusiveLeft ? -1 : 0; }
+  function extraRight(marker) { return marker.inclusiveRight ? 1 : 0; }
+
+  // Returns a number indicating which of two overlapping collapsed
+  // spans is larger (and thus includes the other). Falls back to
+  // comparing ids when the spans cover exactly the same range.
+  function compareCollapsedMarkers(a, b) {
+    var lenDiff = a.lines.length - b.lines.length;
+    if (lenDiff != 0) return lenDiff;
+    var aPos = a.find(), bPos = b.find();
+    var fromCmp = cmp(aPos.from, bPos.from) || extraLeft(a) - extraLeft(b);
+    if (fromCmp) return -fromCmp;
+    var toCmp = cmp(aPos.to, bPos.to) || extraRight(a) - extraRight(b);
+    if (toCmp) return toCmp;
+    return b.id - a.id;
+  }
+
+  // Find out whether a line ends or starts in a collapsed span. If
+  // so, return the marker for that span.
+  function collapsedSpanAtSide(line, start) {
+    var sps = sawCollapsedSpans && line.markedSpans, found;
+    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
+      sp = sps[i];
+      if (sp.marker.collapsed && (start ? sp.from : sp.to) == null &&
+          (!found || compareCollapsedMarkers(found, sp.marker) < 0))
+        found = sp.marker;
+    }
+    return found;
+  }
+  function collapsedSpanAtStart(line) { return collapsedSpanAtSide(line, true); }
+  function collapsedSpanAtEnd(line) { return collapsedSpanAtSide(line, false); }
+
+  // Test whether there exists a collapsed span that partially
+  // overlaps (covers the start or end, but not both) of a new span.
+  // Such overlap is not allowed.
+  function conflictingCollapsedRange(doc, lineNo, from, to, marker) {
+    var line = getLine(doc, lineNo);
+    var sps = sawCollapsedSpans && line.markedSpans;
+    if (sps) for (var i = 0; i < sps.length; ++i) {
+      var sp = sps[i];
+      if (!sp.marker.collapsed) continue;
+      var found = sp.marker.find(0);
+      var fromCmp = cmp(found.from, from) || extraLeft(sp.marker) - extraLeft(marker);
+      var toCmp = cmp(found.to, to) || extraRight(sp.marker) - extraRight(marker);
+      if (fromCmp >= 0 && toCmp <= 0 || fromCmp <= 0 && toCmp >= 0) continue;
+      if (fromCmp <= 0 && (cmp(found.to, from) > 0 || (sp.marker.inclusiveRight && marker.inclusiveLeft)) ||
+          fromCmp >= 0 && (cmp(found.from, to) < 0 || (sp.marker.inclusiveLeft && marker.inclusiveRight)))
+        return true;
+    }
+  }
+
+  // A visual line is a line as drawn on the screen. Folding, for
+  // example, can cause multiple logical lines to appear on the same
+  // visual line. This finds the start of the visual line that the
+  // given line is part of (usually that is the line itself).
+  function visualLine(line) {
+    var merged;
+    while (merged = collapsedSpanAtStart(line))
+      line = merged.find(-1, true).line;
+    return line;
+  }
+
+  // Returns an array of logical lines that continue the visual line
+  // started by the argument, or undefined if there are no such lines.
+  function visualLineContinued(line) {
+    var merged, lines;
+    while (merged = collapsedSpanAtEnd(line)) {
+      line = merged.find(1, true).line;
+      (lines || (lines = [])).push(line);
+    }
+    return lines;
+  }
+
+  // Get the line number of the start of the visual line that the
+  // given line number is part of.
+  function visualLineNo(doc, lineN) {
+    var line = getLine(doc, lineN), vis = visualLine(line);
+    if (line == vis) return lineN;
+    return lineNo(vis);
+  }
+  // Get the line number of the start of the next visual line after
+  // the given line.
+  function visualLineEndNo(doc, lineN) {
+    if (lineN > doc.lastLine()) return lineN;
+    var line = getLine(doc, lineN), merged;
+    if (!lineIsHidden(doc, line)) return lineN;
+    while (merged = collapsedSpanAtEnd(line))
+      line = merged.find(1, true).line;
+    return lineNo(line) + 1;
+  }
+
+  // Compute whether a line is hidden. Lines count as hidden when they
+  // are part of a visual line that starts with another line, or when
+  // they are entirely covered by collapsed, non-widget span.
+  function lineIsHidden(doc, line) {
+    var sps = sawCollapsedSpans && line.markedSpans;
+    if (sps) for (var sp, i = 0; i < sps.length; ++i) {
+      sp = sps[i];
+      if (!sp.marker.collapsed) continue;
+      if (sp.from == null) return true;
+      if (sp.marker.widgetNode) continue;
+      if (sp.from == 0 && sp.marker.inclusiveLeft && lineIsHiddenInner(doc, line, sp))
+        return true;
+    }
+  }
+  function lineIsHiddenInner(doc, line, span) {
+    if (span.to == null) {
+      var end = span.marker.find(1, true);
+      return lineIsHiddenInner(doc, end.line, getMarkedSpanFor(end.line.markedSpans, span.marker));
+    }
+    if (span.marker.inclusiveRight && span.to == line.text.length)
+      return true;
+    for (var sp, i = 0; i < line.markedSpans.length; ++i) {
+      sp = line.markedSpans[i];
+      if (sp.marker.collapsed && !sp.marker.widgetNode && sp.from == span.to &&
+          (sp.to == null || sp.to != span.from) &&
+          (sp.marker.inclusiveLeft || span.marker.inclusiveRight) &&
+          lineIsHiddenInner(doc, line, sp)) return true;
+    }
+  }
+
+  // LINE WIDGETS
+
+  // Line widgets are block elements displayed above or below a line.
+
+  var LineWidget = CodeMirror.LineWidget = function(doc, node, options) {
+    if (options) for (var opt in options) if (options.hasOwnProperty(opt))
+      this[opt] = options[opt];
+    this.doc = doc;
+    this.node = node;
+  };
+  eventMixin(LineWidget);
+
+  function adjustScrollWhenAboveVisible(cm, line, diff) {
+    if (heightAtLine(line) < ((cm.curOp && cm.curOp.scrollTop) || cm.doc.scrollTop))
+      addToScrollPos(cm, null, diff);
+  }
+
+  LineWidget.prototype.clear = function() {
+    var cm = this.doc.cm, ws = this.line.widgets, line = this.line, no = lineNo(line);
+    if (no == null || !ws) return;
+    for (var i = 0; i < ws.length; ++i) if (ws[i] == this) ws.splice(i--, 1);
+    if (!ws.length) line.widgets = null;
+    var height = widgetHeight(this);
+    updateLineHeight(line, Math.max(0, line.height - height));
+    if (cm) runInOp(cm, function() {
+      adjustScrollWhenAboveVisible(cm, line, -height);
+      regLineChange(cm, no, "widget");
+    });
+  };
+  LineWidget.prototype.changed = function() {
+    var oldH = this.height, cm = this.doc.cm, line = this.line;
+    this.height = null;
+    var diff = widgetHeight(this) - oldH;
+    if (!diff) return;
+    updateLineHeight(line, line.height + diff);
+    if (cm) runInOp(cm, function() {
+      cm.curOp.forceUpdate = true;
+      adjustScrollWhenAboveVisible(cm, line, diff);
+    });
+  };
+
+  function widgetHeight(widget) {
+    if (widget.height != null) return widget.height;
+    var cm = widget.doc.cm;
+    if (!cm) return 0;
+    if (!contains(document.body, widget.node)) {
+      var parentStyle = "position: relative;";
+      if (widget.coverGutter)
+        parentStyle += "margin-left: -" + cm.display.gutters.offsetWidth + "px;";
+      if (widget.noHScroll)
+        parentStyle += "width: " + cm.display.wrapper.clientWidth + "px;";
+      removeChildrenAndAdd(cm.display.measure, elt("div", [widget.node], null, parentStyle));
+    }
+    return widget.height = widget.node.offsetHeight;
+  }
+
+  function addLineWidget(doc, handle, node, options) {
+    var widget = new LineWidget(doc, node, options);
+    var cm = doc.cm;
+    if (cm && widget.noHScroll) cm.display.alignWidgets = true;
+    changeLine(doc, handle, "widget", function(line) {
+      var widgets = line.widgets || (line.widgets = []);
+      if (widget.insertAt == null) widgets.push(widget);
+      else widgets.splice(Math.min(widgets.length - 1, Math.max(0, widget.insertAt)), 0, widget);
+      widget.line = line;
+      if (cm && !lineIsHidden(doc, line)) {
+        var aboveVisible = heightAtLine(line) < doc.scrollTop;
+        updateLineHeight(line, line.height + widgetHeight(widget));
+        if (aboveVisible) addToScrollPos(cm, null, widget.height);
+        cm.curOp.forceUpdate = true;
+      }
+      return true;
+    });
+    return widget;
+  }
+
+  // LINE DATA STRUCTURE
+
+  // Line objects. These hold state related to a line, including
+  // highlighting info (the styles array).
+  var Line = CodeMirror.Line = function(text, markedSpans, estimateHeight) {
+    this.text = text;
+    attachMarkedSpans(this, markedSpans);
+    this.height = estimateHeight ? estimateHeight(this) : 1;
+  };
+  eventMixin(Line);
+  Line.prototype.lineNo = function() { return lineNo(this); };
+
+  // Change the content (text, markers) of a line. Automatically
+  // invalidates cached information and tries to re-estimate the
+  // line's height.
+  function updateLine(line, text, markedSpans, estimateHeight) {
+    line.text = text;
+    if (line.stateAfter) line.stateAfter = null;
+    if (line.styles) line.styles = null;
+    if (line.order != null) line.order = null;
+    detachMarkedSpans(line);
+    attachMarkedSpans(line, markedSpans);
+    var estHeight = estimateHeight ? estimateHeight(line) : 1;
+    if (estHeight != line.height) updateLineHeight(line, estHeight);
+  }
+
+  // Detach a line from the document tree and its markers.
+  function cleanUpLine(line) {
+    line.parent = null;
+    detachMarkedSpans(line);
+  }
+
+  function extractLineClasses(type, output) {
+    if (type) for (;;) {
+      var lineClass = type.match(/(?:^|\s+)line-(background-)?(\S+)/);
+      if (!lineClass) break;
+      type = type.slice(0, lineClass.index) + type.slice(lineClass.index + lineClass[0].length);
+      var prop = lineClass[1] ? "bgClass" : "textClass";
+      if (output[prop] == null)
+        output[prop] = lineClass[2];
+      else if (!(new RegExp("(?:^|\s)" + lineClass[2] + "(?:$|\s)")).test(output[prop]))
+        output[prop] += " " + lineClass[2];
+    }
+    return type;
+  }
+
+  function callBlankLine(mode, state) {
+    if (mode.blankLine) return mode.blankLine(state);
+    if (!mode.innerMode) return;
+    var inner = CodeMirror.innerMode(mode, state);
+    if (inner.mode.blankLine) return inner.mode.blankLine(inner.state);
+  }
+
+  function readToken(mode, stream, state, inner) {
+    for (var i = 0; i < 10; i++) {
+      if (inner) inner[0] = CodeMirror.innerMode(mode, state).mode;
+      var style = mode.token(stream, state);
+      if (stream.pos > stream.start) return style;
+    }
+    throw new Error("Mode " + mode.name + " failed to advance stream.");
+  }
+
+  // Utility for getTokenAt and getLineTokens
+  function takeToken(cm, pos, precise, asArray) {
+    function getObj(copy) {
+      return {start: stream.start, end: stream.pos,
+              string: stream.current(),
+              type: style || null,
+              state: copy ? copyState(doc.mode, state) : state};
+    }
+
+    var doc = cm.doc, mode = doc.mode, style;
+    pos = clipPos(doc, pos);
+    var line = getLine(doc, pos.line), state = getStateBefore(cm, pos.line, precise);
+    var stream = new StringStream(line.text, cm.options.tabSize), tokens;
+    if (asArray) tokens = [];
+    while ((asArray || stream.pos < pos.ch) && !stream.eol()) {
+      stream.start = stream.pos;
+      style = readToken(mode, stream, state);
+      if (asArray) tokens.push(getObj(true));
+    }
+    return asArray ? tokens : getObj();
+  }
+
+  // Run the given mode's parser over a line, calling f for each token.
+  function runMode(cm, text, mode, state, f, lineClasses, forceToEnd) {
+    var flattenSpans = mode.flattenSpans;
+    if (flattenSpans == null) flattenSpans = cm.options.flattenSpans;
+    var curStart = 0, curStyle = null;
+    var stream = new StringStream(text, cm.options.tabSize), style;
+    var inner = cm.options.addModeClass && [null];
+    if (text == "") extractLineClasses(callBlankLine(mode, state), lineClasses);
+    while (!stream.eol()) {
+      if (stream.pos > cm.options.maxHighlightLength) {
+        flattenSpans = false;
+        if (forceToEnd) processLine(cm, text, state, stream.pos);
+        stream.pos = text.length;
+        style = null;
+      } else {
+        style = extractLineClasses(readToken(mode, stream, state, inner), lineClasses);
+      }
+      if (inner) {
+        var mName = inner[0].name;
+        if (mName) style = "m-" + (style ? mName + " " + style : mName);
+      }
+      if (!flattenSpans || curStyle != style) {
+        while (curStart < stream.start) {
+          curStart = Math.min(stream.start, curStart + 50000);
+          f(curStart, curStyle);
+        }
+        curStyle = style;
+      }
+      stream.start = stream.pos;
+    }
+    while (curStart < stream.pos) {
+      // Webkit seems to refuse to render text nodes longer than 57444 characters
+      var pos = Math.min(stream.pos, curStart + 50000);
+      f(pos, curStyle);
+      curStart = pos;
+    }
+  }
+
+  // Compute a style array (an array starting with a mode generation
+  // -- for invalidation -- followed by pairs of end positions and
+  // style strings), which is used to highlight the tokens on the
+  // line.
+  function highlightLine(cm, line, state, forceToEnd) {
+    // A styles array always starts with a number identifying the
+    // mode/overlays that it is based on (for easy invalidation).
+    var st = [cm.state.modeGen], lineClasses = {};
+    // Compute the base array of styles
+    runMode(cm, line.text, cm.doc.mode, state, function(end, style) {
+      st.push(end, style);
+    }, lineClasses, forceToEnd);
+
+    // Run overlays, adjust style array.
+    for (var o = 0; o < cm.state.overlays.length; ++o) {
+      var overlay = cm.state.overlays[o], i = 1, at = 0;
+      runMode(cm, line.text, overlay.mode, true, function(end, style) {
+        var start = i;
+        // Ensure there's a token end at the current position, and that i points at it
+        while (at < end) {
+          var i_end = st[i];
+          if (i_end > end)
+            st.splice(i, 1, end, st[i+1], i_end);
+          i += 2;
+          at = Math.min(end, i_end);
+        }
+        if (!style) return;
+        if (overlay.opaque) {
+          st.splice(start, i - start, end, "cm-overlay " + style);
+          i = start + 2;
+        } else {
+          for (; start < i; start += 2) {
+            var cur = st[start+1];
+            st[start+1] = (cur ? cur + " " : "") + "cm-overlay " + style;
+          }
+        }
+      }, lineClasses);
+    }
+
+    return {styles: st, classes: lineClasses.bgClass || lineClasses.textClass ? lineClasses : null};
+  }
+
+  function getLineStyles(cm, line, updateFrontier) {
+    if (!line.styles || line.styles[0] != cm.state.modeGen) {
+      var result = highlightLine(cm, line, line.stateAfter = getStateBefore(cm, lineNo(line)));
+      line.styles = result.styles;
+      if (result.classes) line.styleClasses = result.classes;
+      else if (line.styleClasses) line.styleClasses = null;
+      if (updateFrontier === cm.doc.frontier) cm.doc.frontier++;
+    }
+    return line.styles;
+  }
+
+  // Lightweight form of highlight -- proceed over this line and
+  // update state, but don't save a style array. Used for lines that
+  // aren't currently visible.
+  function processLine(cm, text, state, startAt) {
+    var mode = cm.doc.mode;
+    var stream = new StringStream(text, cm.options.tabSize);
+    stream.start = stream.pos = startAt || 0;
+    if (text == "") callBlankLine(mode, state);
+    while (!stream.eol() && stream.pos <= cm.options.maxHighlightLength) {
+      readToken(mode, stream, state);
+      stream.start = stream.pos;
+    }
+  }
+
+  // Convert a style as returned by a mode (either null, or a string
+  // containing one or more styles) to a CSS style. This is cached,
+  // and also looks for line-wide styles.
+  var styleToClassCache = {}, styleToClassCacheWithMode = {};
+  function interpretTokenStyle(style, options) {
+    if (!style || /^\s*$/.test(style)) return null;
+    var cache = options.addModeClass ? styleToClassCacheWithMode : styleToClassCache;
+    return cache[style] ||
+      (cache[style] = style.replace(/\S+/g, "cm-$&"));
+  }
+
+  // Render the DOM representation of the text of a line. Also builds
+  // up a 'line map', which points at the DOM nodes that represent
+  // specific stretches of text, and is used by the measuring code.
+  // The returned object contains the DOM node, this map, and
+  // information about line-wide styles that were set by the mode.
+  function buildLineContent(cm, lineView) {
+    // The padding-right forces the element to have a 'border', which
+    // is needed on Webkit to be able to get line-level bounding
+    // rectangles for it (in measureChar).
+    var content = elt("span", null, null, webkit ? "padding-right: .1px" : null);
+    var builder = {pre: elt("pre", [content]), content: content,
+                   col: 0, pos: 0, cm: cm,
+                   splitSpaces: (ie || webkit) && cm.getOption("lineWrapping")};
+    lineView.measure = {};
+
+    // Iterate over the logical lines that make up this visual line.
+    for (var i = 0; i <= (lineView.rest ? lineView.rest.length : 0); i++) {
+      var line = i ? lineView.rest[i - 1] : lineView.line, order;
+      builder.pos = 0;
+      builder.addToken = buildToken;
+      // Optionally wire in some hacks into the token-rendering
+      // algorithm, to deal with browser quirks.
+      if (hasBadBidiRects(cm.display.measure) && (order = getOrder(line)))
+        builder.addToken = buildTokenBadBidi(builder.addToken, order);
+      builder.map = [];
+      var allowFrontierUpdate = lineView != cm.display.externalMeasured && lineNo(line);
+      insertLineContent(line, builder, getLineStyles(cm, line, allowFrontierUpdate));
+      if (line.styleClasses) {
+        if (line.styleClasses.bgClass)
+          builder.bgClass = joinClasses(line.styleClasses.bgClass, builder.bgClass || "");
+        if (line.styleClasses.textClass)
+          builder.textClass = joinClasses(line.styleClasses.textClass, builder.textClass || "");
+      }
+
+      // Ensure at least a single node is present, for measuring.
+      if (builder.map.length == 0)
+        builder.map.push(0, 0, builder.content.appendChild(zeroWidthElement(cm.display.measure)));
+
+      // Store the map and a cache object for the current logical line
+      if (i == 0) {
+        lineView.measure.map = builder.map;
+        lineView.measure.cache = {};
+      } else {
+        (lineView.measure.maps || (lineView.measure.maps = [])).push(builder.map);
+        (lineView.measure.caches || (lineView.measure.caches = [])).push({});
+      }
+    }
+
+    // See issue #2901
+    if (webkit && /\bcm-tab\b/.test(builder.content.lastChild.className))
+      builder.content.className = "cm-tab-wrap-hack";
+
+    signal(cm, "renderLine", cm, lineView.line, builder.pre);
+    if (builder.pre.className)
+      builder.textClass = joinClasses(builder.pre.className, builder.textClass || "");
+
+    return builder;
+  }
+
+  function defaultSpecialCharPlaceholder(ch) {
+    var token = elt("span", "\u2022", "cm-invalidchar");
+    token.title = "\\u" + ch.charCodeAt(0).toString(16);
+    token.setAttribute("aria-label", token.title);
+    return token;
+  }
+
+  // Build up the DOM representation for a single token, and add it to
+  // the line map. Takes care to render special characters separately.
+  function buildToken(builder, text, style, startStyle, endStyle, title, css) {
+    if (!text) return;
+    var displayText = builder.splitSpaces ? text.replace(/ {3,}/g, splitSpaces) : text;
+    var special = builder.cm.state.specialChars, mustWrap = false;
+    if (!special.test(text)) {
+      builder.col += text.length;
+      var content = document.createTextNode(displayText);
+      builder.map.push(builder.pos, builder.pos + text.length, content);
+      if (ie && ie_version < 9) mustWrap = true;
+      builder.pos += text.length;
+    } else {
+      var content = document.createDocumentFragment(), pos = 0;
+      while (true) {
+        special.lastIndex = pos;
+        var m = special.exec(text);
+        var skipped = m ? m.index - pos : text.length - pos;
+        if (skipped) {
+          var txt = document.createTextNode(displayText.slice(pos, pos + skipped));
+          if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
+          else content.appendChild(txt);
+          builder.map.push(builder.pos, builder.pos + skipped, txt);
+          builder.col += skipped;
+          builder.pos += skipped;
+        }
+        if (!m) break;
+        pos += skipped + 1;
+        if (m[0] == "\t") {
+          var tabSize = builder.cm.options.tabSize, tabWidth = tabSize - builder.col % tabSize;
+          var txt = content.appendChild(elt("span", spaceStr(tabWidth), "cm-tab"));
+          txt.setAttribute("role", "presentation");
+          txt.setAttribute("cm-text", "\t");
+          builder.col += tabWidth;
+        } else {
+          var txt = builder.cm.options.specialCharPlaceholder(m[0]);
+          txt.setAttribute("cm-text", m[0]);
+          if (ie && ie_version < 9) content.appendChild(elt("span", [txt]));
+          else content.appendChild(txt);
+          builder.col += 1;
+        }
+        builder.map.push(builder.pos, builder.pos + 1, txt);
+        builder.pos++;
+      }
+    }
+    if (style || startStyle || endStyle || mustWrap || css) {
+      var fullStyle = style || "";
+      if (startStyle) fullStyle += startStyle;
+      if (endStyle) fullStyle += endStyle;
+      var token = elt("span", [content], fullStyle, css);
+      if (title) token.title = title;
+      return builder.content.appendChild(token);
+    }
+    builder.content.appendChild(content);
+  }
+
+  function splitSpaces(old) {
+    var out = " ";
+    for (var i = 0; i < old.length - 2; ++i) out += i % 2 ? " " : "\u00a0";
+    out += " ";
+    return out;
+  }
+
+  // Work around nonsense dimensions being reported for stretches of
+  // right-to-left text.
+  function buildTokenBadBidi(inner, order) {
+    return function(builder, text, style, startStyle, endStyle, title, css) {
+      style = style ? style + " cm-force-border" : "cm-force-border";
+      var start = builder.pos, end = start + text.length;
+      for (;;) {
+        // Find the part that overlaps with the start of this text
+        for (var i = 0; i < order.length; i++) {
+          var part = order[i];
+          if (part.to > start && part.from <= start) break;
+        }
+        if (part.to >= end) return inner(builder, text, style, startStyle, endStyle, title, css);
+        inner(builder, text.slice(0, part.to - start), style, startStyle, null, title, css);
+        startStyle = null;
+        text = text.slice(part.to - start);
+        start = part.to;
+      }
+    };
+  }
+
+  function buildCollapsedSpan(builder, size, marker, ignoreWidget) {
+    var widget = !ignoreWidget && marker.widgetNode;
+    if (widget) builder.map.push(builder.pos, builder.pos + size, widget);
+    if (!ignoreWidget && builder.cm.display.input.needsContentAttribute) {
+      if (!widget)
+        widget = builder.content.appendChild(document.createElement("span"));
+      widget.setAttribute("cm-marker", marker.id);
+    }
+    if (widget) {
+      builder.cm.display.input.setUneditable(widget);
+      builder.content.appendChild(widget);
+    }
+    builder.pos += size;
+  }
+
+  // Outputs a number of spans to make up a line, taking highlighting
+  // and marked text into account.
+  function insertLineContent(line, builder, styles) {
+    var spans = line.markedSpans, allText = line.text, at = 0;
+    if (!spans) {
+      for (var i = 1; i < styles.length; i+=2)
+        builder.addToken(builder, allText.slice(at, at = styles[i]), interpretTokenStyle(styles[i+1], builder.cm.options));
+      return;
+    }
+
+    var len = allText.length, pos = 0, i = 1, text = "", style, css;
+    var nextChange = 0, spanStyle, spanEndStyle, spanStartStyle, title, collapsed;
+    for (;;) {
+      if (nextChange == pos) { // Update current marker set
+        spanStyle = spanEndStyle = spanStartStyle = title = css = "";
+        collapsed = null; nextChange = Infinity;
+        var foundBookmarks = [];
+        for (var j = 0; j < spans.length; ++j) {
+          var sp = spans[j], m = sp.marker;
+          if (m.type == "bookmark" && sp.from == pos && m.widgetNode) {
+            foundBookmarks.push(m);
+          } else if (sp.from <= pos && (sp.to == null || sp.to > pos || m.collapsed && sp.to == pos && sp.from == pos)) {
+            if (sp.to != null && sp.to != pos && nextChange > sp.to) {
+              nextChange = sp.to;
+              spanEndStyle = "";
+            }
+            if (m.className) spanStyle += " " + m.className;
+            if (m.css) css = m.css;
+            if (m.startStyle && sp.from == pos) spanStartStyle += " " + m.startStyle;
+            if (m.endStyle && sp.to == nextChange) spanEndStyle += " " + m.endStyle;
+            if (m.title && !title) title = m.title;
+            if (m.collapsed && (!collapsed || compareCollapsedMarkers(collapsed.marker, m) < 0))
+              collapsed = sp;
+          } else if (sp.from > pos && nextChange > sp.from) {
+            nextChange = sp.from;
+          }
+        }
+        if (collapsed && (collapsed.from || 0) == pos) {
+          buildCollapsedSpan(builder, (collapsed.to == null ? len + 1 : collapsed.to) - pos,
+                             collapsed.marker, collapsed.from == null);
+          if (collapsed.to == null) return;
+          if (collapsed.to == pos) collapsed = false;
+        }
+        if (!collapsed && foundBookmarks.length) for (var j = 0; j < foundBookmarks.length; ++j)
+          buildCollapsedSpan(builder, 0, foundBookmarks[j]);
+      }
+      if (pos >= len) break;
+
+      var upto = Math.min(len, nextChange);
+      while (true) {
+        if (text) {
+          var end = pos + text.length;
+          if (!collapsed) {
+            var tokenText = end > upto ? text.slice(0, upto - pos) : text;
+            builder.addToken(builder, tokenText, style ? style + spanStyle : spanStyle,
+                             spanStartStyle, pos + tokenText.length == nextChange ? spanEndStyle : "", title, css);
+          }
+          if (end >= upto) {text = text.slice(upto - pos); pos = upto; break;}
+          pos = end;
+          spanStartStyle = "";
+        }
+        text = allText.slice(at, at = styles[i++]);
+        style = interpretTokenStyle(styles[i++], builder.cm.options);
+      }
+    }
+  }
+
+  // DOCUMENT DATA STRUCTURE
+
+  // By default, updates that start and end at the beginning of a line
+  // are treated specially, in order to make the association of line
+  // widgets and marker elements with the text behave more intuitive.
+  function isWholeLineUpdate(doc, change) {
+    return change.from.ch == 0 && change.to.ch == 0 && lst(change.text) == "" &&
+      (!doc.cm || doc.cm.options.wholeLineUpdateBefore);
+  }
+
+  // Perform a change on the document data structure.
+  function updateDoc(doc, change, markedSpans, estimateHeight) {
+    function spansFor(n) {return markedSpans ? markedSpans[n] : null;}
+    function update(line, text, spans) {
+      updateLine(line, text, spans, estimateHeight);
+      signalLater(line, "change", line, change);
+    }
+    function linesFor(start, end) {
+      for (var i = start, result = []; i < end; ++i)
+        result.push(new Line(text[i], spansFor(i), estimateHeight));
+      return result;
+    }
+
+    var from = change.from, to = change.to, text = change.text;
+    var firstLine = getLine(doc, from.line), lastLine = getLine(doc, to.line);
+    var lastText = lst(text), lastSpans = spansFor(text.length - 1), nlines = to.line - from.line;
+
+    // Adjust the line structure
+    if (change.full) {
+      doc.insert(0, linesFor(0, text.length));
+      doc.remove(text.length, doc.size - text.length);
+    } else if (isWholeLineUpdate(doc, change)) {
+      // This is a whole-line replace. Treated specially to make
+      // sure line objects move the way they are supposed to.
+      var added = linesFor(0, text.length - 1);
+      update(lastLine, lastLine.text, lastSpans);
+      if (nlines) doc.remove(from.line, nlines);
+      if (added.length) doc.insert(from.line, added);
+    } else if (firstLine == lastLine) {
+      if (text.length == 1) {
+        update(firstLine, firstLine.text.slice(0, from.ch) + lastText + firstLine.text.slice(to.ch), lastSpans);
+      } else {
+        var added = linesFor(1, text.length - 1);
+        added.push(new Line(lastText + firstLine.text.slice(to.ch), lastSpans, estimateHeight));
+        update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
+        doc.insert(from.line + 1, added);
+      }
+    } else if (text.length == 1) {
+      update(firstLine, firstLine.text.slice(0, from.ch) + text[0] + lastLine.text.slice(to.ch), spansFor(0));
+      doc.remove(from.line + 1, nlines);
+    } else {
+      update(firstLine, firstLine.text.slice(0, from.ch) + text[0], spansFor(0));
+      update(lastLine, lastText + lastLine.text.slice(to.ch), lastSpans);
+      var added = linesFor(1, text.length - 1);
+      if (nlines > 1) doc.remove(from.line + 1, nlines - 1);
+      doc.insert(from.line + 1, added);
+    }
+
+    signalLater(doc, "change", doc, change);
+  }
+
+  // The document is represented as a BTree consisting of leaves, with
+  // chunk of lines in them, and branches, with up to ten leaves or
+  // other branch nodes below them. The top node is always a branch
+  // node, and is the document object itself (meaning it has
+  // additional methods and properties).
+  //
+  // All nodes have parent links. The tree is used both to go from
+  // line numbers to line objects, and to go from objects to numbers.
+  // It also indexes by height, and is used to convert between height
+  // and line object, and to find the total height of the document.
+  //
+  // See also http://marijnhaverbeke.nl/blog/codemirror-line-tree.html
+
+  function LeafChunk(lines) {
+    this.lines = lines;
+    this.parent = null;
+    for (var i = 0, height = 0; i < lines.length; ++i) {
+      lines[i].parent = this;
+      height += lines[i].height;
+    }
+    this.height = height;
+  }
+
+  LeafChunk.prototype = {
+    chunkSize: function() { return this.lines.length; },
+    // Remove the n lines at offset 'at'.
+    removeInner: function(at, n) {
+      for (var i = at, e = at + n; i < e; ++i) {
+        var line = this.lines[i];
+        this.height -= line.height;
+        cleanUpLine(line);
+        signalLater(line, "delete");
+      }
+      this.lines.splice(at, n);
+    },
+    // Helper used to collapse a small branch into a single leaf.
+    collapse: function(lines) {
+      lines.push.apply(lines, this.lines);
+    },
+    // Insert the given array of lines at offset 'at', count them as
+    // having the given height.
+    insertInner: function(at, lines, height) {
+      this.height += height;
+      this.lines = this.lines.slice(0, at).concat(lines).concat(this.lines.slice(at));
+      for (var i = 0; i < lines.length; ++i) lines[i].parent = this;
+    },
+    // Used to iterate over a part of the tree.
+    iterN: function(at, n, op) {
+      for (var e = at + n; at < e; ++at)
+        if (op(this.lines[at])) return true;
+    }
+  };
+
+  function BranchChunk(children) {
+    this.children = children;
+    var size = 0, height = 0;
+    for (var i = 0; i < children.length; ++i) {
+      var ch = children[i];
+      size += ch.chunkSize(); height += ch.height;
+      ch.parent = this;
+    }
+    this.size = size;
+    this.height = height;
+    this.parent = null;
+  }
+
+  BranchChunk.prototype = {
+    chunkSize: function() { return this.size; },
+    removeInner: function(at, n) {
+      this.size -= n;
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var rm = Math.min(n, sz - at), oldHeight = child.height;
+          child.removeInner(at, rm);
+          this.height -= oldHeight - child.height;
+          if (sz == rm) { this.children.splice(i--, 1); child.parent = null; }
+          if ((n -= rm) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+      // If the result is smaller than 25 lines, ensure that it is a
+      // single leaf node.
+      if (this.size - n < 25 &&
+          (this.children.length > 1 || !(this.children[0] instanceof LeafChunk))) {
+        var lines = [];
+        this.collapse(lines);
+        this.children = [new LeafChunk(lines)];
+        this.children[0].parent = this;
+      }
+    },
+    collapse: function(lines) {
+      for (var i = 0; i < this.children.length; ++i) this.children[i].collapse(lines);
+    },
+    insertInner: function(at, lines, height) {
+      this.size += lines.length;
+      this.height += height;
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at <= sz) {
+          child.insertInner(at, lines, height);
+          if (child.lines && child.lines.length > 50) {
+            while (child.lines.length > 50) {
+              var spilled = child.lines.splice(child.lines.length - 25, 25);
+              var newleaf = new LeafChunk(spilled);
+              child.height -= newleaf.height;
+              this.children.splice(i + 1, 0, newleaf);
+              newleaf.parent = this;
+            }
+            this.maybeSpill();
+          }
+          break;
+        }
+        at -= sz;
+      }
+    },
+    // When a node has grown, check whether it should be split.
+    maybeSpill: function() {
+      if (this.children.length <= 10) return;
+      var me = this;
+      do {
+        var spilled = me.children.splice(me.children.length - 5, 5);
+        var sibling = new BranchChunk(spilled);
+        if (!me.parent) { // Become the parent node
+          var copy = new BranchChunk(me.children);
+          copy.parent = me;
+          me.children = [copy, sibling];
+          me = copy;
+        } else {
+          me.size -= sibling.size;
+          me.height -= sibling.height;
+          var myIndex = indexOf(me.parent.children, me);
+          me.parent.children.splice(myIndex + 1, 0, sibling);
+        }
+        sibling.parent = me.parent;
+      } while (me.children.length > 10);
+      me.parent.maybeSpill();
+    },
+    iterN: function(at, n, op) {
+      for (var i = 0; i < this.children.length; ++i) {
+        var child = this.children[i], sz = child.chunkSize();
+        if (at < sz) {
+          var used = Math.min(n, sz - at);
+          if (child.iterN(at, used, op)) return true;
+          if ((n -= used) == 0) break;
+          at = 0;
+        } else at -= sz;
+      }
+    }
+  };
+
+  var nextDocId = 0;
+  var Doc = CodeMirror.Doc = function(text, mode, firstLine) {
+    if (!(this instanceof Doc)) return new Doc(text, mode, firstLine);
+    if (firstLine == null) firstLine = 0;
+
+    BranchChunk.call(this, [new LeafChunk([new Line("", null)])]);
+    this.first = firstLine;
+    this.scrollTop = this.scrollLeft = 0;
+    this.cantEdit = false;
+    this.cleanGeneration = 1;
+    this.frontier = firstLine;
+    var start = Pos(firstLine, 0);
+    this.sel = simpleSelection(start);
+    this.history = new History(null);
+    this.id = ++nextDocId;
+    this.modeOption = mode;
+
+    if (typeof text == "string") text = splitLines(text);
+    updateDoc(this, {from: start, to: start, text: text});
+    setSelection(this, simpleSelection(start), sel_dontScroll);
+  };
+
+  Doc.prototype = createObj(BranchChunk.prototype, {
+    constructor: Doc,
+    // Iterate over the document. Supports two forms -- with only one
+    // argument, it calls that for each line in the document. With
+    // three, it iterates over the range given by the first two (with
+    // the second being non-inclusive).
+    iter: function(from, to, op) {
+      if (op) this.iterN(from - this.first, to - from, op);
+      else this.iterN(this.first, this.first + this.size, from);
+    },
+
+    // Non-public interface for adding and removing lines.
+    insert: function(at, lines) {
+      var height = 0;
+      for (var i = 0; i < lines.length; ++i) height += lines[i].height;
+      this.insertInner(at - this.first, lines, height);
+    },
+    remove: function(at, n) { this.removeInner(at - this.first, n); },
+
+    // From here, the methods are part of the public interface. Most
+    // are also available from CodeMirror (editor) instances.
+
+    getValue: function(lineSep) {
+      var lines = getLines(this, this.first, this.first + this.size);
+      if (lineSep === false) return lines;
+      return lines.join(lineSep || "\n");
+    },
+    setValue: docMethodOp(function(code) {
+      var top = Pos(this.first, 0), last = this.first + this.size - 1;
+      makeChange(this, {from: top, to: Pos(last, getLine(this, last).text.length),
+                        text: splitLines(code), origin: "setValue", full: true}, true);
+      setSelection(this, simpleSelection(top));
+    }),
+    replaceRange: function(code, from, to, origin) {
+      from = clipPos(this, from);
+      to = to ? clipPos(this, to) : from;
+      replaceRange(this, code, from, to, origin);
+    },
+    getRange: function(from, to, lineSep) {
+      var lines = getBetween(this, clipPos(this, from), clipPos(this, to));
+      if (lineSep === false) return lines;
+      return lines.join(lineSep || "\n");
+    },
+
+    getLine: function(line) {var l = this.getLineHandle(line); return l && l.text;},
+
+    getLineHandle: function(line) {if (isLine(this, line)) return getLine(this, line);},
+    getLineNumber: function(line) {return lineNo(line);},
+
+    getLineHandleVisualStart: function(line) {
+      if (typeof line == "number") line = getLine(this, line);
+      return visualLine(line);
+    },
+
+    lineCount: function() {return this.size;},
+    firstLine: function() {return this.first;},
+    lastLine: function() {return this.first + this.size - 1;},
+
+    clipPos: function(pos) {return clipPos(this, pos);},
+
+    getCursor: function(start) {
+      var range = this.sel.primary(), pos;
+      if (start == null || start == "head") pos = range.head;
+      else if (start == "anchor") pos = range.anchor;
+      else if (start == "end" || start == "to" || start === false) pos = range.to();
+      else pos = range.from();
+      return pos;
+    },
+    listSelections: function() { return this.sel.ranges; },
+    somethingSelected: function() {return this.sel.somethingSelected();},
+
+    setCursor: docMethodOp(function(line, ch, options) {
+      setSimpleSelection(this, clipPos(this, typeof line == "number" ? Pos(line, ch || 0) : line), null, options);
+    }),
+    setSelection: docMethodOp(function(anchor, head, options) {
+      setSimpleSelection(this, clipPos(this, anchor), clipPos(this, head || anchor), options);
+    }),
+    extendSelection: docMethodOp(function(head, other, options) {
+      extendSelection(this, clipPos(this, head), other && clipPos(this, other), options);
+    }),
+    extendSelections: docMethodOp(function(heads, options) {
+      extendSelections(this, clipPosArray(this, heads, options));
+    }),
+    extendSelectionsBy: docMethodOp(function(f, options) {
+      extendSelections(this, map(this.sel.ranges, f), options);
+    }),
+    setSelections: docMethodOp(function(ranges, primary, options) {
+      if (!ranges.length) return;
+      for (var i = 0, out = []; i < ranges.length; i++)
+        out[i] = new Range(clipPos(this, ranges[i].anchor),
+                           clipPos(this, ranges[i].head));
+      if (primary == null) primary = Math.min(ranges.length - 1, this.sel.primIndex);
+      setSelection(this, normalizeSelection(out, primary), options);
+    }),
+    addSelection: docMethodOp(function(anchor, head, options) {
+      var ranges = this.sel.ranges.slice(0);
+      ranges.push(new Range(clipPos(this, anchor), clipPos(this, head || anchor)));
+      setSelection(this, normalizeSelection(ranges, ranges.length - 1), options);
+    }),
+
+    getSelection: function(lineSep) {
+      var ranges = this.sel.ranges, lines;
+      for (var i = 0; i < ranges.length; i++) {
+        var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+        lines = lines ? lines.concat(sel) : sel;
+      }
+      if (lineSep === false) return lines;
+      else return lines.join(lineSep || "\n");
+    },
+    getSelections: function(lineSep) {
+      var parts = [], ranges = this.sel.ranges;
+      for (var i = 0; i < ranges.length; i++) {
+        var sel = getBetween(this, ranges[i].from(), ranges[i].to());
+        if (lineSep !== false) sel = sel.join(lineSep || "\n");
+        parts[i] = sel;
+      }
+      return parts;
+    },
+    replaceSelection: function(code, collapse, origin) {
+      var dup = [];
+      for (var i = 0; i < this.sel.ranges.length; i++)
+        dup[i] = code;
+      this.replaceSelections(dup, collapse, origin || "+input");
+    },
+    replaceSelections: docMethodOp(function(code, collapse, origin) {
+      var changes = [], sel = this.sel;
+      for (var i = 0; i < sel.ranges.length; i++) {
+        var range = sel.ranges[i];
+        changes[i] = {from: range.from(), to: range.to(), text: splitLines(code[i]), origin: origin};
+      }
+      var newSel = collapse && collapse != "end" && computeReplacedSel(this, changes, collapse);
+      for (var i = changes.length - 1; i >= 0; i--)
+        makeChange(this, changes[i]);
+      if (newSel) setSelectionReplaceHistory(this, newSel);
+      else if (this.cm) ensureCursorVisible(this.cm);
+    }),
+    undo: docMethodOp(function() {makeChangeFromHistory(this, "undo");}),
+    redo: docMethodOp(function() {makeChangeFromHistory(this, "redo");}),
+    undoSelection: docMethodOp(function() {makeChangeFromHistory(this, "undo", true);}),
+    redoSelection: docMethodOp(function() {makeChangeFromHistory(this, "redo", true);}),
+
+    setExtending: function(val) {this.extend = val;},
+    getExtending: function() {return this.extend;},
+
+    historySize: function() {
+      var hist = this.history, done = 0, undone = 0;
+      for (var i = 0; i < hist.done.length; i++) if (!hist.done[i].ranges) ++done;
+      for (var i = 0; i < hist.undone.length; i++) if (!hist.undone[i].ranges) ++undone;
+      return {undo: done, redo: undone};
+    },
+    clearHistory: function() {this.history = new History(this.history.maxGeneration);},
+
+    markClean: function() {
+      this.cleanGeneration = this.changeGeneration(true);
+    },
+    changeGeneration: function(forceSplit) {
+      if (forceSplit)
+        this.history.lastOp = this.history.lastSelOp = this.history.lastOrigin = null;
+      return this.history.generation;
+    },
+    isClean: function (gen) {
+      return this.history.generation == (gen || this.cleanGeneration);
+    },
+
+    getHistory: function() {
+      return {done: copyHistoryArray(this.history.done),
+              undone: copyHistoryArray(this.history.undone)};
+    },
+    setHistory: function(histData) {
+      var hist = this.history = new History(this.history.maxGeneration);
+      hist.done = copyHistoryArray(histData.done.slice(0), null, true);
+      hist.undone = copyHistoryArray(histData.undone.slice(0), null, true);
+    },
+
+    addLineClass: docMethodOp(function(handle, where, cls) {
+      return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
+        var prop = where == "text" ? "textClass"
+                 : where == "background" ? "bgClass"
+                 : where == "gutter" ? "gutterClass" : "wrapClass";
+        if (!line[prop]) line[prop] = cls;
+        else if (classTest(cls).test(line[prop])) return false;
+        else line[prop] += " " + cls;
+        return true;
+      });
+    }),
+    removeLineClass: docMethodOp(function(handle, where, cls) {
+      return changeLine(this, handle, where == "gutter" ? "gutter" : "class", function(line) {
+        var prop = where == "text" ? "textClass"
+                 : where == "background" ? "bgClass"
+                 : where == "gutter" ? "gutterClass" : "wrapClass";
+        var cur = line[prop];
+        if (!cur) return false;
+        else if (cls == null) line[prop] = null;
+        else {
+          var found = cur.match(classTest(cls));
+          if (!found) return false;
+          var end = found.index + found[0].length;
+          line[prop] = cur.slice(0, found.index) + (!found.index || end == cur.length ? "" : " ") + cur.slice(end) || null;
+        }
+        return true;
+      });
+    }),
+
+    addLineWidget: docMethodOp(function(handle, node, options) {
+      return addLineWidget(this, handle, node, options);
+    }),
+    removeLineWidget: function(widget) { widget.clear(); },
+
+    markText: function(from, to, options) {
+      return markText(this, clipPos(this, from), clipPos(this, to), options, "range");
+    },
+    setBookmark: function(pos, options) {
+      var realOpts = {replacedWith: options && (options.nodeType == null ? options.widget : options),
+                      insertLeft: options && options.insertLeft,
+                      clearWhenEmpty: false, shared: options && options.shared,
+                      handleMouseEvents: options && options.handleMouseEvents};
+      pos = clipPos(this, pos);
+      return markText(this, pos, pos, realOpts, "bookmark");
+    },
+    findMarksAt: function(pos) {
+      pos = clipPos(this, pos);
+      var markers = [], spans = getLine(this, pos.line).markedSpans;
+      if (spans) for (var i = 0; i < spans.length; ++i) {
+        var span = spans[i];
+        if ((span.from == null || span.from <= pos.ch) &&
+            (span.to == null || span.to >= pos.ch))
+          markers.push(span.marker.parent || span.marker);
+      }
+      return markers;
+    },
+    findMarks: function(from, to, filter) {
+      from = clipPos(this, from); to = clipPos(this, to);
+      var found = [], lineNo = from.line;
+      this.iter(from.line, to.line + 1, function(line) {
+        var spans = line.markedSpans;
+        if (spans) for (var i = 0; i < spans.length; i++) {
+          var span = spans[i];
+          if (!(lineNo == from.line && from.ch > span.to ||
+                span.from == null && lineNo != from.line||
+                lineNo == to.line && span.from > to.ch) &&
+              (!filter || filter(span.marker)))
+            found.push(span.marker.parent || span.marker);
+        }
+        ++lineNo;
+      });
+      return found;
+    },
+    getAllMarks: function() {
+      var markers = [];
+      this.iter(function(line) {
+        var sps = line.markedSpans;
+        if (sps) for (var i = 0; i < sps.length; ++i)
+          if (sps[i].from != null) markers.push(sps[i].marker);
+      });
+      return markers;
+    },
+
+    posFromIndex: function(off) {
+      var ch, lineNo = this.first;
+      this.iter(function(line) {
+        var sz = line.text.length + 1;
+        if (sz > off) { ch = off; return true; }
+        off -= sz;
+        ++lineNo;
+      });
+      return clipPos(this, Pos(lineNo, ch));
+    },
+    indexFromPos: function (coords) {
+      coords = clipPos(this, coords);
+      var index = coords.ch;
+      if (coords.line < this.first || coords.ch < 0) return 0;
+      this.iter(this.first, coords.line, function (line) {
+        index += line.text.length + 1;
+      });
+      return index;
+    },
+
+    copy: function(copyHistory) {
+      var doc = new Doc(getLines(this, this.first, this.first + this.size), this.modeOption, this.first);
+      doc.scrollTop = this.scrollTop; doc.scrollLeft = this.scrollLeft;
+      doc.sel = this.sel;
+      doc.extend = false;
+      if (copyHistory) {
+        doc.history.undoDepth = this.history.undoDepth;
+        doc.setHistory(this.getHistory());
+      }
+      return doc;
+    },
+
+    linkedDoc: function(options) {
+      if (!options) options = {};
+      var from = this.first, to = this.first + this.size;
+      if (options.from != null && options.from > from) from = options.from;
+      if (options.to != null && options.to < to) to = options.to;
+      var copy = new Doc(getLines(this, from, to), options.mode || this.modeOption, from);
+      if (options.sharedHist) copy.history = this.history;
+      (this.linked || (this.linked = [])).push({doc: copy, sharedHist: options.sharedHist});
+      copy.linked = [{doc: this, isParent: true, sharedHist: options.sharedHist}];
+      copySharedMarkers(copy, findSharedMarkers(this));
+      return copy;
+    },
+    unlinkDoc: function(other) {
+      if (other instanceof CodeMirror) other = other.doc;
+      if (this.linked) for (var i = 0; i < this.linked.length; ++i) {
+        var link = this.linked[i];
+        if (link.doc != other) continue;
+        this.linked.splice(i, 1);
+        other.unlinkDoc(this);
+        detachSharedMarkers(findSharedMarkers(this));
+        break;
+      }
+      // If the histories were shared, split them again
+      if (other.history == this.history) {
+        var splitIds = [other.id];
+        linkedDocs(other, function(doc) {splitIds.push(doc.id);}, true);
+        other.history = new History(null);
+        other.history.done = copyHistoryArray(this.history.done, splitIds);
+        other.history.undone = copyHistoryArray(this.history.undone, splitIds);
+      }
+    },
+    iterLinkedDocs: function(f) {linkedDocs(this, f);},
+
+    getMode: function() {return this.mode;},
+    getEditor: function() {return this.cm;}
+  });
+
+  // Public alias.
+  Doc.prototype.eachLine = Doc.prototype.iter;
+
+  // Set up methods on CodeMirror's prototype to redirect to the editor's document.
+  var dontDelegate = "iter insert remove copy getEditor".split(" ");
+  for (var prop in Doc.prototype) if (Doc.prototype.hasOwnProperty(prop) && indexOf(dontDelegate, prop) < 0)
+    CodeMirror.prototype[prop] = (function(method) {
+      return function() {return method.apply(this.doc, arguments);};
+    })(Doc.prototype[prop]);
+
+  eventMixin(Doc);
+
+  // Call f for all linked documents.
+  function linkedDocs(doc, f, sharedHistOnly) {
+    function propagate(doc, skip, sharedHist) {
+      if (doc.linked) for (var i = 0; i < doc.linked.length; ++i) {
+        var rel = doc.linked[i];
+        if (rel.doc == skip) continue;
+        var shared = sharedHist && rel.sharedHist;
+        if (sharedHistOnly && !shared) continue;
+        f(rel.doc, shared);
+        propagate(rel.doc, doc, shared);
+      }
+    }
+    propagate(doc, null, true);
+  }
+
+  // Attach a document to an editor.
+  function attachDoc(cm, doc) {
+    if (doc.cm) throw new Error("This document is already in use.");
+    cm.doc = doc;
+    doc.cm = cm;
+    estimateLineHeights(cm);
+    loadMode(cm);
+    if (!cm.options.lineWrapping) findMaxLine(cm);
+    cm.options.mode = doc.modeOption;
+    regChange(cm);
+  }
+
+  // LINE UTILITIES
+
+  // Find the line object corresponding to the given line number.
+  function getLine(doc, n) {
+    n -= doc.first;
+    if (n < 0 || n >= doc.size) throw new Error("There is no line " + (n + doc.first) + " in the document.");
+    for (var chunk = doc; !chunk.lines;) {
+      for (var i = 0;; ++i) {
+        var child = chunk.children[i], sz = child.chunkSize();
+        if (n < sz) { chunk = child; break; }
+        n -= sz;
+      }
+    }
+    return chunk.lines[n];
+  }
+
+  // Get the part of a document between two positions, as an array of
+  // strings.
+  function getBetween(doc, start, end) {
+    var out = [], n = start.line;
+    doc.iter(start.line, end.line + 1, function(line) {
+      var text = line.text;
+      if (n == end.line) text = text.slice(0, end.ch);
+      if (n == start.line) text = text.slice(start.ch);
+      out.push(text);
+      ++n;
+    });
+    return out;
+  }
+  // Get the lines between from and to, as array of strings.
+  function getLines(doc, from, to) {
+    var out = [];
+    doc.iter(from, to, function(line) { out.push(line.text); });
+    return out;
+  }
+
+  // Update the height of a line, propagating the height change
+  // upwards to parent nodes.
+  function updateLineHeight(line, height) {
+    var diff = height - line.height;
+    if (diff) for (var n = line; n; n = n.parent) n.height += diff;
+  }
+
+  // Given a line object, find its line number by walking up through
+  // its parent links.
+  function lineNo(line) {
+    if (line.parent == null) return null;
+    var cur = line.parent, no = indexOf(cur.lines, line);
+    for (var chunk = cur.parent; chunk; cur = chunk, chunk = chunk.parent) {
+      for (var i = 0;; ++i) {
+        if (chunk.children[i] == cur) break;
+        no += chunk.children[i].chunkSize();
+      }
+    }
+    return no + cur.first;
+  }
+
+  // Find the line at the given vertical position, using the height
+  // information in the document tree.
+  function lineAtHeight(chunk, h) {
+    var n = chunk.first;
+    outer: do {
+      for (var i = 0; i < chunk.children.length; ++i) {
+        var child = chunk.children[i], ch = child.height;
+        if (h < ch) { chunk = child; continue outer; }
+        h -= ch;
+        n += child.chunkSize();
+      }
+      return n;
+    } while (!chunk.lines);
+    for (var i = 0; i < chunk.lines.length; ++i) {
+      var line = chunk.lines[i], lh = line.height;
+      if (h < lh) break;
+      h -= lh;
+    }
+    return n + i;
+  }
+
+
+  // Find the height above the given line.
+  function heightAtLine(lineObj) {
+    lineObj = visualLine(lineObj);
+
+    var h = 0, chunk = lineObj.parent;
+    for (var i = 0; i < chunk.lines.length; ++i) {
+      var line = chunk.lines[i];
+      if (line == lineObj) break;
+      else h += line.height;
+    }
+    for (var p = chunk.parent; p; chunk = p, p = chunk.parent) {
+      for (var i = 0; i < p.children.length; ++i) {
+        var cur = p.children[i];
+        if (cur == chunk) break;
+        else h += cur.height;
+      }
+    }
+    return h;
+  }
+
+  // Get the bidi ordering for the given line (and cache it). Returns
+  // false for lines that are fully left-to-right, and an array of
+  // BidiSpan objects otherwise.
+  function getOrder(line) {
+    var order = line.order;
+    if (order == null) order = line.order = bidiOrdering(line.text);
+    return order;
+  }
+
+  // HISTORY
+
+  function History(startGen) {
+    // Arrays of change events and selections. Doing something adds an
+    // event to done and clears undo. Undoing moves events from done
+    // to undone, redoing moves them in the other direction.
+    this.done = []; this.undone = [];
+    this.undoDepth = Infinity;
+    // Used to track when changes can be merged into a single undo
+    // event
+    this.lastModTime = this.lastSelTime = 0;
+    this.lastOp = this.lastSelOp = null;
+    this.lastOrigin = this.lastSelOrigin = null;
+    // Used by the isClean() method
+    this.generation = this.maxGeneration = startGen || 1;
+  }
+
+  // Create a history change event from an updateDoc-style change
+  // object.
+  function historyChangeFromChange(doc, change) {
+    var histChange = {from: copyPos(change.from), to: changeEnd(change), text: getBetween(doc, change.from, change.to)};
+    attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);
+    linkedDocs(doc, function(doc) {attachLocalSpans(doc, histChange, change.from.line, change.to.line + 1);}, true);
+    return histChange;
+  }
+
+  // Pop all selection events off the end of a history array. Stop at
+  // a change event.
+  function clearSelectionEvents(array) {
+    while (array.length) {
+      var last = lst(array);
+      if (last.ranges) array.pop();
+      else break;
+    }
+  }
+
+  // Find the top change event in the history. Pop off selection
+  // events that are in the way.
+  function lastChangeEvent(hist, force) {
+    if (force) {
+      clearSelectionEvents(hist.done);
+      return lst(hist.done);
+    } else if (hist.done.length && !lst(hist.done).ranges) {
+      return lst(hist.done);
+    } else if (hist.done.length > 1 && !hist.done[hist.done.length - 2].ranges) {
+      hist.done.pop();
+      return lst(hist.done);
+    }
+  }
+
+  // Register a change in the history. Merges changes that are within
+  // a single operation, ore are close together with an origin that
+  // allows merging (starting with "+") into a single event.
+  function addChangeToHistory(doc, change, selAfter, opId) {
+    var hist = doc.history;
+    hist.undone.length = 0;
+    var time = +new Date, cur;
+
+    if ((hist.lastOp == opId ||
+         hist.lastOrigin == change.origin && change.origin &&
+         ((change.origin.charAt(0) == "+" && doc.cm && hist.lastModTime > time - doc.cm.options.historyEventDelay) ||
+          change.origin.charAt(0) == "*")) &&
+        (cur = lastChangeEvent(hist, hist.lastOp == opId))) {
+      // Merge this change into the last event
+      var last = lst(cur.changes);
+      if (cmp(change.from, change.to) == 0 && cmp(change.from, last.to) == 0) {
+        // Optimized case for simple insertion -- don't want to add
+        // new changesets for every character typed
+        last.to = changeEnd(change);
+      } else {
+        // Add new sub-event
+        cur.changes.push(historyChangeFromChange(doc, change));
+      }
+    } else {
+      // Can not be merged, start a new event.
+      var before = lst(hist.done);
+      if (!before || !before.ranges)
+        pushSelectionToHistory(doc.sel, hist.done);
+      cur = {changes: [historyChangeFromChange(doc, change)],
+             generation: hist.generation};
+      hist.done.push(cur);
+      while (hist.done.length > hist.undoDepth) {
+        hist.done.shift();
+        if (!hist.done[0].ranges) hist.done.shift();
+      }
+    }
+    hist.done.push(selAfter);
+    hist.generation = ++hist.maxGeneration;
+    hist.lastModTime = hist.lastSelTime = time;
+    hist.lastOp = hist.lastSelOp = opId;
+    hist.lastOrigin = hist.lastSelOrigin = change.origin;
+
+    if (!last) signal(doc, "historyAdded");
+  }
+
+  function selectionEventCanBeMerged(doc, origin, prev, sel) {
+    var ch = origin.charAt(0);
+    return ch == "*" ||
+      ch == "+" &&
+      prev.ranges.length == sel.ranges.length &&
+      prev.somethingSelected() == sel.somethingSelected() &&
+      new Date - doc.history.lastSelTime <= (doc.cm ? doc.cm.options.historyEventDelay : 500);
+  }
+
+  // Called whenever the selection changes, sets the new selection as
+  // the pending selection in the history, and pushes the old pending
+  // selection into the 'done' array when it was significantly
+  // different (in number of selected ranges, emptiness, or time).
+  function addSelectionToHistory(doc, sel, opId, options) {
+    var hist = doc.history, origin = options && options.origin;
+
+    // A new event is started when the previous origin does not match
+    // the current, or the origins don't allow matching. Origins
+    // starting with * are always merged, those starting with + are
+    // merged when similar and close together in time.
+    if (opId == hist.lastSelOp ||
+        (origin && hist.lastSelOrigin == origin &&
+         (hist.lastModTime == hist.lastSelTime && hist.lastOrigin == origin ||
+          selectionEventCanBeMerged(doc, origin, lst(hist.done), sel))))
+      hist.done[hist.done.length - 1] = sel;
+    else
+      pushSelectionToHistory(sel, hist.done);
+
+    hist.lastSelTime = +new Date;
+    hist.lastSelOrigin = origin;
+    hist.lastSelOp = opId;
+    if (options && options.clearRedo !== false)
+      clearSelectionEvents(hist.undone);
+  }
+
+  function pushSelectionToHistory(sel, dest) {
+    var top = lst(dest);
+    if (!(top && top.ranges && top.equals(sel)))
+      dest.push(sel);
+  }
+
+  // Used to store marked span information in the history.
+  function attachLocalSpans(doc, change, from, to) {
+    var existing = change["spans_" + doc.id], n = 0;
+    doc.iter(Math.max(doc.first, from), Math.min(doc.first + doc.size, to), function(line) {
+      if (line.markedSpans)
+        (existing || (existing = change["spans_" + doc.id] = {}))[n] = line.markedSpans;
+      ++n;
+    });
+  }
+
+  // When un/re-doing restores text containing marked spans, those
+  // that have been explicitly cleared should not be restored.
+  function removeClearedSpans(spans) {
+    if (!spans) return null;
+    for (var i = 0, out; i < spans.length; ++i) {
+      if (spans[i].marker.explicitlyCleared) { if (!out) out = spans.slice(0, i); }
+      else if (out) out.push(spans[i]);
+    }
+    return !out ? spans : out.length ? out : null;
+  }
+
+  // Retrieve and filter the old marked spans stored in a change event.
+  function getOldSpans(doc, change) {
+    var found = change["spans_" + doc.id];
+    if (!found) return null;
+    for (var i = 0, nw = []; i < change.text.length; ++i)
+      nw.push(removeClearedSpans(found[i]));
+    return nw;
+  }
+
+  // Used both to provide a JSON-safe object in .getHistory, and, when
+  // detaching a document, to split the history in two
+  function copyHistoryArray(events, newGroup, instantiateSel) {
+    for (var i = 0, copy = []; i < events.length; ++i) {
+      var event = events[i];
+      if (event.ranges) {
+        copy.push(instantiateSel ? Selection.prototype.deepCopy.call(event) : event);
+        continue;
+      }
+      var changes = event.changes, newChanges = [];
+      copy.push({changes: newChanges});
+      for (var j = 0; j < changes.length; ++j) {
+        var change = changes[j], m;
+        newChanges.push({from: change.from, to: change.to, text: change.text});
+        if (newGroup) for (var prop in change) if (m = prop.match(/^spans_(\d+)$/)) {
+          if (indexOf(newGroup, Number(m[1])) > -1) {
+            lst(newChanges)[prop] = change[prop];
+            delete change[prop];
+          }
+        }
+      }
+    }
+    return copy;
+  }
+
+  // Rebasing/resetting history to deal with externally-sourced changes
+
+  function rebaseHistSelSingle(pos, from, to, diff) {
+    if (to < pos.line) {
+      pos.line += diff;
+    } else if (from < pos.line) {
+      pos.line = from;
+      pos.ch = 0;
+    }
+  }
+
+  // Tries to rebase an array of history events given a change in the
+  // document. If the change touches the same lines as the event, the
+  // event, and everything 'behind' it, is discarded. If the change is
+  // before the event, the event's positions are updated. Uses a
+  // copy-on-write scheme for the positions, to avoid having to
+  // reallocate them all on every rebase, but also avoid problems with
+  // shared position objects being unsafely updated.
+  function rebaseHistArray(array, from, to, diff) {
+    for (var i = 0; i < array.length; ++i) {
+      var sub = array[i], ok = true;
+      if (sub.ranges) {
+        if (!sub.copied) { sub = array[i] = sub.deepCopy(); sub.copied = true; }
+        for (var j = 0; j < sub.ranges.length; j++) {
+          rebaseHistSelSingle(sub.ranges[j].anchor, from, to, diff);
+          rebaseHistSelSingle(sub.ranges[j].head, from, to, diff);
+        }
+        continue;
+      }
+      for (var j = 0; j < sub.changes.length; ++j) {
+        var cur = sub.changes[j];
+        if (to < cur.from.line) {
+          cur.from = Pos(cur.from.line + diff, cur.from.ch);
+          cur.to = Pos(cur.to.line + diff, cur.to.ch);
+        } else if (from <= cur.to.line) {
+          ok = false;
+          break;
+        }
+      }
+      if (!ok) {
+        array.splice(0, i + 1);
+        i = 0;
+      }
+    }
+  }
+
+  function rebaseHist(hist, change) {
+    var from = change.from.line, to = change.to.line, diff = change.text.length - (to - from) - 1;
+    rebaseHistArray(hist.done, from, to, diff);
+    rebaseHistArray(hist.undone, from, to, diff);
+  }
+
+  // EVENT UTILITIES
+
+  // Due to the fact that we still support jurassic IE versions, some
+  // compatibility wrappers are needed.
+
+  var e_preventDefault = CodeMirror.e_preventDefault = function(e) {
+    if (e.preventDefault) e.preventDefault();
+    else e.returnValue = false;
+  };
+  var e_stopPropagation = CodeMirror.e_stopPropagation = function(e) {
+    if (e.stopPropagation) e.stopPropagation();
+    else e.cancelBubble = true;
+  };
+  function e_defaultPrevented(e) {
+    return e.defaultPrevented != null ? e.defaultPrevented : e.returnValue == false;
+  }
+  var e_stop = CodeMirror.e_stop = function(e) {e_preventDefault(e); e_stopPropagation(e);};
+
+  function e_target(e) {return e.target || e.srcElement;}
+  function e_button(e) {
+    var b = e.which;
+    if (b == null) {
+      if (e.button & 1) b = 1;
+      else if (e.button & 2) b = 3;
+      else if (e.button & 4) b = 2;
+    }
+    if (mac && e.ctrlKey && b == 1) b = 3;
+    return b;
+  }
+
+  // EVENT HANDLING
+
+  // Lightweight event framework. on/off also work on DOM nodes,
+  // registering native DOM handlers.
+
+  var on = CodeMirror.on = function(emitter, type, f) {
+    if (emitter.addEventListener)
+      emitter.addEventListener(type, f, false);
+    else if (emitter.attachEvent)
+      emitter.attachEvent("on" + type, f);
+    else {
+      var map = emitter._handlers || (emitter._handlers = {});
+      var arr = map[type] || (map[type] = []);
+      arr.push(f);
+    }
+  };
+
+  var off = CodeMirror.off = function(emitter, type, f) {
+    if (emitter.removeEventListener)
+      emitter.removeEventListener(type, f, false);
+    else if (emitter.detachEvent)
+      emitter.detachEvent("on" + type, f);
+    else {
+      var arr = emitter._handlers && emitter._handlers[type];
+      if (!arr) return;
+      for (var i = 0; i < arr.length; ++i)
+        if (arr[i] == f) { arr.splice(i, 1); break; }
+    }
+  };
+
+  var signal = CodeMirror.signal = function(emitter, type /*, values...*/) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    if (!arr) return;
+    var args = Array.prototype.slice.call(arguments, 2);
+    for (var i = 0; i < arr.length; ++i) arr[i].apply(null, args);
+  };
+
+  var orphanDelayedCallbacks = null;
+
+  // Often, we want to signal events at a point where we are in the
+  // middle of some work, but don't want the handler to start calling
+  // other methods on the editor, which might be in an inconsistent
+  // state or simply not expect any other events to happen.
+  // signalLater looks whether there are any handlers, and schedules
+  // them to be executed when the last operation ends, or, if no
+  // operation is active, when a timeout fires.
+  function signalLater(emitter, type /*, values...*/) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    if (!arr) return;
+    var args = Array.prototype.slice.call(arguments, 2), list;
+    if (operationGroup) {
+      list = operationGroup.delayedCallbacks;
+    } else if (orphanDelayedCallbacks) {
+      list = orphanDelayedCallbacks;
+    } else {
+      list = orphanDelayedCallbacks = [];
+      setTimeout(fireOrphanDelayed, 0);
+    }
+    function bnd(f) {return function(){f.apply(null, args);};};
+    for (var i = 0; i < arr.length; ++i)
+      list.push(bnd(arr[i]));
+  }
+
+  function fireOrphanDelayed() {
+    var delayed = orphanDelayedCallbacks;
+    orphanDelayedCallbacks = null;
+    for (var i = 0; i < delayed.length; ++i) delayed[i]();
+  }
+
+  // The DOM events that CodeMirror handles can be overridden by
+  // registering a (non-DOM) handler on the editor for the event name,
+  // and preventDefault-ing the event in that handler.
+  function signalDOMEvent(cm, e, override) {
+    if (typeof e == "string")
+      e = {type: e, preventDefault: function() { this.defaultPrevented = true; }};
+    signal(cm, override || e.type, cm, e);
+    return e_defaultPrevented(e) || e.codemirrorIgnore;
+  }
+
+  function signalCursorActivity(cm) {
+    var arr = cm._handlers && cm._handlers.cursorActivity;
+    if (!arr) return;
+    var set = cm.curOp.cursorActivityHandlers || (cm.curOp.cursorActivityHandlers = []);
+    for (var i = 0; i < arr.length; ++i) if (indexOf(set, arr[i]) == -1)
+      set.push(arr[i]);
+  }
+
+  function hasHandler(emitter, type) {
+    var arr = emitter._handlers && emitter._handlers[type];
+    return arr && arr.length > 0;
+  }
+
+  // Add on and off methods to a constructor's prototype, to make
+  // registering events on such objects more convenient.
+  function eventMixin(ctor) {
+    ctor.prototype.on = function(type, f) {on(this, type, f);};
+    ctor.prototype.off = function(type, f) {off(this, type, f);};
+  }
+
+  // MISC UTILITIES
+
+  // Number of pixels added to scroller and sizer to hide scrollbar
+  var scrollerGap = 30;
+
+  // Returned or thrown by various protocols to signal 'I'm not
+  // handling this'.
+  var Pass = CodeMirror.Pass = {toString: function(){return "CodeMirror.Pass";}};
+
+  // Reused option objects for setSelection & friends
+  var sel_dontScroll = {scroll: false}, sel_mouse = {origin: "*mouse"}, sel_move = {origin: "+move"};
+
+  function Delayed() {this.id = null;}
+  Delayed.prototype.set = function(ms, f) {
+    clearTimeout(this.id);
+    this.id = setTimeout(f, ms);
+  };
+
+  // Counts the column offset in a string, taking tabs into account.
+  // Used mostly to find indentation.
+  var countColumn = CodeMirror.countColumn = function(string, end, tabSize, startIndex, startValue) {
+    if (end == null) {
+      end = string.search(/[^\s\u00a0]/);
+      if (end == -1) end = string.length;
+    }
+    for (var i = startIndex || 0, n = startValue || 0;;) {
+      var nextTab = string.indexOf("\t", i);
+      if (nextTab < 0 || nextTab >= end)
+        return n + (end - i);
+      n += nextTab - i;
+      n += tabSize - (n % tabSize);
+      i = nextTab + 1;
+    }
+  };
+
+  // The inverse of countColumn -- find the offset that corresponds to
+  // a particular column.
+  function findColumn(string, goal, tabSize) {
+    for (var pos = 0, col = 0;;) {
+      var nextTab = string.indexOf("\t", pos);
+      if (nextTab == -1) nextTab = string.length;
+      var skipped = nextTab - pos;
+      if (nextTab == string.length || col + skipped >= goal)
+        return pos + Math.min(skipped, goal - col);
+      col += nextTab - pos;
+      col += tabSize - (col % tabSize);
+      pos = nextTab + 1;
+      if (col >= goal) return pos;
+    }
+  }
+
+  var spaceStrs = [""];
+  function spaceStr(n) {
+    while (spaceStrs.length <= n)
+      spaceStrs.push(lst(spaceStrs) + " ");
+    return spaceStrs[n];
+  }
+
+  function lst(arr) { return arr[arr.length-1]; }
+
+  var selectInput = function(node) { node.select(); };
+  if (ios) // Mobile Safari apparently has a bug where select() is broken.
+    selectInput = function(node) { node.selectionStart = 0; node.selectionEnd = node.value.length; };
+  else if (ie) // Suppress mysterious IE10 errors
+    selectInput = function(node) { try { node.select(); } catch(_e) {} };
+
+  function indexOf(array, elt) {
+    for (var i = 0; i < array.length; ++i)
+      if (array[i] == elt) return i;
+    return -1;
+  }
+  function map(array, f) {
+    var out = [];
+    for (var i = 0; i < array.length; i++) out[i] = f(array[i], i);
+    return out;
+  }
+
+  function nothing() {}
+
+  function createObj(base, props) {
+    var inst;
+    if (Object.create) {
+      inst = Object.create(base);
+    } else {
+      nothing.prototype = base;
+      inst = new nothing();
+    }
+    if (props) copyObj(props, inst);
+    return inst;
+  };
+
+  function copyObj(obj, target, overwrite) {
+    if (!target) target = {};
+    for (var prop in obj)
+      if (obj.hasOwnProperty(prop) && (overwrite !== false || !target.hasOwnProperty(prop)))
+        target[prop] = obj[prop];
+    return target;
+  }
+
+  function bind(f) {
+    var args = Array.prototype.slice.call(arguments, 1);
+    return function(){return f.apply(null, args);};
+  }
+
+  var nonASCIISingleCaseWordChar = /[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;
+  var isWordCharBasic = CodeMirror.isWordChar = function(ch) {
+    return /\w/.test(ch) || ch > "\x80" &&
+      (ch.toUpperCase() != ch.toLowerCase() || nonASCIISingleCaseWordChar.test(ch));
+  };
+  function isWordChar(ch, helper) {
+    if (!helper) return isWordCharBasic(ch);
+    if (helper.source.indexOf("\\w") > -1 && isWordCharBasic(ch)) return true;
+    return helper.test(ch);
+  }
+
+  function isEmpty(obj) {
+    for (var n in obj) if (obj.hasOwnProperty(n) && obj[n]) return false;
+    return true;
+  }
+
+  // Extending unicode characters. A series of a non-extending char +
+  // any number of extending chars is treated as a single unit as far
+  // as editing and measuring is concerned. This is not fully correct,
+  // since some scripts/fonts/browsers also treat other configurations
+  // of code points as a group.
+  var extendingChars = /[\u0300-\u036f\u0483-\u0489\u0591-\u05bd\u05bf\u05c1\u05c2\u05c4\u05c5\u05c7\u0610-\u061a\u064b-\u065e\u0670\u06d6-\u06dc\u06de-\u06e4\u06e7\u06e8\u06ea-\u06ed\u0711\u0730-\u074a\u07a6-\u07b0\u07eb-\u07f3\u0816-\u0819\u081b-\u0823\u0825-\u0827\u0829-\u082d\u0900-\u0902\u093c\u0941-\u0948\u094d\u0951-\u0955\u0962\u0963\u0981\u09bc\u09be\u09c1-\u09c4\u09cd\u09d7\u09e2\u09e3\u0a01\u0a02\u0a3c\u0a41\u0a42\u0a47\u0a48\u0a4b-\u0a4d\u0a51\u0a70\u0a71\u0a75\u0a81\u0a82\u0abc\u0ac1-\u0ac5\u0ac7\u0ac8\u0acd\u0ae2\u0ae3\u0b01\u0b3c\u0b3e\u0b3f\u0b41-\u0b44\u0b4d\u0b56\u0b57\u0b62\u0b63\u0b82\u0bbe\u0bc0\u0bcd\u0bd7\u0c3e-\u0c40\u0c46-\u0c48\u0c4a-\u0c4d\u0c55\u0c56\u0c62\u0c63\u0cbc\u0cbf\u0cc2\u0cc6\u0ccc\u0ccd\u0cd5\u0cd6\u0ce2\u0ce3\u0d3e\u0d41-\u0d44\u0d4d\u0d57\u0d62\u0d63\u0dca\u0dcf\u0dd2-\u0dd4\u0dd6\u0ddf\u0e31\u0e34-\u0e3a\u0e47-\u0e4e\u0eb1\u0eb4-\u0eb9\u0ebb\u0ebc\u0ec8-\u0ecd\u0f18\u0f19\u0f35\u0f37\u0f39\u0f71-\u0f7e\u0f80-\u0f84\u0f86\u0f87\u0f90-\u0f97\u0f99-\u0fbc\u0fc6\u102d-\u1030\u1032-\u1037\u1039\u103a\u103d\u103e\u1058\u1059\u105e-\u1060\u1071-\u1074\u1082\u1085\u1086\u108d\u109d\u135f\u1712-\u1714\u1732-\u1734\u1752\u1753\u1772\u1773\u17b7-\u17bd\u17c6\u17c9-\u17d3\u17dd\u180b-\u180d\u18a9\u1920-\u1922\u1927\u1928\u1932\u1939-\u193b\u1a17\u1a18\u1a56\u1a58-\u1a5e\u1a60\u1a62\u1a65-\u1a6c\u1a73-\u1a7c\u1a7f\u1b00-\u1b03\u1b34\u1b36-\u1b3a\u1b3c\u1b42\u1b6b-\u1b73\u1b80\u1b81\u1ba2-\u1ba5\u1ba8\u1ba9\u1c2c-\u1c33\u1c36\u1c37\u1cd0-\u1cd2\u1cd4-\u1ce0\u1ce2-\u1ce8\u1ced\u1dc0-\u1de6\u1dfd-\u1dff\u200c\u200d\u20d0-\u20f0\u2cef-\u2cf1\u2de0-\u2dff\u302a-\u302f\u3099\u309a\ua66f-\ua672\ua67c\ua67d\ua6f0\ua6f1\ua802\ua806\ua80b\ua825\ua826\ua8c4\ua8e0-\ua8f1\ua926-\ua92d\ua947-\ua951\ua980-\ua982\ua9b3\ua9b6-\ua9b9\ua9bc\uaa29-\uaa2e\uaa31\uaa32\uaa35\uaa36\uaa43\uaa4c\uaab0\uaab2-\uaab4\uaab7\uaab8\uaabe\uaabf\uaac1\uabe5\uabe8\uabed\udc00-\udfff\ufb1e\ufe00-\ufe0f\ufe20-\ufe26\uff9e\uff9f]/;
+  function isExtendingChar(ch) { return ch.charCodeAt(0) >= 768 && extendingChars.test(ch); }
+
+  // DOM UTILITIES
+
+  function elt(tag, content, className, style) {
+    var e = document.createElement(tag);
+    if (className) e.className = className;
+    if (style) e.style.cssText = style;
+    if (typeof content == "string") e.appendChild(document.createTextNode(content));
+    else if (content) for (var i = 0; i < content.length; ++i) e.appendChild(content[i]);
+    return e;
+  }
+
+  var range;
+  if (document.createRange) range = function(node, start, end, endNode) {
+    var r = document.createRange();
+    r.setEnd(endNode || node, end);
+    r.setStart(node, start);
+    return r;
+  };
+  else range = function(node, start, end) {
+    var r = document.body.createTextRange();
+    try { r.moveToElementText(node.parentNode); }
+    catch(e) { return r; }
+    r.collapse(true);
+    r.moveEnd("character", end);
+    r.moveStart("character", start);
+    return r;
+  };
+
+  function removeChildren(e) {
+    for (var count = e.childNodes.length; count > 0; --count)
+      e.removeChild(e.firstChild);
+    return e;
+  }
+
+  function removeChildrenAndAdd(parent, e) {
+    return removeChildren(parent).appendChild(e);
+  }
+
+  var contains = CodeMirror.contains = function(parent, child) {
+    if (child.nodeType == 3) // Android browser always returns false when child is a textnode
+      child = child.parentNode;
+    if (parent.contains)
+      return parent.contains(child);
+    do {
+      if (child.nodeType == 11) child = child.host;
+      if (child == parent) return true;
+    } while (child = child.parentNode);
+  };
+
+  function activeElt() { return document.activeElement; }
+  // Older versions of IE throws unspecified error when touching
+  // document.activeElement in some cases (during loading, in iframe)
+  if (ie && ie_version < 11) activeElt = function() {
+    try { return document.activeElement; }
+    catch(e) { return document.body; }
+  };
+
+  function classTest(cls) { return new RegExp("(^|\\s)" + cls + "(?:$|\\s)\\s*"); }
+  var rmClass = CodeMirror.rmClass = function(node, cls) {
+    var current = node.className;
+    var match = classTest(cls).exec(current);
+    if (match) {
+      var after = current.slice(match.index + match[0].length);
+      node.className = current.slice(0, match.index) + (after ? match[1] + after : "");
+    }
+  };
+  var addClass = CodeMirror.addClass = function(node, cls) {
+    var current = node.className;
+    if (!classTest(cls).test(current)) node.className += (current ? " " : "") + cls;
+  };
+  function joinClasses(a, b) {
+    var as = a.split(" ");
+    for (var i = 0; i < as.length; i++)
+      if (as[i] && !classTest(as[i]).test(b)) b += " " + as[i];
+    return b;
+  }
+
+  // WINDOW-WIDE EVENTS
+
+  // These must be handled carefully, because naively registering a
+  // handler for each editor will cause the editors to never be
+  // garbage collected.
+
+  function forEachCodeMirror(f) {
+    if (!document.body.getElementsByClassName) return;
+    var byClass = document.body.getElementsByClassName("CodeMirror");
+    for (var i = 0; i < byClass.length; i++) {
+      var cm = byClass[i].CodeMirror;
+      if (cm) f(cm);
+    }
+  }
+
+  var globalsRegistered = false;
+  function ensureGlobalHandlers() {
+    if (globalsRegistered) return;
+    registerGlobalHandlers();
+    globalsRegistered = true;
+  }
+  function registerGlobalHandlers() {
+    // When the window resizes, we need to refresh active editors.
+    var resizeTimer;
+    on(window, "resize", function() {
+      if (resizeTimer == null) resizeTimer = setTimeout(function() {
+        resizeTimer = null;
+        forEachCodeMirror(onResize);
+      }, 100);
+    });
+    // When the window loses focus, we want to show the editor as blurred
+    on(window, "blur", function() {
+      forEachCodeMirror(onBlur);
+    });
+  }
+
+  // FEATURE DETECTION
+
+  // Detect drag-and-drop
+  var dragAndDrop = function() {
+    // There is *some* kind of drag-and-drop support in IE6-8, but I
+    // couldn't get it to work yet.
+    if (ie && ie_version < 9) return false;
+    var div = elt('div');
+    return "draggable" in div || "dragDrop" in div;
+  }();
+
+  var zwspSupported;
+  function zeroWidthElement(measure) {
+    if (zwspSupported == null) {
+      var test = elt("span", "\u200b");
+      removeChildrenAndAdd(measure, elt("span", [test, document.createTextNode("x")]));
+      if (measure.firstChild.offsetHeight != 0)
+        zwspSupported = test.offsetWidth <= 1 && test.offsetHeight > 2 && !(ie && ie_version < 8);
+    }
+    var node = zwspSupported ? elt("span", "\u200b") :
+      elt("span", "\u00a0", null, "display: inline-block; width: 1px; margin-right: -1px");
+    node.setAttribute("cm-text", "");
+    return node;
+  }
+
+  // Feature-detect IE's crummy client rect reporting for bidi text
+  var badBidiRects;
+  function hasBadBidiRects(measure) {
+    if (badBidiRects != null) return badBidiRects;
+    var txt = removeChildrenAndAdd(measure, document.createTextNode("A\u062eA"));
+    var r0 = range(txt, 0, 1).getBoundingClientRect();
+    if (!r0 || r0.left == r0.right) return false; // Safari returns null in some cases (#2780)
+    var r1 = range(txt, 1, 2).getBoundingClientRect();
+    return badBidiRects = (r1.right - r0.right < 3);
+  }
+
+  // See if "".split is the broken IE version, if so, provide an
+  // alternative way to split lines.
+  var splitLines = CodeMirror.splitLines = "\n\nb".split(/\n/).length != 3 ? function(string) {
+    var pos = 0, result = [], l = string.length;
+    while (pos <= l) {
+      var nl = string.indexOf("\n", pos);
+      if (nl == -1) nl = string.length;
+      var line = string.slice(pos, string.charAt(nl - 1) == "\r" ? nl - 1 : nl);
+      var rt = line.indexOf("\r");
+      if (rt != -1) {
+        result.push(line.slice(0, rt));
+        pos += rt + 1;
+      } else {
+        result.push(line);
+        pos = nl + 1;
+      }
+    }
+    return result;
+  } : function(string){return string.split(/\r\n?|\n/);};
+
+  var hasSelection = window.getSelection ? function(te) {
+    try { return te.selectionStart != te.selectionEnd; }
+    catch(e) { return false; }
+  } : function(te) {
+    try {var range = te.ownerDocument.selection.createRange();}
+    catch(e) {}
+    if (!range || range.parentElement() != te) return false;
+    return range.compareEndPoints("StartToEnd", range) != 0;
+  };
+
+  var hasCopyEvent = (function() {
+    var e = elt("div");
+    if ("oncopy" in e) return true;
+    e.setAttribute("oncopy", "return;");
+    return typeof e.oncopy == "function";
+  })();
+
+  var badZoomedRects = null;
+  function hasBadZoomedRects(measure) {
+    if (badZoomedRects != null) return badZoomedRects;
+    var node = removeChildrenAndAdd(measure, elt("span", "x"));
+    var normal = node.getBoundingClientRect();
+    var fromRange = range(node, 0, 1).getBoundingClientRect();
+    return badZoomedRects = Math.abs(normal.left - fromRange.left) > 1;
+  }
+
+  // KEY NAMES
+
+  var keyNames = {3: "Enter", 8: "Backspace", 9: "Tab", 13: "Enter", 16: "Shift", 17: "Ctrl", 18: "Alt",
+                  19: "Pause", 20: "CapsLock", 27: "Esc", 32: "Space", 33: "PageUp", 34: "PageDown", 35: "End",
+                  36: "Home", 37: "Left", 38: "Up", 39: "Right", 40: "Down", 44: "PrintScrn", 45: "Insert",
+                  46: "Delete", 59: ";", 61: "=", 91: "Mod", 92: "Mod", 93: "Mod", 107: "=", 109: "-", 127: "Delete",
+                  173: "-", 186: ";", 187: "=", 188: ",", 189: "-", 190: ".", 191: "/", 192: "`", 219: "[", 220: "\\",
+                  221: "]", 222: "'", 63232: "Up", 63233: "Down", 63234: "Left", 63235: "Right", 63272: "Delete",
+                  63273: "Home", 63275: "End", 63276: "PageUp", 63277: "PageDown", 63302: "Insert"};
+  CodeMirror.keyNames = keyNames;
+  (function() {
+    // Number keys
+    for (var i = 0; i < 10; i++) keyNames[i + 48] = keyNames[i + 96] = String(i);
+    // Alphabetic keys
+    for (var i = 65; i <= 90; i++) keyNames[i] = String.fromCharCode(i);
+    // Function keys
+    for (var i = 1; i <= 12; i++) keyNames[i + 111] = keyNames[i + 63235] = "F" + i;
+  })();
+
+  // BIDI HELPERS
+
+  function iterateBidiSections(order, from, to, f) {
+    if (!order) return f(from, to, "ltr");
+    var found = false;
+    for (var i = 0; i < order.length; ++i) {
+      var part = order[i];
+      if (part.from < to && part.to > from || from == to && part.to == from) {
+        f(Math.max(part.from, from), Math.min(part.to, to), part.level == 1 ? "rtl" : "ltr");
+        found = true;
+      }
+    }
+    if (!found) f(from, to, "ltr");
+  }
+
+  function bidiLeft(part) { return part.level % 2 ? part.to : part.from; }
+  function bidiRight(part) { return part.level % 2 ? part.from : part.to; }
+
+  function lineLeft(line) { var order = getOrder(line); return order ? bidiLeft(order[0]) : 0; }
+  function lineRight(line) {
+    var order = getOrder(line);
+    if (!order) return line.text.length;
+    return bidiRight(lst(order));
+  }
+
+  function lineStart(cm, lineN) {
+    var line = getLine(cm.doc, lineN);
+    var visual = visualLine(line);
+    if (visual != line) lineN = lineNo(visual);
+    var order = getOrder(visual);
+    var ch = !order ? 0 : order[0].level % 2 ? lineRight(visual) : lineLeft(visual);
+    return Pos(lineN, ch);
+  }
+  function lineEnd(cm, lineN) {
+    var merged, line = getLine(cm.doc, lineN);
+    while (merged = collapsedSpanAtEnd(line)) {
+      line = merged.find(1, true).line;
+      lineN = null;
+    }
+    var order = getOrder(line);
+    var ch = !order ? line.text.length : order[0].level % 2 ? lineLeft(line) : lineRight(line);
+    return Pos(lineN == null ? lineNo(line) : lineN, ch);
+  }
+  function lineStartSmart(cm, pos) {
+    var start = lineStart(cm, pos.line);
+    var line = getLine(cm.doc, start.line);
+    var order = getOrder(line);
+    if (!order || order[0].level == 0) {
+      var firstNonWS = Math.max(0, line.text.search(/\S/));
+      var inWS = pos.line == start.line && pos.ch <= firstNonWS && pos.ch;
+      return Pos(start.line, inWS ? 0 : firstNonWS);
+    }
+    return start;
+  }
+
+  function compareBidiLevel(order, a, b) {
+    var linedir = order[0].level;
+    if (a == linedir) return true;
+    if (b == linedir) return false;
+    return a < b;
+  }
+  var bidiOther;
+  function getBidiPartAt(order, pos) {
+    bidiOther = null;
+    for (var i = 0, found; i < order.length; ++i) {
+      var cur = order[i];
+      if (cur.from < pos && cur.to > pos) return i;
+      if ((cur.from == pos || cur.to == pos)) {
+        if (found == null) {
+          found = i;
+        } else if (compareBidiLevel(order, cur.level, order[found].level)) {
+          if (cur.from != cur.to) bidiOther = found;
+          return i;
+        } else {
+          if (cur.from != cur.to) bidiOther = i;
+          return found;
+        }
+      }
+    }
+    return found;
+  }
+
+  function moveInLine(line, pos, dir, byUnit) {
+    if (!byUnit) return pos + dir;
+    do pos += dir;
+    while (pos > 0 && isExtendingChar(line.text.charAt(pos)));
+    return pos;
+  }
+
+  // This is needed in order to move 'visually' through bi-directional
+  // text -- i.e., pressing left should make the cursor go left, even
+  // when in RTL text. The tricky part is the 'jumps', where RTL and
+  // LTR text touch each other. This often requires the cursor offset
+  // to move more than one unit, in order to visually move one unit.
+  function moveVisually(line, start, dir, byUnit) {
+    var bidi = getOrder(line);
+    if (!bidi) return moveLogically(line, start, dir, byUnit);
+    var pos = getBidiPartAt(bidi, start), part = bidi[pos];
+    var target = moveInLine(line, start, part.level % 2 ? -dir : dir, byUnit);
+
+    for (;;) {
+      if (target > part.from && target < part.to) return target;
+      if (target == part.from || target == part.to) {
+        if (getBidiPartAt(bidi, target) == pos) return target;
+        part = bidi[pos += dir];
+        return (dir > 0) == part.level % 2 ? part.to : part.from;
+      } else {
+        part = bidi[pos += dir];
+        if (!part) return null;
+        if ((dir > 0) == part.level % 2)
+          target = moveInLine(line, part.to, -1, byUnit);
+        else
+          target = moveInLine(line, part.from, 1, byUnit);
+      }
+    }
+  }
+
+  function moveLogically(line, start, dir, byUnit) {
+    var target = start + dir;
+    if (byUnit) while (target > 0 && isExtendingChar(line.text.charAt(target))) target += dir;
+    return target < 0 || target > line.text.length ? null : target;
+  }
+
+  // Bidirectional ordering algorithm
+  // See http://unicode.org/reports/tr9/tr9-13.html for the algorithm
+  // that this (partially) implements.
+
+  // One-char codes used for character types:
+  // L (L):   Left-to-Right
+  // R (R):   Right-to-Left
+  // r (AL):  Right-to-Left Arabic
+  // 1 (EN):  European Number
+  // + (ES):  European Number Separator
+  // % (ET):  European Number Terminator
+  // n (AN):  Arabic Number
+  // , (CS):  Common Number Separator
+  // m (NSM): Non-Spacing Mark
+  // b (BN):  Boundary Neutral
+  // s (B):   Paragraph Separator
+  // t (S):   Segment Separator
+  // w (WS):  Whitespace
+  // N (ON):  Other Neutrals
+
+  // Returns null if characters are ordered as they appear
+  // (left-to-right), or an array of sections ({from, to, level}
+  // objects) in the order in which they occur visually.
+  var bidiOrdering = (function() {
+    // Character types for codepoints 0 to 0xff
+    var lowTypes = "bbbbbbbbbtstwsbbbbbbbbbbbbbbssstwNN%%%NNNNNN,N,N1111111111NNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNNNLLLLLLLLLLLLLLLLLLLLLLLLLLNNNNbbbbbbsbbbbbbbbbbbbbbbbbbbbbbbbbb,N%%%%NNNNLNNNNN%%11NLNNN1LNNNNNLLLLLLLLLLLLLLLLLLLLLLLNLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLN";
+    // Character types for codepoints 0x600 to 0x6ff
+    var arabicTypes = "rrrrrrrrrrrr,rNNmmmmmmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmrrrrrrrnnnnnnnnnn%nnrrrmrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrmmmmmmmmmmmmmmmmmmmNmmmm";
+    function charType(code) {
+      if (code <= 0xf7) return lowTypes.charAt(code);
+      else if (0x590 <= code && code <= 0x5f4) return "R";
+      else if (0x600 <= code && code <= 0x6ed) return arabicTypes.charAt(code - 0x600);
+      else if (0x6ee <= code && code <= 0x8ac) return "r";
+      else if (0x2000 <= code && code <= 0x200b) return "w";
+      else if (code == 0x200c) return "b";
+      else return "L";
+    }
+
+    var bidiRE = /[\u0590-\u05f4\u0600-\u06ff\u0700-\u08ac]/;
+    var isNeutral = /[stwN]/, isStrong = /[LRr]/, countsAsLeft = /[Lb1n]/, countsAsNum = /[1n]/;
+    // Browsers seem to always treat the boundaries of block elements as being L.
+    var outerType = "L";
+
+    function BidiSpan(level, from, to) {
+      this.level = level;
+      this.from = from; this.to = to;
+    }
+
+    return function(str) {
+      if (!bidiRE.test(str)) return false;
+      var len = str.length, types = [];
+      for (var i = 0, type; i < len; ++i)
+        types.push(type = charType(str.charCodeAt(i)));
+
+      // W1. Examine each non-spacing mark (NSM) in the level run, and
+      // change the type of the NSM to the type of the previous
+      // character. If the NSM is at the start of the level run, it will
+      // get the type of sor.
+      for (var i = 0, prev = outerType; i < len; ++i) {
+        var type = types[i];
+        if (type == "m") types[i] = prev;
+        else prev = type;
+      }
+
+      // W2. Search backwards from each instance of a European number
+      // until the first strong type (R, L, AL, or sor) is found. If an
+      // AL is found, change the type of the European number to Arabic
+      // number.
+      // W3. Change all ALs to R.
+      for (var i = 0, cur = outerType; i < len; ++i) {
+        var type = types[i];
+        if (type == "1" && cur == "r") types[i] = "n";
+        else if (isStrong.test(type)) { cur = type; if (type == "r") types[i] = "R"; }
+      }
+
+      // W4. A single European separator between two European numbers
+      // changes to a European number. A single common separator between
+      // two numbers of the same type changes to that type.
+      for (var i = 1, prev = types[0]; i < len - 1; ++i) {
+        var type = types[i];
+        if (type == "+" && prev == "1" && types[i+1] == "1") types[i] = "1";
+        else if (type == "," && prev == types[i+1] &&
+                 (prev == "1" || prev == "n")) types[i] = prev;
+        prev = type;
+      }
+
+      // W5. A sequence of European terminators adjacent to European
+      // numbers changes to all European numbers.
+      // W6. Otherwise, separators and terminators change to Other
+      // Neutral.
+      for (var i = 0; i < len; ++i) {
+        var type = types[i];
+        if (type == ",") types[i] = "N";
+        else if (type == "%") {
+          for (var end = i + 1; end < len && types[end] == "%"; ++end) {}
+          var replace = (i && types[i-1] == "!") || (end < len && types[end] == "1") ? "1" : "N";
+          for (var j = i; j < end; ++j) types[j] = replace;
+          i = end - 1;
+        }
+      }
+
+      // W7. Search backwards from each instance of a European number
+      // until the first strong type (R, L, or sor) is found. If an L is
+      // found, then change the type of the European number to L.
+      for (var i = 0, cur = outerType; i < len; ++i) {
+        var type = types[i];
+        if (cur == "L" && type == "1") types[i] = "L";
+        else if (isStrong.test(type)) cur = type;
+      }
+
+      // N1. A sequence of neutrals takes the direction of the
+      // surrounding strong text if the text on both sides has the same
+      // direction. European and Arabic numbers act as if they were R in
+      // terms of their influence on neutrals. Start-of-level-run (sor)
+      // and end-of-level-run (eor) are used at level run boundaries.
+      // N2. Any remaining neutrals take the embedding direction.
+      for (var i = 0; i < len; ++i) {
+        if (isNeutral.test(types[i])) {
+          for (var end = i + 1; end < len && isNeutral.test(types[end]); ++end) {}
+          var before = (i ? types[i-1] : outerType) == "L";
+          var after = (end < len ? types[end] : outerType) == "L";
+          var replace = before || after ? "L" : "R";
+          for (var j = i; j < end; ++j) types[j] = replace;
+          i = end - 1;
+        }
+      }
+
+      // Here we depart from the documented algorithm, in order to avoid
+      // building up an actual levels array. Since there are only three
+      // levels (0, 1, 2) in an implementation that doesn't take
+      // explicit embedding into account, we can build up the order on
+      // the fly, without following the level-based algorithm.
+      var order = [], m;
+      for (var i = 0; i < len;) {
+        if (countsAsLeft.test(types[i])) {
+          var start = i;
+          for (++i; i < len && countsAsLeft.test(types[i]); ++i) {}
+          order.push(new BidiSpan(0, start, i));
+        } else {
+          var pos = i, at = order.length;
+          for (++i; i < len && types[i] != "L"; ++i) {}
+          for (var j = pos; j < i;) {
+            if (countsAsNum.test(types[j])) {
+              if (pos < j) order.splice(at, 0, new BidiSpan(1, pos, j));
+              var nstart = j;
+              for (++j; j < i && countsAsNum.test(types[j]); ++j) {}
+              order.splice(at, 0, new BidiSpan(2, nstart, j));
+              pos = j;
+            } else ++j;
+          }
+          if (pos < i) order.splice(at, 0, new BidiSpan(1, pos, i));
+        }
+      }
+      if (order[0].level == 1 && (m = str.match(/^\s+/))) {
+        order[0].from = m[0].length;
+        order.unshift(new BidiSpan(0, 0, m[0].length));
+      }
+      if (lst(order).level == 1 && (m = str.match(/\s+$/))) {
+        lst(order).to -= m[0].length;
+        order.push(new BidiSpan(0, len - m[0].length, len));
+      }
+      if (order[0].level == 2)
+        order.unshift(new BidiSpan(1, order[0].to, order[0].to));
+      if (order[0].level != lst(order).level)
+        order.push(new BidiSpan(order[0].level, len, len));
+
+      return order;
+    };
+  })();
+
+  // THE END
+
+  CodeMirror.version = "5.2.0";
+
+  return CodeMirror;
+});
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/javascript.js b/sources/samples/toolbarconfigurator/lib/codemirror/javascript.js
new file mode 100644 (file)
index 0000000..ef01847
--- /dev/null
@@ -0,0 +1,701 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+// TODO actually recognize syntax of TypeScript constructs
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+"use strict";
+
+CodeMirror.defineMode("javascript", function(config, parserConfig) {
+  var indentUnit = config.indentUnit;
+  var statementIndent = parserConfig.statementIndent;
+  var jsonldMode = parserConfig.jsonld;
+  var jsonMode = parserConfig.json || jsonldMode;
+  var isTS = parserConfig.typescript;
+  var wordRE = parserConfig.wordCharacters || /[\w$\xa1-\uffff]/;
+
+  // Tokenizer
+
+  var keywords = function(){
+    function kw(type) {return {type: type, style: "keyword"};}
+    var A = kw("keyword a"), B = kw("keyword b"), C = kw("keyword c");
+    var operator = kw("operator"), atom = {type: "atom", style: "atom"};
+
+    var jsKeywords = {
+      "if": kw("if"), "while": A, "with": A, "else": B, "do": B, "try": B, "finally": B,
+      "return": C, "break": C, "continue": C, "new": C, "delete": C, "throw": C, "debugger": C,
+      "var": kw("var"), "const": kw("var"), "let": kw("var"),
+      "function": kw("function"), "catch": kw("catch"),
+      "for": kw("for"), "switch": kw("switch"), "case": kw("case"), "default": kw("default"),
+      "in": operator, "typeof": operator, "instanceof": operator,
+      "true": atom, "false": atom, "null": atom, "undefined": atom, "NaN": atom, "Infinity": atom,
+      "this": kw("this"), "module": kw("module"), "class": kw("class"), "super": kw("atom"),
+      "yield": C, "export": kw("export"), "import": kw("import"), "extends": C
+    };
+
+    // Extend the 'normal' keywords with the TypeScript language extensions
+    if (isTS) {
+      var type = {type: "variable", style: "variable-3"};
+      var tsKeywords = {
+        // object-like things
+        "interface": kw("interface"),
+        "extends": kw("extends"),
+        "constructor": kw("constructor"),
+
+        // scope modifiers
+        "public": kw("public"),
+        "private": kw("private"),
+        "protected": kw("protected"),
+        "static": kw("static"),
+
+        // types
+        "string": type, "number": type, "bool": type, "any": type
+      };
+
+      for (var attr in tsKeywords) {
+        jsKeywords[attr] = tsKeywords[attr];
+      }
+    }
+
+    return jsKeywords;
+  }();
+
+  var isOperatorChar = /[+\-*&%=<>!?|~^]/;
+  var isJsonldKeyword = /^@(context|id|value|language|type|container|list|set|reverse|index|base|vocab|graph)"/;
+
+  function readRegexp(stream) {
+    var escaped = false, next, inSet = false;
+    while ((next = stream.next()) != null) {
+      if (!escaped) {
+        if (next == "/" && !inSet) return;
+        if (next == "[") inSet = true;
+        else if (inSet && next == "]") inSet = false;
+      }
+      escaped = !escaped && next == "\\";
+    }
+  }
+
+  // Used as scratch variables to communicate multiple values without
+  // consing up tons of objects.
+  var type, content;
+  function ret(tp, style, cont) {
+    type = tp; content = cont;
+    return style;
+  }
+  function tokenBase(stream, state) {
+    var ch = stream.next();
+    if (ch == '"' || ch == "'") {
+      state.tokenize = tokenString(ch);
+      return state.tokenize(stream, state);
+    } else if (ch == "." && stream.match(/^\d+(?:[eE][+\-]?\d+)?/)) {
+      return ret("number", "number");
+    } else if (ch == "." && stream.match("..")) {
+      return ret("spread", "meta");
+    } else if (/[\[\]{}\(\),;\:\.]/.test(ch)) {
+      return ret(ch);
+    } else if (ch == "=" && stream.eat(">")) {
+      return ret("=>", "operator");
+    } else if (ch == "0" && stream.eat(/x/i)) {
+      stream.eatWhile(/[\da-f]/i);
+      return ret("number", "number");
+    } else if (/\d/.test(ch)) {
+      stream.match(/^\d*(?:\.\d*)?(?:[eE][+\-]?\d+)?/);
+      return ret("number", "number");
+    } else if (ch == "/") {
+      if (stream.eat("*")) {
+        state.tokenize = tokenComment;
+        return tokenComment(stream, state);
+      } else if (stream.eat("/")) {
+        stream.skipToEnd();
+        return ret("comment", "comment");
+      } else if (state.lastType == "operator" || state.lastType == "keyword c" ||
+               state.lastType == "sof" || /^[\[{}\(,;:]$/.test(state.lastType)) {
+        readRegexp(stream);
+        stream.match(/^\b(([gimyu])(?![gimyu]*\2))+\b/);
+        return ret("regexp", "string-2");
+      } else {
+        stream.eatWhile(isOperatorChar);
+        return ret("operator", "operator", stream.current());
+      }
+    } else if (ch == "`") {
+      state.tokenize = tokenQuasi;
+      return tokenQuasi(stream, state);
+    } else if (ch == "#") {
+      stream.skipToEnd();
+      return ret("error", "error");
+    } else if (isOperatorChar.test(ch)) {
+      stream.eatWhile(isOperatorChar);
+      return ret("operator", "operator", stream.current());
+    } else if (wordRE.test(ch)) {
+      stream.eatWhile(wordRE);
+      var word = stream.current(), known = keywords.propertyIsEnumerable(word) && keywords[word];
+      return (known && state.lastType != ".") ? ret(known.type, known.style, word) :
+                     ret("variable", "variable", word);
+    }
+  }
+
+  function tokenString(quote) {
+    return function(stream, state) {
+      var escaped = false, next;
+      if (jsonldMode && stream.peek() == "@" && stream.match(isJsonldKeyword)){
+        state.tokenize = tokenBase;
+        return ret("jsonld-keyword", "meta");
+      }
+      while ((next = stream.next()) != null) {
+        if (next == quote && !escaped) break;
+        escaped = !escaped && next == "\\";
+      }
+      if (!escaped) state.tokenize = tokenBase;
+      return ret("string", "string");
+    };
+  }
+
+  function tokenComment(stream, state) {
+    var maybeEnd = false, ch;
+    while (ch = stream.next()) {
+      if (ch == "/" && maybeEnd) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      maybeEnd = (ch == "*");
+    }
+    return ret("comment", "comment");
+  }
+
+  function tokenQuasi(stream, state) {
+    var escaped = false, next;
+    while ((next = stream.next()) != null) {
+      if (!escaped && (next == "`" || next == "$" && stream.eat("{"))) {
+        state.tokenize = tokenBase;
+        break;
+      }
+      escaped = !escaped && next == "\\";
+    }
+    return ret("quasi", "string-2", stream.current());
+  }
+
+  var brackets = "([{}])";
+  // This is a crude lookahead trick to try and notice that we're
+  // parsing the argument patterns for a fat-arrow function before we
+  // actually hit the arrow token. It only works if the arrow is on
+  // the same line as the arguments and there's no strange noise
+  // (comments) in between. Fallback is to only notice when we hit the
+  // arrow, and not declare the arguments as locals for the arrow
+  // body.
+  function findFatArrow(stream, state) {
+    if (state.fatArrowAt) state.fatArrowAt = null;
+    var arrow = stream.string.indexOf("=>", stream.start);
+    if (arrow < 0) return;
+
+    var depth = 0, sawSomething = false;
+    for (var pos = arrow - 1; pos >= 0; --pos) {
+      var ch = stream.string.charAt(pos);
+      var bracket = brackets.indexOf(ch);
+      if (bracket >= 0 && bracket < 3) {
+        if (!depth) { ++pos; break; }
+        if (--depth == 0) break;
+      } else if (bracket >= 3 && bracket < 6) {
+        ++depth;
+      } else if (wordRE.test(ch)) {
+        sawSomething = true;
+      } else if (/["'\/]/.test(ch)) {
+        return;
+      } else if (sawSomething && !depth) {
+        ++pos;
+        break;
+      }
+    }
+    if (sawSomething && !depth) state.fatArrowAt = pos;
+  }
+
+  // Parser
+
+  var atomicTypes = {"atom": true, "number": true, "variable": true, "string": true, "regexp": true, "this": true, "jsonld-keyword": true};
+
+  function JSLexical(indented, column, type, align, prev, info) {
+    this.indented = indented;
+    this.column = column;
+    this.type = type;
+    this.prev = prev;
+    this.info = info;
+    if (align != null) this.align = align;
+  }
+
+  function inScope(state, varname) {
+    for (var v = state.localVars; v; v = v.next)
+      if (v.name == varname) return true;
+    for (var cx = state.context; cx; cx = cx.prev) {
+      for (var v = cx.vars; v; v = v.next)
+        if (v.name == varname) return true;
+    }
+  }
+
+  function parseJS(state, style, type, content, stream) {
+    var cc = state.cc;
+    // Communicate our context to the combinators.
+    // (Less wasteful than consing up a hundred closures on every call.)
+    cx.state = state; cx.stream = stream; cx.marked = null, cx.cc = cc; cx.style = style;
+
+    if (!state.lexical.hasOwnProperty("align"))
+      state.lexical.align = true;
+
+    while(true) {
+      var combinator = cc.length ? cc.pop() : jsonMode ? expression : statement;
+      if (combinator(type, content)) {
+        while(cc.length && cc[cc.length - 1].lex)
+          cc.pop()();
+        if (cx.marked) return cx.marked;
+        if (type == "variable" && inScope(state, content)) return "variable-2";
+        return style;
+      }
+    }
+  }
+
+  // Combinator utils
+
+  var cx = {state: null, column: null, marked: null, cc: null};
+  function pass() {
+    for (var i = arguments.length - 1; i >= 0; i--) cx.cc.push(arguments[i]);
+  }
+  function cont() {
+    pass.apply(null, arguments);
+    return true;
+  }
+  function register(varname) {
+    function inList(list) {
+      for (var v = list; v; v = v.next)
+        if (v.name == varname) return true;
+      return false;
+    }
+    var state = cx.state;
+    if (state.context) {
+      cx.marked = "def";
+      if (inList(state.localVars)) return;
+      state.localVars = {name: varname, next: state.localVars};
+    } else {
+      if (inList(state.globalVars)) return;
+      if (parserConfig.globalVars)
+        state.globalVars = {name: varname, next: state.globalVars};
+    }
+  }
+
+  // Combinators
+
+  var defaultVars = {name: "this", next: {name: "arguments"}};
+  function pushcontext() {
+    cx.state.context = {prev: cx.state.context, vars: cx.state.localVars};
+    cx.state.localVars = defaultVars;
+  }
+  function popcontext() {
+    cx.state.localVars = cx.state.context.vars;
+    cx.state.context = cx.state.context.prev;
+  }
+  function pushlex(type, info) {
+    var result = function() {
+      var state = cx.state, indent = state.indented;
+      if (state.lexical.type == "stat") indent = state.lexical.indented;
+      else for (var outer = state.lexical; outer && outer.type == ")" && outer.align; outer = outer.prev)
+        indent = outer.indented;
+      state.lexical = new JSLexical(indent, cx.stream.column(), type, null, state.lexical, info);
+    };
+    result.lex = true;
+    return result;
+  }
+  function poplex() {
+    var state = cx.state;
+    if (state.lexical.prev) {
+      if (state.lexical.type == ")")
+        state.indented = state.lexical.indented;
+      state.lexical = state.lexical.prev;
+    }
+  }
+  poplex.lex = true;
+
+  function expect(wanted) {
+    function exp(type) {
+      if (type == wanted) return cont();
+      else if (wanted == ";") return pass();
+      else return cont(exp);
+    };
+    return exp;
+  }
+
+  function statement(type, value) {
+    if (type == "var") return cont(pushlex("vardef", value.length), vardef, expect(";"), poplex);
+    if (type == "keyword a") return cont(pushlex("form"), expression, statement, poplex);
+    if (type == "keyword b") return cont(pushlex("form"), statement, poplex);
+    if (type == "{") return cont(pushlex("}"), block, poplex);
+    if (type == ";") return cont();
+    if (type == "if") {
+      if (cx.state.lexical.info == "else" && cx.state.cc[cx.state.cc.length - 1] == poplex)
+        cx.state.cc.pop()();
+      return cont(pushlex("form"), expression, statement, poplex, maybeelse);
+    }
+    if (type == "function") return cont(functiondef);
+    if (type == "for") return cont(pushlex("form"), forspec, statement, poplex);
+    if (type == "variable") return cont(pushlex("stat"), maybelabel);
+    if (type == "switch") return cont(pushlex("form"), expression, pushlex("}", "switch"), expect("{"),
+                                      block, poplex, poplex);
+    if (type == "case") return cont(expression, expect(":"));
+    if (type == "default") return cont(expect(":"));
+    if (type == "catch") return cont(pushlex("form"), pushcontext, expect("("), funarg, expect(")"),
+                                     statement, poplex, popcontext);
+    if (type == "module") return cont(pushlex("form"), pushcontext, afterModule, popcontext, poplex);
+    if (type == "class") return cont(pushlex("form"), className, poplex);
+    if (type == "export") return cont(pushlex("form"), afterExport, poplex);
+    if (type == "import") return cont(pushlex("form"), afterImport, poplex);
+    return pass(pushlex("stat"), expression, expect(";"), poplex);
+  }
+  function expression(type) {
+    return expressionInner(type, false);
+  }
+  function expressionNoComma(type) {
+    return expressionInner(type, true);
+  }
+  function expressionInner(type, noComma) {
+    if (cx.state.fatArrowAt == cx.stream.start) {
+      var body = noComma ? arrowBodyNoComma : arrowBody;
+      if (type == "(") return cont(pushcontext, pushlex(")"), commasep(pattern, ")"), poplex, expect("=>"), body, popcontext);
+      else if (type == "variable") return pass(pushcontext, pattern, expect("=>"), body, popcontext);
+    }
+
+    var maybeop = noComma ? maybeoperatorNoComma : maybeoperatorComma;
+    if (atomicTypes.hasOwnProperty(type)) return cont(maybeop);
+    if (type == "function") return cont(functiondef, maybeop);
+    if (type == "keyword c") return cont(noComma ? maybeexpressionNoComma : maybeexpression);
+    if (type == "(") return cont(pushlex(")"), maybeexpression, comprehension, expect(")"), poplex, maybeop);
+    if (type == "operator" || type == "spread") return cont(noComma ? expressionNoComma : expression);
+    if (type == "[") return cont(pushlex("]"), arrayLiteral, poplex, maybeop);
+    if (type == "{") return contCommasep(objprop, "}", null, maybeop);
+    if (type == "quasi") { return pass(quasi, maybeop); }
+    return cont();
+  }
+  function maybeexpression(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expression);
+  }
+  function maybeexpressionNoComma(type) {
+    if (type.match(/[;\}\)\],]/)) return pass();
+    return pass(expressionNoComma);
+  }
+
+  function maybeoperatorComma(type, value) {
+    if (type == ",") return cont(expression);
+    return maybeoperatorNoComma(type, value, false);
+  }
+  function maybeoperatorNoComma(type, value, noComma) {
+    var me = noComma == false ? maybeoperatorComma : maybeoperatorNoComma;
+    var expr = noComma == false ? expression : expressionNoComma;
+    if (type == "=>") return cont(pushcontext, noComma ? arrowBodyNoComma : arrowBody, popcontext);
+    if (type == "operator") {
+      if (/\+\+|--/.test(value)) return cont(me);
+      if (value == "?") return cont(expression, expect(":"), expr);
+      return cont(expr);
+    }
+    if (type == "quasi") { return pass(quasi, me); }
+    if (type == ";") return;
+    if (type == "(") return contCommasep(expressionNoComma, ")", "call", me);
+    if (type == ".") return cont(property, me);
+    if (type == "[") return cont(pushlex("]"), maybeexpression, expect("]"), poplex, me);
+  }
+  function quasi(type, value) {
+    if (type != "quasi") return pass();
+    if (value.slice(value.length - 2) != "${") return cont(quasi);
+    return cont(expression, continueQuasi);
+  }
+  function continueQuasi(type) {
+    if (type == "}") {
+      cx.marked = "string-2";
+      cx.state.tokenize = tokenQuasi;
+      return cont(quasi);
+    }
+  }
+  function arrowBody(type) {
+    findFatArrow(cx.stream, cx.state);
+    return pass(type == "{" ? statement : expression);
+  }
+  function arrowBodyNoComma(type) {
+    findFatArrow(cx.stream, cx.state);
+    return pass(type == "{" ? statement : expressionNoComma);
+  }
+  function maybelabel(type) {
+    if (type == ":") return cont(poplex, statement);
+    return pass(maybeoperatorComma, expect(";"), poplex);
+  }
+  function property(type) {
+    if (type == "variable") {cx.marked = "property"; return cont();}
+  }
+  function objprop(type, value) {
+    if (type == "variable" || cx.style == "keyword") {
+      cx.marked = "property";
+      if (value == "get" || value == "set") return cont(getterSetter);
+      return cont(afterprop);
+    } else if (type == "number" || type == "string") {
+      cx.marked = jsonldMode ? "property" : (cx.style + " property");
+      return cont(afterprop);
+    } else if (type == "jsonld-keyword") {
+      return cont(afterprop);
+    } else if (type == "[") {
+      return cont(expression, expect("]"), afterprop);
+    }
+  }
+  function getterSetter(type) {
+    if (type != "variable") return pass(afterprop);
+    cx.marked = "property";
+    return cont(functiondef);
+  }
+  function afterprop(type) {
+    if (type == ":") return cont(expressionNoComma);
+    if (type == "(") return pass(functiondef);
+  }
+  function commasep(what, end) {
+    function proceed(type) {
+      if (type == ",") {
+        var lex = cx.state.lexical;
+        if (lex.info == "call") lex.pos = (lex.pos || 0) + 1;
+        return cont(what, proceed);
+      }
+      if (type == end) return cont();
+      return cont(expect(end));
+    }
+    return function(type) {
+      if (type == end) return cont();
+      return pass(what, proceed);
+    };
+  }
+  function contCommasep(what, end, info) {
+    for (var i = 3; i < arguments.length; i++)
+      cx.cc.push(arguments[i]);
+    return cont(pushlex(end, info), commasep(what, end), poplex);
+  }
+  function block(type) {
+    if (type == "}") return cont();
+    return pass(statement, block);
+  }
+  function maybetype(type) {
+    if (isTS && type == ":") return cont(typedef);
+  }
+  function typedef(type) {
+    if (type == "variable"){cx.marked = "variable-3"; return cont();}
+  }
+  function vardef() {
+    return pass(pattern, maybetype, maybeAssign, vardefCont);
+  }
+  function pattern(type, value) {
+    if (type == "variable") { register(value); return cont(); }
+    if (type == "[") return contCommasep(pattern, "]");
+    if (type == "{") return contCommasep(proppattern, "}");
+  }
+  function proppattern(type, value) {
+    if (type == "variable" && !cx.stream.match(/^\s*:/, false)) {
+      register(value);
+      return cont(maybeAssign);
+    }
+    if (type == "variable") cx.marked = "property";
+    return cont(expect(":"), pattern, maybeAssign);
+  }
+  function maybeAssign(_type, value) {
+    if (value == "=") return cont(expressionNoComma);
+  }
+  function vardefCont(type) {
+    if (type == ",") return cont(vardef);
+  }
+  function maybeelse(type, value) {
+    if (type == "keyword b" && value == "else") return cont(pushlex("form", "else"), statement, poplex);
+  }
+  function forspec(type) {
+    if (type == "(") return cont(pushlex(")"), forspec1, expect(")"), poplex);
+  }
+  function forspec1(type) {
+    if (type == "var") return cont(vardef, expect(";"), forspec2);
+    if (type == ";") return cont(forspec2);
+    if (type == "variable") return cont(formaybeinof);
+    return pass(expression, expect(";"), forspec2);
+  }
+  function formaybeinof(_type, value) {
+    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+    return cont(maybeoperatorComma, forspec2);
+  }
+  function forspec2(type, value) {
+    if (type == ";") return cont(forspec3);
+    if (value == "in" || value == "of") { cx.marked = "keyword"; return cont(expression); }
+    return pass(expression, expect(";"), forspec3);
+  }
+  function forspec3(type) {
+    if (type != ")") cont(expression);
+  }
+  function functiondef(type, value) {
+    if (value == "*") {cx.marked = "keyword"; return cont(functiondef);}
+    if (type == "variable") {register(value); return cont(functiondef);}
+    if (type == "(") return cont(pushcontext, pushlex(")"), commasep(funarg, ")"), poplex, statement, popcontext);
+  }
+  function funarg(type) {
+    if (type == "spread") return cont(funarg);
+    return pass(pattern, maybetype);
+  }
+  function className(type, value) {
+    if (type == "variable") {register(value); return cont(classNameAfter);}
+  }
+  function classNameAfter(type, value) {
+    if (value == "extends") return cont(expression, classNameAfter);
+    if (type == "{") return cont(pushlex("}"), classBody, poplex);
+  }
+  function classBody(type, value) {
+    if (type == "variable" || cx.style == "keyword") {
+      if (value == "static") {
+        cx.marked = "keyword";
+        return cont(classBody);
+      }
+      cx.marked = "property";
+      if (value == "get" || value == "set") return cont(classGetterSetter, functiondef, classBody);
+      return cont(functiondef, classBody);
+    }
+    if (value == "*") {
+      cx.marked = "keyword";
+      return cont(classBody);
+    }
+    if (type == ";") return cont(classBody);
+    if (type == "}") return cont();
+  }
+  function classGetterSetter(type) {
+    if (type != "variable") return pass();
+    cx.marked = "property";
+    return cont();
+  }
+  function afterModule(type, value) {
+    if (type == "string") return cont(statement);
+    if (type == "variable") { register(value); return cont(maybeFrom); }
+  }
+  function afterExport(_type, value) {
+    if (value == "*") { cx.marked = "keyword"; return cont(maybeFrom, expect(";")); }
+    if (value == "default") { cx.marked = "keyword"; return cont(expression, expect(";")); }
+    return pass(statement);
+  }
+  function afterImport(type) {
+    if (type == "string") return cont();
+    return pass(importSpec, maybeFrom);
+  }
+  function importSpec(type, value) {
+    if (type == "{") return contCommasep(importSpec, "}");
+    if (type == "variable") register(value);
+    if (value == "*") cx.marked = "keyword";
+    return cont(maybeAs);
+  }
+  function maybeAs(_type, value) {
+    if (value == "as") { cx.marked = "keyword"; return cont(importSpec); }
+  }
+  function maybeFrom(_type, value) {
+    if (value == "from") { cx.marked = "keyword"; return cont(expression); }
+  }
+  function arrayLiteral(type) {
+    if (type == "]") return cont();
+    return pass(expressionNoComma, maybeArrayComprehension);
+  }
+  function maybeArrayComprehension(type) {
+    if (type == "for") return pass(comprehension, expect("]"));
+    if (type == ",") return cont(commasep(maybeexpressionNoComma, "]"));
+    return pass(commasep(expressionNoComma, "]"));
+  }
+  function comprehension(type) {
+    if (type == "for") return cont(forspec, comprehension);
+    if (type == "if") return cont(expression, comprehension);
+  }
+
+  function isContinuedStatement(state, textAfter) {
+    return state.lastType == "operator" || state.lastType == "," ||
+      isOperatorChar.test(textAfter.charAt(0)) ||
+      /[,.]/.test(textAfter.charAt(0));
+  }
+
+  // Interface
+
+  return {
+    startState: function(basecolumn) {
+      var state = {
+        tokenize: tokenBase,
+        lastType: "sof",
+        cc: [],
+        lexical: new JSLexical((basecolumn || 0) - indentUnit, 0, "block", false),
+        localVars: parserConfig.localVars,
+        context: parserConfig.localVars && {vars: parserConfig.localVars},
+        indented: 0
+      };
+      if (parserConfig.globalVars && typeof parserConfig.globalVars == "object")
+        state.globalVars = parserConfig.globalVars;
+      return state;
+    },
+
+    token: function(stream, state) {
+      if (stream.sol()) {
+        if (!state.lexical.hasOwnProperty("align"))
+          state.lexical.align = false;
+        state.indented = stream.indentation();
+        findFatArrow(stream, state);
+      }
+      if (state.tokenize != tokenComment && stream.eatSpace()) return null;
+      var style = state.tokenize(stream, state);
+      if (type == "comment") return style;
+      state.lastType = type == "operator" && (content == "++" || content == "--") ? "incdec" : type;
+      return parseJS(state, style, type, content, stream);
+    },
+
+    indent: function(state, textAfter) {
+      if (state.tokenize == tokenComment) return CodeMirror.Pass;
+      if (state.tokenize != tokenBase) return 0;
+      var firstChar = textAfter && textAfter.charAt(0), lexical = state.lexical;
+      // Kludge to prevent 'maybelse' from blocking lexical scope pops
+      if (!/^\s*else\b/.test(textAfter)) for (var i = state.cc.length - 1; i >= 0; --i) {
+        var c = state.cc[i];
+        if (c == poplex) lexical = lexical.prev;
+        else if (c != maybeelse) break;
+      }
+      if (lexical.type == "stat" && firstChar == "}") lexical = lexical.prev;
+      if (statementIndent && lexical.type == ")" && lexical.prev.type == "stat")
+        lexical = lexical.prev;
+      var type = lexical.type, closing = firstChar == type;
+
+      if (type == "vardef") return lexical.indented + (state.lastType == "operator" || state.lastType == "," ? lexical.info + 1 : 0);
+      else if (type == "form" && firstChar == "{") return lexical.indented;
+      else if (type == "form") return lexical.indented + indentUnit;
+      else if (type == "stat")
+        return lexical.indented + (isContinuedStatement(state, textAfter) ? statementIndent || indentUnit : 0);
+      else if (lexical.info == "switch" && !closing && parserConfig.doubleIndentSwitch != false)
+        return lexical.indented + (/^(?:case|default)\b/.test(textAfter) ? indentUnit : 2 * indentUnit);
+      else if (lexical.align) return lexical.column + (closing ? 0 : 1);
+      else return lexical.indented + (closing ? 0 : indentUnit);
+    },
+
+    electricInput: /^\s*(?:case .*?:|default:|\{|\})$/,
+    blockCommentStart: jsonMode ? null : "/*",
+    blockCommentEnd: jsonMode ? null : "*/",
+    lineComment: jsonMode ? null : "//",
+    fold: "brace",
+    closeBrackets: "()[]{}''\"\"``",
+
+    helperType: jsonMode ? "json" : "javascript",
+    jsonldMode: jsonldMode,
+    jsonMode: jsonMode
+  };
+});
+
+CodeMirror.registerHelper("wordChars", "javascript", /[\w$]/);
+
+CodeMirror.defineMIME("text/javascript", "javascript");
+CodeMirror.defineMIME("text/ecmascript", "javascript");
+CodeMirror.defineMIME("application/javascript", "javascript");
+CodeMirror.defineMIME("application/x-javascript", "javascript");
+CodeMirror.defineMIME("application/ecmascript", "javascript");
+CodeMirror.defineMIME("application/json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/x-json", {name: "javascript", json: true});
+CodeMirror.defineMIME("application/ld+json", {name: "javascript", jsonld: true});
+CodeMirror.defineMIME("text/typescript", { name: "javascript", typescript: true });
+CodeMirror.defineMIME("application/typescript", { name: "javascript", typescript: true });
+
+});
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/neo.css b/sources/samples/toolbarconfigurator/lib/codemirror/neo.css
new file mode 100644 (file)
index 0000000..d019aab
--- /dev/null
@@ -0,0 +1,36 @@
+/* neo theme for codemirror */
+
+/* Color scheme */
+
+.cm-s-neo.CodeMirror {
+  background-color:#ffffff;
+  color:#2e383c;
+  line-height:1.4375;
+}
+.cm-s-neo .cm-comment {color:#75787b}
+.cm-s-neo .cm-keyword, .cm-s-neo .cm-property {color:#1d75b3}
+.cm-s-neo .cm-atom,.cm-s-neo .cm-number {color:#75438a}
+.cm-s-neo .cm-node,.cm-s-neo .cm-tag {color:#9c3328}
+.cm-s-neo .cm-string {color:#b35e14}
+.cm-s-neo .cm-variable,.cm-s-neo .cm-qualifier {color:#047d65}
+
+
+/* Editor styling */
+
+.cm-s-neo pre {
+  padding:0;
+}
+
+.cm-s-neo .CodeMirror-gutters {
+  border:none;
+  border-right:10px solid transparent;
+  background-color:transparent;
+}
+
+.cm-s-neo .CodeMirror-linenumber {
+  padding:0;
+  color:#e0e2e5;
+}
+
+.cm-s-neo .CodeMirror-guttermarker { color: #1d75b3; }
+.cm-s-neo .CodeMirror-guttermarker-subtle { color: #e0e2e5; }
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/show-hint.css b/sources/samples/toolbarconfigurator/lib/codemirror/show-hint.css
new file mode 100644 (file)
index 0000000..924e638
--- /dev/null
@@ -0,0 +1,38 @@
+.CodeMirror-hints {
+  position: absolute;
+  z-index: 10;
+  overflow: hidden;
+  list-style: none;
+
+  margin: 0;
+  padding: 2px;
+
+  -webkit-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  -moz-box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  box-shadow: 2px 3px 5px rgba(0,0,0,.2);
+  border-radius: 3px;
+  border: 1px solid silver;
+
+  background: white;
+  font-size: 90%;
+  font-family: monospace;
+
+  max-height: 20em;
+  overflow-y: auto;
+}
+
+.CodeMirror-hint {
+  margin: 0;
+  padding: 0 4px;
+  border-radius: 2px;
+  max-width: 19em;
+  overflow: hidden;
+  white-space: pre;
+  color: black;
+  cursor: pointer;
+}
+
+li.CodeMirror-hint-active {
+  background: #08f;
+  color: white;
+}
diff --git a/sources/samples/toolbarconfigurator/lib/codemirror/show-hint.js b/sources/samples/toolbarconfigurator/lib/codemirror/show-hint.js
new file mode 100644 (file)
index 0000000..539181f
--- /dev/null
@@ -0,0 +1,392 @@
+// CodeMirror, copyright (c) by Marijn Haverbeke and others
+// Distributed under an MIT license: http://codemirror.net/LICENSE
+
+(function(mod) {
+  if (typeof exports == "object" && typeof module == "object") // CommonJS
+    mod(require("../../lib/codemirror"));
+  else if (typeof define == "function" && define.amd) // AMD
+    define(["../../lib/codemirror"], mod);
+  else // Plain browser env
+    mod(CodeMirror);
+})(function(CodeMirror) {
+  "use strict";
+
+  var HINT_ELEMENT_CLASS        = "CodeMirror-hint";
+  var ACTIVE_HINT_ELEMENT_CLASS = "CodeMirror-hint-active";
+
+  // This is the old interface, kept around for now to stay
+  // backwards-compatible.
+  CodeMirror.showHint = function(cm, getHints, options) {
+    if (!getHints) return cm.showHint(options);
+    if (options && options.async) getHints.async = true;
+    var newOpts = {hint: getHints};
+    if (options) for (var prop in options) newOpts[prop] = options[prop];
+    return cm.showHint(newOpts);
+  };
+
+  CodeMirror.defineExtension("showHint", function(options) {
+    // We want a single cursor position.
+    if (this.listSelections().length > 1 || this.somethingSelected()) return;
+
+    if (this.state.completionActive) this.state.completionActive.close();
+    var completion = this.state.completionActive = new Completion(this, options);
+    if (!completion.options.hint) return;
+
+    CodeMirror.signal(this, "startCompletion", this);
+    completion.update();
+  });
+
+  function Completion(cm, options) {
+    this.cm = cm;
+    this.options = this.buildOptions(options);
+    this.widget = null;
+    this.debounce = 0;
+    this.tick = 0;
+    this.startPos = this.cm.getCursor();
+    this.startLen = this.cm.getLine(this.startPos.line).length;
+
+    var self = this;
+    cm.on("cursorActivity", this.activityFunc = function() { self.cursorActivity(); });
+  }
+
+  var requestAnimationFrame = window.requestAnimationFrame || function(fn) {
+    return setTimeout(fn, 1000/60);
+  };
+  var cancelAnimationFrame = window.cancelAnimationFrame || clearTimeout;
+
+  Completion.prototype = {
+    close: function() {
+      if (!this.active()) return;
+      this.cm.state.completionActive = null;
+      this.tick = null;
+      this.cm.off("cursorActivity", this.activityFunc);
+
+      if (this.widget) this.widget.close();
+      CodeMirror.signal(this.cm, "endCompletion", this.cm);
+    },
+
+    active: function() {
+      return this.cm.state.completionActive == this;
+    },
+
+    pick: function(data, i) {
+      var completion = data.list[i];
+      if (completion.hint) completion.hint(this.cm, data, completion);
+      else this.cm.replaceRange(getText(completion), completion.from || data.from,
+                                completion.to || data.to, "complete");
+      CodeMirror.signal(data, "pick", completion);
+      this.close();
+    },
+
+    showHints: function(data) {
+      if (!data || !data.list.length || !this.active()) return this.close();
+
+      if (this.options.completeSingle && data.list.length == 1)
+        this.pick(data, 0);
+      else
+        this.showWidget(data);
+    },
+
+    cursorActivity: function() {
+      if (this.debounce) {
+        cancelAnimationFrame(this.debounce);
+        this.debounce = 0;
+      }
+
+      var pos = this.cm.getCursor(), line = this.cm.getLine(pos.line);
+      if (pos.line != this.startPos.line || line.length - pos.ch != this.startLen - this.startPos.ch ||
+          pos.ch < this.startPos.ch || this.cm.somethingSelected() ||
+          (pos.ch && this.options.closeCharacters.test(line.charAt(pos.ch - 1)))) {
+        this.close();
+      } else {
+        var self = this;
+        this.debounce = requestAnimationFrame(function() {self.update();});
+        if (this.widget) this.widget.disable();
+      }
+    },
+
+    update: function() {
+      if (this.tick == null) return;
+      if (this.data) CodeMirror.signal(this.data, "update");
+      if (!this.options.hint.async) {
+        this.finishUpdate(this.options.hint(this.cm, this.options), myTick);
+      } else {
+        var myTick = ++this.tick, self = this;
+        this.options.hint(this.cm, function(data) {
+          if (self.tick == myTick) self.finishUpdate(data);
+        }, this.options);
+      }
+    },
+
+    finishUpdate: function(data) {
+      this.data = data;
+      var picked = this.widget && this.widget.picked;
+      if (this.widget) this.widget.close();
+      if (data && data.list.length) {
+        if (picked && data.list.length == 1) this.pick(data, 0);
+        else this.widget = new Widget(this, data);
+      }
+    },
+
+    showWidget: function(data) {
+      this.data = data;
+      this.widget = new Widget(this, data);
+      CodeMirror.signal(data, "shown");
+    },
+
+    buildOptions: function(options) {
+      var editor = this.cm.options.hintOptions;
+      var out = {};
+      for (var prop in defaultOptions) out[prop] = defaultOptions[prop];
+      if (editor) for (var prop in editor)
+        if (editor[prop] !== undefined) out[prop] = editor[prop];
+      if (options) for (var prop in options)
+        if (options[prop] !== undefined) out[prop] = options[prop];
+      return out;
+    }
+  };
+
+  function getText(completion) {
+    if (typeof completion == "string") return completion;
+    else return completion.text;
+  }
+
+  function buildKeyMap(completion, handle) {
+    var baseMap = {
+      Up: function() {handle.moveFocus(-1);},
+      Down: function() {handle.moveFocus(1);},
+      PageUp: function() {handle.moveFocus(-handle.menuSize() + 1, true);},
+      PageDown: function() {handle.moveFocus(handle.menuSize() - 1, true);},
+      Home: function() {handle.setFocus(0);},
+      End: function() {handle.setFocus(handle.length - 1);},
+      Enter: handle.pick,
+      Tab: handle.pick,
+      Esc: handle.close
+    };
+    var custom = completion.options.customKeys;
+    var ourMap = custom ? {} : baseMap;
+    function addBinding(key, val) {
+      var bound;
+      if (typeof val != "string")
+        bound = function(cm) { return val(cm, handle); };
+      // This mechanism is deprecated
+      else if (baseMap.hasOwnProperty(val))
+        bound = baseMap[val];
+      else
+        bound = val;
+      ourMap[key] = bound;
+    }
+    if (custom)
+      for (var key in custom) if (custom.hasOwnProperty(key))
+        addBinding(key, custom[key]);
+    var extra = completion.options.extraKeys;
+    if (extra)
+      for (var key in extra) if (extra.hasOwnProperty(key))
+        addBinding(key, extra[key]);
+    return ourMap;
+  }
+
+  function getHintElement(hintsElement, el) {
+    while (el && el != hintsElement) {
+      if (el.nodeName.toUpperCase() === "LI" && el.parentNode == hintsElement) return el;
+      el = el.parentNode;
+    }
+  }
+
+  function Widget(completion, data) {
+    this.completion = completion;
+    this.data = data;
+    this.picked = false;
+    var widget = this, cm = completion.cm;
+
+    var hints = this.hints = document.createElement("ul");
+    hints.className = "CodeMirror-hints";
+    this.selectedHint = data.selectedHint || 0;
+
+    var completions = data.list;
+    for (var i = 0; i < completions.length; ++i) {
+      var elt = hints.appendChild(document.createElement("li")), cur = completions[i];
+      var className = HINT_ELEMENT_CLASS + (i != this.selectedHint ? "" : " " + ACTIVE_HINT_ELEMENT_CLASS);
+      if (cur.className != null) className = cur.className + " " + className;
+      elt.className = className;
+      if (cur.render) cur.render(elt, data, cur);
+      else elt.appendChild(document.createTextNode(cur.displayText || getText(cur)));
+      elt.hintId = i;
+    }
+
+    var pos = cm.cursorCoords(completion.options.alignWithWord ? data.from : null);
+    var left = pos.left, top = pos.bottom, below = true;
+    hints.style.left = left + "px";
+    hints.style.top = top + "px";
+    // If we're at the edge of the screen, then we want the menu to appear on the left of the cursor.
+    var winW = window.innerWidth || Math.max(document.body.offsetWidth, document.documentElement.offsetWidth);
+    var winH = window.innerHeight || Math.max(document.body.offsetHeight, document.documentElement.offsetHeight);
+    (completion.options.container || document.body).appendChild(hints);
+    var box = hints.getBoundingClientRect(), overlapY = box.bottom - winH;
+    if (overlapY > 0) {
+      var height = box.bottom - box.top, curTop = pos.top - (pos.bottom - box.top);
+      if (curTop - height > 0) { // Fits above cursor
+        hints.style.top = (top = pos.top - height) + "px";
+        below = false;
+      } else if (height > winH) {
+        hints.style.height = (winH - 5) + "px";
+        hints.style.top = (top = pos.bottom - box.top) + "px";
+        var cursor = cm.getCursor();
+        if (data.from.ch != cursor.ch) {
+          pos = cm.cursorCoords(cursor);
+          hints.style.left = (left = pos.left) + "px";
+          box = hints.getBoundingClientRect();
+        }
+      }
+    }
+    var overlapX = box.right - winW;
+    if (overlapX > 0) {
+      if (box.right - box.left > winW) {
+        hints.style.width = (winW - 5) + "px";
+        overlapX -= (box.right - box.left) - winW;
+      }
+      hints.style.left = (left = pos.left - overlapX) + "px";
+    }
+
+    cm.addKeyMap(this.keyMap = buildKeyMap(completion, {
+      moveFocus: function(n, avoidWrap) { widget.changeActive(widget.selectedHint + n, avoidWrap); },
+      setFocus: function(n) { widget.changeActive(n); },
+      menuSize: function() { return widget.screenAmount(); },
+      length: completions.length,
+      close: function() { completion.close(); },
+      pick: function() { widget.pick(); },
+      data: data
+    }));
+
+    if (completion.options.closeOnUnfocus) {
+      var closingOnBlur;
+      cm.on("blur", this.onBlur = function() { closingOnBlur = setTimeout(function() { completion.close(); }, 100); });
+      cm.on("focus", this.onFocus = function() { clearTimeout(closingOnBlur); });
+    }
+
+    var startScroll = cm.getScrollInfo();
+    cm.on("scroll", this.onScroll = function() {
+      var curScroll = cm.getScrollInfo(), editor = cm.getWrapperElement().getBoundingClientRect();
+      var newTop = top + startScroll.top - curScroll.top;
+      var point = newTop - (window.pageYOffset || (document.documentElement || document.body).scrollTop);
+      if (!below) point += hints.offsetHeight;
+      if (point <= editor.top || point >= editor.bottom) return completion.close();
+      hints.style.top = newTop + "px";
+      hints.style.left = (left + startScroll.left - curScroll.left) + "px";
+    });
+
+    CodeMirror.on(hints, "dblclick", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {widget.changeActive(t.hintId); widget.pick();}
+    });
+
+    CodeMirror.on(hints, "click", function(e) {
+      var t = getHintElement(hints, e.target || e.srcElement);
+      if (t && t.hintId != null) {
+        widget.changeActive(t.hintId);
+        if (completion.options.completeOnSingleClick) widget.pick();
+      }
+    });
+
+    CodeMirror.on(hints, "mousedown", function() {
+      setTimeout(function(){cm.focus();}, 20);
+    });
+
+    CodeMirror.signal(data, "select", completions[0], hints.firstChild);
+    return true;
+  }
+
+  Widget.prototype = {
+    close: function() {
+      if (this.completion.widget != this) return;
+      this.completion.widget = null;
+      this.hints.parentNode.removeChild(this.hints);
+      this.completion.cm.removeKeyMap(this.keyMap);
+
+      var cm = this.completion.cm;
+      if (this.completion.options.closeOnUnfocus) {
+        cm.off("blur", this.onBlur);
+        cm.off("focus", this.onFocus);
+      }
+      cm.off("scroll", this.onScroll);
+    },
+
+    disable: function() {
+      this.completion.cm.removeKeyMap(this.keyMap);
+      var widget = this;
+      this.keyMap = {Enter: function() { widget.picked = true; }};
+      this.completion.cm.addKeyMap(this.keyMap);
+    },
+
+    pick: function() {
+      this.completion.pick(this.data, this.selectedHint);
+    },
+
+    changeActive: function(i, avoidWrap) {
+      if (i >= this.data.list.length)
+        i = avoidWrap ? this.data.list.length - 1 : 0;
+      else if (i < 0)
+        i = avoidWrap ? 0  : this.data.list.length - 1;
+      if (this.selectedHint == i) return;
+      var node = this.hints.childNodes[this.selectedHint];
+      node.className = node.className.replace(" " + ACTIVE_HINT_ELEMENT_CLASS, "");
+      node = this.hints.childNodes[this.selectedHint = i];
+      node.className += " " + ACTIVE_HINT_ELEMENT_CLASS;
+      if (node.offsetTop < this.hints.scrollTop)
+        this.hints.scrollTop = node.offsetTop - 3;
+      else if (node.offsetTop + node.offsetHeight > this.hints.scrollTop + this.hints.clientHeight)
+        this.hints.scrollTop = node.offsetTop + node.offsetHeight - this.hints.clientHeight + 3;
+      CodeMirror.signal(this.data, "select", this.data.list[this.selectedHint], node);
+    },
+
+    screenAmount: function() {
+      return Math.floor(this.hints.clientHeight / this.hints.firstChild.offsetHeight) || 1;
+    }
+  };
+
+  CodeMirror.registerHelper("hint", "auto", function(cm, options) {
+    var helpers = cm.getHelpers(cm.getCursor(), "hint"), words;
+    if (helpers.length) {
+      for (var i = 0; i < helpers.length; i++) {
+        var cur = helpers[i](cm, options);
+        if (cur && cur.list.length) return cur;
+      }
+    } else if (words = cm.getHelper(cm.getCursor(), "hintWords")) {
+      if (words) return CodeMirror.hint.fromList(cm, {words: words});
+    } else if (CodeMirror.hint.anyword) {
+      return CodeMirror.hint.anyword(cm, options);
+    }
+  });
+
+  CodeMirror.registerHelper("hint", "fromList", function(cm, options) {
+    var cur = cm.getCursor(), token = cm.getTokenAt(cur);
+    var found = [];
+    for (var i = 0; i < options.words.length; i++) {
+      var word = options.words[i];
+      if (word.slice(0, token.string.length) == token.string)
+        found.push(word);
+    }
+
+    if (found.length) return {
+      list: found,
+      from: CodeMirror.Pos(cur.line, token.start),
+            to: CodeMirror.Pos(cur.line, token.end)
+    };
+  });
+
+  CodeMirror.commands.autocomplete = CodeMirror.showHint;
+
+  var defaultOptions = {
+    hint: CodeMirror.hint.auto,
+    completeSingle: true,
+    alignWithWord: true,
+    closeCharacters: /[\s()\[\]{};:>,]/,
+    closeOnUnfocus: true,
+    completeOnSingleClick: false,
+    container: null,
+    customKeys: null,
+    extraKeys: null
+  };
+
+  CodeMirror.defineOption("hintOptions", null);
+});
diff --git a/sources/samples/toolbarconfigurator/package.json b/sources/samples/toolbarconfigurator/package.json
new file mode 100644 (file)
index 0000000..1fceff9
--- /dev/null
@@ -0,0 +1,12 @@
+{
+  "name": "ckeditor-toolbarconfigurator",
+  "version": "0.0.0",
+  "description": "",
+  "author": "CKSource (http://cksource.com/)",
+  "license": "For licensing, see LICENSE.md or http://ckeditor.com/license.",
+  "devDependencies": {
+    "benderjs": "~0.2.1",
+    "benderjs-chai": "~0.2.0",
+    "benderjs-mocha": "~0.1.2"
+  }
+}
diff --git a/sources/samples/toolbarconfigurator/tests/one.js b/sources/samples/toolbarconfigurator/tests/one.js
new file mode 100644 (file)
index 0000000..1d3837f
--- /dev/null
@@ -0,0 +1,9 @@
+/* global describe, it, expect, ToolbarConfigurator */
+
+describe( 'Full toolbar configurator', function() {
+       var FTE = ToolbarConfigurator.FullToolbarEditor;
+
+       it( 'exists', function() {
+               expect( FTE ).to.be.a( 'function' );
+       } );
+} );
diff --git a/sources/skins/moono/colorpanel.css b/sources/skins/moono/colorpanel.css
new file mode 100644 (file)
index 0000000..efad9d9
--- /dev/null
@@ -0,0 +1,127 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+colorpanel.css (part of editor.css)\r
+=====================================\r
+\r
+The color panel is related to the contents part of the panels that are\r
+displayed when clicking the color buttons of the toolbar. See panels.css for\r
+styles related to the outer part of panels.\r
+\r
+The following is the visual representation of the color panel contents:\r
+\r
++-- .cke_panel_block.cke_colorblock --+\r
+| +-- a.cke_colorauto --------------+ |\r
+| |                                 | |\r
+| |         AUTOMATIC COLOR         | |\r
+| |                                 | |\r
+| +---------------------------------+ |\r
+| +-- table ------------------------+ |\r
+| |                                 | |\r
+| |          COLOR PALETTE          | |\r
+| |                                 | |\r
+| |---------------------------------| |\r
+| |          "More Colors"          | |\r
+| +---------------------------------+ |\r
++-------------------------------------+\r
+\r
+The AUTOMATIC COLOR section is an <a> containing a table with two cells with\r
+the following contents:\r
+\r
++-- TD -----------------+ +-- TD -----------------+\r
+| +-- .cke_colorbox --+ | |                       |\r
+| |                   | | |      "Automatic"      |\r
+| +-------------------+ | |                       |\r
++-----------------------+ +-----------------------+\r
+\r
+The COLOR PALETTE section instead is a table with a variable number of cells\r
+(by default 8). Each cell represents a color box, with the following structure:\r
+\r
++-- A.cke_colorbox ---------+\r
+| +-- SPAN.cke_colorbox --+ |\r
+| |                       | |\r
+| +-----------------------+ |\r
++---------------------------+\r
+*/\r
+\r
+/* The container of the color palette. */\r
+.cke_colorblock\r
+{\r
+       padding: 3px;\r
+       font-size: 11px;\r
+       font-family: 'Microsoft Sans Serif', Tahoma, Arial, Verdana, Sans-Serif;\r
+}\r
+\r
+.cke_colorblock,\r
+.cke_colorblock a\r
+{\r
+       text-decoration: none;\r
+       color: #000;\r
+}\r
+\r
+/* The box which is to represent a single color on the color palette.\r
+   It is a small, square-shaped element which can be selected from the palette. */\r
+span.cke_colorbox\r
+{\r
+       width: 10px;\r
+       height: 10px;\r
+       border: #808080 1px solid;\r
+       float: left;\r
+}\r
+\r
+.cke_rtl span.cke_colorbox\r
+{\r
+       float: right;\r
+}\r
+\r
+/* The wrapper of the span.cke_colorbox. It provides an extra border and padding. */\r
+a.cke_colorbox\r
+{\r
+       border: #fff 1px solid;\r
+       padding: 2px;\r
+       float: left;\r
+       width: 12px;\r
+       height: 12px;\r
+}\r
+\r
+.cke_rtl a.cke_colorbox\r
+{\r
+       float: right;\r
+}\r
+\r
+/* Different states of the a.cke_colorbox wrapper. */\r
+a:hover.cke_colorbox,\r
+a:focus.cke_colorbox,\r
+a:active.cke_colorbox\r
+{\r
+       border: #b6b6b6 1px solid;\r
+       background-color: #e5e5e5;\r
+}\r
+\r
+/* Buttons which are visible at the top/bottom of the color palette:\r
+   - cke_colorauto (TOP) applies the automatic color.\r
+   - cke_colormore (BOTTOM) executes the color dialog.\r
+*/\r
+a.cke_colorauto,\r
+a.cke_colormore\r
+{\r
+       border: #fff 1px solid;\r
+       padding: 2px;\r
+       display: block;\r
+       cursor: pointer;\r
+}\r
+\r
+/* Different states of cke_colorauto/cke_colormore buttons. */\r
+a:hover.cke_colorauto,\r
+a:hover.cke_colormore,\r
+a:focus.cke_colorauto,\r
+a:focus.cke_colormore,\r
+a:active.cke_colorauto,\r
+a:active.cke_colormore\r
+{\r
+       border: #b6b6b6 1px solid;\r
+       background-color: #e5e5e5;\r
+}\r
diff --git a/sources/skins/moono/dev/icons16.png b/sources/skins/moono/dev/icons16.png
new file mode 100644 (file)
index 0000000..a919742
Binary files /dev/null and b/sources/skins/moono/dev/icons16.png differ
diff --git a/sources/skins/moono/dev/icons16.svg b/sources/skins/moono/dev/icons16.svg
new file mode 100644 (file)
index 0000000..5719d3e
--- /dev/null
@@ -0,0 +1,2374 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   width="496.00443"
+   height="368.00006"
+   viewBox="0 0 496.00443 368.00004"
+   enable-background="new 0 0 612 792"
+   xml:space="preserve"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="icons16.svg"
+   inkscape:export-filename="/home/oleq/ck/ckeditor-dev/skins/moono/dev/icons16.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"><metadata
+   id="metadata9"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs7"><marker
+     inkscape:stockid="DiamondLstart"
+     orient="auto"
+     refY="0.0"
+     refX="0.0"
+     id="DiamondLstart"
+     style="overflow:visible"><path
+       id="path4964"
+       d="M 0,-7.0710768 L -7.0710894,0 L 0,7.0710589 L 7.0710462,0 L 0,-7.0710768 z "
+       style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt"
+       transform="scale(0.8) translate(7,0)" /></marker><linearGradient
+     inkscape:collect="always"
+     id="linearGradient4352"><stop
+       style="stop-color:#ff4141;stop-opacity:0"
+       offset="0"
+       id="stop4354" /><stop
+       id="stop4362"
+       offset="0.24227905"
+       style="stop-color:#ff4141;stop-opacity:0.78823529;" /><stop
+       id="stop4360"
+       offset="0.73632693"
+       style="stop-color:#ff4141;stop-opacity:0" /><stop
+       style="stop-color:#ff4141;stop-opacity:1"
+       offset="1"
+       id="stop4356" /></linearGradient><linearGradient
+     id="linearGradient4392"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396" /></linearGradient><linearGradient
+     id="linearGradient4392-45"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-8" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-68" /></linearGradient><linearGradient
+     id="linearGradient4392-7-7"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-2-8" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-7-9" /></linearGradient><filter
+     id="filter3224-1-7-1"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><filter
+     id="filter3224-1-7-1-3"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-70"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-9"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-91"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-53"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-3"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4838"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,48.36541,-271.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4840"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,-1,511,96.250061)"
+     x1="472"
+     y1="17"
+     x2="472"
+     y2="31" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4842"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(47.88294,17.406131)"
+     x1="55"
+     y1="51"
+     x2="55"
+     y2="63" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4844"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-95,49.250061)"
+     x1="136"
+     y1="50"
+     x2="136"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4846"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-15,49.250061)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4848"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-79,49.250061)"
+     x1="88"
+     y1="50"
+     x2="88"
+     y2="63" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4850"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-271,80.250061)"
+     x1="343"
+     y1="50"
+     x2="343"
+     y2="63" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4852"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(148,91.176371)"
+     x1="148"
+     y1="73.073685"
+     x2="148"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4856"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-367,176.25006)"
+     x1="407"
+     y1="113"
+     x2="407"
+     y2="127" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4858"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1649013,0,0,1.1649013,-385.36445,145.3613)"
+     x1="365"
+     y1="96.073685"
+     x2="365"
+     y2="108.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4860"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-414.467,95.072771)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4862"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1673123,0,0,1.1673123,-226.67995,74.209541)"
+     x1="366"
+     y1="48.073685"
+     x2="366"
+     y2="60.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4864"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1111083,0,0,1.1111083,-186.99896,-192.59658)"
+     x1="378"
+     y1="205"
+     x2="378"
+     y2="214" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4866"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(178.99998,90.187541)"
+     x1="246"
+     y1="73.073685"
+     x2="246"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4868"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(170.99998,90.187541)"
+     x1="222"
+     y1="73.073685"
+     x2="222"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4870"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.0131693,0,0,1.0131693,160.31347,89.185861)"
+     x1="197"
+     y1="73.073685"
+     x2="197"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4872"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(154.99998,90.187541)"
+     x1="171"
+     y1="73.073685"
+     x2="171"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4874"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.2458722,0,0,1.1615489,-281.43958,-203.65157)"
+     x1="233"
+     y1="204"
+     x2="233"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4876"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1666672,0,0,1.1723864,-10.00007,112.59337)"
+     x1="126"
+     y1="96.073685"
+     x2="126"
+     y2="108.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4878"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.1621519,95.65429,77.66723)"
+     x1="124"
+     y1="74.073685"
+     x2="124"
+     y2="82.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4880"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1666666,0,0,1.1666669,-22,113.17048)"
+     x1="54"
+     y1="96.073685"
+     x2="54"
+     y2="108.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4882"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-111.63459,-272.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4884"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-111.63459,-272.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4886"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1458395,0,0,1.1458395,-24.974994,183.6777)"
+     x1="30"
+     y1="120.07368"
+     x2="30"
+     y2="132.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4888"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.2584059,0,0,1.2584059,-26.9426,202.63781)"
+     x1="54"
+     y1="122.07368"
+     x2="54"
+     y2="130.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4890"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1739937,0,0,1.1739937,-39.36396,212.27908)"
+     x1="150"
+     y1="120.07368"
+     x2="150"
+     y2="132.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4892"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-30.36848,96.482511)"
+     x1="150"
+     y1="97.073685"
+     x2="150"
+     y2="107.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4894"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1666648,0,0,1.1666669,34.00037,113.17712)"
+     x1="198"
+     y1="96.073685"
+     x2="198"
+     y2="108.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4898"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(97,-203.74994)"
+     x1="136"
+     y1="204"
+     x2="136"
+     y2="220" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4900"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-111,48.250061)"
+     x1="184"
+     y1="50"
+     x2="184"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4904"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(81,48.250061)"
+     x1="216"
+     y1="51.999996"
+     x2="216"
+     y2="59.999996" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4906"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-271,79.250061)"
+     x1="407"
+     y1="51"
+     x2="407"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4908"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-239,78.250061)"
+     x1="407"
+     y1="51"
+     x2="407"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4910"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-79,48.250061)"
+     x1="87"
+     y1="16.999994"
+     x2="87"
+     y2="30.999994" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4912"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1.1111083,0,0,1.1111083,716.999,-192.59658)"
+     x1="378"
+     y1="205"
+     x2="378"
+     y2="214" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4914"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(17,80.250061)"
+     x1="57"
+     y1="83"
+     x2="57"
+     y2="94" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4916"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(49,80.250061)"
+     x1="87"
+     y1="82"
+     x2="87"
+     y2="95" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4918"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,321,80.250061)"
+     x1="87"
+     y1="82"
+     x2="87"
+     y2="95" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4920"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(113,81.250061)"
+     x1="344"
+     y1="82"
+     x2="344"
+     y2="93" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4922"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(113,81.250061)"
+     x1="375"
+     y1="82"
+     x2="375"
+     y2="93" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4924"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.2587978,0,0,1.2587978,-390.22595,101.39303)"
+     x1="340"
+     y1="75.073685"
+     x2="340"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4926"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(49,80.250061)"
+     x1="87"
+     y1="82"
+     x2="87"
+     y2="95" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4928"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(81.11142,80.250041)"
+     x1="87"
+     y1="82"
+     x2="87"
+     y2="95" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4930"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,289,80.250051)"
+     x1="87"
+     y1="82"
+     x2="87"
+     y2="95" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4932"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-15,112.25006)"
+     x1="24"
+     y1="114"
+     x2="24"
+     y2="126" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4934"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-15,112.25006)"
+     x1="216"
+     y1="115"
+     x2="216"
+     y2="126" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4936"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(207,48.250051)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4938"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(16,48.250051)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4940"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(81.18519,49.361171)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4944"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(0.95906074,0,0,0.83983765,-245.54139,86.680785)"
+     x1="263.14438"
+     y1="53.202732"
+     x2="263.14438"
+     y2="65.97139" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4946"
+     gradientUnits="userSpaceOnUse"
+     x1="324.89481"
+     y1="49.999996"
+     x2="327.98953"
+     y2="61.999996" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4948"
+     gradientUnits="userSpaceOnUse"
+     x1="324.89481"
+     y1="49.999996"
+     x2="327.98953"
+     y2="61.999996" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4950"
+     gradientUnits="userSpaceOnUse"
+     x1="263.14438"
+     y1="53.202732"
+     x2="263.14438"
+     y2="65.97139" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4952"
+     gradientUnits="userSpaceOnUse"
+     x1="263.14438"
+     y1="53.202732"
+     x2="263.14438"
+     y2="65.97139" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4954"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1.1111083,0,0,1.1111083,684.999,-192.59658)"
+     x1="378"
+     y1="205"
+     x2="378"
+     y2="214" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4956"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1111083,0,0,1.1111083,-90.99896,-192.59658)"
+     x1="378"
+     y1="205"
+     x2="378"
+     y2="214" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4958"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,352.81481,49.361171)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4960"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1.33333,0,0,1.33333,593.467,95.072771)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4962"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,481,176.25006)"
+     x1="407"
+     y1="113"
+     x2="407"
+     y2="127" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-7-7"
+     id="linearGradient4964"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-207,-111.74995)"
+     x1="280"
+     y1="112"
+     x2="280"
+     y2="128" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4966"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(57,80.250061)"
+     x1="57"
+     y1="83"
+     x2="57"
+     y2="94" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4968"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,449,112.25006)"
+     x1="216"
+     y1="115"
+     x2="216"
+     y2="126" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4970"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1666672,0,0,1.1723864,-106.00007,208.59337)"
+     x1="126"
+     y1="96.073685"
+     x2="126"
+     y2="108.07368" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient4972"
+     gradientUnits="userSpaceOnUse"
+     x1="104"
+     y1="230.99998"
+     x2="104"
+     y2="232.99998"
+     gradientTransform="translate(1.0000001,0.25006141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4974"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(47,47.99999)"
+     x1="120"
+     y1="50"
+     x2="120"
+     y2="62" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4980"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,144.36541,-271.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4982"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-111.63459,-271.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4984"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-80.63459,-273.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4986"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-80.63459,-273.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4988"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-79.63459,-272.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4990"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-15.63459,-271.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4992"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,16.36541,-272.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4994"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,176.36541,-271.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4996"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-80.63459,-244.81697)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient5002"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,67.36541,-272.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient5004"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,208.36541,-272.06703)"
+     x1="91"
+     y1="204"
+     x2="91"
+     y2="216" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient6476"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(17,-2.7499485)"
+     x1="56"
+     y1="225"
+     x2="56"
+     y2="239" /><linearGradient
+     id="linearGradient4392-45-3"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-8-2" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-68-9" /></linearGradient><filter
+     id="filter3224-1-7-1-2"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-0"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-5"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-1"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-8"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-5"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     y2="108.07368"
+     x2="342"
+     y1="97.073685"
+     x1="342"
+     gradientTransform="matrix(1.2681238,0,0,1.2681238,-424.35773,135.21343)"
+     gradientUnits="userSpaceOnUse"
+     id="linearGradient7390"
+     xlink:href="#linearGradient4392-45-3"
+     inkscape:collect="always" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3645"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(33,0.25005141)"
+     x1="72"
+     y1="32"
+     x2="72"
+     y2="47" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3667"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,1,209,0.25005141)"
+     x1="72"
+     y1="32"
+     x2="72"
+     y2="47" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3726"
+     gradientUnits="userSpaceOnUse"
+     x1="72"
+     y1="32"
+     x2="72"
+     y2="47"
+     gradientTransform="translate(1.0000001,0.25005141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3809"
+     x1="264"
+     y1="114"
+     x2="264"
+     y2="121"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,-13.749949)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3576"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-478.467,255.07277)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4352"
+     id="linearGradient4358"
+     x1="366.95544"
+     y1="335.06354"
+     x2="356.00427"
+     y2="335.08957"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(0.90909091,0,0,1,-318.63636,23.250061)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3629"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-127.467,242.82272)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4352"
+     id="linearGradient3631"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(0.90909091,0,0,1,32.363636,11)"
+     x1="366.95544"
+     y1="335.06354"
+     x2="356.00427"
+     y2="335.08957" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3633"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-127.467,242.82271)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4352"
+     id="linearGradient3635"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(0.90909091,0,0,1,32.363636,11)"
+     x1="366.95544"
+     y1="335.06354"
+     x2="356.00427"
+     y2="335.08957" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient4406"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-478.467,255.07277)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient4386"
+     x1="73"
+     y1="321"
+     x2="73"
+     y2="335"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,0.25005141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient4388"
+     x1="69"
+     y1="323"
+     x2="69"
+     y2="333"
+     gradientUnits="userSpaceOnUse" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-3"
+     id="linearGradient4386-0"
+     x1="73"
+     y1="321"
+     x2="73"
+     y2="335"
+     gradientUnits="userSpaceOnUse" /><linearGradient
+     id="linearGradient4392-3"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-6" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-8" /></linearGradient><filter
+     id="filter3224-1-7-1-2-7"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-0-0"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-5-5"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-1-0"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-8-2"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-5-1"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3947"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.33333,0,0,1.33333,-478.467,255.07277)"
+     x1="365"
+     y1="73.073685"
+     x2="365"
+     y2="84.073685" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4352"
+     id="linearGradient3949"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(0.90909091,0,0,1,-318.63636,23.250061)"
+     x1="366.95544"
+     y1="335.06354"
+     x2="356.00427"
+     y2="335.08957" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3951"
+     gradientUnits="userSpaceOnUse"
+     x1="69"
+     y1="323"
+     x2="69"
+     y2="333" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3287"
+     x1="39.452351"
+     y1="196.14122"
+     x2="39.452351"
+     y2="202.77057"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,0.25006141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3289"
+     x1="7.0987959"
+     y1="196.14124"
+     x2="7.0987959"
+     y2="202.87701"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,0.25006141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3291"
+     x1="38.596195"
+     y1="163.43153"
+     x2="38.596195"
+     y2="174.78519"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,0.25006141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3293"
+     x1="9.2478447"
+     y1="162.9012"
+     x2="9.2478447"
+     y2="174.65788"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(1.0000001,0.25006141)" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392"
+     id="linearGradient3295"
+     x1="329"
+     y1="96.25"
+     x2="329"
+     y2="112.25"
+     gradientUnits="userSpaceOnUse" /><linearGradient
+     id="linearGradient4392-4"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-86" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-6" /></linearGradient><filter
+     id="filter3224-1-7-1-3-6"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-70-8"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-9-3"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-91-9"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-53-7"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-3-6"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-4"
+     id="linearGradient6173"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(2,0,0,2,-32,386.0001)"
+     x1="88"
+     y1="161"
+     x2="88"
+     y2="174" /><linearGradient
+     id="linearGradient6287"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop6289" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop6291" /></linearGradient><filter
+     id="filter6293"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset6295"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite6297"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood6299"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend6301"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite6303"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3348"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(-15,193.25005)"
+     x1="88"
+     y1="161"
+     x2="88"
+     y2="174" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45"
+     id="linearGradient3350"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="translate(17,193.25005)"
+     x1="88"
+     y1="161"
+     x2="88"
+     y2="174" /><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45-36"
+     id="linearGradient4840-7"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(-1,0,0,-1,511,96.250061)"
+     x1="472"
+     y1="17"
+     x2="472"
+     y2="31" /><linearGradient
+     id="linearGradient4392-45-36"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-8-4" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-68-0" /></linearGradient><filter
+     id="filter3224-1-7-1-21"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-2"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-2"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-3"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-4"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-1"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     inkscape:collect="always"
+     xlink:href="#linearGradient4392-45-1"
+     id="linearGradient4563-7"
+     gradientUnits="userSpaceOnUse"
+     gradientTransform="matrix(1.1649013,0,0,1.1649013,-321.36445,209.3613)"
+     x1="365"
+     y1="96.073685"
+     x2="365"
+     y2="108.07368" /><linearGradient
+     id="linearGradient4392-45-1"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-8-21" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-68-2" /></linearGradient><filter
+     id="filter3224-1-7-1-5"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-6"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-0"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-6"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-6"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-55"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><linearGradient
+     y2="108.07368"
+     x2="365"
+     y1="96.073685"
+     x1="365"
+     gradientTransform="matrix(1.1649013,0,0,1.1649013,-328.36445,204.3613)"
+     gradientUnits="userSpaceOnUse"
+     id="linearGradient4604-8"
+     xlink:href="#linearGradient4392-45-1-0"
+     inkscape:collect="always" /><linearGradient
+     id="linearGradient4392-45-1-0"><stop
+       style="stop-color:#666666;stop-opacity:1;"
+       offset="0"
+       id="stop4394-8-21-2" /><stop
+       style="stop-color:#424242;stop-opacity:1;"
+       offset="1"
+       id="stop4396-68-2-2" /></linearGradient><filter
+     id="filter3224-1-7-1-5-0"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-6-7"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-0-9"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-6-7"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-6-4"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-55-7"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><filter
+     id="filter3224-1-7-1-5-0-8"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-6-7-6"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-0-9-3"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-6-7-1"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-6-4-1"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-55-7-6"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><filter
+     id="filter3224-1-7-1-7"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-5"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-56"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-7"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-0"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-9"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter><filter
+     id="filter3224-1-7-1-7-5"
+     inkscape:label="Inner Shadow"
+     inkscape:menu="Shadows and Glows"
+     inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+     color-interpolation-filters="sRGB"
+     width="1"
+     height="1"
+     y="0"
+     x="0"><feOffset
+       id="feOffset3228-5-5-5-5-8"
+       dx="0"
+       dy="1.2"
+       result="result11" /><feComposite
+       id="feComposite3230-2-4-1-56-0"
+       in2="result11"
+       result="result6"
+       in="SourceGraphic"
+       operator="in" /><feFlood
+       id="feFlood3232-7-3-4-7-3"
+       result="result10"
+       in="result6"
+       flood-opacity="1"
+       flood-color="rgb(34,34,34)" /><feBlend
+       id="feBlend3234-6-3-5-0-5"
+       in2="result10"
+       mode="normal"
+       in="result6"
+       result="result12" /><feComposite
+       id="feComposite3236-1-3-5-9-5"
+       in2="SourceGraphic"
+       result="result2"
+       operator="in" /></filter></defs><sodipodi:namedview
+   pagecolor="#dddddd"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1360"
+   inkscape:window-height="898"
+   id="namedview5"
+   showgrid="true"
+   inkscape:showpageshadow="false"
+   inkscape:zoom="22.627417"
+   inkscape:cx="133.501"
+   inkscape:cy="41.601897"
+   inkscape:window-x="363"
+   inkscape:window-y="91"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="layer1"
+   fit-margin-top="1"
+   fit-margin-left="0"
+   fit-margin-bottom="0"
+   fit-margin-right="2"
+   showguides="false"
+   inkscape:guide-bbox="true"><inkscape:grid
+     type="xygrid"
+     id="grid2986"
+     units="px"
+     empspacing="16"
+     visible="true"
+     enabled="true"
+     snapvisiblegridlinesonly="true"
+     spacingx="1px"
+     spacingy="1px"
+     dotted="false"
+     originx="0px"
+     originy="4.0855018e-05px" /></sodipodi:namedview>
+
+
+<g
+   inkscape:groupmode="layer"
+   id="layer2"
+   inkscape:label="Dark background"
+   style="display:inline"
+   transform="translate(-1,-0.25001385)"
+   sodipodi:insensitive="true"><rect
+     style="fill:#ffaaaa;fill-opacity:1;stroke:none"
+     id="rect6406"
+     width="496"
+     height="368"
+     x="1"
+     y="0.25000146" /></g><g
+   inkscape:groupmode="layer"
+   id="layer1"
+   inkscape:label="Shadow"
+   style="display:inline"
+   transform="translate(-1,-0.25001385)"
+   sodipodi:insensitive="true"><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 68,2.2664957 0,1 10,0 0,-1 z m 160.09375,1 c -0.0535,0.15448 -0.0937,0.32687 -0.0937,0.5 0,0.83099 0.669,1.5 1.5,1.5 l 7,0 c 0.831,0 1.5,-0.66901 1.5,-1.5 0,-0.17313 -0.0403,-0.34552 -0.0937,-0.5 -0.20326,0.58701 -0.74838,1 -1.40625,1 l -7,0 c -0.65787,0 -1.20299,-0.41299 -1.40625,-1 z m 1.90625,4 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,-0.55401 0.446,-1 1,-1 l 6,0 c 0.554,0 1,0.44599 1,1 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 z m 1.5,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.2769893 0.223,0.4999983 0.5,0.4999983 l 3,0 c 0.277,0 0.5,-0.223009 0.5,-0.4999983 0,-0.277 -0.223,-0.5 -0.5,-0.5 z M 69,10.266494 l 0,1 2,0 2,0 4,0 0,-1 z m 162.5,1 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m -165.5,0.9375 0,1 3,3.0625 9,0 c 1.108,0 2,-0.89201 2,-2 l 0,-1 c 0,1.10799 -0.892,2 -2,2 l -1,0 -4,0 -2,0 -2,0 z m 160,0.0625 0,1 c 0,0.554 0.446,1 1,1 l 2,0 0,-1 -2,0 c -0.554,0 -1,-0.446 -1,-1 z m 14,0 c 0,0.554 -0.446,1 -1,1 l -2,0 0,1 2,0 c 0.554,0 1,-0.446 1,-1 z m -10,3 0,1 6,0 0,-1 z M 5.09375,35.078994 c -0.0321,0.10941 -0.0625,0.22755 -0.0625,0.375 0,2.02126 1.30983,3.93782 2.84375,5.5 l 0.4375,-0.5625 c -1.55369,-1.47791 -2.95861,-3.3358 -3.21875,-5.3125 z m 9.875,0.09375 c -0.25301,1.93915 -1.65457,3.76438 -3.1875,5.21875 l 0.46875,0.53125 c 1.4966,-1.53303 2.75,-3.41075 2.75,-5.375 0,-0.13982 -0.0081,-0.26521 -0.03125,-0.375 z m 211.71875,5.59375 -0.6875,0.5 7,5 0,-1 z m 44.625,0 -6.3125,4.5 0,1 7,-5 z m 32,0 -6.3125,4.5 0,1 7,-5 z m 19.375,0 -0.6875,0.5 7,5 0,-1 z M 10.03125,41.860244 C 9.22019,42.486324 8.48091,42.963334 8,43.266494 c 0.22032,0.18121 0.39081,0.41214 0.53125,0.65625 0.43604,-0.28502 0.92578,-0.61924 1.5,-1.0625 0.60817,0.4711 1.13459,0.82096 1.59375,1.125 0.13177,-0.24582 0.28903,-0.46928 0.5,-0.65625 -0.50956,-0.32059 -1.26151,-0.82409 -2.09375,-1.46875 z M 233,41.922744 l 0,1 c 3.41666,0 5.61556,1.23041 7,3.34375 0,-0.37177 -0.024,-0.7269 -0.0625,-1.0625 -1.38712,-2.06828 -3.5607,-3.28125 -6.9375,-3.28125 z m 32,0 c -3.3768,0 -5.55038,1.21298 -6.9375,3.28125 -0.0385,0.3356 -0.0625,0.69073 -0.0625,1.0625 1.38444,-2.11333 3.58334,-3.34375 7,-3.34375 z m 32,0 c -3.3768,0 -5.55038,1.21298 -6.9375,3.28125 -0.0385,0.3356 -0.0625,0.69073 -0.0625,1.0625 1.38444,-2.11333 3.58334,-3.34375 7,-3.34375 z m 32,0 0,1 c 3.41666,0 5.61556,1.23041 7,3.34375 0,-0.37177 -0.024,-0.7269 -0.0625,-1.0625 -1.38712,-2.06828 -3.5607,-3.28125 -6.9375,-3.28125 z m -322.65625,1.9375 c -0.68772,0 -1.21875,0.51508 -1.21875,1.15625 0,0.18496 0.0456,0.34537 0.125,0.5 0.19583,-0.38143 0.60441,-0.65625 1.09375,-0.65625 0.48369,0 0.88614,0.28199 1.09375,0.65625 0.0876,-0.15786 0.15625,-0.30978 0.15625,-0.5 0,-0.64117 -0.56229,-1.15625 -1.25,-1.15625 z m 7.5,0 c -0.68772,0 -1.25,0.51508 -1.25,1.15625 0,0.19022 0.0687,0.34214 0.15625,0.5 0.2076,-0.37426 0.61005,-0.65625 1.09375,-0.65625 0.48934,0 0.89792,0.27482 1.09375,0.65625 0.0794,-0.15463 0.125,-0.31504 0.125,-0.5 0,-0.64117 -0.53104,-1.15625 -1.21875,-1.15625 z m -5.0625,1.65625 c -0.24632,1.04124 -1.24534,1.8125 -2.4375,1.8125 -1.18081,0 -2.15456,-0.75502 -2.40625,-1.78125 -0.0326,0.15175 -0.0625,0.30846 -0.0625,0.46875 0,1.28234 1.0933,2.3125 2.46875,2.3125 1.37545,0 2.5,-1.03016 2.5,-2.3125 0,-0.17336 -0.0239,-0.33674 -0.0625,-0.5 z m 2.625,0.03125 c -0.0359,0.15617 -0.0625,0.30294 -0.0625,0.46875 0,1.28234 1.12455,2.3125 2.5,2.3125 1.37545,0 2.46875,-1.03016 2.46875,-2.3125 0,-0.16029 -0.03,-0.31697 -0.0625,-0.46875 -0.25169,1.02623 -1.22544,1.78125 -2.40625,1.78125 -1.18081,0 -2.17929,-0.75502 -2.4375,-1.78125 z M 99,67.266494 l 0,1 2,0 0,-1 z m 5,0 0,1 2,0 0,-1 z m 5,0 0,1 3,0 0,-1 z m -101.5,0 c -1.933,0 -3.5,1.567 -3.5,3.5 0,0.16773 0.00805,0.33856 0.03125,0.5 0.24009,-1.699 1.70348,-3 3.46875,-3 1.73308,0 3.15841,1.25256 3.4375,2.90625 0.0156,-0.13448 0.0625,-0.26754 0.0625,-0.40625 0,-1.933 -1.567,-3.5 -3.5,-3.5 z m 27.5,1 0,1 2,0 0,-1 z m 71,1 0,1 1,0 0,-1 z m 0,1 -2,0 0,1 2,0 z m -65.25,-1.5625 -0.75,0.5 3,2 0,-1 z m 2.25,0.1875 0,1 c 2.26799,8.7e-4 3.4435,1.45051 4,2.3125 -0.014,-0.50756 -0.142583,-0.99673 -0.34375,-1.4375 -0.01583,-0.0347 -0.04562,-0.05965 -0.0625,-0.09375 C 45.939623,69.851134 44.84378,68.892204 43,68.891494 z m 56,2.375 0,1 2,0 0,-1 z m -86.03125,-0.0625 c -0.0883,1.09275 -0.49087,2.08521 -1.125,2.90625 l 0.375,0.375 C 12.6919,73.678874 13,72.770744 13,71.766494 c 0,-0.18985 -0.01255,-0.37761 -0.03125,-0.5625 z M 37,71.266494 l 0,1 1,0 0,-1 z m 0,1 -2,0 -2,0 0,1 2,0 2,0 z m 69,0 0,1 1,0 0,-1 z m 0,1 -2,0 -1,0 0,1 1,0 2,0 z m 2,-1 0,0.84375 0,0.15625 0.25,0 0.75,-0.75 0,-0.25 z M 2.03125,71.328994 C 2.01985,71.473844 2,71.618704 2,71.766494 c 0,3.03756 2.46243,5.5 5.5,5.5 1.04725,0 2.01057,-0.30446 2.84375,-0.8125 l 3.53125,3.53125 c 0.39174,0.39173 1.01451,0.39173 1.40625,0 0.33125,-0.33125 0.35395,-0.82959 0.125,-1.21875 -0.0418,0.0711 -0.0645,0.15826 -0.125,0.21875 -0.39174,0.39173 -1.01451,0.39173 -1.40625,0 l -3.53125,-3.53125 c -0.83318,0.50804 -1.7965,0.8125 -2.84375,0.8125 -2.84772,0 -5.1871,-2.1641 -5.46875,-4.9375 z M 98,73.266494 l 0,1 1,0 0,-1 z m 3,0 0,1 1,0 0,-1 z m 9.21875,0 c 0.13749,0.14402 0.26979,0.29334 0.40625,0.4375 l -5.21875,5.25 -1.40625,1.40625 -1.40625,-1.40625 -1.625,-1.625 -0.5,0.5 2.125,2.125 1.40625,1.40625 1.40625,-1.40625 5.21875,-5.25 c -0.13646,-0.14416 -0.26876,-0.29348 -0.40625,-0.4375 l 1.375,0 0.40625,0 0,-1 -0.40625,0 -0.96875,0 z m -67.21875,0 0,1 3,0 0,-1 z m -9,2 c 0.056,2.03024 1.74134,3.6862 4,3.6875 l 0,-1 c -1.64956,-9.5e-4 -2.96714,-0.88894 -3.59375,-2.15625 -0.0253,-0.0318 -0.0386,-0.06245 -0.0625,-0.09375 -0.11831,-0.15487 -0.25718,-0.30341 -0.34375,-0.4375 z m 9,1 0,1 3,0 0,-1 z m -2.75,1.5 -2.25,1.4375 0,1 3,-1.9375 z m 1.75,1.5 0,1 1,0 0,-1 z m 1,1 0,1 3,0 2,0 0,-1 -2,0 z m 292.5,17 -0.5,1 0,1 1,-2 z m -0.5,2 -0.5,0 -4.5,9.000036 0.5,0 4,-8 0.5,0 z M 37,100.48529 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,-0.55401 0.446,-1 1,-1 l 8,0 c 0.554,0 1,0.44599 1,1 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 z m 36,-1.218796 c -0.207107,0 -0.423297,0.01085 -0.625,0.03125 -0.125778,0.0159 -0.252316,0.0374 -0.375,0.0625 -2.278414,0.46623 -4,2.490036 -4,4.906286 0,0.17259 0.01418,0.33191 0.03125,0.5 0.25605,-2.52128 2.379919,-4.5 4.96875,-4.5 2.588831,0 4.7127,1.97872 4.96875,4.5 0.01707,-0.16809 0.03125,-0.32741 0.03125,-0.5 0,-2.41625 -1.721586,-4.440056 -4,-4.906286 -0.122684,-0.0251 -0.249222,-0.0466 -0.375,-0.0625 -0.04024,-0.004 -0.08453,0.003 -0.125,0 -0.168085,-0.0171 -0.327411,-0.03125 -0.5,-0.03125 z m 58,0 c -0.554,0 -1,0.446002 -1,1.000036 l 0,1 c 0,-0.554 0.446,-1 1,-1 l 0.5,0 2,0 9.5,0 c 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554034 -0.446,-1.000036 -1,-1.000036 z m 32.03125,0 c -0.554,0 -1,0.446002 -1,1.000036 l 0,1 c 0,-0.554 0.446,-1 1,-1 l 9.5,0 2,0 0.5,0 c 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554034 -0.446,-1.000036 -1,-1.000036 z M 195,100.26653 c -0.554,0 -1,1 -1,1 l 0,1 c 0,-0.554 0.446,-1 1,-1 l 12,0 c 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554 -0.446,-1 -1,-1 z m 32,0 c -0.554,0 -1,1 -1,1 l 0,1 c 0,-0.554 0.446,-1 1,-1 l 12,0 c 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554 -0.446,-1 -1,-1 z m 96,-1.000036 c -0.554,0 -1,0.445992 -1,1.000036 l 0,1 c 0,-0.55401 0.446,-1 1,-1 l 0.5,0 3.5,0 0.5,0 3.5,0 1,0 0.5,-1.000036 -1.5,0 -4,0 z m 13,0.28125 0,0.718786 0.71875,0 C 336.5419,99.964166 336.30232,99.724594 336,99.547744 z M 99,100.26653 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,-0.55401 0.446,-1 1,-1 l 1.5,0 2,0 8.5,0 c 0.554,0 1,0.44599 1,1 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 z m -96,2.21876 0,1 1,0 3,0 2,0 5,0 1,0 0,7 0,-8 z m 128.5,-1.21876 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.0444,0.53446 0.5625,0.5 l 0.4375,0 0,-1 -0.4375,0 c -0.0257,0.002 -0.0391,-1.5e-4 -0.0625,0 z m 1.5,0 0,1 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 39.53125,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 0.5,0 0,-1 z m 1.5,0 0,1 0.4375,0 c 0.5181,0.0345 0.5625,-0.25763 0.5625,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 -0.0234,-1.5e-4 -0.0368,0.002 -0.0625,0 z m 117.96875,0 c -0.18612,0 -0.35468,0.0304 -0.53125,0.0625 -0.5068,0.14135 -0.92854,0.48982 -1.1875,0.9375 l 1.71875,0 10,0 1.71875,0 c -0.25896,-0.44768 -0.6807,-0.79615 -1.1875,-0.9375 -0.16893,-0.0471 -0.34578,-0.0625 -0.53125,-0.0625 z m 44,0 0,1 1,0 0,-1 z m -235.5,1 c -0.277,0 -0.5,0.22299 -0.5,0.5 0.0807,0.57703 0.3111,0.49624 1,0.5 l 0,-1 -0.4375,0 c -0.0263,-4.3e-4 -0.0385,10e-4 -0.0625,0 z m 1.5,0 0,1 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.777,-0.5 -0.5,-0.5 z m -57.5,1.71876 -4.5,4.5 -1.40625,-1.40625 -0.9375,-0.9375 -0.5,0.5 1.4375,1.4375 1.40625,1.40625 5,-5 z m -40.5,0.5 0,1 3,0 0,-1 z m 197,-0.21876 3,4 3,-4 -0.75,0 -2.25,3 -2.25,-3 z m 26,0 3,4 3,-4 -0.75,0 -2.25,3 -2.25,-3 z m 109,-1 0,1 1,0 0,-1 z m -327,2.21876 0,1 5,0 0,-1 z m 61.0625,-0.71876 c -0.02868,0.16658 -0.0625,0.32524 -0.0625,0.5 0,1.65685 1.34315,3 3,3 1.65685,0 3,-1.34315 3,-3 0,-0.17476 -0.03382,-0.33342 -0.0625,-0.5 -0.243216,1.41264 -1.455414,2.5 -2.9375,2.5 -1.482086,0 -2.694284,-1.08736 -2.9375,-2.5 z m -3.03125,0.125 C 67.02375,105.01412 67,105.14206 67,105.26653 c 0,3.3137 2.68629,6 6,6 3.31371,0 6,-2.6863 6,-6 0,-0.12447 -0.02378,-0.25241 -0.03125,-0.375 -0.273821,2.69627 -2.325104,4.84119 -4.96875,5.28125 -0.162744,0.0333 -0.331915,0.0454 -0.5,0.0625 -0.16239,0.0132 -0.334211,0.0312 -0.5,0.0312 -0.165789,0 -0.33761,-0.0182 -0.5,-0.0312 -0.04138,-0.004 -0.08393,0.005 -0.125,0 -0.127563,-0.013 -0.249927,-0.0417 -0.375,-0.0625 -2.643646,-0.44006 -4.694929,-2.58498 -4.96875,-5.28125 z m 189.96875,0.375 0,1 c 0,1.662 1.338,3 3,3 l 10,0 c 1.662,0 3,-1.338 3,-3 l 0,-1 c 0,1.662 -1.338,3 -3,3 l -10,0 c -1.662,0 -3,-1.338 -3,-3 z m 32,0 0,1 c 0,1.662 1.338,3 3,3 l 10,0 c 1.662,0 3,-1.338 3,-3 l 0,-1 c 0,1.662 -1.338,3 -3,3 l -10,0 c -1.662,0 -3,-1.338 -3,-3 z m 47,0 0,1 1,0 0,-1 z m -192,0.40625 -4.59375,4.59375 0.84375,0 c 0.0134,-0.0178 0.0149,-0.0462 0.0312,-0.0625 l 3.71875,-3.6875 0,-0.84375 z m 18.03125,0 0,0.84375 3.71875,3.6875 c 0.0163,0.0163 0.0179,0.0447 0.0312,0.0625 l 0.84375,0 -4.59375,-4.59375 z M 4,107.48529 l 0,1 3,0 0,-1 z m 321.65625,-0.25001 c -0.0517,0.018 -0.0982,0.0312 -0.15625,0.0312 l -0.5,0 -1,0 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0.5,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.1841 -0.16469,-0.4438 -0.3125,-0.53125 -0.007,-0.004 -0.0247,0.003 -0.0312,0 z M 9,108.48529 l 0,1 5,0 0,-1 z m 26,0 0,1 c 0,1.0907 0.9093,2 2,2 l 8,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 l -8,0 c -1.0907,0 -2,-0.9093 -2,-2 z m 96.5,-1.21876 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.12178,-0.5281 -0.5,-0.5 l -0.5,0 -1,0 z m 40.8125,0 c -0.19381,0.0717 -0.28125,0.29225 -0.28125,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -0.5,0 -1,0 -0.5,0 c -0.0945,-0.007 -0.15415,-0.0239 -0.21875,0 z m 20.6875,1 0,1 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 l -12,0 c -1.0907,0 -2,-0.9093 -2,-2 z m 32,0 0,1 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 l -12,0 c -1.0907,0 -2,-0.9093 -2,-2 z m 96,-1 0,1 c 0,1.09069 0.9093,2 2,2 l 4,0 0.5,-1 -4.5,0 c -1.0907,0 -2,-0.90931 -2,-2 z m 15,0 0,1 0.71875,0 0.28125,0 0,-1 z m -192,0.625 -2.34375,2.375 0.625,0 1.71875,-1.75 z m 18.03125,0 0,0.625 1.71875,1.75 0.625,0 z M 2,109.48529 l 0,1 c 0,0.55399 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44601 1,-1 l 0,-1 c 0,0.55399 -0.446,1 -1,1 l -12,0 c -0.554,0 -1,-0.44601 -1,-1 z m 95,-1.21876 0,1 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 l -12,0 c -1.0907,0 -2,-0.9093 -2,-2 z m 3.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.11921,-0.5 -0.5,-0.5 l -0.5,0 -1,0 z m 28.5,1 0,1 c 0,1.09069 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.90931 2,-2 l 0,-0.375 c 0.0328,-0.0893 0.0213,-0.17215 0,-0.25 l 0,-0.375 c 0,1.09069 -0.9093,2 -2,2 l -0.71875,0 -0.625,0 -1.40625,0 -0.84375,0 -3.375,0 -5.03125,0 c -1.0907,0 -2,-0.90931 -2,-2 z m 32.03125,0 0,0.375 c -0.0213,0.0779 -0.0328,0.1607 0,0.25 l 0,0.375 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 l -7.03125,0 -1.375,0 -0.84375,0 -1.40625,0 -0.625,0 -0.71875,0 c -1.0907,0 -2,-0.9093 -2,-2 z m 168.46875,0 -1.5,3 -1.5,0 -0.5,1 2,0 1.5,-3 1.5,0 0,-1 -1,0 z m 2.5,0 0,1 1,0 0,-1 z m 2,0 0,1 1,0 0,-1 z m 2,0 0,0.71875 c 0.30232,-0.17686 0.5419,-0.41643 0.71875,-0.71875 z m -195.5,22 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.5,0 0,-1 z m 63.96875,0 -0.0937,0.34375 -3,0 -2.40625,8.65625 -2.71875,0 -0.28125,1 3,0 2.40625,-8.65625 3,0 0.3125,-1.34375 -0.21875,0 z m -159.1875,0.0312 -0.25,0.96875 -1.59375,0 -2.0625,8.03125 0.25,0 1.8125,-7.03125 1.59375,0 0.5,-1.96875 z m 150.3125,0.3125 -0.21875,1 2.71875,0 0.28125,-1 z M 8.5625,132.26653 c -0.21684,0.0127 -0.42028,0.0372 -0.59375,0.0625 l 0,1 c 0.17347,-0.0253 0.37691,-0.0498 0.59375,-0.0625 0.21684,-0.0126 0.42262,1e-5 0.625,0 0.24576,1e-5 0.48745,0.0245 0.71875,0.0625 0.23129,0.0253 0.42028,0.0862 0.59375,0.1875 0.17347,0.0886 0.30506,0.19778 0.40625,0.375 0.0253,0.0411 0.0431,0.10584 0.0625,0.15625 0.0553,-0.14566 0.09375,-0.29026 0.09375,-0.46875 0,-0.27849 -0.05499,-0.52292 -0.15625,-0.6875 -0.10119,-0.17722 -0.23278,-0.2864 -0.40625,-0.375 -0.17347,-0.1013 -0.36246,-0.1622 -0.59375,-0.1875 -0.2313,-0.038 -0.47299,-0.0625 -0.71875,-0.0625 -0.20238,1e-5 -0.40816,-0.0126 -0.625,0 z m 31.125,0 -0.25,1 1.34375,0 0.25,-1 z m 104.3125,0.5 c 0,0.277 -0.223,0.5 -0.5,0.5 l -0.5,0 -2,0 0,1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 z m -130.375,1.03125 c -0.063,0.36627 -0.21145,0.69408 -0.4375,1 -0.30358,0.43041 -0.69834,0.77808 -1.21875,1.03125 0.33848,0.10821 0.62371,0.23704 0.875,0.375 0.12273,-0.12465 0.24256,-0.26278 0.34375,-0.40625 0.31803,-0.4304 0.46874,-0.91175 0.46875,-1.46875 0,-0.18355 -6.9e-4,-0.34959 -0.03125,-0.53125 z m 149.46875,0.0937 c -0.19229,0.43111 -0.1321,0.96164 0.21875,1.3125 l 1.53125,1.53125 0.5,-0.5 -2.03125,-2.03125 c -0.0959,-0.0959 -0.16343,-0.1957 -0.21875,-0.3125 z m 7.78125,0 c -0.0553,0.1168 -0.12287,0.21661 -0.21875,0.3125 l -2.03125,2.0313 0.5,0.5 1.53125,-1.53125 c 0.35085,-0.35086 0.41104,-0.88139 0.21875,-1.3125 z m -30.875,0.875 0,1 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 -0.5,0 c -0.277,0 -0.5,-0.223 -0.5,-0.5 z m -8.90625,0.125 c -0.19229,0.43111 -0.1321,0.96164 0.21875,1.3125 l 1.53125,1.53125 0.5,-0.5 -2.03125,-2.03125 c -0.0959,-0.0959 -0.16343,-0.1957 -0.21875,-0.3125 z m 7.78125,0 c -0.0553,0.1168 -0.12287,0.21661 -0.21875,0.3125 l -2.03125,2.0313 0.5,0.5 1.53125,-1.53125 c 0.35085,-0.35086 0.41104,-0.88139 0.21875,-1.3125 z m -69.875,1.8438 0,1 c 0,0 0.0818,1.2882 0.21875,1.84375 0.13694,0.55554 0.35886,1.04609 0.6875,1.4375 0.32865,0.3914 0.76476,0.6916 1.3125,0.90625 0.56144,0.20201 1.24087,0.28125 2.0625,0.28125 0.8353,0 1.53231,-0.0792 2.09375,-0.28125 0.56143,-0.21465 1.03265,-0.51485 1.375,-0.90625 0.34233,-0.39141 0.5818,-0.88196 0.71875,-1.4375 0.13697,-0.55555 0.18749,-1.16195 0.1875,-1.84375 l 0,-1 c -1e-5,0.6818 -0.05053,1.2882 -0.1875,1.84375 -0.13695,0.55554 -0.37642,1.04609 -0.71875,1.4375 -0.34235,0.3914 -0.81357,0.6916 -1.375,0.90625 -0.56144,0.20205 -1.25845,0.28125 -2.09375,0.28125 -0.82163,0 -1.50106,-0.0792 -2.0625,-0.28125 -0.54774,-0.21465 -0.98385,-0.51485 -1.3125,-0.90625 -0.32864,-0.39141 -0.55056,-0.88196 -0.6875,-1.4375 C 69.0818,138.02348 69,137.41708 69,136.73528 z m -61.03125,0.21875 0,1 1.4375,0 c 0.69388,1e-5 1.220231,0.15308 1.625,0.40625 0.29273,0.16795 0.4753,0.42054 0.5625,0.75 0.0413,-0.15807 0.0625,-0.33102 0.0625,-0.53125 0,-0.56965 -0.20578,-0.97823 -0.625,-1.21875 -0.404769,-0.25317 -0.93112,-0.40624 -1.625,-0.40625 z M 167,137.89153 l -2.0625,2.03125 c -0.45327,0.45327 -1.17173,0.45327 -1.625,0 -0.10242,-0.10242 -0.16262,-0.2179 -0.21875,-0.34375 -0.20618,0.43535 -0.13864,0.98636 0.21875,1.34375 0.45327,0.45327 1.17173,0.45327 1.625,0 l 2.0625,-2.03125 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.35739,-0.35739 0.42493,-0.9084 0.21875,-1.34375 -0.0561,0.12585 -0.11633,0.24133 -0.21875,0.34375 -0.45327,0.45327 -1.17173,0.45327 -1.625,0 z m -32,1 -2.0625,2.03125 c -0.45327,0.45327 -1.17173,0.45327 -1.625,0 -0.10242,-0.10242 -0.16262,-0.2179 -0.21875,-0.34375 -0.20618,0.43535 -0.13864,0.98636 0.21875,1.34375 0.45327,0.45327 1.17173,0.45327 1.625,0 l 2.0625,-2.03125 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.35739,-0.35739 0.42493,-0.9084 0.21875,-1.34375 -0.0561,0.12585 -0.11633,0.24133 -0.21875,0.34375 -0.45327,0.45327 -1.17173,0.45327 -1.625,0 z m -120.75,0.28125 c -0.0559,0.448 -0.1825,0.85035 -0.375,1.1875 -0.27467,0.46838 -0.64796,0.83384 -1.125,1.125 -0.4626,0.2785 -1.00573,0.49841 -1.65625,0.625 -0.636069,0.11395 -1.32525,0.15625 -2.0625,0.15625 l -3.75,0 0,1 3.75,0 c 0.73725,0 1.426431,-0.0423 2.0625,-0.15625 0.65052,-0.12659 1.19365,-0.3465 1.65625,-0.625 0.47704,-0.29116 0.85033,-0.65662 1.125,-1.125 0.27465,-0.48104 0.40624,-1.07235 0.40625,-1.78125 0,-0.13608 -0.01035,-0.27282 -0.03125,-0.40625 z m 158.25,0.0937 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.24281,0.60287 0.5,0.5 l 2.5,0 0,-1 z m 29.75,0.65625 -0.5,0.46875 1.4375,1.46875 0.46875,-0.5 z m 4.8125,0 -1.4375,1.4375 0.5,0.5 1.4375,-1.46875 z M 176,140.76653 c 0,0.277 -0.223,0.5 -0.5,0.5 l -0.5,0 -2,0 0,1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 z m -133.28125,0.53125 -0.25,0.96875 -5.34375,0 -0.28125,1 5.625,0 0.5,-1.96875 z M 194.5,142.26653 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 10.125,0.0937 -1.90625,1.96875 -0.5,-0.5 -0.46875,0.5 0.96875,1 1.90625,-1.96875 1.96875,1.96875 0.96875,-1 -0.5,-0.5 -0.46875,0.5 z m -32.625,0.40625 0,1 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 -0.5,0 c -0.277,0 -0.5,-0.223 -0.5,-0.5 z m -103.5,0.5 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 10,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 224.5,19 0,1 2,0 0,-1 z m -288.5,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 0.5,0 0,-1 z m 4,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 27,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 10,0 c 0,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.599346,0.45353 0.5625,0.5 l 0.4375,0 0,-1 -0.4375,0 z m 28,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 25,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 361.5,0 0,1 1,0 0,-1 z m 27,0 0,1 1,0 0,-1 z m -354.5,1 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.20711 0.13304,0.39285 0.3125,0.46875 0.0598,0.0253 0.11847,0.0312 0.1875,0.0312 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.069,0 -0.12768,0.006 -0.1875,0.0312 -0.17946,0.0759 -0.3125,0.26164 -0.3125,0.46875 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 2,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 37,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -2,0 -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m -9,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m 41,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.777,0.46875 -0.5,0.46875 l -3,0 -2,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 27,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 2,0 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 -0.223,-0.46875 -0.5,-0.46875 z m 9,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 85.5,0 0,1 7,0 0,-1 z m 33.875,0 0,1 8.09375,0 0,-1 z m 35.125,0 0,1 7,0 0,-1 z m 27,0 0,1 12,0 0,-1 z m 43,0 0,1 1,0 0,-1 z m 27,0 0,1 1,0 0,-1 z m -421.9375,0.5 c -0.0411,0.15976 -0.0625,0.32741 -0.0625,0.5 0,1.10456 0.895431,2 2,2 1.104569,0 2,-0.89544 2,-2 0,-0.17259 -0.0214,-0.34024 -0.0625,-0.5 -0.221963,0.8627 -1.00552,1.5 -1.9375,1.5 -0.93198,0 -1.715537,-0.6373 -1.9375,-1.5 z m 40,0 c -0.0411,0.15976 -0.0625,0.32741 -0.0625,0.5 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-0.17259 -0.0214,-0.34024 -0.0625,-0.5 -0.22196,0.8627 -1.00552,1.5 -1.9375,1.5 -0.93198,0 -1.71554,-0.6373 -1.9375,-1.5 z m -98.5625,0.5 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 27,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 38,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 25,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 200.5,0 0,1 1,0 0,-1 z m 3,0 0,1 1,0 0,-1 z m 154.0625,0.5 c -0.0287,0.16658 -0.0625,0.32524 -0.0625,0.5 0,1.65685 1.34315,3 3,3 l 0,-1 c -1.48209,0 -2.69428,-1.08736 -2.9375,-2.5 z m 27,0 c -0.0287,0.16658 -0.0625,0.32524 -0.0625,0.5 0,1.65685 1.34315,3 3,3 l 0,-1 c -1.48209,0 -2.69428,-1.08736 -2.9375,-2.5 z m -224.125,0.0625 c -0.0395,0.16596 -0.0625,0.33 -0.0625,0.5 0,1.2454 1.11952,2.25457 2.53125,2.3125 0.11409,-0.35505 0.2024,-0.68476 0.25,-1 -0.0438,8.7e-4 -0.0797,0 -0.125,0 -1.27634,0 -2.33451,-0.77035 -2.59375,-1.8125 z m 8,0 c -0.0395,0.165 -0.0625,0.33 -0.0625,0.5 0,1.24541 1.11952,2.25457 2.53125,2.3125 0.11379,-0.35113 0.2024,-0.68899 0.25,-1 -0.0465,8.7e-4 -0.077,0 -0.125,0 -1.27634,0 -2.33451,-0.77035 -2.59375,-1.8125 z m -2.78125,0.34375 c -0.32899,3.04037 -2.38768,4.9421 -3.9375,5.71875 -0.35953,0.46482 -0.80193,0.93399 -1.34375,1.40625 1.33333,0 5.3125,-2.32015 5.3125,-6.96875 0,-0.0539 -0.0272,-0.10254 -0.0312,-0.15625 z m 8,0 c -0.32572,3.03782 -2.38152,4.9188 -3.9375,5.6875 -0.35966,0.46296 -0.80081,0.93301 -1.34375,1.40625 1.37466,0 5.3125,-2.28889 5.3125,-6.9375 0,-0.0539 -0.0272,-0.10264 -0.0312,-0.15625 z M 138.5,167.26653 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 35,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 26,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 29,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 -0.223,-0.46875 -0.5,-0.46875 z m 66.5,0 0,1 1,0 0,-1 z m 0,1 -2,0 -1,0 0,1 1,0 2,0 z m -290,-0.5 0,1 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-1 c 0,0.27699 -0.223,0.5 -0.5,0.5 -0.277,0 -0.5,-0.22301 -0.5,-0.5 z m 41,0 0,1 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-1 c 0,0.27699 -0.223,0.5 -0.5,0.5 -0.277,0 -0.5,-0.22301 -0.5,-0.5 z m 251,0.5 0,1 1,0 0,-1 z m 3,0 0,1 2,0 0,-1 z m 23,0 0,1 9,0 2,0 0,-1 z m 65,0 0,1 2,0 9,0 0,-1 z m 31,0 0,1 12,0 0,-1 z m -64.15625,0.0312 0,1 2.03125,0 8.09375,0 2.03125,0 0,-1 z m -224.21875,0.9688 -0.625,0.46875 0,0.0625 2,1.46875 0,-1 z m 1.375,1 2.5,0 c 0.0693,0 0.12764,-0.008 0.1875,-0.0312 0.17958,-0.0702 0.3125,-0.24018 0.3125,-0.4375 l 0,-0.0625 c 0,-0.0658 -0.006,-0.13122 -0.0312,-0.1875 -0.0757,-0.16883 -0.261,-0.28125 -0.46875,-0.28125 l -2.5,0 0,1 z m 6.5,-1 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 2,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 37,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -2,0 -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m -9.125,0 0.625,0.46875 0,0.0625 -2,1.46875 0,-1 z m -1.375,1 -2.5,0 c -0.27637,0 -0.5,-0.18037 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.22363,-0.46875 0.5,-0.46875 l 2.5,0 z m 42.59375,-1 c 0.28935,0 0.53125,0.20565 0.53125,0.46875 l 0,0.0625 c 0,0.43405 -0.2419,0.46875 -0.53125,0.46875 l -2.59375,0 0,-1 z m -2.59375,1 0,1 -2.09375,-1.46875 0,-0.0625 0.65625,-0.46875 z m -5.5,-1 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.777,0.46875 -0.5,0.46875 l -3,0 -2,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 27,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 2,0 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 -0.223,-0.46875 -0.5,-0.46875 z m 9,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 2.5,0 0,-1 z m 2.5,1 0,1 2,-1.46875 0,-0.0625 -0.625,-0.46875 z m 215.5,-0.5 -2.5,2.5 0,1 3,-3 z m 39,0 -0.5,0.5 3,3 0,-1 z m -193.3125,0.875 -2.09375,4.65625 -1.40625,0 -0.4375,1 1.84375,0 2.53125,-5.65625 z m -4.75,0.4375 -1.40625,1.375 0.5,0.5 1.40625,-1.375 z m 5.875,0 -0.5,0.5 1.375,1.375 0.5,-0.5 z M 3.5,171.26653 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,-1 z m 5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 27,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 9,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,-1 z m 29,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 25,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 40,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 35,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 26,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 29,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 -0.223,-0.46875 -0.5,-0.46875 z m 94.5,0 0,1 9,0 0,-1 z m 67,0 0,1 9,0 0,-1 z m 29,0 0,1 12,0 0,-1 z m -62.125,0.0625 0,1 8.09375,0 0,-1 z M 6,172.76653 c 0,0.0693 -0.00605,0.12755 -0.03125,0.1875 -0.0505,0.13912 -0.15407,0.24025 -0.28125,0.28125 -0.0599,0.0252 -0.1182,0.0312 -0.1875,0.0312 l -0.5,0 -1,0 0,1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 C 5.99395,173.89413 6,173.83578 6,173.76653 z m 41,0 c 0,0.0693 -0.0061,0.12755 -0.03125,0.1875 -0.05055,0.13912 -0.15407,0.24025 -0.28125,0.28125 -0.05986,0.0252 -0.1182,0.0312 -0.1875,0.0312 l -0.5,0 -1,0 0,1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 C 46.99395,173.89413 47,173.83578 47,173.76653 z m 20.0625,0 c -0.0411,0.15976 -0.0625,0.32741 -0.0625,0.5 0,1.10456 0.895431,2 2,2 1.104569,0 2,-0.89544 2,-2 0,-0.17259 -0.0214,-0.34024 -0.0625,-0.5 -0.221963,0.8627 -1.00552,1.5 -1.9375,1.5 -0.93198,0 -1.715537,-0.6373 -1.9375,-1.5 z m 40,0 c -0.0411,0.15976 -0.0625,0.32741 -0.0625,0.5 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-0.17259 -0.0214,-0.34024 -0.0625,-0.5 -0.22196,0.8627 -1.00552,1.5 -1.9375,1.5 -0.93198,0 -1.71554,-0.6373 -1.9375,-1.5 z m 184.5625,0.1875 -0.5,0.5 2.84375,2.84375 0.96875,-0.90625 -0.5,-0.53125 -0.46875,0.4375 z m 11.5,0 -2.34375,2.34375 -0.46875,-0.4375 -0.5,0.53125 0.96875,0.90625 2.84375,-2.84375 z M 8.5,173.26653 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 27,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 38,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 25,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 34,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.069,0 -0.12768,0.006 -0.1875,0.0312 -0.17946,0.0759 -0.3125,0.26164 -0.3125,0.46875 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 37,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m -9,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m 41,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 27,0 c -0.277,0 -0.5,0.20566 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 -0.223,-0.46875 -0.5,-0.46875 z m 9,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 221.5,0 0,1 1,0 0,-1 z m 2,0 0,1 1,0 0,-1 z m 25,0 0,1 1,0 0,-1 z m 2,0 0,1 1,0 0,-1 z m -165,1 0,1 12,0 0,-1 z m 64,0 0,1 12,0 0,-1 z m 32,0 0,1 12,0 0,-1 z m -64.15625,0.0937 0,1 12.15625,0 0,-1 z M 3,174.76653 l 0,1 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 -0.5,0 c -0.277,0 -0.5,-0.22301 -0.5,-0.5 z m 41,0 0,1 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 -0.5,0 c -0.277,0 -0.5,-0.22301 -0.5,-0.5 z m 92.0625,0 0,1 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 l 0,-1 c 0,0.277 -0.21154,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.223 -0.46875,-0.5 z m 32.9375,0 0,1 c 0,0.277 -0.21154,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.223 -0.46875,-0.5 l 0,-1 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 z m 32.9375,0 0,1 c 0,0.27699 -0.21154,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.22301 -0.46875,-0.5 l 0,-1 c 0,0.27699 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.22301 0.46875,-0.5 z m 31.0625,0 0,1 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25722,0 0.46875,-0.223 0.46875,-0.5 l 0,-1 c 0,0.277 -0.21153,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.223 -0.46875,-0.5 z m -228,22.5 c -0.1602,0 -0.31869,0.0256 -0.46875,0.0625 C 3.6596,197.54351 3,198.33602 3,199.26653 l 0,1 c 0,-1.09071 0.9093,-2 2,-2 l 3,0 0,-1 z m 5,0 0,1 3,0 c 1.0907,0 2,0.90929 2,2 l 0,-1 c 0,-0.93051 -0.6596,-1.72302 -1.53125,-1.9375 -0.0216,-0.004 -0.0407,-0.0283 -0.0625,-0.0312 -0.12925,-0.027 -0.26991,-0.0312 -0.40625,-0.0312 l -3,0 z m 27,0 c -0.1602,0 -0.31869,0.0256 -0.46875,0.0625 C 35.6596,197.54351 35,198.33602 35,199.26653 l 0,1 c 0,-1.09071 0.9093,-2 2,-2 l 3,0 0,-1 z m 5,0 0,1 3,0 c 1.0907,0 2,0.90929 2,2 l 0,0.4375 0.53125,0.53125 0.4375,0.4375 C 47.98778,201.5373 48,201.40693 48,201.26653 l 0,-1 c 0,0.1404 -0.01222,0.27077 -0.03125,0.40625 l -0.4375,-0.4375 L 47,199.70403 l 0,-0.4375 c 0,-0.93051 -0.659603,-1.72302 -1.53125,-1.9375 -0.02162,-0.004 -0.04073,-0.0283 -0.0625,-0.0312 -0.129247,-0.027 -0.269913,-0.0312 -0.40625,-0.0312 l -3,0 z m -36.5,2 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 7,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 -2,0 z m 32,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 4.3125,0 1.5,0 1.1875,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 -2,0 z m -35.5,1 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 1,-1 1,1 3,0 c 1.64649,0 3,-1.35351 3,-3 l 0,-1 c 0,1.48353 -1.10933,2.70546 -2.53125,2.9375 -0.0223,0.005 -0.0399,0.0265 -0.0625,0.0312 -0.13548,0.019 -0.26585,0.0312 -0.40625,0.0312 l -3,0 -1,-1 -1,1 -3,0 c -0.1404,0 -0.27077,-0.0122 -0.40625,-0.0312 -0.0226,-0.005 -0.0402,-0.0258 -0.0625,-0.0312 C 3.10933,202.97199 2,201.75006 2,200.26653 z m 2,0 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,-1 -2.5,0 -0.5,0 c -0.554,0 -1,-0.446 -1,-1 z m 10,0 c 0,0.554 -0.446,1 -1,1 l -0.5,0 -2.5,0 0,1 3,0 c 0.554,0 1,-0.446 1,-1 z m 20,0 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 0.6875,-0.6875 -0.5,-0.5 -0.1875,0.1875 -3,0 c -0.1404,0 -0.27077,-0.0122 -0.40625,-0.0312 -0.0226,-0.005 -0.0401,-0.0258 -0.0625,-0.0312 C 35.10933,202.97189 34,201.75006 34,200.26653 z m 2,0 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,-1 -2.5,0 -0.5,0 c -0.554,0 -1,-0.446 -1,-1 z m 10,0 c 0,0.0353 -0.02772,0.0594 -0.03125,0.0937 l -0.875,0.875 c -0.03434,0.004 -0.05845,0.0312 -0.09375,0.0312 l -0.5,0 -0.1875,0 -1,0 1,1 0.6875,0 c 0.0353,0 0.05941,-0.0277 0.09375,-0.0312 l 0.875,-0.875 C 45.97225,201.32598 46,201.30183 46,201.26653 z m 25.8125,0.65625 c -0.899959,-0.0141 -1.82217,0.32909 -2.8125,1.34375 l 0,1 c 3.96132,-4.05865 6.94268,2.81598 11,-1 l 0,-1 c -3.04299,2.86198 -5.487624,-0.30138 -8.1875,-0.34375 z m 35.375,0 c -2.69988,0.0424 -5.14451,3.20574 -8.1875,0.34375 l 0,1 c 4.05732,3.81599 7.03868,-3.05865 11,1 l 0,-1 c -0.99033,-1.01466 -1.91254,-1.35788 -2.8125,-1.34375 z m -66.34375,0.34375 -0.03125,0.0312 -0.65625,0.71875 0.46875,0.5 0.1875,-0.21875 1,-1.03125 -0.96875,0 z m 1.1875,1.21875 -0.5,0.5 1.59375,1.59375 0.5,-0.5 z m 5.3125,0 -1.59375,1.59375 0.5,0.5 1.59375,-1.59375 z m -2.65625,2.65625 -2.125,2.125 -0.53125,-0.5625 -0.5,0.5 1.03125,1.0625 2.125,-2.125 2.125,2.125 1.03125,-1.0625 -0.5,-0.5 -0.53125,0.5625 z m 22.3125,2.125 0,1 1,0 0,-1 z m 44,0 0,1 1,0 0,-1 z m 154,19 c -0.34628,0 -0.67165,0.0352 -1,0.0937 -0.98506,0.17561 -1.89451,0.59634 -2.65625,1.1875 0.13763,0.005 0.26821,0.0331 0.40625,0.0625 0.0582,0.0594 -0.12804,0.19841 -0.3125,0.34375 0.31668,-0.24446 0.66584,-0.3597 1.09375,-0.375 0.20293,-0.0412 0.41536,-0.0346 0.59375,0 0.16865,-0.0578 0.35611,-0.0825 0.53125,-0.125 -0.22012,-0.0629 0.0305,-0.20755 0.28125,-0.21875 0.0955,-0.004 0.16445,0.0179 0.21875,0.0625 0.11003,0.002 0.2574,-0.10843 0.1875,0.0312 0.12547,-0.0147 0.24703,-0.0248 0.375,-0.0312 -0.12874,-0.0406 0.003,-0.1019 0.125,-0.125 0.10685,-0.0202 0.16269,0.002 0.0312,0.0937 0.0427,-9.4e-4 0.0821,0 0.125,0 0.13861,0 0.27026,0.0205 0.40625,0.0312 0.0233,-0.0312 0.0578,-0.0728 0.125,-0.125 0.0886,-0.0585 0.113,-0.0756 0.125,-0.0625 0.027,0.0293 -0.0732,0.19992 -0.0312,0.1875 0.014,-0.004 0.0355,-0.0411 0.0937,-0.0937 0.27569,-0.0726 0.65041,0.0656 0.84375,0.28125 0.009,0.01 0.0231,0.0209 0.0312,0.0312 0.016,0.0203 0.0186,0.041 0.0312,0.0625 0.005,0.009 -0.005,0.0221 0,0.0312 0.0224,0.0438 0.0566,0.0778 0.0625,0.125 0.11394,-0.038 0.23099,-0.0536 0.34375,-0.0937 0.0491,0.0177 0.10773,0.0123 0.15625,0.0312 -0.057,0.0184 -0.10829,0.071 -0.15625,0.0625 -0.2431,0.18027 0.18715,0.11836 0.4375,0.21875 -0.0479,-0.17153 0.0692,-0.42292 0.15625,-0.46875 0.041,-0.0216 0.0545,0.0172 0.0625,0.125 -0.0128,0.0643 0.017,0.19499 0.0312,0.3125 1.80061,0.91451 3.06549,2.70374 3.25,4.8125 0.012,-0.15544 0.0312,-0.31017 0.0312,-0.46875 0,-2.36207 -1.35959,-4.39623 -3.34375,-5.375 0.0114,0.14518 0.0591,0.3475 -0.0312,0.3125 0.10838,-0.49625 -0.9425,-0.21013 -0.59375,-0.46875 0.048,0.009 0.0992,-0.0441 0.15625,-0.0625 -0.0485,-0.0189 -0.10715,-0.0137 -0.15625,-0.0312 -0.26917,0.0961 -0.54455,0.1962 -0.8125,0.25 -0.0958,-0.002 -0.2497,-0.019 -0.3125,-0.0312 0.0241,-0.006 0.0765,-0.0264 0.1875,-0.0312 0.0729,-0.099 0.0423,-0.0421 0.15625,-0.125 0.0599,-0.086 0.79642,-0.122 0.1875,-0.125 -0.0279,-0.003 -0.019,-0.0282 -0.0312,-0.0312 0.0509,-0.01 0.14162,-0.0192 0.25,-0.0312 -0.26349,-0.0756 -0.53626,-0.14391 -0.8125,-0.1875 -0.27624,-0.0436 -0.55593,-0.0625 -0.84375,-0.0625 z m 0.9375,0.34375 c 0.10941,-0.002 0.19002,0.0392 -0.0312,0.125 l -0.125,0 c -0.0956,-0.0755 0.047,-0.123 0.15625,-0.125 z m -0.34375,0.34375 c 0.0496,-0.007 0.1158,-0.01 0.1875,0.0312 0.23935,-0.0591 0.64214,0.0399 0.15625,0.0937 -0.0173,-0.0557 -0.1805,0.0348 -0.1875,-0.0312 -0.30815,0.0694 -0.3051,-0.0736 -0.15625,-0.0937 z m -96.375,0.125 c -2.01716,0.24966 -3.59375,2.35002 -3.59375,4.84375 0,0.18815 0.0135,0.38055 0.0312,0.5625 0.18622,-2.45446 1.88384,-4.40625 3.96875,-4.40625 2.08491,0 3.78253,1.95179 3.96875,4.40625 0.0174,-0.18193 0.0312,-0.37435 0.0312,-0.5625 0,-2.65998 -1.79067,-4.84375 -4,-4.84375 -0.13808,0 -0.27177,-0.0166 -0.40625,0 z m 95.96875,0.0625 c 0.14032,-0.0399 0.26801,0.0676 -0.0625,0.0937 -0.0249,0.0331 -0.039,0.001 -0.0625,0 0.0321,-0.0541 0.0782,-0.0805 0.125,-0.0937 z m -1.5625,0.0312 c 0.17989,-0.004 0.26434,0.0509 -0.0937,0.125 -0.11866,0.0154 -0.22739,0.165 -0.34375,0.125 -9e-5,-0.1727 0.25776,-0.246 0.4375,-0.25 z M 3,227.26653 l 0,1 2.5,0 9.5,0 0,-1 z m 40.46875,0.3125 c -1.88316,0.0897 -2.926,2.52114 -3.9375,4.78125 l -0.21875,0.5 c -0.80967,1.77098 -1.63642,3.3095 -2.96875,3.3125 0.3882,0.27003 0.75663,0.46625 1.09375,0.59375 0.74347,-0.56869 1.31215,-1.67512 1.875,-2.90625 l 0.21875,-0.5 c 1.0115,-2.26011 2.05434,-4.69152 3.9375,-4.78125 0.33166,-0.0157 0.67688,0.0457 1.0625,0.1875 0.33672,-0.25016 0.70547,-0.40625 1.125,-0.40625 -0.85371,-0.58916 -1.55978,-0.81105 -2.1875,-0.78125 z m 222.46875,0.0312 c -0.10926,0.002 -0.25181,0.0495 -0.15625,0.125 l 0.125,0 c 0.22132,-0.0858 0.14066,-0.12682 0.0312,-0.125 z m 0.5,0.15625 c -0.0203,0.0141 -0.0254,0.0267 -0.0312,0.0625 0.0724,-0.0194 0.14598,-0.0391 0.21875,-0.0625 -0.076,-0.0103 -0.15699,-0.0211 -0.1875,0 z m -0.84375,0.1875 c -0.12371,0.0168 -0.14134,0.131 0.0312,0.125 0.0351,-0.001 0.0729,-0.0196 0.125,-0.0312 0.007,0.066 0.1702,-0.0245 0.1875,0.0312 0.0875,-0.01 0.12024,-0.0198 0.15625,-0.0312 -0.007,-0.0318 -0.0413,-0.0395 -0.0625,-0.0625 -0.0797,-0.0105 -0.16296,-0.0215 -0.25,0 -0.0717,-0.0408 -0.13788,-0.038 -0.1875,-0.0312 z m 2.03125,0.15625 c 0.004,0.029 0.008,0.0565 0,0.0937 0.0384,0.0149 0.0606,-0.0143 0.0625,-0.0625 -0.0144,10e-4 -0.038,-0.0146 -0.0625,-0.0312 z m -2.4375,0.0312 c -0.0468,0.0133 -0.0929,0.0396 -0.125,0.0937 0.0235,0.001 0.0376,0.0331 0.0625,0 0.33051,-0.0263 0.20282,-0.13368 0.0625,-0.0937 z m -0.34375,0.0312 c -0.12212,0.0231 -0.25374,0.0844 -0.125,0.125 l 0.0312,0.0312 0.0937,-0.0312 c 0.22922,-0.13332 0.12212,-0.14807 0,-0.125 z m 1.0625,0.0312 c 0.065,0.0918 0.1072,0.21301 0.1875,0.21875 0.0987,-0.11602 0.1767,-0.13872 0.21875,-0.125 -0.1283,-0.0667 -0.26786,-0.0902 -0.40625,-0.0937 z m -1.5625,0.0315 c -0.0283,0.006 -0.0807,0.0189 -0.125,0.0312 -0.10641,0.0913 -0.14533,0.19131 -0.0625,0.28125 0.23141,-0.0322 0.39735,-0.0693 0.15625,-0.15625 0.0809,-0.1276 0.0749,-0.16495 0.0312,-0.15625 z M 265,228.36023 c -0.0243,-0.005 -0.0587,0.0139 -0.0937,0.0312 -0.0387,0.23854 -0.27092,0.27701 -0.53125,0.28125 0.18753,0.0603 0.34616,0.1219 0.34375,0.3125 0.34901,0.0214 0.0627,-0.2312 0.375,-0.1875 0.0374,-0.0477 0.0595,-0.10421 0.0937,-0.15625 -0.0739,-0.0575 -0.0798,-0.26094 -0.1875,-0.28125 z m 1.375,0 c 0.0343,0.11949 0.009,0.35008 0.0625,0.40625 0.0407,-0.0282 0.12377,-0.0215 0.25,0 -0.007,-0.16706 -0.14492,-0.29959 -0.3125,-0.40625 z m -5.96875,0.0625 c -0.87281,1.042 -1.40625,2.37815 -1.40625,3.84375 0,0.20711 0.0109,0.4233 0.0312,0.625 0.05,-0.77883 0.24163,-1.51871 0.5625,-2.1875 -0.0134,-0.002 -0.021,-0.0151 -0.0312,-0.0625 0.0384,-0.0679 0.0822,-0.1008 0.0937,-0.0937 0.20706,-0.40173 0.46215,-0.78135 0.75,-1.125 0.25655,-0.0158 0.56015,0.0785 0.6875,0.25 0.0297,-0.0169 0.0688,-0.0334 0.0937,-0.0312 0.042,-0.0985 0.08,-0.16987 0.125,-0.1875 -0.33344,-0.18836 -0.1679,-0.36609 -0.0937,-0.5625 -0.009,0.0116 -0.0318,0.0132 -0.0625,-0.0312 0.0243,-0.30945 -0.40794,-0.4586 -0.75,-0.4375 z m 4.25,0.0625 c -0.0294,0.007 -0.0677,0.0412 -0.0937,0.0937 0.23501,0.0305 0.18197,-0.11403 0.0937,-0.0937 z m 2.96875,0 c -0.1229,0.0647 -0.30864,0.56687 0,0.625 0.19641,0.13297 0.0343,-0.35877 0.0625,-0.5 -0.008,-0.10783 -0.0215,-0.14656 -0.0625,-0.125 z m -6.40625,0.15625 c -0.009,0.0326 -0.003,0.0919 0,0.15625 0.008,-0.04 0.0392,-0.0815 0.0312,-0.125 -0.001,-0.0172 -0.0254,-0.0171 -0.0312,-0.0312 z M 261,228.82903 c 0.0264,-0.019 0.0968,0.0763 0,0.0625 -0.007,-0.0415 -0.009,-0.0565 0,-0.0625 z m 4.875,0.34375 c -0.23735,-0.008 -0.70217,0.40793 -0.21875,0.15625 0.44403,-0.16004 -0.2027,0.70993 -0.125,0.125 l -0.0312,0.0625 c -0.0217,0.31005 -0.5469,0.5013 -0.5625,0.5625 -0.30778,0.0882 -0.38275,0.41405 -0.46875,0.34375 0.0688,0.4831 -0.87396,0.50311 -0.53125,1.09375 -0.0138,0.0154 -0.0211,0.21545 -0.0937,0.15625 -0.0109,-0.394 -0.37081,-0.61268 -0.71875,-0.4375 0.0163,0.0122 0.0242,0.0232 0.0312,0.0312 -0.10385,0.007 -0.5117,-0.077 -0.5625,0.125 -0.10172,0.1351 -0.1738,0.2411 -0.25,0.1875 0.0576,0.14242 0.0733,0.32522 0,0.4375 -0.005,0.23701 0.13149,0.33275 0.28125,0.34375 0.004,-0.007 0.0258,0.006 0.0312,0 0.0616,-0.0648 0.13539,-0.0965 0.25,-0.0937 0.0604,-0.0487 0.12526,-0.1103 0.15625,-0.1875 0.14196,-0.0234 0.16896,0.0402 0.15625,0.125 0.31377,-0.0921 0.61514,0.11241 0.625,0.46875 0.0727,0.0592 0.0799,-0.14085 0.0937,-0.15625 -0.12166,-0.20968 -0.0682,-0.3254 0.0312,-0.4375 -0.004,-0.002 0.004,-0.0297 0,-0.0312 -0.18038,-0.0735 -0.37537,-0.1227 -0.4375,-0.0937 0.0102,-0.029 0.024,-0.0525 0.0625,-0.0625 0.10213,-0.0253 0.27432,0.0391 0.4375,0.0937 0.19261,-0.16267 0.4762,-0.29076 0.4375,-0.5625 0.086,0.0703 0.16097,-0.25555 0.46875,-0.34375 0.0156,-0.0612 0.5408,-0.25245 0.5625,-0.5625 l 0.0312,-0.0625 c -0.0777,0.58493 0.56903,-0.28504 0.125,-0.125 -0.48342,0.25168 -0.0186,-0.16425 0.21875,-0.15625 0.2339,0.10315 1.13432,-0.3299 0.59375,-0.375 -0.0817,0.002 -0.0573,-0.25438 -0.0937,-0.40625 -0.002,-0.007 -0.0294,0.006 -0.0312,0 -0.0448,0.005 -0.0241,-0.019 0,-0.0625 -0.0396,-0.0514 -0.12172,-0.0571 -0.25,0.0937 -0.091,-0.007 -0.14021,-0.15128 -0.21875,-0.25 z m -4.84375,0.15625 c 0.0652,0.004 0.34053,0.29011 0.0312,0.125 -0.0557,-0.0851 -0.053,-0.126 -0.0312,-0.125 z m 4.875,0.1875 c 0.0553,0.002 0.006,0.0768 -0.0937,0.0312 0.0427,-0.0211 0.0754,-0.032 0.0937,-0.0312 z m 0.21875,0 c -0.0161,0.0169 -0.0897,0.0798 -0.25,0.15625 -0.098,0.0228 -0.17812,0.12482 -0.28125,0.125 0.054,-0.10979 0.30057,-0.2123 0.4375,-0.25 0.0685,-0.0188 0.10987,-0.0481 0.0937,-0.0312 z m 0.4375,0.59375 c -0.0981,0.006 -0.34815,0.29505 -0.21875,0.28125 0.13337,0.0266 0.64304,-0.01 0.25,-0.15625 0.021,-0.0859 8.5e-4,-0.12697 -0.0312,-0.125 z M 4.09375,230.26653 C 4.04015,230.42085 4,230.59394 4,230.76653 c 0,0.82842 0.67157,1.5 1.5,1.5 0.82843,0 1.5,-0.67158 1.5,-1.5 0,-0.17259 -0.04015,-0.34568 -0.09375,-0.5 -0.20384,0.58641 -0.75041,1 -1.40625,1 -0.65584,0 -1.20241,-0.41359 -1.40625,-1 z m 93.90625,3 0,1 14,0 0,-1 z m 101,-3 0,1 10,0 0,-1 z m 26,0 0,1 10,0 0,-1 z m 40.90625,0.25 c -0.0184,-7.1e-4 -0.051,0.0102 -0.0937,0.0312 0.0994,0.0455 0.14906,-0.0292 0.0937,-0.0312 z m 0.21875,0 c 0.0161,-0.0169 -0.0253,0.0124 -0.0937,0.0312 -0.13693,0.0377 -0.38348,0.14021 -0.4375,0.25 0.10313,-1.8e-4 0.18325,-0.1022 0.28125,-0.125 0.16025,-0.0764 0.23388,-0.1394 0.25,-0.15625 z m -5.28125,0.4375 c -0.11123,0.1825 -0.1956,0.40944 -0.1875,0.5625 -0.006,0.28224 0.15163,0.47561 0.375,0.5625 -0.16645,0.0629 -0.0795,0.49173 0.0937,0.625 0.234,0.59128 0.0786,-0.21992 -0.0625,-0.40625 0.1184,-0.41868 0.28654,0.49131 0.5,0.59375 0.0459,0.40021 0.30654,0.5924 0.6875,0.71875 0.1724,0.007 0.42696,0.0904 0.5625,0 -0.0572,0.0939 -0.0543,0.2011 0.0937,0.21875 0.0497,0.0166 0.18315,0.0719 0.21875,0 0.0368,0.0175 0.10148,0.0197 0.15625,-0.0312 0.0432,-0.0198 0.0361,0.0124 0.0625,0 -0.11865,0.0885 -0.24669,0.23155 0.0312,0.28125 0.18197,0.12198 0.21941,-0.59882 -0.0312,-0.46875 -0.27053,-0.0764 -0.31824,0.10185 -0.25,0.1875 -0.15746,0.0411 -0.11319,-0.12221 -0.0312,-0.28125 -0.0131,-0.0878 -0.1107,-0.0461 -0.1875,0.0312 0.0164,-0.0269 0.0254,-0.0521 0.0312,-0.0937 0.0937,-0.0718 0.12538,-0.11212 0.15625,-0.125 0.065,-0.0272 0.0304,0.0826 0,0.1875 0.11801,-0.22906 0.30468,-0.48768 0,-0.4375 -0.14636,0.36457 -0.72915,0.44313 -0.71875,-0.0625 0.0685,-0.10487 0.0484,-0.26871 0,-0.40625 -0.0319,-0.004 -0.0654,0.001 -0.0937,0 -0.38096,-0.12635 -0.6416,-0.31854 -0.6875,-0.71875 -0.21346,-0.10244 -0.3816,-1.01243 -0.5,-0.59375 0.1411,0.18633 0.2965,0.99753 0.0625,0.40625 -0.1732,-0.13327 -0.26025,-0.5621 -0.0937,-0.625 -0.0698,-0.0272 -0.13352,-0.0776 -0.1875,-0.125 z M 43.3125,231.29778 c -0.1816,0.31879 -0.35963,0.64171 -0.53125,1 l 1.5,0 c 0.0209,0 0.0427,-0.003 0.0625,0 l 0.375,-0.5 c 0,-0.26716 -0.17967,-0.5 -0.4375,-0.5 z m 216.34375,0.25 c -0.0116,-0.007 -0.0553,0.0258 -0.0937,0.0937 0.0414,0.1895 0.12859,-0.0729 0.0937,-0.0937 z M 163,232.32903 c -0.0205,0.19287 -0.0312,0.39628 -0.0312,0.59375 0,2.09778 1.19729,3.92576 3,5 l 1,0 0,-0.5 c -2.21887,-0.87849 -3.79699,-2.80631 -3.96875,-5.09375 z m 13.28125,0 c -0.17176,2.28744 -1.74988,4.21527 -3.96875,5.09375 l 0,0.5 1,0 c 1.80271,-1.07423 3,-2.90222 3,-5 0,-0.19747 -0.0105,-0.40088 -0.0312,-0.59375 z m -142.25,0.4375 c -0.0117,0.16523 -0.03125,0.33181 -0.03125,0.5 0,3.86518 3.13483,7 7,7 3.86633,0 7,-3.13482 7,-7 0,-0.16819 -0.01958,-0.33477 -0.03125,-0.5 -0.256502,3.63184 -3.27066,6.5 -6.96875,6.5 -3.69698,0 -6.71216,-2.86816 -6.96875,-6.5 z m 224,0 c -0.0117,0.16523 -0.0312,0.33181 -0.0312,0.5 0,3.86516 3.13484,7 7,7 3.86516,0 7,-3.13484 7,-7 0,-0.16819 -0.0197,-0.33477 -0.0312,-0.5 -0.23218,3.28629 -2.72453,5.92969 -5.9375,6.40625 -0.2472,0.0367 -0.49509,0.0837 -0.75,0.0937 -0.0934,0.004 -0.1869,0 -0.28125,0 -0.23901,0 -0.48704,-0.004 -0.71875,-0.0312 -0.17128,-0.0174 -0.33259,-0.0642 -0.5,-0.0937 -3.12189,-0.55073 -5.52238,-3.15326 -5.75,-6.375 z m 5.5625,0.1249 c -0.0385,0.01 -0.0523,0.0335 -0.0625,0.0625 0.0946,-0.044 0.49211,0.15054 0.6875,0.21875 0.0251,-0.024 0.0663,-0.0415 0.0937,-0.0625 -0.12035,-0.0982 -0.5371,-0.26382 -0.71875,-0.21875 z M 199,233.26653 l 0,1 3,0 0,-1 z m 4,0 0,1 3,0 0,-1 z m 4,0 0,1 2,0 0,-1 z m 18,0 0,1 2,0 0,-1 z m 3,0 0,1 3,0 0,-1 z m 4,0 0,1 3,0 0,-1 z m -34.5625,0.0625 -3.4375,2.9375 0,1 4,-3.4375 z m 39.125,0 -0.5625,0.5 4,3.4375 0,-1 z m 27.4375,0 c -0.008,0.003 -0.012,0.0122 0,0.0312 0.0896,0.0203 0.0878,0.008 0.0937,0 -0.003,-0.002 0.003,-0.0298 0,-0.0312 -0.021,-0.009 -0.0441,-10e-4 -0.0625,0 2.1e-4,0.004 -0.0269,-0.004 -0.0312,0 z m -0.71875,0.78125 c -0.0104,0.0169 0.0106,0.052 0.15625,0.15625 0.36178,0.0251 -0.12511,-0.20702 -0.15625,-0.15625 z m 0.34375,0.15625 c -0.0422,0.0167 -0.0392,0.0395 0.0312,0.0937 0.0399,0.0493 0.0896,0.0317 0.125,0 0.004,-0.0295 0.0211,-0.0628 0.0312,-0.0937 -0.0712,-0.007 -0.14694,-0.016 -0.1875,0 z m 0.34375,0.65625 c -0.10804,0.2558 -0.28337,0.47349 -0.125,0.65625 0.16253,-0.007 0.37406,0.005 0.59375,0.0625 -0.14762,-0.22531 -0.31541,-0.46286 -0.46875,-0.71875 z m 0.46875,0.71875 c 0.0531,0.0811 0.10775,0.1673 0.15625,0.25 0.13697,0.0174 0.23403,0.0459 0.40625,0.0625 -0.11265,-0.16775 -0.33219,-0.2521 -0.5625,-0.3125 z m 0.15625,0.25 c -0.35747,-0.0455 -0.56127,-0.0826 -0.71875,-0.125 0.18134,0.32397 0.38486,0.60386 0.5625,0.875 0.21419,0.0562 0.41301,0.13583 0.53125,0.28125 -10e-4,-0.0109 10e-4,-0.0203 0,-0.0312 -0.06,-0.39876 -0.20182,-0.7051 -0.375,-1 z m -0.15625,0.75 c -0.72058,-0.18902 -1.52571,0.0359 0.15625,0.25 -0.0485,-0.0827 -0.10312,-0.16891 -0.15625,-0.25 z m 0.15625,0.25 c 0.17318,0.2949 0.31495,0.60124 0.375,1 0.0174,0.13576 0.0395,0.24991 0.0625,0.375 0.0832,6.6e-4 0.16831,0.004 0.25,0 -0.11731,-0.35952 -0.24191,-0.79815 -0.3125,-1.3125 -0.14943,-0.0169 -0.24832,-0.0464 -0.375,-0.0625 z m 3,-1.5 c -0.0448,0.33467 0.0313,0.75539 -0.3125,0.875 -0.59418,0.0802 -0.30854,0.82256 -0.71875,1.15625 -0.0731,0.0783 -0.14495,-0.0104 -0.21875,-0.0312 -0.0534,-0.0219 -0.1027,-0.0513 -0.125,-0.0937 0.007,0.12666 0.0413,0.2432 0.1875,0.34375 -0.0237,0.28512 -0.4357,0.12709 -0.375,0.4375 -10e-4,0.0372 0.002,0.0587 0,0.0937 0.0652,-0.0112 0.12302,-0.0492 0.1875,-0.0625 0.0225,-0.12203 0.0832,-0.12133 0.0625,0 0.17042,-0.0369 0.33537,-0.10524 0.5,-0.15625 0.0746,-0.31626 0.11553,-0.6356 0.5,-0.6875 0.47136,-0.164 0.14359,-0.87555 0.4375,-1.1875 0.32681,-0.29111 0.15382,-0.54762 -0.125,-0.6875 z m -1.375,1.90625 c 0.15775,-0.34927 -0.0227,-0.40268 0,0 z M 2,238.26653 l 0,1 14,0 0,-1 -13,0 z m 197,0 0,1 10,0 0,-1 z m 26,0 0,1 10,0 0,-1 z m -62.03125,0.3125 0,1 c 0,0.36933 0.28692,0.65625 0.65625,0.65625 l 4,0 c 0.368,0 0.6875,-0.28825 0.6875,-0.65625 l 0,-0.78125 0,-0.21875 c 0,0.368 -0.3195,0.65625 -0.6875,0.65625 l -4,0 c -0.36933,0 -0.65625,-0.28692 -0.65625,-0.65625 z m 8,0 0,0.21875 0,0.78125 c 0,0.368 0.28825,0.65625 0.65625,0.65625 l 4,0 c 0.0924,0 0.17019,0.002 0.25,-0.0312 0.23926,-0.1012 0.4375,-0.349 0.4375,-0.625 l 0,-1 c 0,0.276 -0.19824,0.5238 -0.4375,0.625 -0.0798,0.0332 -0.1576,0.0312 -0.25,0.0312 l -4,0 c -0.368,0 -0.65625,-0.28825 -0.65625,-0.65625 z M 99,239.26653 l 0,1 12,0 0,-1 z m -58.875,20.34375 -0.15625,0.4375 -3.625,8.875 0.40625,0 3.21875,-7.875 0.15625,-0.4375 1.8125,0 0.09375,0.21875 3.25,8.09375 0.40625,0 -3.65625,-9.09375 -0.09375,-0.21875 z m -30.8330666,1.40537 -1,2.6875 0.375,0 0.625,-1.6875 0.5625,1.6875 0.3437496,0 z m -1.71875,4.71875 -0.90625,2.5 -2.09375,0 c -0.13585,0.33226 -0.27307,0.67472 -0.40625,1 l 2.5,0 0.90625,-2.5 3.3437496,0 0.8125,2.5 2.625,0 c -0.13156,-0.32951 -0.27229,-0.66624 -0.40625,-1 l -2.21875,0 -0.8125,-2.5 z m 32.5205666,-0.34287 -0.28125,0.53125 c 0,0.32152 0.27225,0.59375 0.59375,0.59375 l 1.15625,0 c 0.32151,0 0.59288,-0.27223 0.59375,-0.59375 L 41.875,265.39153 c -0.0948,0.0648 -0.19193,0.125 -0.3125,0.125 l -1.15625,0 c -0.12056,0 -0.21755,-0.0602 -0.3125,-0.125 z M 34,268.92278 l 0,1 c 0,1.28606 1.0577,2.34375 2.34375,2.34375 l 9.3125,0 c 1.28606,0 2.3125,-1.05769 2.3125,-2.34375 l 0,-1 c 0,1.28606 -1.02644,2.34375 -2.3125,2.34375 l -9.3125,0 C 35.0577,271.26653 34,270.20884 34,268.92278 z m -31.03125,2.34375 0,1 13.03125,0 0,-1 z m 3.09375,19 -0.5625,0.625 0.46875,0.46875 L 7,290.26653 z m 4.9375,0 1.03125,1.09375 0.46875,-0.46875 -0.5625,-0.625 z m 23.5,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 3.5,0 c -0.554,0 -1,0.446 -1,1 l 0,1 c 0,-0.554 0.446,-1 1,-1 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554 -0.446,-1 -1,-1 z m 22,0 c -0.554,0 -1,0.446 -1,1 l 0,1 c 0,-0.554 0.446,-1 1,-1 0.554,0 1,0.446 1,1 l 0,-1 c 0,-0.554 -0.446,-1 -1,-1 z m 3.5,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -45,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 29,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -76,0.625 -1.5,1.375 0,1 1.5,-1.375 2,2 2,0 0,-1 -2,0 z m 11,0 -2,2 -2,0 0,1 2,0 2,-2 1.5,1.375 0,-1 z m 20,1.375 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 29,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -45,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 29,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -45,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 29,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -72,1.375 -2,2 0.46875,0.53125 L 7.5,300.64153 z m 3,0 0,1 1.53125,1.53125 0.46875,-0.53125 z m 25.5,0.625 c -0.554,0 -1,0.446 -1,1 0,0.1879 0.0668,0.35013 0.15625,0.5 0.17423,-0.29199 0.47765,-0.5 0.84375,-0.5 l 5,0 c 0.3661,0 0.66952,0.20801 0.84375,0.5 0.0894,-0.14987 0.15625,-0.3121 0.15625,-0.5 0,-0.554 -0.446,-1 -1,-1 z m 37,0 c -0.554,0 -1,0.446 -1,1 0,0.1879 0.06682,0.35013 0.15625,0.5 0.174233,-0.29199 0.477651,-0.5 0.84375,-0.5 l 5,0 c 0.366099,0 0.669517,0.20801 0.84375,0.5 0.08943,-0.14987 0.15625,-0.3121 0.15625,-0.5 0,-0.554 -0.446,-1 -1,-1 z m -29,1 0,1 c 0,1.0907 0.9093,2 2,2 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 -1.0907,0 -2,-0.9093 -2,-2 z m 22,0 0,1 c 0,1.0907 0.9093,2 2,2 1.0907,0 2,-0.9093 2,-2 l 0,-1 c 0,1.0907 -0.9093,2 -2,2 -1.0907,0 -2,-0.9093 -2,-2 z m -31.9375,0.5 c -0.0416,0.15879 -0.0625,0.32958 -0.0625,0.5 0,1.0907 0.9093,2 2,2 l 5,0 c 1.0907,0 2,-0.9093 2,-2 0,-0.17042 -0.0209,-0.34121 -0.0625,-0.5 -0.22476,0.85745 -1.01722,1.5 -1.9375,1.5 l -5,0 c -0.92028,0 -1.71274,-0.64255 -1.9375,-1.5 z m 37,0 c -0.04162,0.15879 -0.0625,0.32958 -0.0625,0.5 0,1.0907 0.9093,2 2,2 l 5,0 c 1.0907,0 2,-0.9093 2,-2 0,-0.17042 -0.02088,-0.34121 -0.0625,-0.5 -0.224763,0.85745 -1.017222,1.5 -1.9375,1.5 l -5,0 c -0.920278,0 -1.712737,-0.64255 -1.9375,-1.5 z m -69.0625,1.5 0,1 5,0 -0.9375,-1 z m 9.9375,0 -0.9375,1 5,0 0,-1 z m -2.53125,20.28125 c -1.26501,0 -2.3125,1.04749 -2.3125,2.3125 l -2.15625,0 c -0.071,0.3201 -0.125,0.659 -0.125,1 l 2.28125,0 c 0,-1.26501 1.04749,-2.3125 2.3125,-2.3125 1.09686,0 2.02751,0.77849 2.25,1.8125 0.0343,-0.15805 0.03125,-0.33128 0.03125,-0.5 0,-1.26501 -1.01624,-2.3125 -2.28125,-2.3125 z m 4.53125,2.875 c -0.23194,1.88014 -1.607221,3.4109 -3.40625,3.875 l 0,0.125 c 0,0.6325 -0.4925,1.15625 -1.125,1.15625 -0.6325,0 -1.15625,-0.52375 -1.15625,-1.15625 l 0,0.875 0,0.125 c 0,0.41052 0.2347,0.76332 0.5625,0.96875 0.18372,-0.0736 0.3831,-0.125 0.59375,-0.125 0.21065,0 0.41003,0.0514 0.59375,0.125 0.31856,-0.20543 0.53125,-0.55823 0.53125,-0.96875 l 0,-0.125 c 1.976569,-0.5099 3.4375,-2.30281 3.4375,-4.4375 0,-0.14723 -0.01785,-0.29375 -0.03125,-0.4375 z m -6.03125,7.9375 c -0.0529,0.15899 -0.09375,0.32277 -0.09375,0.5 0,0.88308 0.71066,1.625 1.59375,1.625 0.88309,0 1.59375,-0.74192 1.59375,-1.625 0,-0.17723 -0.04095,-0.34101 -0.09375,-0.5 -0.21067,0.64123 -0.79413,1.125 -1.5,1.125 -0.70587,0 -1.28933,-0.48377 -1.5,-1.125 z"
+     id="path5248"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccsssscssccsscsscsssssssssscccccccssssssscccsscsccccccssccsccsccsscccccccsccccccsccccccccccccccccccccccccccccccccccccccccccccccccsscscsssscscsscscsssccssscsccccccccccccccccsscscssccccccccccccccccccccccccccccccccccscccccccccccccccccccccccccccccccccsscssccscsccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccsscsscssssccscscscccssscsccscssssscsccscssssscsscssssscsscssssscsccccccccsccccsscsccscssscccccccccccscccccccssscsssccscccscccsccccccsscccccccccccccsssccccccccccccccccccccccccccccccccccccccccssscsccssscccscccccsssscssccsssscssccccccccccccccccccccccccccsccssscsscccccccccsssscsscssssscccscssssscccccsssscssccsssscssccssccsccccccccccccccccccsssscssccsssscsscssssssccscsssscccscccccsccccsssscscccccscccccccccccccccccccccccccsssccscccccccccccccccccccccccccccccccccccscccccccccccscccssccccccccccccscccccccccssssscscccccscccccccccccccsccccccccscccccccccscccccscsccsscsscccscsccsscsscccccsccscccccsscccscccccccccccscccssccccccccsssssssccccccccccccssssscscssssssscccccsssccssssssssssssssscscccccsssssssssssssscccccccccccscssccccsssccsssscssssssssscssssssssssssssssssssssssssssscssssssssscssssssssssssssscccccccccccccccccccccccccccccccssscsccssscscsssssssssssssssssssssssssssscccccccccccsccccsccccsccsccsccsccccscccccsccsssssssssssssssssssssssssssssssssssscccccccccccccssscsccssscsccccccccccccccccccccccccccccccccccccccccccscsscscccsssscssssssssscssssscccccccssssccssssccsccccccsssscssssssssscsssssssssccscccccccccccccccccccccccccccccccccsssccssssssssssssssssssccssssssssssssssssssssssssssssssssssssssssssssssssssscccccccccccccccccccccccscccsccsccccscccsccsccssscsccssscscccccccccccccccsssssssssssssssssssssssssssssssssccsssccsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscccccccccccccccccccccccccccccccccccccccccssssscsccssssscsccssscsccssscsccssscsccssscscscscsccsccscsccsccscscsccsccsscccsccccsccsccssssssccssssccsssccscsscccsscccscccsccccsscccsccscccssccssccccsccccsscccsccccsccccsccscccccccsccccscccccccccccccccccccccccccccccccccccccccccccccccccccccsccccccccccccccccccsccccccccccccccccccccccccccscscsscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccssscscccccccccccccccccccccccccccccccccccccccccccccccccccccccccsccscccccscccccccccscccssscsccssscccscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccssssccsscccssscsccsscccccccccccccccccccccccccccccccccccccccccssccssccsssscssccccccccccccccccssssssssssssssssssssssssssscscsssscscsssssssssssssssssssssssssssssssssssssssssssssssccccccccccccccccccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssccccccccccsscsscssssscsscssscssscsccssscsccsssscssccsssscsscccccccccccsccccscssccssccscscscsccssscsc" /><path
+     sodipodi:nodetypes="sssss"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 41,322.20096 c -3.86517,0 -7,3.1502 -7,7.03432 0,3.88412 3.13483,7.03431 7,7.03431 3.86633,0 7,-3.15019 7,-7.03431 0,-3.88412 -3.13367,-7.03432 -7,-7.03432 z"
+     id="path4290-7"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 99,2.2352457 0,13.9999983 11,0 0,-8.9999983 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.4999983 -5,0 -3,0 -1,0 z"
+     id="path4249"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4303"
+     d="m 142,2.2352457 0,13.9999983 -11,0 0,-8.9999983 0,-1 4,-4 1,0 z m -1,1 -5.5,0 -3.5,3.5 0,8.4999983 5,0 3,0 1,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 47,2.2352457 0,13.9999983 -11,0 0,-8.9999983 0,-1 4,-4 1,0 z m -1,1 -5.5,0 -3.5,3.5 0,8.4999983 5,0 3,0 1,0 z"
+     id="path4305"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4307"
+     d="m 3,2.2352457 0,13.9999983 11,0 0,-8.9999983 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.4999983 -5,0 -3,0 -1,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4311"
+     d="m 259,2.2352457 0,13.9999983 11,0 0,-8.9999983 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.4999983 -5,0 -3,0 -1,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 291,2.2664961 0,4.75 c 0.19146,-0.120143 0.37062,-0.220842 0.5625,-0.3125 l 0.4375,-0.21875 0,-3.21875 5.34375,0 3.65625,3.65625 0,8.3437479 -5,0 0,0.96875 c 0,0.01043 1.6e-4,0.02085 0,0.03125 l 6,0 0,-8.9999979 0,-1 -4,-4 -1,0 -6,0 z m 1,5.34375 c -0.36123,0.1725556 -0.68892,0.3764146 -0.96875,0.6562496 C 290.39787,8.8998727 290,9.7999957 290,10.766494 c 0,1.393522 0.8237,2.564396 2,3.125 l 0,2.34375 c 0,0.554002 0.44599,1.000002 1,1 l 1,0.03125 c 0.554,-2e-6 1,-0.477248 1,-1.03125 l 0,-2.34375 c 1.17629,-0.560603 2,-1.731478 2,-3.125 0,-1.3935203 -0.82119,-2.5931323 -2,-3.1562479 l 0,2.6562479 -1.46875,1 -1.53125,-1 0,-2.6562479 z"
+     id="path5011-3" /><path
+     id="path4415"
+     d="m 334,2.2664961 0,4.75 c -0.19146,-0.120143 -0.37062,-0.220842 -0.5625,-0.3125 L 333,6.4852461 l 0,-3.21875 -5.34375,0 -3.65625,3.65625 0,8.3437479 5,0 0,0.96875 c 0,0.01043 -1.6e-4,0.02085 0,0.03125 l -6,0 0,-8.9999979 0,-1 4,-4 1,0 6,0 z m -1,5.34375 c 0.36123,0.1725556 0.68892,0.3764146 0.96875,0.6562496 0.63338,0.633377 1.03125,1.5335 1.03125,2.4999983 0,1.393522 -0.8237,2.564396 -2,3.125 l 0,2.34375 c 0,0.554002 -0.44599,1.000002 -1,1 l -1,0.03125 c -0.554,-2e-6 -1,-0.477248 -1,-1.03125 l 0,-2.34375 c -1.17629,-0.560603 -2,-1.731478 -2,-3.125 0,-1.3935203 0.82119,-2.5931323 2,-3.1562479 l 0,2.6562479 1.46875,1 1.53125,-1 0,-2.6562479 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 163,2.2352457 0,13.9999983 8.8125,0 -1,-1 -1.3125,0 -1.5,0 -3,0 -1,0 0,-11.9999983 5.5,0 3.5,3.5 0,1.21875 c 0.61468,0.769889 1,1.728793 1,2.7812483 l 0,-3.4999983 0,-1 -4,-4 -1,0 -6,0 z m 11,8.4999983 c 0,0.483188 -0.20077,0.86276 -0.34375,1.28125 l 0.34375,0.34375 0,-1.625 z m -4.5,-3.4999983 c -1.92115,0 -3.5,1.57884 -3.5,3.4999983 0,1.92115 1.57885,3.5 3.5,3.5 0.49539,0 0.94633,-0.12374 1.375,-0.3125 l 2.34375,2.34375 1.625,-1.625 -2.28125,-2.28125 c 0.2665,-0.49285 0.4375,-1.0296 0.4375,-1.625 0,-1.9211583 -1.57885,-3.4999983 -3.5,-3.4999983 z m -0.0312,1 c 1.38071,0 2.5,1.11929 2.5,2.4999983 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.3807083 1.11929,-2.4999983 2.5,-2.4999983 z"
+     id="path4953-8" /><path
+     id="path4243"
+     d="m 207,2.2352457 0,13.9999983 -8.8125,0 1,-1 1.3125,0 1.5,0 3,0 1,0 0,-11.9999983 -5.5,0 -3.5,3.5 0,1.21875 c -0.61468,0.769889 -1,1.728793 -1,2.7812483 l 0,-3.4999983 0,-1 4,-4 1,0 6,0 z m -11,8.4999983 c 0,0.483188 0.20077,0.86276 0.34375,1.28125 L 196,12.360244 l 0,-1.625 z m 4.5,-3.4999983 c 1.92115,0 3.5,1.57884 3.5,3.4999983 0,1.92115 -1.57885,3.5 -3.5,3.5 -0.49539,0 -0.94633,-0.12374 -1.375,-0.3125 l -2.34375,2.34375 -1.625,-1.625 2.28125,-2.28125 c -0.2665,-0.49285 -0.4375,-1.0296 -0.4375,-1.625 0,-1.9211583 1.57885,-3.4999983 3.5,-3.4999983 z m 0.0312,1 c -1.38071,0 -2.5,1.11929 -2.5,2.4999983 0,1.38071 1.11929,2.5 2.5,2.5 1.38071,0 2.5,-1.11929 2.5,-2.5 0,-1.3807083 -1.11929,-2.4999983 -2.5,-2.4999983 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 34,33.235244 0,10 3,0 0,-1 -1,0 -1,0 0,-8 4.5,0 2.5,2.5 0,0.5 1,0 0,-1 -3,-3 -1,0 -5,0 z m 4,5 0,10 9,0 0,-6 0,-1 -3,-3 -1,0 -5,0 z m 1,1 4.5,0 2.5,2.5 0,5.5 -5,0 -1,0 -1,0 0,-8 z"
+     id="path3594-7" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="M 71.53125,33.235244 C 71.236645,33.235244 71,33.471889 71,33.766494 l 0,0.46875 -0.46875,0 C 70.236645,34.235244 70,34.471889 70,34.766494 l 0,0.9375 c 0,0.294605 0.236645,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.294605,0 0.53125,-0.236645 0.53125,-0.53125 l 0,-0.9375 c 0,-0.294605 -0.236645,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.294605 -0.236645,-0.53125 -0.53125,-0.53125 z m -2.53125,1 c -1.090704,0 -2,0.909296 -2,2 l 0,9 c 0,1.090704 0.909296,2 2,2 l 1,0 0,-1 -1,0 c -0.554001,0 -1,-0.445999 -1,-1 l 0,-9 c 0,-0.554001 0.445999,-1 1,-1 l 0,-0.46875 c 0,-0.183581 0.0316,-0.366605 0.09375,-0.53125 z m 7.90625,0 C 76.968395,34.399889 77,34.582913 77,34.766494 l 0,0.46875 c 0.554001,0 1,0.445999 1,1 l 0,2 1,0 0,-2 c 0,-1.090704 -0.909296,-2 -2,-2 z m -4.90625,12 c -0.554,0 -1,1 -1,1 l 0,0 c 0,0 0.446,1 1,1 l 7,0 c 0.554,0 1,-1 1,-1 l 0,0 c 0,0 -0.446,-1 -1,-1 z"
+     id="rect4963-2"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccsscsssssssss" /><path
+     inkscape:connector-curvature="0"
+     id="path4569"
+     d="m 103.53125,33.235244 c -0.29461,0 -0.53125,0.236645 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.236645 -0.53125,0.53125 l 0,0.9375 c 0,0.294605 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.236645 0.53125,-0.53125 l 0,-0.9375 c 0,-0.294605 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.294605 -0.23664,-0.53125 -0.53125,-0.53125 z m -2.53125,1 c -1.090704,0 -2,0.909296 -2,2 l 0,9 c 0,1.090704 0.909296,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.445999 -1,-1 l 0,-9 c 0,-0.554001 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.183581 0.0316,-0.366605 0.0937,-0.53125 z m 7.90625,0 c 0.0622,0.164645 0.0937,0.347669 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.445999 1,1 l 0,2 1,0 0,-2 c 0,-1.090704 -0.9093,-2 -2,-2 l -0.0937,0 z m -4.90625,12 c -0.554,0 -1,1 -1,1 l 0,0 c 0,0 0.446,1 1,1 l 7,0 c 0.554,0 1,-1 1,-1 l 0,0 c 0,0 -0.446,-1 -1,-1 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 138.46875,33.235244 c 0.29461,0 0.53125,0.236645 0.53125,0.53125 l 0,0.46875 0.46875,0 c 0.29461,0 0.53125,0.236645 0.53125,0.53125 l 0,0.9375 c 0,0.294605 -0.23664,0.53125 -0.53125,0.53125 l -1,0 -2.9375,0 -1,0 c -0.29461,0 -0.53125,-0.236645 -0.53125,-0.53125 l 0,-0.9375 c 0,-0.294605 0.23664,-0.53125 0.53125,-0.53125 l 0.46875,0 0,-0.46875 c 0,-0.294605 0.23664,-0.53125 0.53125,-0.53125 z m 2.53125,1 c 1.0907,0 2,0.909296 2,2 l 0,9 c 0,1.090704 -0.9093,2 -2,2 l -1,0 0,-1 1,0 c 0.554,0 1,-0.445999 1,-1 l 0,-9 c 0,-0.554001 -0.446,-1 -1,-1 l 0,-0.46875 c 0,-0.183581 -0.0316,-0.366605 -0.0937,-0.53125 z m -7.90625,0 C 133.0316,34.399889 133,34.582913 133,34.766494 l 0,0.46875 c -0.554,0 -1,0.445999 -1,1 l 0,2 -1,0 0,-2 c 0,-1.090704 0.9093,-2 2,-2 l 0.0937,0 z m 4.90625,12 c 0.554,0 1,1 1,1 l 0,0 c 0,0 -0.446,1 -1,1 l -7,0 c -0.554,0 -1,-1 -1,-1 l 0,0 c 0,0 0.446,-1 1,-1 z"
+     id="path4571"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     inkscape:connector-curvature="0"
+     id="path4573"
+     d="m 167.53125,33.235244 c -0.29461,0 -0.53125,0.236645 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.236645 -0.53125,0.53125 l 0,0.9375 c 0,0.294605 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.236645 0.53125,-0.53125 l 0,-0.9375 c 0,-0.294605 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.294605 -0.23664,-0.53125 -0.53125,-0.53125 z m -2.53125,1 c -1.0907,0 -2,0.909296 -2,2 l 0,9 c 0,1.090704 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.445999 -1,-1 l 0,-9 c 0,-0.554001 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.183581 0.0316,-0.366605 0.0937,-0.53125 z m 7.90625,0 c 0.0622,0.164645 0.0937,0.347669 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.445999 1,1 l 0,2 1,0 0,-2 c 0,-1.090704 -0.9093,-2 -2,-2 l -0.0937,0 z m -4.90625,12 c -0.554,0 -1,1 -1,1 l 0,0 c 0,0 0.446,1 1,1 l 7,0 c 0.554,0 1,-1 1,-1 l 0,0 c 0,0 -0.446,-1 -1,-1 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 202.46875,33.235244 c 0.29461,0 0.53125,0.236645 0.53125,0.53125 l 0,0.46875 0.46875,0 c 0.29461,0 0.53125,0.236645 0.53125,0.53125 l 0,0.9375 c 0,0.294605 -0.23664,0.53125 -0.53125,0.53125 l -1,0 -2.9375,0 -1,0 c -0.29461,0 -0.53125,-0.236645 -0.53125,-0.53125 l 0,-0.9375 c 0,-0.294605 0.23664,-0.53125 0.53125,-0.53125 l 0.46875,0 0,-0.46875 c 0,-0.294605 0.23664,-0.53125 0.53125,-0.53125 z m 2.53125,1 c 1.0907,0 2,0.909296 2,2 l 0,9 c 0,1.090704 -0.9093,2 -2,2 l -1,0 0,-1 1,0 c 0.554,0 1,-0.445999 1,-1 l 0,-9 c 0,-0.554001 -0.446,-1 -1,-1 l 0,-0.46875 c 0,-0.183581 -0.0316,-0.366605 -0.0937,-0.53125 z m -7.90625,0 C 197.0316,34.399889 197,34.582913 197,34.766494 l 0,0.46875 c -0.554,0 -1,0.445999 -1,1 l 0,2 -1,0 0,-2 c 0,-1.090704 0.9093,-2 2,-2 l 0.0937,0 z m 4.90625,12 c 0.554,0 1,1 1,1 l 0,0 c 0,0 -0.446,1 -1,1 l -7,0 c -0.554,0 -1,-1 -1,-1 l 0,0 c 0,0 0.446,-1 1,-1 z"
+     id="path4575"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     inkscape:connector-curvature="0"
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:0.99215686;stroke:none;display:inline"
+     d="m 65,65.235244 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 10,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+     id="rect6608-2" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 137,226.17278 c -3.86517,0 -7,3.14713 -7,7.03125 0,3.88412 3.13483,7.03125 7,7.03125 3.86633,0 7,-3.14713 7,-7.03125 0,-3.88412 -3.13367,-7.03125 -7,-7.03125 z m 0,1.03125 c 3.31371,0 6,2.68629 6,6 0,3.31371 -2.68629,6 -6,6 -3.31371,0 -6,-2.68629 -6,-6 0,-3.31371 2.68629,-6 6,-6 z m -2.34375,3 c -0.78758,0 -1.40625,0.64605 -1.40625,1.4375 0,0.79145 0.61867,1.4375 1.40625,1.4375 0.78761,0 1.4375,-0.64605 1.4375,-1.4375 0,-0.79145 -0.64989,-1.4375 -1.4375,-1.4375 z m 4.6875,0 c -0.7876,0 -1.4375,0.64605 -1.4375,1.4375 0,0.79145 0.6499,1.4375 1.4375,1.4375 0.78759,0 1.40625,-0.64605 1.40625,-1.4375 0,-0.79145 -0.61866,-1.4375 -1.40625,-1.4375 z m -5.23219,4.77513 c -0.0366,0.1544 -0.081,0.31581 -0.081,0.4768 0,1.55998 2.42289,1.8242 2.96945,1.81057 0.54656,-0.0136 2.96945,-0.25059 2.96945,-1.81057 0,-0.16099 -0.0444,-0.3224 -0.081,-0.4768 -1.30709,1.24337 -2.63751,1.02963 -2.88845,1.05774 -0.25094,0.0281 -2.02946,-0.0474 -2.88844,-1.05774 z"
+     id="path3733"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssscszsczcc" /><path
+     sodipodi:nodetypes="ssssssssscccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path3755"
+     d="m 67,226.23528 c -1.108,0 -2,0.892 -2,2 l 0,10 c 0,1.108 0.892,2 2,2 l 12,0 c 1.108,0 2,-0.892 2,-2 l 0,-10 c 0,-1.108 -0.892,-2 -2,-2 z m -1,4 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m -10,5 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z"
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline" /><path
+     style="font-size:15.85716724px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98999999;fill:#ffffff;fill-opacity:0.99215686;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+     d="m 105.21875,131.23528 c -1.3937,1e-5 -2.47545,0.28684 -3.21875,0.90625 -0.7433,0.61943 -1.09375,1.50517 -1.09375,2.65625 0,0.91881 0.24958,1.67676 0.78125,2.21875 0.0797,0.0804 0.18796,0.14481 0.28125,0.21875 l -2.46875,0 c -0.277,0 -0.5,0.18355 -0.5,0.4375 l 0,0.0937 c 0,0.25396 0.223,0.4688 0.5,0.4688 l 5,0 0.875,0.21875 c 0.70201,0.15486 1.17396,0.30385 1.40625,0.5 0.23744,0.19615 0.37499,0.48242 0.375,0.84375 -1e-5,0.40262 -0.18542,0.7207 -0.53125,0.9375 -0.34585,0.2168 -0.84961,0.3125 -1.5,0.3125 -0.64007,0 -1.30832,-0.0851 -2,-0.28125 -0.68653,-0.20131 -1.38686,-0.51394 -2.125,-0.90625 l 0,2.53125 c 0.73814,0.27358 1.4806,0.48563 2.21875,0.625 0.73814,0.13935 1.45451,0.21875 2.1875,0.21875 1.5537,0 2.71511,-0.31808 3.46875,-0.9375 0.75878,-0.62458 1.15624,-1.56877 1.15625,-2.84375 0,-0.44811 -0.0719,-0.8653 -0.1875,-1.21875 l 1.65625,0 c 0.277,0 0.5,-0.2148 0.5,-0.46875 l 0,-0.0937 c 0,-0.25396 -0.223,-0.43755 -0.5,-0.43755 l -2.25,0 c -0.0105,-0.0105 -0.0206,-0.0209 -0.0312,-0.0312 -0.542,-0.5265 -1.46471,-0.9294 -2.75,-1.1875 l -1.28125,-0.25 c -0.60393,-0.12388 -1.01772,-0.26715 -1.25,-0.4375 -0.22713,-0.17549 -0.34376,-0.44028 -0.34375,-0.75 -1e-5,-0.41294 0.19056,-0.71009 0.53125,-0.90625 0.34068,-0.19613 0.85016,-0.28124 1.5625,-0.28125 0.53683,1e-5 1.11481,0.0742 1.71875,0.21875 0.60393,0.14454 0.99009,0.34111 1.625,0.625 l 0,-2.46875 c -0.7175,-0.19098 -1.17272,-0.31335 -1.84375,-0.40625 -0.67104,-0.0981 -1.33385,-0.12499 -1.96875,-0.125 z"
+     id="path3568-3"
+     inkscape:connector-curvature="0" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 65,322.23528 0,14 3,0 0,-1 -2,0 0,-12 2,0 0,-1 z m 13,0 0,1 2,0 0,12 -2,0 0,1 3,0 0,-14 z"
+     id="rect3578-3"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccc" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+     d="m 112,322.78127 -6,0.9375 0,1 2,-0.3125 0,2.84375 -3,0 0,1 3,0 0,3 -2,0 -1,0 0,5 1,0 0,-1 5,0 1,0 0,-4 -1,0 -2,0 0,-3 3,0 0,-1 -3,0 0,-3 3,-0.46875 0,-1 z m -13.999999,0.46875 0,1 5.999999,0 0,-1 -5.999999,0 z m -1,2 0,1 7.999999,0 0,-1 -7.999999,0 z m 1,2 0,1 5.999999,0 0,-1 -5.999999,0 z m 0,2 0,1 5.999999,0 0,-1 -5.999999,0 z m 0,2 0,5 1,0 0,-1 3.999999,0 1,0 0,-4 -1,0 -3.999999,0 -1,0 z m 1,1 3.999999,0 0,2 -3.999999,0 0,-2 z m 6.999999,0 5,0 0,2 -5,0 0,-2 z"
+     id="rect4258-3" /><path
+     style="fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 129,322.25002 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,5 0,1 0,3 5,0 0,-1 -4,0 0,-1 4,0 1,0 0,-1 -5,0 0,-1 6,0 4,0 0,-1 0,-4 -4,0 -7,0 z m 12,0 0,1 1,0 0,-1 -1,0 z m -11,1 9,0 0,1 -9,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -11,1 8.96875,0 0,1 -8.96875,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -3,1.75 -3.6875,3.375 3.6875,3.28125 0,-1.90625 -1.4375,-1.40625 1.4375,-1.53125 0,-1.8125 z m 1,0 0,1.875 1.375,1.46875 -1.375,1.46875 0,1.90625 3.625,-3.375 -3.625,-3.34375 z m -12,0.25 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+     id="rect5051-5"
+     inkscape:connector-curvature="0" /></g><g
+   inkscape:groupmode="layer"
+   id="layer3"
+   inkscape:label="Icons"
+   style="display:inline"
+   transform="translate(-1,-0.25001385)"
+   sodipodi:insensitive="true"><rect
+     y="321.25006"
+     x="69"
+     height="14.00004"
+     width="8"
+     id="rect4452"
+     style="fill:#cccccc;fill-opacity:1;stroke:none" /><rect
+     style="fill:#cccccc;fill-opacity:1;stroke:none"
+     id="rect4367"
+     width="12"
+     height="10.000055"
+     x="67"
+     y="323.25006" /><g
+     id="g4363"
+     style="font-size:13.71140385px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#676767;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;font-family:Sans"
+     transform="translate(2.0000001,0.25006141)"><path
+       sodipodi:nodetypes="csssccccccsssc"
+       inkscape:connector-curvature="0"
+       id="path4365"
+       style="font-variant:normal;font-weight:bold;font-stretch:normal;fill:#676767;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L Bold"
+       d="m 70.006423,329.43503 1.991763,0 c 1.837326,0 3.016509,-1.30258 3.016509,-3.33187 0,-2.00186 -1.138049,-3.09877 -3.22218,-3.09877 l -3.790777,0 0,9.99561 2.004685,0 0,-3.56497 m 0,-1.71392 0,-3.0028 1.347327,0 c 1.096911,0 1.604234,0.4799 1.604234,1.50826 0,1.01464 -0.507323,1.49454 -1.604234,1.49454 l -1.347327,0" /></g><path
+     style="fill:url(#linearGradient4406);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+     d="m 7.5,353.8438 c -0.79075,0.009 -1.60031,0.34033 -2.5,1.375 l 0,7 0,0.25 0,0.75 0,0.0312 c 0.22508,-0.25367 0.43768,-0.45147 0.65625,-0.625 0.18735,-0.14874 0.37931,-0.27793 0.5625,-0.375 0.0624,-0.0331 0.12551,-0.0662 0.1875,-0.0937 0.0832,-0.035 0.16738,-0.0679 0.25,-0.0937 0.0314,-0.0105 0.0624,-0.0221 0.0937,-0.0312 0.0824,-0.0228 0.16846,-0.047 0.25,-0.0625 0.009,10e-4 0.0222,-0.001 0.0312,0 0.17684,-0.0316 0.35709,-0.0655 0.53125,-0.0625 1.36919,0.0236 2.67349,0.99995 4.03125,1.375 0.20073,0.0554 0.38983,0.1016 0.59375,0.125 0.0652,0.007 0.12196,0.0277 0.1875,0.0312 0.0591,0.003 0.12808,3.1e-4 0.1875,0 0.028,0.004 0.0652,8.2e-4 0.0937,0 0.0532,-0.002 0.10326,-0.0244 0.15625,-0.0312 0.0415,-0.005 0.0829,0.005 0.125,0 0.0301,-0.004 0.0636,0.005 0.0937,0 0.0961,-0.0161 0.18405,-0.0665 0.28125,-0.0937 0.16842,-0.0473 0.32806,-0.10258 0.5,-0.1875 0.0298,-0.0141 0.0637,-0.0155 0.0937,-0.0312 0.015,-0.008 0.0175,-0.0197 0.0312,-0.0312 0.0138,-0.0116 0.0161,-0.0229 0.0312,-0.0312 0.16236,-0.0914 0.33405,-0.18218 0.5,-0.3125 0.0109,-0.009 0.0203,-0.0225 0.0312,-0.0312 0.16802,-0.13283 0.32813,-0.25969 0.5,-0.4375 l 0,-0.0312 0,-1 0,-6 0,-1 c -0.15402,0.16401 -0.31736,0.31409 -0.46875,0.4375 -0.0109,0.009 -0.0203,0.0224 -0.0312,0.0312 -0.13895,0.11076 -0.26887,0.19638 -0.40625,0.28125 -0.0367,0.0227 -0.0884,0.0417 -0.125,0.0625 -0.33321,0.18959 -0.64527,0.29368 -0.96875,0.34375 -1.94086,0.30044 -3.7208,-1.55267 -5.5,-1.53125 z m -4.5,0.40625 0,13 1,0 0,-13 -1,0 z"
+     id="path3613"
+     inkscape:connector-curvature="0"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><rect
+     style="fill:#ffffff;fill-opacity:0;stroke:none"
+     id="rect4382"
+     width="16"
+     height="16"
+     x="1"
+     y="352.25006"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><path
+     style="fill:#b8b8b8;fill-opacity:1;stroke:none"
+     d="m 65,64.250051 0,15 5,0 0,-1.153846 0,-1.153846 0,-1.692308 5,-0.153846 0,1.153846 5,0 0,-12 z"
+     id="rect6534"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccc" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3726);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 71.53125,32.250051 c -0.294605,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.294605,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.9375 c 0,0.2946 0.236645,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.294605,0 0.53125,-0.23665 0.53125,-0.53125 l 0,-0.9375 c 0,-0.29461 -0.236645,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.29461 -0.236645,-0.53125 -0.53125,-0.53125 l -2.9375,0 z m -2.53125,1 c -1.090704,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.909296,2 2,2 l 1,0 0,-1 -1,0 c -0.554001,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.445999,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0316,-0.36661 0.09375,-0.53125 l -0.09375,0 z m 7.90625,0 C 76.9684,33.414701 77,33.597721 77,33.781301 l 0,0.46875 c 0.554001,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.909296,-2 -2,-2 l -0.09375,0 z m -4.90625,5 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z"
+     id="path3624"
+     inkscape:connector-curvature="0" /><path
+     id="path4583"
+     d="m 163,1.2500515 0,13.9999995 8.8125,0 -1,-1 -1.3125,0 -1.5,0 -3,0 -1,0 0,-11.9999995 5.5,0 3.5,3.5 0,1.21875 c 0.61468,0.76989 1,1.72879 1,2.78125 l 0,-3.5 0,-1 -4,-4 -1,0 -6,0 z m 11,8.5 c 0,0.4831895 -0.20077,0.8627595 -0.34375,1.2812495 L 174,11.375051 174,9.7500515 z m -4.5,-3.5 c -1.92115,0 -3.5,1.57884 -3.5,3.5 0,1.9211495 1.57885,3.4999995 3.5,3.4999995 0.49539,0 0.94633,-0.12374 1.375,-0.3125 l 2.34375,2.34375 1.625,-1.625 -2.28125,-2.28125 C 172.829,10.882201 173,10.345451 173,9.7500515 c 0,-1.92116 -1.57885,-3.5 -3.5,-3.5 z m -0.0312,1 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.3807095 -1.11929,2.4999995 -2.5,2.4999995 -1.38071,0 -2.5,-1.11929 -2.5,-2.4999995 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
+     style="fill:url(#linearGradient4838);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#4c4c4c;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-2)"
+     d="m 167.53125,32.250051 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.9375 c 0,0.2946 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.23665 0.53125,-0.53125 l 0,-0.9375 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -2.9375,0 z m -2.53125,1 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0317,-0.36661 0.0937,-0.53125 l -0.0937,0 z m 7.90625,0 c 0.0622,0.16465 0.0937,0.34767 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z m -4.90625,5 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 0,4 1,0 1,-1 1,0 1,1 1,0 0,-4 0,-1 -1,0 0,3 -0.25,0 -0.75,0 0,-1 -1,0 0,1 -0.75,0 -0.25,0 0,-3 -1,0 z"
+     id="path4585"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4589"
+     d="m 33,64.250051 0,8 2,0 2,0 0,-1 -2,0 0,-3 2,0 0,-1 -2,0 0,-3 z m 4,4 0,3 1,0 0,-3 z m 6,-2 -3,1.9375 3,2 0,-1.3125 c 2.26799,8.8e-4 3.4435,1.45051 4,2.3125 -0.056,-2.03024 -1.74134,-3.6862 -4,-3.6875 z m 0,6 0,1 3,0 0,2 -3,0 0,1 3,0 0,3 -3,0 0,1 3,0 2,0 0,-7 -1,0 0,-1 z m 1,7 0,-3 -2,0 0,3 z m -10,-5 c 0.056,2.03024 1.74134,3.68621 4,3.6875 l 0,1.25 3,-1.9375 -3,-2 0,1.3125 c -2.26799,-8.7e-4 -3.4435,-1.45051 -4,-2.3125 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4840);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     id="path4591"
+     d="m 99,66.250051 0,1 2,0 0,-1 -2,0 z m 2,1 0,3 -2,0 0,-3 -1,0 0,6 1,0 0,-2 2,0 0,2 1,0 0,-6 -1,0 z m 2,-1 0,7 1,0 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 0,-2 2,0 0,-1 -2,0 -1,0 z m 3,1 0,2 1,0 0,-2 -1,0 z m 0,3 0,2 1,0 0,-2 -1,0 z m 3,-4 0,1 3,0 0,-1 -3,0 z m 0,1 -1,0 0,3 0,1.84375 0,0.15625 1,0 0,-1.15625 0,-0.84375 0,-3 z m 0,5 0,0.25 c -0.42708,0.42709 -0.85415,0.85417 -1.28125,1.28125 l -3.71875,3.75 -2.125,-2.125 -1.40625,1.40625 2.125,2.125 1.40625,1.40625 1.40625,-1.40625 5.21875,-5.25 c -0.13646,-0.14416 -0.26876,-0.29348 -0.40625,-0.4375 l 1.375,0 0.40625,0 0,-1 -1.375,0 -1.375,0 -0.25,0 z"
+     style="fill:url(#linearGradient4842);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     id="path4593"
+     d="m 37,99.250061 c -1.0907,0 -2,0.909289 -2,1.999999 l 0,7 c 0,1.0907 0.9093,2 2,2 l 8,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.09071 -0.9093,-1.999999 -2,-1.999999 l -8,0 z m 0,0.999999 8,0 c 0.554,0 1,0.44599 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -8,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.55401 0.446,-1 1,-1 z m 6.59375,1.59375 -3.59375,3.59375 -1.40625,-1.4375 -1.4375,1.40625 1.4375,1.4375 1.40625,1.40625 5,-5 -1.40625,-1.40625 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4844);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     sodipodi:nodetypes="ssssssssssssssssssscccssssssccssss"
+     inkscape:connector-curvature="0"
+     id="path4595"
+     d="m 99,99.250061 c -1.0907,0 -2,0.909289 -2,1.999999 l 0,7 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.09071 -0.9093,-1.999999 -2,-1.999999 z m 0,0.999999 12,0 c 0.554,0 1,0.44599 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -12,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.55401 0.446,-1 1,-1 z m 1.5,1 c -0.277,0 -0.5,0.22299 -0.5,0.5 0.0807,0.57703 0.3111,0.49624 1,0.5 l 0,5 -0.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.11921,-0.5 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4846);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     sodipodi:nodetypes="cccccccsssscccsssscccccccccccccccccccccccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4597"
+     d="m 334,96.250061 -1,2 -2,0 0,1 1.5,0 -4.5,8.999999 -1,0 -4,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.554009 0.446,-0.999999 1,-0.999999 l 4,0 4,0 0,-1 -8,0 c -1.0907,0 -2,0.9093 -2,1.999999 l 0,7 c 0,1.09069 0.9093,2 2,2 l 4.5,0 -1.5,3 2,0 1.5,-3 1.5,0 0,-1 -1,0 4.5,-8.999999 0.5,0 0,-1 1,-2 z m 2,2.28125 0,0.71875 0.71875,0 c -0.17685,-0.30233 -0.41643,-0.5419 -0.71875,-0.71875 z m 0,1.718749 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m -4,2 0,1 1,0 0,-1 z m 2,0 0,1 1,0 0,-1 z m 2,0 0,0.71875 c 0.30232,-0.17686 0.5419,-0.41643 0.71875,-0.71875 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3295);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path4600"
+     d="m 3.0000001,99.250061 c -0.554,0 -1,0.446 -1,0.999999 l 0,9 c 0,0.55399 0.446,1 1,1 l 11.9999999,0 c 0.554,0 1,-0.44601 1,-1 l 0,-9 c 0,-0.553999 -0.446,-0.999999 -1,-0.999999 l -11.9999999,0 z m 0,2.999999 11.9999999,0 0,7 -11.9999999,0 0,-7 z m 1,1 0,1 3,0 0,-1 -3,0 z m 4.9999999,0 0,2 5,0 0,-2 -5,0 z m -4.9999999,3 0,1 3,0 0,-1 -3,0 z m 4.9999999,0 0,2 5,0 0,-2 -5,0 z"
+     style="fill:url(#linearGradient4848);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     id="path4604"
+     d="m 37,196.25005 c -1.64649,0 -3,1.3535 -3,3 l 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 0.6875,-0.6875 -0.53125,-0.5625 0.65625,-0.71875 1,-1.03125 -4.3125,0 c -0.277,0 -0.5,-0.223 -0.5,-0.5 0,-0.27701 0.223,-0.5 0.5,-0.5 l 7,0 c 0.277,0 0.5,0.22299 0.5,0.5 0,0.277 -0.223,0.5 -0.5,0.5 l -1.1875,0 1,1 0.6875,0 c 0.0353,0 0.0594,-0.0277 0.0937,-0.0312 l 0.875,-0.875 c 0.004,-0.0344 0.0312,-0.0585 0.0312,-0.0938 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 l -3,0 0,-1 3,0 c 1.0907,0 2,0.90929 2,2 l 0,0.4375 0.53125,0.53125 0.4375,0.4375 c 0.019,-0.13548 0.0312,-0.26585 0.0312,-0.40625 l 0,-1 c 0,-1.6465 -1.35351,-3 -3,-3 l -3,0 -1,1 -1,-1 -3,0 z m 0,1 3,0 0,1 -3,0 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,1 -3,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-1 c 0,-1.09071 0.9093,-2 2,-2 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3287);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="sssscccsssscccssccssssccsssscssssccssssccsssssss"
+     inkscape:connector-curvature="0"
+     id="path4606"
+     d="m 5.0000001,196.25006 c -1.64649,0 -3,1.3535 -3,3 l 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 0.9999999,-1 1,1 3,0 c 1.64649,0 3,-1.35351 3,-3 l 0,-1 c 0,-1.6465 -1.35351,-3 -3,-3 l -3,0 -1,1 -0.9999999,-1 z m 0,1 3,0 0,1 -3,0 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,1 -3,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-1 c 0,-1.09071 0.9093,-2 2,-2 z m 4.9999999,0 3,0 c 1.0907,0 2,0.90929 2,2 l 0,1 c 0,1.0907 -0.9093,2 -2,2 l -3,0 0,-1 3,0 c 0.554,0 1,-0.446 1,-1 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 l -3,0 z m -4.4999999,2 6.9999999,0 c 0.277,0 0.5,0.22299 0.5,0.5 0,0.277 -0.223,0.5 -0.5,0.5 l -6.9999999,0 c -0.277,0 -0.5,-0.223 -0.5,-0.5 0,-0.27701 0.223,-0.5 0.5,-0.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3289);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path4608"
+     d="m 69,130.21881 0,6.5 c 0,0.6818 0.0818,1.2882 0.21875,1.84375 0.13694,0.55554 0.35886,1.04609 0.6875,1.4375 0.32865,0.3914 0.76476,0.6916 1.3125,0.90625 0.56144,0.20201 1.24087,0.28125 2.0625,0.28125 0.8353,0 1.53231,-0.0792 2.09375,-0.28125 0.56143,-0.21465 1.03265,-0.51485 1.375,-0.90625 0.34233,-0.39141 0.5818,-0.88196 0.71875,-1.4375 0.13697,-0.55555 0.18749,-1.16195 0.1875,-1.84375 l 0,-6.5 -2.5,0 0,6.3125 c -1.1e-4,0.49241 -0.039,0.9091 -0.0937,1.25 -0.0548,0.32828 -0.14432,0.59785 -0.28125,0.8125 -0.13695,0.20201 -0.32971,0.34911 -0.5625,0.4375 -0.23279,0.0884 -0.51896,0.15625 -0.875,0.15625 -0.35604,0 -0.67347,-0.0679 -0.90625,-0.15625 -0.2328,-0.0884 -0.39431,-0.23549 -0.53125,-0.4375 -0.12325,-0.20202 -0.22648,-0.45297 -0.28125,-0.78125 -0.0548,-0.3409 -0.0625,-0.75759 -0.0625,-1.25 l 0,-6.34375 -2.5625,0 z m -0.5,12.03125 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 10,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -10,0 z"
+     style="font-size:15.23443031px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4850);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Sans" /><path
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4610"
+     d="m 292,161.25005 0,7 1,0 2,0 0,-1 -2,0 0,-5 2,0 0,-1 -2,0 z m 3,1 0,3 0,2 1,0 0,-2 0,-3 z m 2,-1 0,7 1,0 0,-7 z m 2,0 0,5 1,0 0,-5 z m 1,5 0,2 2,0 0,-2 z m 2,0 1,0 0,-5 -1,0 z m -8.03585,3.36417 -2.83816,2.83816 2.83816,2.83816 0.95788,-0.9224 -1.88029,-1.91576 1.88029,-1.88028 z m 3.6896,0 -2.41243,5.67632 1.8448,0 2.54323,-5.67222 z m 3.12198,0 -0.95788,0.95788 1.88028,1.88028 -1.88028,1.91576 0.95788,0.9224 2.83816,-2.83816 z"
+     style="fill:url(#linearGradient4852);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4612"
+     d="m 73.5,354.25005 c -1.9217,0 -3.5,1.5783 -3.5,3.5 l 0,1.5 -1,0 c -0.554,0 -1,0.44599 -1,1 l 0,6 c 0,0.554 0.446,1 1,1 l 9,0 c 0.554,0 1,-0.446 1,-1 l 0,-6 c 0,-0.55401 -0.446,-1 -1,-1 l -1,0 0,-1.5 c 0,-1.9217 -1.5783,-3.5 -3.5,-3.5 z m 0,1 c 1.385,0 2.5,1.115 2.5,2.5 l 0,1.5 -5,0 0,-1.5 c 0,-1.385 1.115,-2.5 2.5,-2.5 z m 0,7 c 0.82843,0 1.5,0.67157 1.5,1.5 0,0.82842 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67158 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3348);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path4614"
+     d="m 34.5,289.25006 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 3.5,0 c -1.0907,0 -2,0.9093 -2,2 l 0,10 c 0,1.0907 0.9093,2 2,2 1.0907,0 2,-0.9093 2,-2 l 0,-10 c 0,-1.0907 -0.9093,-2 -2,-2 z m 0,1 c 0.554,0 1,0.446 1,1 l 0,10 c 0,0.554 -0.446,1 -1,1 -0.554,0 -1,-0.446 -1,-1 l 0,-10 c 0,-0.554 0.446,-1 1,-1 z m -11.5,1 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -8,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -8,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 8,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -8,2 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22386 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27614 -0.22386,-0.5 -0.5,-0.5 z m -6.5,2 c -1.0907,0 -2,0.9093 -2,2 0,1.0907 0.9093,2 2,2 l 5,0 c 1.0907,0 2,-0.9093 2,-2 0,-1.0907 -0.9093,-2 -2,-2 l -5,0 z m 0,1 5,0 c 0.554,0 1,0.446 1,1 0,0.554 -0.446,1 -1,1 l -5,0 c -0.554,0 -1,-0.446 -1,-1 0,-0.554 0.446,-1 1,-1 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4856);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     id="path4616"
+     d="m 290,102.25006 14,0 0,5 -14,0 z"
+     style="fill:#c4c4c4;fill-opacity:1;stroke:none"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4858);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 36.3298,257.27124 c -1.28605,0 -2.3298,1.04375 -2.3298,2.3298 l 0,9.31921 c 0,1.28606 1.04375,2.32981 2.3298,2.32981 l 9.31921,0 c 1.28606,0 2.3298,-1.04375 2.3298,-2.32981 l 0,-9.31921 c 0,-1.28605 -1.04374,-2.3298 -2.3298,-2.3298 z m 3.80414,2.33622 1.79284,0 0.11832,0.212 3.64032,9.10079 -2.3298,0 -0.87368,-2.29339 -3.02147,0 -0.87367,2.29339 -2.257,0 3.64032,-8.88237 z"
+     id="path4618"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssccccccccccc" /><path
+     style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 41.57171,265.48627 -1.16491,0 c -0.3215,0 -0.58244,-0.26094 -0.58244,-0.58246 l 1.1381,-2.19467 1.19286,2.19467 c -8.7e-4,0.32152 -0.2621,0.58246 -0.58361,0.58246 z"
+     id="path4620"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscccs" /><path
+     sodipodi:nodetypes="cccccccccccc"
+     style="fill:url(#linearGradient4860);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 67,193.25006 0,14 1,0 0,-14 z m 4.74999,-0.41664 c -0.86983,0.009 -1.76033,0.34033 -2.74999,1.375 l 0,8.04164 c 3.96132,-4.05865 6.94268,2.81598 11,-1 l 0,-8.04165 c -3.03099,2.934 -5.64051,-0.40352 -8.25001,-0.37496 z"
+     id="path4622"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="cccccccccccccsssssss"
+     inkscape:connector-curvature="0"
+     id="path4624"
+     d="m 202.71875,138.46881 -0.96875,0.90625 1.90625,1.96875 -1.90625,1.96875 0.96875,1 1.90625,-1.96875 1.96875,1.96875 0.96875,-1 -1.9375,-1.96875 1.9375,-1.96875 -0.96875,-0.90625 -1.96875,1.90625 z M 194.5,141.25006 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z"
+     style="fill:url(#linearGradient4862);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="ccccccc"
+     style="fill:url(#linearGradient4864);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 233,35.250061 -7,5 6.99998,4.99998 2e-5,-3.33332 c 3.41666,0 5.61556,1.22 7,3.33334 0,-4.98333 -3.60112,-6.66667 -7,-6.66667 2e-5,-0.85078 1e-5,-2.61388 0,-3.33333 z"
+     id="path4626"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4866);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 418.99999,163.25006 0,2 12.00001,0 0,-2 -12.00001,0 z m 0,3 0,1.99999 12.00001,0 0,-1.99999 -12.00001,0 z m 0,3 0,2 12.00001,0 0,-2 -12.00001,0 z m 0,2.99999 0,2.00001 12.00001,0 0,-2.00001 -12.00001,0 z"
+     id="path4628"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4868);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 392,163.25006 0,2 7,0 0,-2 -7,0 z m -4,3 0,1.99999 11,0 0,-1.99999 -11,0 z m 2,3 0,2 9,0 0,-2 -9,0 z m -3,3 0,2 12,0 0,-2 -12,0 z"
+     id="path4630"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4870);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 356.8683,163.21055 0,2.02634 8.10536,0 0,-2.02634 -8.10536,0 z m -2.02634,3.03951 0,2.02633 12.15804,0 0,-2.02633 -12.15804,0 z m 2.02634,3.0395 0,2.02634 8.10536,0 0,-2.02634 -8.10536,0 z m -2.02634,3.03951 0,2.02634 12.15804,0 0,-2.02634 -12.15804,0 z"
+     id="path4632"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4872);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 323,163.25006 0,2 7,0 0,-2 -7,0 z m 0,3 0,2 11,0 0,-2 -11,0 z m 0,3 0,2 9,0 0,-2 -9,0 z m 0,3 0,2 12,0 0,-2 -12,0 z"
+     id="path4634"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4874);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 14.143585,33.304411 -4.126956,5.00918 -4.0880185,-4.93658 c 0,0 -0.8954698,0.0269 -0.8954698,1.05265 0,2.21508 1.5511147,4.31748 3.2704133,5.95293 l -1.7909395,2.17791 0.1167447,0.14519 c -0.089703,-0.009 -0.1790976,-0.0363 -0.2725383,-0.0363 -1.3754463,0 -2.4917443,1.04074 -2.4917443,2.3231 0,1.28234 1.116298,2.3231 2.4917443,2.3231 1.3754463,0 2.4917443,-1.04076 2.4917443,-2.3231 0,-0.69345 -0.3382551,-1.31604 -0.8565423,-1.74234 0.4809109,-0.30316 1.2134861,-0.78955 2.0245501,-1.41563 0.832239,0.64465 1.592846,1.16764 2.102405,1.48823 -0.478416,0.42398 -0.778669,1.00648 -0.778669,1.66974 0,1.28234 1.116298,2.3231 2.491745,2.3231 1.375446,0 2.491744,-1.04076 2.491744,-2.3231 0,-1.28236 -1.115055,-2.32427 -2.491744,-2.3231 -0.06354,0 -0.132378,0.0317 -0.194665,0.0363 l 0.03887,-0.0363 -1.907749,-2.28681 c 1.695639,-1.60874 3.231485,-3.67659 3.231485,-5.84404 0,-1.11857 -0.856533,-1.23414 -0.856533,-1.23414 z m -7.7866987,10.52654 c 0.6877138,0 1.2458722,0.52037 1.2458722,1.16154 0,0.64118 -0.5581584,1.16155 -1.2458722,1.16155 -0.6877231,0 -1.2458721,-0.52037 -1.2458721,-1.16155 0,-0.64117 0.558149,-1.16154 1.2458721,-1.16154 z m 7.4752327,0 c 0.687714,0 1.245872,0.52037 1.245872,1.16154 0,0.64118 -0.558158,1.16155 -1.245872,1.16155 -0.687723,0 -1.245872,-0.52037 -1.245872,-1.16155 0,-0.64117 0.558149,-1.16154 1.245872,-1.16154 z"
+     id="path4636"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="sssssssssssssssssssscszsczcc"
+     inkscape:connector-curvature="0"
+     id="path4638"
+     d="m 137,225.2188 c -3.86517,0 -7,3.14713 -7,7.03125 0,3.88412 3.13483,7.03125 7,7.03125 3.86633,0 7,-3.14713 7,-7.03125 0,-3.88412 -3.13367,-7.03125 -7,-7.03125 z m 0,1.03125 c 3.31371,0 6,2.68629 6,6 0,3.31371 -2.68629,6 -6,6 -3.31371,0 -6,-2.68629 -6,-6 0,-3.31371 2.68629,-6 6,-6 z m -2.34375,3 c -0.78758,0 -1.40625,0.64605 -1.40625,1.4375 0,0.79145 0.61867,1.4375 1.40625,1.4375 0.78761,0 1.4375,-0.64605 1.4375,-1.4375 0,-0.79145 -0.64989,-1.4375 -1.4375,-1.4375 z m 4.6875,0 c -0.7876,0 -1.4375,0.64605 -1.4375,1.4375 0,0.79145 0.6499,1.4375 1.4375,1.4375 0.78759,0 1.40625,-0.64605 1.40625,-1.4375 0,-0.79145 -0.61866,-1.4375 -1.40625,-1.4375 z m -5.23219,4.77513 c -0.0366,0.1544 -0.081,0.31581 -0.081,0.4768 0,1.55998 2.42289,1.8242 2.96945,1.81057 0.54656,-0.0136 2.96945,-0.25059 2.96945,-1.81057 0,-0.16099 -0.0444,-0.3224 -0.081,-0.4768 -1.30709,1.24337 -2.63751,1.02963 -2.88845,1.05774 -0.25094,0.0281 -2.02946,-0.0474 -2.88844,-1.05774 z"
+     style="fill:url(#linearGradient4876);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     transform="matrix(1.0570818,0,0,1.0570818,-13.669289,-9.0845785)"
+     sodipodi:nodetypes="cssccscccssccscc"
+     style="fill:url(#linearGradient4878);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 259.65386,163.531 c -1.472,0 -2.66666,1.24939 -2.66666,2.53241 0,1.28301 1.19466,2.3243 2.66666,2.3243 0.0453,0 0.0811,8.7e-4 0.12493,0 -0.196,1.29812 -0.87033,2.97394 -2.79166,4.64861 1.33333,0 5.33332,-2.32431 5.33332,-6.97291 0,-1.28302 -1.19466,-2.53241 -2.66666,-2.53241 z m 7.99998,0.026 c -1.472,0 -2.66666,1.22337 -2.66666,2.50639 0,1.28302 1.19466,2.32431 2.66666,2.32431 0.048,0 0.0784,8.7e-4 0.12493,0 -0.196,1.28069 -0.86633,2.93413 -2.79166,4.61228 1.37466,0 5.33332,-2.28798 5.33332,-6.93659 0,-1.28302 -1.19466,-2.50639 -2.66666,-2.50639 z"
+     id="path4640"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4880);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 41,225.25006 c -3.86517,0 -7,3.13483 -7,6.99999 0,3.86518 3.13483,7.00001 7,7.00001 3.86633,0 7,-3.13483 7,-7.00001 0,-3.86516 -3.13367,-6.99999 -7,-6.99999 z m 2.47916,2.29688 c 0.62773,-0.0298 1.3338,0.21291 2.1875,0.80207 -1.27516,0 -2.10904,1.30666 -2.88021,2.91667 l 1.4948,0 c 0.25783,0 0.4375,0.24325 0.4375,0.51041 l -1.16667,1.64063 -1.75,0 c -1.19233,2.56317 -2.57892,4.74454 -5.46875,2.73437 1.33233,-0.003 2.17992,-1.54671 2.98958,-3.31769 l 0.21875,-0.47398 c 1.0115,-2.26011 2.05434,-4.72275 3.9375,-4.81248 z"
+     id="path4642"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ssssscccsccccccc" /><path
+     inkscape:connector-curvature="0"
+     id="path4644"
+     d="m 8.0000001,6.2500615 0,1.875 -1.375,1.46875 1.375,1.4687495 0,1.90625 -3.625,-3.3749995 z"
+     style="fill:url(#linearGradient4882);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4646"
+     d="m 9,6.2500615 3.6875,3.375 L 9,12.906311 9,11.000061 10.4375,9.5938115 9,8.0625615 z"
+     style="fill:url(#linearGradient4884);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="sccsscccssscsssssss"
+     style="fill:url(#linearGradient4886);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 9.400192,321.25006 c -2.5311594,0 -4.5833578,2.05219 -4.5833578,4.58335 l 2.2916789,0 c 0,-1.26501 1.0266722,-2.29168 2.2916789,-2.29168 1.265007,0 2.29168,1.02667 2.29168,2.29168 0,1.265 -1.026673,2.29168 -2.29168,2.29168 -0.8015237,0.007 -1.2388122,0.57905 -1.1458394,1.14585 l 0,1.0026 0,0.14323 c 0,0.6325 0.5133366,1.14584 1.1458394,1.14584 0.632504,0 1.145839,-0.51334 1.145839,-1.14584 l 0,-0.14323 c 1.976573,-0.5099 3.437519,-2.30544 3.437519,-4.44013 0,-2.53116 -2.052199,-4.58335 -4.583358,-4.58335 z m 0,11.00442 c -0.8830925,0 -1.5998062,0.71671 -1.5998062,1.59981 0,0.88308 0.7167137,1.5998 1.5998062,1.5998 0.883094,0 1.599806,-0.71672 1.599806,-1.5998 0,-0.8831 -0.716712,-1.59981 -1.599806,-1.59981 z"
+     id="path4648"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4888);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 36.34264,356.62101 c 0.51469,-0.51344 1.34901,-0.51344 1.86244,0 L 41,359.40963 l 2.79492,-2.78862 c 0.51469,-0.51344 1.34901,-0.51344 1.86244,0 0.51469,0.51344 0.51469,1.34524 0,1.85992 l -2.79492,2.78989 2.79492,2.78864 c 0.51469,0.51341 0.51469,1.34648 0,1.85992 -0.51469,0.51343 -1.34901,0.51343 -1.86244,0 L 41,363.12949 l -2.79492,2.78989 c -0.51469,0.51343 -1.34901,0.51343 -1.86244,0 -0.51469,-0.51344 -0.51469,-1.34651 0,-1.85992 l 2.79492,-2.78864 -2.79492,-2.78989 c -0.51469,-0.51468 -0.51469,-1.34774 0,-1.85992 z"
+     id="path4651"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4890);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 137.90909,353.25005 0,7.08065 4.69598,-3.57702 z m -1.17399,2.32963 c -3.2461,0 -5.86997,2.66057 -5.86997,5.90666 0,3.24609 2.62387,5.86997 5.86997,5.86997 3.24609,0 5.86997,-2.62388 5.86997,-5.86997 l 0,-0.0366 -2.34799,0 c 0,1.9453 -1.57667,3.52198 -3.52198,3.52198 -1.94531,0 -3.52198,-1.57668 -3.52198,-3.52198 0,-1.94531 1.57667,-3.52198 3.52198,-3.52198 0.41441,0 0.80535,0.0898 1.17399,0.22013 l 0,-2.42137 c -0.37685,-0.0763 -0.77484,-0.14675 -1.17399,-0.14675 z"
+     id="path4653"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccsssccssscccc" /><path
+     style="fill:url(#linearGradient4892);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 169.63108,225.85717 c -3.68133,0 -6.66665,2.71633 -6.66665,6.04164 0,2.46666 1.64933,4.56932 3.99999,5.49999 l 0,0.5 -2.66666,0 0,-0.66667 c 0,-0.36933 -0.29733,-0.66666 -0.66667,-0.66666 -0.36933,0 -0.66666,0.29733 -0.66666,0.66666 l 0,1.33333 c 0,0.36933 0.29733,0.66667 0.66666,0.66667 l 3.99999,0 c 0.368,0 0.66667,-0.29867 0.66667,-0.66667 l 0,-0.79166 0,-0.54167 0,-0.83333 c -1.55066,-0.66266 -2.66666,-2.40533 -2.66666,-4.49999 0,-2.65998 1.79066,-4.83331 3.99999,-4.83331 2.20933,0 3.99999,2.17333 3.99999,4.83331 0,2.09466 -1.116,3.83599 -2.66666,4.49999 l 0,0.83333 0,0.54167 0,0.79166 c 0,0.368 0.29866,0.66667 0.66666,0.66667 l 3.99999,0 c 0.0924,0 0.17019,-0.008 0.25,-0.0416 0.23926,-0.1012 0.41667,-0.349 0.41667,-0.625 l 0,-1.33333 c 0,-0.36933 -0.29733,-0.66667 -0.66667,-0.66667 -0.36933,0 -0.66666,0.29734 -0.66666,0.66667 l 0,0.66666 -2.66666,0 0,-0.5 c 2.35066,-0.93066 3.99999,-3.03332 3.99999,-5.49998 0,-3.32531 -2.98399,-6.04164 -6.66665,-6.04164 z"
+     id="path4655"
+     inkscape:connector-curvature="0" /><path
+     id="path4657"
+     d="m 265,225.25005 c -3.86516,0 -7,3.13484 -7,7 0,3.86516 3.13484,7 7,7 3.86516,0 7,-3.13484 7,-7 0,-3.86516 -3.13484,-7 -7,-7 z m 0,1 c 0.57563,0 1.12928,0.0987 1.65625,0.25 -0.21686,0.024 -0.40509,0.0414 -0.21875,0.0625 0.60892,0.003 -0.1276,0.039 -0.1875,0.125 -0.11394,0.0829 -0.0834,0.026 -0.15625,0.125 -0.11101,0.005 -0.16343,0.0248 -0.1875,0.0312 0.0628,0.0123 0.21665,0.0288 0.3125,0.0312 0.26795,-0.0538 0.54333,-0.1539 0.8125,-0.25 0.0491,0.0177 0.10773,0.0123 0.15625,0.0312 -0.057,0.0184 -0.10829,0.071 -0.15625,0.0625 -0.34875,0.25862 0.70213,-0.0275 0.59375,0.46875 0.0904,0.035 0.0426,-0.16732 0.0312,-0.3125 1.98416,0.97877 3.34375,3.01293 3.34375,5.375 0,2.96499 -2.14232,5.42075 -4.96875,5.90625 0.002,-0.0351 -0.001,-0.0564 0,-0.0937 -0.0607,-0.31041 0.3513,-0.15238 0.375,-0.4375 -0.14618,-0.10055 -0.18095,-0.21709 -0.1875,-0.34375 -0.0227,-0.40268 0.15775,-0.34927 0,0 0.0223,0.0426 0.0716,0.0718 0.125,0.0937 0.0738,0.0209 0.14565,0.10949 0.21875,0.0312 0.41021,-0.33369 0.12457,-1.07604 0.71875,-1.15625 0.47136,-0.164 0.14359,-0.87555 0.4375,-1.1875 0.53462,-0.47621 -0.2551,-0.89849 -0.6875,-0.78125 -0.0559,-0.0857 -0.27353,-0.28009 -0.5,-0.0625 0.15857,-0.1649 -0.008,-0.23324 -0.25,-0.0312 0.24467,-0.17708 0.25848,-0.47377 -0.0625,-0.65625 -0.0508,9.9e-4 -0.10507,-0.004 -0.125,0.0312 -0.0638,-0.0687 -0.22894,-0.0608 -0.28125,0.0312 -0.0101,-0.0804 -0.0318,-0.15944 -0.0625,-0.1875 -0.12961,-0.14754 -0.16689,-0.11264 -0.1875,-0.0312 0.0112,-0.0474 0.002,-0.10756 0,-0.15625 -0.32535,-0.0722 -0.953,-0.49438 -1,0 0.002,-0.20286 -0.0586,-0.23675 -0.0937,-0.1875 0.0276,-0.0332 0.0683,-0.0615 0.125,-0.0937 -0.23557,0.0464 -0.5475,0.32011 -0.5625,0.5625 0.0648,0.41584 -0.42384,0.78976 -0.1875,1.0625 -0.0185,-0.003 -0.0422,0.0103 -0.0625,0 0.20991,0.41324 0.44408,0.73866 0.65625,1.0625 0.23031,0.0604 0.44985,0.14475 0.5625,0.3125 -0.17222,-0.0166 -0.26928,-0.0451 -0.40625,-0.0625 0.17318,0.2949 0.31495,0.60124 0.375,1 0.0695,0.54303 0.19023,1.00029 0.3125,1.375 -0.0919,0.004 -0.18828,0 -0.28125,0 -3.31371,0 -6,-2.6863 -6,-6 0,-1.4656 0.53344,-2.80175 1.40625,-3.84375 0.34206,-0.0211 0.7743,0.12805 0.75,0.4375 0.0307,0.0446 0.0539,0.0428 0.0625,0.0312 -0.0741,0.19641 -0.23979,0.37414 0.0937,0.5625 0.22757,0.0776 -0.005,-0.0939 -0.125,0.1875 -0.18886,-0.0161 -0.54745,0.56888 -0.53125,0.875 -0.006,0.28224 0.15163,0.47561 0.375,0.5625 -0.16645,0.0629 -0.0795,0.49173 0.0937,0.625 0.234,0.59128 0.0786,-0.21992 -0.0625,-0.40625 0.1184,-0.41868 0.28654,0.49131 0.5,0.59375 0.0459,0.40021 0.30654,0.5924 0.6875,0.71875 0.1724,0.007 0.42696,0.0904 0.5625,0 -0.0572,0.0939 -0.0543,0.2011 0.0937,0.21875 0.0497,0.0166 0.18315,0.0719 0.21875,0 0.0368,0.0175 0.10148,0.0198 0.15625,-0.0312 0.0432,-0.0198 0.0361,0.0124 0.0625,0 -0.11865,0.0885 -0.24679,0.23155 0.0312,0.28125 0.18197,0.12198 0.21951,-0.59882 -0.0312,-0.46875 -0.27053,-0.0764 -0.31824,0.10185 -0.25,0.1875 -0.38423,0.10029 0.48507,-0.80377 -0.0312,-0.71875 -0.14636,0.36457 -0.72915,0.44313 -0.71875,-0.0625 0.0733,-0.11228 0.0576,-0.29508 0,-0.4375 0.0762,0.0536 0.14828,-0.0524 0.25,-0.1875 0.0508,-0.20201 0.45865,-0.11762 0.5625,-0.125 -0.007,-0.008 -0.0149,-0.019 -0.0312,-0.0312 0.34794,-0.17518 0.70785,0.0435 0.71875,0.4375 0.0727,0.0592 0.0799,-0.14085 0.0937,-0.15625 -0.34271,-0.59064 0.60005,-0.61065 0.53125,-1.09375 0.086,0.0703 0.16097,-0.25555 0.46875,-0.34375 0.0156,-0.0612 0.5408,-0.25245 0.5625,-0.5625 l 0.0312,-0.0625 c -0.0777,0.58493 0.56903,-0.28504 0.125,-0.125 -0.48342,0.25168 -0.0186,-0.16425 0.21875,-0.15625 0.2339,0.10315 1.13432,-0.3299 0.59375,-0.375 -0.14861,0.004 0.0197,-0.83907 -0.375,-0.375 -0.18201,-0.013 -0.21657,-0.52148 -0.59375,-0.28125 -0.21308,0.35773 -0.42379,0.80911 -0.78125,0.96875 0.10551,-0.34815 -0.17558,-0.37355 -0.4375,-0.46875 -0.50037,-0.22009 0.22843,-0.53767 0.40625,-0.65625 0.42598,0.0488 0.0804,-0.2331 0.40625,-0.1875 0.25965,0.11567 0.79746,-0.45867 0.3125,-0.25 -0.34093,0.38477 -0.21848,-0.29476 -0.5,-0.15625 -0.0588,0.36258 -0.54949,0.31735 -0.9375,0.28125 -0.20901,0.22494 -0.18621,0.0524 -0.40625,0.0312 -0.22948,-0.0557 -0.62539,-0.2074 -1.03125,-0.125 -0.42791,0.0153 -0.77707,0.13054 -1.09375,0.375 0.18446,-0.14534 0.37067,-0.28434 0.3125,-0.34375 -0.13804,-0.0294 -0.26862,-0.0577 -0.40625,-0.0625 1.0158,-0.78806 2.2713,-1.2811 3.6564,-1.2811 z m -0.40625,9.625 c -0.0485,-0.0827 -0.10312,-0.16891 -0.15625,-0.25 -0.72058,-0.18902 -1.52571,0.0359 0.15625,0.25 z m 1.34375,-9.28125 c -0.10926,0.002 -0.25181,0.0495 -0.15625,0.125 l 0.125,0 c 0.22132,-0.0858 0.14056,-0.12682 0.0312,-0.125 z m -0.34375,0.34375 c -0.14885,0.0202 -0.1519,0.1631 0.15625,0.0937 0.007,0.066 0.1702,-0.0245 0.1875,0.0312 0.48589,-0.054 0.0831,-0.1527 -0.15625,-0.0937 -0.0717,-0.0408 -0.13788,-0.038 -0.1875,-0.0312 z m 0.0625,0.15625 c -0.012,-0.0131 -0.0364,0.004 -0.125,0.0625 -0.53787,0.41757 0.48274,0.0767 0.59375,0.34375 0.375,0.26203 -0.0911,0.19656 -0.28125,0.3125 -0.0495,0.0102 -0.0367,0.0257 -0.0625,0.0312 0.11906,0.007 0.28635,0.0602 0.3125,0.1875 l 0.0625,0.0312 c 0.31303,0.0938 -0.14015,-0.27069 0.25,-0.0937 -0.0154,-0.25514 0.0288,-0.26175 0.28125,-0.21875 -0.016,-0.36645 -0.58414,-0.66376 -0.96875,-0.5625 -0.23333,0.21055 -0.0265,-0.0545 -0.0625,-0.0937 z m -0.46875,0.0312 c -0.0468,0.0133 -0.0929,0.0396 -0.125,0.0937 0.0235,10e-4 0.0376,0.0331 0.0625,0 0.33051,-0.0263 0.20282,-0.13358 0.0625,-0.0937 z m -1.5625,0.0312 c -0.17974,0.004 -0.43759,0.0773 -0.4375,0.25 0.11636,0.04 0.22509,-0.1096 0.34375,-0.125 0.35814,-0.0741 0.27354,-0.12883 0.0937,-0.125 z m 1.21875,0 c -0.12212,0.0231 -0.25374,0.0844 -0.125,0.125 l 0.0312,0.0312 0.0937,-0.0312 c 0.22922,-0.13332 0.12212,-0.14807 0,-0.125 z m -0.90625,0.0625 c -0.28655,0.0128 -0.61607,0.21385 -0.1875,0.25 -0.20655,0.0632 -0.46416,0.0131 -0.0625,0.125 0.24304,-0.0302 1.03903,-0.0694 0.625,-0.21875 0.16188,-0.2552 -0.0305,-0.0918 -0.15625,-0.0937 -0.0543,-0.0446 -0.12323,-0.0668 -0.21875,-0.0625 z m 0.71875,0.25 c -0.0294,0.007 -0.0677,0.0411 -0.0937,0.0937 0.23501,0.0305 0.18187,-0.11393 0.0937,-0.0937 z m 2.96875,0 c -0.1229,0.0647 -0.30864,0.56687 0,0.625 0.19641,0.13297 0.0343,-0.35877 0.0625,-0.5 -0.008,-0.10783 -0.0215,-0.14656 -0.0625,-0.125 z m -4.65625,0.3125 c 0.0326,-0.004 0.0441,-0.007 0.0312,0.0312 -0.33578,0.11083 -0.12904,-0.0181 -0.0312,-0.0312 z m 2.3125,0.0625 c -0.1313,-0.0266 -0.39703,0.19962 0,0.125 l 0.0625,0 c 0.0111,-0.0813 -0.0187,-0.11612 -0.0625,-0.125 z m -4.0625,0.78125 c 0.006,0.0143 0.0299,0.014 0.0312,0.0312 0.008,0.0435 -0.0235,0.085 -0.0312,0.125 -0.003,-0.0643 -0.009,-0.12364 0,-0.15625 z M 261,228.81255 c -0.009,0.006 -0.007,0.021 0,0.0625 0.0968,0.0138 0.0264,-0.0815 0,-0.0625 z m 5.5625,0.28125 c -0.0981,0.006 -0.34815,0.29505 -0.21875,0.28125 0.13337,0.0266 0.64304,-0.01 0.25,-0.15625 0.021,-0.0859 9.5e-4,-0.12697 -0.0312,-0.125 z m -5.53125,0.21875 c -0.0218,-10e-4 -0.0245,0.0399 0.0312,0.125 0.30923,0.16511 0.034,-0.12127 -0.0312,-0.125 z m 4.875,0.1875 c -0.0184,-7.1e-4 -0.051,0.0101 -0.0937,0.0312 0.0994,0.0455 0.14896,-0.0291 0.0937,-0.0312 z m 0.125,0.0312 c -0.13693,0.0377 -0.38348,0.14021 -0.4375,0.25 0.10313,-1.8e-4 0.18325,-0.1022 0.28125,-0.125 0.32049,-0.15288 0.29318,-0.16268 0.15625,-0.125 z m -6.375,1 c -0.0116,-0.007 -0.0552,0.0257 -0.0937,0.0937 0.0414,0.1895 0.12849,-0.0728 0.0937,-0.0937 z m 1.5,0.53125 c 0.052,0.004 0.0833,0.0625 0.125,0.0937 -0.0524,-0.0363 -0.0856,-0.0794 -0.125,-0.0937 z m 2.4375,0.8125 c -0.0385,0.01 -0.0523,0.0335 -0.0625,0.0625 0.0946,-0.044 0.49211,0.15054 0.6875,0.21875 0.48854,0.0204 -0.35512,-0.34821 -0.625,-0.28125 z m 0.90625,0.28125 c -0.0182,-0.002 0.003,0.0237 0.0312,0.0937 -0.19576,0.095 -0.24616,0.0339 0.0312,0.0625 0.0616,0.0235 0.0953,0.025 0.0937,0 0.38314,0.0396 0.0666,-0.24469 -0.0312,-0.0625 -0.0308,-0.0484 -0.0997,-0.0915 -0.125,-0.0937 z m 0.53125,0.0938 c -0.0231,2.4e-4 -0.0377,0.0285 -0.0625,0.0625 0.0442,0.0146 0.0742,0.003 0.0937,0 -0.009,-0.0182 -0.005,-0.0628 -0.0312,-0.0625 z m -1.96875,0.0625 c 0.065,-0.0272 0.0304,0.0826 0,0.1875 -0.0131,-0.0878 -0.1107,-0.0462 -0.1875,0.0312 0.0164,-0.0269 0.0254,-0.0519 0.0312,-0.0937 0.0937,-0.0718 0.12538,-0.11212 0.15625,-0.125 z m 0.9375,0 c -0.008,0.003 -0.012,0.0121 0,0.0312 0.23882,0.0542 0.0924,-0.0358 0.0312,-0.0312 -0.0102,5e-4 -0.023,-0.003 -0.0312,0 z m 1.46875,0.75 c -0.0101,0.006 -0.0453,-0.003 -0.0625,0.0312 0.0396,0.0611 0.061,0.007 0.0625,-0.0312 z m -2.1875,0.0312 c -0.0104,0.0169 0.0106,0.052 0.15625,0.15625 0.36178,0.0251 -0.12511,-0.20702 -0.15625,-0.15625 z m 0.34375,0.1563 c -0.0422,0.0167 -0.0392,0.0395 0.0312,0.0937 0.0799,0.0985 0.14452,-0.0616 0.21875,-0.0937 -0.0966,-0.016 -0.19592,-0.0213 -0.25,0 z m 0.28125,0 c 0.0269,0.001 0.0379,0.0223 0.0625,0.0937 0.12084,-0.0286 0.0505,-0.0711 -0.0625,-0.0937 z m 0.59375,0.0625 c 0.0151,0.0164 0.0447,0.016 0.0625,0.0312 -0.0224,-0.004 -0.0368,0.002 -0.0625,0 -0.006,-0.01 0.005,-0.0214 0,-0.0312 z m 0.71875,0.0937 c 0.0918,-0.004 0.19416,0.006 0.3125,0.0312 -0.93272,0.60426 -0.955,-0.004 -0.3125,-0.0312 z m 0.875,0.1875 c 0.0209,0.0339 0.037,0.0652 0,0.125 -0.01,-0.0407 -0.0132,-0.0852 0,-0.125 z m -0.28125,0.0937 c 0.008,0.0407 0.0223,0.0692 0.0625,0.125 0.002,0.0174 0.0188,0.0345 0.0312,0.0312 0.0374,-0.01 0.0901,-0.078 0.0937,-0.0312 0.0326,-0.03 0.0758,-0.0367 0.0937,-0.0625 0.0122,0.0307 0.0395,0.0525 0.0625,0.0625 -0.0786,0.0243 -0.16205,0.0214 -0.25,0.0312 -0.55894,0.20149 0.0265,0.0442 -0.0937,-0.15625 z"
+     style="fill:url(#linearGradient4894);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/skins/moono/icons/print.png"
+     sodipodi:nodetypes="ssccssssssscsssscssssscccccssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4664"
+     d="m 229.5,2.2500615 c -0.831,0 -1.5,0.669 -1.5,1.5 l 0,0.49999 10,0 0,-0.49999 c 0,-0.831 -0.669,-1.5 -1.5,-1.5 z m -2.5,3 c -0.554,0 -1,0.44599 -1,1 l 0,5.9999995 c 0,0.554 0.446,1 1,1 l 2,0 0,-4.9999995 c 0,-0.55401 0.446,-1 1,-1 l 6,0 c 0.554,0 1,0.44599 1,1 l 0,4.9999995 2,0 c 0.554,0 1,-0.446 1,-1 l 0,-5.9999995 c 0,-0.55401 -0.446,-1 -1,-1 z m 3,3 0,6.9999995 6,0 0,-6.9999995 z m 1.5,1 3,0 c 0.277,0 0.5,0.223 0.5,0.5 0,0.2769895 -0.223,0.4999995 -0.5,0.4999995 l -3,0 c -0.277,0 -0.5,-0.22301 -0.5,-0.4999995 0,-0.277 0.223,-0.5 0.5,-0.5 z m 0,1.9999995 3,0 c 0.277,0 0.5,0.223 0.5,0.5 0,0.27699 -0.223,0.5 -0.5,0.5 l -3,0 c -0.277,0 -0.5,-0.22301 -0.5,-0.5 0,-0.277 0.223,-0.5 0.5,-0.5 z"
+     style="fill:url(#linearGradient4898);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4666"
+     d="m 73,98.250061 c -3.31371,0 -6,2.686289 -6,5.999999 0,3.3137 2.68629,6 6,6 3.31371,0 6,-2.6863 6,-6 0,-3.31371 -2.68629,-5.999999 -6,-5.999999 z m 0,1 c 2.76142,0 5,2.238569 5,4.999999 0,2.76142 -2.23858,5 -5,5 -2.76142,0 -5,-2.23858 -5,-5 0,-2.76143 2.23858,-4.999999 5,-4.999999 z m 0,1.999999 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 1.65685,0 3,-1.34315 3,-3 0,-1.65686 -1.34315,-3 -3,-3 z"
+     style="fill:url(#linearGradient4900);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="ssssssssssssscccccsss"
+     inkscape:connector-curvature="0"
+     id="path4670"
+     d="m 292,100.25006 c -1.662,0 -3,1.33799 -3,3 l 0,2 c 0,1.662 1.338,3 3,3 l 10,0 c 1.662,0 3,-1.338 3,-3 l 0,-2 c 0,-1.66201 -1.338,-3 -3,-3 z m 0,1 10,0 c 1.108,0 2,0.89199 2,2 l 0,2 c 0,1.108 -0.892,2 -2,2 l -2,-3 -3,3 -3,-2 -2,2 c -1.108,0 -2,-0.892 -2,-2 l 0,-2 c 0,-1.10801 0.892,-2 2,-2 z"
+     style="fill:url(#linearGradient4904);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     style="font-size:16.54135895px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4906);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Sans"
+     d="m 140.5,130.25006 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.5,0 0,1 -2.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 l 0,2 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 0,-1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-2 c 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -3,0 z m -8.375,2.9375 c -0.29577,0 -0.58586,0.11711 -0.8125,0.34375 -0.45327,0.45327 -0.45327,1.20297 0,1.65625 l 2.03125,2.03125 -2.03125,2.03125 c -0.45327,0.45327 -0.45327,1.20297 0,1.65625 0.45327,0.45327 1.17173,0.45327 1.625,0 l 2.0625,-2.03125 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 l -2.03125,-2.03125 2.03125,-2.03125 c 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 -0.45327,-0.45328 -1.17173,-0.45328 -1.625,0 L 135,135.56256 l -2.0625,-2.03125 c -0.22664,-0.22664 -0.51673,-0.34375 -0.8125,-0.34375 z"
+     id="path4672"
+     inkscape:connector-curvature="0" /><path
+     id="path4674"
+     d="m 172.5,138.25006 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.24281,0.60287 0.5,0.5 l 2.5,0 0,1 -2.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 l 0,2 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 0,-1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-2 c 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m -8.375,-6.0625 c -0.29577,0 -0.58586,0.11711 -0.8125,0.34375 -0.45327,0.45327 -0.45327,1.20297 0,1.65625 l 2.03125,2.03125 -2.03125,2.03125 c -0.45327,0.45327 -0.45327,1.20297 0,1.65625 0.45327,0.45327 1.17173,0.45327 1.625,0 l 2.0625,-2.03125 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 l -2.03125,-2.03125 2.03125,-2.03125 c 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 -0.45327,-0.45328 -1.17173,-0.45328 -1.625,0 L 167,134.56256 l -2.0625,-2.03125 c -0.22664,-0.22664 -0.51673,-0.34375 -0.8125,-0.34375 z"
+     style="font-size:16.54135895px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4908);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Sans"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssccsssssssccsssssssscssccssscsssccs" /><path
+     inkscape:connector-curvature="0"
+     id="path4676"
+     d="m 7.5000001,65.250051 c -3.03757,0 -5.5,2.46243 -5.5,5.5 0,3.03756 2.46243,5.5 5.5,5.5 0.938705,0 1.7919409,-0.27092 2.5624999,-0.6875 l 3.75,3.75 c 0.587606,0.58761 1.537394,0.58761 2.125,0 0.587606,-0.58761 0.587606,-1.53739 0,-2.125 l -3.71875,-3.71875 C 12.691902,72.662431 13,71.754301 13,70.750051 c 0,-3.03757 -2.46243,-5.5 -5.4999999,-5.5 z m 0,2 c 1.9329999,0 3.4999999,1.567 3.4999999,3.5 0,1.06272 -0.47105,2.01435 -1.21875,2.65625 -0.006,0.005 -0.02525,-0.005 -0.03125,0 -0.60985,0.51643 -1.3882799,0.84375 -2.2499999,0.84375 -1.933,0 -3.5,-1.56701 -3.5,-3.5 0,-1.933 1.567,-3.5 3.5,-3.5 z"
+     style="fill:url(#linearGradient4910);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4678"
+     d="m 297.00004,35.250051 7,5 -6.99998,4.99999 -2e-5,-3.33332 c -3.41666,0 -5.61556,1.22 -7,3.33333 0,-4.98332 3.60112,-6.66666 7,-6.66666 -2e-5,-0.85078 -1e-5,-2.61389 0,-3.33334 z"
+     style="fill:url(#linearGradient4912);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     sodipodi:nodetypes="ccccccc" /><path
+     inkscape:connector-curvature="0"
+     id="path4680"
+     d="m 69,163.25006 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 4.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -6,0 z m -4.5,5 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 4.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z"
+     style="fill:url(#linearGradient4914);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4682"
+     d="m 136.53125,162.25006 c -0.25721,0 -0.46875,0.22299 -0.46875,0.5 l 0,12 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 l 0,-12 c 0,-0.27701 -0.21154,-0.5 -0.46875,-0.5 z m -4.03125,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -8.5,2.46875 0,0.0625 2,1.46875 0,-1 2.5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 l -2.5,0 0,-1 z m 8.5,-0.46875 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z"
+     style="fill:url(#linearGradient4916);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     style="fill:url(#linearGradient4918);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 233.46875,162.25006 c 0.25721,0 0.46875,0.22299 0.46875,0.5 l 0,12 c 0,0.277 -0.21154,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.223 -0.46875,-0.5 l 0,-12 c 0,-0.27701 0.21154,-0.5 0.46875,-0.5 z m 4.03125,2 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 0,2 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 8.49436,2.53125 0,-0.0625 -1.99549,-1.46875 0,1 -2.49436,0 c -0.27637,0 -0.49887,0.18037 -0.49887,0.46875 l 0,0.0625 c 0,0.2631 0.2225,0.46875 0.49887,0.46875 l 2.49436,0 0,1 z M 231.5,168.25006 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 0,2 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z m 6,2 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 0.223,-0.46875 0.5,-0.46875 z"
+     id="path4684"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss" /><path
+     sodipodi:nodetypes="sscccccccccccscccc"
+     inkscape:connector-curvature="0"
+     id="path4686"
+     d="m 459,163.25006 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 l 0,4 1,0 0,-9 1,0 0,1 0,8 1,0 0,-8 1,0 0,-2 z m -8,3 0,6 3,-3 z"
+     style="fill:url(#linearGradient4920);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="sscccccccccccscccc"
+     inkscape:connector-curvature="0"
+     id="path4688"
+     d="m 486,163.25006 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 l 0,4 1,0 0,-9 1,0 0,1 0,8 1,0 0,-8 1,0 0,-2 z m 9.00442,3 0,6 -3.00884,-3 z"
+     style="fill:url(#linearGradient4922);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     transform="matrix(0.99963181,0,0,1,0.17783468,0)" /><path
+     sodipodi:nodetypes="ccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4691"
+     d="m 42.56445,200.91673 -1.02277,1.06211 2.08489,2.08489 -2.08489,2.12422 1.02277,1.06211 2.12422,-2.12422 2.12423,2.12422 1.02277,-1.06211 -2.08489,-2.12423 2.08489,-2.08488 -1.02277,-1.06211 -2.12423,2.12422 z"
+     style="fill:url(#linearGradient4924);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     style="fill:url(#linearGradient4926);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 136.53125,162.25006 c -0.25721,0 -0.46875,0.22299 -0.46875,0.5 l 0,12 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 l 0,-12 c 0,-0.27701 -0.21154,-0.5 -0.46875,-0.5 z m -4.03125,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -8.5,2.46875 0,0.0625 2,1.46875 0,-1 2.5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 l -2.5,0 0,-1 z m 8.5,-0.46875 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z"
+     id="path4693"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4695"
+     d="m 168.64267,162.25006 c -0.25721,0 -0.46875,0.223 -0.46875,0.5 l 0,12 c 0,0.27699 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.22301 0.46875,-0.5 l 0,-12 c 0,-0.277 -0.21154,-0.5 -0.46875,-0.5 z m -4.03125,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -3.38858,2.46875 0,0.0625 -2.08914,1.46875 0,-1 -2.61141,0 c -0.28935,0 -0.52229,-0.0347 -0.52229,-0.46875 l 0,-0.0625 c 0,-0.2631 0.23294,-0.46875 0.52229,-0.46875 l 2.61141,0 0,-1 z m 3.38858,-0.46875 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z"
+     style="fill:url(#linearGradient4928);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4698"
+     d="m 201.46875,162.25006 c 0.25722,0 0.46875,0.223 0.46875,0.5 l 0,12 c 0,0.277 -0.21153,0.5 -0.46875,0.5 -0.25721,0 -0.46875,-0.223 -0.46875,-0.5 l 0,-12 c 0,-0.277 0.21154,-0.5 0.46875,-0.5 z m 4.03125,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 0.223,-0.46875 0.5,-0.46875 z m 0,2 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 0.223,-0.46875 0.5,-0.46875 z m 3.5,2.53125 0,-0.0625 2,-1.46875 0,1 2.5,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.22343,0.48425 -0.5,0.46875 l -2.5,0 0,1 z m -3.5,-0.53125 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 0.223,-0.46875 0.5,-0.46875 z m 0,2 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 0.223,-0.46875 0.5,-0.46875 z m 6,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.223,0.46875 -0.5,0.46875 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 c 0,-0.26309 0.223,-0.46875 0.5,-0.46875 z"
+     style="fill:url(#linearGradient4930);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4700"
+     d="m 2.0000001,226.25006 0,12 13.9999999,0 0,-12 -13.9999999,0 z m 1,1 11.9999999,0 0,7.59375 -2.90625,-3.59375 -3.09375,4 -2.9999999,-2 -3,4 0,-10 z m 2.5,1 c -0.82843,0 -1.5,0.67157 -1.5,1.5 0,0.82842 0.67157,1.5 1.5,1.5 0.82842,0 1.5,-0.67158 1.5,-1.5 0,-0.82843 -0.67158,-1.5 -1.5,-1.5 z"
+     style="fill:url(#linearGradient4932);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4702"
+     d="m 199,227.25006 0,3 10,0 0,-3 z m -5,2 0,7 4,-3.4375 z m 5,3 0,1 3,0 0,-1 z m 4,0 0,1 3,0 0,-1 z m 4,0 0,1 2,0 0,-1 z m -8,3 0,3 10,0 0,-3 z"
+     style="fill:url(#linearGradient4934);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="sscccssssscccssss"
+     inkscape:connector-curvature="0"
+     id="path4704"
+     d="m 323.5,100.25006 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24236 0.59935,0.45353 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.37612,-0.74776 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4936);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     sodipodi:nodetypes="ssssssccssssssccsssssscccssssscccssssccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4706"
+     d="m 131,98.250061 c -1.0907,0 -2,0.9093 -2,1.999999 l 0,9 c 0,1.09069 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.90931 2,-2 l 0,-0.375 c 0.0328,-0.0893 0.0213,-0.17215 0,-0.25 l 0,-8.375 c 0,-1.090699 -0.9093,-1.999999 -2,-1.999999 z m 0,1 12,0 c 0.554,0 1,0.446 1,0.999999 l 0,4.11795 -5.88205,5.88195 -7.11795,1e-4 c -0.554,10e-6 -1,-0.446 -1,-1 l 0,-9 c 0,-0.553999 0.446,-0.999999 1,-0.999999 z m 0.5,0.999999 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.0444,0.53446 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.12178,-0.5281 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 12.5,5.40625 0,0.84375 -3.71875,3.6875 -0.0312,0.0625 -0.84375,0 z m 0,2.21875 0,0.625 -1.71875,1.75 -0.625,0 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4938);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     sodipodi:nodetypes="sssssssssssssssssscccc"
+     inkscape:connector-curvature="0"
+     id="path4708"
+     d="m 195,99.250061 c -1.0907,0 -2,0.909299 -2,1.999999 l 0,7 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.0907 -0.9093,-1.999999 -2,-1.999999 z m 0,0.999999 12,0 c 0.554,0 1,0.446 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -12,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.554 0.446,-1 1,-1 z m 6,3 3,4 3,-4 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4940);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path4710"
+     d="m 105.5,354.25005 c -1.37614,0 -2.55454,0.83475 -3.125,2 l 1.125,0 c 0.45491,-0.61149 1.17592,-1 2,-1 1.385,0 2.5,1.115 2.5,2.5 l 0,1.5 -3,0 -2,0 -1,0 -1,0 c -0.554,0 -1,0.44598 -1,1 l 0,6 c 0,0.554 0.446,1 1,1 l 9,0 c 0.554,0 1,-0.446 1,-1 l 0,-6 c 0,-0.55402 -0.446,-1 -1,-1 l -1,0 0,-1.5 c 0,-1.9217 -1.5783,-3.5 -3.5,-3.5 z m 0,8 c 0.82843,0 1.5,0.67157 1.5,1.5 0,0.82841 -0.67157,1.5 -1.5,1.5 -0.82843,0 -1.5,-0.67159 -1.5,-1.5 0,-0.82843 0.67157,-1.5 1.5,-1.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3350);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path4712"
+     d="m 4.5000001,163.25006 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 0.5,0 0,3.5 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-4 c 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1,0 z m 4,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 5.9999999,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -5.9999999,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 5.9999999,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -5.9999999,0 z m -5,5 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,1 -1.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,2 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 0,-1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 0.0252,-0.0599 0.0312,-0.11825 0.0312,-0.1875 l 0,-2 c 0,-0.0693 -0.006,-0.12765 -0.0312,-0.1875 -0.0505,-0.13913 -0.15407,-0.24028 -0.28125,-0.28125 -0.0404,-0.0171 -0.0799,-0.0253 -0.125,-0.0312 l -0.0625,0 -2,0 z m 5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 5.9999999,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -5.9999999,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 5.9999999,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -5.9999999,0 z"
+     style="fill:url(#linearGradient3293);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="cccccccccccccccccccscccscscccscccccccc"
+     d="m 14.295877,138.53521 c -9e-6,0.70891 -0.137341,1.30388 -0.411995,1.78492 -0.274673,0.46838 -0.650527,0.84815 -1.127571,1.1393 -0.462605,0.2785 -1.019157,0.48105 -1.669674,0.60763 -0.636069,0.11394 -1.322728,0.1709 -2.059977,0.1709 l -3.72966,0.0121 0,-12.04805 3.4694455,-0.003 c 1.0119225,1e-5 1.8359135,0.095 2.4719815,0.28482 0.636059,0.17724 1.134796,0.41776 1.496201,0.72156 0.361395,0.29117 0.607142,0.6203 0.737259,0.9874 0.130097,0.36712 0.195146,0.73423 0.195156,1.10133 -10e-6,0.557 -0.159025,1.0507 -0.477054,1.4811 -0.303581,0.43041 -0.715576,0.7722 -1.235986,1.02538 0.910722,0.29116 1.525098,0.68359 1.843147,1.17728 0.332478,0.49371 0.498718,1.01272 0.498727,1.55705 m -6.3317392,-1.59503 0,3.19006 c 0.1879221,0.0253 0.3903124,0.0443 0.6071515,0.057 0.2312976,0.0127 0.4553617,0.019 0.6722097,0.019 0.303571,1e-5 0.599918,-0.019 0.88904,-0.057 0.289122,-0.0506 0.542103,-0.13292 0.758942,-0.24685 0.231297,-0.12659 0.419219,-0.29748 0.563785,-0.51269 0.144556,-0.22786 0.216839,-0.51268 0.216839,-0.85448 0,-0.56965 -0.209614,-0.97473 -0.628834,-1.21526 -0.404771,-0.25317 -0.954098,-0.37976 -1.647981,-0.37977 l -1.4311522,0 m 1.0408392,-1.93682 c 0.679425,1e-5 1.192611,-0.12658 1.539567,-0.37977 0.346937,-0.26583 0.52041,-0.62661 0.52041,-1.08234 0,-0.27849 -0.05059,-0.50002 -0.15179,-0.66459 -0.101191,-0.17722 -0.238522,-0.31014 -0.411996,-0.39876 -0.173473,-0.10126 -0.375863,-0.16456 -0.607151,-0.18989 -0.231298,-0.038 -0.46982,-0.057 -0.715576,-0.057 -0.2023808,1e-5 -0.4119955,0.006 -0.6288347,0.019 -0.2168391,0.0127 -0.4119953,0.0317 -0.5854685,0.057 l 0,2.69636 1.0408392,0"
+     style="font-size:22.63113022px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4944);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono Bold"
+     id="path4714"
+     inkscape:connector-curvature="0"
+     transform="matrix(1,0,0,0.99576386,0,0.60259052)" /><g
+     id="g4716"
+     style="font-size:14.87401295px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4948);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Sans"
+     transform="matrix(0.90955065,0,-0.23456935,0.90955065,-244.41664,85.857921)"><path
+       sodipodi:nodetypes="ccccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path4718"
+       style="font-size:21.24859047px;font-variant:normal;font-weight:bold;font-stretch:normal;fill:url(#linearGradient4946);font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono Bold"
+       d="m 325.2364,61.999996 0,-2.167356 1.76912,0 -0.1287,-8.818165 -1.76912,0 0,-2.167356 6.15181,0 0,2.167356 -1.74787,0 0.1287,8.818165 1.74787,0 0,2.167356 -6.15181,0" /></g><g
+     id="g4720"
+     style="font-size:15.82676315px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4952);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1);font-family:Sans"
+     transform="matrix(1.0640547,0,0,0.9425284,-84.03155,80.070151)"><path
+       sodipodi:nodetypes="ccccccccc"
+       inkscape:connector-curvature="0"
+       id="path4722"
+       style="font-size:22.60966301px;font-style:italic;font-variant:normal;font-stretch:normal;fill:url(#linearGradient4950);font-family:'8bitoperator JVE';-inkscape-font-specification:'8bitoperator JVE Italic'"
+       d="m 263.15116,63.849438 2.25213,-9.18288 -2.8262,0 0.28703,-1.413104 8.47863,0 -0.28704,1.413104 -2.82621,0 -2.25213,9.18288 -2.82621,0" /></g><path
+     inkscape:connector-curvature="0"
+     id="path4726"
+     d="m 265.00004,35.250051 7,5 -6.99998,4.99999 -2e-5,-3.33332 c -3.41666,0 -5.61556,1.22 -7,3.33333 0,-4.98332 3.60112,-6.66666 7,-6.66666 -2e-5,-0.85078 -1e-5,-2.61389 0,-3.33334 z"
+     style="fill:url(#linearGradient4954);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     sodipodi:nodetypes="ccccccc" /><path
+     sodipodi:nodetypes="ccccccc"
+     style="fill:url(#linearGradient4956);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 329,35.250061 -7,5 6.99998,4.99998 2e-5,-3.33332 c 3.41666,0 5.61556,1.22 7,3.33334 0,-4.98333 -3.60112,-6.66667 -7,-6.66667 2e-5,-0.85078 10e-6,-2.61388 0,-3.33333 z"
+     id="path4728"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="sssssssssssssssssscccc"
+     inkscape:connector-curvature="0"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4958);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 239,99.250061 c 1.0907,0 2,0.909299 2,1.999999 l 0,7 c 0,1.0907 -0.9093,2 -2,2 l -12,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-7 c 0,-1.0907 0.9093,-1.999999 2,-1.999999 z m 0,0.999999 -12,0 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 z m -6,3 -3,4 -3,-4 z"
+     id="path4730" /><path
+     inkscape:connector-curvature="0"
+     id="path4732"
+     d="m 112,193.25006 0,14 -1,0 0,-14 z m -4.74999,-0.41664 c 0.86983,0.009 1.76033,0.34033 2.74999,1.375 l 0,8.04164 c -3.96132,-4.05865 -6.94268,2.81598 -11,-1 l 0,-8.04165 c 3.03099,2.934 5.64051,-0.40352 8.25001,-0.37496 z"
+     style="fill:url(#linearGradient4960);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     sodipodi:nodetypes="cccccccccccc" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4962);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 79.5,289.25006 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -3.5,0 c 1.0907,0 2,0.9093 2,2 l 0,10 c 0,1.0907 -0.9093,2 -2,2 -1.0907,0 -2,-0.9093 -2,-2 l 0,-10 c 0,-1.0907 0.9093,-2 2,-2 z m 0,1 c -0.554,0 -1,0.446 -1,1 l 0,10 c 0,0.554 0.446,1 1,1 0.554,0 1,-0.446 1,-1 l 0,-10 c 0,-0.554 -0.446,-1 -1,-1 z m 11.5,1 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 6.5,2 c 1.0907,0 2,0.9093 2,2 0,1.0907 -0.9093,2 -2,2 l -5,0 c -1.0907,0 -2,-0.9093 -2,-2 0,-1.0907 0.9093,-2 2,-2 l 5,0 z m 0,1 -5,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 5,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z"
+     id="path4734"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="ssccsssssccsssscccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4736"
+     d="m 68,1.2500615 c -1.108,0 -2,0.892 -2,2 l 0,8.9374995 3,3.0625 9,0 c 1.108,0 2,-0.892 2,-2 l 0,-9.9999995 c 0,-1.108 -0.892,-2 -2,-2 z m 0,1 10,0 0,4 c 0,1.108 0.108,1 -1,1 l -8,0 c -1.108,0 -1,0.108 -1,-1 z m 1,7.9999995 8,0 0,4 -4,0 0,-3 -2,0 0,3 -2,0 z"
+     style="fill:url(#linearGradient4964);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     sodipodi:nodetypes="ssscsssssssssssssssssssscssccsssssssccsccssccccccssssssssssssss"
+     style="fill:url(#linearGradient3291);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 45.5,163.25006 c 0,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.777,0.5 0.5,0.5 l 0.5,0 0,3.5 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-4 c 0,-0.277 -0.5,-0.5 -0.5,-0.5 z m -10,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 9,5 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,1 -1.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,2 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 0,-1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 0.0252,-0.0599 0.0312,-0.11825 0.0312,-0.1875 l 0,-2 c 0,-0.0693 -0.006,-0.12765 -0.0312,-0.1875 -0.0505,-0.13913 -0.15407,-0.24028 -0.28125,-0.28125 -0.0404,-0.0171 -0.0799,-0.0253 -0.125,-0.0312 l -0.0625,0 -2,0 z m -9,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     id="path4738"
+     inkscape:connector-curvature="0" /><path
+     sodipodi:nodetypes="ssssssssssssssssssssssssssssssssssssss"
+     style="fill:url(#linearGradient4966);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 109,163.25006 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m -10.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 10.5,5 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m -10.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     id="path4740"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4968);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 235,227.25006 0,3 -10,0 0,-3 z m 5,2 0,7 -4,-3.4375 z m -5,3 0,1 -3,0 0,-1 z m -4,0 0,1 -3,0 0,-1 z m -4,0 0,1 -2,0 0,-1 z m 8,3 0,3 -10,0 0,-3 z"
+     id="path4742"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccc" /><path
+     inkscape:connector-curvature="0"
+     id="path4744"
+     d="m 6.0000001,297.25005 0,1 -1,0 0,1 -1,0 0,0.875 -0.5,-0.5 -1.5,-1.375 0,5 5,0 -1.5,-1.625 -0.375,-0.375 0.875,0 0,-1 1,0 0,-1 1,0 0,-2 -2,0 z"
+     style="fill:#585858;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     id="path4746"
+     d="m 41,321.21574 c -3.86517,0 -7,3.1502 -7,7.03432 0,3.88412 3.13483,7.03431 7,7.03431 3.86633,0 7,-3.15019 7,-7.03431 0,-3.88412 -3.13367,-7.03432 -7,-7.03432 z"
+     style="fill:url(#linearGradient4970);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     sodipodi:nodetypes="sssss" /><path
+     inkscape:transform-center-y="2.9999632"
+     inkscape:transform-center-x="-1.4999864"
+     sodipodi:end="2.0943951"
+     sodipodi:start="0"
+     sodipodi:type="arc"
+     style="fill:#999999;fill-opacity:1;stroke:none"
+     id="path4748"
+     sodipodi:cx="39.5"
+     sodipodi:cy="327.5"
+     sodipodi:rx="5.5"
+     sodipodi:ry="5.5"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     transform="matrix(1.0909017,0,0,1.0909017,-2.0906205,-29.020279)" /><path
+     transform="matrix(-0.54545087,0.94474863,-0.94474863,-0.54545087,371.95048,469.56763)"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     sodipodi:ry="5.5"
+     sodipodi:rx="5.5"
+     sodipodi:cy="327.5"
+     sodipodi:cx="39.5"
+     id="path4750"
+     style="fill:#cccccc;fill-opacity:1;stroke:none"
+     sodipodi:type="arc"
+     sodipodi:start="0"
+     sodipodi:end="2.0943951"
+     inkscape:transform-center-x="3.0004864" /><path
+     inkscape:transform-center-y="-3.0004886"
+     inkscape:transform-center-x="-1.4999969"
+     sodipodi:end="2.0943951"
+     sodipodi:start="0"
+     sodipodi:type="arc"
+     style="fill:#666666;fill-opacity:1;stroke:none"
+     id="path4752"
+     sodipodi:cx="39.5"
+     sodipodi:cy="327.5"
+     sodipodi:rx="5.5"
+     sodipodi:ry="5.5"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     transform="matrix(-0.54545087,-0.94474863,0.94474863,-0.54545087,-246.85986,544.20276)" /><rect
+     ry="0"
+     rx="0"
+     y="231.25003"
+     x="98"
+     height="2"
+     width="14"
+     id="rect4754"
+     style="fill:url(#linearGradient4972);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)" /><rect
+     style="fill:#999999;fill-opacity:1;stroke:none"
+     id="rect4756"
+     width="12"
+     height="0.99999475"
+     x="99"
+     y="228.25003"
+     rx="0"
+     ry="0" /><rect
+     ry="0"
+     rx="0"
+     y="226.25003"
+     x="99"
+     height="0.99999475"
+     width="12"
+     id="rect4758"
+     style="fill:#999999;fill-opacity:1;stroke:none" /><rect
+     ry="0"
+     rx="0"
+     y="237.25003"
+     x="99"
+     height="0.99999475"
+     width="12"
+     id="rect4760"
+     style="fill:#999999;fill-opacity:1;stroke:none" /><rect
+     style="fill:#999999;fill-opacity:1;stroke:none"
+     id="rect4762"
+     width="12"
+     height="0.99999475"
+     x="99"
+     y="235.25003"
+     rx="0"
+     ry="0" /><rect
+     style="fill:#999999;fill-opacity:1;stroke:none"
+     id="rect4764"
+     width="12"
+     height="0.99999475"
+     x="99"
+     y="224.25003"
+     rx="0"
+     ry="0" /><rect
+     ry="0"
+     rx="0"
+     y="239.25003"
+     x="99"
+     height="0.99999475"
+     width="12"
+     id="rect4766"
+     style="fill:#999999;fill-opacity:1;stroke:none" /><path
+     transform="matrix(-1,0,0,1,337.02051,0.25006141)"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient4974);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 162,98 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.09069 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.90931 2,-2 l 0,-0.375 c 0.0328,-0.0893 0.0213,-0.17215 0,-0.25 L 176,100 c 0,-1.0907 -0.9093,-2 -2,-2 z m 0,1 12,0 c 0.554,0 1,0.446 1,1 l 0,4.11795 -5.88205,5.88195 L 162,110 c -0.554,1e-5 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 z m 0.5,1 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.0444,0.53446 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.12178,-0.5281 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 12.5,5.40625 0,0.84375 -3.71875,3.6875 -0.0312,0.0625 -0.84375,0 z m 0,2.21875 0,0.625 -1.71875,1.75 -0.625,0 z"
+     id="path4768"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ssssssccssssssccsssssscccssssscccssssccccccccccc" /><path
+     style="fill:url(#linearGradient6476);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 65,225.25005 0,2 0,10 0,2 16,0 0,-2 0,-10 0,-2 z m 1,4 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m -10,5 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z"
+     id="path4770"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc" /><path
+     transform="matrix(1,0,0,-1,1.0000001,585.25004)"
+     inkscape:connector-curvature="0"
+     style="fill:#585858;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 5,289.99999 0,1 -1,0 0,1 -1,0 0,0.875 -0.5,-0.5 -1.5,-1.375 0,5 5,0 -1.5,-1.625 -0.375,-0.375 0.875,0 0,-1 1,0 0,-1 1,0 0,-2 -2,0 z"
+     id="path4788" /><path
+     transform="matrix(-1,0,0,1,25,0.25006141)"
+     inkscape:connector-curvature="0"
+     style="fill:#585858;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     d="m 13,296.99999 0,1 -1,0 0,1 -1,0 0,0.875 -0.5,-0.5 -1.5,-1.375 0,5 5,0 -1.5,-1.625 -0.375,-0.375 0.875,0 0,-1 1,0 0,-1 1,0 0,-2 -2,0 z"
+     id="path4790" /><path
+     id="path4792"
+     d="m 5,289.99999 0,1 -1,0 0,1 -1,0 0,0.875 -0.5,-0.5 -1.5,-1.375 0,5 5,0 -1.5,-1.625 -0.375,-0.375 0.875,0 0,-1 1,0 0,-1 1,0 0,-2 -2,0 z"
+     style="fill:#585858;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0"
+     transform="matrix(-1,0,0,-1,17,585.25004)" /><path
+     id="path4795"
+     d="m 259,1.2500515 0,13.9999995 11,0 0,-8.9999995 0,-1 -4,-4 -1,0 -6,0 z m 1,1 5.34375,0 3.65625,3.65625 0,8.3437495 -5,0 -3,0 -1,0 0,-11.9999995 z m 2,5 0,1 5,0 0,-1 -5,0 z m 0,2 0,0.9999995 5,0 0,-0.9999995 -5,0 z m 0,1.9999995 0,1 5,0 0,-1 -5,0 z"
+     style="fill:url(#linearGradient4980);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient4982);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 3.0000001,1.2500515 0,13.9999995 10.9999999,0 0,-8.9999995 0,-1 -4,-4 -1,0 z m 1,1 5.4999999,0 3.5,3.5 0,8.4999995 -4.9999999,0 -3,0 -1,0 z"
+     id="path4797"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     transform="matrix(-1,0,0,1,81,0.25006141)"
+     style="fill:url(#linearGradient4984);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 39,6 0,1.875 -1.375,1.46875 1.375,1.46875 0,1.90625 -3.625,-3.375 z"
+     id="path4799"
+     inkscape:connector-curvature="0" /><path
+     transform="matrix(-1,0,0,1,81,0.25006141)"
+     style="fill:url(#linearGradient4986);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="M 40,6 43.6875,9.375 40,12.65625 40,10.75 41.4375,9.34375 40,7.8125 z"
+     id="path4801"
+     inkscape:connector-curvature="0" /><path
+     transform="matrix(-1,0,0,1,82,0.25006141)"
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4803"
+     d="m 35,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     style="fill:url(#linearGradient4988);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     style="fill:url(#linearGradient4990);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 99,1.2500515 0,13.9999995 11,0 0,-8.9999995 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.4999995 -5,0 -3,0 -1,0 z"
+     id="path4805"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     transform="matrix(-1,0,0,1,273,0.25006141)"
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4807"
+     d="m 131,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     style="fill:url(#linearGradient4992);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     id="path4809"
+     d="m 291,1.2500515 0,4.75 c 0.19146,-0.12014 0.37062,-0.22084 0.5625,-0.3125 l 0.4375,-0.21875 0,-3.21875 5.34375,0 3.65625,3.65625 0,8.3437495 -5,0 0,0.96875 c 0,0.0104 1.6e-4,0.0209 0,0.0312 l 6,0 0,-8.9999995 0,-1 -4,-4 -1,0 -6,0 z m 1,5.34375 c -0.36123,0.17256 -0.68892,0.37641 -0.96875,0.65625 -0.63338,0.63338 -1.03125,1.5335 -1.03125,2.5 0,1.3935195 0.8237,2.5643995 2,3.1249995 l 0,2.34375 c 0,0.554 0.44599,1 1,1 l 1,0.0312 c 0.554,0 1,-0.47725 1,-1.03125 l 0,-2.34375 c 1.17629,-0.5606 2,-1.73148 2,-3.1249995 0,-1.39352 -0.82119,-2.59313 -2,-3.15625 l 0,2.65625 -1.46875,0.9999995 L 292,9.2500015 l 0,-2.65625 z"
+     style="fill:url(#linearGradient4994);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     id="path4817"
+     d="m 34,32.250051 0,10 3,0 0,-1 -1,0 -1,0 0,-8 4.5,0 2.5,2.5 0,0.5 1,0 0,-1 -3,-3 -1,0 -5,0 z m 4,5 0,10 9,0 0,-6 0,-1 -3,-3 -1,0 -5,0 z m 1,1 4.5,0 2.5,2.5 0,5.5 -5,0 -1,0 -1,0 0,-8 z"
+     style="fill:url(#linearGradient4996);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0" /><path
+     transform="matrix(-1,0,0,1,389,0.25006141)"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient5002);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 182,0.99999 0,14 8.8125,0 -1,-1 -1.3125,0 -1.5,0 -3,0 -1,0 0,-12 5.5,0 3.5,3.5 0,1.21875 c 0.61468,0.7698887 1,1.7287934 1,2.78125 l 0,-3.5 0,-1 -4,-4 -1,0 -6,0 z m 11,8.5 c 0,0.4831876 -0.20077,0.86276 -0.34375,1.28125 L 193,11.12499 l 0,-1.625 z m -4.5,-3.5 c -1.92115,0 -3.5,1.57884 -3.5,3.5 0,1.92115 1.57885,3.5 3.5,3.5 0.49539,0 0.94633,-0.12374 1.375,-0.3125 l 2.34375,2.34375 1.625,-1.625 -2.28125,-2.28125 C 191.829,10.63214 192,10.09539 192,9.49999 c 0,-1.92116 -1.57885,-3.5 -3.5,-3.5 z m -0.0312,1 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
+     id="path4828" /><path
+     transform="matrix(-1,0,0,1,657,0.25006141)"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient5004);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 323,0.99999 0,4.75 c 0.19146,-0.1201434 0.37062,-0.2208417 0.5625,-0.3125 L 324,5.21874 l 0,-3.21875 5.34375,0 3.65625,3.65625 0,8.34375 -5,0 0,0.96875 c 0,0.01043 1.6e-4,0.02085 0,0.03125 l 6,0 0,-9 0,-1 -4,-4 -1,0 -6,0 z m 1,5.34375 c -0.36123,0.1725562 -0.68892,0.3764154 -0.96875,0.65625 C 322.39787,7.6333667 322,8.5334899 322,9.49999 c 0,1.393522 0.8237,2.564396 2,3.125 l 0,2.34375 c 0,0.554002 0.44599,1.000002 1,1 l 1,0.03125 c 0.554,-2e-6 1,-0.477248 1,-1.03125 l 0,-2.34375 c 1.17629,-0.560603 2,-1.731478 2,-3.125 0,-1.3935222 -0.82119,-2.5931341 -2,-3.15625 l 0,2.65625 -1.46875,1 -1.53125,-1 0,-2.65625 z"
+     id="path4830" /><rect
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     id="rect6517"
+     width="6.9999981"
+     height="1"
+     x="71"
+     y="68.250053" /><rect
+     y="70.250053"
+     x="67"
+     height="1"
+     width="11"
+     id="rect6519"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     y="74.250053"
+     x="67"
+     height="1"
+     width="11"
+     id="rect6523"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     id="rect6525"
+     width="3"
+     height="1"
+     x="67"
+     y="76.250053" /><path
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     d="m 71,76.250051 0,1 1,0 0,2 -1,0 0,1 3,0 0,-1 -1,0 0,-2 1,0 0,-1 -1,0 -1,0 -1,0 z"
+     id="rect6527"
+     inkscape:connector-curvature="0" /><rect
+     y="72.250053"
+     x="67"
+     height="1"
+     width="11"
+     id="rect6539"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     y="66.250053"
+     x="71"
+     height="1"
+     width="7"
+     id="rect6547"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     style="fill:#2d2d2d;fill-opacity:0.99215686;stroke:none"
+     id="rect6606"
+     width="3"
+     height="3"
+     x="67"
+     y="66.250053" /><path
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient7390);fill-opacity:1;fill-rule:evenodd;display:inline;filter:url(#filter3224-1-7-1-2)"
+     d="m 8.4240611,258.26107 c -1.28354,3.14452 -2.79862,6.87174 -4.15625,10.1875 l 2.5,0 0.90625,-2.5 3.3437499,0 0.8125,2.5 2.625,0 c -1.33823,-3.35178 -2.81774,-6.95392 -4.09375,-10.1875 l -1.9374999,0 z m 0.9687499,2.96875 0.90625,2.6875 -1.9062499,0 0.9999999,-2.6875 z"
+     id="path4763" /><path
+     style="fill:#999999;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 2.0000001,270.26107 0,1.98898 14.9999999,0 0,-1.98898 z"
+     id="path3812"
+     inkscape:connector-curvature="0" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3645);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 103.53125,32.250051 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.9375 c 0,0.2946 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.23665 0.53125,-0.53125 l 0,-0.9375 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -2.9375,0 z m -2.53125,1 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0316,-0.36661 0.0937,-0.53125 l -0.0937,0 z m 7.90625,0 c 0.0622,0.16465 0.0937,0.34767 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z m -4.90625,5 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 2,0 0,4 1,0 0,-4 2,0 0,-1 -5,0 z"
+     id="path3631"
+     inkscape:connector-curvature="0" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3667);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 135.53125,32.250051 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.9375 c 0,0.2946 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.23665 0.53125,-0.53125 l 0,-0.9375 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -2.9375,0 z m -2.53125,1 c -1.0907,0 -2,0.9093 -2,2 l 0,2 1,0 0,-2 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0316,-0.3666 0.0937,-0.53125 l -0.0937,0 z m 7.90625,0 c 0.0621,0.16464 0.0937,0.34767 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.446 1,1 l 0,9 c 0,0.554 -0.446,1 -1,1 l -1,0 0,1 1,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-9 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z m -9.90625,5 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 2,0 0,4 1,0 0,-4 2,0 0,-1 -5,0 z"
+     id="path3655"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#4c4c4c;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-2)"
+     d="m 199.53125,32.250051 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.46875 -0.46875,0 c -0.29461,0 -0.53125,0.23664 -0.53125,0.53125 l 0,0.9375 c 0,0.2946 0.23664,0.53125 0.53125,0.53125 l 1,0 2.9375,0 1,0 c 0.29461,0 0.53125,-0.23665 0.53125,-0.53125 l 0,-0.9375 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -0.46875,0 0,-0.46875 c 0,-0.29461 -0.23664,-0.53125 -0.53125,-0.53125 l -2.9375,0 z m -2.53125,1 c -1.0907,0 -2,0.9093 -2,2 l 0,2 1,0 0,-2 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0316,-0.3666 0.0937,-0.53125 l -0.0937,0 z m 7.90625,0 c 0.0621,0.16464 0.0937,0.34767 0.0937,0.53125 l 0,0.46875 c 0.554,0 1,0.446 1,1 l 0,9 c 0,0.554 -0.446,1 -1,1 l -1,0 0,1 1,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-9 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z m -9.90625,5 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 0,4 1,0 1,-1 1,0 1,1 1,0 0,-4 0,-1 -1,0 0,3 -0.25,0 -0.75,0 0,-1 -1,0 0,1 -0.75,0 -0.25,0 0,-3 -1,0 z"
+     id="path3708"
+     inkscape:connector-curvature="0" /><rect
+     style="fill:url(#linearGradient3809);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-2)"
+     id="rect3807"
+     width="16"
+     height="7.9999976"
+     x="257"
+     y="100.25005"
+     rx="2"
+     ry="2" /><path
+     style="fill:#767676;fill-opacity:1;stroke:none"
+     d="m 259,106.25005 0,-3.375 c 0,-0.35225 0.27275,-0.625 0.625,-0.625 l 12.375,0 0,-0.375 c 0,-0.35225 -0.27275,-0.625 -0.625,-0.625 l -12.75,0 c -0.35225,0 -0.625,0.27275 -0.625,0.625 l 0,3.75 c 0,0.35225 0.27275,0.625 0.625,0.625 l 0.375,0 z"
+     id="rect3811"
+     inkscape:connector-curvature="0" /><g
+     style="font-size:15.85716724px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#585858;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-2);font-family:Sans"
+     id="text3563"
+     transform="translate(18,0.25006141)"><path
+       d="m 91.018035,130.55223 0,2.44671 c -0.634915,-0.28389 -1.011554,-0.48077 -1.615481,-0.62531 -0.603942,-0.14452 -1.174325,-0.21679 -1.71115,-0.2168 -0.712338,10e-6 -1.238845,0.0981 -1.579522,0.29423 -0.340685,0.19616 -0.511026,0.5007 -0.511022,0.91364 -4e-6,0.30972 0.113556,0.55233 0.340681,0.72782 0.232279,0.17035 0.650387,0.31746 1.254327,0.44134 l 1.269812,0.25551 c 1.28529,0.2581 2.198934,0.6504 2.740936,1.1769 0.541983,0.52651 0.81298,1.27498 0.81299,2.2454 -10e-6,1.27498 -0.379405,2.22475 -1.138185,2.84933 -0.753637,0.61942 -1.907307,0.92913 -3.461013,0.92913 -0.732986,0 -1.468547,-0.0697 -2.206686,-0.20905 -0.738146,-0.13937 -1.476288,-0.34584 -2.214429,-0.61942 l 0,-2.5164 c 0.738141,0.39231 1.450474,0.68911 2.137002,0.89042 0.691682,0.19615 1.357558,0.29423 1.997631,0.29423 0.650386,0 1.148502,-0.1084 1.494352,-0.3252 0.345836,-0.2168 0.518757,-0.52651 0.518765,-0.92913 -8e-6,-0.36133 -0.11873,-0.64007 -0.356167,-0.83622 -0.232289,-0.19615 -0.699435,-0.37165 -1.401439,-0.52651 l -1.153671,-0.25551 c -1.156255,-0.24776 -2.002796,-0.64264 -2.539624,-1.18464 -0.531671,-0.54199 -0.797506,-1.27239 -0.797504,-2.1912 -2e-6,-1.15108 0.37165,-2.03634 1.114957,-2.65577 0.743301,-0.61941 1.811801,-0.92912 3.205501,-0.92913 0.6349,1e-5 1.287872,0.049 1.958918,0.14712 0.671031,0.0929 1.122516,0.21753 1.840021,0.40851"
+       style="font-weight:bold;fill:#585858;-inkscape-font-specification:Sans Bold"
+       id="path3568"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccsccccsccccccssccc" /></g><path
+     id="path3593"
+     d="m 99.5,136.25006 12,0 c 0.277,0 0.5,0.20442 0.5,0.45833 l 0,0.0833 c 0,0.25395 -0.223,0.45837 -0.5,0.45837 l -12,0 c -0.277,0 -0.5,-0.20442 -0.5,-0.45833 l 0,-0.0833 c 0,-0.25395 0.223,-0.45837 0.5,-0.45837 z"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1)"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssss" /><path
+     style="fill:url(#linearGradient3947);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 3,354.25006 0,13 1,0 0,-13 z"
+     id="path3580"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc" /><path
+     style="fill:#b50000;fill-opacity:1;fill-rule:evenodd"
+     d="m 7.49999,353.83342 c -0.79075,0.009 -1.6003,0.34033 -2.49999,1.375 l 0,8.04164 c 3.6012,-4.05865 6.31153,2.81598 10,-1 l 0,-8.04165 c -2.75545,2.934 -5.12774,-0.40352 -7.50001,-0.37496 z"
+     id="path3574"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0" /><path
+     id="path4350"
+     d="m 7.49999,354.83342 c -0.79075,0.009 -1.6003,0.34033 -2.49999,1.375 l 0,7.04164 c 3.6012,-4.05865 6.31153,2.81598 10,-1 l 0,-7.04165 c -2.75545,2.934 -5.12774,-0.40352 -7.50001,-0.37496 z"
+     style="fill:url(#linearGradient3949);fill-opacity:1;fill-rule:evenodd"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccc"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><path
+     style="fill:#8e0000;fill-opacity:1;fill-rule:evenodd"
+     d="m 15,354.2188 c -0.30805,0.32801 -0.61008,0.56529 -0.90909,0.75 l 0,7 c -2.37556,1.46746 -4.48386,-1.15037 -6.59091,-1.125 -0.79075,0.009 -1.60031,0.34033 -2.5,1.375 l 0,0.25 0,0.75 0,0.0312 c 0.17642,-0.19882 0.34007,-0.3831 0.51136,-0.53125 0.17129,-0.14815 0.34405,-0.27195 0.51137,-0.375 0.33463,-0.2061 0.66866,-0.31581 0.99432,-0.375 -0.0646,-0.009 -0.13201,-0.0172 -0.19887,-0.0312 0.22905,-0.0632 0.45744,-0.0912 0.68182,-0.0937 1.52669,-0.0184 3.05867,1.36143 4.6875,1.5625 0.0643,0.008 0.13429,-0.004 0.19886,0 0.086,0.005 0.16893,0.0337 0.25569,0.0312 0.0948,-0.003 0.18827,-0.0188 0.28409,-0.0312 0.13088,-0.017 0.26485,-0.0564 0.39772,-0.0937 0.18899,-0.0529 0.37588,-0.1176 0.56819,-0.21875 0.0301,-0.0155 0.055,-0.0457 0.0852,-0.0625 0.16982,-0.0943 0.33776,-0.20651 0.51137,-0.34375 0.16802,-0.13283 0.33949,-0.25969 0.51136,-0.4375 l 0,-0.0312 0,-1 0,-7 z"
+     id="path4364"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0" /><rect
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     y="352.25006"
+     x="1"
+     height="16"
+     width="16"
+     id="rect3598"
+     style="fill:#ffffff;fill-opacity:0;stroke:none" /><path
+     sodipodi:nodetypes="ccccc"
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3600"
+     d="m 3,354.25006 0,13 1,0 0,-13 z"
+     style="fill:url(#linearGradient3576);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)" /><path
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3602"
+     d="m 7.49999,353.83342 c -0.79075,0.009 -1.6003,0.34033 -2.49999,1.375 l 0,8.04164 c 3.6012,-4.05865 6.31153,2.81598 10,-1 l 0,-8.04165 c -2.75545,2.934 -5.12774,-0.40352 -7.50001,-0.37496 z"
+     style="fill:#b50000;fill-opacity:1;fill-rule:evenodd" /><path
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     sodipodi:nodetypes="ccccccc"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient4358);fill-opacity:1;fill-rule:evenodd"
+     d="m 7.49999,354.83342 c -0.79075,0.009 -1.6003,0.34033 -2.49999,1.375 l 0,7.04164 c 3.6012,-4.05865 6.31153,2.81598 10,-1 l 0,-7.04165 c -2.75545,2.934 -5.12774,-0.40352 -7.50001,-0.37496 z"
+     id="path3604" /><path
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3606"
+     d="m 15,354.2188 c -0.30805,0.32801 -0.61008,0.56529 -0.90909,0.75 l 0,7 c -2.37556,1.46746 -4.48386,-1.15037 -6.59091,-1.125 -0.79075,0.009 -1.60031,0.34033 -2.5,1.375 l 0,0.25 0,0.75 0,0.0312 c 0.17642,-0.19882 0.34007,-0.3831 0.51136,-0.53125 0.17129,-0.14815 0.34405,-0.27195 0.51137,-0.375 0.33463,-0.2061 0.66866,-0.31581 0.99432,-0.375 -0.0646,-0.009 -0.13201,-0.0172 -0.19887,-0.0312 0.22905,-0.0632 0.45744,-0.0912 0.68182,-0.0937 1.52669,-0.0184 3.05867,1.36143 4.6875,1.5625 0.0643,0.008 0.13429,-0.004 0.19886,0 0.086,0.005 0.16893,0.0337 0.25569,0.0312 0.0948,-0.003 0.18827,-0.0188 0.28409,-0.0312 0.13088,-0.017 0.26485,-0.0564 0.39772,-0.0937 0.18899,-0.0529 0.37588,-0.1176 0.56819,-0.21875 0.0301,-0.0155 0.055,-0.0457 0.0852,-0.0625 0.16982,-0.0943 0.33776,-0.20651 0.51137,-0.34375 0.16802,-0.13283 0.33949,-0.25969 0.51136,-0.4375 l 0,-0.0312 0,-1 0,-7 z"
+     style="fill:#8e0000;fill-opacity:1;fill-rule:evenodd" /><path
+     style="fill:url(#linearGradient4386);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-2)"
+     d="m 65,321.25005 0,14 3,0 0,-1 -2,0 0,-12 2,0 0,-1 z m 13,0 0,1 2,0 0,12 -2,0 0,1 3,0 0,-14 z"
+     id="rect3578"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccc" /><g
+     style="font-size:13.71140385px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4388);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-2);font-family:Sans"
+     id="text4354"
+     transform="translate(2.0000001,0.25006141)"><path
+       d="m 70.006423,329.43503 1.991763,0 c 1.837326,0 3.016509,-1.30258 3.016509,-3.33187 0,-2.00186 -1.138049,-3.09877 -3.22218,-3.09877 l -3.790777,0 0,9.99561 2.004685,0 0,-3.56497 m 0,-1.71392 0,-3.0028 1.347327,0 c 1.096911,0 1.604234,0.4799 1.604234,1.50826 0,1.01464 -0.507323,1.49454 -1.604234,1.49454 l -1.347327,0"
+       style="font-variant:normal;font-weight:bold;font-stretch:normal;fill:url(#linearGradient3951);font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L Bold"
+       id="path4361"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csssccccccsssc" /></g><path
+     style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;filter:url(#filter3224-1-7-1-5-0-8)"
+     d="m 111,321.53125 -6,0.9375 0,1 2,-0.3125 0,2.84375 -3,0 0,1 3,0 0,3 -2,0 -1,0 0,5 1,0 0,-1 5,0 1,0 0,-4 -1,0 -2,0 0,-3 3,0 0,-1 -3,0 0,-3 3,-0.46875 0,-1 z M 97,322 l 0,1 6,0 0,-1 -6,0 z m -1,2 0,1 8,0 0,-1 -8,0 z m 1,2 0,1 6,0 0,-1 -6,0 z m 0,2 0,1 6,0 0,-1 -6,0 z m 0,2 0,5 1,0 0,-1 4,0 1,0 0,-4 -1,0 -4,0 -1,0 z m 1,1 4,0 0,2 -4,0 0,-2 z m 7,0 5,0 0,2 -5,0 0,-2 z"
+     transform="translate(1,0.2500015)"
+     id="rect4258"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#515151;fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-7)"
+     d="m 129,321.25002 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,5 0,1 0,3 5,0 0,-1 -4,0 0,-1 4,0 1,0 0,-1 -5,0 0,-1 6,0 4,0 0,-1 0,-4 -4,0 -7,0 z m 12,0 0,1 1,0 0,-1 -1,0 z m -11,1 9,0 0,1 -9,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -11,1 8.96875,0 0,1 -8.96875,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -3,1.75 -3.6875,3.375 3.6875,3.28125 0,-1.90625 -1.4375,-1.40625 1.4375,-1.53125 0,-1.8125 z m 1,0 0,1.875 1.375,1.46875 -1.375,1.46875 0,1.90625 3.625,-3.375 -3.625,-3.34375 z m -12,0.25 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+     id="rect5051"
+     inkscape:connector-curvature="0" /></g></svg>
\ No newline at end of file
diff --git a/sources/skins/moono/dev/icons32.png b/sources/skins/moono/dev/icons32.png
new file mode 100644 (file)
index 0000000..a74c093
Binary files /dev/null and b/sources/skins/moono/dev/icons32.png differ
diff --git a/sources/skins/moono/dev/icons32.svg b/sources/skins/moono/dev/icons32.svg
new file mode 100644 (file)
index 0000000..12b8908
--- /dev/null
@@ -0,0 +1,2722 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Generator: Adobe Illustrator 15.1.0, SVG Export Plug-In . SVG Version: 6.00 Build 0)  -->
+
+<svg
+   xmlns:dc="http://purl.org/dc/elements/1.1/"
+   xmlns:cc="http://creativecommons.org/ns#"
+   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+   xmlns:svg="http://www.w3.org/2000/svg"
+   xmlns="http://www.w3.org/2000/svg"
+   xmlns:xlink="http://www.w3.org/1999/xlink"
+   xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+   xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+   version="1.1"
+   id="Layer_1"
+   x="0px"
+   y="0px"
+   width="992"
+   height="736"
+   viewBox="0 0 992 735.99996"
+   enable-background="new 0 0 612 792"
+   xml:space="preserve"
+   inkscape:version="0.48.3.1 r9886"
+   sodipodi:docname="icons32.svg"
+   inkscape:export-filename="/home/oleq/ck/ckeditor-dev/skins/moono/dev/icons32.png"
+   inkscape:export-xdpi="90"
+   inkscape:export-ydpi="90"><metadata
+   id="metadata9"><rdf:RDF><cc:Work
+       rdf:about=""><dc:format>image/svg+xml</dc:format><dc:type
+         rdf:resource="http://purl.org/dc/dcmitype/StillImage" /><dc:title></dc:title></cc:Work></rdf:RDF></metadata><defs
+   id="defs7"><linearGradient
+   inkscape:collect="always"
+   id="linearGradient4352"><stop
+     style="stop-color:#ff4141;stop-opacity:0"
+     offset="0"
+     id="stop4354" /><stop
+     id="stop4362"
+     offset="0.24227905"
+     style="stop-color:#ff4141;stop-opacity:0.78823529;" /><stop
+     id="stop4360"
+     offset="0.73632693"
+     style="stop-color:#ff4141;stop-opacity:0" /><stop
+     style="stop-color:#ff4141;stop-opacity:1"
+     offset="1"
+     id="stop4356" /></linearGradient><linearGradient
+   id="linearGradient4392"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396" /></linearGradient><filter
+   id="filter3224-1-7-1-3"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-70"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-9"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-91"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-53"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-3"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3429"
+   gradientUnits="userSpaceOnUse"
+   x1="72"
+   y1="32"
+   x2="72"
+   y2="47" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3431"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,47.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3437"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-96,49)"
+   x1="136"
+   y1="50"
+   x2="136"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3439"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-16,49)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3441"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-80,49)"
+   x1="88"
+   y1="50"
+   x2="88"
+   y2="63" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3443"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-272,80)"
+   x1="343"
+   y1="50"
+   x2="343"
+   y2="63" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3447"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-16,192.99999)"
+   x1="88"
+   y1="161"
+   x2="88"
+   y2="174" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3451"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1649013,0,0,1.1649013,-386.36445,145.11124)"
+   x1="365"
+   y1="96.073685"
+   x2="365"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3453"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-415.467,94.82271)"
+   x1="365"
+   y1="73.073685"
+   x2="365"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3455"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1673123,0,0,1.1673123,-227.67995,73.95948)"
+   x1="366"
+   y1="48.073685"
+   x2="366"
+   y2="60.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3457"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1111083,0,0,1.1111083,-187.99896,-192.84664)"
+   x1="378"
+   y1="205"
+   x2="378"
+   y2="214" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3459"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(177.99998,89.93748)"
+   x1="246"
+   y1="73.073685"
+   x2="246"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3461"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(169.99998,89.93748)"
+   x1="222"
+   y1="73.073685"
+   x2="222"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3463"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.0131693,0,0,1.0131693,159.31347,88.9358)"
+   x1="197"
+   y1="73.073685"
+   x2="197"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3465"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(153.99998,89.93748)"
+   x1="171"
+   y1="73.073685"
+   x2="171"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3467"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.2458722,0,0,1.1615489,-282.43958,-203.90163)"
+   x1="233"
+   y1="204"
+   x2="233"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3469"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1666672,0,0,1.1723864,-11.00007,112.34331)"
+   x1="126"
+   y1="96.073685"
+   x2="126"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3471"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.1621519,95.65429,77.66723)"
+   x1="124"
+   y1="74.073685"
+   x2="124"
+   y2="82.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3473"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1666666,0,0,1.1666669,-23,112.92042)"
+   x1="54"
+   y1="96.073685"
+   x2="54"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3475"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-112.63459,-273.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3477"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-112.63459,-273.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3479"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1458395,0,0,1.1458395,-25.974994,183.42764)"
+   x1="30"
+   y1="120.07368"
+   x2="30"
+   y2="132.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3481"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.2584059,0,0,1.2584059,-27.9426,202.38775)"
+   x1="54"
+   y1="122.07368"
+   x2="54"
+   y2="130.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3483"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1739937,0,0,1.1739937,-40.36396,212.02902)"
+   x1="150"
+   y1="120.07368"
+   x2="150"
+   y2="132.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3485"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-31.36848,96.23245)"
+   x1="150"
+   y1="97.073685"
+   x2="150"
+   y2="107.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3487"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1666648,0,0,1.1666669,33.00037,112.92706)"
+   x1="198"
+   y1="96.073685"
+   x2="198"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3489"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(96,-204)"
+   x1="136"
+   y1="204"
+   x2="136"
+   y2="220" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3491"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-112,48)"
+   x1="184"
+   y1="50"
+   x2="184"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3493"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(80,48)"
+   x1="216"
+   y1="51.999996"
+   x2="216"
+   y2="59.999996" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3495"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-272,79)"
+   x1="407"
+   y1="51"
+   x2="407"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3497"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-240,78)"
+   x1="407"
+   y1="51"
+   x2="407"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3499"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-80,48)"
+   x1="87"
+   y1="16.999994"
+   x2="87"
+   y2="30.999994" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3501"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1.1111083,0,0,1.1111083,715.999,-192.84664)"
+   x1="378"
+   y1="205"
+   x2="378"
+   y2="214" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3503"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(16,80)"
+   x1="57"
+   y1="83"
+   x2="57"
+   y2="94" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3505"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(48,80)"
+   x1="87"
+   y1="82"
+   x2="87"
+   y2="95" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3507"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,320,80)"
+   x1="87"
+   y1="82"
+   x2="87"
+   y2="95" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3509"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(112,81)"
+   x1="344"
+   y1="82"
+   x2="344"
+   y2="93" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3511"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(112,81)"
+   x1="375"
+   y1="82"
+   x2="375"
+   y2="93" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3513"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.2587978,0,0,1.2587978,-391.22595,101.14297)"
+   x1="340"
+   y1="75.073685"
+   x2="340"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3515"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(48,80)"
+   x1="87"
+   y1="82"
+   x2="87"
+   y2="95" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3517"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(80.11142,79.99998)"
+   x1="87"
+   y1="82"
+   x2="87"
+   y2="95" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3519"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,288,79.99999)"
+   x1="87"
+   y1="82"
+   x2="87"
+   y2="95" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3521"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-16,112)"
+   x1="24"
+   y1="114"
+   x2="24"
+   y2="126" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3523"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-16,112)"
+   x1="216"
+   y1="115"
+   x2="216"
+   y2="126" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3525"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(206,47.99999)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3527"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(15,47.99999)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3529"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(80.18519,49.11111)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3531"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,32,386.0001)"
+   x1="88"
+   y1="161"
+   x2="88"
+   y2="174" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3533"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(0.95906074,0,0,0.83983765,-246.54178,86.44281)"
+   x1="263.14438"
+   y1="53.202732"
+   x2="263.14438"
+   y2="65.97139" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3535"
+   gradientUnits="userSpaceOnUse"
+   x1="324.89481"
+   y1="49.999996"
+   x2="327.98953"
+   y2="61.999996" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3537"
+   gradientUnits="userSpaceOnUse"
+   x1="324.89481"
+   y1="49.999996"
+   x2="327.98953"
+   y2="61.999996" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3543"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1.1111083,0,0,1.1111083,683.999,-192.84664)"
+   x1="378"
+   y1="205"
+   x2="378"
+   y2="214" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3545"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1111083,0,0,1.1111083,-91.99896,-192.84664)"
+   x1="378"
+   y1="205"
+   x2="378"
+   y2="214" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3547"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,351.81481,49.11111)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3549"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1.33333,0,0,1.33333,592.467,94.82271)"
+   x1="365"
+   y1="73.073685"
+   x2="365"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3551"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,480,176)"
+   x1="407.125"
+   y1="113.37494"
+   x2="407.125"
+   y2="126.38035" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3553"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-208,-112.00001)"
+   x1="280"
+   y1="112"
+   x2="280"
+   y2="128" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3555"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(56,80)"
+   x1="57"
+   y1="83"
+   x2="57"
+   y2="94" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3557"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,448,112)"
+   x1="216"
+   y1="115"
+   x2="216"
+   y2="126" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3559"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.1666672,0,0,1.1723864,-107.00007,208.34331)"
+   x1="126"
+   y1="96.073685"
+   x2="126"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3561"
+   gradientUnits="userSpaceOnUse"
+   x1="104"
+   y1="230.99998"
+   x2="104"
+   y2="232.99998" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3563"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(47,47.99999)"
+   x1="120"
+   y1="50"
+   x2="120"
+   y2="62" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3565"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(16,-3)"
+   x1="56"
+   y1="228.23837"
+   x2="56"
+   y2="242.00908" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3567"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,143.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3569"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-112.63459,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3571"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-80.63459,-273.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3573"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-80.63459,-273.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3575"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-79.63459,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3577"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-16.63459,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3579"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,16.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3581"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,175.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3583"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-81.63459,-245.06703)"
+   x1="91"
+   y1="208.11006"
+   x2="91"
+   y2="219.18719" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3585"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,67.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3587"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,208.36541,-272.06703)"
+   x1="91"
+   y1="204"
+   x2="91"
+   y2="216" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3589"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.2681238,0,0,1.2681238,-425.35773,134.96337)"
+   x1="342"
+   y1="97.073685"
+   x2="342"
+   y2="108.07368" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3591"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(32,0)"
+   x1="72"
+   y1="32"
+   x2="72"
+   y2="47" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3593"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-1,0,0,1,208,0)"
+   x1="72"
+   y1="32"
+   x2="72"
+   y2="47" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3595"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(0,-14.00001)"
+   x1="264"
+   y1="114"
+   x2="264"
+   y2="121" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-45"
+   id="linearGradient3597"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-479.467,254.82271)"
+   x1="365"
+   y1="73.073685"
+   x2="365"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3601"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.33333,0,0,1.33333,-479.467,254.82271)"
+   x1="365"
+   y1="73.073685"
+   x2="365"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3605"
+   gradientUnits="userSpaceOnUse"
+   x1="73"
+   y1="321"
+   x2="73"
+   y2="335" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3607"
+   gradientUnits="userSpaceOnUse"
+   x1="69"
+   y1="323"
+   x2="69"
+   y2="333" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3609"
+   gradientUnits="userSpaceOnUse"
+   x1="69"
+   y1="323"
+   x2="69"
+   y2="333" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3667"
+   x1="167.75"
+   y1="32.497749"
+   x2="167.75"
+   y2="46.375"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3671"
+   x1="40.166676"
+   y1="163.16667"
+   x2="40.166676"
+   y2="174.48146"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3673"
+   x1="7.7296576"
+   y1="162.72966"
+   x2="7.7296576"
+   y2="174.83665"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3675"
+   x1="7.7175145"
+   y1="196.31802"
+   x2="7.7175145"
+   y2="202.94867"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3677"
+   x1="40.159454"
+   y1="195.87607"
+   x2="40.159454"
+   y2="203.08347"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3679"
+   x1="328.75046"
+   y1="96.928932"
+   x2="328.75046"
+   y2="111.26538"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient3713"
+   x1="86.009781"
+   y1="129.98354"
+   x2="86.009781"
+   y2="142.15057"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient4491"
+   x1="266.98074"
+   y1="53.301754"
+   x2="266.98074"
+   y2="63.243984"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient4534"
+   x1="45"
+   y1="71.999939"
+   x2="45"
+   y2="79.999939"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(0.21875,0)" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient4540"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(10.21875,0)"
+   x1="45"
+   y1="71.999939"
+   x2="45"
+   y2="79.999939" /><linearGradient
+   id="linearGradient4392-7"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-7" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-6" /></linearGradient><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-7"
+   id="linearGradient4540-8"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="translate(-4.1709228,8.0000007)"
+   x1="45"
+   y1="71.999939"
+   x2="45"
+   y2="79.999939" /><linearGradient
+   id="linearGradient4392-45"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-8" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-68" /></linearGradient><filter
+   id="filter3224-1-7-1"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5"
+     dx="0"
+     dy="1"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-9"
+   id="linearGradient3435-5"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,93.76588,34.31226)"
+   x1="55"
+   y1="49.409008"
+   x2="55"
+   y2="63" /><linearGradient
+   id="linearGradient4392-9"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-2" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-9" /></linearGradient><filter
+   id="filter3224-1-7-1-3-0"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-70-4"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-9-5"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-91-7"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-53-5"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-3-2"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-0"
+   id="linearGradient4300-5"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,294,181.85274)"
+   x1="148"
+   y1="73.073685"
+   x2="148"
+   y2="84.073685" /><linearGradient
+   id="linearGradient4392-0"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-6" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-2" /></linearGradient><filter
+   id="filter3224-1-7-1-3-2"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-70-5"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-9-6"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-91-0"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-53-56"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-3-24"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5619"
+   gradientUnits="userSpaceOnUse"
+   x1="266.98074"
+   y1="53.301754"
+   x2="266.98074"
+   y2="63.243984" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5621"
+   gradientUnits="userSpaceOnUse"
+   x1="86.009781"
+   y1="129.98354"
+   x2="86.009781"
+   y2="142.15057" />
+<linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4352"
+   id="linearGradient5632"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.8181818,0,0,2,-638.27272,-321.74989)"
+   x1="366.95544"
+   y1="335.06354"
+   x2="356.00427"
+   y2="335.08957" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4352"
+   id="linearGradient5639"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(1.8181818,0,0,2,-638.27272,-321.74989)"
+   x1="366.95544"
+   y1="335.06354"
+   x2="356.00427"
+   y2="335.08957" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5672"
+   gradientUnits="userSpaceOnUse"
+   x1="17.949585"
+   y1="577.80402"
+   x2="17.949585"
+   y2="604.75"
+   gradientTransform="translate(1,-367.75001)" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5746"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,-735,-15.74989)"
+   x1="408.47479"
+   y1="113.77696"
+   x2="408.47479"
+   y2="126.90414" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5750"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,295,-185.89727)"
+   x1="148"
+   y1="73.073685"
+   x2="148"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5760"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,94.76588,-333.43775)"
+   x1="55"
+   y1="49.409008"
+   x2="55"
+   y2="63" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-45"
+   id="linearGradient5768"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2.66666,0,0,2.66666,-957.934,141.89553)"
+   x1="365"
+   y1="73.073685"
+   x2="365"
+   y2="84.073685" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-3"
+   id="linearGradient5624-9"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-2,0,0,-2,1022,-175.74999)"
+   x1="472"
+   y1="17"
+   x2="472"
+   y2="31" /><linearGradient
+   id="linearGradient4392-3"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-4" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-1" /></linearGradient><filter
+   id="filter3224-1-7-1-34"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-3"
+     dx="0"
+     dy="1"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-1"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-3"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-9"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-1"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5855"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(-2,0,0,-2,1021,192.00002)"
+   x1="472"
+   y1="17"
+   x2="472"
+   y2="31" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient5906"
+   x1="593.375"
+   y1="-45.500015"
+   x2="593.375"
+   y2="-31.493313"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-2"
+   id="linearGradient5906-9"
+   x1="593.375"
+   y1="-45.500015"
+   x2="593.375"
+   y2="-31.493313"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   id="linearGradient4392-2"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-1" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-7" /></linearGradient><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-2"
+   id="linearGradient5922"
+   x1="593.375"
+   y1="-45.500015"
+   x2="593.375"
+   y2="-31.493313"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   id="linearGradient5924"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop5926" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop5928" /></linearGradient><filter
+   id="filter3224-1-7-1-3-24"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-70-8"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-9-0"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-91-5"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-53-2"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-3-1"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-2"
+   id="linearGradient5936"
+   x1="593.375"
+   y1="-45.500015"
+   x2="593.375"
+   y2="-31.493313"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   id="linearGradient5938"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop5940" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop5942" /></linearGradient><filter
+   id="filter5944"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset5946"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite5948"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood5950"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend5952"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite5954"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-2"
+   id="linearGradient5956"
+   x1="593.375"
+   y1="-45.500015"
+   x2="593.375"
+   y2="-31.493313"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   id="linearGradient5958"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop5960" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop5962" /></linearGradient><filter
+   id="filter5964"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset5966"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite5968"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood5970"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend5972"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite5974"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392-6"
+   id="linearGradient3667-5"
+   x1="167.75"
+   y1="32.497749"
+   x2="167.75"
+   y2="46.375"
+   gradientUnits="userSpaceOnUse" /><linearGradient
+   id="linearGradient4392-6"><stop
+     style="stop-color:#666666;stop-opacity:1;"
+     offset="0"
+     id="stop4394-64" /><stop
+     style="stop-color:#424242;stop-opacity:1;"
+     offset="1"
+     id="stop4396-14" /></linearGradient><filter
+   id="filter3224-1-7-1-3-1"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-70-83"
+     dx="0"
+     dy="0.69999999999999996"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-9-4"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-91-3"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-53-3"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-3-7"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><linearGradient
+   y2="46.375"
+   x2="167.75"
+   y1="32.497749"
+   x1="167.75"
+   gradientUnits="userSpaceOnUse"
+   id="linearGradient6101"
+   xlink:href="#linearGradient4392-6"
+   inkscape:collect="always" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient6155"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,93.76588,34.31226)"
+   x1="55"
+   y1="49.409008"
+   x2="55"
+   y2="63" /><linearGradient
+   inkscape:collect="always"
+   xlink:href="#linearGradient4392"
+   id="linearGradient6173"
+   gradientUnits="userSpaceOnUse"
+   gradientTransform="matrix(2,0,0,2,-32,386.0001)"
+   x1="88"
+   y1="161"
+   x2="88"
+   y2="174" /><filter
+   id="filter3224-1-7-1-5-0"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-5-0-2"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7-5"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9-8"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7-0"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4-3"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7-9"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-5-0-8"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7-6"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9-3"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7-1"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4-1"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7-6"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-5-0-8-5"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7-6-5"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9-3-2"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7-1-1"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4-1-6"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7-6-3"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-5-0-8-7"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7-6-9"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9-3-0"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7-1-3"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4-1-1"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7-6-8"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-5-0-8-7-8"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-6-7-6-9-8"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-0-9-3-0-9"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-6-7-1-3-0"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-6-4-1-1-8"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-55-7-6-8-6"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-7"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-5"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-56"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-7"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-0"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-9"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter><filter
+   id="filter3224-1-7-1-7-9"
+   inkscape:label="Inner Shadow"
+   inkscape:menu="Shadows and Glows"
+   inkscape:menu-tooltip="Adds a colorizable drop shadow inside"
+   color-interpolation-filters="sRGB"
+   width="1"
+   height="1"
+   y="0"
+   x="0"><feOffset
+     id="feOffset3228-5-5-5-5-8"
+     dx="0"
+     dy="1.2"
+     result="result11" /><feComposite
+     id="feComposite3230-2-4-1-56-4"
+     in2="result11"
+     result="result6"
+     in="SourceGraphic"
+     operator="in" /><feFlood
+     id="feFlood3232-7-3-4-7-8"
+     result="result10"
+     in="result6"
+     flood-opacity="1"
+     flood-color="rgb(34,34,34)" /><feBlend
+     id="feBlend3234-6-3-5-0-4"
+     in2="result10"
+     mode="normal"
+     in="result6"
+     result="result12" /><feComposite
+     id="feComposite3236-1-3-5-9-9"
+     in2="SourceGraphic"
+     result="result2"
+     operator="in" /></filter></defs><sodipodi:namedview
+   pagecolor="#d4a8a8"
+   bordercolor="#666666"
+   borderopacity="1"
+   objecttolerance="10"
+   gridtolerance="10"
+   guidetolerance="10"
+   inkscape:pageopacity="0"
+   inkscape:pageshadow="2"
+   inkscape:window-width="1466"
+   inkscape:window-height="925"
+   id="namedview5"
+   showgrid="true"
+   inkscape:showpageshadow="false"
+   inkscape:zoom="4"
+   inkscape:cx="212.27233"
+   inkscape:cy="102.59658"
+   inkscape:window-x="97"
+   inkscape:window-y="49"
+   inkscape:window-maximized="0"
+   inkscape:current-layer="layer1"
+   fit-margin-top="0"
+   fit-margin-left="0"
+   fit-margin-bottom="32"
+   fit-margin-right="0"
+   showguides="true"
+   inkscape:guide-bbox="true"><inkscape:grid
+     type="xygrid"
+     id="grid2986"
+     units="px"
+     empspacing="16"
+     visible="true"
+     enabled="true"
+     snapvisiblegridlinesonly="true"
+     spacingx="1px"
+     spacingy="1px"
+     dotted="false"
+     originx="0px"
+     originy="0px" /></sodipodi:namedview>
+
+
+<g
+   inkscape:groupmode="layer"
+   id="layer2"
+   inkscape:label="Dark background"
+   style="display:inline"
+   transform="translate(-1,367.74999)"
+   sodipodi:insensitive="true"><rect
+     style="fill:#e9afaf;fill-opacity:1;stroke:none"
+     id="rect6406"
+     width="992"
+     height="736"
+     x="1"
+     y="-367.75" /></g><g
+   inkscape:groupmode="layer"
+   id="layer1"
+   inkscape:label="Shadow"
+   style="display:inline"
+   transform="translate(-1,367.74999)"
+   sodipodi:insensitive="true"><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 135,-363.75001 0,2 20,0 0,-2 z m 320.1875,2 c -0.107,0.30896 -0.1874,0.65374 -0.1874,1 0,1.66198 1.338,3 3,3 l 14,0 c 1.662,0 3,-1.33802 3,-3 0,-0.34626 -0.0806,-0.69104 -0.1874,-1 -0.40652,1.17402 -1.49676,2 -2.8125,2 l -14,0 c -1.31574,0 -2.40598,-0.82598 -2.8125,-2 z m 3.8125,8 c -1.108,0 -2,0.89198 -2,2 l 0,2 c 0,-1.10802 0.892,-2 2,-2 l 12,0 c 1.108,0 2,0.89198 2,2 l 0,-2 c 0,-1.10802 -0.892,-2 -2,-2 z m 3,4 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 6,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m -325,2 0,2 4,0 4,0 8,0 0,-2 z m 325,2 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 6,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m -331,1.875 0,2 6,6.125 18,0 c 2.216,0 4,-1.78402 4,-4 l 0,-2 c 0,2.21598 -1.784,4 -4,4 l -2,0 -8,0 -4,0 -4,0 z m 320,0.125 0,2 c 0,1.108 0.892,2 2,2 l 4,0 0,-2 -4,0 c -1.108,0 -2,-0.892 -2,-2 z m 28,0 c 0,1.108 -0.892,2 -2,2 l -4,0 0,2 4,0 c 1.108,0 2,-0.892 2,-2 z m -20,6 0,2 12,0 0,-2 z m -449.8125,39.625 c -0.0642,0.21882 -0.125,0.4551 -0.125,0.75 0,4.04252 2.61966,7.87564 5.6875,11 l 0.875,-1.125 c -3.10738,-2.95582 -5.91722,-6.6716 -6.4375,-10.625 z m 19.75,0.1875 c -0.50602,3.8783 -3.30914,7.52876 -6.375,10.4375 l 0.9375,1.0625 c 2.9932,-3.06606 5.5,-6.8215 5.5,-10.75 0,-0.27964 -0.0162,-0.53042 -0.0625,-0.75 z m 423.4375,11.1875 -1.375,1 14,10 0,-2 z m 89.25,0 -12.625,9 0,2 14,-10 z m 64,0 -12.625,9 0,2 14,-10 z m 38.75,0 -1.375,1 14,10 0,-2 z m -625.3125,2.1875 c -1.62212,1.25216 -3.10068,2.20618 -4.0625,2.8125 0.44064,0.36242 0.78162,0.82428 1.0625,1.3125 0.87208,-0.57004 1.85156,-1.23848 3,-2.125 1.21634,0.9422 2.26918,1.64192 3.1875,2.25 0.26354,-0.49164 0.57806,-0.93856 1,-1.3125 -1.01912,-0.64118 -2.52302,-1.64818 -4.1875,-2.9375 z m 445.9375,0.125 0,2 c 6.83332,0 11.23112,2.46082 14,6.6875 0,-0.74354 -0.048,-1.4538 -0.125,-2.125 -2.77424,-4.13656 -7.1214,-6.5625 -13.875,-6.5625 z m 64,0 c -6.7536,0 -11.10076,2.42596 -13.875,6.5625 -0.077,0.6712 -0.125,1.38146 -0.125,2.125 2.76888,-4.22666 7.16668,-6.6875 14,-6.6875 z m 64,0 c -6.7536,0 -11.10076,2.42596 -13.875,6.5625 -0.077,0.6712 -0.125,1.38146 -0.125,2.125 2.76888,-4.22666 7.16668,-6.6875 14,-6.6875 z m 64,0 0,2 c 6.83332,0 11.23112,2.46082 14,6.6875 0,-0.74354 -0.048,-1.4538 -0.125,-2.125 -2.77424,-4.13656 -7.1214,-6.5625 -13.875,-6.5625 z m -645.3125,3.875 c -1.37544,0 -2.4375,1.03016 -2.4375,2.3125 0,0.36992 0.0912,0.69074 0.25,1 0.39166,-0.76286 1.20882,-1.3125 2.1875,-1.3125 0.96738,0 1.77228,0.56398 2.1875,1.3125 0.1752,-0.31572 0.3125,-0.61956 0.3125,-1 0,-1.28234 -1.12458,-2.3125 -2.5,-2.3125 z m 15,0 c -1.37544,0 -2.5,1.03016 -2.5,2.3125 0,0.38044 0.1374,0.68428 0.3125,1 0.4152,-0.74852 1.2201,-1.3125 2.1875,-1.3125 0.97868,0 1.79584,0.54964 2.1875,1.3125 0.1588,-0.30926 0.25,-0.63008 0.25,-1 0,-1.28234 -1.06208,-2.3125 -2.4375,-2.3125 z m -10.125,3.3125 c -0.49264,2.08248 -2.49068,3.625 -4.875,3.625 -2.36162,0 -4.30912,-1.51004 -4.8125,-3.5625 -0.0652,0.3035 -0.125,0.61692 -0.125,0.9375 0,2.56468 2.1866,4.625 4.9375,4.625 2.7509,0 5,-2.06032 5,-4.625 0,-0.34672 -0.0478,-0.67348 -0.125,-1 z m 5.25,0.0625 c -0.0718,0.31234 -0.125,0.60588 -0.125,0.9375 0,2.56468 2.2491,4.625 5,4.625 2.7509,0 4.9375,-2.06032 4.9375,-4.625 0,-0.32058 -0.06,-0.63394 -0.125,-0.9375 -0.50338,2.05246 -2.45088,3.5625 -4.8125,3.5625 -2.36162,0 -4.35858,-1.51004 -4.875,-3.5625 z M 14,-233.75001 c -3.866,0 -7,3.134 -7,7 0,0.33546 0.0161,0.67712 0.0625,1 0.48018,-3.398 3.40696,-6 6.9375,-6 3.46616,0 6.31682,2.50512 6.875,5.8125 0.0312,-0.26896 0.125,-0.53508 0.125,-0.8125 0,-3.866 -3.134,-7 -7,-7 z m 10.9375,7.875 c -0.1766,2.1855 -0.98174,4.17042 -2.25,5.8125 l 0.75,0.75 c 0.9463,-1.61274 1.5625,-3.429 1.5625,-5.4375 0,-0.3797 -0.0251,-0.75522 -0.0625,-1.125 z m -21.875,0.25 c -0.0228,0.2897 -0.0625,0.57942 -0.0625,0.875 0,6.07512 4.92486,11 11,11 2.0945,0 4.02114,-0.60892 5.6875,-1.625 l 7.0625,7.0625 c 0.78348,0.78346 2.02902,0.78346 2.8125,0 0.6625,-0.6625 0.7079,-1.65918 0.25,-2.4375 -0.0836,0.1422 -0.129,0.31652 -0.25,0.4375 -0.78348,0.78346 -2.02902,0.78346 -2.8125,0 l -7.0625,-7.0625 c -1.66636,1.01608 -3.593,1.625 -5.6875,1.625 -5.69544,0 -10.3742,-4.3282 -10.9375,-9.875 z m 666.9375,51.875 -1,2 0,2 2,-4 z m -1,4 -1,0 -9,18 1,0 8,-16 1,0 z m -596,0 c -1.108,0 -2,0.89198 -2,2 l 0,2 c 0,-1.10802 0.892,-2 2,-2 l 16,0 c 1.108,0 2,0.89198 2,2 l 0,-2 c 0,-1.10802 -0.892,-2 -2,-2 z m 72,0 c -0.41421,0 -0.84659,0.0217 -1.25,0.0625 -0.25156,0.0318 -0.50463,0.0748 -0.75,0.125 -4.55683,0.93246 -8,4.98 -8,9.8125 0,0.34518 0.0284,0.66382 0.0625,1 0.5121,-5.04256 4.75984,-9 9.9375,-9 5.17766,0 9.4254,3.95744 9.9375,9 0.0341,-0.33618 0.0625,-0.65482 0.0625,-1 0,-4.8325 -3.44317,-8.88004 -8,-9.8125 -0.24537,-0.0502 -0.49844,-0.0932 -0.75,-0.125 -0.0805,-0.008 -0.16906,0.006 -0.25,0 -0.33617,-0.0342 -0.65482,-0.0625 -1,-0.0625 z m 116,0 c -1.108,0 -2,0.892 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 l 1,0 4,0 19,0 c 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 64.0625,0 c -1.108,0 -2,0.892 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 l 19,0 4,0 1,0 c 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 63.9375,2 c -1.108,0 -2,2 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 l 24,0 c 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 64,0 c -1.108,0 -2,2 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 l 24,0 c 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 192,-2 c -1.108,0 -2,0.89198 -2,2 l 0,2 c 0,-1.10802 0.892,-2 2,-2 l 1,0 7,0 1,0 7,0 2,0 1,-2 -3,0 -8,0 z m 26,0.5625 0,1.4375 1.4375,0 c -0.3537,-0.60466 -0.83286,-1.0838 -1.4375,-1.4375 z m -474,1.4375 c -1.108,0 -2,0.89198 -2,2 l 0,2 c 0,-1.10802 0.892,-2 2,-2 l 3,0 4,0 17,0 c 1.108,0 2,0.89198 2,2 l 0,-2 c 0,-1.10802 -0.892,-2 -2,-2 z m -192,2 0,2 2,0 6,0 4,0 10,0 2,0 0,-2 z m 257,0 c -0.554,0 -1,0.446 -1,1 0,0.48474 0.0888,1.06892 1.125,1 l 0.875,0 0,-2 -0.875,0 c -0.0514,0.004 -0.0782,-3e-4 -0.125,0 z m 3,0 0,2 1,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 79.0625,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 1,0 0,-2 z m 3,0 0,2 0.875,0 c 1.0362,0.069 1.125,-0.51526 1.125,-1 0,-0.554 -0.446,-1 -1,-1 -0.0468,-3e-4 -0.0736,0.004 -0.125,0 z m 235.9375,0 c -0.37224,0 -0.70936,0.0608 -1.0625,0.125 -1.0136,0.2827 -1.85708,0.97964 -2.375,1.875 l 3.4375,0 20,0 3.4375,0 c -0.51792,-0.89536 -1.3614,-1.5923 -2.375,-1.875 -0.33786,-0.0942 -0.69156,-0.125 -1.0625,-0.125 z m 88,0 0,2 2,0 0,-2 z m -471,2 c -0.554,0 -1,0.44598 -1,1 0.1614,1.15406 0.6222,0.99248 2,1 l 0,-2 -0.875,0 c -0.0526,-8.6e-4 -0.077,0.002 -0.125,0 z m 3,0 0,2 1,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -1.554,-1 -1,-1 z m -115,1 -9,9 -2.8125,-2.8125 -1.875,-1.875 -1,1 2.875,2.875 2.8125,2.8125 10,-10 z m -81,1 0,2 6,0 0,-2 z m 394,2 6,8 6,-8 -1.5,0 -4.5,6 -4.5,-6 z m 52,0 6,8 6,-8 -1.5,0 -4.5,6 -4.5,-6 z m 218,-2 0,2 2,0 0,-2 z m -654,2 0,2 10,0 0,-2 z m 122.125,1 c -0.0574,0.33316 -0.125,0.65048 -0.125,1 0,3.3137 2.6863,6 6,6 3.3137,0 6,-2.6863 6,-6 0,-0.34952 -0.0676,-0.66684 -0.125,-1 -0.48643,2.82528 -2.91083,5 -5.875,5 -2.96417,0 -5.38857,-2.17472 -5.875,-5 z m -6.0625,0.25 c -0.015,0.24518 -0.0625,0.50106 -0.0625,0.75 0,6.6274 5.37258,12 12,12 6.62742,0 12,-5.3726 12,-12 0,-0.24894 -0.0476,-0.50482 -0.0625,-0.75 -0.54764,5.39254 -4.65021,9.68238 -9.9375,10.5625 -0.32549,0.0666 -0.66383,0.0908 -1,0.125 -0.32478,0.0264 -0.66842,0.0624 -1,0.0624 -0.33158,0 -0.67522,-0.0364 -1,-0.0624 -0.0828,-0.008 -0.16786,0.01 -0.25,0 -0.25513,-0.026 -0.49985,-0.0834 -0.75,-0.125 -5.28729,-0.88012 -9.38986,-5.16996 -9.9375,-10.5625 z m 379.9375,0.75 0,2 c 0,3.324 2.676,6 6,6 l 20,0 c 3.324,0 6,-2.676 6,-6 l 0,-2 c 0,3.324 -2.676,6 -6,6 l -20,0 c -3.324,0 -6,-2.676 -6,-6 z m 64,0 0,2 c 0,3.324 2.676,6 6,6 l 20,0 c 3.324,0 6,-2.676 6,-6 l 0,-2 c 0,3.324 -2.676,6 -6,6 l -20,0 c -3.324,0 -6,-2.676 -6,-6 z m 94,0 0,2 2,0 0,-2 z m -384,0.8125 -9.1875,9.1875 1.6875,0 c 0.0268,-0.0356 0.0298,-0.0924 0.0624,-0.125 l 7.4375,-7.375 0,-1.6875 z m 36.0625,0 0,1.6875 7.4375,7.375 c 0.0326,0.0326 0.0358,0.0894 0.0624,0.125 l 1.6875,0 -9.1875,-9.1875 z M 7,-155.75001 l 0,2 6,0 0,-2 z m 643.3125,1.9375 c -0.1034,0.036 -0.1964,0.0624 -0.3125,0.0624 l -1,0 -2,0 -1,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 3,0 1,0 c 0.554,0 1,-0.44602 1,-1 0,-0.3682 -0.32938,-0.8876 -0.625,-1.0625 -0.014,-0.008 -0.0494,0.006 -0.0624,0 z M 17,-153.75001 l 0,2 10,0 0,-2 z m 52,0 0,2 c 0,2.1814 1.8186,4 4,4 l 16,0 c 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 l -16,0 c -2.1814,0 -4,-1.8186 -4,-4 z m 193,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 4,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.24356,-1.0562 -1,-1 l -1,0 -2,0 z m 81.625,0 c -0.38762,0.1434 -0.5625,0.5845 -0.5625,1 0,0.554 0.446,1 1,1 l 4,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 l -1,0 -2,0 -1,0 c -0.189,-0.014 -0.3083,-0.0478 -0.4375,0 z m 41.375,2 0,2 c 0,2.1814 1.8186,4 4,4 l 24,0 c 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 l -24,0 c -2.1814,0 -4,-1.8186 -4,-4 z m 64,0 0,2 c 0,2.1814 1.8186,4 4,4 l 24,0 c 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 l -24,0 c -2.1814,0 -4,-1.8186 -4,-4 z m 192,-2 0,2 c 0,2.18138 1.8186,4 4,4 l 8,0 1,-2 -9,0 c -2.1814,0 -4,-1.81862 -4,-4 z m 30,0 0,2 1.4375,0 0.5625,0 0,-2 z m -384,1.25 -4.6875,4.75 1.25,0 3.4375,-3.5 z m 36.0625,0 0,1.25 3.4375,3.5 1.25,0 z m -320.0625,0.75 0,2 c 0,1.10798 0.892,2 2,2 l 24,0 c 1.108,0 2,-0.89202 2,-2 l 0,-2 c 0,1.10798 -0.892,2 -2,2 l -24,0 c -1.108,0 -2,-0.89202 -2,-2 z m 190,0 0,2 c 0,2.1814 1.8186,4 4,4 l 24,0 c 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 l -24,0 c -2.1814,0 -4,-1.8186 -4,-4 z m 7,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 4,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.23842,-1 -1,-1 l -1,0 -2,0 z m 57,2 0,2 c 0,2.18138 1.8186,4 4,4 l 24,0 c 2.1814,0 4,-1.81862 4,-4 l 0,-0.75 c 0.0656,-0.1786 0.0426,-0.3443 0,-0.5 l 0,-0.75 c 0,2.18138 -1.8186,4 -4,4 l -1.4375,0 -1.25,0 -2.8125,0 -1.6875,0 -6.75,0 -10.0625,0 c -2.1814,0 -4,-1.81862 -4,-4 z m 64.0625,0 0,0.75 c -0.0426,0.1558 -0.0656,0.3214 0,0.5 l 0,0.75 c 0,2.1814 1.8186,4 4,4 l 24,0 c 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 l -14.0625,0 -2.75,0 -1.6875,0 -2.8125,0 -1.25,0 -1.4375,0 c -2.1814,0 -4,-1.8186 -4,-4 z m 336.9375,0 -3,6 -3,0 -1,2 4,0 3,-6 3,0 0,-2 -2,0 z m 5,0 0,2 2,0 0,-2 z m 4,0 0,2 2,0 0,-2 z m 4,0 0,1.4375 c 0.60464,-0.35372 1.0838,-0.83286 1.4375,-1.4375 z m -391,44 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 5,0 0,-2 z m 127.9375,0 -0.1874,0.6875 -6,0 -4.8125,17.3125 -5.4375,0 -0.5625,2 6,0 4.8125,-17.3125 6,0 0.625,-2.6875 -0.4375,0 z m -318.375,0.0624 -0.5,1.9375 -3.1875,0 -4.125,16.0625 0.5,0 3.625,-14.0625 3.1875,0 1,-3.9375 z m 300.625,0.625 -0.4375,2 5.4375,0 0.5625,-2 z m -374.0625,1.3126 c -0.43368,0.0254 -0.84056,0.0744 -1.1875,0.125 l 0,2 c 0.34694,-0.0506 0.75382,-0.0996 1.1875,-0.125 0.43368,-0.0252 0.84524,2e-5 1.25,0 0.49152,2e-5 0.9749,0.049 1.4375,0.125 0.46258,0.0506 0.84056,0.1724 1.1875,0.375 0.34694,0.1772 0.61012,0.39556 0.8125,0.75 0.0506,0.0822 0.0862,0.21168 0.125,0.3125 0.1106,-0.29132 0.1875,-0.58052 0.1875,-0.9375 0,-0.55698 -0.10998,-1.04584 -0.3125,-1.375 -0.20238,-0.35444 -0.46556,-0.5728 -0.8125,-0.75 -0.34694,-0.2026 -0.72492,-0.3244 -1.1875,-0.375 -0.4626,-0.076 -0.94598,-0.125 -1.4375,-0.125 -0.40476,2e-5 -0.81632,-0.0252 -1.25,0 z m 62.25,0 -0.5,2 2.6875,0 0.5,-2 z m 208.625,1 c 0,0.554 -0.446,1 -1,1 l -1,0 -4,0 0,2 5,0 c 0.554,0 1,-0.446 1,-1 z m -260.75,2.0625 c -0.126,0.73254 -0.4229,1.38816 -0.875,2 -0.60716,0.86082 -1.39668,1.55616 -2.4375,2.0625 0.67696,0.21642 1.24742,0.47408 1.75,0.75 0.24546,-0.2493 0.48512,-0.52556 0.6875,-0.8125 0.63606,-0.8608 0.93748,-1.8235 0.9375,-2.9375 0,-0.3671 -0.001,-0.69918 -0.0625,-1.0625 z m 298.9375,0.1874 c -0.38458,0.86222 -0.2642,1.92328 0.4375,2.625 l 3.0625,3.0625 1,-1 -4.0625,-4.0625 c -0.1918,-0.1918 -0.32686,-0.3914 -0.4375,-0.625 z m 15.5625,0 c -0.1106,0.2336 -0.24574,0.43322 -0.4375,0.625 l -4.0625,4.0626 1,1 3.0625,-3.0625 c 0.7017,-0.70172 0.82208,-1.76278 0.4375,-2.625 z m -61.75,1.75 0,2 c 0,0.554 0.446,1 1,1 l 6,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 l -5,0 -1,0 c -0.554,0 -1,-0.446 -1,-1 z m -17.8125,0.25 c -0.38458,0.86222 -0.2642,1.92328 0.4375,2.625 l 3.0625,3.0625 1,-1 -4.0625,-4.0625 c -0.1918,-0.1918 -0.32686,-0.3914 -0.4375,-0.625 z m 15.5625,0 c -0.1106,0.2336 -0.24574,0.43322 -0.4375,0.625 l -4.0625,4.0626 1,1 3.0625,-3.0625 c 0.7017,-0.70172 0.82208,-1.76278 0.4375,-2.625 z m -139.75,3.6876 0,2 c 0,0 0.1636,2.5764 0.4375,3.6875 0.27388,1.11108 0.71772,2.09218 1.375,2.875 0.6573,0.7828 1.52952,1.3832 2.625,1.8125 1.12288,0.40402 2.48174,0.5625 4.125,0.5625 1.6706,0 3.06462,-0.1584 4.1875,-0.5625 1.12286,-0.4293 2.0653,-1.0297 2.75,-1.8125 0.68466,-0.78282 1.1636,-1.76392 1.4375,-2.875 0.27394,-1.1111 0.37498,-2.3239 0.375,-3.6875 l 0,-2 c -2e-5,1.3636 -0.10106,2.5764 -0.375,3.6875 -0.2739,1.11108 -0.75284,2.09218 -1.4375,2.875 -0.6847,0.7828 -1.62714,1.3832 -2.75,1.8125 -1.12288,0.4041 -2.5169,0.5625 -4.1875,0.5625 -1.64326,0 -3.00212,-0.1584 -4.125,-0.5625 -1.09548,-0.4293 -1.9677,-1.0297 -2.625,-1.8125 -0.65728,-0.78282 -1.10112,-1.76392 -1.375,-2.875 -0.2739,-1.1111 -0.4375,-2.3239 -0.4375,-3.6875 z m -122.0625,0.4375 0,2 2.875,0 c 1.38776,2e-5 2.44046,0.30616 3.25,0.8125 0.58546,0.3359 0.9506,0.84108 1.125,1.5 0.0826,-0.31614 0.125,-0.66204 0.125,-1.0625 0,-1.1393 -0.41156,-1.95646 -1.25,-2.4375 -0.80954,-0.50634 -1.86224,-0.81248 -3.25,-0.8125 z m 318.0625,1.875 -4.125,4.0625 c -0.90654,0.90654 -2.34346,0.90654 -3.25,0 -0.20484,-0.20484 -0.32524,-0.4358 -0.4375,-0.6875 -0.41236,0.8707 -0.27728,1.97272 0.4375,2.6875 0.90654,0.90654 2.34346,0.90654 3.25,0 l 4.125,-4.0625 4.0625,4.0625 c 0.90654,0.90654 2.34346,0.90654 3.25,0 0.71478,-0.71478 0.84986,-1.8168 0.4375,-2.6875 -0.1122,0.2517 -0.23266,0.48266 -0.4375,0.6875 -0.90654,0.90654 -2.34346,0.90654 -3.25,0 z m -64,2 -4.125,4.0625 c -0.90654,0.90654 -2.34346,0.90654 -3.25,0 -0.20484,-0.20484 -0.32524,-0.4358 -0.4375,-0.6875 -0.41236,0.8707 -0.27728,1.97272 0.4375,2.6875 0.90654,0.90654 2.34346,0.90654 3.25,0 l 4.125,-4.0625 4.0625,4.0625 c 0.90654,0.90654 2.34346,0.90654 3.25,0 0.71478,-0.71478 0.84986,-1.8168 0.4375,-2.6875 -0.1122,0.2517 -0.23266,0.48266 -0.4375,0.6875 -0.90654,0.90654 -2.34346,0.90654 -3.25,0 z m -241.5,0.5625 c -0.1118,0.896 -0.365,1.7007 -0.75,2.375 -0.54934,0.93676 -1.29592,1.66768 -2.25,2.25 -0.9252,0.557 -2.01146,0.99682 -3.3125,1.25 -1.27214,0.2279 -2.6505,0.3125 -4.125,0.3125 l -7.5,0 0,2 7.5,0 c 1.4745,0 2.85286,-0.0846 4.125,-0.3125 1.30104,-0.25318 2.3873,-0.693 3.3125,-1.25 0.95408,-0.58232 1.70066,-1.31324 2.25,-2.25 0.5493,-0.96208 0.81248,-2.1447 0.8125,-3.5625 0,-0.27216 -0.0207,-0.54564 -0.0625,-0.8125 z m 316.5,0.1874 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.48562,1.20574 1,1 l 5,0 0,-2 z m 59.5,1.3125 -1,0.9375 2.875,2.9375 0.9375,-1 z m 9.625,0 -2.875,2.875 1,1 2.875,-2.9375 z M 351,-86.75001 c 0,0.554 -0.446,1 -1,1 l -1,0 -4,0 0,2 5,0 c 0.554,0 1,-0.446 1,-1 z m -266.5625,1.0625 -0.5,1.9375 -10.6875,0 -0.5625,2 11.25,0 1,-3.9375 z M 388,-83.75001 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m 20.25,0.1874 -3.8125,3.9375 -1,-1 -0.9375,1 1.9375,2 3.8125,-3.9375 3.9375,3.9375 1.9375,-2 -1,-1 -0.9375,1 z m -65.25,0.8125 0,2 c 0,0.554 0.446,1 1,1 l 6,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 l -5,0 -1,0 c -0.554,0 -1,-0.446 -1,-1 z m -207,1 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 20,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m -128,42 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 1,0 0,-2 z m 8,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 54,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 20,0 c 0,0 -1,0.446 -1,1 0,0.48474 1.19869,0.90706 1.125,1 l 0.875,0 0,-2 -0.875,0 z m 56,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m 50,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m 723,0 0,2 2,0 0,-2 z m 54,0 0,2 2,0 0,-2 z m -709,2 c -0.55228,0 -1,0.4477 -1,1 0,0.41422 0.26608,0.7857 0.625,0.9375 0.1196,0.0506 0.23694,0.0624 0.375,0.0624 0.55228,0 1,-0.44772 1,-1 0,-0.5523 -0.44772,-1 -1,-1 z m 4,0 c -0.138,0 -0.25536,0.012 -0.375,0.0624 -0.35892,0.1518 -0.625,0.52328 -0.625,0.9375 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.5523 -0.44772,-1 -1,-1 z m 8,0 c -0.554,0 -1,0.4113 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 4,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.5262 -0.446,-0.9375 -1,-0.9375 z m 74,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -4,0 -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m -18,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -4,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m 82,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -4,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -8,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -1.554,0.9375 -1,0.9375 l -6,0 -4,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 54,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 4,0 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.52618 -0.446,-0.9375 -1,-0.9375 z m 18,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 171,0 0,2 14,0 0,-2 z m 67.75,0 0,2 16.1875,0 0,-2 z m 70.25,0 0,2 14,0 0,-2 z m 54,0 0,2 24,0 0,-2 z m 86,0 0,2 2,0 0,-2 z m 54,0 0,2 2,0 0,-2 z m -843.875,1 c -0.0822,0.31952 -0.125,0.65482 -0.125,1 0,2.20912 1.79086,4 4,4 2.20914,0 4,-1.79088 4,-4 0,-0.34518 -0.0428,-0.68048 -0.125,-1 -0.44393,1.7254 -2.01104,3 -3.875,3 -1.86396,0 -3.43107,-1.2746 -3.875,-3 z m 80,0 c -0.0822,0.31952 -0.125,0.65482 -0.125,1 0,2.20912 1.79086,4 4,4 2.20914,0 4,-1.79088 4,-4 0,-0.34518 -0.0428,-0.68048 -0.125,-1 -0.44392,1.7254 -2.01104,3 -3.875,3 -1.86396,0 -3.43108,-1.2746 -3.875,-3 z m -197.125,1 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 54,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 76,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m 50,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 z m 715.125,1 c -0.0574,0.33316 -0.125,0.65048 -0.125,1 0,3.3137 2.6863,6 6,6 l 0,-2 c -2.96418,0 -5.38856,-2.17472 -5.875,-5 z m 54,0 c -0.0574,0.33316 -0.125,0.65048 -0.125,1 0,3.3137 2.6863,6 6,6 l 0,-2 c -2.96418,0 -5.38856,-2.17472 -5.875,-5 z m -448.25,0.125 c -0.079,0.33192 -0.125,0.66 -0.125,1 0,2.4908 2.23904,4.50914 5.0625,4.625 0.22818,-0.7101 0.4048,-1.36952 0.5,-2 -0.0876,0.002 -0.1594,0 -0.25,0 -2.55268,0 -4.66902,-1.5407 -5.1875,-3.625 z m 16,0 c -0.079,0.33 -0.125,0.66 -0.125,1 0,2.49082 2.23904,4.50914 5.0625,4.625 0.22758,-0.70226 0.4048,-1.37798 0.5,-2 -0.093,0.002 -0.154,0 -0.25,0 -2.55268,0 -4.66902,-1.5407 -5.1875,-3.625 z m -5.5625,0.6875 c -0.65798,6.08074 -4.77536,9.8842 -7.875,11.4375 -0.71906,0.92964 -1.60386,1.86798 -2.6875,2.8125 2.66666,0 10.625,-4.6403 10.625,-13.9375 0,-0.1078 -0.0544,-0.20508 -0.0624,-0.3125 z m 16,0 c -0.65144,6.07564 -4.76304,9.8376 -7.875,11.375 -0.71932,0.92592 -1.60162,1.86602 -2.6875,2.8125 2.74932,0 10.625,-4.57778 10.625,-13.875 0,-0.1078 -0.0544,-0.20528 -0.0624,-0.3125 z M 276,-33.75001 c -0.554,0 -1,0.4113 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.5262 -0.446,-0.9375 -1,-0.9375 z m 70,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 52,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 58,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.52618 -0.446,-0.9375 -1,-0.9375 z m -447,1 0,2 c 0,0.55398 0.446,1 1,1 0.554,0 1,-0.44602 1,-1 l 0,-2 c 0,0.55398 -0.446,1 -1,1 -0.554,0 -1,-0.44602 -1,-1 z m 82,0 0,2 c 0,0.55398 0.446,1 1,1 0.554,0 1,-0.44602 1,-1 l 0,-2 c 0,0.55398 -0.446,1 -1,1 -0.554,0 -1,-0.44602 -1,-1 z m 554,1 0,2 18,0 4,0 0,-2 z m 130,0 0,2 4,0 18,0 0,-2 z m 62,0 0,2 24,0 0,-2 z m -128.3125,0.0624 0,2 4.0625,0 16.1875,0 4.0625,0 0,-2 z m -448.4375,1.9376 -1.25,0.9375 0,0.125 4,2.9375 0,-2 z m 2.75,2 5,0 c 0.1386,0 0.25528,-0.016 0.375,-0.0624 0.35916,-0.1404 0.625,-0.48036 0.625,-0.875 l 0,-0.125 c 0,-0.1316 -0.012,-0.26244 -0.0624,-0.375 -0.1514,-0.33766 -0.522,-0.5625 -0.9375,-0.5625 l -5,0 0,2 z m 13,-2 c -0.554,0 -1,0.4113 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 4,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.5262 -0.446,-0.9375 -1,-0.9375 z m 74,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -4,0 -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m -18.25,0 1.25,0.9375 0,0.125 -4,2.9375 0,-2 z m -2.75,2 -5,0 c -0.55274,0 -1,-0.36074 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.44726,-0.9375 1,-0.9375 l 5,0 z m 85.1875,-2 c 0.5787,0 1.0625,0.4113 1.0625,0.9375 l 0,0.125 c 0,0.8681 -0.4838,0.9375 -1.0625,0.9375 l -5.1875,0 0,-2 z m -5.1875,2 0,2 -4.1875,-2.9375 0,-0.125 1.3125,-0.9375 z m -11,-2 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -1.554,0.9375 -1,0.9375 l -6,0 -4,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 54,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 4,0 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.52618 -0.446,-0.9375 -1,-0.9375 z m 18,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 5,0 0,-2 z m 5,2 0,2 4,-2.9375 0,-0.125 -1.25,-0.9375 z m 431,-1 -5,5 0,2 6,-6 z m 78,0 -1,1 6,6 0,-2 z m -978,3 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 3,0 0,-2 z m 10,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 54,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 18,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 3,0 0,-2 z m 58,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 50,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 80,0 c -0.554,0 -1,0.4113 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.5262 -0.446,-0.9375 -1,-0.9375 z m 70,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 52,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -6,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 58,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 6,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.52618 -0.446,-0.9375 -1,-0.9375 z m 189,0 0,2 18,0 0,-2 z m 134,0 0,2 18,0 0,-2 z m 58,0 0,2 24,0 0,-2 z m -124.25,0.125 0,2 16.1875,0 0,-2 z M 11,-22.75001 c 0,0.1386 -0.0121,0.2551 -0.0625,0.375 -0.101,0.27824 -0.30814,0.4805 -0.5625,0.5625 -0.1198,0.0504 -0.2364,0.0624 -0.375,0.0624 l -1,0 -2,0 0,2 3,0 c 0.1386,0 0.25528,-0.012 0.375,-0.0624 0.25436,-0.082 0.4614,-0.28426 0.5625,-0.5625 0.0504,-0.1198 0.0625,-0.2365 0.0625,-0.375 z m 82,0 c 0,0.1386 -0.0122,0.2551 -0.0625,0.375 -0.1011,0.27824 -0.30814,0.4805 -0.5625,0.5625 -0.11972,0.0504 -0.2364,0.0624 -0.375,0.0624 l -1,0 -2,0 0,2 3,0 c 0.1386,0 0.25528,-0.012 0.375,-0.0624 0.25436,-0.082 0.4614,-0.28426 0.5625,-0.5625 0.0504,-0.1198 0.0625,-0.2365 0.0625,-0.375 z m 40.125,0 c -0.0822,0.31952 -0.125,0.65482 -0.125,1 0,2.20912 1.79086,4 4,4 2.20914,0 4,-1.79088 4,-4 0,-0.34518 -0.0428,-0.68048 -0.125,-1 -0.44393,1.7254 -2.01104,3 -3.875,3 -1.86396,0 -3.43107,-1.2746 -3.875,-3 z m 80,0 c -0.0822,0.31952 -0.125,0.65482 -0.125,1 0,2.20912 1.79086,4 4,4 2.20914,0 4,-1.79088 4,-4 0,-0.34518 -0.0428,-0.68048 -0.125,-1 -0.44392,1.7254 -2.01104,3 -3.875,3 -1.86396,0 -3.43108,-1.2746 -3.875,-3 z m -197.125,1 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 54,0 c -0.554,0 -1,0.446 -1,1 0,0.55398 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 76,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 50,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z m 68,0 c -0.55228,0 -1,0.4477 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.5523 -0.44772,-1 -1,-1 z m 4,0 c -0.138,0 -0.25536,0.012 -0.375,0.0624 -0.35892,0.1518 -0.625,0.52328 -0.625,0.9375 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.5523 -0.44772,-1 -1,-1 z m 8,0 c -0.554,0 -1,0.4113 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 10,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.5262 -0.446,-0.9375 -1,-0.9375 z m 74,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -10,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m -18,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -4,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m 82,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -4,0 c 0.55228,0 1,0.4477 1,1 0,0.55228 -0.44772,1 -1,1 -0.55228,0 -1,-0.44772 -1,-1 0,-0.5523 0.44772,-1 1,-1 z m -8,0 c 0.554,0 1,0.4113 1,0.9375 l 0,0.125 c 0,0.52618 -0.446,0.9375 -1,0.9375 l -10,0 c -0.554,0 -1,-0.41132 -1,-0.9375 l 0,-0.125 c 0,-0.5262 0.446,-0.9375 1,-0.9375 z m 54,0 c -0.554,0 -1,0.41132 -1,0.9375 l 0,0.125 c 0,0.52618 0.446,0.9375 1,0.9375 l 10,0 c 0.554,0 1,-0.41132 1,-0.9375 l 0,-0.125 c 0,-0.52618 -0.446,-0.9375 -1,-0.9375 z m 18,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 443,0 0,2 2,0 0,-2 z m 4,0 0,2 2,0 0,-2 z m 50,0 0,2 2,0 0,-2 z m 4,0 0,2 2,0 0,-2 z m -330,2 0,2 24,0 0,-2 z m 128,0 0,2 24,0 0,-2 z m 64,0 0,2 24,0 0,-2 z m -128.3125,0.1874 0,2 24.3125,0 0,-2 z M 5,-18.75001 l 0,2 c 0,0.55398 0.446,1 1,1 l 4,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 l -3,0 -1,0 c -0.554,0 -1,-0.44602 -1,-1 z m 82,0 0,2 c 0,0.55398 0.446,1 1,1 l 4,0 c 0.554,0 1,-0.44602 1,-1 0,-0.554 -0.446,-1 -1,-1 l -3,0 -1,0 c -0.554,0 -1,-0.44602 -1,-1 z m 184.125,0 0,2 c 0,0.554 0.42308,1 0.9375,1 0.51442,0 0.9375,-0.446 0.9375,-1 l 0,-2 c 0,0.554 -0.42308,1 -0.9375,1 -0.51442,0 -0.9375,-0.446 -0.9375,-1 z m 65.875,0 0,2 c 0,0.554 -0.42308,1 -0.9375,1 -0.51442,0 -0.9375,-0.446 -0.9375,-1 l 0,-2 c 0,0.554 0.42308,1 0.9375,1 0.51442,0 0.9375,-0.446 0.9375,-1 z m 65.875,0 0,2 c 0,0.55398 -0.42308,1 -0.9375,1 -0.51442,0 -0.9375,-0.44602 -0.9375,-1 l 0,-2 c 0,0.55398 0.42308,1 0.9375,1 0.51442,0 0.9375,-0.44602 0.9375,-1 z m 62.125,0 0,2 c 0,0.554 0.42308,1 0.9375,1 0.51444,0 0.9375,-0.446 0.9375,-1 l 0,-2 c 0,0.554 -0.42306,1 -0.9375,1 -0.51442,0 -0.9375,-0.446 -0.9375,-1 z m -456,45 c -0.3204,0 -0.63738,0.0512 -0.9375,0.125 C 6.3192,26.80395 5,28.38897 5,30.24999 l 0,2 c 0,-2.18142 1.8186,-4 4,-4 l 6,0 0,-2 z m 10,0 0,2 6,0 c 2.1814,0 4,1.81858 4,4 l 0,-2 c 0,-1.86102 -1.3192,-3.44604 -3.0625,-3.875 -0.0432,-0.008 -0.0814,-0.0566 -0.125,-0.0624 -0.2585,-0.054 -0.53982,-0.0624 -0.8125,-0.0624 l -6,0 z m 54,0 c -0.3204,0 -0.63738,0.0512 -0.9375,0.125 C 70.3192,26.80395 69,28.38897 69,30.24999 l 0,2 c 0,-2.18142 1.8186,-4 4,-4 l 6,0 0,-2 z m 10,0 0,2 6,0 c 2.1814,0 4,1.81858 4,4 l 0,0.875 1.0625,1.0625 0.875,0.875 C 94.9756,34.79153 95,34.53079 95,34.24999 l 0,-2 c 0,0.2808 -0.0244,0.54154 -0.0625,0.8125 l -0.875,-0.875 -1.0625,-1.0625 0,-0.875 c 0,-1.86102 -1.31921,-3.44604 -3.0625,-3.875 -0.0432,-0.008 -0.0815,-0.0566 -0.125,-0.0624 -0.25849,-0.054 -0.53983,-0.0624 -0.8125,-0.0624 l -6,0 z m -73,4 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 14,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 l -5,0 -4,0 z m 64,0 c -0.554,0 -1,0.44598 -1,1 0,0.554 0.446,1 1,1 l 8.625,0 3,0 2.375,0 c 0.554,0 1,-0.446 1,-1 0,-0.55402 -0.446,-1 -1,-1 l -5,0 -4,0 z m -71,2 0,2 c 0,3.29298 2.70702,6 6,6 l 6,0 2,-2 2,2 6,0 c 3.29298,0 6,-2.70702 6,-6 l 0,-2 c 0,2.96706 -2.21866,5.41092 -5.0625,5.875 -0.0446,0.01 -0.0798,0.053 -0.125,0.0624 -0.27096,0.038 -0.5317,0.0624 -0.8125,0.0624 l -6,0 -2,-2 -2,2 -6,0 c -0.2808,0 -0.54154,-0.0244 -0.8125,-0.0624 -0.0452,-0.01 -0.0804,-0.0516 -0.125,-0.0624 C 5.21866,37.66091 3,35.21705 3,32.24999 z m 4,0 0,2 c 0,1.108 0.892,2 2,2 l 6,0 0,-2 -5,0 -1,0 c -1.108,0 -2,-0.892 -2,-2 z m 20,0 c 0,1.108 -0.892,2 -2,2 l -1,0 -5,0 0,2 6,0 c 1.108,0 2,-0.892 2,-2 z m 40,0 0,2 c 0,3.29298 2.70702,6 6,6 l 6,0 1.375,-1.375 -1,-1 -0.375,0.375 -6,0 c -0.2808,0 -0.54154,-0.0244 -0.8125,-0.0624 -0.0452,-0.01 -0.0802,-0.0516 -0.125,-0.0624 C 69.21866,37.66071 67,35.21705 67,32.24999 z m 4,0 0,2 c 0,1.108 0.892,2 2,2 l 6,0 0,-2 -5,0 -1,0 c -1.108,0 -2,-0.892 -2,-2 z m 20,0 c 0,0.0706 -0.0554,0.1188 -0.0625,0.1874 l -1.75,1.75 c -0.0687,0.008 -0.1169,0.0624 -0.1875,0.0624 l -1,0 -0.375,0 -2,0 2,2 1.375,0 c 0.0706,0 0.11882,-0.0554 0.1875,-0.0624 l 1.75,-1.75 C 90.9445,34.36889 91,34.32059 91,34.24999 z m 51.625,1.3125 c -1.79992,-0.0282 -3.64434,0.65818 -5.625,2.6875 l 0,2 c 7.92264,-8.1173 13.88536,5.63196 22,-2 l 0,-2 c -6.08598,5.72396 -10.97525,-0.60276 -16.375,-0.6875 z m 70.75,0 c -5.39976,0.0848 -10.28902,6.41148 -16.375,0.6875 l 0,2 c 8.11464,7.63198 14.07736,-6.1173 22,2 l 0,-2 c -1.98066,-2.02932 -3.82508,-2.71576 -5.625,-2.6875 z m -132.6875,0.6875 -0.0625,0.0624 -1.3125,1.4375 0.9375,1 0.375,-0.4375 2,-2.0625 -1.9375,0 z m 2.375,2.4375 -1,1 3.1875,3.1875 1,-1 z m 10.625,0 -3.1875,3.1875 1,1 3.1875,-3.1875 z m -5.3125,5.3125 -4.25,4.25 -1.0625,-1.125 -1,1 2.0625,2.125 4.25,-4.25 4.25,4.25 2.0625,-2.125 -1,-1 -1.0625,1.125 z m 44.625,4.25 0,2 2,0 0,-2 z m 88,0 0,2 2,0 0,-2 z m 308,38 c -0.69256,0 -1.3433,0.0704 -2,0.1874 -1.97012,0.35122 -3.78902,1.19268 -5.3125,2.375 0.27526,0.01 0.53642,0.0662 0.8125,0.125 0.1164,0.1188 -0.25608,0.39682 -0.625,0.6875 0.63336,-0.48892 1.33168,-0.7194 2.1875,-0.75 0.40586,-0.0824 0.83072,-0.0692 1.1875,0 0.3373,-0.1156 0.71222,-0.165 1.0625,-0.25 -0.44024,-0.1258 0.061,-0.4151 0.5625,-0.4375 0.191,-0.008 0.3289,0.0358 0.4375,0.125 0.22006,0.004 0.5148,-0.21686 0.375,0.0624 0.25094,-0.0294 0.49406,-0.0496 0.75,-0.0624 -0.25748,-0.0812 0.006,-0.2038 0.25,-0.25 0.2137,-0.0404 0.32538,0.004 0.0624,0.1874 0.0854,-0.002 0.1642,0 0.25,0 0.27722,0 0.54052,0.041 0.8125,0.0624 0.0466,-0.0624 0.1156,-0.1456 0.25,-0.25 0.1772,-0.117 0.226,-0.1512 0.25,-0.125 0.054,0.0586 -0.1464,0.39984 -0.0624,0.375 0.028,-0.008 0.071,-0.0822 0.1874,-0.1874 0.55138,-0.1452 1.30082,0.1312 1.6875,0.5625 0.018,0.02 0.0462,0.0418 0.0624,0.0624 0.032,0.0406 0.0372,0.082 0.0624,0.125 0.01,0.018 -0.01,0.0442 0,0.0624 0.0448,0.0876 0.1132,0.1556 0.125,0.25 0.22788,-0.076 0.46198,-0.1072 0.6875,-0.1874 0.0982,0.0354 0.21546,0.0246 0.3125,0.0624 -0.114,0.0368 -0.21658,0.142 -0.3125,0.125 -0.4862,0.36054 0.3743,0.23672 0.875,0.4375 -0.0958,-0.34306 0.1384,-0.84584 0.3125,-0.9375 0.082,-0.0432 0.109,0.0344 0.125,0.25 -0.0256,0.1286 0.034,0.38998 0.0624,0.625 3.60122,1.82902 6.13098,5.40748 6.5,9.625 0.024,-0.31088 0.0624,-0.62034 0.0624,-0.9375 0,-4.72414 -2.71918,-8.79246 -6.6875,-10.75 0.0228,0.29036 0.1182,0.695 -0.0624,0.625 0.21676,-0.9925 -1.885,-0.42026 -1.1875,-0.9375 0.096,0.018 0.1984,-0.0882 0.3125,-0.125 -0.097,-0.0378 -0.2143,-0.0274 -0.3125,-0.0624 -0.53834,0.1922 -1.0891,0.3924 -1.625,0.5 -0.1916,-0.004 -0.4994,-0.038 -0.625,-0.0624 0.0482,-0.012 0.153,-0.0528 0.375,-0.0624 0.1458,-0.198 0.0846,-0.0842 0.3125,-0.25 0.1198,-0.172 1.59284,-0.244 0.375,-0.25 -0.0558,-0.006 -0.038,-0.0564 -0.0624,-0.0624 0.1018,-0.02 0.28324,-0.0384 0.5,-0.0624 -0.52698,-0.1512 -1.07252,-0.28782 -1.625,-0.375 -0.55248,-0.0872 -1.11186,-0.125 -1.6875,-0.125 z m 1.875,0.6875 c 0.21882,-0.004 0.38004,0.0784 -0.0624,0.25 l -0.25,0 c -0.1912,-0.151 0.094,-0.246 0.3125,-0.25 z m -0.6875,0.6875 c 0.0992,-0.014 0.2316,-0.02 0.375,0.0624 0.4787,-0.1182 1.28428,0.0798 0.3125,0.1874 -0.0346,-0.1114 -0.361,0.0696 -0.375,-0.0624 -0.6163,0.1388 -0.6102,-0.1472 -0.3125,-0.1874 z m -192.75,0.25 c -4.03432,0.49932 -7.1875,4.70004 -7.1875,9.6875 0,0.3763 0.027,0.7611 0.0624,1.125 0.37244,-4.90892 3.76768,-8.8125 7.9375,-8.8125 4.16982,0 7.56506,3.90358 7.9375,8.8125 0.0348,-0.36386 0.0624,-0.7487 0.0624,-1.125 0,-5.31996 -3.58134,-9.6875 -8,-9.6875 -0.27616,0 -0.54354,-0.0332 -0.8125,0 z m 191.9375,0.125 c 0.28064,-0.0798 0.53602,0.1352 -0.125,0.1874 -0.0498,0.0662 -0.078,0.002 -0.125,0 0.0642,-0.1082 0.1564,-0.161 0.25,-0.1874 z m -3.125,0.0624 c 0.35978,-0.008 0.52868,0.1018 -0.1874,0.25 -0.23732,0.0308 -0.45478,0.33 -0.6875,0.25 -1.8e-4,-0.3454 0.51552,-0.492 0.875,-0.5 z M 5,86.24999 l 0,2 5,0 19,0 0,-2 z m 80.9375,0.625 c -3.76632,0.1794 -5.852,5.04228 -7.875,9.5625 l -0.4375,1 c -1.61934,3.54196 -3.27284,6.619 -5.9375,6.625 0.7764,0.54006 1.51326,0.9325 2.1875,1.1875 1.48694,-1.13738 2.6243,-3.35024 3.75,-5.8125 l 0.4375,-1 c 2.023,-4.52022 4.10868,-9.38304 7.875,-9.5625 0.66332,-0.0314 1.35376,0.0914 2.125,0.375 0.67344,-0.50032 1.41094,-0.8125 2.25,-0.8125 -1.70742,-1.17832 -3.11956,-1.6221 -4.375,-1.5625 z m 444.9375,0.0624 c -0.21852,0.004 -0.50362,0.099 -0.3125,0.25 l 0.25,0 c 0.44264,-0.1716 0.28132,-0.25364 0.0624,-0.25 z m 1,0.3125 c -0.0406,0.0282 -0.0508,0.0534 -0.0624,0.125 0.1448,-0.0388 0.29196,-0.0782 0.4375,-0.125 -0.152,-0.0206 -0.31398,-0.0422 -0.375,0 z m -1.6875,0.375 c -0.24742,0.0336 -0.28268,0.262 0.0624,0.25 0.0702,-0.002 0.1458,-0.0392 0.25,-0.0624 0.014,0.132 0.3404,-0.049 0.375,0.0624 0.175,-0.02 0.24048,-0.0396 0.3125,-0.0624 -0.014,-0.0636 -0.0826,-0.079 -0.125,-0.125 -0.1594,-0.021 -0.32592,-0.043 -0.5,0 -0.1434,-0.0816 -0.27576,-0.076 -0.375,-0.0624 z m 4.0625,0.3125 c 0.008,0.058 0.016,0.113 0,0.1874 0.0768,0.0298 0.1212,-0.0286 0.125,-0.125 -0.0288,0.002 -0.076,-0.0292 -0.125,-0.0624 z m -4.875,0.0624 c -0.0936,0.0266 -0.1858,0.0792 -0.25,0.1874 0.047,0.002 0.0752,0.0662 0.125,0 0.66102,-0.0526 0.40564,-0.26736 0.125,-0.1874 z m -0.6875,0.0624 c -0.24424,0.0462 -0.50748,0.1688 -0.25,0.25 l 0.0624,0.0624 0.1874,-0.0624 c 0.45844,-0.26664 0.24424,-0.29614 0,-0.25 z m 2.125,0.0624 c 0.13,0.1836 0.2144,0.42602 0.375,0.4375 0.1974,-0.23204 0.3534,-0.27744 0.4375,-0.25 -0.2566,-0.1334 -0.53572,-0.1804 -0.8125,-0.1874 z m -3.125,0.0629 c -0.0566,0.012 -0.1614,0.0378 -0.25,0.0624 -0.21282,0.1826 -0.29066,0.38262 -0.125,0.5625 0.46282,-0.0644 0.7947,-0.1386 0.3125,-0.3125 0.1618,-0.2552 0.1498,-0.3299 0.0624,-0.3125 z M 529,88.43739 c -0.0486,-0.01 -0.1174,0.0278 -0.1874,0.0624 -0.0774,0.47708 -0.54184,0.55402 -1.0625,0.5625 0.37506,0.1206 0.69232,0.2438 0.6875,0.625 0.69802,0.0428 0.1254,-0.4624 0.75,-0.375 0.0748,-0.0954 0.119,-0.20842 0.1874,-0.3125 -0.1478,-0.115 -0.1596,-0.52188 -0.375,-0.5625 z m 2.75,0 c 0.0686,0.23898 0.018,0.70016 0.125,0.8125 0.0814,-0.0564 0.24754,-0.043 0.5,0 -0.014,-0.33412 -0.28984,-0.59918 -0.625,-0.8125 z m -11.9375,0.125 c -1.74562,2.084 -2.8125,4.7563 -2.8125,7.6875 0,0.41422 0.0218,0.8466 0.0624,1.25 0.1,-1.55766 0.48326,-3.03742 1.125,-4.375 -0.0268,-0.004 -0.042,-0.0302 -0.0624,-0.125 0.0768,-0.1358 0.1644,-0.2016 0.1874,-0.1874 0.41412,-0.80346 0.9243,-1.5627 1.5,-2.25 0.5131,-0.0316 1.1203,0.157 1.375,0.5 0.0594,-0.0338 0.1376,-0.0668 0.1874,-0.0624 0.084,-0.197 0.16,-0.33974 0.25,-0.375 -0.66688,-0.37672 -0.3358,-0.73218 -0.1874,-1.125 -0.018,0.0232 -0.0636,0.0264 -0.125,-0.0624 0.0486,-0.6189 -0.81588,-0.9172 -1.5,-0.875 z m 8.5,0.125 c -0.0588,0.014 -0.1354,0.0824 -0.1874,0.1874 0.47002,0.061 0.36394,-0.22806 0.1874,-0.1874 z m 5.9375,0 c -0.2458,0.1294 -0.61728,1.13374 0,1.25 0.39282,0.26594 0.0686,-0.71754 0.125,-1 -0.016,-0.21566 -0.043,-0.29312 -0.125,-0.25 z m -12.8125,0.3125 c -0.018,0.0652 -0.006,0.1838 0,0.3125 0.016,-0.08 0.0784,-0.163 0.0624,-0.25 -0.002,-0.0344 -0.0508,-0.0342 -0.0624,-0.0624 z M 521,89.37499 c 0.0528,-0.038 0.1936,0.1526 0,0.125 -0.014,-0.083 -0.018,-0.113 0,-0.125 z m 9.75,0.6875 c -0.4747,-0.016 -1.40434,0.81586 -0.4375,0.3125 0.88806,-0.32008 -0.4054,1.41986 -0.25,0.25 l -0.0624,0.125 c -0.0434,0.6201 -1.0938,1.0026 -1.125,1.125 -0.61556,0.1764 -0.7655,0.8281 -0.9375,0.6875 0.1376,0.9662 -1.74792,1.00622 -1.0625,2.1875 -0.0276,0.0308 -0.0422,0.4309 -0.1874,0.3125 -0.0218,-0.788 -0.74162,-1.22536 -1.4375,-0.875 0.0326,0.0244 0.0484,0.0464 0.0624,0.0624 -0.2077,0.014 -1.0234,-0.154 -1.125,0.25 -0.20344,0.2702 -0.3476,0.4822 -0.5,0.375 0.1152,0.28484 0.1466,0.65044 0,0.875 -0.01,0.47402 0.26298,0.6655 0.5625,0.6875 0.008,-0.014 0.0516,0.012 0.0624,0 0.1232,-0.1296 0.27078,-0.193 0.5,-0.1874 0.1208,-0.0974 0.25052,-0.2206 0.3125,-0.375 0.28392,-0.0468 0.33792,0.0804 0.3125,0.25 0.62754,-0.1842 1.23028,0.22482 1.25,0.9375 0.1454,0.1184 0.1598,-0.2817 0.1874,-0.3125 -0.24332,-0.41936 -0.1364,-0.6508 0.0624,-0.875 -0.008,-0.004 0.008,-0.0594 0,-0.0624 -0.36076,-0.147 -0.75074,-0.2454 -0.875,-0.1874 0.0204,-0.058 0.048,-0.105 0.125,-0.125 0.20426,-0.0506 0.54864,0.0782 0.875,0.1874 0.38522,-0.32534 0.9524,-0.58152 0.875,-1.125 0.172,0.1406 0.32194,-0.5111 0.9375,-0.6875 0.0312,-0.1224 1.0816,-0.5049 1.125,-1.125 l 0.0624,-0.125 c -0.1554,1.16986 1.13806,-0.57008 0.25,-0.25 -0.96684,0.50336 -0.0372,-0.3285 0.4375,-0.3125 0.4678,0.2063 2.26864,-0.6598 1.1875,-0.75 -0.1634,0.004 -0.1146,-0.50876 -0.1874,-0.8125 -0.004,-0.014 -0.0588,0.012 -0.0624,0 -0.0896,0.01 -0.0482,-0.038 0,-0.125 -0.0792,-0.1028 -0.24344,-0.1142 -0.5,0.1874 -0.182,-0.014 -0.28042,-0.30256 -0.4375,-0.5 z m -9.6875,0.3125 c 0.1304,0.008 0.68106,0.58022 0.0624,0.25 -0.1114,-0.1702 -0.106,-0.252 -0.0624,-0.25 z m 9.75,0.375 c 0.1106,0.004 0.012,0.1536 -0.1874,0.0624 0.0854,-0.0422 0.1508,-0.064 0.1874,-0.0624 z m 0.4375,0 c -0.0322,0.0338 -0.1794,0.1596 -0.5,0.3125 -0.196,0.0456 -0.35624,0.24964 -0.5625,0.25 0.108,-0.21958 0.60114,-0.4246 0.875,-0.5 0.137,-0.0376 0.21974,-0.0962 0.1874,-0.0624 z m 0.875,1.1875 c -0.1962,0.012 -0.6963,0.5901 -0.4375,0.5625 0.26674,0.0532 1.28608,-0.02 0.5,-0.3125 0.042,-0.1718 0.002,-0.25394 -0.0624,-0.25 z M 7.1875,92.24999 C 7.0803,92.55863 7,92.90481 7,93.24999 c 0,1.65684 1.34314,3 3,3 1.65686,0 3,-1.34316 3,-3 0,-0.34518 -0.0803,-0.69136 -0.1875,-1 -0.40768,1.17282 -1.50082,2 -2.8125,2 -1.31168,0 -2.40482,-0.82718 -2.8125,-2 z m 187.8125,6 0,2 28,0 0,-2 z m 202,-6 0,2 20,0 0,-2 z m 52,0 0,2 20,0 0,-2 z m 81.8125,0.5 c -0.0368,-10e-4 -0.102,0.0204 -0.1874,0.0624 0.1988,0.091 0.29812,-0.0584 0.1874,-0.0624 z m 0.4375,0 c 0.0322,-0.0338 -0.0506,0.0248 -0.1874,0.0624 -0.27386,0.0754 -0.76696,0.28042 -0.875,0.5 0.20626,-3.6e-4 0.3665,-0.2044 0.5625,-0.25 0.3205,-0.1528 0.46776,-0.2788 0.5,-0.3125 z m -10.5625,0.875 c -0.22246,0.365 -0.3912,0.81888 -0.375,1.125 -0.012,0.56448 0.30326,0.95122 0.75,1.125 -0.3329,0.1258 -0.159,0.98346 0.1874,1.25 0.468,1.18256 0.1572,-0.43984 -0.125,-0.8125 0.2368,-0.83736 0.57308,0.98262 1,1.1875 0.0918,0.80042 0.61308,1.1848 1.375,1.4375 0.3448,0.014 0.85392,0.1808 1.125,0 -0.1144,0.1878 -0.1086,0.4022 0.1874,0.4375 0.0994,0.0332 0.3663,0.1438 0.4375,0 0.0736,0.035 0.20296,0.0394 0.3125,-0.0624 0.0864,-0.0396 0.0722,0.0248 0.125,0 -0.2373,0.177 -0.49338,0.4631 0.0624,0.5625 0.36394,0.24396 0.43882,-1.19764 -0.0624,-0.9375 -0.54106,-0.1528 -0.63648,0.2037 -0.5,0.375 -0.31492,0.0822 -0.22638,-0.24442 -0.0624,-0.5625 -0.0262,-0.1756 -0.2214,-0.0922 -0.375,0.0624 0.0328,-0.0538 0.0508,-0.1042 0.0624,-0.1874 0.1874,-0.1436 0.25076,-0.22424 0.3125,-0.25 0.13,-0.0544 0.0608,0.1652 0,0.375 0.23602,-0.45812 0.60936,-0.97536 0,-0.875 -0.29272,0.72914 -1.4583,0.88626 -1.4375,-0.125 0.137,-0.20974 0.0968,-0.53742 0,-0.8125 -0.0638,-0.008 -0.1308,0.002 -0.1874,0 -0.76192,-0.2527 -1.2832,-0.63708 -1.375,-1.4375 -0.42692,-0.20488 -0.7632,-2.02486 -1,-1.1875 0.2822,0.37266 0.593,1.99506 0.125,0.8125 -0.3464,-0.26654 -0.5205,-1.1242 -0.1874,-1.25 -0.1396,-0.0544 -0.26704,-0.1552 -0.375,-0.25 z M 85.625,94.31249 c -0.3632,0.63758 -0.71926,1.28342 -1.0625,2 l 3,0 c 0.0418,0 0.0854,-0.006 0.125,0 l 0.75,-1 c 0,-0.53432 -0.35934,-1 -0.875,-1 z m 432.6875,0.5 c -0.0232,-0.014 -0.1106,0.0516 -0.1874,0.1874 0.0828,0.379 0.25718,-0.1458 0.1874,-0.1874 z M 325,96.37499 c -0.041,0.38574 -0.0624,0.79256 -0.0624,1.1875 0,4.19556 2.39458,7.85152 6,10 l 2,0 0,-1 c -4.43774,-1.75698 -7.59398,-5.61262 -7.9375,-10.1875 z m 26.5625,0 c -0.34352,4.57488 -3.49976,8.43054 -7.9375,10.1875 l 0,1 2,0 c 3.60542,-2.14846 6,-5.80444 6,-10 0,-0.39494 -0.021,-0.80176 -0.0624,-1.1875 z m -284.5,0.875 c -0.0234,0.33046 -0.0625,0.66362 -0.0625,1 0,7.73036 6.26966,14 14,14 7.73266,0 14,-6.26964 14,-14 0,-0.33638 -0.0392,-0.66954 -0.0625,-1 -0.513,7.26368 -6.54132,13 -13.9375,13 -7.39396,0 -13.42432,-5.73632 -13.9375,-13 z m 448,0 c -0.0234,0.33046 -0.0624,0.66362 -0.0624,1 0,7.73032 6.26968,14 14,14 7.73032,0 14,-6.26968 14,-14 0,-0.33638 -0.0394,-0.66954 -0.0624,-1 -0.46436,6.57258 -5.44906,11.85938 -11.875,12.8125 -0.4944,0.0734 -0.99018,0.1674 -1.5,0.1874 -0.1868,0.008 -0.3738,0 -0.5625,0 -0.47802,0 -0.97408,-0.008 -1.4375,-0.0624 -0.34256,-0.0348 -0.66518,-0.1284 -1,-0.1874 -6.24378,-1.10146 -11.04476,-6.30652 -11.5,-12.75 z m 11.125,0.2498 c -0.077,0.02 -0.1046,0.067 -0.125,0.125 0.1892,-0.088 0.98422,0.30108 1.375,0.4375 0.0502,-0.048 0.1326,-0.083 0.1874,-0.125 -0.2407,-0.1964 -1.0742,-0.52764 -1.4375,-0.4375 z M 397,98.24999 l 0,2 6,0 0,-2 z m 8,0 0,2 6,0 0,-2 z m 8,0 0,2 4,0 0,-2 z m 36,0 0,2 4,0 0,-2 z m 6,0 0,2 6,0 0,-2 z m 8,0 0,2 6,0 0,-2 z m -69.125,0.125 -6.875,5.875 0,2 8,-6.875 z m 78.25,0 -1.125,1 8,6.875 0,-2 z m 54.875,0 c -0.016,0.006 -0.024,0.0244 0,0.0624 0.1792,0.0406 0.1756,0.016 0.1874,0 -0.006,-0.004 0.006,-0.0596 0,-0.0624 -0.042,-0.018 -0.0882,-0.002 -0.125,0 4.2e-4,0.008 -0.0538,-0.008 -0.0624,0 z m -1.4375,1.5625 c -0.0208,0.0338 0.0212,0.104 0.3125,0.3125 0.72356,0.0502 -0.25022,-0.41404 -0.3125,-0.3125 z m 0.6875,0.3125 c -0.0844,0.0334 -0.0784,0.079 0.0624,0.1874 0.0798,0.0986 0.1792,0.0634 0.25,0 0.008,-0.059 0.0422,-0.1256 0.0624,-0.1874 -0.1424,-0.014 -0.29388,-0.032 -0.375,0 z m 0.6875,1.3125 c -0.21608,0.5116 -0.56674,0.94698 -0.25,1.3125 0.32506,-0.014 0.74812,0.01 1.1875,0.125 -0.29524,-0.45062 -0.63082,-0.92572 -0.9375,-1.4375 z m 0.9375,1.4375 c 0.1062,0.1622 0.2155,0.3346 0.3125,0.5 0.27394,0.0348 0.46806,0.0918 0.8125,0.125 -0.2253,-0.3355 -0.66438,-0.5042 -1.125,-0.625 z m 0.3125,0.5 c -0.71494,-0.091 -1.12254,-0.1652 -1.4375,-0.25 0.36268,0.64794 0.76972,1.20772 1.125,1.75 0.42838,0.1124 0.82602,0.27166 1.0625,0.5625 -0.002,-0.0218 0.002,-0.0406 0,-0.0624 -0.12,-0.79752 -0.40364,-1.4102 -0.75,-2 z m -0.3125,1.5 c -1.44116,-0.37804 -3.05142,0.0718 0.3125,0.5 -0.097,-0.1654 -0.20624,-0.33782 -0.3125,-0.5 z m 0.3125,0.5 c 0.34636,0.5898 0.6299,1.20248 0.75,2 0.0348,0.27152 0.079,0.49982 0.125,0.75 0.1664,0.001 0.33662,0.008 0.5,0 -0.23462,-0.71904 -0.48382,-1.5963 -0.625,-2.625 -0.29886,-0.0338 -0.49664,-0.0928 -0.75,-0.125 z m 6,-3 c -0.0896,0.66934 0.0626,1.51078 -0.625,1.75 -1.18836,0.1604 -0.61708,1.64512 -1.4375,2.3125 -0.1462,0.1566 -0.2899,-0.0208 -0.4375,-0.0624 -0.1068,-0.0438 -0.2054,-0.1026 -0.25,-0.1874 0.014,0.25332 0.0826,0.4864 0.375,0.6875 -0.0474,0.57024 -0.8714,0.25418 -0.75,0.875 -0.002,0.0744 0.004,0.1174 0,0.1874 0.1304,-0.0224 0.24604,-0.0984 0.375,-0.125 0.045,-0.24406 0.1664,-0.24266 0.125,0 0.34084,-0.0738 0.67074,-0.21048 1,-0.3125 0.1492,-0.63252 0.23106,-1.2712 1,-1.375 0.94272,-0.328 0.28718,-1.7511 0.875,-2.375 0.65362,-0.58222 0.30764,-1.09524 -0.25,-1.375 z m -2.75,3.8125 c 0.3155,-0.69854 -0.0454,-0.80536 0,0 z M 3,108.24999 l 0,2 28,0 0,-2 -26,0 z m 394,0 0,2 20,0 0,-2 z m 52,0 0,2 20,0 0,-2 z m -124.0625,0.625 0,2 c 0,0.73866 0.57384,1.3125 1.3125,1.3125 l 8,0 c 0.736,0 1.375,-0.5765 1.375,-1.3125 l 0,-1.5625 0,-0.4375 c 0,0.736 -0.639,1.3125 -1.375,1.3125 l -8,0 c -0.73866,0 -1.3125,-0.57384 -1.3125,-1.3125 z m 16,0 0,0.4375 0,1.5625 c 0,0.736 0.5765,1.3125 1.3125,1.3125 l 8,0 c 0.1848,0 0.34038,0.004 0.5,-0.0624 0.47852,-0.2024 0.875,-0.698 0.875,-1.25 l 0,-2 c 0,0.552 -0.39648,1.0476 -0.875,1.25 -0.1596,0.0664 -0.3152,0.0624 -0.5,0.0624 l -8,0 c -0.736,0 -1.3125,-0.5765 -1.3125,-1.3125 z m -143.9375,1.375 0,2 24,0 0,-2 z m -117.75,40.6875 -0.3125,0.875 -7.25,17.75 0.8125,0 6.4375,-15.75 0.3125,-0.875 3.625,0 0.1875,0.4375 6.5,16.1875 0.8125,0 -7.3125,-18.1875 -0.1875,-0.4375 z m -61.66613,2.81074 -2,5.375 0.75,0 1.25,-3.375 1.125,3.375 0.6875,0 z m -3.4375,9.4375 -1.8125,5 -4.1875,0 c -0.2717,0.66452 -0.54614,1.34944 -0.8125,2 l 5,0 1.8125,-5 6.6875,0 1.625,5 5.25,0 c -0.26312,-0.65902 -0.54458,-1.33248 -0.8125,-2 l -4.4375,0 -1.625,-5 z m 65.04113,-0.68574 -0.5625,1.0625 c 0,0.64304 0.5445,1.1875 1.1875,1.1875 l 2.3125,0 c 0.64302,0 1.18576,-0.54446 1.1875,-1.1875 l -0.5625,-1.0625 c -0.1896,0.1296 -0.38386,0.25 -0.625,0.25 l -2.3125,0 c -0.24112,0 -0.4351,-0.1204 -0.625,-0.25 z M 67,169.56249 l 0,2 c 0,2.57212 2.1154,4.6875 4.6875,4.6875 l 18.625,0 c 2.57212,0 4.625,-2.11538 4.625,-4.6875 l 0,-2 c 0,2.57212 -2.05288,4.6875 -4.625,4.6875 l -18.625,0 c -2.5721,0 -4.6875,-2.11538 -4.6875,-4.6875 z m -62.0625,4.6875 0,2 26.0625,0 0,-2 z m 6.1875,38 -1.125,1.25 0.9375,0.9375 2.0625,-2.1875 z m 9.875,0 2.0625,2.1875 0.9375,-0.9375 -1.125,-1.25 z m 47,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 7,0 c -1.108,0 -2,0.892 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 44,0 c -1.108,0 -2,0.892 -2,2 l 0,2 c 0,-1.108 0.892,-2 2,-2 1.108,0 2,0.892 2,2 l 0,-2 c 0,-1.108 -0.892,-2 -2,-2 z m 7,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -90,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 58,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -152,1.25 -3,2.75 0,2 3,-2.75 4,4 4,0 0,-2 -4,0 z m 22,0 -4,4 -4,0 0,2 4,0 4,-4 3,2.75 0,-2 z m 40,2.75 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 58,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -90,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 58,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -90,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 58,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -144,2.75 -4,4 0.9375,1.0625 3.0625,-3.0625 z m 6,0 0,2 3.0625,3.0625 0.9375,-1.0625 z m 51,1.25 c -1.108,0 -2,0.892 -2,2 0,0.3758 0.1336,0.70026 0.3125,1 0.34846,-0.58398 0.9553,-1 1.6875,-1 l 10,0 c 0.7322,0 1.33904,0.41602 1.6875,1 0.1788,-0.29974 0.3125,-0.6242 0.3125,-1 0,-1.108 -0.892,-2 -2,-2 z m 74,0 c -1.108,0 -2,0.892 -2,2 0,0.3758 0.13364,0.70026 0.3125,1 0.34847,-0.58398 0.9553,-1 1.6875,-1 l 10,0 c 0.7322,0 1.33903,0.41602 1.6875,1 0.17886,-0.29974 0.3125,-0.6242 0.3125,-1 0,-1.108 -0.892,-2 -2,-2 z m -58,2 0,2 c 0,2.1814 1.8186,4 4,4 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 -2.1814,0 -4,-1.8186 -4,-4 z m 44,0 0,2 c 0,2.1814 1.8186,4 4,4 2.1814,0 4,-1.8186 4,-4 l 0,-2 c 0,2.1814 -1.8186,4 -4,4 -2.1814,0 -4,-1.8186 -4,-4 z m -63.875,1 c -0.0832,0.31758 -0.125,0.65916 -0.125,1 0,2.1814 1.8186,4 4,4 l 10,0 c 2.1814,0 4,-1.8186 4,-4 0,-0.34084 -0.0418,-0.68242 -0.125,-1 -0.44952,1.7149 -2.03444,3 -3.875,3 l -10,0 c -1.84056,0 -3.42548,-1.2851 -3.875,-3 z m 74,0 c -0.0832,0.31758 -0.125,0.65916 -0.125,1 0,2.1814 1.8186,4 4,4 l 10,0 c 2.1814,0 4,-1.8186 4,-4 0,-0.34084 -0.0418,-0.68242 -0.125,-1 -0.44953,1.7149 -2.03444,3 -3.875,3 l -10,0 c -1.84056,0 -3.42547,-1.2851 -3.875,-3 z m -138.125,3 0,2 10,0 -1.875,-2 z m 19.875,0 -1.875,2 10,0 0,-2 z m -5.0625,40.5625 c -2.53002,0 -4.625,2.09498 -4.625,4.625 l -4.3125,0 c -0.142,0.6402 -0.25,1.318 -0.25,2 l 4.5625,0 c 0,-2.53002 2.09498,-4.625 4.625,-4.625 2.19372,0 4.05502,1.55698 4.5,3.625 0.0686,-0.3161 0.0625,-0.66256 0.0625,-1 0,-2.53002 -2.03248,-4.625 -4.5625,-4.625 z m 9.0625,5.75 c -0.46388,3.76028 -3.21444,6.8218 -6.8125,7.75 l 0,0.25 c 0,1.265 -0.985,2.3125 -2.25,2.3125 -1.265,0 -2.3125,-1.0475 -2.3125,-2.3125 l 0,1.75 0,0.25 c 0,0.82104 0.4694,1.52664 1.125,1.9375 0.36744,-0.1472 0.7662,-0.25 1.1875,-0.25 0.4213,0 0.82006,0.1028 1.1875,0.25 0.63712,-0.41086 1.0625,-1.11646 1.0625,-1.9375 l 0,-0.25 c 3.95314,-1.0198 6.875,-4.60562 6.875,-8.875 0,-0.29446 -0.0357,-0.5875 -0.0625,-0.875 z m -12.0625,15.875 c -0.1058,0.31798 -0.1875,0.64554 -0.1875,1 0,1.76616 1.42132,3.25 3.1875,3.25 1.76618,0 3.1875,-1.48384 3.1875,-3.25 0,-0.35446 -0.0819,-0.68202 -0.1875,-1 -0.42134,1.28246 -1.58826,2.25 -3,2.25 -1.41174,0 -2.57866,-0.96754 -3,-2.25 z"
+     id="path5248"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccsssscssccsscsscsssssssssscccccccssssssscccsscsccccccssccsccsccsscccccccsccccccsccccccccccccccccccccccccccccccccccccccccccccccccsscscsssscscsscscsssccssscscsscscsscccsccsscssccscscccccccccccccsscsscssssccscscscccssscsccscssssscsccscssssscsscssssscsscssssscsccccccccsccccsscsccscsssccccccccccscccccccssscsssccscccscccsccccccsscccccccccccccsssccccccccccccccccccccccccccccccccccccccccssscsccssscccscccccsssscssccsssscssccccccccccccccccccccccccccsccssscsscccccccccsssscsscssssscccscssssscccccsssscssccsssscssccssccsccccccccccccccccccsssscssccsssscsscssssssccscsssscccscccccsccccsssscscccccscccccccccccccccccccccccccsssccscccccccccccccccccccccccccccccccccccscccccccccccscccssccccccccccccscccccccccssssscscccccscccccccccccccsccccccccscccccccccscccccscsccsscsscccscsccsscsscccccsccscccccsscccscccccccccccscccssccccccccsssssssccccccccccccssssscscssssssssssccssssssssssssssscscccccsssssssssssssscccccccccccscssccccsssccsssscssssssssscssssssssssssssssssssssssssssscssssssssscssssssssssssssscccccccccccccccccccccccccccccccssscsccssscscsssssssssssssssssssssssssssscsccccsccccsccsccsccsccccscccccsccsssssssssssssssssssssssssssssssssssscssscsccssscsccccccccccccccccccccccccccccccccscsscscccsssscssssssssscssssscccccccssssccssssccsccccccsssscssssssssscsssssssssccsccccccccccccccccsssccssssssssssssssssssccssssssssssssssssssssssssssssssssssssssssssssssssssscccccccccccccccccccccccscccsccsccccscccsccsccssscsccssscscsssssssssssssssssssssssssssssssssccsssccsssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssscccccccccccccccccccccccccccccccccccccccccssssscsccssssscsccssscsccssscsccssscsccssscscscscsccsccscsccsccscscsccsccsscccsccccsccsccssssssccssssccsssccscsscccsscccscccsccccsscccsccscccssccssccccsccccsscccsccccsccccsccscccccccsccccscccccccccccccccccccccccccccccccccccccccccccccccccccccsccccccccccccccccccsccccccccccccccccccccccccccscscsscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccssscscccccccccccccccccccccccccccccccccccccccccccccccccccccccccsccscccccscccccccccscccssscsccssscccscccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccssssccsscccssscsccsscccccccccccccccccccccccccccccccccccccccccssccssccsssscssccccccccccccccccssssssssssssssssssssssssssscscsssscscsssssssssssssssssssssssssssssssssssssssssssssssccccccccccccccccccssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssssccccccccccsscsscssssscsscssscssscsccssscsccsssscssccsssscsscccccccccccsccccscssccssccscscscsccssscsc" /><path
+     sodipodi:nodetypes="sssss"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 81,276.11885 c -7.73034,0 -14,6.3004 -14,14.06864 0,7.76824 6.26966,14.06862 14,14.06862 7.73266,0 14,-6.30038 14,-14.06862 0,-7.76824 -6.26734,-14.06864 -14,-14.06864 z"
+     id="path4290-7"
+     inkscape:connector-curvature="0" /><path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 197,-363.81251 0,28 22,0 0,-18 0,-2 -8,-8 -2,0 z m 2,2 11,0 7,7 0,17 -10,0 -6,0 -2,0 z"
+     id="path4249"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4303"
+     d="m 283,-363.81251 0,28 -22,0 0,-18 0,-2 8,-8 2,0 z m -2,2 -11,0 -7,7 0,17 10,0 6,0 2,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 93,-363.81251 0,28 -22,0 0,-18 0,-2 8,-8 2,0 z m -2,2 -11,0 -7,7 0,17 10,0 6,0 2,0 z"
+     id="path4305"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4307"
+     d="m 5,-363.81251 0,28 22,0 0,-18 0,-2 -8,-8 -2,0 z m 2,2 11,0 7,7 0,17 -10,0 -6,0 -2,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4311"
+     d="m 517,-363.81251 0,28 22,0 0,-18 0,-2 -8,-8 -2,0 z m 2,2 11,0 7,7 0,17 -10,0 -6,0 -2,0 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 581,-363.75001 0,9.5 c 0.38292,-0.24029 0.74124,-0.44168 1.125,-0.625 l 0.875,-0.4375 0,-6.4375 10.6875,0 7.3125,7.3125 0,16.6875 -10,0 0,1.9375 c 0,0.0209 3.2e-4,0.0417 0,0.0625 l 12,0 0,-18 0,-2 -8,-8 -2,0 -12,0 z m 2,10.6875 c -0.72246,0.34511 -1.37784,0.75283 -1.9375,1.3125 -1.26676,1.26675 -2.0625,3.067 -2.0625,5 0,2.78704 1.6474,5.12879 4,6.25 l 0,4.6875 c 0,1.108 0.89198,2 2,2 l 2,0.0625 c 1.108,0 2,-0.9545 2,-2.0625 l 0,-4.6875 c 2.35258,-1.12121 4,-3.46296 4,-6.25 0,-2.78704 -1.64238,-5.18627 -4,-6.3125 l 0,5.3125 -2.9375,2 -3.0625,-2 0,-5.3125 z"
+     id="path5011-3" /><path
+     id="path4415"
+     d="m 667,-363.75001 0,9.5 c -0.38292,-0.24029 -0.74124,-0.44168 -1.125,-0.625 l -0.875,-0.4375 0,-6.4375 -10.6875,0 -7.3125,7.3125 0,16.6875 10,0 0,1.9375 c 0,0.0209 -3.2e-4,0.0417 0,0.0625 l -12,0 0,-18 0,-2 8,-8 2,0 12,0 z m -2,10.6875 c 0.72246,0.34511 1.37784,0.75283 1.9375,1.3125 1.26676,1.26675 2.0625,3.067 2.0625,5 0,2.78704 -1.6474,5.12879 -4,6.25 l 0,4.6875 c 0,1.108 -0.89198,2 -2,2 l -2,0.0625 c -1.108,0 -2,-0.9545 -2,-2.0625 l 0,-4.6875 c -2.35258,-1.12121 -4,-3.46296 -4,-6.25 0,-2.78704 1.64238,-5.18627 4,-6.3125 l 0,5.3125 2.9375,2 3.0625,-2 0,-5.3125 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 325,-363.81251 0,28 17.625,0 -2,-2 -2.625,0 -3,0 -6,0 -2,0 0,-24 11,0 7,7 0,2.4375 c 1.22936,1.53978 2,3.45759 2,5.5625 l 0,-7 0,-2 -8,-8 -2,0 -12,0 z m 22,17 c 0,0.96638 -0.40154,1.72552 -0.6875,2.5625 l 0.6875,0.6875 0,-3.25 z m -9,-7 c -3.8423,0 -7,3.15768 -7,7 0,3.8423 3.1577,7 7,7 0.99078,0 1.89266,-0.24748 2.75,-0.625 l 4.6875,4.6875 3.25,-3.25 -4.5625,-4.5625 c 0.533,-0.9857 0.875,-2.0592 0.875,-3.25 0,-3.84232 -3.1577,-7 -7,-7 z m -0.0624,2 c 2.76142,0 5,2.23858 5,5 0,2.76142 -2.23858,5 -5,5 -2.76142,0 -5,-2.23858 -5,-5 0,-2.76142 2.23858,-5 5,-5 z"
+     id="path4953-8" /><path
+     id="path4243"
+     d="m 413,-363.81251 0,28 -17.625,0 2,-2 2.625,0 3,0 6,0 2,0 0,-24 -11,0 -7,7 0,2.4375 c -1.22936,1.53978 -2,3.45759 -2,5.5625 l 0,-7 0,-2 8,-8 2,0 12,0 z m -22,17 c 0,0.96638 0.40154,1.72552 0.6875,2.5625 l -0.6875,0.6875 0,-3.25 z m 9,-7 c 3.8423,0 7,3.15768 7,7 0,3.8423 -3.1577,7 -7,7 -0.99078,0 -1.89266,-0.24748 -2.75,-0.625 l -4.6875,4.6875 -3.25,-3.25 4.5625,-4.5625 c -0.533,-0.9857 -0.875,-2.0592 -0.875,-3.25 0,-3.84232 3.1577,-7 7,-7 z m 0.0624,2 c -2.76142,0 -5,2.23858 -5,5 0,2.76142 2.23858,5 5,5 2.76142,0 5,-2.23858 5,-5 0,-2.76142 -2.23858,-5 -5,-5 z"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     style="fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 67,-301.81251 0,20 6,0 0,-2 -2,0 -2,0 0,-16 9,0 5,5 0,1 2,0 0,-2 -6,-6 -2,0 -10,0 z m 8,10 0,20 18,0 0,-12 0,-2 -6,-6 -2,0 -10,0 z m 2,2 9,0 5,5 0,11 -10,0 -2,0 -2,0 0,-16 z"
+     id="path3594-7" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 142.0625,-301.81251 c -0.58921,0 -1.0625,0.47329 -1.0625,1.0625 l 0,0.9375 -0.9375,0 c -0.58921,0 -1.0625,0.47329 -1.0625,1.0625 l 0,1.875 c 0,0.58921 0.47329,1.0625 1.0625,1.0625 l 2,0 5.875,0 2,0 c 0.58921,0 1.0625,-0.47329 1.0625,-1.0625 l 0,-1.875 c 0,-0.58921 -0.47329,-1.0625 -1.0625,-1.0625 l -0.9375,0 0,-0.9375 c 0,-0.58921 -0.47329,-1.0625 -1.0625,-1.0625 z m -5.0625,2 c -2.18141,0 -4,1.81859 -4,4 l 0,18 c 0,2.18141 1.81859,4 4,4 l 2,0 0,-2 -2,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-18 c 0,-1.108 0.892,-2 2,-2 l 0,-0.9375 c 0,-0.36716 0.0632,-0.73321 0.1875,-1.0625 z m 15.8125,0 c 0.12429,0.32929 0.1875,0.69534 0.1875,1.0625 l 0,0.9375 c 1.108,0 2,0.892 2,2 l 0,4 2,0 0,-4 c 0,-2.18141 -1.81859,-4 -4,-4 z m -9.8125,24 c -1.108,0 -2,2 -2,2 l 0,0 c 0,0 0.892,2 2,2 l 14,0 c 1.108,0 2,-2 2,-2 l 0,0 c 0,0 -0.892,-2 -2,-2 z"
+     id="rect4963-2"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccsscsssssssss" /><path
+     inkscape:connector-curvature="0"
+     id="path4569"
+     d="m 206.0625,-301.81251 c -0.58922,0 -1.0625,0.47329 -1.0625,1.0625 l 0,0.9375 -0.9375,0 c -0.58922,0 -1.0625,0.47329 -1.0625,1.0625 l 0,1.875 c 0,0.58921 0.47328,1.0625 1.0625,1.0625 l 2,0 5.875,0 2,0 c 0.58922,0 1.0625,-0.47329 1.0625,-1.0625 l 0,-1.875 c 0,-0.58921 -0.47328,-1.0625 -1.0625,-1.0625 l -0.9375,0 0,-0.9375 c 0,-0.58921 -0.47328,-1.0625 -1.0625,-1.0625 z m -5.0625,2 c -2.18141,0 -4,1.81859 -4,4 l 0,18 c 0,2.18141 1.81859,4 4,4 l 2,0 0,-2 -2,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-18 c 0,-1.108 0.892,-2 2,-2 l 0,-0.9375 c 0,-0.36716 0.0632,-0.73321 0.1874,-1.0625 z m 15.8125,0 c 0.1243,0.32929 0.1875,0.69534 0.1875,1.0625 l 0,0.9375 c 1.108,0 2,0.892 2,2 l 0,4 2,0 0,-4 c 0,-2.18141 -1.8186,-4 -4,-4 l -0.1874,0 z m -9.8125,24 c -1.108,0 -2,2 -2,2 l 0,0 c 0,0 0.892,2 2,2 l 14,0 c 1.108,0 2,-2 2,-2 l 0,0 c 0,0 -0.892,-2 -2,-2 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 275.9375,-301.81251 c 0.58922,0 1.0625,0.47329 1.0625,1.0625 l 0,0.9375 0.9375,0 c 0.58922,0 1.0625,0.47329 1.0625,1.0625 l 0,1.875 c 0,0.58921 -0.47328,1.0625 -1.0625,1.0625 l -2,0 -5.875,0 -2,0 c -0.58922,0 -1.0625,-0.47329 -1.0625,-1.0625 l 0,-1.875 c 0,-0.58921 0.47328,-1.0625 1.0625,-1.0625 l 0.9375,0 0,-0.9375 c 0,-0.58921 0.47328,-1.0625 1.0625,-1.0625 z m 5.0625,2 c 2.1814,0 4,1.81859 4,4 l 0,18 c 0,2.18141 -1.8186,4 -4,4 l -2,0 0,-2 2,0 c 1.108,0 2,-0.892 2,-2 l 0,-18 c 0,-1.108 -0.892,-2 -2,-2 l 0,-0.9375 c 0,-0.36716 -0.0632,-0.73321 -0.1874,-1.0625 z m -15.8125,0 c -0.1243,0.32929 -0.1875,0.69534 -0.1875,1.0625 l 0,0.9375 c -1.108,0 -2,0.892 -2,2 l 0,4 -2,0 0,-4 c 0,-2.18141 1.8186,-4 4,-4 l 0.1874,0 z m 9.8125,24 c 1.108,0 2,2 2,2 l 0,0 c 0,0 -0.892,2 -2,2 l -14,0 c -1.108,0 -2,-2 -2,-2 l 0,0 c 0,0 0.892,-2 2,-2 z"
+     id="path4571"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     inkscape:connector-curvature="0"
+     id="path4573"
+     d="m 334.0625,-301.81251 c -0.58922,0 -1.0625,0.47329 -1.0625,1.0625 l 0,0.9375 -0.9375,0 c -0.58922,0 -1.0625,0.47329 -1.0625,1.0625 l 0,1.875 c 0,0.58921 0.47328,1.0625 1.0625,1.0625 l 2,0 5.875,0 2,0 c 0.58922,0 1.0625,-0.47329 1.0625,-1.0625 l 0,-1.875 c 0,-0.58921 -0.47328,-1.0625 -1.0625,-1.0625 l -0.9375,0 0,-0.9375 c 0,-0.58921 -0.47328,-1.0625 -1.0625,-1.0625 z m -5.0625,2 c -2.1814,0 -4,1.81859 -4,4 l 0,18 c 0,2.18141 1.8186,4 4,4 l 2,0 0,-2 -2,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-18 c 0,-1.108 0.892,-2 2,-2 l 0,-0.9375 c 0,-0.36716 0.0632,-0.73321 0.1874,-1.0625 z m 15.8125,0 c 0.1243,0.32929 0.1875,0.69534 0.1875,1.0625 l 0,0.9375 c 1.108,0 2,0.892 2,2 l 0,4 2,0 0,-4 c 0,-2.18141 -1.8186,-4 -4,-4 l -0.1874,0 z m -9.8125,24 c -1.108,0 -2,2 -2,2 l 0,0 c 0,0 0.892,2 2,2 l 14,0 c 1.108,0 2,-2 2,-2 l 0,0 c 0,0 -0.892,-2 -2,-2 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 403.9375,-301.81251 c 0.58922,0 1.0625,0.47329 1.0625,1.0625 l 0,0.9375 0.9375,0 c 0.58922,0 1.0625,0.47329 1.0625,1.0625 l 0,1.875 c 0,0.58921 -0.47328,1.0625 -1.0625,1.0625 l -2,0 -5.875,0 -2,0 c -0.58922,0 -1.0625,-0.47329 -1.0625,-1.0625 l 0,-1.875 c 0,-0.58921 0.47328,-1.0625 1.0625,-1.0625 l 0.9375,0 0,-0.9375 c 0,-0.58921 0.47328,-1.0625 1.0625,-1.0625 z m 5.0625,2 c 2.1814,0 4,1.81859 4,4 l 0,18 c 0,2.18141 -1.8186,4 -4,4 l -2,0 0,-2 2,0 c 1.108,0 2,-0.892 2,-2 l 0,-18 c 0,-1.108 -0.892,-2 -2,-2 l 0,-0.9375 c 0,-0.36716 -0.0632,-0.73321 -0.1874,-1.0625 z m -15.8125,0 c -0.1243,0.32929 -0.1875,0.69534 -0.1875,1.0625 l 0,0.9375 c -1.108,0 -2,0.892 -2,2 l 0,4 -2,0 0,-4 c 0,-2.18141 1.8186,-4 4,-4 l 0.1874,0 z m 9.8125,24 c 1.108,0 2,2 2,2 l 0,0 c 0,0 -0.892,2 -2,2 l -14,0 c -1.108,0 -2,-2 -2,-2 l 0,0 c 0,0 0.892,-2 2,-2 z"
+     id="path4575"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssss" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 273,84.06249 c -7.73034,0 -14,6.29426 -14,14.0625 0,7.76824 6.26966,14.0625 14,14.0625 7.73266,0 14,-6.29426 14,-14.0625 0,-7.76824 -6.26734,-14.0625 -14,-14.0625 z m 0,2.0625 c 6.62742,0 12,5.37258 12,12 0,6.62742 -5.37258,12 -12,12 -6.62742,0 -12,-5.37258 -12,-12 0,-6.62742 5.37258,-12 12,-12 z m -4.6875,6 c -1.57516,0 -2.8125,1.2921 -2.8125,2.875 0,1.5829 1.23734,2.875 2.8125,2.875 1.57522,0 2.875,-1.2921 2.875,-2.875 0,-1.5829 -1.29978,-2.875 -2.875,-2.875 z m 9.375,0 c -1.5752,0 -2.875,1.2921 -2.875,2.875 0,1.5829 1.2998,2.875 2.875,2.875 1.57518,0 2.8125,-1.2921 2.8125,-2.875 0,-1.5829 -1.23732,-2.875 -2.8125,-2.875 z m -10.46438,9.55026 c -0.0732,0.3088 -0.162,0.63162 -0.162,0.9536 0,3.11996 4.84578,3.6484 5.9389,3.62114 1.09312,-0.0272 5.9389,-0.50118 5.9389,-3.62114 0,-0.32198 -0.0888,-0.6448 -0.162,-0.9536 -2.61418,2.48674 -5.27502,2.05926 -5.7769,2.11548 -0.50188,0.0562 -4.05892,-0.0948 -5.77688,-2.11548 z"
+     id="path3733"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssscszsczcc" /><path
+     sodipodi:nodetypes="ssssssssscccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path3755"
+     d="m 133,84.18749 c -2.216,0 -4,1.784 -4,4 l 0,20 c 0,2.216 1.784,4 4,4 l 24,0 c 2.216,0 4,-1.784 4,-4 l 0,-20 c 0,-2.216 -1.784,-4 -4,-4 z m -2,8 8,0 0,8 -8,0 z m 10,0 8,0 0,8 -8,0 z m 10,0 8,0 0,8 -8,0 z m -20,10 8,0 0,8 -8,0 z m 10,0 8,0 0,8 -8,0 z m 10,0 8,0 0,8 -8,0 z"
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline" /><path
+     style="font-size:15.85716724px;font-style:normal;font-weight:bold;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98999999;fill:#ffffff;fill-opacity:0.99215686;stroke:none;font-family:Sans;-inkscape-font-specification:Sans Bold"
+     d="m 209.4375,-105.81251 c -2.7874,2e-5 -4.9509,0.57368 -6.4375,1.8125 -1.4866,1.23886 -2.1875,3.01034 -2.1875,5.3125 0,1.83762 0.49916,3.35352 1.5625,4.4375 0.1594,0.1608 0.37592,0.28962 0.5625,0.4375 l -4.9375,0 c -0.554,0 -1,0.3671 -1,0.875 l 0,0.1874 c 0,0.50792 0.446,0.9376 1,0.9376 l 10,0 1.75,0.4375 c 1.40402,0.30972 2.34792,0.6077 2.8125,1 0.47488,0.3923 0.74998,0.96484 0.75,1.6875 -2e-5,0.80524 -0.37084,1.4414 -1.0625,1.875 -0.6917,0.4336 -1.69922,0.625 -3,0.625 -1.28014,0 -2.61664,-0.1702 -4,-0.5625 -1.37306,-0.40262 -2.77372,-1.02788 -4.25,-1.8125 l 0,5.0625 c 1.47628,0.54716 2.9612,0.97126 4.4375,1.25 1.47628,0.2787 2.90902,0.4375 4.375,0.4375 3.1074,0 5.43022,-0.63616 6.9375,-1.875 1.51756,-1.24916 2.31248,-3.13754 2.3125,-5.6875 0,-0.89622 -0.1438,-1.7306 -0.375,-2.4375 l 3.3125,0 c 0.554,0 1,-0.4296 1,-0.9375 l 0,-0.1874 c 0,-0.50792 -0.446,-0.8751 -1,-0.8751 l -4.5,0 c -0.021,-0.021 -0.0412,-0.0418 -0.0624,-0.0624 -1.084,-1.053 -2.92942,-1.8588 -5.5,-2.375 l -2.5625,-0.5 c -1.20786,-0.24776 -2.03544,-0.5343 -2.5,-0.875 -0.45426,-0.35098 -0.68752,-0.88056 -0.6875,-1.5 -2e-5,-0.82588 0.38112,-1.42018 1.0625,-1.8125 0.68136,-0.39226 1.70032,-0.56248 3.125,-0.5625 1.07366,2e-5 2.22962,0.1484 3.4375,0.4375 1.20786,0.28908 1.98018,0.68222 3.25,1.25 l 0,-4.9375 c -1.435,-0.38196 -2.34544,-0.6267 -3.6875,-0.8125 -1.34208,-0.1962 -2.6677,-0.24998 -3.9375,-0.25 z"
+     id="path3568-3"
+     inkscape:connector-curvature="0" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 129,276.18749 0,28 6,0 0,-2 -4,0 0,-24 4,0 0,-2 z m 26,0 0,2 4,0 0,24 -4,0 0,2 6,0 0,-28 z"
+     id="rect3578-3"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccc" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 197.9375,-233.75001 -2.9375,12.25 0,1.75 2.34375,0 0,-1.75 0.5,-2.90625 2.5,0 0.5,2.90625 0,1.75 2.34375,0 0,-1.75 -2.90625,-12.25 -2.34375,0 z m 7.0625,0 0,14 4.6875,0 c 0.68312,-0.0583 1.26208,-0.20417 1.75,-0.4375 1.17106,-0.58333 1.74998,-1.60416 1.75,-3.0625 l 0,-1.15625 c -2e-5,-1.32222 -0.62982,-2.35485 -1.9375,-3.09375 0.91732,-0.42777 1.375,-1.14513 1.375,-2.15625 l 0,-0.59375 c -0.0585,-0.68055 -0.2033,-1.26388 -0.4375,-1.75 -0.58554,-1.16665 -1.62993,-1.74999 -3.09375,-1.75 l -4.09375,0 z m 13.5,0 c -0.68312,0.0583 -1.26206,0.20418 -1.75,0.4375 -1.17106,0.58335 -1.75,1.60418 -1.75,3.0625 l 0,7 c 0.0585,0.68056 0.20328,1.26389 0.4375,1.75 0.20859,0.41563 0.49244,0.73244 0.8125,1 l -1.8125,1.8125 -7.4375,7.5 -4.25,-4.25 -2.8125,2.8125 4.25,4.25 2.8125,2.8125 2.8125,-2.8125 10.4375,-10.5 c -0.10769,-0.11377 -0.62171,-0.47602 -1.1875,-0.875 l 0.625,0 c 0.6831,-0.0389 1.26208,-0.18472 1.75,-0.4375 1.17106,-0.58333 1.74998,-1.60416 1.75,-3.0625 l 0,-0.59375 -2.34375,0 0,1.1875 c -0.0586,0.77778 -0.43413,1.15625 -1.15625,1.15625 l -1.1875,0 c -0.78072,-0.0583 -1.15625,-0.4368 -1.15625,-1.15625 l 0,-8.1875 c 0.0585,-0.77777 0.43409,-1.15624 1.15625,-1.15625 l 1.1875,0 c 0.7807,0.0583 1.15625,0.43682 1.15625,1.15625 l 0,1.1875 2.34375,0 0,-0.59375 c -0.0586,-0.68055 -0.2033,-1.26388 -0.4375,-1.75 -0.58554,-1.16665 -1.5987,-1.74999 -3.0625,-1.75 l -1.1875,0 z m -19.40625,1.75 0.96875,5.84375 -1.9375,0 0.96875,-5.84375 z m 8.25,0 1.75,0 c 0.7807,0.0583 1.1875,0.43682 1.1875,1.15625 l 0,1.75 c -0.0585,0.77779 -0.46536,1.18751 -1.1875,1.1875 l -1.75,0 0,-4.09375 z m 0,5.84375 2.34375,0 c 0.78072,0.0583 1.15625,0.43681 1.15625,1.15625 l 0,2.34375 c -0.0586,0.77778 -0.43411,1.15625 -1.15625,1.15625 l -2.34375,0 0,-4.65625 z"
+     id="path4591-8"
+     inkscape:connector-curvature="0" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 129,-237.75001 0,30 10,0 0,-2.3125 0,-1.6875 0,-0.625 0,-3.375 10,0 0,2 10,0 0,-24 -30,0 z m 12,24 0,2 2,0 0,4 -2,0 0,2 6,0 0,-2 -2,0 0,-4 2,0 0,-2 -2,0 -2,0 -2,0 z"
+     id="rect6534-3"
+     inkscape:connector-curvature="0" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;fill-rule:evenodd;display:inline"
+     d="m 586.9375,-27.03126 -5.6875,5.6875 5.6875,5.6875 1.90625,-1.84375 -3.75,-3.84375 3.75,-3.75 z m 7.375,0 -4.84375,11.375 3.71875,0 5.0625,-11.34375 -3.9375,-0.0312 z m 6.25,0 -1.9375,1.9375 3.78125,3.75 -3.78125,3.84375 1.9375,1.84375 5.65625,-5.6875 z"
+     id="path4610-9"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccccc" /><path
+     sodipodi:nodetypes="sssssssscsscccccccscsssscssssssssssssssscsssscscccccccsssssssss"
+     inkscape:connector-curvature="0"
+     id="path4589-5"
+     d="m 68,-237.75001 c -1.108,0 -2,0.892 -2,2 l 0,12 c 0,1.108 0.892,2 2,2 l 7,0 c 1.108,0 2,-0.892 2,-2 l 0,-6 c 0,-1.108 -0.892,-2 -2,-2 l -5,0 0,-4 c 0,-1.108 -0.892,-2 -2,-2 z m 18,4 -6,3.875 6,4 0,-2.625 c 4.53598,0.002 6.887,2.90102 8,4.625 -0.112,-4.06048 -3.48268,-7.3724 -8,-7.375 z m -15,4 2,0 1,0 c 0,0 1,0.446 1,1 l 0,4 c 0,0.554 -0.446,1 -1,1 l -1,0 -2,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-4 c 0,-0.554 1,-1 1,-1 z m 16,8 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 4,0 c 0.554,0 1,0.446 1,1 l 0,2 c 0,0.554 -0.446,1 -1,1 l -5,0 c -1.108,0 -2,0.892 -2,2 l 0,6 c 0,1.108 0.892,2 2,2 l 6,0 2,0 c 1.108,0 2,-0.892 2,-2 l 0,-12 c 0,-1.108 -0.892,-2 -2,-2 l -1,0 z m -19,4 c 0.112,4.06048 3.48268,7.37242 8,7.375 l 0,2.5 6,-3.875 -6,-4 0,2.625 c -4.53598,-0.002 -6.887,-2.90102 -8,-4.625 z m 20,4 3,0 c 0.554,0 1,0.446 1,1 l 0,4 c 0,0.554 -0.446,1 -1,1 l -3,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-4 c 0,-0.554 0.446,-1 1,-1 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.98999999;color:#000000;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     inkscape:connector-curvature="0"
+     id="path5866-1"
+     style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98009997;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+     d="m 584.66965,-43.747414 c 1.46129,2e-5 2.48419,0.58335 3.06872,1.75001 0.2338,0.48612 0.37993,1.06945 0.43839,1.74999 l 0,7.00001 c -10e-6,1.45834 -0.58452,2.47916 -1.75355,3.0625 -0.48711,0.23333 -1.07162,0.37917 -1.75356,0.4375 l -4.67613,0 0,-14.00001 4.67613,0 m 1.16904,11.08334 0,-8.16667 c -1e-5,-0.71943 -0.38969,-1.10832 -1.16904,-1.16666 l -2.33806,0 0,10.5 2.33806,0 c 0.7209,0 1.11058,-0.38889 1.16904,-1.16667" /><path
+     inkscape:connector-curvature="0"
+     id="path5868-6"
+     style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98009997;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+     d="m 597.00773,-41.997404 -2.33807,0 0,10.5 2.33807,0 0,1.75 -7.0142,0 0,-1.75 2.33806,0 0,-10.5 -2.33806,0 0,-1.75001 7.0142,0 0,1.75001" /><path
+     inkscape:connector-curvature="0"
+     id="path5870-0"
+     style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98009997;fill:#ffffff;fill-opacity:1;stroke:none;display:inline;font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+     d="m 607.17677,-41.997404 -2.92259,12.25 -2.33807,0 -2.92258,-12.25 0,-1.75001 2.33807,0 0,1.75001 1.75354,10.5 1.75356,-10.5 0,-1.75001 2.33807,0 0,1.75001" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline"
+     d="m 223.46875,278.31249 c -5.17784,1.61214 -11.48202,1.46403 -12.53125,1.375 l 0.5,1.9375 c 1.53833,0.005 2.5625,0.0382 4.5625,-0.0781 l 0,4.70312 -6,0 0,2 6,0 0,6 -4,0 -2,0 0,10 2,0 0,-2 10,0 0,1 2,0 0,-1 0,-8 -2,0 -4,0 0,-6 6,0 0,-2 -6,0 0,-4.84375 c 2.35241,-0.16735 3.875,-0.53375 5.875,-1.25 z M 196,278.24999 l 0,2 12,0 0,-2 z m -2,4 0,2 16,0 0,-2 z m 2,4 0,2 12,0 0,-2 z m 0,4 0,2 12,0 0,-2 z m 0,4 0,10 2,0 0,-2 8,0 0,1 2,0 0,-1 0,-8 -2,0 -8,0 z m 2,2 8,0 0,4 -8,0 z m 14,0 10,0 0,4 -10,0 z"
+     id="rect4258-5"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" /><path
+     style="opacity:0.98999999;fill:#ffffff;fill-opacity:1;stroke:none;display:inline"
+     d="m 257,276.24999 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m -28,4 0,2 2,0 0,-2 -2,0 z m 4,0 0,10 0,2 0,6 10,0 0,-2 -8,0 0,-2 8,0 2,0 0,-2 -10,0 0,-2 12,0 8,0 0,-2 0,-8 -8,0 -14,0 z m 24,0 0,2 2,0 0,-2 -2,0 z m -22,2 18,0 0,2 -18,0 0,-2 z m -6,2 0,2 2,0 0,-2 -2,0 z m 28,0 0,2 2,0 0,-2 -2,0 z m -22,2 17.9374,0 0,2 -17.9374,0 0,-2 z m -6,2 0,2 2,0 0,-2 -2,0 z m 28,0 0,2 2,0 0,-2 -2,0 z m -6,3.5 -7.375,6.75 7.375,6.5625 0,-3.8125 -2.875,-2.8125 2.875,-3.0625 0,-3.625 z m 2,0 0,3.75 2.75,2.9375 -2.75,2.9375 0,3.8125 7.25,-6.75 -7.25,-6.6875 z m -24,0.5 0,2 2,0 0,-2 -2,0 z m 0,4 0,2 2,0 0,-2 -2,0 z m 0,4 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z m 4,0 0,2 2,0 0,-2 -2,0 z"
+     id="rect5051-9"
+     inkscape:connector-curvature="0" /></g><g
+   inkscape:groupmode="layer"
+   id="layer3"
+   inkscape:label="Icons"
+   style="opacity:0.98999999;display:inline"
+   transform="translate(-1,367.74999)"
+   sodipodi:insensitive="true"><rect
+     y="274.25012"
+     x="137"
+     height="28.00008"
+     width="16"
+     id="rect4452"
+     style="fill:#cccccc;fill-opacity:1;stroke:none" /><rect
+     style="fill:#cccccc;fill-opacity:1;stroke:none"
+     id="rect4367"
+     width="24"
+     height="20.000111"
+     x="133"
+     y="278.25012" /><g
+     id="g4363"
+     style="font-size:13.71140385px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:#676767;fill-opacity:1;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;font-family:Sans"
+     transform="matrix(2,0,0,2,3.0000003,-367.74989)"><path
+       sodipodi:nodetypes="csssccccccsssc"
+       inkscape:connector-curvature="0"
+       id="path4365"
+       style="font-variant:normal;font-weight:bold;font-stretch:normal;fill:#676767;stroke:#ffffff;stroke-width:2;stroke-miterlimit:4;stroke-dasharray:none;font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L Bold"
+       d="m 70.006423,329.43503 1.991763,0 c 1.837326,0 3.016509,-1.30258 3.016509,-3.33187 0,-2.00186 -1.138049,-3.09877 -3.22218,-3.09877 l -3.790777,0 0,9.99561 2.004685,0 0,-3.56497 m 0,-1.71392 0,-3.0028 1.347327,0 c 1.096911,0 1.604234,0.4799 1.604234,1.50826 0,1.01464 -0.507323,1.49454 -1.604234,1.49454 l -1.347327,0" /></g><path
+     style="fill:url(#linearGradient5768);fill-opacity:1;fill-rule:evenodd;stroke:#ffffff;stroke-width:4;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none"
+     d="m 14,339.43759 c -1.5815,0.018 -3.20062,0.68066 -4.9999999,2.75 l 0,14 0,0.5 0,1.5 0,0.0624 c 0.45016,-0.50734 0.87536,-0.90294 1.3124999,-1.25 0.3747,-0.29748 0.75862,-0.55586 1.125,-0.75 0.1248,-0.0662 0.25102,-0.1324 0.375,-0.1874 0.1664,-0.07 0.33476,-0.1358 0.5,-0.1874 0.0628,-0.021 0.1248,-0.0442 0.1874,-0.0624 0.1648,-0.0456 0.33692,-0.094 0.5,-0.125 0.018,0.002 0.0444,-0.002 0.0624,0 0.35368,-0.0632 0.71418,-0.131 1.0625,-0.125 2.73838,0.0472 5.34698,1.9999 8.0625,2.75 0.40146,0.1108 0.77966,0.2032 1.1875,0.25 0.1304,0.014 0.24392,0.0554 0.375,0.0624 0.1182,0.006 0.25616,6.2e-4 0.375,0 0.056,0.008 0.1304,0.002 0.1874,0 0.1064,-0.004 0.20652,-0.0488 0.3125,-0.0624 0.083,-0.01 0.1658,0.01 0.25,0 0.0602,-0.008 0.1272,0.01 0.1874,0 0.1922,-0.0322 0.3681,-0.133 0.5625,-0.1874 0.33684,-0.0946 0.65612,-0.20516 1,-0.375 0.0596,-0.0282 0.1274,-0.031 0.1874,-0.0624 0.03,-0.016 0.035,-0.0394 0.0624,-0.0624 0.0276,-0.0232 0.0322,-0.0458 0.0624,-0.0624 0.32472,-0.1828 0.6681,-0.36436 1,-0.625 0.0218,-0.018 0.0406,-0.045 0.0624,-0.0624 0.33604,-0.26566 0.65626,-0.51938 1,-0.875 l 0,-0.0624 0,-2 0,-12 0,-2 c -0.30804,0.32802 -0.63472,0.62818 -0.9375,0.875 -0.0218,0.018 -0.0406,0.0448 -0.0624,0.0624 -0.2779,0.22152 -0.53774,0.39276 -0.8125,0.5625 -0.0734,0.0454 -0.1768,0.0834 -0.25,0.125 -0.66642,0.37918 -1.29054,0.58736 -1.9375,0.6875 -3.88172,0.60088 -7.4416,-3.10534 -11,-3.0625 z m -8.9999999,0.8125 0,26 2,0 0,-26 -2,0 z"
+     id="path3613"
+     inkscape:connector-curvature="0"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><rect
+     style="fill:#ffffff;fill-opacity:0;stroke:none"
+     id="rect4382"
+     width="32"
+     height="32"
+     x="1"
+     y="336.25012"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><path
+     style="fill:#b8b8b8;fill-opacity:1;stroke:none"
+     d="m 129,-239.74991 0,30 10,0 0,-2.30769 0,-2.30769 0,-3.38462 10,-0.30769 0,2.30769 10,0 0,-24 z"
+     id="rect6534"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccc" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3429);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="M 70.53125,32 C 70.236645,32 70,32.23664 70,32.53125 L 70,33 69.53125,33 C 69.236645,33 69,33.23664 69,33.53125 l 0,0.9375 C 69,34.76335 69.236645,35 69.53125,35 l 1,0 2.9375,0 1,0 C 74.763355,35 75,34.76335 75,34.46875 l 0,-0.9375 C 75,33.23664 74.763355,33 74.46875,33 L 74,33 74,32.53125 C 74,32.23664 73.763355,32 73.46875,32 l -2.9375,0 z M 68,33 c -1.090704,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.909296,2 2,2 l 1,0 0,-1 -1,0 c -0.554001,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.445999,-1 1,-1 l 0,-0.46875 C 68,33.34767 68.0316,33.16464 68.09375,33 L 68,33 z m 7.90625,0 C 75.9684,33.16465 76,33.34767 76,33.53125 L 76,34 c 0.554001,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.909296,-2 -2,-2 l -0.09375,0 z M 71,38 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="path3624"
+     inkscape:connector-curvature="0" /><path
+     id="path4583"
+     d="m 162,0.99999 0,14 8.8125,0 -1,-1 -1.3125,0 -1.5,0 -3,0 -1,0 0,-12 5.5,0 3.5,3.5 0,1.21875 c 0.61468,0.76989 1,1.72879 1,2.78125 l 0,-3.5 0,-1 -4,-4 -1,0 -6,0 z m 11,8.5 c 0,0.48319 -0.20077,0.86276 -0.34375,1.28125 L 173,11.12499 l 0,-1.625 z m -4.5,-3.5 c -1.92115,0 -3.5,1.57884 -3.5,3.5 0,1.92115 1.57885,3.5 3.5,3.5 0.49539,0 0.94633,-0.12374 1.375,-0.3125 l 2.34375,2.34375 1.625,-1.625 -2.28125,-2.28125 C 171.829,10.63214 172,10.09539 172,9.49999 c 0,-1.92116 -1.57885,-3.5 -3.5,-3.5 z m -0.0312,1 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
+     style="fill:url(#linearGradient3431);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3667);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="M 166.53125,32 C 166.23664,32 166,32.23664 166,32.53125 L 166,33 165.53125,33 C 165.23664,33 165,33.23664 165,33.53125 l 0,0.9375 C 165,34.76335 165.23664,35 165.53125,35 l 1,0 2.9375,0 1,0 C 170.76336,35 171,34.76335 171,34.46875 l 0,-0.9375 C 171,33.23664 170.76336,33 170.46875,33 L 170,33 170,32.53125 C 170,32.23664 169.76336,32 169.46875,32 z M 164,33 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0317,-0.36661 0.0937,-0.53125 z m 7.90625,0 C 171.9684,33.16465 172,33.34767 172,33.53125 L 172,34 c 0.554,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z M 167,38 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 z m 0,1 7,0 0,7 -7,0 z m 1,1 0,1 0,4 1,0 1,-1 0.5,-0.50005 L 171,44 l 1,1 1,0 0,-4 0,-1 -1,0 0,3 -1,-1 -1,0 -1,1 0,-3 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="path4585"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssssccccccccccccccccccccccc" /><path
+     style="fill:url(#linearGradient6155);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="M 196.9375,132 194,144.25 l 0,1.75 2.34375,0 0,-1.75 0.5,-2.90625 2.5,0 0.5,2.90625 0,1.75 2.34375,0 0,-1.75 -2.90625,-12.25 -2.34375,0 z m 7.0625,0 0,14 4.6875,0 c 0.68312,-0.0583 1.26208,-0.20417 1.75,-0.4375 1.17106,-0.58333 1.74998,-1.60416 1.75,-3.0625 l 0,-1.15625 c -2e-5,-1.32222 -0.62982,-2.35485 -1.9375,-3.09375 0.91732,-0.42777 1.375,-1.14513 1.375,-2.15625 l 0,-0.59375 c -0.0585,-0.68055 -0.2033,-1.26388 -0.4375,-1.75 -0.58554,-1.16665 -1.62993,-1.74999 -3.09375,-1.75 L 204,132 z m 13.5,0 c -0.68312,0.0583 -1.26206,0.20418 -1.75,0.4375 -1.17106,0.58335 -1.75,1.60418 -1.75,3.0625 l 0,7 c 0.0585,0.68056 0.20328,1.26389 0.4375,1.75 l 0.0312,0 c 0.0734,0.14265 0.16363,0.28124 0.25,0.40625 0.0864,0.12501 0.18177,0.23644 0.28125,0.34375 0.0846,0.0856 0.15855,0.17355 0.25,0.25 0.57061,0.47686 1.31935,0.71875 2.25,0.71875 l 1.15625,0 c 0.59333,-0.0339 1.11708,-0.14742 1.5625,-0.34375 l 0.0312,0 c 0.0619,-0.0275 0.12831,-0.0318 0.1875,-0.0625 1.17106,-0.58333 1.74998,-1.60416 1.75,-3.0625 l 0,-0.59375 -2.34375,0 0,1.1875 c -0.0586,0.77778 -0.43413,1.15625 -1.15625,1.15625 l -1.1875,0 c -0.78072,-0.0583 -1.15625,-0.4368 -1.15625,-1.15625 l 0,-8.1875 c 0.0585,-0.77777 0.43409,-1.15624 1.15625,-1.15625 l 1.1875,0 c 0.7807,0.0583 1.15625,0.43682 1.15625,1.15625 l 0,1.1875 2.34375,0 0,-0.59375 c -0.0586,-0.68055 -0.2033,-1.26388 -0.4375,-1.75 -0.58554,-1.16665 -1.5987,-1.74999 -3.0625,-1.75 l -1.1875,0 z m -19.40625,1.75 0.96875,5.84375 -1.9375,0 0.96875,-5.84375 z m 8.25,0 1.75,0 c 0.7807,0.0583 1.1875,0.43682 1.1875,1.15625 l 0,1.75 c -0.0585,0.77779 -0.46536,1.18751 -1.1875,1.1875 l -1.75,0 0,-4.09375 z m 0,5.84375 2.34375,0 c 0.78072,0.0583 1.15625,0.43681 1.15625,1.15625 l 0,2.34375 c -0.0586,0.77778 -0.43411,1.15625 -1.15625,1.15625 l -2.34375,0 0,-4.65625 z m 8.21875,6.34375 -1.125,1.125 -7.4375,7.5 -4.25,-4.25 -2.8125,2.8125 4.25,4.25 2.8125,2.8125 2.8125,-2.8125 10.40625,-10.46875 c -0.16686,0.0246 -0.32642,0.0526 -0.5,0.0625 a 1.0001,1.0001 0 0 1 -0.0625,0 l -1.15625,0 c -1.12657,0 -2.151,-0.37304 -2.9375,-1.03125 z"
+     transform="translate(1,-367.75001)"
+     id="path4591"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     id="path4593"
+     d="m 36,99 c -1.0907,0 -2,0.90929 -2,2 l 0,7 c 0,1.0907 0.9093,2 2,2 l 8,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.09071 -0.9093,-2 -2,-2 l -8,0 z m 0,1 8,0 c 0.554,0 1,0.44599 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -8,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.55401 0.446,-1 1,-1 z m 6.59375,1.59375 L 39,105.1875 37.59375,103.75 l -1.4375,1.40625 1.4375,1.4375 L 39,108 l 5,-5 -1.40625,-1.40625 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3437);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssssssssssssssssssscccssssssccssss"
+     inkscape:connector-curvature="0"
+     id="path4595"
+     d="m 98,99 c -1.0907,0 -2,0.90929 -2,2 l 0,7 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.09071 -0.9093,-2 -2,-2 z m 0,1 12,0 c 0.554,0 1,0.44599 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -12,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.55401 0.446,-1 1,-1 z m 1.5,1 c -0.277,0 -0.5,0.22299 -0.5,0.5 0.0807,0.57703 0.3111,0.49624 1,0.5 l 0,5 -0.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.11921,-0.5 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3439);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="cccccccsssscccsssscccccccccccccccccccccccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4597"
+     d="m 333,96 -1,2 -2,0 0,1 1.5,0 -4.5,9 -1,0 -4,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.55401 0.446,-1 1,-1 l 4,0 4,0 0,-1 -8,0 c -1.0907,0 -2,0.9093 -2,2 l 0,7 c 0,1.09069 0.9093,2 2,2 l 4.5,0 -1.5,3 2,0 1.5,-3 1.5,0 0,-1 -1,0 4.5,-9 0.5,0 0,-1 1,-2 z m 2,2.28125 0,0.71875 0.71875,0 C 335.5419,98.69767 335.30232,98.4581 335,98.28125 z m 0,1.71875 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m 0,2 0,1 1,0 0,-1 z m -4,2 0,1 1,0 0,-1 z m 2,0 0,1 1,0 0,-1 z m 2,0 0,0.71875 c 0.30232,-0.17686 0.5419,-0.41643 0.71875,-0.71875 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3679);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4600"
+     d="m 2,99 c -0.554,0 -1,0.446 -1,1 l 0,9 c 0,0.55399 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.44601 1,-1 l 0,-9 c 0,-0.554 -0.446,-1 -1,-1 L 2,99 z m 0,3 12,0 0,7 -12,0 0,-7 z m 1,1 0,1 3,0 0,-1 -3,0 z m 5,0 0,2 5,0 0,-2 -5,0 z m -5,3 0,1 3,0 0,-1 -3,0 z m 5,0 0,2 5,0 0,-2 -5,0 z"
+     style="fill:url(#linearGradient3441);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     id="path4604"
+     d="m 36,195.99999 c -1.64649,0 -3,1.3535 -3,3 l 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 0.6875,-0.6875 -0.53125,-0.5625 0.65625,-0.71875 1,-1.03125 -4.3125,0 c -0.277,0 -0.5,-0.223 -0.5,-0.5 0,-0.27701 0.223,-0.5 0.5,-0.5 l 7,0 c 0.277,0 0.5,0.22299 0.5,0.5 0,0.277 -0.223,0.5 -0.5,0.5 l -1.1875,0 1,1 0.6875,0 c 0.0353,0 0.0594,-0.0277 0.0937,-0.0312 l 0.875,-0.875 c 0.004,-0.0344 0.0312,-0.0585 0.0312,-0.0938 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 l -3,0 0,-1 3,0 c 1.0907,0 2,0.90929 2,2 l 0,0.4375 0.53125,0.53125 0.4375,0.4375 c 0.019,-0.13548 0.0312,-0.26585 0.0312,-0.40625 l 0,-1 c 0,-1.6465 -1.35351,-3 -3,-3 l -3,0 -1,1 -1,-1 -3,0 z m 0,1 3,0 0,1 -3,0 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,1 -3,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-1 c 0,-1.09071 0.9093,-2 2,-2 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3677);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssscccsssscccssccssssccsssscssssccssssccsssssss"
+     inkscape:connector-curvature="0"
+     id="path4606"
+     d="m 4,196 c -1.64649,0 -3,1.3535 -3,3 l 0,1 c 0,1.64649 1.35351,3 3,3 l 3,0 1,-1 1,1 3,0 c 1.64649,0 3,-1.35351 3,-3 l 0,-1 c 0,-1.6465 -1.35351,-3 -3,-3 l -3,0 -1,1 -1,-1 z m 0,1 3,0 0,1 -3,0 c -0.554,0 -1,0.44599 -1,1 l 0,1 c 0,0.554 0.446,1 1,1 l 3,0 0,1 -3,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-1 c 0,-1.09071 0.9093,-2 2,-2 z m 5,0 3,0 c 1.0907,0 2,0.90929 2,2 l 0,1 c 0,1.0907 -0.9093,2 -2,2 l -3,0 0,-1 3,0 c 0.554,0 1,-0.446 1,-1 l 0,-1 c 0,-0.55401 -0.446,-1 -1,-1 l -3,0 z m -4.5,2 7,0 c 0.277,0 0.5,0.22299 0.5,0.5 0,0.277 -0.223,0.5 -0.5,0.5 l -7,0 C 4.223,200 4,199.777 4,199.5 4,199.22299 4.223,199 4.5,199 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3675);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4608"
+     d="m 68,129.96875 0,6.5 c 0,0.6818 0.0818,1.2882 0.21875,1.84375 0.13694,0.55554 0.35886,1.04609 0.6875,1.4375 0.32865,0.3914 0.76476,0.6916 1.3125,0.90625 0.56144,0.20201 1.24087,0.28125 2.0625,0.28125 0.8353,0 1.53231,-0.0792 2.09375,-0.28125 0.56143,-0.21465 1.03265,-0.51485 1.375,-0.90625 0.34233,-0.39141 0.5818,-0.88196 0.71875,-1.4375 0.13697,-0.55555 0.18749,-1.16195 0.1875,-1.84375 l 0,-6.5 -2.5,0 0,6.3125 c -1.1e-4,0.49241 -0.039,0.9091 -0.0937,1.25 -0.0548,0.32828 -0.14432,0.59785 -0.28125,0.8125 -0.13695,0.20201 -0.32971,0.34911 -0.5625,0.4375 -0.23279,0.0884 -0.51896,0.15625 -0.875,0.15625 -0.35604,0 -0.67347,-0.0679 -0.90625,-0.15625 -0.2328,-0.0884 -0.39431,-0.23549 -0.53125,-0.4375 -0.12325,-0.20202 -0.22648,-0.45297 -0.28125,-0.78125 -0.0548,-0.3409 -0.0625,-0.75759 -0.0625,-1.25 l 0,-6.34375 -2.5625,0 z M 67.5,142 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 10,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -10,0 z"
+     style="font-size:15.23443031px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3443);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4610"
+     d="m 586.9375,-29.03126 -5.6875,5.6875 5.6875,5.6875 1.90625,-1.84375 -3.75,-3.84375 3.75,-3.75 z m 7.375,0 -4.84375,11.375 3.71875,0 5.0625,-11.34375 -3.9375,-0.0312 z m 6.25,0 -1.9375,1.9375 3.78125,3.75 -3.78125,3.84375 1.9375,1.84375 5.65625,-5.6875 z"
+     style="fill:url(#linearGradient5750);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     sodipodi:nodetypes="cccccccccccccccccccc" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient6173);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 145,707 c -4.36281,0 -8,3.63719 -8,8 l 0,3 -1,0 c -1.108,0 -2,0.89198 -2,2 l 0,12 c 0,1.108 0.892,2 2,2 l 18,0 c 1.108,0 2,-0.892 2,-2 l 0,-12 c 0,-1.10802 -0.892,-2 -2,-2 l -1,0 0,-3 c 0,-4.36281 -3.63719,-8 -8,-8 z m 0,4 c 2.216,0 4,1.784 4,4 l 0,3 -8,0 0,-3 c 0,-2.216 1.784,-4 4,-4 z m 0,13 c 1.65686,0 3,1.34314 3,3 0,1.65684 -1.34314,3 -3,3 -1.65686,0 -3,-1.34316 -3,-3 0,-1.65686 1.34314,-3 3,-3 z"
+     transform="translate(1,-367.75001)"
+     id="path4612"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     id="path4614"
+     d="m 68,210.24999 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 7,0 c -2.1814,0 -4,1.8186 -4,4 l 0,20 c 0,2.1814 1.8186,4 4,4 2.1814,0 4,-1.8186 4,-4 l 0,-20 c 0,-2.1814 -1.8186,-4 -4,-4 z m 0,2 c 1.108,0 2,0.892 2,2 l 0,20 c 0,1.108 -0.892,2 -2,2 -1.108,0 -2,-0.892 -2,-2 l 0,-20 c 0,-1.108 0.892,-2 2,-2 z m -23,2 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -16,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -16,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 16,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -16,4 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m 4,0 c -0.55228,0 -1,0.44772 -1,1 0,0.55228 0.44772,1 1,1 0.55228,0 1,-0.44772 1,-1 0,-0.55228 -0.44772,-1 -1,-1 z m -13,4 c -2.1814,0 -4,1.8186 -4,4 0,2.1814 1.8186,4 4,4 l 10,0 c 2.1814,0 4,-1.8186 4,-4 0,-2.1814 -1.8186,-4 -4,-4 l -10,0 z m 0,2 10,0 c 1.108,0 2,0.892 2,2 0,1.108 -0.892,2 -2,2 l -10,0 c -1.108,0 -2,-0.892 -2,-2 0,-1.108 0.892,-2 2,-2 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient5746);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans" /><path
+     id="path4616"
+     d="m 579,-163.74989 28,0 0,10 -28,0 z"
+     style="fill:#c4c4c4;fill-opacity:1;stroke:none"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient3451);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 35.3298,257.02118 c -1.28605,0 -2.3298,1.04375 -2.3298,2.3298 l 0,9.31921 C 33,269.95625 34.04375,271 35.3298,271 l 9.31921,0 c 1.28606,0 2.3298,-1.04375 2.3298,-2.32981 l 0,-9.31921 c 0,-1.28605 -1.04374,-2.3298 -2.3298,-2.3298 z m 3.80414,2.33622 1.79284,0 0.11832,0.212 3.64032,9.10079 -2.3298,0 -0.87368,-2.29339 -3.02147,0 -0.87367,2.29339 -2.257,0 3.64032,-8.88237 z"
+     id="path4618"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssccccccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:#4b4b4b;fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 40.57171,265.23621 -1.16491,0 c -0.3215,0 -0.58244,-0.26094 -0.58244,-0.58246 l 1.1381,-2.19467 1.19286,2.19467 c -8.7e-4,0.32152 -0.2621,0.58246 -0.58361,0.58246 z"
+     id="path4620"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscccs"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="cccccccccccc"
+     style="fill:url(#linearGradient3453);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 66,193 0,14 1,0 0,-14 z m 4.74999,-0.41664 c -0.86983,0.009 -1.76033,0.34033 -2.74999,1.375 L 68,202 c 3.96132,-4.05865 6.94268,2.81598 11,-1 l 0,-8.04165 c -3.03099,2.934 -5.64051,-0.40352 -8.25001,-0.37496 z"
+     id="path4622"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="cccccccccccccsssssss"
+     inkscape:connector-curvature="0"
+     id="path4624"
+     d="m 201.71875,138.21875 -0.96875,0.90625 1.90625,1.96875 -1.90625,1.96875 0.96875,1 1.90625,-1.96875 1.96875,1.96875 0.96875,-1 -1.9375,-1.96875 1.9375,-1.96875 -0.96875,-0.90625 -1.96875,1.90625 z M 193.5,141 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z"
+     style="fill:url(#linearGradient3455);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ccccccc"
+     style="fill:url(#linearGradient3457);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 232,35 -7,5 6.99998,4.99998 2e-5,-3.33332 c 3.41666,0 5.61556,1.22 7,3.33334 0,-4.98333 -3.60112,-6.66667 -7,-6.66667 2e-5,-0.85078 1e-5,-2.61388 0,-3.33333 z"
+     id="path4626"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3459);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 417.99999,163 0,2 12.00001,0 0,-2 -12.00001,0 z m 0,3 0,1.99999 12.00001,0 0,-1.99999 -12.00001,0 z m 0,3 0,2 12.00001,0 0,-2 -12.00001,0 z m 0,2.99999 0,2.00001 12.00001,0 0,-2.00001 -12.00001,0 z"
+     id="path4628"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3461);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 391,163 0,2 7,0 0,-2 -7,0 z m -4,3 0,1.99999 11,0 0,-1.99999 -11,0 z m 2,3 0,2 9,0 0,-2 -9,0 z m -3,3 0,2 12,0 0,-2 -12,0 z"
+     id="path4630"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(1.9740024,0,0,1.9740042,10.515129,-363.4347)"
+     style="fill:url(#linearGradient3463);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 355.8683,162.96049 0,2.02634 8.10536,0 0,-2.02634 -8.10536,0 z M 353.84196,166 l 0,2.02633 12.15804,0 0,-2.02633 -12.15804,0 z m 2.02634,3.0395 0,2.02634 8.10536,0 0,-2.02634 -8.10536,0 z m -2.02634,3.03951 0,2.02634 12.15804,0 0,-2.02634 -12.15804,0 z"
+     id="path4632"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient3465);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 322,163 0,2 7,0 0,-2 -7,0 z m 0,3 0,2 11,0 0,-2 -11,0 z m 0,3 0,2 9,0 0,-2 -9,0 z m 0,3 0,2 12,0 0,-2 -12,0 z"
+     id="path4634"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3467);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="M 13.143585,33.05435 9.0166293,38.06353 4.9286104,33.12695 c 0,0 -0.8954698,0.0269 -0.8954698,1.05265 0,2.21508 1.5511147,4.31748 3.2704133,5.95293 l -1.7909395,2.17791 0.1167447,0.14519 c -0.089703,-0.009 -0.1790976,-0.0363 -0.2725383,-0.0363 -1.3754463,0 -2.4917443,1.04074 -2.4917443,2.3231 0,1.28234 1.116298,2.3231 2.4917443,2.3231 1.3754463,0 2.4917443,-1.04076 2.4917443,-2.3231 0,-0.69345 -0.3382551,-1.31604 -0.8565423,-1.74234 0.4809109,-0.30316 1.2134856,-0.78955 2.0245504,-1.41563 0.8322385,0.64465 1.5928458,1.16764 2.1024048,1.48823 -0.478416,0.42398 -0.778669,1.00648 -0.778669,1.66974 0,1.28234 1.116298,2.3231 2.491745,2.3231 1.375446,0 2.491744,-1.04076 2.491744,-2.3231 0,-1.28236 -1.115055,-2.32427 -2.491744,-2.3231 -0.06354,0 -0.132378,0.0317 -0.194665,0.0363 l 0.03887,-0.0363 -1.907749,-2.28681 c 1.695639,-1.60874 3.231485,-3.67659 3.231485,-5.84404 0,-1.11857 -0.856533,-1.23414 -0.856533,-1.23414 z M 5.3568862,43.58089 c 0.6877138,0 1.2458722,0.52037 1.2458722,1.16154 0,0.64118 -0.5581584,1.16155 -1.2458722,1.16155 -0.6877231,0 -1.2458721,-0.52037 -1.2458721,-1.16155 0,-0.64117 0.558149,-1.16154 1.2458721,-1.16154 z m 7.4752328,0 c 0.687714,0 1.245872,0.52037 1.245872,1.16154 0,0.64118 -0.558158,1.16155 -1.245872,1.16155 -0.687723,0 -1.245872,-0.52037 -1.245872,-1.16155 0,-0.64117 0.558149,-1.16154 1.245872,-1.16154 z"
+     id="path4636"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssscszsczcc"
+     inkscape:connector-curvature="0"
+     id="path4638"
+     d="m 136,224.96874 c -3.86517,0 -7,3.14713 -7,7.03125 0,3.88412 3.13483,7.03125 7,7.03125 3.86633,0 7,-3.14713 7,-7.03125 0,-3.88412 -3.13367,-7.03125 -7,-7.03125 z m 0,1.03125 c 3.31371,0 6,2.68629 6,6 0,3.31371 -2.68629,6 -6,6 -3.31371,0 -6,-2.68629 -6,-6 0,-3.31371 2.68629,-6 6,-6 z m -2.34375,3 c -0.78758,0 -1.40625,0.64605 -1.40625,1.4375 0,0.79145 0.61867,1.4375 1.40625,1.4375 0.78761,0 1.4375,-0.64605 1.4375,-1.4375 0,-0.79145 -0.64989,-1.4375 -1.4375,-1.4375 z m 4.6875,0 c -0.7876,0 -1.4375,0.64605 -1.4375,1.4375 0,0.79145 0.6499,1.4375 1.4375,1.4375 0.78759,0 1.40625,-0.64605 1.40625,-1.4375 0,-0.79145 -0.61866,-1.4375 -1.40625,-1.4375 z m -5.23219,4.77513 c -0.0366,0.1544 -0.081,0.31581 -0.081,0.4768 0,1.55998 2.42289,1.8242 2.96945,1.81057 0.54656,-0.0136 2.96945,-0.25059 2.96945,-1.81057 0,-0.16099 -0.0444,-0.3224 -0.081,-0.4768 -1.30709,1.24337 -2.63751,1.02963 -2.88845,1.05774 -0.25094,0.0281 -2.02946,-0.0474 -2.88844,-1.05774 z"
+     style="fill:url(#linearGradient3469);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(2.1141636,0,0,2.1141636,-28.338578,-386.41917)"
+     sodipodi:nodetypes="cssccscccssccscc"
+     style="fill:url(#linearGradient3471);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 259.65386,163.531 c -1.472,0 -2.66666,1.24939 -2.66666,2.53241 0,1.28301 1.19466,2.3243 2.66666,2.3243 0.0453,0 0.0811,8.7e-4 0.12493,0 -0.196,1.29812 -0.87033,2.97394 -2.79166,4.64861 1.33333,0 5.33332,-2.32431 5.33332,-6.97291 0,-1.28302 -1.19466,-2.53241 -2.66666,-2.53241 z m 7.99998,0.026 c -1.472,0 -2.66666,1.22337 -2.66666,2.50639 0,1.28302 1.19466,2.32431 2.66666,2.32431 0.048,0 0.0784,8.7e-4 0.12493,0 -0.196,1.28069 -0.86633,2.93413 -2.79166,4.61228 1.37466,0 5.33332,-2.28798 5.33332,-6.93659 0,-1.28302 -1.19466,-2.50639 -2.66666,-2.50639 z"
+     id="path4640"
+     inkscape:connector-curvature="0" /><path
+     style="fill:url(#linearGradient3473);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 40,225 c -3.86517,0 -7,3.13483 -7,6.99999 0,3.86518 3.13483,7.00001 7,7.00001 3.86633,0 7,-3.13483 7,-7.00001 C 47,228.13483 43.86633,225 40,225 z m 2.47916,2.29688 c 0.62773,-0.0298 1.3338,0.21291 2.1875,0.80207 -1.27516,0 -2.10904,1.30666 -2.88021,2.91667 l 1.4948,0 c 0.25783,0 0.4375,0.24325 0.4375,0.51041 l -1.16667,1.64063 -1.75,0 c -1.19233,2.56317 -2.57892,4.74454 -5.46875,2.73437 1.33233,-0.003 2.17992,-1.54671 2.98958,-3.31769 l 0.21875,-0.47398 c 1.0115,-2.26011 2.05434,-4.72275 3.9375,-4.81248 z"
+     id="path4642"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ssssscccsccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4644"
+     d="M 7,6 7,7.875 5.625,9.34375 7,10.8125 7,12.71875 3.375,9.34375 z"
+     style="fill:url(#linearGradient3475);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4646"
+     d="M 8,6 11.6875,9.375 8,12.65625 8,10.75 9.4375,9.34375 8,7.8125 z"
+     style="fill:url(#linearGradient3477);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sccsscccssscsssssss"
+     style="fill:url(#linearGradient3479);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 8.4001919,321 c -2.5311594,0 -4.5833578,2.05219 -4.5833578,4.58335 l 2.2916789,0 c 0,-1.26501 1.0266722,-2.29168 2.2916789,-2.29168 1.2650067,0 2.2916801,1.02667 2.2916801,2.29168 0,1.265 -1.0266734,2.29168 -2.2916801,2.29168 -0.8015237,0.007 -1.2388122,0.57905 -1.1458394,1.14585 l 0,1.0026 0,0.14323 c 0,0.6325 0.5133366,1.14584 1.1458394,1.14584 0.6325038,0 1.1458394,-0.51334 1.1458394,-1.14584 l 0,-0.14323 C 11.522604,329.51358 12.98355,327.71804 12.98355,325.58335 12.98355,323.05219 10.931351,321 8.4001919,321 z m 0,11.00442 c -0.8830925,0 -1.5998062,0.71671 -1.5998062,1.59981 0,0.88308 0.7167137,1.5998 1.5998062,1.5998 0.8830935,0 1.5998062,-0.71672 1.5998062,-1.5998 0,-0.8831 -0.7167127,-1.59981 -1.5998062,-1.59981 z"
+     id="path4648"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3481);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 35.34264,356.37095 c 0.51469,-0.51344 1.34901,-0.51344 1.86244,0 L 40,359.15957 l 2.79492,-2.78862 c 0.51469,-0.51344 1.34901,-0.51344 1.86244,0 0.51469,0.51344 0.51469,1.34524 0,1.85992 l -2.79492,2.78989 2.79492,2.78864 c 0.51469,0.51341 0.51469,1.34648 0,1.85992 -0.51469,0.51343 -1.34901,0.51343 -1.86244,0 L 40,362.87943 l -2.79492,2.78989 c -0.51469,0.51343 -1.34901,0.51343 -1.86244,0 -0.51469,-0.51344 -0.51469,-1.34651 0,-1.85992 l 2.79492,-2.78864 -2.79492,-2.78989 c -0.51469,-0.51468 -0.51469,-1.34774 0,-1.85992 z"
+     id="path4651"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3483);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 136.90909,352.99999 0,7.08065 4.69598,-3.57702 z m -1.17399,2.32963 c -3.2461,0 -5.86997,2.66057 -5.86997,5.90666 0,3.24609 2.62387,5.86997 5.86997,5.86997 3.24609,0 5.86997,-2.62388 5.86997,-5.86997 l 0,-0.0366 -2.34799,0 c 0,1.9453 -1.57667,3.52198 -3.52198,3.52198 -1.94531,0 -3.52198,-1.57668 -3.52198,-3.52198 0,-1.94531 1.57667,-3.52198 3.52198,-3.52198 0.41441,0 0.80535,0.0898 1.17399,0.22013 l 0,-2.42137 c -0.37685,-0.0763 -0.77484,-0.14675 -1.17399,-0.14675 z"
+     id="path4653"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccsssccssscccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3485);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 168.63108,225.60711 c -3.68133,0 -6.66665,2.71633 -6.66665,6.04164 0,2.46666 1.64933,4.56932 3.99999,5.49999 l 0,0.5 -2.66666,0 0,-0.66667 c 0,-0.36933 -0.29733,-0.66666 -0.66667,-0.66666 -0.36933,0 -0.66666,0.29733 -0.66666,0.66666 l 0,1.33333 c 0,0.36933 0.29733,0.66667 0.66666,0.66667 l 3.99999,0 c 0.368,0 0.66667,-0.29867 0.66667,-0.66667 l 0,-0.79166 0,-0.54167 0,-0.83333 c -1.55066,-0.66266 -2.66666,-2.40533 -2.66666,-4.49999 0,-2.65998 1.79066,-4.83331 3.99999,-4.83331 2.20933,0 3.99999,2.17333 3.99999,4.83331 0,2.09466 -1.116,3.83599 -2.66666,4.49999 l 0,0.83333 0,0.54167 0,0.79166 c 0,0.368 0.29866,0.66667 0.66666,0.66667 l 3.99999,0 c 0.0924,0 0.17019,-0.008 0.25,-0.0416 0.23926,-0.1012 0.41667,-0.349 0.41667,-0.625 l 0,-1.33333 c 0,-0.36933 -0.29733,-0.66667 -0.66667,-0.66667 -0.36933,0 -0.66666,0.29734 -0.66666,0.66667 l 0,0.66666 -2.66666,0 0,-0.5 c 2.35066,-0.93066 3.99999,-3.03332 3.99999,-5.49998 0,-3.32531 -2.98399,-6.04164 -6.66665,-6.04164 z"
+     id="path4655"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     id="path4657"
+     d="m 264,224.99999 c -3.86516,0 -7,3.13484 -7,7 0,3.86516 3.13484,7 7,7 3.86516,0 7,-3.13484 7,-7 0,-3.86516 -3.13484,-7 -7,-7 z m 0,1 c 0.57563,0 1.12928,0.0987 1.65625,0.25 -0.21686,0.024 -0.40509,0.0414 -0.21875,0.0625 0.60892,0.003 -0.1276,0.039 -0.1875,0.125 -0.11394,0.0829 -0.0834,0.026 -0.15625,0.125 -0.11101,0.005 -0.16343,0.0248 -0.1875,0.0312 0.0628,0.0123 0.21665,0.0288 0.3125,0.0312 0.26795,-0.0538 0.54333,-0.1539 0.8125,-0.25 0.0491,0.0177 0.10773,0.0123 0.15625,0.0312 -0.057,0.0184 -0.10829,0.071 -0.15625,0.0625 -0.34875,0.25862 0.70213,-0.0275 0.59375,0.46875 0.0904,0.035 0.0426,-0.16732 0.0312,-0.3125 1.98416,0.97877 3.34375,3.01293 3.34375,5.375 0,2.96499 -2.14232,5.42075 -4.96875,5.90625 0.002,-0.0351 -0.001,-0.0564 0,-0.0937 -0.0607,-0.31041 0.3513,-0.15238 0.375,-0.4375 -0.14618,-0.10055 -0.18095,-0.21709 -0.1875,-0.34375 -0.0227,-0.40268 0.15775,-0.34927 0,0 0.0223,0.0426 0.0716,0.0718 0.125,0.0937 0.0738,0.0209 0.14565,0.10949 0.21875,0.0312 0.41021,-0.33369 0.12457,-1.07604 0.71875,-1.15625 0.47136,-0.164 0.14359,-0.87555 0.4375,-1.1875 0.53462,-0.47621 -0.2551,-0.89849 -0.6875,-0.78125 -0.0559,-0.0857 -0.27353,-0.28009 -0.5,-0.0625 0.15857,-0.1649 -0.008,-0.23324 -0.25,-0.0312 0.24467,-0.17708 0.25848,-0.47377 -0.0625,-0.65625 -0.0508,9.9e-4 -0.10507,-0.004 -0.125,0.0312 -0.0638,-0.0687 -0.22894,-0.0608 -0.28125,0.0312 -0.0101,-0.0804 -0.0318,-0.15944 -0.0625,-0.1875 -0.12961,-0.14754 -0.16689,-0.11264 -0.1875,-0.0312 0.0112,-0.0474 0.002,-0.10756 0,-0.15625 -0.32535,-0.0722 -0.953,-0.49438 -1,0 0.002,-0.20286 -0.0586,-0.23675 -0.0937,-0.1875 0.0276,-0.0332 0.0683,-0.0615 0.125,-0.0937 -0.23557,0.0464 -0.5475,0.32011 -0.5625,0.5625 0.0648,0.41584 -0.42384,0.78976 -0.1875,1.0625 -0.0185,-0.003 -0.0422,0.0103 -0.0625,0 0.20991,0.41324 0.44408,0.73866 0.65625,1.0625 0.23031,0.0604 0.44985,0.14475 0.5625,0.3125 -0.17222,-0.0166 -0.26928,-0.0451 -0.40625,-0.0625 0.17318,0.2949 0.31495,0.60124 0.375,1 0.0695,0.54303 0.19023,1.00029 0.3125,1.375 -0.0919,0.004 -0.18828,0 -0.28125,0 -3.31371,0 -6,-2.6863 -6,-6 0,-1.4656 0.53344,-2.80175 1.40625,-3.84375 0.34206,-0.0211 0.7743,0.12805 0.75,0.4375 0.0307,0.0446 0.0539,0.0428 0.0625,0.0312 -0.0741,0.19641 -0.23979,0.37414 0.0937,0.5625 0.22757,0.0776 -0.005,-0.0939 -0.125,0.1875 -0.18886,-0.0161 -0.54745,0.56888 -0.53125,0.875 -0.006,0.28224 0.15163,0.47561 0.375,0.5625 -0.16645,0.0629 -0.0795,0.49173 0.0937,0.625 0.234,0.59128 0.0786,-0.21992 -0.0625,-0.40625 0.1184,-0.41868 0.28654,0.49131 0.5,0.59375 0.0459,0.40021 0.30654,0.5924 0.6875,0.71875 0.1724,0.007 0.42696,0.0904 0.5625,0 -0.0572,0.0939 -0.0543,0.2011 0.0937,0.21875 0.0497,0.0166 0.18315,0.0719 0.21875,0 0.0368,0.0175 0.10148,0.0198 0.15625,-0.0312 0.0432,-0.0198 0.0361,0.0124 0.0625,0 -0.11865,0.0885 -0.24679,0.23155 0.0312,0.28125 0.18197,0.12198 0.21951,-0.59882 -0.0312,-0.46875 -0.27053,-0.0764 -0.31824,0.10185 -0.25,0.1875 -0.38423,0.10029 0.48507,-0.80377 -0.0312,-0.71875 -0.14636,0.36457 -0.72915,0.44313 -0.71875,-0.0625 0.0733,-0.11228 0.0576,-0.29508 0,-0.4375 0.0762,0.0536 0.14828,-0.0524 0.25,-0.1875 0.0508,-0.20201 0.45865,-0.11762 0.5625,-0.125 -0.007,-0.008 -0.0149,-0.019 -0.0312,-0.0312 0.34794,-0.17518 0.70785,0.0435 0.71875,0.4375 0.0727,0.0592 0.0799,-0.14085 0.0937,-0.15625 -0.34271,-0.59064 0.60005,-0.61065 0.53125,-1.09375 0.086,0.0703 0.16097,-0.25555 0.46875,-0.34375 0.0156,-0.0612 0.5408,-0.25245 0.5625,-0.5625 l 0.0312,-0.0625 c -0.0777,0.58493 0.56903,-0.28504 0.125,-0.125 -0.48342,0.25168 -0.0186,-0.16425 0.21875,-0.15625 0.2339,0.10315 1.13432,-0.3299 0.59375,-0.375 -0.14861,0.004 0.0197,-0.83907 -0.375,-0.375 -0.18201,-0.013 -0.21657,-0.52148 -0.59375,-0.28125 -0.21308,0.35773 -0.42379,0.80911 -0.78125,0.96875 0.10551,-0.34815 -0.17558,-0.37355 -0.4375,-0.46875 -0.50037,-0.22009 0.22843,-0.53767 0.40625,-0.65625 0.42598,0.0488 0.0804,-0.2331 0.40625,-0.1875 0.25965,0.11567 0.79746,-0.45867 0.3125,-0.25 -0.34093,0.38477 -0.21848,-0.29476 -0.5,-0.15625 -0.0588,0.36258 -0.54949,0.31735 -0.9375,0.28125 -0.20901,0.22494 -0.18621,0.0524 -0.40625,0.0312 -0.22948,-0.0557 -0.62539,-0.2074 -1.03125,-0.125 -0.42791,0.0153 -0.77707,0.13054 -1.09375,0.375 0.18446,-0.14534 0.37067,-0.28434 0.3125,-0.34375 -0.13804,-0.0294 -0.26862,-0.0577 -0.40625,-0.0625 1.0158,-0.78806 2.2713,-1.2811 3.6564,-1.2811 z m -0.40625,9.625 c -0.0485,-0.0827 -0.10312,-0.16891 -0.15625,-0.25 -0.72058,-0.18902 -1.52571,0.0359 0.15625,0.25 z m 1.34375,-9.28125 c -0.10926,0.002 -0.25181,0.0495 -0.15625,0.125 l 0.125,0 c 0.22132,-0.0858 0.14056,-0.12682 0.0312,-0.125 z m -0.34375,0.34375 c -0.14885,0.0202 -0.1519,0.1631 0.15625,0.0937 0.007,0.066 0.1702,-0.0245 0.1875,0.0312 0.48589,-0.054 0.0831,-0.1527 -0.15625,-0.0937 -0.0717,-0.0408 -0.13788,-0.038 -0.1875,-0.0312 z m 0.0625,0.15625 c -0.012,-0.0131 -0.0364,0.004 -0.125,0.0625 -0.53787,0.41757 0.48274,0.0767 0.59375,0.34375 0.375,0.26203 -0.0911,0.19656 -0.28125,0.3125 -0.0495,0.0102 -0.0367,0.0257 -0.0625,0.0312 0.11906,0.007 0.28635,0.0602 0.3125,0.1875 l 0.0625,0.0312 c 0.31303,0.0938 -0.14015,-0.27069 0.25,-0.0937 -0.0154,-0.25514 0.0288,-0.26175 0.28125,-0.21875 -0.016,-0.36645 -0.58414,-0.66376 -0.96875,-0.5625 -0.23333,0.21055 -0.0265,-0.0545 -0.0625,-0.0937 z m -0.46875,0.0312 c -0.0468,0.0133 -0.0929,0.0396 -0.125,0.0937 0.0235,0.001 0.0376,0.0331 0.0625,0 0.33051,-0.0263 0.20282,-0.13358 0.0625,-0.0937 z m -1.5625,0.0312 c -0.17974,0.004 -0.43759,0.0773 -0.4375,0.25 0.11636,0.04 0.22509,-0.1096 0.34375,-0.125 0.35814,-0.0741 0.27354,-0.12883 0.0937,-0.125 z m 1.21875,0 c -0.12212,0.0231 -0.25374,0.0844 -0.125,0.125 l 0.0312,0.0312 0.0937,-0.0312 c 0.22922,-0.13332 0.12212,-0.14807 0,-0.125 z m -0.90625,0.0625 c -0.28655,0.0128 -0.61607,0.21385 -0.1875,0.25 -0.20655,0.0632 -0.46416,0.0131 -0.0625,0.125 0.24304,-0.0302 1.03903,-0.0694 0.625,-0.21875 0.16188,-0.2552 -0.0305,-0.0918 -0.15625,-0.0937 -0.0543,-0.0446 -0.12323,-0.0668 -0.21875,-0.0625 z m 0.71875,0.25 c -0.0294,0.007 -0.0677,0.0411 -0.0937,0.0937 0.23501,0.0305 0.18187,-0.11393 0.0937,-0.0937 z m 2.96875,0 c -0.1229,0.0647 -0.30864,0.56687 0,0.625 0.19641,0.13297 0.0343,-0.35877 0.0625,-0.5 -0.008,-0.10783 -0.0215,-0.14656 -0.0625,-0.125 z m -4.65625,0.3125 c 0.0326,-0.004 0.0441,-0.007 0.0312,0.0312 -0.33578,0.11083 -0.12904,-0.0181 -0.0312,-0.0312 z m 2.3125,0.0625 c -0.1313,-0.0266 -0.39703,0.19962 0,0.125 l 0.0625,0 c 0.0111,-0.0813 -0.0187,-0.11612 -0.0625,-0.125 z m -4.0625,0.78125 c 0.006,0.0143 0.0299,0.014 0.0312,0.0312 0.008,0.0435 -0.0235,0.085 -0.0312,0.125 -0.003,-0.0643 -0.009,-0.12364 0,-0.15625 z M 260,228.56249 c -0.009,0.006 -0.007,0.021 0,0.0625 0.0968,0.0138 0.0264,-0.0815 0,-0.0625 z m 5.5625,0.28125 c -0.0981,0.006 -0.34815,0.29505 -0.21875,0.28125 0.13337,0.0266 0.64304,-0.01 0.25,-0.15625 0.021,-0.0859 9.5e-4,-0.12697 -0.0312,-0.125 z m -5.53125,0.21875 c -0.0218,-0.001 -0.0245,0.0399 0.0312,0.125 0.30923,0.16511 0.034,-0.12127 -0.0312,-0.125 z m 4.875,0.1875 c -0.0184,-7.1e-4 -0.051,0.0101 -0.0937,0.0312 0.0994,0.0455 0.14896,-0.0291 0.0937,-0.0312 z m 0.125,0.0312 c -0.13693,0.0377 -0.38348,0.14021 -0.4375,0.25 0.10313,-1.8e-4 0.18325,-0.1022 0.28125,-0.125 0.32049,-0.15288 0.29318,-0.16268 0.15625,-0.125 z m -6.375,1 c -0.0116,-0.007 -0.0552,0.0257 -0.0937,0.0937 0.0414,0.1895 0.12849,-0.0728 0.0937,-0.0937 z m 1.5,0.53125 c 0.052,0.004 0.0833,0.0625 0.125,0.0937 -0.0524,-0.0363 -0.0856,-0.0794 -0.125,-0.0937 z m 2.4375,0.8125 c -0.0385,0.01 -0.0523,0.0335 -0.0625,0.0625 0.0946,-0.044 0.49211,0.15054 0.6875,0.21875 0.48854,0.0204 -0.35512,-0.34821 -0.625,-0.28125 z m 0.90625,0.28125 c -0.0182,-0.002 0.003,0.0237 0.0312,0.0937 -0.19576,0.095 -0.24616,0.0339 0.0312,0.0625 0.0616,0.0235 0.0953,0.025 0.0937,0 0.38314,0.0396 0.0666,-0.24469 -0.0312,-0.0625 -0.0308,-0.0484 -0.0997,-0.0915 -0.125,-0.0937 z m 0.53125,0.0938 c -0.0231,2.4e-4 -0.0377,0.0285 -0.0625,0.0625 0.0442,0.0146 0.0742,0.003 0.0937,0 -0.009,-0.0182 -0.005,-0.0628 -0.0312,-0.0625 z m -1.96875,0.0625 c 0.065,-0.0272 0.0304,0.0826 0,0.1875 -0.0131,-0.0878 -0.1107,-0.0462 -0.1875,0.0312 0.0164,-0.0269 0.0254,-0.0519 0.0312,-0.0937 0.0937,-0.0718 0.12538,-0.11212 0.15625,-0.125 z m 0.9375,0 c -0.008,0.003 -0.012,0.0121 0,0.0312 0.23882,0.0542 0.0924,-0.0358 0.0312,-0.0312 -0.0102,5e-4 -0.023,-0.003 -0.0312,0 z m 1.46875,0.75 c -0.0101,0.006 -0.0453,-0.003 -0.0625,0.0312 0.0396,0.0611 0.061,0.007 0.0625,-0.0312 z m -2.1875,0.0312 c -0.0104,0.0169 0.0106,0.052 0.15625,0.15625 0.36178,0.0251 -0.12511,-0.20702 -0.15625,-0.15625 z m 0.34375,0.1563 c -0.0422,0.0167 -0.0392,0.0395 0.0312,0.0937 0.0799,0.0985 0.14452,-0.0616 0.21875,-0.0937 -0.0966,-0.016 -0.19592,-0.0213 -0.25,0 z m 0.28125,0 c 0.0269,0.001 0.0379,0.0223 0.0625,0.0937 0.12084,-0.0286 0.0505,-0.0711 -0.0625,-0.0937 z m 0.59375,0.0625 c 0.0151,0.0164 0.0447,0.016 0.0625,0.0312 -0.0224,-0.004 -0.0368,0.002 -0.0625,0 -0.006,-0.01 0.005,-0.0214 0,-0.0312 z m 0.71875,0.0937 c 0.0918,-0.004 0.19416,0.006 0.3125,0.0312 -0.93272,0.60426 -0.955,-0.004 -0.3125,-0.0312 z m 0.875,0.1875 c 0.0209,0.0339 0.037,0.0652 0,0.125 -0.01,-0.0407 -0.0132,-0.0852 0,-0.125 z m -0.28125,0.0937 c 0.008,0.0407 0.0223,0.0692 0.0625,0.125 0.002,0.0174 0.0188,0.0345 0.0312,0.0312 0.0374,-0.01 0.0901,-0.078 0.0937,-0.0312 0.0326,-0.03 0.0758,-0.0367 0.0937,-0.0625 0.0122,0.0307 0.0395,0.0525 0.0625,0.0625 -0.0786,0.0243 -0.16205,0.0214 -0.25,0.0312 -0.55894,0.20149 0.0265,0.0442 -0.0937,-0.15625 z"
+     style="fill:url(#linearGradient3487);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/skins/moono/icons/print.png"
+     sodipodi:nodetypes="ssccssssssscsssscssssscccccssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4664"
+     d="M 228.5,2 C 227.669,2 227,2.669 227,3.5 l 0,0.49999 10,0 L 237,3.5 C 237,2.669 236.331,2 235.5,2 z M 226,5 c -0.554,0 -1,0.44599 -1,1 l 0,6 c 0,0.554 0.446,1 1,1 l 2,0 0,-5 c 0,-0.55401 0.446,-1 1,-1 l 6,0 c 0.554,0 1,0.44599 1,1 l 0,5 2,0 c 0.554,0 1,-0.446 1,-1 l 0,-6 c 0,-0.55401 -0.446,-1 -1,-1 z m 3,3 0,7 6,0 0,-7 z m 1.5,1 3,0 c 0.277,0 0.5,0.223 0.5,0.5 0,0.27699 -0.223,0.5 -0.5,0.5 l -3,0 C 230.223,10 230,9.77699 230,9.5 230,9.223 230.223,9 230.5,9 z m 0,2 3,0 c 0.277,0 0.5,0.223 0.5,0.5 0,0.27699 -0.223,0.5 -0.5,0.5 l -3,0 c -0.277,0 -0.5,-0.22301 -0.5,-0.5 0,-0.277 0.223,-0.5 0.5,-0.5 z"
+     style="fill:url(#linearGradient3489);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4666"
+     d="m 72,98 c -3.31371,0 -6,2.68629 -6,6 0,3.3137 2.68629,6 6,6 3.31371,0 6,-2.6863 6,-6 0,-3.31371 -2.68629,-6 -6,-6 z m 0,1 c 2.76142,0 5,2.23857 5,5 0,2.76142 -2.23858,5 -5,5 -2.76142,0 -5,-2.23858 -5,-5 0,-2.76143 2.23858,-5 5,-5 z m 0,2 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 1.65685,0 3,-1.34315 3,-3 0,-1.65686 -1.34315,-3 -3,-3 z"
+     style="fill:url(#linearGradient3491);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssssssssssssscccccsss"
+     inkscape:connector-curvature="0"
+     id="path4670"
+     d="m 291,100 c -1.662,0 -3,1.33799 -3,3 l 0,2 c 0,1.662 1.338,3 3,3 l 10,0 c 1.662,0 3,-1.338 3,-3 l 0,-2 c 0,-1.66201 -1.338,-3 -3,-3 z m 0,1 10,0 c 1.108,0 2,0.89199 2,2 l 0,2 c 0,1.108 -0.892,2 -2,2 l -2,-3 -3,3 -3,-2 -2,2 c -1.108,0 -2,-0.892 -2,-2 l 0,-2 c 0,-1.10801 0.892,-2 2,-2 z"
+     style="fill:url(#linearGradient3493);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="font-size:16.54135895px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3495);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     d="m 139.5,130 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 2.5,0 0,1 -2.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 l 0,2 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 0,-1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-2 c 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -3,0 z m -8.375,2.9375 c -0.29577,0 -0.58586,0.11711 -0.8125,0.34375 -0.45327,0.45327 -0.45327,1.20297 0,1.65625 l 2.03125,2.03125 L 130.3125,139 c -0.45327,0.45327 -0.45327,1.20297 0,1.65625 0.45327,0.45327 1.17173,0.45327 1.625,0 L 134,138.625 l 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 l -2.03125,-2.03125 2.03125,-2.03125 c 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 -0.45327,-0.45328 -1.17173,-0.45328 -1.625,0 L 134,135.3125 l -2.0625,-2.03125 c -0.22664,-0.22664 -0.51673,-0.34375 -0.8125,-0.34375 z"
+     id="path4672"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     id="path4674"
+     d="m 171.5,138 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.24281,0.60287 0.5,0.5 l 2.5,0 0,1 -2.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 l 0,2 c 0,0.277 0.223,0.5 0.5,0.5 l 3,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -2.5,0 0,-1 2.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 l 0,-2 c 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m -8.375,-6.0625 c -0.29577,0 -0.58586,0.11711 -0.8125,0.34375 -0.45327,0.45327 -0.45327,1.20297 0,1.65625 l 2.03125,2.03125 L 162.3125,138 c -0.45327,0.45327 -0.45327,1.20297 0,1.65625 0.45327,0.45327 1.17173,0.45327 1.625,0 L 166,137.625 l 2.03125,2.03125 c 0.45327,0.45327 1.17173,0.45327 1.625,0 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 l -2.03125,-2.03125 2.03125,-2.03125 c 0.45327,-0.45328 0.45327,-1.20298 0,-1.65625 -0.45327,-0.45328 -1.17173,-0.45328 -1.625,0 L 166,134.3125 l -2.0625,-2.03125 c -0.22664,-0.22664 -0.51673,-0.34375 -0.8125,-0.34375 z"
+     style="font-size:16.54135895px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3497);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssccsssssssccsssssssscssccssscsssccs"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4676"
+     d="m 6.5,64.99999 c -3.03757,0 -5.5,2.46243 -5.5,5.5 0,3.03756 2.46243,5.5 5.5,5.5 0.938705,0 1.7919409,-0.27092 2.5625,-0.6875 l 3.75,3.75 c 0.587606,0.58761 1.537394,0.58761 2.125,0 0.587606,-0.58761 0.587606,-1.53739 0,-2.125 L 11.21875,73.21874 C 11.691902,72.41237 12,71.50424 12,70.49999 c 0,-3.03757 -2.46243,-5.5 -5.5,-5.5 z m 0,2 c 1.933,0 3.5,1.567 3.5,3.5 0,1.06272 -0.47105,2.01435 -1.21875,2.65625 -0.006,0.005 -0.02525,-0.005 -0.03125,0 -0.60985,0.51643 -1.38828,0.84375 -2.25,0.84375 -1.933,0 -3.5,-1.56701 -3.5,-3.5 0,-1.933 1.567,-3.5 3.5,-3.5 z"
+     style="fill:url(#linearGradient3499);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4678"
+     d="m 296.00004,34.99999 7,5 -6.99998,4.99999 -2e-5,-3.33332 c -3.41666,0 -5.61556,1.22 -7,3.33333 0,-4.98332 3.60112,-6.66666 7,-6.66666 -2e-5,-0.85078 -1e-5,-2.61389 0,-3.33334 z"
+     style="fill:url(#linearGradient3501);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     sodipodi:nodetypes="ccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4680"
+     d="m 68,163 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 4.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 l -6,0 z m -4.5,5 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m 4.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z"
+     style="fill:url(#linearGradient3503);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4682"
+     d="m 135.53125,162 c -0.25721,0 -0.46875,0.22299 -0.46875,0.5 l 0,12 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 l 0,-12 c 0,-0.27701 -0.21154,-0.5 -0.46875,-0.5 z M 131.5,164 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,164.20565 142.777,164 142.5,164 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 141,166.20565 140.777,166 140.5,166 z m -8.5,2.46875 0,0.0625 2,1.46875 0,-1 2.5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 134,168.20565 133.777,168 133.5,168 l -2.5,0 0,-1 z M 137.5,168 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,168.20565 142.777,168 142.5,168 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 141,170.20565 140.777,170 140.5,170 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,172.20565 142.777,172 142.5,172 z"
+     style="fill:url(#linearGradient3505);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3507);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 232.46875,162 c 0.25721,0 0.46875,0.22299 0.46875,0.5 l 0,12 c 0,0.277 -0.21154,0.5 -0.46875,0.5 C 232.21154,175 232,174.777 232,174.5 l 0,-12 c 0,-0.27701 0.21154,-0.5 0.46875,-0.5 z m 4.03125,2 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 C 231,164.79434 230.777,165 230.5,165 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 225,164.20565 225.223,164 225.5,164 z m 0,2 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 C 231,166.79434 230.777,167 230.5,167 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 227,166.20565 227.223,166 227.5,166 z m 8.49436,2.53125 0,-0.0625 -1.99549,-1.46875 0,1 -2.49436,0 c -0.27637,0 -0.49887,0.18037 -0.49887,0.46875 l 0,0.0625 c 0,0.2631 0.2225,0.46875 0.49887,0.46875 l 2.49436,0 0,1 z M 230.5,168 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 C 231,168.79434 230.777,169 230.5,169 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 225,168.20565 225.223,168 225.5,168 z m 0,2 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 C 231,170.79434 230.777,171 230.5,171 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 227,170.20565 227.223,170 227.5,170 z m 6,2 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22385 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27615 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20565 0.5,0.46875 l 0,0.0625 C 231,172.79434 230.777,173 230.5,173 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 225,172.20565 225.223,172 225.5,172 z"
+     id="path4684"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sscccccccccccscccc"
+     inkscape:connector-curvature="0"
+     id="path4686"
+     d="m 458,163 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 l 0,4 1,0 0,-9 1,0 0,1 0,8 1,0 0,-8 1,0 0,-2 z m -8,3 0,6 3,-3 z"
+     style="fill:url(#linearGradient3509);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sscccccccccccscccc"
+     inkscape:connector-curvature="0"
+     id="path4688"
+     d="m 485,163 c -1.65685,0 -3,1.34314 -3,3 0,1.65685 1.34315,3 3,3 l 0,4 1,0 0,-9 1,0 0,1 0,8 1,0 0,-8 1,0 0,-2 z m 9.00442,3 0,6 -3.00884,-3 z"
+     style="fill:url(#linearGradient3511);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4691"
+     d="m 41.56445,200.66667 -1.02277,1.06211 2.08489,2.08489 -2.08489,2.12422 L 41.56445,207 43.68867,204.87578 45.8129,207 l 1.02277,-1.06211 -2.08489,-2.12423 2.08489,-2.08488 -1.02277,-1.06211 -2.12423,2.12422 z"
+     style="fill:url(#linearGradient3513);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3515);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 135.53125,162 c -0.25721,0 -0.46875,0.22299 -0.46875,0.5 l 0,12 c 0,0.277 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.223 0.46875,-0.5 l 0,-12 c 0,-0.27701 -0.21154,-0.5 -0.46875,-0.5 z M 131.5,164 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,164.20565 142.777,164 142.5,164 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 141,166.20565 140.777,166 140.5,166 z m -8.5,2.46875 0,0.0625 2,1.46875 0,-1 2.5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 134,168.20565 133.777,168 133.5,168 l -2.5,0 0,-1 z M 137.5,168 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,168.20565 142.777,168 142.5,168 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 141,170.20565 140.777,170 140.5,170 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 C 143,172.20565 142.777,172 142.5,172 z"
+     id="path4693"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4695"
+     d="m 167.64267,162 c -0.25721,0 -0.46875,0.223 -0.46875,0.5 l 0,12 c 0,0.27699 0.21154,0.5 0.46875,0.5 0.25721,0 0.46875,-0.22301 0.46875,-0.5 l 0,-12 c 0,-0.277 -0.21154,-0.5 -0.46875,-0.5 z m -4.03125,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -3.38858,2.46875 0,0.0625 -2.08914,1.46875 0,-1 -2.61141,0 C 161.23294,169 161,168.9653 161,168.53125 l 0,-0.0625 C 161,168.20565 161.23294,168 161.52229,168 l 2.61141,0 0,-1 z M 169.61142,168 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m 0,2 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 3,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z m -6,2 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 2,0 c -0.27614,0 -0.5,0.22385 -0.5,0.5 0,0.27614 0.22386,0.5 0.5,0.5 0.27614,0 0.5,-0.22386 0.5,-0.5 0,-0.27615 -0.22386,-0.5 -0.5,-0.5 z m 4,0 c -0.277,0 -0.5,0.20565 -0.5,0.46875 l 0,0.0625 c 0,0.26309 0.223,0.46875 0.5,0.46875 l 5,0 c 0.277,0 0.5,-0.20566 0.5,-0.46875 l 0,-0.0625 c 0,-0.2631 -0.223,-0.46875 -0.5,-0.46875 z"
+     style="fill:url(#linearGradient3517);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssssssssssssssssssssccccsssscccsssssssssssssssssssssssssssssssssssss"
+     inkscape:connector-curvature="0"
+     id="path4698"
+     d="m 200.46875,162 c 0.25722,0 0.46875,0.223 0.46875,0.5 l 0,12 c 0,0.277 -0.21153,0.5 -0.46875,0.5 C 200.21154,175 200,174.777 200,174.5 l 0,-12 c 0,-0.277 0.21154,-0.5 0.46875,-0.5 z m 4.03125,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 C 199,164.79434 198.777,165 198.5,165 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 193,164.20566 193.223,164 193.5,164 z m 0,2 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 C 199,166.79434 198.777,167 198.5,167 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 195,166.20566 195.223,166 195.5,166 z m 3.5,2.53125 0,-0.0625 2,-1.46875 0,1 2.5,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 c 0,0.26309 -0.22343,0.48425 -0.5,0.46875 l -2.5,0 0,1 z M 198.5,168 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 C 199,168.79434 198.777,169 198.5,169 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 193,168.20566 193.223,168 193.5,168 z m 0,2 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 C 199,170.79434 198.777,171 198.5,171 l -3,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 195,170.20566 195.223,170 195.5,170 z m 6,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -4,0 c 0.277,0 0.5,0.20566 0.5,0.46875 l 0,0.0625 C 199,172.79434 198.777,173 198.5,173 l -5,0 c -0.277,0 -0.5,-0.20566 -0.5,-0.46875 l 0,-0.0625 C 193,172.20566 193.223,172 193.5,172 z"
+     style="fill:url(#linearGradient3519);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4700"
+     d="m 1,226 0,12 14,0 0,-12 -14,0 z m 1,1 12,0 0,7.59375 L 11.09375,231 8,235 5,233 2,237 2,227 z m 2.5,1 C 3.67157,228 3,228.67157 3,229.5 3,230.32842 3.67157,231 4.5,231 5.32842,231 6,230.32842 6,229.5 6,228.67157 5.32842,228 4.5,228 z"
+     style="fill:url(#linearGradient3521);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4702"
+     d="m 198,227 0,3 10,0 0,-3 z m -5,2 0,7 4,-3.4375 z m 5,3 0,1 3,0 0,-1 z m 4,0 0,1 3,0 0,-1 z m 4,0 0,1 2,0 0,-1 z m -8,3 0,3 10,0 0,-3 z"
+     style="fill:url(#linearGradient3523);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sscccssssscccssss"
+     inkscape:connector-curvature="0"
+     id="path4704"
+     d="m 322.5,100 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24236 0.59935,0.45353 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.37612,-0.74776 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3525);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssssssccssssssccsssssscccssssscccssssccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4706"
+     d="m 130,98 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.09069 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.90931 2,-2 l 0,-0.375 c 0.0328,-0.0893 0.0213,-0.17215 0,-0.25 L 144,100 c 0,-1.0907 -0.9093,-2 -2,-2 z m 0,1 12,0 c 0.554,0 1,0.446 1,1 l 0,4.11795 -5.88205,5.88195 L 130,110 c -0.554,1e-5 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 z m 0.5,1 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.0444,0.53446 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.12178,-0.5281 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 12.5,5.40625 0,0.84375 -3.71875,3.6875 -0.0312,0.0625 -0.84375,0 z m 0,2.21875 0,0.625 -1.71875,1.75 -0.625,0 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3527);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssscccc"
+     inkscape:connector-curvature="0"
+     id="path4708"
+     d="m 194,99 c -1.0907,0 -2,0.9093 -2,2 l 0,7 c 0,1.0907 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-7 c 0,-1.0907 -0.9093,-2 -2,-2 z m 0,1 12,0 c 0.554,0 1,0.446 1,1 l 0,7 c 0,0.554 -0.446,1 -1,1 l -12,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-7 c 0,-0.554 0.446,-1 1,-1 z m 6,3 3,4 3,-4 z"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3529);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3531);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 209,707 c -2.32953,0 -4.43371,1.05678 -5.90625,2.6875 l 3.5625,2.0625 C 207.31214,711.27977 208.12788,711 209,711 c 2.216,0 4,1.784 4,4 l 0,3 -5,0 -4,0 -2,0 -2,0 c -1.108,0 -2,0.89196 -2,2 l 0,12 c 0,1.108 0.892,2 2,2 l 18,0 c 1.108,0 2,-0.892 2,-2 l 0,-12 c 0,-1.10804 -0.892,-2 -2,-2 l -1,0 0,-3 c 0,-4.36281 -3.63719,-8 -8,-8 z m 0,17 c 1.65686,0 3,1.34314 3,3 0,1.65682 -1.34314,3 -3,3 -1.65686,0 -3,-1.34318 -3,-3 0,-1.65686 1.34314,-3 3,-3 z"
+     transform="translate(1,-367.75001)"
+     id="path4710"
+     inkscape:connector-curvature="0" /><path
+     inkscape:connector-curvature="0"
+     id="path4712"
+     d="m 3.5,163 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 0.5,0 0,3.5 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-4 C 5,163.223 4.777,163 4.5,163 l -1,0 z m 4,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z m -5,5 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,1 -1.5,0 C 2.223,172 2,172.223 2,172.5 l 0,2 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 C 4.777,175 5,174.77699 5,174.5 5,174.223 4.777,174 4.5,174 l -1.5,0 0,-1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 0.0252,-0.0599 0.0312,-0.11825 0.0312,-0.1875 l 0,-2 c 0,-0.0693 -0.006,-0.12765 -0.0312,-0.1875 -0.0505,-0.13913 -0.15407,-0.24028 -0.28125,-0.28125 -0.0404,-0.0171 -0.0799,-0.0253 -0.125,-0.0312 l -0.0625,0 -2,0 z m 5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -6,0 z"
+     style="fill:url(#linearGradient3673);fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="cccccccccccccccccccscccscscccscccccccc"
+     d="m 13.295487,138.29724 c -9e-6,0.70891 -0.137341,1.30388 -0.411995,1.78492 -0.274673,0.46838 -0.650527,0.84815 -1.127571,1.1393 -0.462605,0.2785 -1.019157,0.48105 -1.669674,0.60763 -0.6360688,0.11394 -1.3227277,0.1709 -2.059977,0.1709 l -3.7296601,0.0121 0,-12.04805 3.4694455,-0.003 c 1.0119224,1e-5 1.8359131,0.095 2.4719816,0.28482 0.636059,0.17724 1.134796,0.41776 1.496201,0.72156 0.361395,0.29117 0.607142,0.6203 0.737259,0.9874 0.130097,0.36712 0.195146,0.73423 0.195156,1.10133 -10e-6,0.557 -0.159025,1.0507 -0.477054,1.4811 -0.303581,0.43041 -0.715576,0.7722 -1.235986,1.02538 0.910722,0.29116 1.525098,0.68359 1.843147,1.17728 0.332478,0.49371 0.498718,1.01272 0.498727,1.55705 m -6.3317393,-1.59503 0,3.19006 c 0.1879221,0.0253 0.3903124,0.0443 0.6071515,0.057 0.2312976,0.0127 0.4553613,0.019 0.67221,0.019 0.303571,1e-5 0.5999175,-0.019 0.8890395,-0.057 0.2891221,-0.0506 0.5421027,-0.13292 0.7589418,-0.24685 0.2312975,-0.12659 0.4192195,-0.29748 0.5637855,-0.51269 0.144556,-0.22786 0.216839,-0.51268 0.216839,-0.85448 0,-0.56965 -0.209614,-0.97473 -0.628834,-1.21526 -0.4047711,-0.25317 -0.9540982,-0.37976 -1.6479815,-0.37977 l -1.4311518,0 m 1.0408394,-1.93682 c 0.6794248,1e-5 1.1926105,-0.12658 1.5395666,-0.37977 0.3469368,-0.26583 0.5204103,-0.62661 0.5204103,-1.08234 0,-0.27849 -0.05059,-0.50002 -0.1517905,-0.66459 -0.1011903,-0.17722 -0.2385221,-0.31014 -0.4119953,-0.39876 -0.1734733,-0.10126 -0.3758635,-0.16456 -0.6071516,-0.18989 -0.2312976,-0.038 -0.4698197,-0.057 -0.7155759,-0.057 -0.2023806,1e-5 -0.4119953,0.006 -0.6288345,0.019 -0.2168391,0.0127 -0.4119953,0.0317 -0.5854685,0.057 l 0,2.69636 1.0408394,0"
+     style="font-size:22.63113022px;font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3533);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono Bold"
+     id="path4714"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><g
+     id="g4716"
+     style="font-size:14.87401295px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3537);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     transform="matrix(1.8191013,0,-0.4691387,1.8191013,-489.83328,-196.53417)"><path
+       sodipodi:nodetypes="ccccccccccccc"
+       inkscape:connector-curvature="0"
+       id="path4718"
+       style="font-size:21.24859047px;font-variant:normal;font-weight:bold;font-stretch:normal;fill:url(#linearGradient3535);font-family:Ubuntu Mono;-inkscape-font-specification:Ubuntu Mono Bold"
+       d="m 325.2364,61.999996 0,-2.167356 1.76912,0 -0.1287,-8.818165 -1.76912,0 0,-2.167356 6.15181,0 0,2.167356 -1.74787,0 0.1287,8.818165 1.74787,0 0,2.167356 -6.15181,0" /></g><g
+     id="g4720"
+     style="font-size:15.82676315px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient4491);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     transform="matrix(2.1281094,0,0,1.8850568,-169.0631,-208.10971)"><path
+       sodipodi:nodetypes="ccccccccc"
+       inkscape:connector-curvature="0"
+       id="path4722"
+       style="font-size:22.60966301px;font-style:italic;font-variant:normal;font-stretch:normal;fill:url(#linearGradient5619);fill-opacity:1;font-family:'8bitoperator JVE';-inkscape-font-specification:'8bitoperator JVE Italic'"
+       d="m 263.15116,63.849438 2.25213,-9.18288 -2.8262,0 0.28703,-1.413104 8.47863,0 -0.28704,1.413104 -2.82621,0 -2.25213,9.18288 -2.82621,0" /></g><path
+     inkscape:connector-curvature="0"
+     id="path4726"
+     d="m 264.00004,34.99999 7,5 -6.99998,4.99999 -2e-5,-3.33332 c -3.41666,0 -5.61556,1.22 -7,3.33333 0,-4.98332 3.60112,-6.66666 7,-6.66666 -2e-5,-0.85078 -1e-5,-2.61389 0,-3.33334 z"
+     style="fill:url(#linearGradient3543);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     sodipodi:nodetypes="ccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ccccccc"
+     style="fill:url(#linearGradient3545);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 328,35 -7,5 6.99998,4.99998 2e-5,-3.33332 c 3.41666,0 5.61556,1.22 7,3.33334 0,-4.98333 -3.60112,-6.66667 -7,-6.66667 2e-5,-0.85078 10e-6,-2.61388 0,-3.33333 z"
+     id="path4728"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="sssssssssssssssssscccc"
+     inkscape:connector-curvature="0"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3547);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 238,99 c 1.0907,0 2,0.9093 2,2 l 0,7 c 0,1.0907 -0.9093,2 -2,2 l -12,0 c -1.0907,0 -2,-0.9093 -2,-2 l 0,-7 c 0,-1.0907 0.9093,-2 2,-2 z m 0,1 -12,0 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 12,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 z m -6,3 -3,4 -3,-4 z"
+     id="path4730"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4732"
+     d="m 111,193 0,14 -1,0 0,-14 z m -4.74999,-0.41664 c 0.86983,0.009 1.76033,0.34033 2.74999,1.375 L 109,202 c -3.96132,-4.05865 -6.94268,2.81598 -11,-1 l 0,-8.04165 c 3.03099,2.934 5.64051,-0.40352 8.25001,-0.37496 z"
+     style="fill:url(#linearGradient3549);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     sodipodi:nodetypes="cccccccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3551);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 78.5,289 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -3.5,0 c 1.0907,0 2,0.9093 2,2 l 0,10 c 0,1.0907 -0.9093,2 -2,2 -1.0907,0 -2,-0.9093 -2,-2 l 0,-10 c 0,-1.0907 0.9093,-2 2,-2 z m 0,1 c -0.554,0 -1,0.446 -1,1 l 0,10 c 0,0.554 0.446,1 1,1 0.554,0 1,-0.446 1,-1 l 0,-10 c 0,-0.554 -0.446,-1 -1,-1 z m 11.5,1 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -8,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 8,2 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m -2,0 c 0.27614,0 0.5,0.22386 0.5,0.5 0,0.27614 -0.22386,0.5 -0.5,0.5 -0.27614,0 -0.5,-0.22386 -0.5,-0.5 0,-0.27614 0.22386,-0.5 0.5,-0.5 z m 6.5,2 c 1.0907,0 2,0.9093 2,2 0,1.0907 -0.9093,2 -2,2 l -5,0 c -1.0907,0 -2,-0.9093 -2,-2 0,-1.0907 0.9093,-2 2,-2 l 5,0 z m 0,1 -5,0 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 5,0 c 0.554,0 1,-0.446 1,-1 0,-0.554 -0.446,-1 -1,-1 z"
+     id="path4734"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssccsssssccsssscccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4736"
+     d="m 67,1 c -1.108,0 -2,0.892 -2,2 l 0,8.9375 3,3.0625 9,0 c 1.108,0 2,-0.892 2,-2 L 79,3 C 79,1.892 78.108,1 77,1 z m 0,1 10,0 0,4 c 0,1.108 0.108,1 -1,1 L 68,7 C 66.892,7 67,7.108 67,6 z m 1,8 8,0 0,4 -4,0 0,-3 -2,0 0,3 -2,0 z"
+     style="fill:url(#linearGradient3553);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssscsssssssssssssssssssscssccsssssssccsccssccccccssssssssssssss"
+     style="fill:url(#linearGradient3671);fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 44.5,163 c 0,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.777,0.5 0.5,0.5 l 0.5,0 0,3.5 c 0,0.27699 0.223,0.5 0.5,0.5 0.277,0 0.5,-0.22301 0.5,-0.5 l 0,-4 c 0,-0.277 -0.5,-0.5 -0.5,-0.5 z m -10,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 9,5 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 1.5,0 0,1 -1.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 l 0,2 c 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 l -1.5,0 0,-1 1.5,0 c 0.0693,0 0.12764,-0.006 0.1875,-0.0312 0.12718,-0.041 0.2307,-0.14213 0.28125,-0.28125 0.0252,-0.0599 0.0312,-0.11825 0.0312,-0.1875 l 0,-2 c 0,-0.0693 -0.006,-0.12765 -0.0312,-0.1875 -0.0505,-0.13913 -0.15407,-0.24028 -0.28125,-0.28125 -0.0404,-0.0171 -0.0799,-0.0253 -0.125,-0.0312 l -0.0625,0 -2,0 z m -9,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     id="path4738"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     sodipodi:nodetypes="ssssssssssssssssssssssssssssssssssssss"
+     style="fill:url(#linearGradient3555);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 108,163 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m -10.5,0 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.22299 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.27701 -0.223,-0.5 -0.5,-0.5 z m 10.5,5 c -1.10457,0 -2,0.89543 -2,2 0,1.10456 0.89543,2 2,2 1.10457,0 2,-0.89544 2,-2 0,-1.10457 -0.89543,-2 -2,-2 z m -10.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 0,2 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.277 0.223,0.5 0.5,0.5 l 6,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z"
+     id="path4740"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3557);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 234,227 0,3 -10,0 0,-3 z m 5,2 0,7 -4,-3.4375 z m -5,3 0,1 -3,0 0,-1 z m -4,0 0,1 -3,0 0,-1 z m -4,0 0,1 -2,0 0,-1 z m 8,3 0,3 -10,0 0,-3 z"
+     id="path4742"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     id="path4746"
+     d="m 40,320.96568 c -3.86517,0 -7,3.1502 -7,7.03432 0,3.88412 3.13483,7.03431 7,7.03431 3.86633,0 7,-3.15019 7,-7.03431 0,-3.88412 -3.13367,-7.03432 -7,-7.03432 z"
+     style="fill:url(#linearGradient3559);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     sodipodi:nodetypes="sssss"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:transform-center-y="2.9999632"
+     inkscape:transform-center-x="-1.4999864"
+     sodipodi:end="2.0943951"
+     sodipodi:start="0"
+     sodipodi:type="arc"
+     style="fill:#999999;fill-opacity:1;stroke:none"
+     id="path4748"
+     sodipodi:cx="39.5"
+     sodipodi:cy="327.5"
+     sodipodi:rx="5.5"
+     sodipodi:ry="5.5"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     transform="matrix(2.1818034,0,0,2.1818034,-5.1812409,-426.29057)" /><path
+     transform="matrix(-1.0909017,1.8894973,-1.8894973,-1.0909017,742.90096,570.88525)"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     sodipodi:ry="5.5"
+     sodipodi:rx="5.5"
+     sodipodi:cy="327.5"
+     sodipodi:cx="39.5"
+     id="path4750"
+     style="fill:#cccccc;fill-opacity:1;stroke:none"
+     sodipodi:type="arc"
+     sodipodi:start="0"
+     sodipodi:end="2.0943951"
+     inkscape:transform-center-x="3.0004864" /><path
+     inkscape:transform-center-y="-3.0004886"
+     inkscape:transform-center-x="-1.4999969"
+     sodipodi:end="2.0943951"
+     sodipodi:start="0"
+     sodipodi:type="arc"
+     style="fill:#666666;fill-opacity:1;stroke:none"
+     id="path4752"
+     sodipodi:cx="39.5"
+     sodipodi:cy="327.5"
+     sodipodi:rx="5.5"
+     sodipodi:ry="5.5"
+     d="m 45,327.5 a 5.5,5.5 0 0 1 -8.25,4.76314 L 39.5,327.5 z"
+     transform="matrix(-1.0909017,-1.8894973,1.8894973,-1.0909017,-494.71972,720.15551)" /><rect
+     ry="0"
+     rx="0"
+     y="230.99997"
+     x="97"
+     height="2"
+     width="14"
+     id="rect4754"
+     style="fill:url(#linearGradient3561);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     id="rect4756"
+     width="12"
+     height="0.99999475"
+     x="98"
+     y="227.99997"
+     rx="0"
+     ry="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     ry="0"
+     rx="0"
+     y="225.99997"
+     x="98"
+     height="0.99999475"
+     width="12"
+     id="rect4758"
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     ry="0"
+     rx="0"
+     y="236.99997"
+     x="98"
+     height="0.99999475"
+     width="12"
+     id="rect4760"
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     id="rect4762"
+     width="12"
+     height="0.99999475"
+     x="98"
+     y="234.99997"
+     rx="0"
+     ry="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     id="rect4764"
+     width="12"
+     height="0.99999475"
+     x="98"
+     y="223.99997"
+     rx="0"
+     ry="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><rect
+     ry="0"
+     rx="0"
+     y="238.99997"
+     x="98"
+     height="0.99999475"
+     width="12"
+     id="rect4766"
+     style="fill:#636363;fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(-2,0,0,2,673.04102,-367.74989)"
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3563);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 162,98 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.09069 0.9093,2 2,2 l 12,0 c 1.0907,0 2,-0.90931 2,-2 l 0,-0.375 c 0.0328,-0.0893 0.0213,-0.17215 0,-0.25 L 176,100 c 0,-1.0907 -0.9093,-2 -2,-2 z m 0,1 12,0 c 0.554,0 1,0.446 1,1 l 0,4.11795 -5.88205,5.88195 L 162,110 c -0.554,1e-5 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 z m 0.5,1 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.24237 0.0444,0.53446 0.5625,0.5 l 0.4375,0 0,5 -0.5,0 c -0.277,0 -0.5,0.223 -0.5,0.5 0,0.27699 0.223,0.5 0.5,0.5 l 2,0 c 0.277,0 0.5,-0.22301 0.5,-0.5 0,-0.277 -0.12178,-0.5281 -0.5,-0.5 l -0.5,0 0,-5 0.5,0 c 0.277,0 0.5,-0.223 0.5,-0.5 0,-0.277 -0.223,-0.5 -0.5,-0.5 z m 12.5,5.40625 0,0.84375 -3.71875,3.6875 -0.0312,0.0625 -0.84375,0 z m 0,2.21875 0,0.625 -1.71875,1.75 -0.625,0 z"
+     id="path4768"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ssssssccssssssccsssssscccssssscccssssccccccccccc" /><path
+     style="fill:url(#linearGradient3565);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 64,225 0,2 0,10 0,2 16,0 0,-2 0,-10 0,-2 z m 1,4 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m -10,5 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z m 5,0 4,0 0,4 -4,0 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="path4770"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccccccccccccccccccccccccccccccccccc" /><path
+     inkscape:connector-curvature="0"
+     id="path4788"
+     d="m 3,210.24999 0,10 3,-2.75 5,4.75 4,0 0,-4 -5,-4.75 3,-3.25 -10,0 z m 18,0 3,3.25 -5,4.75 0,4 4,0 5,-4.75 3,2.75 0,-10 -10,0 z m -10,16 -5,4.75 -3,-2.75 0,10 10,0 -3,-3.25 5,-4.75 0,-4 -4,0 z m 8,0 0,4 5,4.75 -3,3.25 10,0 0,-10 -3,2.75 -5,-4.75 -4,0 z"
+     style="fill:url(#linearGradient5672);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)" /><path
+     id="path4795"
+     d="m 258,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 -6,0 z m 1,1 5.34375,0 3.65625,3.65625 0,8.34375 -5,0 -3,0 -1,0 0,-12 z m 2,5 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z m 0,2 0,1 5,0 0,-1 -5,0 z"
+     style="fill:url(#linearGradient3567);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3569);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 2,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     id="path4797"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(-2,0,0,2,161,-367.74989)"
+     style="fill:url(#linearGradient3571);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 39,6 0,1.875 -1.375,1.46875 1.375,1.46875 0,1.90625 -3.625,-3.375 z"
+     id="path4799"
+     inkscape:connector-curvature="0" /><path
+     transform="matrix(-2,0,0,2,161,-367.74989)"
+     style="fill:url(#linearGradient3573);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="M 40,6 43.6875,9.375 40,12.65625 40,10.75 41.4375,9.34375 40,7.8125 z"
+     id="path4801"
+     inkscape:connector-curvature="0" /><path
+     transform="matrix(-2,0,0,2,163,-367.74989)"
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4803"
+     d="m 35,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     style="fill:url(#linearGradient3575);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)" /><path
+     style="fill:url(#linearGradient3577);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 98,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     id="path4805"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(-2,0,0,2,545,-367.74989)"
+     sodipodi:nodetypes="cccccccccccccccc"
+     inkscape:connector-curvature="0"
+     id="path4807"
+     d="m 131,0.99999 0,14 11,0 0,-9 0,-1 -4,-4 -1,0 z m 1,1 5.5,0 3.5,3.5 0,8.5 -5,0 -3,0 -1,0 z"
+     style="fill:url(#linearGradient3579);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)" /><path
+     id="path4809"
+     d="m 290,0.99999 0,4.75 c 0.19146,-0.12014 0.37062,-0.22084 0.5625,-0.3125 L 291,5.21874 l 0,-3.21875 5.34375,0 3.65625,3.65625 0,8.34375 -5,0 0,0.96875 c 0,0.0104 1.6e-4,0.0209 0,0.0312 l 6,0 0,-9 0,-1 -4,-4 -1,0 -6,0 z m 1,5.34375 c -0.36123,0.17256 -0.68892,0.37641 -0.96875,0.65625 -0.63338,0.63338 -1.03125,1.5335 -1.03125,2.5 0,1.39352 0.8237,2.5644 2,3.125 l 0,2.34375 c 0,0.554 0.44599,1 1,1 l 1,0.0312 c 0.554,0 1,-0.47725 1,-1.03125 l 0,-2.34375 c 1.17629,-0.5606 2,-1.73148 2,-3.125 0,-1.39352 -0.82119,-2.59313 -2,-3.15625 l 0,2.65625 -1.46875,1 -1.53125,-1 0,-2.65625 z"
+     style="fill:url(#linearGradient3581);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     id="path4817"
+     d="m 33,31.99999 0,10 3,0 0,-1 -1,0 -1,0 0,-8 4.5,0 2.5,2.5 0,0.5 1,0 0,-1 -3,-3 -1,0 -5,0 z m 4,5 0,10 9,0 0,-6 0,-1 -3,-3 -1,0 -5,0 z m 1,1 4.5,0 2.5,2.5 0,5.5 -5,0 -1,0 -1,0 0,-8 z"
+     style="fill:url(#linearGradient3583);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     transform="matrix(-2,0,0,2,777,-367.74989)"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient3585);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 182,0.99999 0,14 8.8125,0 -1,-1 -1.3125,0 -1.5,0 -3,0 -1,0 0,-12 5.5,0 3.5,3.5 0,1.21875 c 0.61468,0.7698887 1,1.7287934 1,2.78125 l 0,-3.5 0,-1 -4,-4 -1,0 -6,0 z m 11,8.5 c 0,0.4831876 -0.20077,0.86276 -0.34375,1.28125 L 193,11.12499 l 0,-1.625 z m -4.5,-3.5 c -1.92115,0 -3.5,1.57884 -3.5,3.5 0,1.92115 1.57885,3.5 3.5,3.5 0.49539,0 0.94633,-0.12374 1.375,-0.3125 l 2.34375,2.34375 1.625,-1.625 -2.28125,-2.28125 C 191.829,10.63214 192,10.09539 192,9.49999 c 0,-1.92116 -1.57885,-3.5 -3.5,-3.5 z m -0.0312,1 c 1.38071,0 2.5,1.11929 2.5,2.5 0,1.38071 -1.11929,2.5 -2.5,2.5 -1.38071,0 -2.5,-1.11929 -2.5,-2.5 0,-1.38071 1.11929,-2.5 2.5,-2.5 z"
+     id="path4828" /><path
+     transform="matrix(-2,0,0,2,1313,-367.74989)"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient3587);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     d="m 323,0.99999 0,4.75 c 0.19146,-0.1201434 0.37062,-0.2208417 0.5625,-0.3125 L 324,5.21874 l 0,-3.21875 5.34375,0 3.65625,3.65625 0,8.34375 -5,0 0,0.96875 c 0,0.01043 1.6e-4,0.02085 0,0.03125 l 6,0 0,-9 0,-1 -4,-4 -1,0 -6,0 z m 1,5.34375 c -0.36123,0.1725562 -0.68892,0.3764154 -0.96875,0.65625 C 322.39787,7.6333667 322,8.5334899 322,9.49999 c 0,1.393522 0.8237,2.564396 2,3.125 l 0,2.34375 c 0,0.554002 0.44599,1.000002 1,1 l 1,0.03125 c 0.554,-2e-6 1,-0.477248 1,-1.03125 l 0,-2.34375 c 1.17629,-0.560603 2,-1.731478 2,-3.125 0,-1.3935222 -0.82119,-2.5931341 -2,-3.15625 l 0,2.65625 -1.46875,1 -1.53125,-1 0,-2.65625 z"
+     id="path4830" /><rect
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     id="rect6517"
+     width="13.999996"
+     height="2"
+     x="141"
+     y="-231.74991" /><rect
+     y="-227.74991"
+     x="133"
+     height="2"
+     width="22"
+     id="rect6519"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     y="-219.74991"
+     x="133"
+     height="2"
+     width="22"
+     id="rect6523"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     id="rect6525"
+     width="6"
+     height="2"
+     x="133"
+     y="-215.74991" /><path
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none"
+     d="m 141,-215.74991 0,2 2,0 0,4 -2,0 0,2 6,0 0,-2 -2,0 0,-4 2,0 0,-2 -2,0 -2,0 -2,0 z"
+     id="rect6527"
+     inkscape:connector-curvature="0" /><rect
+     y="-223.74991"
+     x="133"
+     height="2"
+     width="22"
+     id="rect6539"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     y="-235.74991"
+     x="141"
+     height="2"
+     width="14"
+     id="rect6547"
+     style="fill:#2d2d2d;fill-opacity:1;stroke:none" /><rect
+     style="fill:#2d2d2d;fill-opacity:0.99215686;stroke:none"
+     id="rect6606"
+     width="6"
+     height="6"
+     x="133"
+     y="-235.74991" /><path
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient3589);fill-opacity:1;fill-rule:evenodd;display:inline;filter:url(#filter3224-1-7-1-3)"
+     d="m 7.424061,258.01101 c -1.28354,3.14452 -2.79862,6.87174 -4.15625,10.1875 l 2.5,0 0.90625,-2.5 3.34375,0 0.8125,2.5 2.625,0 c -1.33823,-3.35178 -2.81774,-6.95392 -4.09375,-10.1875 l -1.9375,0 z m 0.96875,2.96875 0.90625,2.6875 -1.90625,0 1,-2.6875 z"
+     id="path4763"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:#999999;fill-opacity:1;fill-rule:evenodd;display:inline;filter:url(#filter3224-1-7-1-3)"
+     d="m 1,270.01101 0,1.98898 15,0 0,-1.98898 z"
+     id="path3812"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3591);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="M 102.53125,32 C 102.23664,32 102,32.23664 102,32.53125 L 102,33 101.53125,33 C 101.23664,33 101,33.23664 101,33.53125 l 0,0.9375 C 101,34.76335 101.23664,35 101.53125,35 l 1,0 2.9375,0 1,0 C 106.76336,35 107,34.76335 107,34.46875 l 0,-0.9375 C 107,33.23664 106.76336,33 106.46875,33 L 106,33 106,32.53125 C 106,32.23664 105.76336,32 105.46875,32 l -2.9375,0 z M 100,33 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 C 100,33.34767 100.0316,33.16464 100.0937,33 L 100,33 z m 7.90625,0 C 107.9684,33.16465 108,33.34767 108,33.53125 L 108,34 c 0.554,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z M 103,38 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 2,0 0,4 1,0 0,-4 2,0 0,-1 -5,0 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="path3631"
+     inkscape:connector-curvature="0" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;color:#000000;fill:url(#linearGradient3593);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1-3);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="M 134.53125,32 C 134.23664,32 134,32.23664 134,32.53125 L 134,33 133.53125,33 C 133.23664,33 133,33.23664 133,33.53125 l 0,0.9375 C 133,34.76335 133.23664,35 133.53125,35 l 1,0 2.9375,0 1,0 C 138.76336,35 139,34.76335 139,34.46875 l 0,-0.9375 C 139,33.23664 138.76336,33 138.46875,33 L 138,33 138,32.53125 C 138,32.23664 137.76336,32 137.46875,32 l -2.9375,0 z M 132,33 c -1.0907,0 -2,0.9093 -2,2 l 0,2 1,0 0,-2 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0316,-0.3666 0.0937,-0.53125 L 132,33 z m 7.90625,0 C 139.96835,33.16464 140,33.34767 140,33.53125 L 140,34 c 0.554,0 1,0.446 1,1 l 0,9 c 0,0.554 -0.446,1 -1,1 l -1,0 0,1 1,0 c 1.0907,0 2,-0.9093 2,-2 l 0,-9 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z M 130,38 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 l -7,0 z m 0,1 7,0 0,7 -7,0 0,-7 z m 1,1 0,1 2,0 0,4 1,0 0,-4 2,0 0,-1 -5,0 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="path3655"
+     inkscape:connector-curvature="0" /><rect
+     style="fill:url(#linearGradient3595);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     id="rect3807"
+     width="16"
+     height="7.9999976"
+     x="256"
+     y="99.999992"
+     rx="2"
+     ry="2"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><g
+     style="font-size:15.85716724px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3713);fill-opacity:0.99215686;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     id="text3563"
+     transform="matrix(2,0,0,2,35,-367.74989)"><path
+       d="m 91.018035,130.55223 0,2.44671 c -0.634915,-0.28389 -1.011554,-0.48077 -1.615481,-0.62531 -0.603942,-0.14452 -1.174325,-0.21679 -1.71115,-0.2168 -0.712338,10e-6 -1.238845,0.0981 -1.579522,0.29423 -0.340685,0.19616 -0.511026,0.5007 -0.511022,0.91364 -4e-6,0.30972 0.113556,0.55233 0.340681,0.72782 0.232279,0.17035 0.650387,0.31746 1.254327,0.44134 l 1.269812,0.25551 c 1.28529,0.2581 2.198934,0.6504 2.740936,1.1769 0.541983,0.52651 0.81298,1.27498 0.81299,2.2454 -10e-6,1.27498 -0.379405,2.22475 -1.138185,2.84933 -0.753637,0.61942 -1.907307,0.92913 -3.461013,0.92913 -0.732986,0 -1.468547,-0.0697 -2.206686,-0.20905 -0.738146,-0.13937 -1.476288,-0.34584 -2.214429,-0.61942 l 0,-2.5164 c 0.738141,0.39231 1.450474,0.68911 2.137002,0.89042 0.691682,0.19615 1.357558,0.29423 1.997631,0.29423 0.650386,0 1.148502,-0.1084 1.494352,-0.3252 0.345836,-0.2168 0.518757,-0.52651 0.518765,-0.92913 -8e-6,-0.36133 -0.11873,-0.64007 -0.356167,-0.83622 -0.232289,-0.19615 -0.699435,-0.37165 -1.401439,-0.52651 l -1.153671,-0.25551 c -1.156255,-0.24776 -2.002796,-0.64264 -2.539624,-1.18464 -0.531671,-0.54199 -0.797506,-1.27239 -0.797504,-2.1912 -2e-6,-1.15108 0.37165,-2.03634 1.114957,-2.65577 0.743301,-0.61941 1.811801,-0.92912 3.205501,-0.92913 0.6349,1e-5 1.287872,0.049 1.958918,0.14712 0.671031,0.0929 1.122516,0.21753 1.840021,0.40851"
+       style="font-weight:bold;fill:url(#linearGradient5621);-inkscape-font-specification:Sans Bold"
+       id="path3568"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="ccccccccccccsccccsccccccssccc" /></g><path
+     id="path3593"
+     d="m 98.5,136 12,0 c 0.277,0 0.5,0.20442 0.5,0.45833 l 0,0.0833 C 111,136.79558 110.777,137 110.5,137 l -12,0 c -0.277,0 -0.5,-0.20442 -0.5,-0.45833 l 0,-0.0833 C 98,136.20442 98.223,136 98.5,136 z"
+     style="fill:#565656;fill-opacity:0.98431373;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sssssssss"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:url(#linearGradient3597);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1)"
+     d="m 1.9999999,354 0,13 1,0 0,-13 z"
+     id="path3580"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccc"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     style="fill:#b50000;fill-opacity:1;fill-rule:evenodd"
+     d="m 13.99998,339.41683 c -1.5815,0.018 -3.2006,0.68066 -4.9999799,2.75 l 0,16.08328 C 16.2024,350.13281 21.62306,363.88207 29,356.25011 l 0,-16.0833 c -5.5109,5.868 -10.25548,-0.80704 -15.00002,-0.74992 z"
+     id="path3574"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0" /><path
+     id="path4350"
+     d="m 13.99998,341.41683 c -1.5815,0.018 -3.2006,0.68066 -4.9999799,2.75 l 0,14.08328 C 16.2024,350.13281 21.62306,363.88207 29,356.25011 l 0,-14.0833 c -5.5109,5.868 -10.25548,-0.80704 -15.00002,-0.74992 z"
+     style="fill:url(#linearGradient5639);fill-opacity:1;fill-rule:evenodd"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ccccccc"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90" /><path
+     style="fill:#8e0000;fill-opacity:1;fill-rule:evenodd"
+     d="m 29,340.18759 c -0.6161,0.65602 -1.22016,1.13058 -1.81818,1.5 l 0,14 c -4.75112,2.93492 -8.96772,-2.30074 -13.18182,-2.25 -1.5815,0.018 -3.20062,0.68066 -4.9999999,2.75 l 0,0.5 0,1.5 0,0.0624 c 0.35284,-0.39764 0.68014,-0.7662 1.0227199,-1.0625 0.34258,-0.2963 0.6881,-0.5439 1.02274,-0.75 0.66926,-0.4122 1.33732,-0.63162 1.98864,-0.75 -0.1292,-0.018 -0.26402,-0.0344 -0.39774,-0.0624 0.4581,-0.1264 0.91488,-0.1824 1.36364,-0.1874 3.05338,-0.0368 6.11734,2.72286 9.375,3.125 0.1286,0.016 0.26858,-0.008 0.39772,0 0.172,0.01 0.33786,0.0674 0.51138,0.0624 0.1896,-0.006 0.37654,-0.0376 0.56818,-0.0624 0.26176,-0.034 0.5297,-0.1128 0.79544,-0.1874 0.37798,-0.1058 0.75176,-0.2352 1.13638,-0.4375 0.0602,-0.031 0.11,-0.0914 0.1704,-0.125 0.33964,-0.1886 0.67552,-0.41302 1.02274,-0.6875 0.33604,-0.26566 0.67898,-0.51938 1.02272,-0.875 l 0,-0.0624 0,-2 0,-14 z"
+     id="path4364"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     inkscape:export-xdpi="90"
+     inkscape:export-ydpi="90"
+     inkscape:connector-curvature="0" /><rect
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     y="336.25012"
+     x="1"
+     height="32"
+     width="32"
+     id="rect3598"
+     style="fill:#ffffff;fill-opacity:0;stroke:none" /><path
+     sodipodi:nodetypes="ccccc"
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3600"
+     d="m 1.9999999,354 0,13 1,0 0,-13 z"
+     style="fill:url(#linearGradient3601);fill-opacity:1;fill-rule:evenodd;filter:url(#filter3224-1-7-1-3)"
+     transform="matrix(2,0,0,2,1.0000003,-367.74989)" /><path
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3602"
+     d="m 13.99998,339.41683 c -1.5815,0.018 -3.2006,0.68066 -4.9999799,2.75 l 0,16.08328 C 16.2024,350.13281 21.62306,363.88207 29,356.25011 l 0,-16.0833 c -5.5109,5.868 -10.25548,-0.80704 -15.00002,-0.74992 z"
+     style="fill:#b50000;fill-opacity:1;fill-rule:evenodd" /><path
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     sodipodi:nodetypes="ccccccc"
+     inkscape:connector-curvature="0"
+     style="fill:url(#linearGradient5632);fill-opacity:1;fill-rule:evenodd"
+     d="m 13.99998,341.41683 c -1.5815,0.018 -3.2006,0.68066 -4.9999799,2.75 l 0,14.08328 C 16.2024,350.13281 21.62306,363.88207 29,356.25011 l 0,-14.0833 c -5.5109,5.868 -10.25548,-0.80704 -15.00002,-0.74992 z"
+     id="path3604" /><path
+     inkscape:connector-curvature="0"
+     inkscape:export-ydpi="90"
+     inkscape:export-xdpi="90"
+     inkscape:export-filename="/home/oleq/ck/ckeditor-dev/plugins/link/images/anchor.png"
+     id="path3606"
+     d="m 29,340.18759 c -0.6161,0.65602 -1.22016,1.13058 -1.81818,1.5 l 0,14 c -4.75112,2.93492 -8.96772,-2.30074 -13.18182,-2.25 -1.5815,0.018 -3.20062,0.68066 -4.9999999,2.75 l 0,0.5 0,1.5 0,0.0624 c 0.35284,-0.39764 0.68014,-0.7662 1.0227199,-1.0625 0.34258,-0.2963 0.6881,-0.5439 1.02274,-0.75 0.66926,-0.4122 1.33732,-0.63162 1.98864,-0.75 -0.1292,-0.018 -0.26402,-0.0344 -0.39774,-0.0624 0.4581,-0.1264 0.91488,-0.1824 1.36364,-0.1874 3.05338,-0.0368 6.11734,2.72286 9.375,3.125 0.1286,0.016 0.26858,-0.008 0.39772,0 0.172,0.01 0.33786,0.0674 0.51138,0.0624 0.1896,-0.006 0.37654,-0.0376 0.56818,-0.0624 0.26176,-0.034 0.5297,-0.1128 0.79544,-0.1874 0.37798,-0.1058 0.75176,-0.2352 1.13638,-0.4375 0.0602,-0.031 0.11,-0.0914 0.1704,-0.125 0.33964,-0.1886 0.67552,-0.41302 1.02274,-0.6875 0.33604,-0.26566 0.67898,-0.51938 1.02272,-0.875 l 0,-0.0624 0,-2 0,-14 z"
+     style="fill:#8e0000;fill-opacity:1;fill-rule:evenodd" /><path
+     style="fill:url(#linearGradient3605);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3)"
+     d="m 64,321 0,14 3,0 0,-1 -2,0 0,-12 2,0 0,-1 z m 13,0 0,1 2,0 0,12 -2,0 0,1 3,0 0,-14 z"
+     transform="matrix(2,0,0,2,1.0000003,-367.74991)"
+     id="rect3578"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccc" /><g
+     style="font-size:13.71140385px;font-style:normal;font-weight:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;fill:url(#linearGradient3609);fill-opacity:1;stroke:none;filter:url(#filter3224-1-7-1-3);font-family:Sans"
+     id="text4354"
+     transform="matrix(2,0,0,2,3.0000003,-367.74989)"><path
+       d="m 70.006423,329.43503 1.991763,0 c 1.837326,0 3.016509,-1.30258 3.016509,-3.33187 0,-2.00186 -1.138049,-3.09877 -3.22218,-3.09877 l -3.790777,0 0,9.99561 2.004685,0 0,-3.56497 m 0,-1.71392 0,-3.0028 1.347327,0 c 1.096911,0 1.604234,0.4799 1.604234,1.50826 0,1.01464 -0.507323,1.49454 -1.604234,1.49454 l -1.347327,0"
+       style="font-variant:normal;font-weight:bold;font-stretch:normal;fill:url(#linearGradient3607);font-family:Nimbus Sans L;-inkscape-font-specification:Nimbus Sans L Bold"
+       id="path4361"
+       inkscape:connector-curvature="0"
+       sodipodi:nodetypes="csssccccccsssc" /></g><path
+     inkscape:connector-curvature="0"
+     id="rect4493"
+     d="m 518,-165.75001 c -1.662,0 -3,1.338 -3,3 l 0,5 c 0,1.36076 0.91892,2.47391 2.15625,2.84375 -0.0819,-0.27391 -0.15625,-0.54251 -0.15625,-0.84375 l 0,-5 c 0,-1.662 1.338,-3 3,-3 l 22,0 c 0.30124,0 0.56984,0.0744 0.84375,0.15625 -0.36984,-1.23733 -1.48299,-2.15625 -2.84375,-2.15625 l -22,0 z"
+     style="fill:#808080;fill-opacity:0.99215686;fill-rule:nonzero;stroke:none" /><path
+     style="font-size:medium;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-indent:0;text-align:start;text-decoration:none;line-height:normal;letter-spacing:normal;word-spacing:normal;text-transform:none;direction:ltr;block-progression:tb;writing-mode:lr-tb;text-anchor:start;baseline-shift:baseline;opacity:0.98999999;color:#000000;fill:url(#linearGradient5855);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:2;marker:none;visibility:visible;display:inline;overflow:visible;filter:url(#filter3224-1-7-1);enable-background:accumulate;font-family:Sans;-inkscape-font-specification:Sans"
+     d="m 67,128 c -1.108,0 -2,0.892 -2,2 l 0,12 c 0,1.108 0.892,2 2,2 l 1,0 1,0 3,0 c 2.181406,0 4,-1.81859 4,-4 l 0,-2 c 0,-2.18141 -1.818594,-4 -4,-4 l -3,0 0,-4 c 0,-1.108 -0.892,-2 -2,-2 z m 18,4 -6,3.875 6,4 0,-2.625 c 4.53598,0.002 6.887,2.90102 8,4.625 -0.112,-4.06048 -3.48268,-7.3724 -8,-7.375 z m -16,4 3,0 c 1.108,0 2,0.892 2,2 l 0,2 c 0,1.108 -0.892,2 -2,2 l -3,0 z m 17,8 c -0.554,0 -1,0.446 -1,1 0,0.554 0.446,1 1,1 l 2,0 c 3,0 3,2 3,3 l 0,1 -4,0 c -2.181406,0 -4,1.81859 -4,4 l 0,2 c 0,2.18141 1.818594,4 4,4 l 4,0 1,0 1,0 c 1.108,0 2,-0.892 2,-2 l 0,-10 c 0,-4 -5,-4 -5,-4 l -1,0 z m -19,4 c 0.112,4.06048 3.48268,7.37242 8,7.375 l 0,2.5 6,-3.875 -6,-4 0,2.625 C 70.46402,152.623 68.113,149.72398 67,148 z m 20,4 4,0 0,1 0,4 0,1 -4,0 c -1.108,0 -2,-0.892 -2,-2 l 0,-2 c 0,-1.108 0.892,-2 2,-2 z"
+     transform="translate(1,-367.75001)"
+     id="path4589"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="ssssccsssscssccccccccssssccssssscssssccsssccscccccccsccccssss" /><g
+     id="g5901"
+     style="fill:url(#linearGradient5906)"><path
+       d="m 584.67613,-45.75002 c 1.46129,2e-5 2.48419,0.58335 3.06872,1.75001 0.2338,0.48612 0.37993,1.06945 0.43839,1.74999 l 0,7.00001 c -10e-6,1.45834 -0.58452,2.47916 -1.75355,3.0625 -0.48711,0.23333 -1.07162,0.37917 -1.75356,0.4375 l -4.67613,0 0,-14.00001 4.67613,0 m 1.16904,11.08334 0,-8.16667 c -1e-5,-0.71943 -0.38969,-1.10832 -1.16904,-1.16666 l -2.33806,0 0,10.5 2.33806,0 c 0.7209,0 1.11058,-0.38889 1.16904,-1.16667"
+       style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98999999;fill:url(#linearGradient5906);fill-opacity:1;stroke:none;display:inline;filter:url(#filter3224-1-7-1-3);font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+       id="path5866"
+       inkscape:connector-curvature="0" /><path
+       d="m 597.01421,-44.00001 -2.33807,0 0,10.5 2.33807,0 0,1.75 -7.0142,0 0,-1.75 2.33806,0 0,-10.5 -2.33806,0 0,-1.75001 7.0142,0 0,1.75001"
+       style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98999999;fill:url(#linearGradient5906);fill-opacity:1;stroke:none;display:inline;filter:url(#filter3224-1-7-1-3);font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+       id="path5868"
+       inkscape:connector-curvature="0" /><path
+       d="m 607.18325,-44.00001 -2.92259,12.25 -2.33807,0 -2.92258,-12.25 0,-1.75001 2.33807,0 0,1.75001 1.75354,10.5 1.75356,-10.5 0,-1.75001 2.33807,0 0,1.75001"
+       style="font-size:22.18914413px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;line-height:125%;letter-spacing:0px;word-spacing:0px;opacity:0.98999999;fill:url(#linearGradient5906);fill-opacity:1;stroke:none;display:inline;filter:url(#filter3224-1-7-1-3);font-family:Audimat Mono;-inkscape-font-specification:Audimat Mono"
+       id="path5870"
+       inkscape:connector-curvature="0" /></g><path
+     style="opacity:0.98999999;fill:url(#linearGradient6101);fill-opacity:1;stroke:none;display:inline;filter:url(#filter3224-1-7-1-3-1)"
+     d="M 166.53125,32 C 166.23664,32 166,32.23664 166,32.53125 L 166,33 165.53125,33 C 165.23664,33 165,33.23664 165,33.53125 l 0,0.9375 C 165,34.76335 165.23664,35 165.53125,35 l 1,0 2.9375,0 1,0 C 170.76336,35 171,34.76335 171,34.46875 l 0,-0.9375 C 171,33.23664 170.76336,33 170.46875,33 L 170,33 170,32.53125 C 170,32.23664 169.76336,32 169.46875,32 z M 164,33 c -1.0907,0 -2,0.9093 -2,2 l 0,9 c 0,1.0907 0.9093,2 2,2 l 1,0 0,-1 -1,0 c -0.554,0 -1,-0.446 -1,-1 l 0,-9 c 0,-0.554 0.446,-1 1,-1 l 0,-0.46875 c 0,-0.18358 0.0317,-0.36661 0.0937,-0.53125 z m 7.90625,0 C 171.9684,33.16465 172,33.34767 172,33.53125 L 172,34 c 0.554,0 1,0.446 1,1 l 0,2 1,0 0,-2 c 0,-1.0907 -0.9093,-2 -2,-2 l -0.0937,0 z M 167,38 c -0.554,0 -1,0.446 -1,1 l 0,7 c 0,0.554 0.446,1 1,1 l 7,0 c 0.554,0 1,-0.446 1,-1 l 0,-7 c 0,-0.554 -0.446,-1 -1,-1 z m 0,1 7,0 0,7 -7,0 z m 1,1 0,1 0,4 1,0 1,-1 0.5,-0.50005 L 171,44 l 1,1 1,0 0,-4 0,-1 -1,0 0,3 -1,-1 -1,0 -1,1 0,-3 z"
+     transform="matrix(-2,0,0,2,737,-367.75001)"
+     id="path4585-1"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="sscssssccsssscsssssssccssscscscscsccssccsssssssssccccccccccccccccccccccc" /><path
+     style="fill:#666666;fill-opacity:1;fill-rule:nonzero;stroke:none;display:inline;filter:url(#filter3224-1-7-1-5-0-8)"
+     d="m 223.46875,276.31249 c -5.17784,1.61214 -11.48202,1.46403 -12.53125,1.375 l 0.5,1.9375 c 1.53833,0.005 2.5625,0.0382 4.5625,-0.0781 l 0,4.70312 -6,0 0,2 6,0 0,6 -4,0 -2,0 0,10 2,0 0,-2 10,0 0,1 2,0 0,-1 0,-8 -2,0 -4,0 0,-6 6,0 0,-2 -6,0 0,-4.84375 c 2.35241,-0.16735 3.875,-0.53375 5.875,-1.25 z M 196,276.24999 l 0,2 12,0 0,-2 z m -2,4 0,2 16,0 0,-2 z m 2,4 0,2 12,0 0,-2 z m 0,4 0,2 12,0 0,-2 z m 0,4 0,10 2,0 0,-2 8,0 0,1 2,0 0,-1 0,-8 -2,0 -8,0 z m 2,2 8,0 0,4 -8,0 z m 14,0 10,0 0,4 -10,0 z"
+     id="rect4258"
+     inkscape:connector-curvature="0"
+     sodipodi:nodetypes="cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc" /><path
+     style="fill:#515151;fill-opacity:1;stroke:none;display:inline;filter:url(#filter3224-1-7-1-3-24)"
+     d="m 170,230.24999 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m -14,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,5 0,1 0,3 5,0 0,-1 -4,0 0,-1 4,0 1,0 0,-1 -5,0 0,-1 6,0 4,0 0,-1 0,-4 -4,0 -7,0 z m 12,0 0,1 1,0 0,-1 -1,0 z m -11,1 9,0 0,1 -9,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -11,1 8.9687,0 0,1 -8.9687,0 0,-1 z m -3,1 0,1 1,0 0,-1 -1,0 z m 14,0 0,1 1,0 0,-1 -1,0 z m -3,1.75 -3.6875,3.375 3.6875,3.28125 0,-1.90625 -1.4375,-1.40625 1.4375,-1.53125 0,-1.8125 z m 1,0 0,1.875 1.375,1.46875 -1.375,1.46875 0,1.90625 3.625,-3.375 -3.625,-3.34375 z m -12,0.25 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 0,2 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z m 2,0 0,1 1,0 0,-1 -1,0 z"
+     id="rect5051"
+     inkscape:connector-curvature="0"
+     transform="matrix(2,0,0,2,-83,-186.24999)" /></g></svg>
\ No newline at end of file
diff --git a/sources/skins/moono/dev/locations.json b/sources/skins/moono/dev/locations.json
new file mode 100644 (file)
index 0000000..4e09053
--- /dev/null
@@ -0,0 +1,145 @@
+{
+       "0": [
+               [
+                       "plugins/sourcearea/icons/source.png",
+                       "plugins/sourcedialog/icons/sourcedialog.png"
+               ],
+               [
+                       "plugins/sourcearea/icons/source-rtl.png",
+                       "plugins/sourcedialog/icons/sourcedialog-rtl.png"
+               ],
+               "plugins/save/icons/save.png",
+               "plugins/newpage/icons/newpage.png",
+               "plugins/newpage/icons/newpage-rtl.png",
+               "plugins/preview/icons/preview.png",
+               "plugins/preview/icons/preview-rtl.png",
+               "plugins/print/icons/print.png",
+               [
+                       "plugins/templates/icons/templates.png",
+                       "plugins/templates/icons/templates-rtl.png"
+               ],
+               "plugins/docprops/icons/docprops.png",
+               "plugins/docprops/icons/docprops-rtl.png"
+       ],
+       "1": [
+               [
+                       "plugins/clipboard/icons/cut-rtl.png",
+                       "plugins/clipboard/icons/cut.png"
+               ],
+               [
+                       "plugins/clipboard/icons/copy.png",
+                       "plugins/clipboard/icons/copy-rtl.png"
+               ],
+               [
+                       "plugins/clipboard/icons/paste.png",
+                       "plugins/clipboard/icons/paste-rtl.png"
+               ],
+               "plugins/pastetext/icons/pastetext.png",
+               "plugins/pastetext/icons/pastetext-rtl.png",
+               "plugins/pastefromword/icons/pastefromword.png",
+               "plugins/pastefromword/icons/pastefromword-rtl.png",
+               "plugins/undo/icons/undo.png",
+               "plugins/undo/icons/undo-rtl.png",
+               "plugins/undo/icons/redo.png",
+               "plugins/undo/icons/redo-rtl.png"
+       ],
+       "2": [
+               [
+                       "plugins/find/icons/find-rtl.png",
+                       "plugins/find/icons/find.png"
+               ],
+               "plugins/find/icons/replace.png",
+               "plugins/selectall/icons/selectall.png",
+               [
+                       "plugins/wsc/icons/spellchecker.png",
+                       "plugins/scayt/icons/scayt.png"
+               ]
+       ],
+       "3": [
+               "plugins/forms/icons/form.png",
+               "plugins/forms/icons/checkbox.png",
+               "plugins/forms/icons/radio.png",
+               [
+                       "plugins/forms/icons/textfield-rtl.png",
+                       "plugins/forms/icons/textfield.png"
+               ],
+               "plugins/forms/icons/textarea.png",
+               "plugins/forms/icons/textarea-rtl.png",
+               "plugins/forms/icons/select.png",
+               "plugins/forms/icons/select-rtl.png",
+               "plugins/forms/icons/button.png",
+               "plugins/forms/icons/imagebutton.png",
+               "plugins/forms/icons/hiddenfield.png"
+       ],
+       "4": [
+               "plugins/basicstyles/icons/bold.png",
+               "plugins/basicstyles/icons/italic.png",
+               "plugins/basicstyles/icons/underline.png",
+               "plugins/basicstyles/icons/strike.png",
+               "plugins/basicstyles/icons/superscript.png",
+               "plugins/basicstyles/icons/subscript.png",
+               "plugins/removeformat/icons/removeformat.png"
+       ],
+       "5": [
+               "plugins/list/icons/numberedlist.png",
+               "plugins/list/icons/numberedlist-rtl.png",
+               "plugins/list/icons/bulletedlist.png",
+               "plugins/list/icons/bulletedlist-rtl.png",
+               "plugins/indent/icons/outdent.png",
+               "plugins/indent/icons/indent.png",
+               "plugins/indent/icons/indent-rtl.png",
+               "plugins/indent/icons/outdent-rtl.png",
+               "plugins/blockquote/icons/blockquote.png",
+               "plugins/div/icons/creatediv.png",
+               "plugins/justify/icons/justifyleft.png",
+               "plugins/justify/icons/justifycenter.png",
+               "plugins/justify/icons/justifyright.png",
+               "plugins/justify/icons/justifyblock.png",
+               "plugins/bidi/icons/bidiltr.png",
+               "plugins/bidi/icons/bidirtl.png"
+       ],
+       "6": [
+               "plugins/link/icons/link.png",
+               "plugins/link/icons/unlink.png",
+               "plugins/link/icons/anchor.png",
+               "plugins/link/icons/anchor-rtl.png",
+               "plugins/copyformatting/icons/copyformatting.png"
+       ],
+       "7": [
+               [
+                       "plugins/image/icons/image.png",
+                       "plugins/image2/icons/image.png"
+               ],
+               "plugins/flash/icons/flash.png",
+               "plugins/table/icons/table.png",
+               "plugins/horizontalrule/icons/horizontalrule.png",
+               "plugins/smiley/icons/smiley.png",
+               "plugins/specialchar/icons/specialchar.png",
+               "plugins/pagebreak/icons/pagebreak.png",
+               "plugins/pagebreak/icons/pagebreak-rtl.png",
+               "plugins/iframe/icons/iframe.png"
+       ],
+       "8": [
+               "plugins/colorbutton/icons/textcolor.png",
+               "plugins/colorbutton/icons/bgcolor.png"
+       ],
+       "9": [
+               "plugins/maximize/icons/maximize.png",
+               "plugins/showblocks/icons/showblocks.png",
+               "plugins/showblocks/icons/showblocks-rtl.png"
+       ],
+       "10": [
+               "plugins/about/icons/about.png",
+               "plugins/uicolor/icons/uicolor.png",
+               "plugins/placeholder/icons/placeholder.png",
+               "plugins/language/icons/language.png",
+               "plugins/codesnippet/icons/codesnippet.png"
+       ],
+       "11": [
+               "plugins/link/images/anchor.png",
+               "skins/moono/images/close.png",
+               "skins/moono/images/lock.png",
+               "skins/moono/images/lock-open.png",
+               "skins/moono/images/refresh.png"
+       ]
+}
diff --git a/sources/skins/moono/dialog.css b/sources/skins/moono/dialog.css
new file mode 100644 (file)
index 0000000..93907be
--- /dev/null
@@ -0,0 +1,1060 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+dialog.css\r
+============\r
+\r
+This file styles dialogs and all widgets available inside of it (tabs, buttons,\r
+fields, etc.).\r
+\r
+Dialogs are a complex system because they're very flexible. The CKEditor API\r
+makes it easy to create and customize dialogs by code, by making use of several\r
+different widgets inside its contents.\r
+\r
+All dialogs share a main dialog strucuture, which can be visually represented\r
+as follows:\r
+\r
++-- .cke_dialog -------------------------------------------------+\r
+| +-- .cke_dialog_body ----------------------------------------+ |\r
+| | +-- .cke_dialog_title --+ +-- .cke_dialog_close_button --+ | |\r
+| | |                       | |                              | | |\r
+| | +-----------------------+ +------------------------------+ | |\r
+| | +-- .cke_dialog_tabs ------------------------------------+ | |\r
+| | |                                                        | | |\r
+| | +--------------------------------------------------------+ | |\r
+| | +-- .cke_dialog_contents --------------------------------+ | |\r
+| | | +-- .cke_dialog_contents_body -----------------------+ | | |\r
+| | | |                                                    | | | |\r
+| | | +----------------------------------------------------+ | | |\r
+| | | +-- .cke_dialog_footer ------------------------------+ | | |\r
+| | | |                                                    | | | |\r
+| | | +----------------------------------------------------+ | | |\r
+| | +--------------------------------------------------------+ | |\r
+| +------------------------------------------------------------+ |\r
++----------------------------------------------------------------+\r
+\r
+Comments in this file will give more details about each of the above blocks.\r
+*/\r
+\r
+/* The outer container of the dialog. */\r
+.cke_dialog\r
+{\r
+       /* Mandatory: Because the dialog.css file is loaded on demand, we avoid\r
+               showing an unstyled dialog by hidding it. Here, we restore its visibility. */\r
+       visibility: visible;\r
+}\r
+\r
+/* The inner boundary container. */\r
+.cke_dialog_body\r
+{\r
+       z-index: 1;\r
+       background: #eaeaea;\r
+       border: 1px solid #b2b2b2;\r
+       border-bottom-color: #999;\r
+       border-radius: 3px;\r
+       box-shadow: 0 0 3px rgba(0, 0, 0, .15);\r
+}\r
+\r
+/* Due to our reset we have to recover the styles of some elements. */\r
+.cke_dialog strong\r
+{\r
+       font-weight: bold;\r
+}\r
+\r
+/* The dialog title. */\r
+.cke_dialog_title\r
+{\r
+       font-weight: bold;\r
+       font-size: 13px;\r
+       cursor: move;\r
+       position: relative;\r
+\r
+       color: #474747;\r
+       text-shadow: 0 1px 0 rgba(255,255,255,.75);\r
+\r
+       border-bottom: 1px solid #999;\r
+       padding: 6px 10px;\r
+\r
+       border-radius: 2px 2px 0 0;\r
+       box-shadow: 0 1px 0 #fff inset;\r
+\r
+       background: #cfd1cf;\r
+       background-image: linear-gradient(to bottom, #f5f5f5, #cfd1cf);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f5f5f5', endColorstr='#cfd1cf');\r
+}\r
+\r
+.cke_dialog_spinner\r
+{\r
+       border-radius: 50%;\r
+\r
+       width: 12px;\r
+       height: 12px;\r
+       overflow: hidden;\r
+\r
+       text-indent: -9999em;\r
+\r
+       border-top: 2px solid rgba(102, 102, 102, 0.2);\r
+       border-right: 2px solid rgba(102, 102, 102, 0.2);\r
+       border-bottom: 2px solid rgba(102, 102, 102, 0.2);\r
+       border-left: 2px solid rgba(102, 102, 102, 1);\r
+\r
+       -webkit-animation: dialog_spinner 1s infinite linear;\r
+       animation: dialog_spinner 1s infinite linear;\r
+}\r
+\r
+/* A GIF fallback for IE8 and IE9 which does not support CSS animations. */\r
+.cke_browser_ie8 .cke_dialog_spinner,\r
+.cke_browser_ie9 .cke_dialog_spinner\r
+{\r
+       background: url(images/spinner.gif) center top no-repeat;\r
+       width: 16px;\r
+       height: 16px;\r
+       border: 0;\r
+}\r
+\r
+@-webkit-keyframes dialog_spinner\r
+{\r
+       0% {\r
+               -webkit-transform: rotate(0deg);\r
+               transform: rotate(0deg);\r
+       }\r
+       100% {\r
+               -webkit-transform: rotate(360deg);\r
+               transform: rotate(360deg);\r
+       }\r
+}\r
+\r
+@keyframes dialog_spinner\r
+{\r
+       0% {\r
+               -webkit-transform: rotate(0deg);\r
+               transform: rotate(0deg);\r
+       }\r
+       100% {\r
+               -webkit-transform: rotate(360deg);\r
+               transform: rotate(360deg);\r
+       }\r
+}\r
+\r
+/* The outer part of the dialog contants, which contains the contents body\r
+   and the footer. */\r
+.cke_dialog_contents\r
+{\r
+       background-color: #fff;\r
+       overflow: auto;\r
+       padding: 15px 10px 5px 10px;\r
+       margin-top: 30px;\r
+       border-top: 1px solid #bfbfbf;\r
+       border-radius: 0 0 3px 3px;\r
+}\r
+\r
+/* The contents body part, which will hold all elements available in the dialog. */\r
+.cke_dialog_contents_body\r
+{\r
+       overflow: auto;\r
+       padding: 17px 10px 5px 10px;\r
+       margin-top: 22px;\r
+}\r
+\r
+/* The dialog footer, which usually contains the "Ok" and "Cancel" buttons as\r
+   well as a resize handler. */\r
+.cke_dialog_footer\r
+{\r
+       text-align: right;\r
+       position: relative;\r
+       border: none;\r
+       outline: 1px solid #bfbfbf;\r
+       box-shadow: 0 1px 0 #fff inset;\r
+       border-radius: 0 0 2px 2px;\r
+       background: #cfd1cf;\r
+       background-image: linear-gradient(to bottom, #ebebeb, #cfd1cf);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ebebeb', endColorstr='#cfd1cf');\r
+}\r
+\r
+.cke_rtl .cke_dialog_footer\r
+{\r
+       text-align: left;\r
+}\r
+\r
+.cke_hc .cke_dialog_footer\r
+{\r
+       outline: none;\r
+       border-top: 1px solid #fff;\r
+}\r
+\r
+.cke_dialog .cke_resizer\r
+{\r
+       margin-top: 22px;\r
+}\r
+\r
+.cke_dialog .cke_resizer_rtl\r
+{\r
+       margin-left: 5px;\r
+}\r
+\r
+.cke_dialog .cke_resizer_ltr\r
+{\r
+       margin-right: 5px;\r
+}\r
+\r
+/*\r
+Dialog tabs\r
+-------------\r
+\r
+Tabs are presented on some of the dialogs to make it possible to have its\r
+contents split on different groups, visible one after the other.\r
+\r
+The main element that holds the tabs can be made hidden, in case of no tabs\r
+available.\r
+\r
+The following is the visual representation of the tabs block:\r
+\r
++-- .cke_dialog_tabs ------------------------------------+\r
+|  +-- .cke_dialog_tab --+ +-- .cke_dialog_tab --+ ...   |\r
+|  |                     | |                     |       |\r
+|  +---------------------+ +---------------------+       |\r
++--------------------------------------------------------+\r
+\r
+The .cke_dialog_tab_selected class is appended to the active tab.\r
+*/\r
+\r
+/* The main tabs container. */\r
+.cke_dialog_tabs\r
+{\r
+       height: 24px;\r
+       display: inline-block;\r
+       margin: 5px 0 0;\r
+       position: absolute;\r
+       z-index: 2;\r
+       left: 10px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_tabs\r
+{\r
+       right: 10px;\r
+}\r
+\r
+/* A single tab (an <a> element). */\r
+a.cke_dialog_tab\r
+{\r
+\r
+       height: 16px;\r
+       padding: 4px 8px;\r
+       margin-right: 3px;\r
+       display: inline-block;\r
+       cursor: pointer;\r
+       line-height: 16px;\r
+       outline: none;\r
+       color: #595959;\r
+       border: 1px solid #bfbfbf;\r
+\r
+       border-radius: 3px 3px 0 0;\r
+\r
+       background: #d4d4d4;\r
+       background-image: linear-gradient(to bottom, #fafafa, #ededed);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#fafafa', endColorstr='#ededed');\r
+}\r
+\r
+.cke_rtl a.cke_dialog_tab\r
+{\r
+       margin-right: 0;\r
+       margin-left: 3px;\r
+}\r
+\r
+/* A hover state of a regular inactive tab. */\r
+a.cke_dialog_tab:hover,\r
+a.cke_dialog_tab:focus\r
+{\r
+       background: #ebebeb;\r
+       background: linear-gradient(to bottom, #ebebeb 0%,#dfdfdf 100%);\r
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ebebeb', endColorstr='#dfdfdf',GradientType=0 );\r
+}\r
+\r
+a.cke_dialog_tab_selected\r
+{\r
+       background: #fff;\r
+       color: #383838;\r
+       border-bottom-color: #fff;\r
+       cursor: default;\r
+       filter: none;\r
+}\r
+\r
+/* A hover state for selected tab. */\r
+a.cke_dialog_tab_selected:hover,\r
+a.cke_dialog_tab_selected:focus\r
+{\r
+       background: #ededed;\r
+       background: linear-gradient(to bottom, #ededed 0%,#ffffff 100%);\r
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ededed', endColorstr='#ffffff',GradientType=0 );\r
+}\r
+\r
+.cke_hc a.cke_dialog_tab:hover,\r
+.cke_hc a.cke_dialog_tab:focus,\r
+.cke_hc a.cke_dialog_tab_selected\r
+{\r
+       border: 3px solid;\r
+       padding: 2px 6px;\r
+}\r
+\r
+a.cke_dialog_tab_disabled\r
+{\r
+       color: #bababa;\r
+       cursor: default;\r
+}\r
+\r
+/* The .cke_single_page class is appended to the dialog outer element in case\r
+   of dialogs that has no tabs. */\r
+.cke_single_page .cke_dialog_tabs\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_single_page .cke_dialog_contents\r
+{\r
+       padding-top: 5px;\r
+       margin-top: 0;\r
+       border-top: none;\r
+}\r
+\r
+/* The close button at the top of the dialog. */\r
+\r
+a.cke_dialog_close_button\r
+{\r
+       background-image: url(images/close.png);\r
+       background-repeat: no-repeat;\r
+       background-position: 50%;\r
+       position: absolute;\r
+       cursor: pointer;\r
+       text-align: center;\r
+       height: 20px;\r
+       width: 20px;\r
+       top: 4px;\r
+       z-index: 5;\r
+       opacity: 0.8;\r
+       filter: alpha(opacity = 80);\r
+}\r
+\r
+.cke_dialog_close_button:hover\r
+{\r
+       opacity: 1;\r
+       filter: alpha(opacity = 100);\r
+}\r
+\r
+.cke_hidpi .cke_dialog_close_button\r
+{\r
+       background-image: url(images/hidpi/close.png);\r
+       background-size: 16px;\r
+}\r
+\r
+.cke_dialog_close_button span\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_hc .cke_dialog_close_button span\r
+{\r
+       display: inline;\r
+       cursor: pointer;\r
+       font-weight: bold;\r
+       position: relative;\r
+       top: 3px;\r
+}\r
+\r
+.cke_ltr .cke_dialog_close_button\r
+{\r
+       right: 5px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_close_button\r
+{\r
+       left: 6px;\r
+}\r
+\r
+.cke_dialog_close_button\r
+{\r
+       top: 4px;\r
+}\r
+\r
+/*\r
+Dialog UI Elements\r
+--------------------\r
+\r
+The remaining styles define the UI elements that can be used inside dialog\r
+contents.\r
+\r
+Most of the UI elements on dialogs contain a textual label. All of them share\r
+the same labelling structure, having the label text inside an element with\r
+.cke_dialog_ui_labeled_label and the element specific part inside the\r
+.cke_dialog_ui_labeled_content class.\r
+*/\r
+\r
+/* If an element is supposed to be disabled, the .cke_disabled class is\r
+   appended to it. */\r
+div.cke_disabled .cke_dialog_ui_labeled_content div *\r
+{\r
+       background-color: #ddd;\r
+       cursor: default;\r
+}\r
+\r
+/*\r
+Horizontal-Box and Vertical-Box\r
+---------------------------------\r
+\r
+There are basic layou element used by the editor to properly align elements in\r
+the dialog. They're basically tables that have each cell filled by UI elements.\r
+\r
+The following is the visual representation of a H-Box:\r
+\r
++-- .cke_dialog_ui_hbox --------------------------------------------------------------------------------+\r
+|  +-- .cke_dialog_ui_hbox_first --+ +-- .cke_dialog_ui_hbox_child --+ +-- .cke_dialog_ui_hbox_last --+ |\r
+|  +                               + +                               + +                              + |\r
+|  +-------------------------------+ +-------------------------------+ +------------------------------+ |\r
++-------------------------------------------------------------------------------------------------------+\r
+\r
+It is possible to have nested V/H-Boxes.\r
+*/\r
+\r
+.cke_dialog_ui_vbox table,\r
+.cke_dialog_ui_hbox table\r
+{\r
+       margin: auto;\r
+}\r
+\r
+.cke_dialog_ui_vbox_child\r
+{\r
+       padding: 5px 0px;\r
+}\r
+\r
+.cke_dialog_ui_hbox\r
+{\r
+       width: 100%;\r
+}\r
+\r
+.cke_dialog_ui_hbox_first,\r
+.cke_dialog_ui_hbox_child,\r
+.cke_dialog_ui_hbox_last\r
+{\r
+       vertical-align: top;\r
+}\r
+\r
+.cke_ltr .cke_dialog_ui_hbox_first,\r
+.cke_ltr .cke_dialog_ui_hbox_child\r
+{\r
+       padding-right: 10px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_ui_hbox_first,\r
+.cke_rtl .cke_dialog_ui_hbox_child\r
+{\r
+       padding-left: 10px;\r
+}\r
+\r
+.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,\r
+.cke_ltr .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child\r
+{\r
+       padding-right: 5px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_first,\r
+.cke_rtl .cke_dialog_footer_buttons .cke_dialog_ui_hbox_child\r
+{\r
+       padding-left: 5px;\r
+       padding-right: 0;\r
+}\r
+\r
+/* Applies to all labeled dialog fields */\r
+.cke_hc div.cke_dialog_ui_input_text,\r
+.cke_hc div.cke_dialog_ui_input_password,\r
+.cke_hc div.cke_dialog_ui_input_textarea,\r
+.cke_hc div.cke_dialog_ui_input_select,\r
+.cke_hc div.cke_dialog_ui_input_file\r
+{\r
+       border: 1px solid;\r
+}\r
+\r
+/*\r
+Text Input\r
+------------\r
+\r
+The basic text field to input text.\r
+\r
++-- .cke_dialog_ui_text --------------------------+\r
+|  +-- .cke_dialog_ui_labeled_label ------------+ |\r
+|  |                                            | |\r
+|  +--------------------------------------------+ |\r
+|  +-- .cke_dialog_ui_labeled_content ----------+ |\r
+|  | +-- div.cke_dialog_ui_input_text --------+ | |\r
+|  | | +-- input.cke_dialog_ui_input_text --+ | | |\r
+|  | | |                                    | | | |\r
+|  | | +------------------------------------+ | | |\r
+|  | +----------------------------------------+ | |\r
+|  +--------------------------------------------+ |\r
++-------------------------------------------------+\r
+*/\r
+\r
+/*\r
+Textarea\r
+----------\r
+\r
+The textarea field to input larger text.\r
+\r
++-- .cke_dialog_ui_textarea --------------------------+\r
+|  +-- .cke_dialog_ui_labeled_label ----------------+ |\r
+|  |                                                | |\r
+|  +------------------------------------------------+ |\r
+|  +-- .cke_dialog_ui_labeled_content --------------+ |\r
+|  | +-- div.cke_dialog_ui_input_textarea --------+ | |\r
+|  | | +-- input.cke_dialog_ui_input_textarea --+ | | |\r
+|  | | |                                        | | | |\r
+|  | | +----------------------------------------+ | | |\r
+|  | +--------------------------------------------+ | |\r
+|  +------------------------------------------------+ |\r
++-----------------------------------------------------+\r
+*/\r
+\r
+textarea.cke_dialog_ui_input_textarea\r
+{\r
+       overflow: auto;\r
+       resize: none;\r
+}\r
+\r
+input.cke_dialog_ui_input_text,\r
+input.cke_dialog_ui_input_password,\r
+textarea.cke_dialog_ui_input_textarea\r
+{\r
+       background-color: #fff;\r
+       border: 1px solid #c9cccf;\r
+       border-top-color: #aeb3b9;\r
+       padding: 4px 6px;\r
+       outline: none;\r
+       width: 100%;\r
+       *width: 95%;\r
+\r
+       box-sizing: border-box;\r
+\r
+       border-radius: 3px;\r
+\r
+       box-shadow: 0 1px 2px rgba(0,0,0,.15) inset;\r
+}\r
+\r
+input.cke_dialog_ui_input_text:hover,\r
+input.cke_dialog_ui_input_password:hover,\r
+textarea.cke_dialog_ui_input_textarea:hover\r
+{\r
+       border: 1px solid #aeb3b9;\r
+       border-top-color: #a0a6ad;\r
+}\r
+\r
+input.cke_dialog_ui_input_text:focus,\r
+input.cke_dialog_ui_input_password:focus,\r
+textarea.cke_dialog_ui_input_textarea:focus,\r
+select.cke_dialog_ui_input_select:focus\r
+{\r
+       outline: none;\r
+       border: 1px solid #139ff7;\r
+       border-top-color: #1392e9;\r
+}\r
+\r
+/*\r
+Button\r
+--------\r
+\r
+The buttons used in the dialog footer or inside the contents.\r
+\r
++-- a.cke_dialog_ui_button -----------+\r
+|  +-- span.cke_dialog_ui_button --+  |\r
+|  |                               |  |\r
+|  +-------------------------------+  |\r
++-------------------------------------+\r
+*/\r
+\r
+/* The outer part of the button. */\r
+a.cke_dialog_ui_button\r
+{\r
+       display: inline-block;\r
+       *display: inline;\r
+       *zoom: 1;\r
+\r
+       padding: 4px 0;\r
+       margin: 0;\r
+\r
+       text-align: center;\r
+       color: #333;\r
+       vertical-align: middle;\r
+       cursor: pointer;\r
+\r
+       border: 1px solid #b6b6b6;\r
+       border-bottom-color: #999;\r
+       border-radius: 3px;\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.5), 0 0 2px rgba(255,255,255,.15) inset, 0 1px 0 rgba(255,255,255,.15) inset;\r
+\r
+       background: #e4e4e4;\r
+       background-image: linear-gradient(to bottom, #ffffff, #e4e4e4);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ffffff', endColorstr='#e4e4e4');\r
+\r
+}\r
+\r
+span.cke_dialog_ui_button\r
+{\r
+       padding: 0 10px;\r
+}\r
+\r
+a.cke_dialog_ui_button:hover\r
+{\r
+       border-color: #9e9e9e;\r
+\r
+       background: #ccc;\r
+       background-image: linear-gradient(to bottom, #f2f2f2, #ccc);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f2f2f2', endColorstr='#cccccc');\r
+}\r
+\r
+/*     :focus/:active styles for dialog buttons: regular and footer. */\r
+a.cke_dialog_ui_button:focus,\r
+a.cke_dialog_ui_button:active\r
+{\r
+       border-color: #969696;\r
+       outline: none;\r
+       box-shadow: 0 0 6px rgba(0,0,0,.4) inset;\r
+}\r
+\r
+.cke_hc a.cke_dialog_ui_button:hover,\r
+.cke_hc a.cke_dialog_ui_button:focus,\r
+.cke_hc a.cke_dialog_ui_button:active\r
+{\r
+       border: 3px solid;\r
+       padding-top: 1px;\r
+       padding-bottom: 1px;\r
+}\r
+\r
+.cke_hc a.cke_dialog_ui_button:hover span,\r
+.cke_hc a.cke_dialog_ui_button:focus span,\r
+.cke_hc a.cke_dialog_ui_button:active span\r
+{\r
+       padding-left: 10px;\r
+       padding-right: 10px;\r
+}\r
+\r
+/*\r
+a.cke_dialog_ui_button[style*="width"]\r
+{\r
+       display: block !important;\r
+       width: auto !important;\r
+}\r
+*/\r
+/* The inner part of the button (both in dialog tabs and dialog footer). */\r
+.cke_dialog_footer_buttons a.cke_dialog_ui_button span\r
+{\r
+       color: inherit;\r
+       font-size: 12px;\r
+       font-weight: bold;\r
+       line-height: 18px;\r
+       padding: 0 12px;\r
+}\r
+\r
+/* Special class appended to the Ok button. */\r
+a.cke_dialog_ui_button_ok\r
+{\r
+       color: #fff;\r
+       text-shadow: 0 -1px 0 #55830c;\r
+       border-color: #62a60a #62a60a #4d9200;\r
+\r
+       background: #69b10b;\r
+       background-image: linear-gradient(to bottom, #9ad717, #69b10b);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#9ad717', endColorstr='#69b10b');\r
+}\r
+\r
+a.cke_dialog_ui_button_ok:hover\r
+{\r
+       border-color: #5b9909 #5b9909 #478500;\r
+\r
+       background: #88be14;\r
+       background: linear-gradient(to bottom, #88be14 0%,#5d9c0a 100%);\r
+       filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#88be14', endColorstr='#5d9c0a',GradientType=0 );\r
+}\r
+\r
+a.cke_dialog_ui_button_ok.cke_disabled {\r
+       border-color: #7D9F51;\r
+\r
+       background: #8DAD62;\r
+       background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#B3D271), to(#8DAD62));\r
+       background-image: -webkit-linear-gradient(top, #B3D271, #8DAD62);\r
+       background-image: -o-linear-gradient(top, #B3D271, #8DAD62);\r
+       background-image: linear-gradient(to bottom, #B3D271, #8DAD62);\r
+       background-image: -moz-linear-gradient(top, #B3D271, #8DAD62);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#B3D271', endColorstr='#8DAD62');\r
+}\r
+\r
+a.cke_dialog_ui_button_ok.cke_disabled span {\r
+       color: #E0E8D1;\r
+}\r
+\r
+/* Default text shadow used for inner parts of all dialog buttons (both in dialog tabs and dialog footer). */\r
+a.cke_dialog_ui_button span\r
+{\r
+       text-shadow: 0 1px 0 #fff;\r
+}\r
+\r
+/* Text shadow used for inner part of OK dialog button in footer. */\r
+a.cke_dialog_ui_button_ok span\r
+{\r
+       text-shadow: 0 -1px 0 #55830c;\r
+}\r
+\r
+span.cke_dialog_ui_button\r
+{\r
+       cursor: pointer;\r
+}\r
+\r
+/*     :focus/:active styles for dialog footer buttons (ok & cancel) */\r
+a.cke_dialog_ui_button_ok:focus,\r
+a.cke_dialog_ui_button_ok:active,\r
+a.cke_dialog_ui_button_cancel:focus,\r
+a.cke_dialog_ui_button_cancel:active\r
+{\r
+       border-width: 2px;\r
+       padding: 3px 0;\r
+}\r
+\r
+a.cke_dialog_ui_button_ok:focus,\r
+a.cke_dialog_ui_button_ok:active\r
+{\r
+       border-color: #568C0A;\r
+}\r
+\r
+a.cke_dialog_ui_button_ok.cke_disabled:focus,\r
+a.cke_dialog_ui_button_ok.cke_disabled:active\r
+{\r
+       border-color: #6F8C49;\r
+}\r
+\r
+/*     :focus/:active styles for dialog footer buttons (ok & cancel) spans */\r
+a.cke_dialog_ui_button_ok:focus span,\r
+a.cke_dialog_ui_button_ok:active span,\r
+a.cke_dialog_ui_button_cancel:focus span,\r
+a.cke_dialog_ui_button_cancel:active span\r
+{\r
+       padding: 0 11px;        /* Thick button border must be compensated. */\r
+}\r
+\r
+/* A special container that holds the footer buttons. */\r
+.cke_dialog_footer_buttons\r
+{\r
+       display: inline-table;\r
+       margin: 5px;\r
+       width: auto;\r
+       position: relative;\r
+       vertical-align: middle;\r
+}\r
+\r
+/*\r
+Styles for other dialog element types.\r
+*/\r
+\r
+div.cke_dialog_ui_input_select\r
+{\r
+       display: table;\r
+}\r
+\r
+select.cke_dialog_ui_input_select\r
+{\r
+       height: 25px;\r
+       line-height: 25px;\r
+\r
+       background-color: #fff;\r
+       border: 1px solid #c9cccf;\r
+       border-top-color: #aeb3b9;\r
+       padding: 3px 3px 3px 6px;\r
+       outline: none;\r
+       border-radius: 3px;\r
+       box-shadow: 0 1px 2px rgba(0,0,0,.15) inset;\r
+}\r
+\r
+.cke_dialog_ui_input_file\r
+{\r
+       width: 100%;\r
+       height: 25px;\r
+}\r
+\r
+.cke_hc .cke_dialog_ui_labeled_content input:focus,\r
+.cke_hc .cke_dialog_ui_labeled_content select:focus,\r
+.cke_hc .cke_dialog_ui_labeled_content textarea:focus\r
+{\r
+       outline: 1px dotted;\r
+}\r
+\r
+/*\r
+ * Some utility CSS classes for dialog authors.\r
+ */\r
+.cke_dialog .cke_dark_background\r
+{\r
+       background-color: #DEDEDE;\r
+}\r
+\r
+.cke_dialog .cke_light_background\r
+{\r
+       background-color: #EBEBEB;\r
+}\r
+\r
+.cke_dialog .cke_centered\r
+{\r
+       text-align: center;\r
+}\r
+\r
+.cke_dialog a.cke_btn_reset\r
+{\r
+       float: right;\r
+       background: url(images/refresh.png) top left no-repeat;\r
+       width: 16px;\r
+       height: 16px;\r
+       border: 1px none;\r
+       font-size: 1px;\r
+}\r
+\r
+.cke_hidpi .cke_dialog a.cke_btn_reset {\r
+       background-size: 16px;\r
+       background-image: url(images/hidpi/refresh.png);\r
+}\r
+\r
+.cke_rtl .cke_dialog a.cke_btn_reset\r
+{\r
+       float: left;\r
+}\r
+\r
+.cke_dialog a.cke_btn_locked,\r
+.cke_dialog a.cke_btn_unlocked\r
+{\r
+       float: left;\r
+       width: 16px;\r
+       height: 16px;\r
+       background-repeat: no-repeat;\r
+       border: none 1px;\r
+       font-size: 1px;\r
+}\r
+\r
+.cke_dialog a.cke_btn_locked .cke_icon\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_rtl .cke_dialog a.cke_btn_locked,\r
+.cke_rtl .cke_dialog a.cke_btn_unlocked\r
+{\r
+       float: right;\r
+}\r
+\r
+.cke_dialog a.cke_btn_locked\r
+{\r
+       background-image: url(images/lock.png);\r
+}\r
+\r
+.cke_dialog a.cke_btn_unlocked\r
+{\r
+       background-image: url(images/lock-open.png);\r
+}\r
+\r
+.cke_hidpi .cke_dialog a.cke_btn_unlocked,\r
+.cke_hidpi .cke_dialog a.cke_btn_locked {\r
+       background-size: 16px;\r
+}\r
+\r
+.cke_hidpi .cke_dialog a.cke_btn_locked {\r
+       background-image: url(images/hidpi/lock.png);\r
+}\r
+\r
+.cke_hidpi .cke_dialog a.cke_btn_unlocked {\r
+       background-image: url(images/hidpi/lock-open.png);\r
+}\r
+\r
+.cke_dialog .cke_btn_over\r
+{\r
+       border: outset 1px;\r
+       cursor: pointer;\r
+}\r
+\r
+/*\r
+The rest of the file contains style used on several common plugins. There is a\r
+tendency that these will be moved to the plugins code in the future.\r
+*/\r
+\r
+.cke_dialog  .ImagePreviewBox\r
+{\r
+       border: 2px ridge black;\r
+       overflow: scroll;\r
+       height: 200px;\r
+       width: 300px;\r
+       padding: 2px;\r
+       background-color: white;\r
+}\r
+\r
+.cke_dialog .ImagePreviewBox table td\r
+{\r
+       white-space: normal;\r
+}\r
+\r
+.cke_dialog  .ImagePreviewLoader\r
+{\r
+       position: absolute;\r
+       white-space: normal;\r
+       overflow: hidden;\r
+       height: 160px;\r
+       width: 230px;\r
+       margin: 2px;\r
+       padding: 2px;\r
+       opacity: 0.9;\r
+       filter: alpha(opacity = 90);\r
+\r
+       background-color: #e4e4e4;\r
+}\r
+\r
+.cke_dialog .FlashPreviewBox\r
+{\r
+       white-space: normal;\r
+       border: 2px ridge black;\r
+       overflow: auto;\r
+       height: 160px;\r
+       width: 390px;\r
+       padding: 2px;\r
+       background-color: white;\r
+}\r
+\r
+.cke_dialog .cke_pastetext\r
+{\r
+       width: 346px;\r
+       height: 170px;\r
+}\r
+\r
+.cke_dialog .cke_pastetext textarea\r
+{\r
+       width: 340px;\r
+       height: 170px;\r
+       resize: none;\r
+}\r
+\r
+.cke_dialog iframe.cke_pasteframe\r
+{\r
+       width: 346px;\r
+       height: 130px;\r
+       background-color: white;\r
+       border: 1px solid #aeb3b9;\r
+       border-radius: 3px;\r
+}\r
+\r
+.cke_dialog .cke_hand\r
+{\r
+       cursor: pointer;\r
+}\r
+\r
+.cke_disabled\r
+{\r
+       color: #a0a0a0;\r
+}\r
+\r
+.cke_dialog_body .cke_label\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_dialog_body label\r
+{\r
+       display: inline;\r
+       margin-bottom: auto;\r
+       cursor: default;\r
+}\r
+\r
+.cke_dialog_body label.cke_required\r
+{\r
+       font-weight: bold;\r
+}\r
+\r
+a.cke_smile\r
+{\r
+       overflow: hidden;\r
+       display: block;\r
+       text-align: center;\r
+       padding: 0.3em 0;\r
+}\r
+\r
+a.cke_smile img\r
+{\r
+       vertical-align: middle;\r
+}\r
+\r
+a.cke_specialchar\r
+{\r
+       cursor: inherit;\r
+       display: block;\r
+       height: 1.25em;\r
+       padding: 0.2em 0.3em;\r
+       text-align: center;\r
+}\r
+\r
+a.cke_smile,\r
+a.cke_specialchar\r
+{\r
+       border: 1px solid transparent;\r
+}\r
+\r
+a.cke_smile:hover,\r
+a.cke_smile:focus,\r
+a.cke_smile:active,\r
+a.cke_specialchar:hover,\r
+a.cke_specialchar:focus,\r
+a.cke_specialchar:active\r
+{\r
+       background: #fff;\r
+       outline: 0;\r
+}\r
+\r
+a.cke_smile:hover,\r
+a.cke_specialchar:hover\r
+{\r
+       border-color: #888;\r
+}\r
+\r
+a.cke_smile:focus,\r
+a.cke_smile:active,\r
+a.cke_specialchar:focus,\r
+a.cke_specialchar:active\r
+{\r
+       border-color: #139FF7;\r
+}\r
+\r
+/**\r
+ * Styles specific to "cellProperties" dialog.\r
+ */\r
+\r
+.cke_dialog_contents a.colorChooser\r
+{\r
+       display: block;\r
+       margin-top: 6px;\r
+       margin-left: 10px;\r
+       width: 80px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_contents a.colorChooser\r
+{\r
+       margin-right: 10px;\r
+}\r
+\r
+/* Compensate focus outline for some input elements. (#6200) */\r
+.cke_dialog_ui_checkbox_input:focus,\r
+.cke_dialog_ui_radio_input:focus,\r
+.cke_btn_over\r
+{\r
+       outline: 1px dotted #696969;\r
+}\r
+\r
+.cke_iframe_shim\r
+{\r
+       display: block;\r
+       position: absolute;\r
+       top: 0;\r
+       left: 0;\r
+       z-index: -1;\r
+       filter: alpha(opacity = 0);\r
+       width: 100%;\r
+       height: 100%;\r
+}\r
diff --git a/sources/skins/moono/dialog_ie.css b/sources/skins/moono/dialog_ie.css
new file mode 100644 (file)
index 0000000..af86642
--- /dev/null
@@ -0,0 +1,62 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+dialog_ie.css\r
+===============\r
+\r
+This file contains styles to used by all versions of Internet Explorer only.\r
+*/\r
+\r
+/* Base it on dialog.css, overriding it with styles defined in this file. */\r
+@import url("dialog.css");\r
+\r
+/* IE doesn't leave enough padding in text input for cursor to blink in RTL. (#6087) */\r
+.cke_rtl input.cke_dialog_ui_input_text,\r
+.cke_rtl input.cke_dialog_ui_input_password\r
+{\r
+       padding-right: 2px;\r
+}\r
+/* Compensate the padding added above on container. */\r
+.cke_rtl div.cke_dialog_ui_input_text,\r
+.cke_rtl div.cke_dialog_ui_input_password\r
+{\r
+       padding-left: 2px;\r
+}\r
+.cke_rtl div.cke_dialog_ui_input_text {\r
+       padding-right: 1px;\r
+}\r
+\r
+.cke_rtl .cke_dialog_ui_vbox_child,\r
+.cke_rtl .cke_dialog_ui_hbox_child,\r
+.cke_rtl .cke_dialog_ui_hbox_first,\r
+.cke_rtl .cke_dialog_ui_hbox_last\r
+{\r
+       padding-right: 2px !important;\r
+}\r
+\r
+\r
+/* Disable filters for HC mode. */\r
+.cke_hc .cke_dialog_title,\r
+.cke_hc .cke_dialog_footer,\r
+.cke_hc a.cke_dialog_tab,\r
+.cke_hc a.cke_dialog_ui_button,\r
+.cke_hc a.cke_dialog_ui_button:hover,\r
+.cke_hc a.cke_dialog_ui_button_ok,\r
+.cke_hc a.cke_dialog_ui_button_ok:hover\r
+{\r
+    filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\r
+}\r
+\r
+/*     Remove border from dialog field wrappers in HC\r
+       to avoid double borders. */\r
+.cke_hc div.cke_dialog_ui_input_text,\r
+.cke_hc div.cke_dialog_ui_input_password,\r
+.cke_hc div.cke_dialog_ui_input_textarea,\r
+.cke_hc div.cke_dialog_ui_input_select,\r
+.cke_hc div.cke_dialog_ui_input_file\r
+{\r
+       border: 0;\r
+}\r
diff --git a/sources/skins/moono/dialog_ie7.css b/sources/skins/moono/dialog_ie7.css
new file mode 100644 (file)
index 0000000..148645d
--- /dev/null
@@ -0,0 +1,68 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+dialog_ie7.css\r
+===============\r
+\r
+This file contains styles to used by Internet Explorer 7 only.\r
+*/\r
+\r
+/* Base it on dialog_ie.css, overriding it with styles defined in this file. */\r
+@import url("dialog_ie.css");\r
+\r
+.cke_dialog_title\r
+{\r
+       /* gradient fix */\r
+       zoom: 1;\r
+}\r
+\r
+.cke_dialog_footer\r
+{\r
+       /* IE7 ignores footer's outline. Use border instead. */\r
+       border-top: 1px solid #bfbfbf;\r
+}\r
+\r
+/* IE7 needs position static #6806 */\r
+.cke_dialog_footer_buttons\r
+{\r
+       position: static;\r
+}\r
+\r
+/* IE7 crops the bottom pixels of footer buttons (#9491) */\r
+.cke_dialog_footer_buttons a.cke_dialog_ui_button\r
+{\r
+       vertical-align: top;\r
+}\r
+\r
+/* IE7 margin loose on float. */\r
+.cke_dialog .cke_resizer_ltr\r
+{\r
+       padding-left: 4px;\r
+}\r
+.cke_dialog .cke_resizer_rtl\r
+{\r
+       padding-right: 4px;\r
+}\r
+\r
+/*     IE7 doesn't support box-sizing and therefore we cannot\r
+       have sexy inputs which go well with the layout. */\r
+.cke_dialog_ui_input_text,\r
+.cke_dialog_ui_input_password,\r
+.cke_dialog_ui_input_textarea,\r
+.cke_dialog_ui_input_select\r
+{\r
+       padding: 0 !important;\r
+}\r
+\r
+/* Predefined border to avoid visual size change impact. */\r
+.cke_dialog_ui_checkbox_input,\r
+.cke_dialog_ui_ratio_input,\r
+.cke_btn_reset,\r
+.cke_btn_locked,\r
+.cke_btn_unlocked\r
+{\r
+       border: 1px solid transparent !important;\r
+}\r
diff --git a/sources/skins/moono/dialog_ie8.css b/sources/skins/moono/dialog_ie8.css
new file mode 100644 (file)
index 0000000..1926e50
--- /dev/null
@@ -0,0 +1,24 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+dialog_ie8.css\r
+===============\r
+\r
+This file contains styles to used by Internet Explorer 8 only.\r
+*/\r
+\r
+/* Base it on dialog_ie.css, overriding it with styles defined in this file. */\r
+@import url("dialog_ie.css");\r
+\r
+/*     Without the following, IE8 cannot compensate footer button thick borders\r
+       on :focus/:active. */\r
+a.cke_dialog_ui_button_ok:focus span,\r
+a.cke_dialog_ui_button_ok:active span,\r
+a.cke_dialog_ui_button_cancel:focus span,\r
+a.cke_dialog_ui_button_cancel:active span\r
+{\r
+       display: block;\r
+}\r
diff --git a/sources/skins/moono/dialog_iequirks.css b/sources/skins/moono/dialog_iequirks.css
new file mode 100644 (file)
index 0000000..2f89fdf
--- /dev/null
@@ -0,0 +1,21 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+dialog_ie7.css\r
+===============\r
+\r
+This file contains styles to used by Internet Explorer in\r
+Quirks mode only.\r
+*/\r
+\r
+/* Base it on dialog_ie.css, overriding it with styles defined in this file. */\r
+@import url("dialog_ie.css");\r
+\r
+/* [IE7-8] Filter on footer causes background artifacts when opening dialog. */\r
+.cke_dialog_footer\r
+{\r
+       filter: "";\r
+}\r
diff --git a/sources/skins/moono/editor.css b/sources/skins/moono/editor.css
new file mode 100644 (file)
index 0000000..f3f65df
--- /dev/null
@@ -0,0 +1,69 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor.css\r
+============\r
+\r
+This is he heart of the skin system. This is the file loaded by the editor to\r
+style all elements inside its main interface.\r
+\r
+To make it easier to maintain, instead of including all styles here, we import\r
+other files.\r
+*/\r
+\r
+/* "Reset" styles, necessary to avoid the editor UI being broken by external CSS. */\r
+@import url("reset.css");\r
+\r
+/* Styles the main interface structure (holding box). */\r
+@import url("mainui.css");\r
+\r
+/* Styles all "panels", which are the floating elements that appear when\r
+   opening toolbar combos, menu buttons, context menus, etc. */\r
+@import url("panel.css");\r
+\r
+/* Styles the color panel displayed by the color buttons. */\r
+@import url("colorpanel.css");\r
+\r
+/* Styles to toolbar. */\r
+@import url("toolbar.css");\r
+\r
+/* Styles menus, which are lists of selectable items (context menu, menu button). */\r
+@import url("menu.css");\r
+\r
+/* Styles toolbar combos. */\r
+@import url("richcombo.css");\r
+\r
+/* Styles the elements path bar, available at the bottom of the editor UI.*/\r
+@import url("elementspath.css");\r
+\r
+/* Contains hard-coded presets for "configurable-like" options of the UI\r
+   (e.g. display labels on specific buttons) */\r
+@import url("presets.css");\r
+\r
+/* Styles for notifications. */\r
+@import url("notification.css");\r
+\r
+/* Important!\r
+   To avoid showing the editor UI while its styles are still not available, the\r
+   editor creates it with visibility:hidden. Here, we restore the UI visibility. */\r
+.cke_chrome\r
+{\r
+       visibility: inherit;\r
+}\r
+\r
+/* For accessibility purposes, several "voice labels" are present in the UI.\r
+   These are usually <span> elements that show not be visible, but that are\r
+   used by screen-readers to announce other elements. Here, we hide these\r
+   <spans>, in fact. */\r
+.cke_voice_label\r
+{\r
+       display: none;\r
+}\r
+\r
+legend.cke_voice_label\r
+{\r
+       display: none;\r
+}\r
diff --git a/sources/skins/moono/editor_gecko.css b/sources/skins/moono/editor_gecko.css
new file mode 100644 (file)
index 0000000..370ffff
--- /dev/null
@@ -0,0 +1,25 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor_gecko.css\r
+==================\r
+\r
+This file contains styles to used by all Gecko based browsers (Firefox) only.\r
+*/\r
+\r
+/* Base it on editor.css, overriding it with styles defined in this file. */\r
+@import url("editor.css");\r
+\r
+.cke_bottom\r
+{\r
+       padding-bottom: 3px;\r
+}\r
+\r
+.cke_combo_text\r
+{\r
+       margin-bottom: -1px;\r
+       margin-top: 1px;\r
+}\r
diff --git a/sources/skins/moono/editor_ie.css b/sources/skins/moono/editor_ie.css
new file mode 100644 (file)
index 0000000..504789f
--- /dev/null
@@ -0,0 +1,71 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor_ie.css\r
+===============\r
+\r
+This file contains styles to used by all versions of Internet Explorer only.\r
+*/\r
+\r
+/* Base it on editor.css, overriding it with styles defined in this file. */\r
+@import url("editor.css");\r
+\r
+a.cke_button_disabled,\r
+\r
+/* Those two are to overwrite the gradient filter since we cannot have both of them. */\r
+a.cke_button_disabled:hover,\r
+a.cke_button_disabled:focus,\r
+a.cke_button_disabled:active\r
+{\r
+       filter: alpha(opacity = 30);\r
+}\r
+\r
+/* PNG Alpha Transparency Fix For IE<9 */\r
+.cke_button_disabled .cke_button_icon\r
+{\r
+       filter: progid:DXImageTransform.Microsoft.gradient(startColorstr=#00ffffff, endColorstr=#00ffffff);\r
+}\r
+\r
+.cke_button_off:hover,\r
+.cke_button_off:focus,\r
+.cke_button_off:active\r
+{\r
+       filter: alpha(opacity = 100);\r
+}\r
+\r
+.cke_combo_disabled .cke_combo_inlinelabel,\r
+.cke_combo_disabled .cke_combo_open\r
+{\r
+       filter: alpha(opacity = 30);\r
+}\r
+\r
+.cke_toolbox_collapser\r
+{\r
+       border: 1px solid #a6a6a6;\r
+}\r
+\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       margin-top: 1px;\r
+}\r
+\r
+/* Gradient filters must be removed for HC mode to reveal the background. */\r
+.cke_hc .cke_top,\r
+.cke_hc .cke_bottom,\r
+.cke_hc .cke_combo_button,\r
+.cke_hc a.cke_combo_button:hover,\r
+.cke_hc a.cke_combo_button:focus,\r
+.cke_hc .cke_toolgroup,\r
+.cke_hc .cke_button_on,\r
+.cke_hc a.cke_button_off:hover,\r
+.cke_hc a.cke_button_off:focus,\r
+.cke_hc a.cke_button_off:active,\r
+.cke_hc .cke_toolbox_collapser,\r
+.cke_hc .cke_toolbox_collapser:hover,\r
+.cke_hc .cke_panel_grouptitle\r
+{\r
+       filter: progid:DXImageTransform.Microsoft.gradient(enabled=false);\r
+}\r
diff --git a/sources/skins/moono/editor_ie7.css b/sources/skins/moono/editor_ie7.css
new file mode 100644 (file)
index 0000000..8079504
--- /dev/null
@@ -0,0 +1,213 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor_ie7.css\r
+===============\r
+\r
+This file contains styles to used by Internet Explorer 7 only.\r
+*/\r
+\r
+/* Base it on editor_ie.css, overriding it with styles defined in this file. */\r
+@import url("editor_ie.css");\r
+\r
+.cke_rtl .cke_toolgroup,\r
+.cke_rtl .cke_toolbar_separator,\r
+.cke_rtl .cke_button,\r
+.cke_rtl .cke_button *,\r
+.cke_rtl .cke_combo,\r
+.cke_rtl .cke_combo *,\r
+.cke_rtl .cke_path_item,\r
+.cke_rtl .cke_path_item *,\r
+.cke_rtl .cke_path_empty\r
+{\r
+       float: none;\r
+}\r
+\r
+.cke_rtl .cke_toolgroup,\r
+.cke_rtl .cke_toolbar_separator,\r
+.cke_rtl .cke_combo_button,\r
+.cke_rtl .cke_combo_button *,\r
+.cke_rtl .cke_button,\r
+.cke_rtl .cke_button_icon\r
+{\r
+       display: inline-block;\r
+       vertical-align: top;\r
+}\r
+\r
+.cke_toolbox\r
+{\r
+       display:inline-block;\r
+       padding-bottom: 5px;\r
+       height: 100%;\r
+}\r
+.cke_rtl .cke_toolbox\r
+{\r
+       padding-bottom: 0;\r
+}\r
+\r
+.cke_toolbar\r
+{\r
+       margin-bottom: 5px;\r
+}\r
+.cke_rtl .cke_toolbar\r
+{\r
+       margin-bottom: 0;\r
+}\r
+\r
+/* IE7: toolgroup must be adapted to toolbar items height. */\r
+.cke_toolgroup\r
+{\r
+       height: 26px;\r
+}\r
+\r
+/* Avoid breaking elements that use background gradient when page zoom > 1 (#9548) */\r
+.cke_toolgroup,\r
+.cke_combo\r
+{\r
+       position: relative;\r
+}\r
+\r
+a.cke_button\r
+{\r
+       /* IE7: buttons must not float to wrap the toolbar in a whole. */\r
+       float:none;\r
+\r
+       /* IE7: buttons have to be aligned to top. Otherwise, some buttons like\r
+        * source and scayt are displayed a few pixels below the base line.\r
+        */\r
+       vertical-align:top;\r
+}\r
+\r
+.cke_toolbar_separator\r
+{\r
+       display: inline-block;\r
+       float: none;\r
+       vertical-align: top;\r
+       background-color: #c0c0c0;\r
+}\r
+\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       margin-top: 0;\r
+}\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       border-width:4px;\r
+}\r
+.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow\r
+{\r
+       border-width:3px;\r
+}\r
+\r
+.cke_rtl .cke_button_arrow\r
+{\r
+       padding-top: 8px;\r
+       margin-right: 2px;\r
+}\r
+\r
+.cke_rtl .cke_combo_inlinelabel\r
+{\r
+       display: table-cell;\r
+       vertical-align: middle;\r
+}\r
+\r
+/*\r
+ * Editor menus are display:table-driven. IE7 doesn't support this approach,\r
+ * hence this position&float hybrid fall-back.\r
+ */\r
+.cke_menubutton\r
+{\r
+       display: block;\r
+       height: 24px;\r
+}\r
+\r
+.cke_menubutton_inner\r
+{\r
+       display: block;\r
+       position: relative;\r
+}\r
+\r
+.cke_menubutton_icon\r
+{\r
+       height: 16px;\r
+       width: 16px;\r
+}\r
+\r
+.cke_menubutton_icon,\r
+.cke_menubutton_label,\r
+.cke_menuarrow\r
+{\r
+       display: inline-block;\r
+}\r
+\r
+.cke_menubutton_label\r
+{\r
+       width: auto;\r
+       vertical-align: top;\r
+       line-height: 24px;\r
+       height: 24px;\r
+       margin: 0 10px 0 0;\r
+}\r
+\r
+.cke_menuarrow\r
+{\r
+       width: 5px;\r
+       height: 6px;\r
+       padding: 0;\r
+       position: absolute;\r
+       right: 8px;\r
+       top: 10px;\r
+\r
+       background-position: 0 0;\r
+}\r
+\r
+/* Menus in RTL mode. */\r
+.cke_rtl .cke_menubutton_icon\r
+{\r
+       position: absolute;\r
+       right: 0px;\r
+       top: 0px;\r
+}\r
+\r
+.cke_rtl .cke_menubutton_label\r
+{\r
+       float: right;\r
+       clear: both;\r
+       margin: 0 24px 0 10px;\r
+}\r
+\r
+.cke_hc .cke_rtl .cke_menubutton_label\r
+{\r
+       margin-right: 0;\r
+}\r
+\r
+\r
+.cke_rtl .cke_menuarrow\r
+{\r
+       left: 8px;\r
+       right: auto;\r
+       background-position: 0 -24px;\r
+}\r
+\r
+.cke_hc .cke_menuarrow\r
+{\r
+       top: 5px;\r
+       padding: 0 5px;\r
+}\r
+\r
+.cke_rtl input.cke_dialog_ui_input_text,\r
+.cke_rtl input.cke_dialog_ui_input_password\r
+{\r
+       /* Positioning is required for IE7 on text inputs not to stretch dialog horizontally. (#8971)*/\r
+       position: relative;\r
+}\r
+\r
+/* Reset vertical paddings which put editing area under bottom UI space. (#9721) */\r
+.cke_wysiwyg_div\r
+{\r
+       padding-top: 0 !important;\r
+       padding-bottom: 0 !important;\r
+}\r
diff --git a/sources/skins/moono/editor_ie8.css b/sources/skins/moono/editor_ie8.css
new file mode 100644 (file)
index 0000000..9862024
--- /dev/null
@@ -0,0 +1,27 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor_ie8.css\r
+===============\r
+\r
+This file contains styles to used by Internet Explorer 8 only.\r
+*/\r
+\r
+/* Base it on editor_ie.css, overriding it with styles defined in this file. */\r
+@import url("editor_ie.css");\r
+\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       border-width:4px;\r
+}\r
+.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow\r
+{\r
+       border-width:3px;\r
+}\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       margin-top: 0;\r
+}\r
diff --git a/sources/skins/moono/editor_iequirks.css b/sources/skins/moono/editor_iequirks.css
new file mode 100644 (file)
index 0000000..2376992
--- /dev/null
@@ -0,0 +1,79 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+editor_iequirks.css\r
+===============\r
+\r
+This file contains styles to used by all versions of Internet Explorer\r
+in Quirks mode only.\r
+*/\r
+\r
+/* Base it on editor_ie.css, overriding it with styles defined in this file. */\r
+@import url("editor_ie.css");\r
+\r
+.cke_top,\r
+.cke_contents,\r
+.cke_bottom\r
+{\r
+       width: 100%; /* hasLayout = true */\r
+}\r
+\r
+.cke_button_arrow\r
+{\r
+       font-size: 0; /* Set minimal font size, so arrow won't be streched by the text that doesn't exist. */\r
+}\r
+\r
+/* Bring back toolbar buttons in RTL. */\r
+\r
+.cke_rtl .cke_toolgroup,\r
+.cke_rtl .cke_toolbar_separator,\r
+.cke_rtl .cke_button,\r
+.cke_rtl .cke_button *,\r
+.cke_rtl .cke_combo,\r
+.cke_rtl .cke_combo *,\r
+.cke_rtl .cke_path_item,\r
+.cke_rtl .cke_path_item *,\r
+.cke_rtl .cke_path_empty\r
+{\r
+       float: none;\r
+}\r
+\r
+.cke_rtl .cke_toolgroup,\r
+.cke_rtl .cke_toolbar_separator,\r
+.cke_rtl .cke_combo_button,\r
+.cke_rtl .cke_combo_button *,\r
+.cke_rtl .cke_button,\r
+.cke_rtl .cke_button_icon\r
+{\r
+       display: inline-block;\r
+       vertical-align: top;\r
+}\r
+\r
+/* Otherwise formatting toolbar breaks when editing a mixed content (#9893). */\r
+.cke_rtl .cke_button_icon\r
+{\r
+       float: none;\r
+}\r
+\r
+.cke_resizer\r
+{\r
+       width: 10px;\r
+}\r
+\r
+.cke_source\r
+{\r
+       white-space: normal;\r
+}\r
+\r
+.cke_bottom\r
+{\r
+       position: static; /* Without this bottom space doesn't move when resizing editor. */\r
+}\r
+\r
+.cke_colorbox\r
+{\r
+       font-size: 0; /* Set minimal font size, so button won't be streched by the text that doesn't exist. */\r
+}\r
diff --git a/sources/skins/moono/elementspath.css b/sources/skins/moono/elementspath.css
new file mode 100644 (file)
index 0000000..3bf10d6
--- /dev/null
@@ -0,0 +1,76 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+elementspath.css (part of editor.css)\r
+=======================================\r
+\r
+This file styles the "Elements Path", whith is the list of element names\r
+present at the the bottom bar of the CKEditor interface.\r
+\r
+The following is a visual representation of its main elements:\r
+\r
++-- .cke_path ---------------------------------------------------------------+\r
+| +-- .cke_path_item ----+ +-- .cke_path_item ----+ +-- .cke_path_empty ---+ |\r
+| |                      | |                      | |                      | |\r
+| +----------------------+ +----------------------+ +----------------------+ |\r
++----------------------------------------------------------------------------+\r
+*/\r
+\r
+/* The box that holds the entire elements path. */\r
+.cke_path\r
+{\r
+       float: left;\r
+       margin: -2px 0 2px;\r
+}\r
+\r
+/* Each item of the elements path. */\r
+a.cke_path_item,\r
+/* Empty element available at the end of the elements path, to help us keeping\r
+   the proper box size when the elements path is empty. */\r
+span.cke_path_empty\r
+{\r
+       display: inline-block;\r
+       float: left;\r
+       padding: 3px 4px;\r
+       margin-right: 2px;\r
+       cursor: default;\r
+       text-decoration: none;\r
+       outline: 0;\r
+       border: 0;\r
+       color: #4c4c4c;\r
+       text-shadow: 0 1px 0 #fff;\r
+       font-weight: bold;\r
+       font-size: 11px;\r
+}\r
+\r
+.cke_rtl .cke_path,\r
+.cke_rtl .cke_path_item,\r
+.cke_rtl .cke_path_empty\r
+{\r
+       float: right;\r
+}\r
+\r
+/* The items are <a> elements, so we define its hover states here. */\r
+a.cke_path_item:hover,\r
+a.cke_path_item:focus,\r
+a.cke_path_item:active\r
+{\r
+       background-color: #bfbfbf;\r
+       color: #333;\r
+       text-shadow: 0 1px 0 rgba(255,255,255,.5);\r
+\r
+       border-radius: 2px;\r
+\r
+       box-shadow: 0 0 4px rgba(0,0,0,.5) inset, 0 1px 0 rgba(255,255,255,.5);\r
+}\r
+\r
+.cke_hc a.cke_path_item:hover,\r
+.cke_hc a.cke_path_item:focus,\r
+.cke_hc a.cke_path_item:active\r
+{\r
+       border: 2px solid;\r
+       padding: 1px 2px;\r
+}\r
diff --git a/sources/skins/moono/icons/about.png b/sources/skins/moono/icons/about.png
new file mode 100644 (file)
index 0000000..d36b8a1
Binary files /dev/null and b/sources/skins/moono/icons/about.png differ
diff --git a/sources/skins/moono/icons/anchor-rtl.png b/sources/skins/moono/icons/anchor-rtl.png
new file mode 100644 (file)
index 0000000..a07d34e
Binary files /dev/null and b/sources/skins/moono/icons/anchor-rtl.png differ
diff --git a/sources/skins/moono/icons/anchor.png b/sources/skins/moono/icons/anchor.png
new file mode 100644 (file)
index 0000000..2d2f91d
Binary files /dev/null and b/sources/skins/moono/icons/anchor.png differ
diff --git a/sources/skins/moono/icons/bgcolor.png b/sources/skins/moono/icons/bgcolor.png
new file mode 100644 (file)
index 0000000..549f0fa
Binary files /dev/null and b/sources/skins/moono/icons/bgcolor.png differ
diff --git a/sources/skins/moono/icons/bidiltr.png b/sources/skins/moono/icons/bidiltr.png
new file mode 100644 (file)
index 0000000..8a11ec5
Binary files /dev/null and b/sources/skins/moono/icons/bidiltr.png differ
diff --git a/sources/skins/moono/icons/bidirtl.png b/sources/skins/moono/icons/bidirtl.png
new file mode 100644 (file)
index 0000000..318e245
Binary files /dev/null and b/sources/skins/moono/icons/bidirtl.png differ
diff --git a/sources/skins/moono/icons/blockquote.png b/sources/skins/moono/icons/blockquote.png
new file mode 100644 (file)
index 0000000..61d8fd3
Binary files /dev/null and b/sources/skins/moono/icons/blockquote.png differ
diff --git a/sources/skins/moono/icons/bold.png b/sources/skins/moono/icons/bold.png
new file mode 100644 (file)
index 0000000..885e916
Binary files /dev/null and b/sources/skins/moono/icons/bold.png differ
diff --git a/sources/skins/moono/icons/bulletedlist-rtl.png b/sources/skins/moono/icons/bulletedlist-rtl.png
new file mode 100644 (file)
index 0000000..617096f
Binary files /dev/null and b/sources/skins/moono/icons/bulletedlist-rtl.png differ
diff --git a/sources/skins/moono/icons/bulletedlist.png b/sources/skins/moono/icons/bulletedlist.png
new file mode 100644 (file)
index 0000000..6bef9a5
Binary files /dev/null and b/sources/skins/moono/icons/bulletedlist.png differ
diff --git a/sources/skins/moono/icons/button.png b/sources/skins/moono/icons/button.png
new file mode 100644 (file)
index 0000000..c0f2fcc
Binary files /dev/null and b/sources/skins/moono/icons/button.png differ
diff --git a/sources/skins/moono/icons/checkbox.png b/sources/skins/moono/icons/checkbox.png
new file mode 100644 (file)
index 0000000..45397d4
Binary files /dev/null and b/sources/skins/moono/icons/checkbox.png differ
diff --git a/sources/skins/moono/icons/codesnippet.png b/sources/skins/moono/icons/codesnippet.png
new file mode 100644 (file)
index 0000000..6493f6f
Binary files /dev/null and b/sources/skins/moono/icons/codesnippet.png differ
diff --git a/sources/skins/moono/icons/copy-rtl.png b/sources/skins/moono/icons/copy-rtl.png
new file mode 100644 (file)
index 0000000..1d65071
Binary files /dev/null and b/sources/skins/moono/icons/copy-rtl.png differ
diff --git a/sources/skins/moono/icons/copy.png b/sources/skins/moono/icons/copy.png
new file mode 100644 (file)
index 0000000..1d65071
Binary files /dev/null and b/sources/skins/moono/icons/copy.png differ
diff --git a/sources/skins/moono/icons/copyformatting.png b/sources/skins/moono/icons/copyformatting.png
new file mode 100644 (file)
index 0000000..0eb02ee
Binary files /dev/null and b/sources/skins/moono/icons/copyformatting.png differ
diff --git a/sources/skins/moono/icons/creatediv.png b/sources/skins/moono/icons/creatediv.png
new file mode 100644 (file)
index 0000000..79d5bb5
Binary files /dev/null and b/sources/skins/moono/icons/creatediv.png differ
diff --git a/sources/skins/moono/icons/cut-rtl.png b/sources/skins/moono/icons/cut-rtl.png
new file mode 100644 (file)
index 0000000..97f826e
Binary files /dev/null and b/sources/skins/moono/icons/cut-rtl.png differ
diff --git a/sources/skins/moono/icons/cut.png b/sources/skins/moono/icons/cut.png
new file mode 100644 (file)
index 0000000..97f826e
Binary files /dev/null and b/sources/skins/moono/icons/cut.png differ
diff --git a/sources/skins/moono/icons/docprops-rtl.png b/sources/skins/moono/icons/docprops-rtl.png
new file mode 100644 (file)
index 0000000..1e6d212
Binary files /dev/null and b/sources/skins/moono/icons/docprops-rtl.png differ
diff --git a/sources/skins/moono/icons/docprops.png b/sources/skins/moono/icons/docprops.png
new file mode 100644 (file)
index 0000000..dd7e1e8
Binary files /dev/null and b/sources/skins/moono/icons/docprops.png differ
diff --git a/sources/skins/moono/icons/find-rtl.png b/sources/skins/moono/icons/find-rtl.png
new file mode 100644 (file)
index 0000000..8d94455
Binary files /dev/null and b/sources/skins/moono/icons/find-rtl.png differ
diff --git a/sources/skins/moono/icons/find.png b/sources/skins/moono/icons/find.png
new file mode 100644 (file)
index 0000000..8d94455
Binary files /dev/null and b/sources/skins/moono/icons/find.png differ
diff --git a/sources/skins/moono/icons/flash.png b/sources/skins/moono/icons/flash.png
new file mode 100644 (file)
index 0000000..6b7c843
Binary files /dev/null and b/sources/skins/moono/icons/flash.png differ
diff --git a/sources/skins/moono/icons/form.png b/sources/skins/moono/icons/form.png
new file mode 100644 (file)
index 0000000..68c5b6b
Binary files /dev/null and b/sources/skins/moono/icons/form.png differ
diff --git a/sources/skins/moono/icons/hiddenfield.png b/sources/skins/moono/icons/hiddenfield.png
new file mode 100644 (file)
index 0000000..ddc547f
Binary files /dev/null and b/sources/skins/moono/icons/hiddenfield.png differ
diff --git a/sources/skins/moono/icons/hidpi/.DS_Store b/sources/skins/moono/icons/hidpi/.DS_Store
new file mode 100644 (file)
index 0000000..9d2abe5
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/.DS_Store differ
diff --git a/sources/skins/moono/icons/hidpi/about.png b/sources/skins/moono/icons/hidpi/about.png
new file mode 100644 (file)
index 0000000..8ecc4a6
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/about.png differ
diff --git a/sources/skins/moono/icons/hidpi/anchor-rtl.png b/sources/skins/moono/icons/hidpi/anchor-rtl.png
new file mode 100644 (file)
index 0000000..318a138
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/anchor-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/anchor.png b/sources/skins/moono/icons/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..53486a8
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/anchor.png differ
diff --git a/sources/skins/moono/icons/hidpi/bgcolor.png b/sources/skins/moono/icons/hidpi/bgcolor.png
new file mode 100644 (file)
index 0000000..20fcf37
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bgcolor.png differ
diff --git a/sources/skins/moono/icons/hidpi/bidiltr.png b/sources/skins/moono/icons/hidpi/bidiltr.png
new file mode 100644 (file)
index 0000000..6fb7456
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bidiltr.png differ
diff --git a/sources/skins/moono/icons/hidpi/bidirtl.png b/sources/skins/moono/icons/hidpi/bidirtl.png
new file mode 100644 (file)
index 0000000..80f063d
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bidirtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/blockquote.png b/sources/skins/moono/icons/hidpi/blockquote.png
new file mode 100644 (file)
index 0000000..965f910
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/blockquote.png differ
diff --git a/sources/skins/moono/icons/hidpi/bold.png b/sources/skins/moono/icons/hidpi/bold.png
new file mode 100644 (file)
index 0000000..613319b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bold.png differ
diff --git a/sources/skins/moono/icons/hidpi/bulletedlist-rtl.png b/sources/skins/moono/icons/hidpi/bulletedlist-rtl.png
new file mode 100644 (file)
index 0000000..34da46b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bulletedlist-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/bulletedlist.png b/sources/skins/moono/icons/hidpi/bulletedlist.png
new file mode 100644 (file)
index 0000000..f322ed9
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/bulletedlist.png differ
diff --git a/sources/skins/moono/icons/hidpi/button.png b/sources/skins/moono/icons/hidpi/button.png
new file mode 100644 (file)
index 0000000..a7b2b42
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/button.png differ
diff --git a/sources/skins/moono/icons/hidpi/checkbox.png b/sources/skins/moono/icons/hidpi/checkbox.png
new file mode 100644 (file)
index 0000000..53ac357
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/checkbox.png differ
diff --git a/sources/skins/moono/icons/hidpi/codesnippet.png b/sources/skins/moono/icons/hidpi/codesnippet.png
new file mode 100644 (file)
index 0000000..a9b3a98
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/codesnippet.png differ
diff --git a/sources/skins/moono/icons/hidpi/copy-rtl.png b/sources/skins/moono/icons/hidpi/copy-rtl.png
new file mode 100644 (file)
index 0000000..6c9a0fe
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/copy-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/copy.png b/sources/skins/moono/icons/hidpi/copy.png
new file mode 100644 (file)
index 0000000..6c9a0fe
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/copy.png differ
diff --git a/sources/skins/moono/icons/hidpi/copyformatting.png b/sources/skins/moono/icons/hidpi/copyformatting.png
new file mode 100644 (file)
index 0000000..4f95e7a
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/copyformatting.png differ
diff --git a/sources/skins/moono/icons/hidpi/creatediv.png b/sources/skins/moono/icons/hidpi/creatediv.png
new file mode 100644 (file)
index 0000000..808e466
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/creatediv.png differ
diff --git a/sources/skins/moono/icons/hidpi/cut-rtl.png b/sources/skins/moono/icons/hidpi/cut-rtl.png
new file mode 100644 (file)
index 0000000..39c4af0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/cut-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/cut.png b/sources/skins/moono/icons/hidpi/cut.png
new file mode 100644 (file)
index 0000000..39c4af0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/cut.png differ
diff --git a/sources/skins/moono/icons/hidpi/docprops-rtl.png b/sources/skins/moono/icons/hidpi/docprops-rtl.png
new file mode 100644 (file)
index 0000000..de8722f
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/docprops-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/docprops.png b/sources/skins/moono/icons/hidpi/docprops.png
new file mode 100644 (file)
index 0000000..74af812
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/docprops.png differ
diff --git a/sources/skins/moono/icons/hidpi/find-rtl.png b/sources/skins/moono/icons/hidpi/find-rtl.png
new file mode 100644 (file)
index 0000000..ff0e0c6
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/find-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/find.png b/sources/skins/moono/icons/hidpi/find.png
new file mode 100644 (file)
index 0000000..ff0e0c6
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/find.png differ
diff --git a/sources/skins/moono/icons/hidpi/flash.png b/sources/skins/moono/icons/hidpi/flash.png
new file mode 100644 (file)
index 0000000..7323b19
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/flash.png differ
diff --git a/sources/skins/moono/icons/hidpi/form.png b/sources/skins/moono/icons/hidpi/form.png
new file mode 100644 (file)
index 0000000..90f4813
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/form.png differ
diff --git a/sources/skins/moono/icons/hidpi/hiddenfield.png b/sources/skins/moono/icons/hidpi/hiddenfield.png
new file mode 100644 (file)
index 0000000..fd10781
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/hiddenfield.png differ
diff --git a/sources/skins/moono/icons/hidpi/horizontalrule.png b/sources/skins/moono/icons/hidpi/horizontalrule.png
new file mode 100644 (file)
index 0000000..0ae87fb
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/horizontalrule.png differ
diff --git a/sources/skins/moono/icons/hidpi/iframe.png b/sources/skins/moono/icons/hidpi/iframe.png
new file mode 100644 (file)
index 0000000..a56ecb0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/iframe.png differ
diff --git a/sources/skins/moono/icons/hidpi/image.png b/sources/skins/moono/icons/hidpi/image.png
new file mode 100644 (file)
index 0000000..e9579fb
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/image.png differ
diff --git a/sources/skins/moono/icons/hidpi/imagebutton.png b/sources/skins/moono/icons/hidpi/imagebutton.png
new file mode 100644 (file)
index 0000000..f38b758
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/imagebutton.png differ
diff --git a/sources/skins/moono/icons/hidpi/indent-rtl.png b/sources/skins/moono/icons/hidpi/indent-rtl.png
new file mode 100644 (file)
index 0000000..44eea22
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/indent-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/indent.png b/sources/skins/moono/icons/hidpi/indent.png
new file mode 100644 (file)
index 0000000..417f092
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/indent.png differ
diff --git a/sources/skins/moono/icons/hidpi/italic.png b/sources/skins/moono/icons/hidpi/italic.png
new file mode 100644 (file)
index 0000000..07b1d1d
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/italic.png differ
diff --git a/sources/skins/moono/icons/hidpi/justifyblock.png b/sources/skins/moono/icons/hidpi/justifyblock.png
new file mode 100644 (file)
index 0000000..4535a39
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/justifyblock.png differ
diff --git a/sources/skins/moono/icons/hidpi/justifycenter.png b/sources/skins/moono/icons/hidpi/justifycenter.png
new file mode 100644 (file)
index 0000000..8749f69
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/justifycenter.png differ
diff --git a/sources/skins/moono/icons/hidpi/justifyleft.png b/sources/skins/moono/icons/hidpi/justifyleft.png
new file mode 100644 (file)
index 0000000..50a4307
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/justifyleft.png differ
diff --git a/sources/skins/moono/icons/hidpi/justifyright.png b/sources/skins/moono/icons/hidpi/justifyright.png
new file mode 100644 (file)
index 0000000..6d127e7
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/justifyright.png differ
diff --git a/sources/skins/moono/icons/hidpi/language.png b/sources/skins/moono/icons/hidpi/language.png
new file mode 100644 (file)
index 0000000..d778031
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/language.png differ
diff --git a/sources/skins/moono/icons/hidpi/link.png b/sources/skins/moono/icons/hidpi/link.png
new file mode 100644 (file)
index 0000000..fed6b91
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/link.png differ
diff --git a/sources/skins/moono/icons/hidpi/maximize.png b/sources/skins/moono/icons/hidpi/maximize.png
new file mode 100644 (file)
index 0000000..eeaa700
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/maximize.png differ
diff --git a/sources/skins/moono/icons/hidpi/newpage-rtl.png b/sources/skins/moono/icons/hidpi/newpage-rtl.png
new file mode 100644 (file)
index 0000000..c5e1d3b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/newpage-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/newpage.png b/sources/skins/moono/icons/hidpi/newpage.png
new file mode 100644 (file)
index 0000000..139279b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/newpage.png differ
diff --git a/sources/skins/moono/icons/hidpi/numberedlist-rtl.png b/sources/skins/moono/icons/hidpi/numberedlist-rtl.png
new file mode 100644 (file)
index 0000000..b449c2b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/numberedlist-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/numberedlist.png b/sources/skins/moono/icons/hidpi/numberedlist.png
new file mode 100644 (file)
index 0000000..b7442ef
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/numberedlist.png differ
diff --git a/sources/skins/moono/icons/hidpi/outdent-rtl.png b/sources/skins/moono/icons/hidpi/outdent-rtl.png
new file mode 100644 (file)
index 0000000..a642bca
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/outdent-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/outdent.png b/sources/skins/moono/icons/hidpi/outdent.png
new file mode 100644 (file)
index 0000000..6d715a5
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/outdent.png differ
diff --git a/sources/skins/moono/icons/hidpi/pagebreak-rtl.png b/sources/skins/moono/icons/hidpi/pagebreak-rtl.png
new file mode 100644 (file)
index 0000000..6fc486b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pagebreak-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/pagebreak.png b/sources/skins/moono/icons/hidpi/pagebreak.png
new file mode 100644 (file)
index 0000000..a19ecc0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pagebreak.png differ
diff --git a/sources/skins/moono/icons/hidpi/paste-rtl.png b/sources/skins/moono/icons/hidpi/paste-rtl.png
new file mode 100644 (file)
index 0000000..14f9eff
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/paste-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/paste.png b/sources/skins/moono/icons/hidpi/paste.png
new file mode 100644 (file)
index 0000000..14f9eff
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/paste.png differ
diff --git a/sources/skins/moono/icons/hidpi/pastefromword-rtl.png b/sources/skins/moono/icons/hidpi/pastefromword-rtl.png
new file mode 100644 (file)
index 0000000..fb9ef9e
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pastefromword-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/pastefromword.png b/sources/skins/moono/icons/hidpi/pastefromword.png
new file mode 100644 (file)
index 0000000..7666b0f
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pastefromword.png differ
diff --git a/sources/skins/moono/icons/hidpi/pastetext-rtl.png b/sources/skins/moono/icons/hidpi/pastetext-rtl.png
new file mode 100644 (file)
index 0000000..b30fc9b
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pastetext-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/pastetext.png b/sources/skins/moono/icons/hidpi/pastetext.png
new file mode 100644 (file)
index 0000000..e811afc
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/pastetext.png differ
diff --git a/sources/skins/moono/icons/hidpi/placeholder.png b/sources/skins/moono/icons/hidpi/placeholder.png
new file mode 100644 (file)
index 0000000..0874f14
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/placeholder.png differ
diff --git a/sources/skins/moono/icons/hidpi/preview-rtl.png b/sources/skins/moono/icons/hidpi/preview-rtl.png
new file mode 100644 (file)
index 0000000..06d06c0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/preview-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/preview.png b/sources/skins/moono/icons/hidpi/preview.png
new file mode 100644 (file)
index 0000000..993e79e
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/preview.png differ
diff --git a/sources/skins/moono/icons/hidpi/print.png b/sources/skins/moono/icons/hidpi/print.png
new file mode 100644 (file)
index 0000000..42064c2
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/print.png differ
diff --git a/sources/skins/moono/icons/hidpi/radio.png b/sources/skins/moono/icons/hidpi/radio.png
new file mode 100644 (file)
index 0000000..c84bc00
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/radio.png differ
diff --git a/sources/skins/moono/icons/hidpi/redo-rtl.png b/sources/skins/moono/icons/hidpi/redo-rtl.png
new file mode 100644 (file)
index 0000000..c8583ea
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/redo-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/redo.png b/sources/skins/moono/icons/hidpi/redo.png
new file mode 100644 (file)
index 0000000..fb25750
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/redo.png differ
diff --git a/sources/skins/moono/icons/hidpi/removeformat.png b/sources/skins/moono/icons/hidpi/removeformat.png
new file mode 100644 (file)
index 0000000..738ebcd
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/removeformat.png differ
diff --git a/sources/skins/moono/icons/hidpi/replace.png b/sources/skins/moono/icons/hidpi/replace.png
new file mode 100644 (file)
index 0000000..3944ec3
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/replace.png differ
diff --git a/sources/skins/moono/icons/hidpi/save.png b/sources/skins/moono/icons/hidpi/save.png
new file mode 100644 (file)
index 0000000..21f92bf
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/save.png differ
diff --git a/sources/skins/moono/icons/hidpi/scayt.png b/sources/skins/moono/icons/hidpi/scayt.png
new file mode 100644 (file)
index 0000000..5f0b6d9
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/scayt.png differ
diff --git a/sources/skins/moono/icons/hidpi/select-rtl.png b/sources/skins/moono/icons/hidpi/select-rtl.png
new file mode 100644 (file)
index 0000000..925c06d
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/select-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/select.png b/sources/skins/moono/icons/hidpi/select.png
new file mode 100644 (file)
index 0000000..0e995f9
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/select.png differ
diff --git a/sources/skins/moono/icons/hidpi/selectall.png b/sources/skins/moono/icons/hidpi/selectall.png
new file mode 100644 (file)
index 0000000..68f3239
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/selectall.png differ
diff --git a/sources/skins/moono/icons/hidpi/showblocks-rtl.png b/sources/skins/moono/icons/hidpi/showblocks-rtl.png
new file mode 100644 (file)
index 0000000..d210fad
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/showblocks-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/showblocks.png b/sources/skins/moono/icons/hidpi/showblocks.png
new file mode 100644 (file)
index 0000000..d6d51d1
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/showblocks.png differ
diff --git a/sources/skins/moono/icons/hidpi/smiley.png b/sources/skins/moono/icons/hidpi/smiley.png
new file mode 100644 (file)
index 0000000..5a70b89
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/smiley.png differ
diff --git a/sources/skins/moono/icons/hidpi/source-rtl.png b/sources/skins/moono/icons/hidpi/source-rtl.png
new file mode 100644 (file)
index 0000000..64b2266
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/source-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/source.png b/sources/skins/moono/icons/hidpi/source.png
new file mode 100644 (file)
index 0000000..4e732c0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/source.png differ
diff --git a/sources/skins/moono/icons/hidpi/sourcedialog-rtl.png b/sources/skins/moono/icons/hidpi/sourcedialog-rtl.png
new file mode 100644 (file)
index 0000000..64b2266
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/sourcedialog-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/sourcedialog.png b/sources/skins/moono/icons/hidpi/sourcedialog.png
new file mode 100644 (file)
index 0000000..4e732c0
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/sourcedialog.png differ
diff --git a/sources/skins/moono/icons/hidpi/specialchar.png b/sources/skins/moono/icons/hidpi/specialchar.png
new file mode 100644 (file)
index 0000000..5874ea3
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/specialchar.png differ
diff --git a/sources/skins/moono/icons/hidpi/spellchecker.png b/sources/skins/moono/icons/hidpi/spellchecker.png
new file mode 100644 (file)
index 0000000..5f0b6d9
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/spellchecker.png differ
diff --git a/sources/skins/moono/icons/hidpi/strike.png b/sources/skins/moono/icons/hidpi/strike.png
new file mode 100644 (file)
index 0000000..45c3269
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/strike.png differ
diff --git a/sources/skins/moono/icons/hidpi/subscript.png b/sources/skins/moono/icons/hidpi/subscript.png
new file mode 100644 (file)
index 0000000..d59e216
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/subscript.png differ
diff --git a/sources/skins/moono/icons/hidpi/superscript.png b/sources/skins/moono/icons/hidpi/superscript.png
new file mode 100644 (file)
index 0000000..2951416
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/superscript.png differ
diff --git a/sources/skins/moono/icons/hidpi/table.png b/sources/skins/moono/icons/hidpi/table.png
new file mode 100644 (file)
index 0000000..795e8c8
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/table.png differ
diff --git a/sources/skins/moono/icons/hidpi/templates-rtl.png b/sources/skins/moono/icons/hidpi/templates-rtl.png
new file mode 100644 (file)
index 0000000..0784b00
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/templates-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/templates.png b/sources/skins/moono/icons/hidpi/templates.png
new file mode 100644 (file)
index 0000000..0784b00
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/templates.png differ
diff --git a/sources/skins/moono/icons/hidpi/textarea-rtl.png b/sources/skins/moono/icons/hidpi/textarea-rtl.png
new file mode 100644 (file)
index 0000000..4bc1c06
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/textarea-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/textarea.png b/sources/skins/moono/icons/hidpi/textarea.png
new file mode 100644 (file)
index 0000000..8156e51
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/textarea.png differ
diff --git a/sources/skins/moono/icons/hidpi/textcolor.png b/sources/skins/moono/icons/hidpi/textcolor.png
new file mode 100644 (file)
index 0000000..42c5e4f
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/textcolor.png differ
diff --git a/sources/skins/moono/icons/hidpi/textfield-rtl.png b/sources/skins/moono/icons/hidpi/textfield-rtl.png
new file mode 100644 (file)
index 0000000..1d5970a
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/textfield-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/textfield.png b/sources/skins/moono/icons/hidpi/textfield.png
new file mode 100644 (file)
index 0000000..1d5970a
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/textfield.png differ
diff --git a/sources/skins/moono/icons/hidpi/uicolor.png b/sources/skins/moono/icons/hidpi/uicolor.png
new file mode 100644 (file)
index 0000000..dbd21ff
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/uicolor.png differ
diff --git a/sources/skins/moono/icons/hidpi/underline.png b/sources/skins/moono/icons/hidpi/underline.png
new file mode 100644 (file)
index 0000000..53302c6
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/underline.png differ
diff --git a/sources/skins/moono/icons/hidpi/undo-rtl.png b/sources/skins/moono/icons/hidpi/undo-rtl.png
new file mode 100644 (file)
index 0000000..fb25750
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/undo-rtl.png differ
diff --git a/sources/skins/moono/icons/hidpi/undo.png b/sources/skins/moono/icons/hidpi/undo.png
new file mode 100644 (file)
index 0000000..c8583ea
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/undo.png differ
diff --git a/sources/skins/moono/icons/hidpi/unlink.png b/sources/skins/moono/icons/hidpi/unlink.png
new file mode 100644 (file)
index 0000000..dc7fc78
Binary files /dev/null and b/sources/skins/moono/icons/hidpi/unlink.png differ
diff --git a/sources/skins/moono/icons/horizontalrule.png b/sources/skins/moono/icons/horizontalrule.png
new file mode 100644 (file)
index 0000000..513d193
Binary files /dev/null and b/sources/skins/moono/icons/horizontalrule.png differ
diff --git a/sources/skins/moono/icons/iframe.png b/sources/skins/moono/icons/iframe.png
new file mode 100644 (file)
index 0000000..2393ca5
Binary files /dev/null and b/sources/skins/moono/icons/iframe.png differ
diff --git a/sources/skins/moono/icons/image.png b/sources/skins/moono/icons/image.png
new file mode 100644 (file)
index 0000000..281dbc7
Binary files /dev/null and b/sources/skins/moono/icons/image.png differ
diff --git a/sources/skins/moono/icons/imagebutton.png b/sources/skins/moono/icons/imagebutton.png
new file mode 100644 (file)
index 0000000..e26854b
Binary files /dev/null and b/sources/skins/moono/icons/imagebutton.png differ
diff --git a/sources/skins/moono/icons/indent-rtl.png b/sources/skins/moono/icons/indent-rtl.png
new file mode 100644 (file)
index 0000000..23ab113
Binary files /dev/null and b/sources/skins/moono/icons/indent-rtl.png differ
diff --git a/sources/skins/moono/icons/indent.png b/sources/skins/moono/icons/indent.png
new file mode 100644 (file)
index 0000000..8c2ee08
Binary files /dev/null and b/sources/skins/moono/icons/indent.png differ
diff --git a/sources/skins/moono/icons/italic.png b/sources/skins/moono/icons/italic.png
new file mode 100644 (file)
index 0000000..0983afe
Binary files /dev/null and b/sources/skins/moono/icons/italic.png differ
diff --git a/sources/skins/moono/icons/justifyblock.png b/sources/skins/moono/icons/justifyblock.png
new file mode 100644 (file)
index 0000000..72164e7
Binary files /dev/null and b/sources/skins/moono/icons/justifyblock.png differ
diff --git a/sources/skins/moono/icons/justifycenter.png b/sources/skins/moono/icons/justifycenter.png
new file mode 100644 (file)
index 0000000..5721c9e
Binary files /dev/null and b/sources/skins/moono/icons/justifycenter.png differ
diff --git a/sources/skins/moono/icons/justifyleft.png b/sources/skins/moono/icons/justifyleft.png
new file mode 100644 (file)
index 0000000..0b1fa97
Binary files /dev/null and b/sources/skins/moono/icons/justifyleft.png differ
diff --git a/sources/skins/moono/icons/justifyright.png b/sources/skins/moono/icons/justifyright.png
new file mode 100644 (file)
index 0000000..f039348
Binary files /dev/null and b/sources/skins/moono/icons/justifyright.png differ
diff --git a/sources/skins/moono/icons/language.png b/sources/skins/moono/icons/language.png
new file mode 100644 (file)
index 0000000..dfa11fa
Binary files /dev/null and b/sources/skins/moono/icons/language.png differ
diff --git a/sources/skins/moono/icons/link.png b/sources/skins/moono/icons/link.png
new file mode 100644 (file)
index 0000000..2bf8900
Binary files /dev/null and b/sources/skins/moono/icons/link.png differ
diff --git a/sources/skins/moono/icons/maximize.png b/sources/skins/moono/icons/maximize.png
new file mode 100644 (file)
index 0000000..95427dc
Binary files /dev/null and b/sources/skins/moono/icons/maximize.png differ
diff --git a/sources/skins/moono/icons/newpage-rtl.png b/sources/skins/moono/icons/newpage-rtl.png
new file mode 100644 (file)
index 0000000..e88f7f4
Binary files /dev/null and b/sources/skins/moono/icons/newpage-rtl.png differ
diff --git a/sources/skins/moono/icons/newpage.png b/sources/skins/moono/icons/newpage.png
new file mode 100644 (file)
index 0000000..410eb50
Binary files /dev/null and b/sources/skins/moono/icons/newpage.png differ
diff --git a/sources/skins/moono/icons/numberedlist-rtl.png b/sources/skins/moono/icons/numberedlist-rtl.png
new file mode 100644 (file)
index 0000000..d40582d
Binary files /dev/null and b/sources/skins/moono/icons/numberedlist-rtl.png differ
diff --git a/sources/skins/moono/icons/numberedlist.png b/sources/skins/moono/icons/numberedlist.png
new file mode 100644 (file)
index 0000000..beaa1b2
Binary files /dev/null and b/sources/skins/moono/icons/numberedlist.png differ
diff --git a/sources/skins/moono/icons/outdent-rtl.png b/sources/skins/moono/icons/outdent-rtl.png
new file mode 100644 (file)
index 0000000..bd7bb34
Binary files /dev/null and b/sources/skins/moono/icons/outdent-rtl.png differ
diff --git a/sources/skins/moono/icons/outdent.png b/sources/skins/moono/icons/outdent.png
new file mode 100644 (file)
index 0000000..b48e099
Binary files /dev/null and b/sources/skins/moono/icons/outdent.png differ
diff --git a/sources/skins/moono/icons/pagebreak-rtl.png b/sources/skins/moono/icons/pagebreak-rtl.png
new file mode 100644 (file)
index 0000000..c8b22cc
Binary files /dev/null and b/sources/skins/moono/icons/pagebreak-rtl.png differ
diff --git a/sources/skins/moono/icons/pagebreak.png b/sources/skins/moono/icons/pagebreak.png
new file mode 100644 (file)
index 0000000..616dfcd
Binary files /dev/null and b/sources/skins/moono/icons/pagebreak.png differ
diff --git a/sources/skins/moono/icons/paste-rtl.png b/sources/skins/moono/icons/paste-rtl.png
new file mode 100644 (file)
index 0000000..beb842b
Binary files /dev/null and b/sources/skins/moono/icons/paste-rtl.png differ
diff --git a/sources/skins/moono/icons/paste.png b/sources/skins/moono/icons/paste.png
new file mode 100644 (file)
index 0000000..beb842b
Binary files /dev/null and b/sources/skins/moono/icons/paste.png differ
diff --git a/sources/skins/moono/icons/pastefromword-rtl.png b/sources/skins/moono/icons/pastefromword-rtl.png
new file mode 100644 (file)
index 0000000..234e660
Binary files /dev/null and b/sources/skins/moono/icons/pastefromword-rtl.png differ
diff --git a/sources/skins/moono/icons/pastefromword.png b/sources/skins/moono/icons/pastefromword.png
new file mode 100644 (file)
index 0000000..39afbe3
Binary files /dev/null and b/sources/skins/moono/icons/pastefromword.png differ
diff --git a/sources/skins/moono/icons/pastetext-rtl.png b/sources/skins/moono/icons/pastetext-rtl.png
new file mode 100644 (file)
index 0000000..7dffd18
Binary files /dev/null and b/sources/skins/moono/icons/pastetext-rtl.png differ
diff --git a/sources/skins/moono/icons/pastetext.png b/sources/skins/moono/icons/pastetext.png
new file mode 100644 (file)
index 0000000..f5aba32
Binary files /dev/null and b/sources/skins/moono/icons/pastetext.png differ
diff --git a/sources/skins/moono/icons/placeholder.png b/sources/skins/moono/icons/placeholder.png
new file mode 100644 (file)
index 0000000..8bd808a
Binary files /dev/null and b/sources/skins/moono/icons/placeholder.png differ
diff --git a/sources/skins/moono/icons/preview-rtl.png b/sources/skins/moono/icons/preview-rtl.png
new file mode 100644 (file)
index 0000000..a1402fb
Binary files /dev/null and b/sources/skins/moono/icons/preview-rtl.png differ
diff --git a/sources/skins/moono/icons/preview.png b/sources/skins/moono/icons/preview.png
new file mode 100644 (file)
index 0000000..256fa5a
Binary files /dev/null and b/sources/skins/moono/icons/preview.png differ
diff --git a/sources/skins/moono/icons/print.png b/sources/skins/moono/icons/print.png
new file mode 100644 (file)
index 0000000..e2fd5c3
Binary files /dev/null and b/sources/skins/moono/icons/print.png differ
diff --git a/sources/skins/moono/icons/radio.png b/sources/skins/moono/icons/radio.png
new file mode 100644 (file)
index 0000000..136e433
Binary files /dev/null and b/sources/skins/moono/icons/radio.png differ
diff --git a/sources/skins/moono/icons/redo-rtl.png b/sources/skins/moono/icons/redo-rtl.png
new file mode 100644 (file)
index 0000000..9e03f4a
Binary files /dev/null and b/sources/skins/moono/icons/redo-rtl.png differ
diff --git a/sources/skins/moono/icons/redo.png b/sources/skins/moono/icons/redo.png
new file mode 100644 (file)
index 0000000..f7119cb
Binary files /dev/null and b/sources/skins/moono/icons/redo.png differ
diff --git a/sources/skins/moono/icons/removeformat.png b/sources/skins/moono/icons/removeformat.png
new file mode 100644 (file)
index 0000000..4e74dfc
Binary files /dev/null and b/sources/skins/moono/icons/removeformat.png differ
diff --git a/sources/skins/moono/icons/replace.png b/sources/skins/moono/icons/replace.png
new file mode 100644 (file)
index 0000000..9597eb1
Binary files /dev/null and b/sources/skins/moono/icons/replace.png differ
diff --git a/sources/skins/moono/icons/save.png b/sources/skins/moono/icons/save.png
new file mode 100644 (file)
index 0000000..97635c8
Binary files /dev/null and b/sources/skins/moono/icons/save.png differ
diff --git a/sources/skins/moono/icons/scayt.png b/sources/skins/moono/icons/scayt.png
new file mode 100644 (file)
index 0000000..46d7570
Binary files /dev/null and b/sources/skins/moono/icons/scayt.png differ
diff --git a/sources/skins/moono/icons/select-rtl.png b/sources/skins/moono/icons/select-rtl.png
new file mode 100644 (file)
index 0000000..33dd89d
Binary files /dev/null and b/sources/skins/moono/icons/select-rtl.png differ
diff --git a/sources/skins/moono/icons/select.png b/sources/skins/moono/icons/select.png
new file mode 100644 (file)
index 0000000..c3d89cc
Binary files /dev/null and b/sources/skins/moono/icons/select.png differ
diff --git a/sources/skins/moono/icons/selectall.png b/sources/skins/moono/icons/selectall.png
new file mode 100644 (file)
index 0000000..a4cff3d
Binary files /dev/null and b/sources/skins/moono/icons/selectall.png differ
diff --git a/sources/skins/moono/icons/showblocks-rtl.png b/sources/skins/moono/icons/showblocks-rtl.png
new file mode 100644 (file)
index 0000000..6f391b1
Binary files /dev/null and b/sources/skins/moono/icons/showblocks-rtl.png differ
diff --git a/sources/skins/moono/icons/showblocks.png b/sources/skins/moono/icons/showblocks.png
new file mode 100644 (file)
index 0000000..0b240e8
Binary files /dev/null and b/sources/skins/moono/icons/showblocks.png differ
diff --git a/sources/skins/moono/icons/smiley.png b/sources/skins/moono/icons/smiley.png
new file mode 100644 (file)
index 0000000..e7607ca
Binary files /dev/null and b/sources/skins/moono/icons/smiley.png differ
diff --git a/sources/skins/moono/icons/source-rtl.png b/sources/skins/moono/icons/source-rtl.png
new file mode 100644 (file)
index 0000000..c734db6
Binary files /dev/null and b/sources/skins/moono/icons/source-rtl.png differ
diff --git a/sources/skins/moono/icons/source.png b/sources/skins/moono/icons/source.png
new file mode 100644 (file)
index 0000000..004e73b
Binary files /dev/null and b/sources/skins/moono/icons/source.png differ
diff --git a/sources/skins/moono/icons/sourcedialog-rtl.png b/sources/skins/moono/icons/sourcedialog-rtl.png
new file mode 100644 (file)
index 0000000..c734db6
Binary files /dev/null and b/sources/skins/moono/icons/sourcedialog-rtl.png differ
diff --git a/sources/skins/moono/icons/sourcedialog.png b/sources/skins/moono/icons/sourcedialog.png
new file mode 100644 (file)
index 0000000..004e73b
Binary files /dev/null and b/sources/skins/moono/icons/sourcedialog.png differ
diff --git a/sources/skins/moono/icons/specialchar.png b/sources/skins/moono/icons/specialchar.png
new file mode 100644 (file)
index 0000000..4dafefd
Binary files /dev/null and b/sources/skins/moono/icons/specialchar.png differ
diff --git a/sources/skins/moono/icons/spellchecker.png b/sources/skins/moono/icons/spellchecker.png
new file mode 100644 (file)
index 0000000..46d7570
Binary files /dev/null and b/sources/skins/moono/icons/spellchecker.png differ
diff --git a/sources/skins/moono/icons/strike.png b/sources/skins/moono/icons/strike.png
new file mode 100644 (file)
index 0000000..8007832
Binary files /dev/null and b/sources/skins/moono/icons/strike.png differ
diff --git a/sources/skins/moono/icons/subscript.png b/sources/skins/moono/icons/subscript.png
new file mode 100644 (file)
index 0000000..89e8bf4
Binary files /dev/null and b/sources/skins/moono/icons/subscript.png differ
diff --git a/sources/skins/moono/icons/superscript.png b/sources/skins/moono/icons/superscript.png
new file mode 100644 (file)
index 0000000..1a269c6
Binary files /dev/null and b/sources/skins/moono/icons/superscript.png differ
diff --git a/sources/skins/moono/icons/table.png b/sources/skins/moono/icons/table.png
new file mode 100644 (file)
index 0000000..f29d051
Binary files /dev/null and b/sources/skins/moono/icons/table.png differ
diff --git a/sources/skins/moono/icons/templates-rtl.png b/sources/skins/moono/icons/templates-rtl.png
new file mode 100644 (file)
index 0000000..0ebeb55
Binary files /dev/null and b/sources/skins/moono/icons/templates-rtl.png differ
diff --git a/sources/skins/moono/icons/templates.png b/sources/skins/moono/icons/templates.png
new file mode 100644 (file)
index 0000000..0ebeb55
Binary files /dev/null and b/sources/skins/moono/icons/templates.png differ
diff --git a/sources/skins/moono/icons/textarea-rtl.png b/sources/skins/moono/icons/textarea-rtl.png
new file mode 100644 (file)
index 0000000..6ae1560
Binary files /dev/null and b/sources/skins/moono/icons/textarea-rtl.png differ
diff --git a/sources/skins/moono/icons/textarea.png b/sources/skins/moono/icons/textarea.png
new file mode 100644 (file)
index 0000000..4edac92
Binary files /dev/null and b/sources/skins/moono/icons/textarea.png differ
diff --git a/sources/skins/moono/icons/textcolor.png b/sources/skins/moono/icons/textcolor.png
new file mode 100644 (file)
index 0000000..48ed589
Binary files /dev/null and b/sources/skins/moono/icons/textcolor.png differ
diff --git a/sources/skins/moono/icons/textfield-rtl.png b/sources/skins/moono/icons/textfield-rtl.png
new file mode 100644 (file)
index 0000000..a0564ea
Binary files /dev/null and b/sources/skins/moono/icons/textfield-rtl.png differ
diff --git a/sources/skins/moono/icons/textfield.png b/sources/skins/moono/icons/textfield.png
new file mode 100644 (file)
index 0000000..a0564ea
Binary files /dev/null and b/sources/skins/moono/icons/textfield.png differ
diff --git a/sources/skins/moono/icons/uicolor.png b/sources/skins/moono/icons/uicolor.png
new file mode 100644 (file)
index 0000000..b633a3c
Binary files /dev/null and b/sources/skins/moono/icons/uicolor.png differ
diff --git a/sources/skins/moono/icons/underline.png b/sources/skins/moono/icons/underline.png
new file mode 100644 (file)
index 0000000..2ac6fb7
Binary files /dev/null and b/sources/skins/moono/icons/underline.png differ
diff --git a/sources/skins/moono/icons/undo-rtl.png b/sources/skins/moono/icons/undo-rtl.png
new file mode 100644 (file)
index 0000000..f7119cb
Binary files /dev/null and b/sources/skins/moono/icons/undo-rtl.png differ
diff --git a/sources/skins/moono/icons/undo.png b/sources/skins/moono/icons/undo.png
new file mode 100644 (file)
index 0000000..4c80228
Binary files /dev/null and b/sources/skins/moono/icons/undo.png differ
diff --git a/sources/skins/moono/icons/unlink.png b/sources/skins/moono/icons/unlink.png
new file mode 100644 (file)
index 0000000..8a4c84d
Binary files /dev/null and b/sources/skins/moono/icons/unlink.png differ
diff --git a/sources/skins/moono/images/anchor.png b/sources/skins/moono/images/anchor.png
new file mode 100644 (file)
index 0000000..1c802f5
Binary files /dev/null and b/sources/skins/moono/images/anchor.png differ
diff --git a/sources/skins/moono/images/arrow.png b/sources/skins/moono/images/arrow.png
new file mode 100644 (file)
index 0000000..d72b5f3
Binary files /dev/null and b/sources/skins/moono/images/arrow.png differ
diff --git a/sources/skins/moono/images/close.png b/sources/skins/moono/images/close.png
new file mode 100644 (file)
index 0000000..2d02977
Binary files /dev/null and b/sources/skins/moono/images/close.png differ
diff --git a/sources/skins/moono/images/hidpi/anchor.png b/sources/skins/moono/images/hidpi/anchor.png
new file mode 100644 (file)
index 0000000..17cca97
Binary files /dev/null and b/sources/skins/moono/images/hidpi/anchor.png differ
diff --git a/sources/skins/moono/images/hidpi/close.png b/sources/skins/moono/images/hidpi/close.png
new file mode 100644 (file)
index 0000000..de4eedf
Binary files /dev/null and b/sources/skins/moono/images/hidpi/close.png differ
diff --git a/sources/skins/moono/images/hidpi/lock-open.png b/sources/skins/moono/images/hidpi/lock-open.png
new file mode 100644 (file)
index 0000000..594f0d3
Binary files /dev/null and b/sources/skins/moono/images/hidpi/lock-open.png differ
diff --git a/sources/skins/moono/images/hidpi/lock.png b/sources/skins/moono/images/hidpi/lock.png
new file mode 100644 (file)
index 0000000..1e23a0b
Binary files /dev/null and b/sources/skins/moono/images/hidpi/lock.png differ
diff --git a/sources/skins/moono/images/hidpi/refresh.png b/sources/skins/moono/images/hidpi/refresh.png
new file mode 100644 (file)
index 0000000..42d94a9
Binary files /dev/null and b/sources/skins/moono/images/hidpi/refresh.png differ
diff --git a/sources/skins/moono/images/lock-open.png b/sources/skins/moono/images/lock-open.png
new file mode 100644 (file)
index 0000000..7d24c5f
Binary files /dev/null and b/sources/skins/moono/images/lock-open.png differ
diff --git a/sources/skins/moono/images/lock.png b/sources/skins/moono/images/lock.png
new file mode 100644 (file)
index 0000000..8baeaa4
Binary files /dev/null and b/sources/skins/moono/images/lock.png differ
diff --git a/sources/skins/moono/images/refresh.png b/sources/skins/moono/images/refresh.png
new file mode 100644 (file)
index 0000000..d8106b0
Binary files /dev/null and b/sources/skins/moono/images/refresh.png differ
diff --git a/sources/skins/moono/images/spinner.gif b/sources/skins/moono/images/spinner.gif
new file mode 100644 (file)
index 0000000..d898d41
Binary files /dev/null and b/sources/skins/moono/images/spinner.gif differ
diff --git a/sources/skins/moono/mainui.css b/sources/skins/moono/mainui.css
new file mode 100644 (file)
index 0000000..6ad85ef
--- /dev/null
@@ -0,0 +1,214 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+mainui.css (part of editor.css)\r
+=================================\r
+\r
+This file styles the basic structure of the CKEditor user interface - the box\r
+that holds everything.\r
+\r
+CKEditor offers two main editing modes. The main UI blocks that compose these\r
+modes are:\r
+\r
+       For "Theme UI" mode, the one most generally used:\r
+\r
+       +-- .cke_chrome ----------------------+\r
+       |+-- .cke_inner ---------------------+|\r
+       || +-- .cke_top -------------------+ ||\r
+       || |                               | ||\r
+       || +-------------------------------+ ||\r
+       || +-- .cke_contents --------------+ ||\r
+       || |                               | ||\r
+       || +-------------------------------+ ||\r
+       || +-- .cke_bottom ----------------+ ||\r
+       || |                               | ||\r
+       || +-------------------------------+ ||\r
+       |+-----------------------------------+|\r
+       +-------------------------------------+\r
+\r
+       For "Inline Editing" mode:\r
+\r
+       +-- .cke_chrome .cke_float------------+\r
+       |+-- .cke_inner ---------------------+|\r
+       || +-- .cke_top -------------------+ ||\r
+       || |                               | ||\r
+       || +-------------------------------+ ||\r
+       |+-----------------------------------+|\r
+       +-------------------------------------+\r
+\r
+Special outer level classes used in this file:\r
+\r
+       .cke_hc: Available when the editor is rendered on "High Contrast".\r
+\r
+*/\r
+\r
+/* The outer boundary of the interface. */\r
+.cke_chrome\r
+{\r
+       /* This is <span>, so transform it into a block.*/\r
+       display: block;\r
+       border: 1px solid #b6b6b6;\r
+       padding: 0;\r
+\r
+       box-shadow: 0 0 3px rgba(0,0,0,.15);\r
+}\r
+\r
+/* The inner boundary of the interface. */\r
+.cke_inner\r
+{\r
+       /* This is <span>, so transform it into a block.*/\r
+       display: block;\r
+\r
+       -webkit-touch-callout: none;\r
+\r
+       background: #fff;\r
+       padding: 0;\r
+}\r
+\r
+/* Added to the outer boundary of the UI when in inline editing,\r
+   when the UI is floating. */\r
+.cke_float\r
+{\r
+       /* Make white the space between the outer and the inner borders. */\r
+       border: none;\r
+}\r
+\r
+.cke_float .cke_inner\r
+{\r
+       /* As we don't have blocks following top (toolbar) we suppress the padding\r
+          as the toolbar defines its own margin. */\r
+       padding-bottom: 0;\r
+}\r
+\r
+/* Make the main spaces enlarge to hold potentially floated content. */\r
+.cke_top,\r
+.cke_contents,\r
+.cke_bottom\r
+{\r
+       /* These are <span>s, so transform them into blocks.*/\r
+       display: block;\r
+\r
+       /* Ideally this should be "auto", but it shows scrollbars in IE7. */\r
+       overflow: hidden;\r
+}\r
+\r
+.cke_top\r
+{\r
+       /*border: 1px solid #b2b2b2;*/\r
+       border-bottom: 1px solid #b6b6b6;\r
+       padding: 6px 8px 2px;\r
+\r
+       /* Allow breaking toolbars when in a narrow editor. (#9947) */\r
+       white-space: normal;\r
+\r
+       box-shadow: 0 1px 0 #fff inset;\r
+\r
+       background: #cfd1cf;\r
+       background-image: linear-gradient(to bottom, #f5f5f5, #cfd1cf);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f5f5f5', endColorstr='#cfd1cf');\r
+}\r
+\r
+.cke_float .cke_top\r
+{\r
+       border: 1px solid #b6b6b6;\r
+       border-bottom-color: #999;\r
+}\r
+\r
+.cke_bottom\r
+{\r
+       padding: 6px 8px 2px;\r
+       position: relative;\r
+\r
+       border-top: 1px solid #bfbfbf;\r
+\r
+       box-shadow: 0 1px 0 #fff inset;\r
+\r
+       background: #cfd1cf;\r
+       background-image: linear-gradient(to bottom, #ebebeb, #cfd1cf);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ebebeb', endColorstr='#cfd1cf');\r
+}\r
+\r
+/* On iOS we need to manually enable scrolling in the contents block. (#9945) */\r
+.cke_browser_ios .cke_contents\r
+{\r
+    overflow-y: auto;\r
+    -webkit-overflow-scrolling: touch;\r
+}\r
+\r
+/* The resizer is the small UI element that is rendered at the bottom right\r
+   part of the editor. It makes is possible to resize the editor UI. */\r
+.cke_resizer\r
+{\r
+       /* To avoid using images for the resizer, we create a small triangle,\r
+          using some CSS magic. */\r
+       width: 0;\r
+       height: 0;\r
+       overflow: hidden;\r
+       width: 0;\r
+       height: 0;\r
+       overflow: hidden;\r
+       border-width: 10px 10px 0 0;\r
+       border-color: transparent #666 transparent transparent;\r
+       border-style: dashed solid dashed dashed;\r
+\r
+       font-size: 0;\r
+       vertical-align: bottom;\r
+\r
+       margin-top: 6px;\r
+\r
+       /*      A margin in case of no other element in the same container\r
+               to keep a distance to the bottom edge. */\r
+       margin-bottom: 2px;\r
+\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.3);\r
+}\r
+\r
+.cke_hc .cke_resizer\r
+{\r
+       font-size: 15px;\r
+       width: auto;\r
+       height: auto;\r
+       border-width: 0;\r
+}\r
+\r
+.cke_resizer_ltr\r
+{\r
+       cursor: se-resize;\r
+\r
+       float: right;\r
+       margin-right: -4px;\r
+}\r
+\r
+/* This class is added in RTL mode. This is a special case for the resizer\r
+   (usually the .cke_rtl class is used), because it may not necessarily be in\r
+   RTL mode if the main UI is RTL. It depends instead on the context where the\r
+   editor is inserted on. */\r
+.cke_resizer_rtl\r
+{\r
+       border-width: 10px 0 0 10px;\r
+       border-color: transparent transparent transparent #A5A5A5;\r
+       border-style: dashed dashed dashed solid;\r
+\r
+       cursor: sw-resize;\r
+\r
+       float: left;\r
+       margin-left: -4px;\r
+       right: auto;\r
+}\r
+\r
+/* The editing area (where users type) can be rendered as an editable <div>\r
+   element (e.g. divarea plugin). In that case, this is the class applied to\r
+   that element. */\r
+.cke_wysiwyg_div\r
+{\r
+       display: block;\r
+       height: 100%;\r
+       overflow: auto;\r
+       padding: 0 8px;\r
+       outline-style: none;\r
+\r
+       box-sizing: border-box;\r
+}\r
diff --git a/sources/skins/moono/menu.css b/sources/skins/moono/menu.css
new file mode 100644 (file)
index 0000000..0c1ab59
--- /dev/null
@@ -0,0 +1,207 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+menu.css (part of editor.css)\r
+===============================\r
+\r
+This file styles menus used in the editor UI. These menus are the list of\r
+options available inside some "floating panels", like menu buttons of the\r
+toolbar or the context menu.\r
+\r
+Note that the menu itself doesn't include the floating element that holds it.\r
+That element is styles in the panel.css file.\r
+\r
+The following is a visual representation of the main elements of a menu:\r
+\r
++-- .cke_menu -----------------+\r
+| +-- .cke_menuitem  --------+ |\r
+| | +-- .cke_menubutton ---+ | |\r
+| | |                      | | |\r
+| | +----------------------+ | |\r
+| +--------------------------+ |\r
+| +-- .cke_menuseparator ----+ |\r
+| ...                          |\r
++------------------------------+\r
+\r
+This is the .cke_menubutton structure:\r
+(Note that the menu button icon shares with toolbar button the common class .cke_button_icon to achieve the same outlook.)\r
+\r
++-- .cke_menubutton -------------------------------------------------------------------------+\r
+| +-- .cke_menubutton_inner ---------------------------------------------------------------+ |\r
+| | +-- .cke_menubutton_icon ---+ +-- .cke_menubutton_label --+ +-- .cke_cke_menuarrow --+ | |\r
+| | | +-- .cke_button_icon ---+ | |                           | |                        | | |\r
+| | | |                       | | |                           | |                        | | |\r
+| | | +-----------------------+ | |                           | |                        | | |\r
+| | +---------------------------+ +---------------------------+ +------------------------+ | |\r
+| +----------------------------------------------------------------------------------------+ |\r
++--------------------------------------------------------------------------------------------+\r
+\r
+Special outer level classes used in this file:\r
+\r
+       .cke_hc: Available when the editor is rendered on "High Contrast".\r
+       .cke_rtl: Available when the editor UI is on RTL.\r
+*/\r
+\r
+/* .cke_menuitem is the element that holds the entire structure of each of the\r
+   menu items. */\r
+\r
+.cke_menubutton\r
+{\r
+       /* The "button" inside a menu item is a <a> element.\r
+          Transforms it into a block. */\r
+       display: block;\r
+}\r
+\r
+.cke_menuitem span\r
+{\r
+       /* Avoid the text selection cursor inside menu items. */\r
+       cursor: default;\r
+}\r
+\r
+.cke_menubutton:hover,\r
+.cke_menubutton:focus,\r
+.cke_menubutton:active\r
+{\r
+       background-color: #D3D3D3;\r
+       display: block;\r
+}\r
+\r
+.cke_hc .cke_menubutton\r
+{\r
+       padding: 2px;\r
+}\r
+\r
+.cke_hc .cke_menubutton:hover,\r
+.cke_hc .cke_menubutton:focus,\r
+.cke_hc .cke_menubutton:active\r
+{\r
+       border: 2px solid;\r
+       padding: 0;\r
+}\r
+\r
+.cke_menubutton_inner {\r
+       display: table-row;\r
+}\r
+\r
+.cke_menubutton_icon,\r
+.cke_menubutton_label,\r
+.cke_menuarrow {\r
+       display: table-cell;\r
+}\r
+\r
+/* The menu item icon. */\r
+.cke_menubutton_icon\r
+{\r
+       background-color: #D7D8D7;\r
+       opacity: 0.70; /* Safari, Opera and Mozilla */\r
+       filter: alpha(opacity=70); /* IE */\r
+       padding: 4px;\r
+}\r
+\r
+.cke_hc .cke_menubutton_icon\r
+{\r
+       height: 16px;\r
+       width: 0;\r
+       padding: 4px 0;\r
+}\r
+\r
+.cke_menubutton:hover .cke_menubutton_icon,\r
+.cke_menubutton:focus .cke_menubutton_icon,\r
+.cke_menubutton:active .cke_menubutton_icon\r
+{\r
+       background-color: #D0D2D0;\r
+}\r
+\r
+.cke_menubutton_disabled:hover .cke_menubutton_icon,\r
+.cke_menubutton_disabled:focus .cke_menubutton_icon,\r
+.cke_menubutton_disabled:active .cke_menubutton_icon\r
+{\r
+       /* The icon will get opacity as well when hovered. */\r
+       opacity: 0.3;\r
+       filter: alpha(opacity=30);\r
+}\r
+\r
+/* The textual part of each menu item. */\r
+.cke_menubutton_label\r
+{\r
+       padding: 0 5px;\r
+       background-color: transparent;\r
+       width: 100%;\r
+       vertical-align: middle;\r
+}\r
+\r
+/* Keyboard shortcut placed next to the label. */\r
+.cke_menubutton_shortcut\r
+{\r
+       color: #979797;\r
+}\r
+\r
+.cke_menubutton_disabled .cke_menubutton_label\r
+{\r
+       /* Greyed label text indicates a disabled menu item. */\r
+       opacity: 0.3;\r
+       filter: alpha(opacity=30);\r
+}\r
+\r
+.cke_menubutton_on\r
+{\r
+       border: 1px solid #dedede;\r
+       background-color: #f2f2f2;\r
+\r
+       box-shadow: 0 0 2px rgba(0,0,0,.1) inset;\r
+}\r
+\r
+.cke_menubutton_on .cke_menubutton_icon\r
+{\r
+       padding-right: 3px;\r
+}\r
+\r
+.cke_menubutton:hover,\r
+.cke_menubutton:focus,\r
+.cke_menubutton:active\r
+{\r
+       background-color: #EFF0EF;\r
+}\r
+\r
+.cke_panel_frame .cke_menubutton_label\r
+{\r
+       display: none;\r
+}\r
+\r
+/* The separator used to separate menu item groups. */\r
+.cke_menuseparator\r
+{\r
+       background-color: #D3D3D3;\r
+       height: 1px;\r
+       filter: alpha(opacity=70); /* IE */\r
+       opacity: 0.70; /* Safari, Opera and Mozilla */\r
+}\r
+\r
+/* The small arrow shown for item with sub-menus. */\r
+.cke_menuarrow\r
+{\r
+       background-image: url(images/arrow.png);\r
+       background-position: 0 10px;\r
+       background-repeat: no-repeat;\r
+       padding: 0 5px;\r
+}\r
+\r
+.cke_rtl .cke_menuarrow\r
+{\r
+       background-position: 5px -13px;\r
+       background-repeat: no-repeat;\r
+}\r
+\r
+.cke_menuarrow span\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_hc .cke_menuarrow span\r
+{\r
+       vertical-align: middle;\r
+       display: inline;\r
+}\r
diff --git a/sources/skins/moono/notification.css b/sources/skins/moono/notification.css
new file mode 100644 (file)
index 0000000..659fef7
--- /dev/null
@@ -0,0 +1,168 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/**\r
+ * Progress notification structure:\r
+ *\r
+ * +---div.cke_notification cke_notification_info--------------------------+\r
+ * |                                                                       |\r
+ * | +---div.cke_notification_progress-----------------------------------+ |\r
+ * | |                                                                   | |\r
+ * | +-------------------------------------------------------------------+ |\r
+ * |                                                                       |\r
+ * | +---p.cke_notification_message--------------------------------------+ |\r
+ * | | Foo                                                               | |\r
+ * | +-------------------------------------------------------------------+ |\r
+ * |                                                                       |\r
+ * | +---a.cke_notification_close----------------------------------------+ |\r
+ * | | +---span.cke_label----------------------------------------------+ | |\r
+ * | | | X                                                             | | |\r
+ * | | +---------------------------------------------------------------+ | |\r
+ * | +-------------------------------------------------------------------+ |\r
+ * |                                                                       |\r
+ * +-----------------------------------------------------------------------+\r
+ *\r
+ *\r
+ * Warning notification structure:\r
+ *\r
+ * +---div.cke_notification cke_notification_warning-----------------------+\r
+ * |                                                                       |\r
+ * | +---p.cke_notification_message--------------------------------------+ |\r
+ * | | Foo                                                               | |\r
+ * | +-------------------------------------------------------------------+ |\r
+ * |                                                                       |\r
+ * | +---a.cke_notification_close----------------------------------------+ |\r
+ * | | +---span.cke_label----------------------------------------------+ | |\r
+ * | | | X                                                             | | |\r
+ * | | +---------------------------------------------------------------+ | |\r
+ * | +-------------------------------------------------------------------+ |\r
+ * |                                                                       |\r
+ * +-----------------------------------------------------------------------+\r
+ *\r
+ * Success and info notifications have the same structure as warning, but use\r
+ * `cke_notification_success` and `cke_notification_info` instead of `cke_notification_warning`.\r
+ */\r
+.cke_notifications_area\r
+{\r
+       /* Prevent notification margin capture clicking. */\r
+       pointer-events: none;\r
+}\r
+.cke_notification\r
+{\r
+       pointer-events: auto;\r
+       position: relative;\r
+       margin: 10px;\r
+       width: 300px;\r
+       color: white;\r
+       border-radius: 3px;\r
+       text-align: center;\r
+       opacity: 0.95;\r
+       filter: alpha(opacity = 95);\r
+       box-shadow: 2px 2px 3px 0px rgba(50, 50, 50, 0.3);\r
+\r
+       -webkit-animation: fadeIn 0.7s;\r
+       animation: fadeIn 0.7s;\r
+}\r
+\r
+.cke_notification_message a\r
+{\r
+       color: #12306F;\r
+}\r
+\r
+@-webkit-keyframes fadeIn\r
+{\r
+       from { opacity: 0.4; }\r
+       to { opacity: 0.95; }\r
+}\r
+\r
+@keyframes fadeIn\r
+{\r
+       from { opacity: 0.4; }\r
+       to { opacity: 0.95; }\r
+}\r
+\r
+.cke_notification_success\r
+{\r
+       background: #72B572;\r
+       border: 1px solid #63A563;\r
+}\r
+\r
+.cke_notification_warning\r
+{\r
+       background: #C83939;\r
+       border: 1px solid #902B2B;\r
+}\r
+\r
+.cke_notification_info\r
+{\r
+       background: #2E9AD0;\r
+       border: 1px solid #0F74A8;\r
+}\r
+\r
+.cke_notification_info span.cke_notification_progress\r
+{\r
+       background-color: #0F74A8;\r
+       display: block;\r
+       padding: 0;\r
+       margin: 0;\r
+       height: 100%;\r
+       overflow: hidden;\r
+       position: absolute;\r
+       z-index: 1;\r
+}\r
+\r
+.cke_notification_message\r
+{\r
+       position: relative;\r
+       margin: 4px 23px 3px;\r
+       font-family: Arial, Helvetica, sans-serif;\r
+       font-size: 12px;\r
+       line-height: 18px;\r
+       z-index: 4;\r
+       text-overflow: ellipsis;\r
+       overflow: hidden;\r
+}\r
+\r
+.cke_notification_close\r
+{\r
+       background-image: url(images/close.png);\r
+       background-repeat: no-repeat;\r
+       background-position: 50%;\r
+       position: absolute;\r
+       cursor: pointer;\r
+       text-align: center;\r
+       height: 20px;\r
+       width: 20px;\r
+       top: 1px;\r
+       right: 1px;\r
+       padding: 0;\r
+       margin: 0;\r
+       z-index: 5;\r
+       opacity: 0.6;\r
+       filter: alpha(opacity = 60);\r
+}\r
+\r
+.cke_notification_close:hover\r
+{\r
+       opacity: 1;\r
+       filter: alpha(opacity = 100);\r
+}\r
+\r
+.cke_notification_close span\r
+{\r
+       display: none;\r
+}\r
+\r
+.cke_notification_warning a.cke_notification_close\r
+{\r
+       opacity: 0.8;\r
+       filter: alpha(opacity = 80);\r
+}\r
+\r
+.cke_notification_warning a.cke_notification_close:hover\r
+{\r
+       opacity: 1;\r
+       filter: alpha(opacity = 100);\r
+}\r
diff --git a/sources/skins/moono/panel.css b/sources/skins/moono/panel.css
new file mode 100644 (file)
index 0000000..b1f457f
--- /dev/null
@@ -0,0 +1,237 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+panel.css (part of editor.css)\r
+================================\r
+\r
+Panels are floating elements that can hold different types of contents.\r
+The following are common uses of it:\r
+\r
+       - The element that toolbar combos display when opening them.\r
+       - The context menu.\r
+       - The list of items displayed by "menu buttons" (e.g. scayt).\r
+       - The panel shown when opening "panel buttons" (e.g. color buttons).\r
+\r
+Panel contents are wrapped into an iframe, so it is possible to have additional\r
+CSS loaded inside them (e.g. to have more accurate preview on the styles combo).\r
+\r
+The following is a visual representation of the outer elements of a panel:\r
+\r
++-- .cke_panel(*) ---------------------+\r
+| +-- IFRAME.cke_panel_frame --------+ |\r
+| | +-- HTML.cke_panel_container --+ | |\r
+| | | +-- .cke_panel_block ------+ | | |\r
+| | | |                          | | | |\r
+| | | |     (contents here)      | | | |\r
+| | | |                          | | | |\r
+| | | +--------------------------+ | | |\r
+| | +------------------------------+ | |\r
+| +----------------------------------+ |\r
++--------------------------------------+\r
+\r
+(*) All kinds of panel share the above structure. Menu panels adds the\r
+    .cke_menu_panel class to the outer element, while toolbar combos add the\r
+       .cke_combopanel class.\r
+\r
+This file also defines styles for panel lists (used by combos). For menu-like\r
+panel contents and color panels check menu.css and colorpanel.css.\r
+*/\r
+\r
+/* The box that holds an IFRAME. It's inserted into a host document and positioned\r
+   absolutely by the application. It floats above the host document/editor. */\r
+.cke_panel\r
+{\r
+       /* Restore the loading hide */\r
+       visibility: visible;\r
+    width: 120px;\r
+       height: 100px;\r
+       overflow: hidden;\r
+\r
+       background-color: #fff;\r
+    border: 1px solid #b6b6b6;\r
+    border-bottom-color: #999;\r
+\r
+       border-radius: 3px;\r
+\r
+    box-shadow: 0 0 3px rgba(0,0,0,.15);\r
+}\r
+\r
+/* This class represents panels which are used as context menus. */\r
+.cke_menu_panel\r
+{\r
+       padding: 0;\r
+       margin: 0;\r
+}\r
+\r
+/* This class represents panels which are used by rich combos. */\r
+.cke_combopanel\r
+{\r
+    width: 150px;\r
+    height: 170px;\r
+}\r
+\r
+/* The IFRAME the panel is wrapped into. */\r
+.cke_panel_frame\r
+{\r
+       width: 100%;\r
+       height: 100%;\r
+       font-size: 12px;\r
+\r
+       overflow: auto;\r
+       overflow-x: hidden;\r
+}\r
+\r
+/* The HTML document which is a direct descendant of the IFRAME */\r
+.cke_panel_container\r
+{\r
+       overflow-y: auto;\r
+       overflow-x: hidden;\r
+}\r
+\r
+/*\r
+Here we start the definition of panel lists (e.g. combo panels). The following\r
+is its visual representation:\r
+\r
++-- .cke_panel_block -----------------+\r
+| +-- .cke_panel_grouptitle --------+ |\r
+| |                                 | |\r
+| +---------------------------------+ |\r
+| +-- .cke_panel_list --------------+ |\r
+| | +-- .cke_panel_listItem ------+ | |\r
+| | | +-- a --------------------+ | | |\r
+| | | | +-- span -------------+ | | | |\r
+| | | | |                     | | | | |\r
+| | | | +---------------------+ | | | |\r
+| | | +-------------------------+ | | |\r
+| | +-----------------------------+ | |\r
+| | +-- .cke_panel_listItem ------+ | |\r
+| | | +-- a --------------------+ | | |\r
+| | | | +-- span -------------+ | | | |\r
+| | | | |                     | | | | |\r
+| | | | +---------------------+ | | | |\r
+| | | +-------------------------+ | | |\r
+| | +-----------------------------+ | |\r
+| | ...                             | |\r
+| +---------------------------------+ |\r
++-------------------------------------+\r
+*/\r
+\r
+\r
+/* The list of panel items. */\r
+.cke_panel_list\r
+{\r
+       list-style-type: none;\r
+       margin: 3px;\r
+       padding: 0;\r
+       white-space: nowrap;\r
+}\r
+\r
+/* The item of .cke_panel_list */\r
+.cke_panel_listItem\r
+{\r
+       margin: 0;\r
+    padding-bottom: 1px;\r
+}\r
+\r
+/* The child of .cke_panel_listItem. These elements contain spans which are\r
+   to display a real name of the property which is visible for an end-user. */\r
+.cke_panel_listItem a\r
+{\r
+       padding: 3px 4px;\r
+       display: block;\r
+       border: 1px solid #fff;\r
+       color: inherit !important;\r
+       text-decoration: none;\r
+       overflow: hidden;\r
+       text-overflow: ellipsis;\r
+\r
+    border-radius: 2px;\r
+}\r
+\r
+/* IE6 */\r
+* html .cke_panel_listItem a\r
+{\r
+       width : 100%;\r
+\r
+       /* IE is not able to inherit the color, so we must force it to black */\r
+       color: #000;\r
+}\r
+\r
+/* IE7 */\r
+*:first-child+html .cke_panel_listItem a\r
+{\r
+       /* IE is not able to inherit the color, so we must force it to black */\r
+       color: #000;\r
+}\r
+\r
+.cke_panel_listItem.cke_selected a\r
+{\r
+       border: 1px solid #dedede;\r
+       background-color: #f2f2f2;\r
+\r
+    box-shadow: 0 0 2px rgba(0,0,0,.1) inset;\r
+}\r
+\r
+.cke_panel_listItem a:hover,\r
+.cke_panel_listItem a:focus,\r
+.cke_panel_listItem a:active\r
+{\r
+       border-color: #dedede;\r
+       background-color: #f2f2f2;\r
+\r
+    box-shadow: 0 0 2px rgba(0,0,0,.1) inset;\r
+}\r
+\r
+.cke_hc .cke_panel_listItem a\r
+{\r
+       border-style: none;\r
+}\r
+\r
+.cke_hc .cke_panel_listItem a:hover,\r
+.cke_hc .cke_panel_listItem a:focus,\r
+.cke_hc .cke_panel_listItem a:active\r
+{\r
+       border: 2px solid;\r
+       padding: 1px 2px;\r
+}\r
+\r
+/* The title of the entire panel which is visible on top of the list. */\r
+.cke_panel_grouptitle\r
+{\r
+       cursor: default;\r
+       font-size: 11px;\r
+       font-weight: bold;\r
+       white-space: nowrap;\r
+       margin: 0;\r
+       padding: 4px 6px;\r
+\r
+    color: #474747;\r
+    text-shadow: 0 1px 0 rgba(255,255,255,.75);\r
+    border-bottom: 1px solid #b6b6b6;\r
+\r
+    border-radius: 2px 2px 0 0;\r
+\r
+    box-shadow: 0 1px 0 #fff inset;\r
+\r
+    background: #cfd1cf;\r
+    background-image: linear-gradient(to bottom, #f5f5f5, #cfd1cf);\r
+    filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f5f5f5', endColorstr='#cfd1cf');\r
+}\r
+\r
+/* The following styles set defaults of the elements used by the Paragraph\r
+   Format panel. */\r
+.cke_panel_listItem p,\r
+.cke_panel_listItem h1,\r
+.cke_panel_listItem h2,\r
+.cke_panel_listItem h3,\r
+.cke_panel_listItem h4,\r
+.cke_panel_listItem h5,\r
+.cke_panel_listItem h6,\r
+.cke_panel_listItem pre\r
+{\r
+       margin-top: 0px;\r
+       margin-bottom: 0px;\r
+}\r
diff --git a/sources/skins/moono/presets.css b/sources/skins/moono/presets.css
new file mode 100644 (file)
index 0000000..2d06deb
--- /dev/null
@@ -0,0 +1,41 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/* "Source" button label */\r
+.cke_button__source_label,\r
+.cke_button__sourcedialog_label\r
+{\r
+       display: inline;\r
+}\r
+\r
+/* "Font Size" combo width */\r
+.cke_combo__fontsize .cke_combo_text\r
+{\r
+       width: 30px;\r
+}\r
+\r
+/* "Font Size" panel size */\r
+.cke_combopanel__fontsize\r
+{\r
+       width: 120px;\r
+}\r
+\r
+/* Editable regions */\r
+textarea.cke_source\r
+{\r
+       font-family: 'Courier New', Monospace;\r
+       font-size: small;\r
+       background-color: #fff;\r
+       white-space: pre-wrap;\r
+       border: none;\r
+       padding: 0;\r
+       margin: 0;\r
+       display: block;\r
+}\r
+\r
+.cke_wysiwyg_frame, .cke_wysiwyg_div\r
+{\r
+       background-color: #fff;\r
+}\r
diff --git a/sources/skins/moono/readme.md b/sources/skins/moono/readme.md
new file mode 100644 (file)
index 0000000..4a4ed6b
--- /dev/null
@@ -0,0 +1,49 @@
+"Moono" Skin\r
+====================\r
+\r
+This skin has been chosen for the **default skin** of CKEditor 4.x (replaced by "Moono-lisa" skin since CKEditor 4.6.0),\r
+elected from the CKEditor [skin contest](http://ckeditor.com/blog/new_ckeditor_4_skin) and further shaped by\r
+the CKEditor team. "Moono" is maintained by the core developers.\r
+\r
+For more information about skins, please check the [CKEditor Skin SDK](http://docs.cksource.com/CKEditor_4.x/Skin_SDK)\r
+documentation.\r
+\r
+Features\r
+-------------------\r
+"Moono" is a monochromatic skin, which offers a modern look coupled with gradients and transparency.\r
+It comes with the following features:\r
+\r
+- Chameleon feature with brightness,\r
+- high-contrast compatibility,\r
+- graphics source provided in SVG.\r
+\r
+Directory Structure\r
+-------------------\r
+\r
+CSS parts:\r
+- **editor.css**: the main CSS file. It's simply loading several other files, for easier maintenance,\r
+- **mainui.css**: the file contains styles of entire editor outline structures,\r
+- **toolbar.css**: the file contains styles of the editor toolbar space (top),\r
+- **richcombo.css**: the file contains styles of the rich combo ui elements on toolbar,\r
+- **panel.css**: the file contains styles of the rich combo drop-down, it's not loaded\r
+until the first panel open up,\r
+- **elementspath.css**: the file contains styles of the editor elements path bar (bottom),\r
+- **menu.css**: the file contains styles of all editor menus including context menu and button drop-down,\r
+it's not loaded until the first menu open up,\r
+- **dialog.css**: the CSS files for the dialog UI, it's not loaded until the first dialog open,\r
+- **reset.css**: the file defines the basis of style resets among all editor UI spaces,\r
+- **preset.css**: the file defines the default styles of some UI elements reflecting the skin preference,\r
+- **editor_XYZ.css** and **dialog_XYZ.css**: browser specific CSS hacks.\r
+\r
+Other parts:\r
+- **skin.js**: the only JavaScript part of the skin that registers the skin, its browser specific files and its icons and defines the Chameleon feature,\r
+- **icons/**: contains all skin defined icons,\r
+- **images/**: contains a fill general used images,\r
+- **dev/**: contains SVG source of the skin icons.\r
+\r
+License\r
+-------\r
+\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+\r
+For licensing, see LICENSE.md or [http://ckeditor.com/license](http://ckeditor.com/license)\r
diff --git a/sources/skins/moono/reset.css b/sources/skins/moono/reset.css
new file mode 100644 (file)
index 0000000..d64bf82
--- /dev/null
@@ -0,0 +1,115 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+reset.css (part of editor.css)\r
+================================\r
+\r
+This file holds the "reset" requirements of CKEditor, as well as define the\r
+default interface styles.\r
+\r
+CKEditor includes two main "reset" class names in the DOM structure created for\r
+editors:\r
+\r
+       * .cke_reset: Intended to reset a specific element, but not its children.\r
+         Because of this, only styles that will not be inherited can be defined.\r
+\r
+       * .cke_reset_all: Intended to reset not only the element holding it, but\r
+          also its child elements.\r
+\r
+To understand why "reset" is needed, check the CKEditor Skin SDK:\r
+http://docs.cksource.com/CKEditor_4.x/Skin_SDK/Reset\r
+*/\r
+\r
+/* Reset for single elements, not their children. */\r
+.cke_reset\r
+{\r
+       /* Do not include inheritable rules here. */\r
+       margin: 0;\r
+       padding: 0;\r
+       border: 0;\r
+       background: transparent;\r
+       text-decoration: none;\r
+       width: auto;\r
+       height: auto;\r
+       vertical-align: baseline;\r
+       box-sizing: content-box;\r
+       position: static;\r
+       transition: none;\r
+}\r
+\r
+/* Reset for elements and their children. */\r
+.cke_reset_all, .cke_reset_all *,\r
+.cke_reset_all a, .cke_reset_all textarea\r
+{\r
+       /* The following must be identical to .cke_reset. */\r
+       margin: 0;\r
+       padding: 0;\r
+       border: 0;\r
+       background: transparent;\r
+       text-decoration: none;\r
+       width: auto;\r
+       height: auto;\r
+       vertical-align: baseline;\r
+       box-sizing: content-box;\r
+       position: static;\r
+       transition: none;\r
+\r
+       /* These are rule inherited by all children elements. */\r
+       border-collapse: collapse;\r
+       font: normal normal normal 12px Arial,Helvetica,Tahoma,Verdana,Sans-Serif;\r
+       color: #000;\r
+       text-align: left;\r
+       white-space: nowrap;\r
+       cursor: auto;\r
+       float: none;\r
+}\r
+\r
+.cke_reset_all .cke_rtl *\r
+{\r
+       text-align: right;\r
+}\r
+\r
+/* Defaults for some elements. */\r
+\r
+.cke_reset_all iframe\r
+{\r
+       vertical-align: inherit;        /** For IE */\r
+}\r
+\r
+.cke_reset_all textarea\r
+{\r
+       white-space: pre-wrap;\r
+}\r
+\r
+.cke_reset_all textarea,\r
+.cke_reset_all input[type="text"],\r
+.cke_reset_all input[type="password"]\r
+{\r
+       cursor: text;\r
+}\r
+\r
+.cke_reset_all textarea[disabled],\r
+.cke_reset_all input[type="text"][disabled],\r
+.cke_reset_all input[type="password"][disabled]\r
+{\r
+       cursor: default;\r
+}\r
+\r
+.cke_reset_all fieldset\r
+{\r
+       padding: 10px;\r
+       border: 2px groove #E0DFE3;\r
+}\r
+\r
+.cke_reset_all select\r
+{\r
+       box-sizing: border-box;\r
+}\r
+\r
+.cke_reset_all table\r
+{\r
+       table-layout: auto;\r
+}\r
diff --git a/sources/skins/moono/richcombo.css b/sources/skins/moono/richcombo.css
new file mode 100644 (file)
index 0000000..7897a66
--- /dev/null
@@ -0,0 +1,210 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+richcombo.css (part of editor.css)\r
+=================================\r
+\r
+This file holds the style set of the "Rich Combo" widget which is commonly used\r
+in the toolbar. It doesn't, however, styles the panel that is displayed when\r
+clicking on the combo, which is instead styled by panel.css.\r
+\r
+The visual representation of a rich combo widget looks as follows:\r
+\r
++-- .cke_combo----------------------------------------------------------------------+\r
+| +-- .cke_combo_label --+ +-- .cke_combo_button ---------------------------------+ |\r
+| |                      | | +-- .cke_combo_text --+ +-- .cke_combo_open -------+ | |\r
+| |                      | | |                     | | +-- .cke_combo_arrow --+ | | |\r
+| |                      | | |                     | | |                      | | | |\r
+| |                      | | |                     | | +----------------------+ | | |\r
+| |                      | | +---------------------+ +--------------------------+ | |\r
+| +----------------------+ +------------------------------------------------------+ |\r
++-----------------------------------------------------------------------------------+\r
+*/\r
+\r
+/* The box that hold the entire combo widget */\r
+.cke_combo\r
+{\r
+       display: inline-block;\r
+       float: left;\r
+}\r
+\r
+.cke_rtl .cke_combo\r
+{\r
+       float: right;\r
+}\r
+\r
+.cke_hc .cke_combo\r
+{\r
+       margin-top: -2px;\r
+}\r
+\r
+/* The label of the combo widget. It is invisible by default, yet\r
+   it's important for semantics and accessibility. */\r
+.cke_combo_label\r
+{\r
+       display: none;\r
+       float: left;\r
+       line-height: 26px;\r
+       vertical-align: top;\r
+       margin-right: 5px;\r
+}\r
+\r
+.cke_rtl .cke_combo_label\r
+{\r
+       float: right;\r
+       margin-left: 5px;\r
+       margin-right: 0;\r
+}\r
+\r
+/* The container for combo text and arrow. */\r
+a.cke_combo_button\r
+{\r
+       cursor: default;\r
+       display: inline-block;\r
+       float: left;\r
+       margin: 0 6px 5px 0;\r
+\r
+       border: 1px solid #a6a6a6;\r
+       border-bottom-color: #979797;\r
+\r
+       border-radius: 3px;\r
+\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.5), 0 0 2px rgba(255,255,255,.15) inset, 0 1px 0 rgba(255,255,255,.15) inset;\r
+\r
+       background: #e4e4e4;\r
+       background-image: linear-gradient(to bottom, #ffffff, #e4e4e4);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ffffff', endColorstr='#e4e4e4');\r
+}\r
+\r
+/* Different states of the container. */\r
+.cke_combo_off a.cke_combo_button:hover,\r
+.cke_combo_off a.cke_combo_button:focus\r
+{\r
+       background: #ccc;\r
+       background-image: linear-gradient(to bottom, #f2f2f2, #ccc);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f2f2f2', endColorstr='#cccccc');\r
+\r
+       outline: none;\r
+}\r
+\r
+.cke_combo_off a.cke_combo_button:active,\r
+.cke_combo_on a.cke_combo_button\r
+{\r
+       border: 1px solid #777;\r
+\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.5), 0 1px 5px rgba(0,0,0,.6) inset;\r
+\r
+       background: #b5b5b5;\r
+       background-image: linear-gradient(to bottom, #aaa, #cacaca);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#aaaaaa', endColorstr='#cacaca');\r
+}\r
+\r
+.cke_combo_on a.cke_combo_button:hover,\r
+.cke_combo_on a.cke_combo_button:focus,\r
+.cke_combo_on a.cke_combo_button:active\r
+{\r
+       box-shadow: 0 1px 6px rgba(0,0,0,.7) inset, 0 1px 0 rgba(0,0,0,.2);\r
+}\r
+\r
+.cke_rtl .cke_combo_button\r
+{\r
+       float: right;\r
+       margin-left: 5px;\r
+       margin-right: 0;\r
+}\r
+\r
+.cke_hc a.cke_combo_button\r
+{\r
+       padding: 3px;\r
+}\r
+\r
+.cke_hc .cke_combo_on a.cke_combo_button,\r
+.cke_hc .cke_combo_off a.cke_combo_button:hover,\r
+.cke_hc .cke_combo_off a.cke_combo_button:focus,\r
+.cke_hc .cke_combo_off a.cke_combo_button:active\r
+{\r
+       border-width: 3px;\r
+       padding: 1px;\r
+}\r
+\r
+/* The label that shows the current value of the rich combo.\r
+   By default, it holds the name of the property.\r
+   See: .cke_combo_inlinelabel */\r
+.cke_combo_text\r
+{\r
+       line-height: 26px;\r
+       padding-left: 10px;\r
+       text-overflow: ellipsis;\r
+       overflow: hidden;\r
+       float: left;\r
+       cursor: default;\r
+       color: #474747;\r
+       text-shadow: 0 1px 0 rgba(255,255,255,.5);\r
+    width: 60px;\r
+}\r
+\r
+.cke_rtl .cke_combo_text\r
+{\r
+       float: right;\r
+       text-align: right;\r
+       padding-left: 0;\r
+       padding-right: 10px;\r
+}\r
+\r
+.cke_hc .cke_combo_text\r
+{\r
+       line-height: 18px;\r
+       font-size: 12px;\r
+}\r
+\r
+/* The handler which opens the panel of rich combo properties.\r
+   It holds an arrow as a visual indicator. */\r
+.cke_combo_open\r
+{\r
+       cursor: default;\r
+       display: inline-block;\r
+       font-size: 0;\r
+       height: 19px;\r
+       line-height: 17px;\r
+       margin: 1px 7px 1px;\r
+       width: 5px;\r
+}\r
+\r
+.cke_hc .cke_combo_open\r
+{\r
+       height: 12px;\r
+}\r
+\r
+/* The arrow which is displayed inside of the .cke_combo_open handler. */\r
+.cke_combo_arrow\r
+{\r
+       cursor: default;\r
+       margin: 11px 0 0;\r
+       float: left;\r
+\r
+       /* Pure CSS Arrow */\r
+       height: 0;\r
+       width: 0;\r
+       font-size: 0;\r
+       border-left: 3px solid transparent;\r
+       border-right: 3px solid transparent;\r
+       border-top: 3px solid #474747;\r
+}\r
+\r
+.cke_hc .cke_combo_arrow\r
+{\r
+       font-size: 10px;\r
+       width: auto;\r
+       border: 0;\r
+       margin-top: 3px;\r
+}\r
+\r
+/* Disabled combo button styles. */\r
+.cke_combo_disabled .cke_combo_inlinelabel,\r
+.cke_combo_disabled .cke_combo_open\r
+{\r
+       opacity: 0.3;\r
+}\r
diff --git a/sources/skins/moono/skin.js b/sources/skins/moono/skin.js
new file mode 100644 (file)
index 0000000..420b22e
--- /dev/null
@@ -0,0 +1,316 @@
+/**\r
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+ * For licensing, see LICENSE.md or http://ckeditor.com/license\r
+ */\r
+\r
+/*\r
+skin.js\r
+=========\r
+\r
+In this file we interact with the CKEditor JavaScript API to register the skin\r
+and enable additional skin related features.\r
+\r
+The level of complexity of this file depends on the features available in the\r
+skin. There is only one mandatory line of code to be included here, which is\r
+setting CKEDITOR.skin.name. All the rest is optional, but recommended to be\r
+implemented as they make higher quality skins.\r
+\r
+For this skin, the following tasks are achieved in this file:\r
+\r
+       1. Register the skin.\r
+       2. Register browser specific skin files.\r
+       3. Define the "Chameleon" feature.\r
+       4. Register the skin icons, to have them used on the development version of\r
+               the skin.\r
+*/\r
+\r
+// 1. Register the skin\r
+// ----------------------\r
+// The CKEDITOR.skin.name property must be set to the skin name. This is a\r
+// lower-cased name, which must match the skin folder name as well as the value\r
+// used on config.skin to tell the editor to use the skin.\r
+//\r
+// This is the only mandatory property to be defined in this file.\r
+CKEDITOR.skin.name = 'moono';\r
+\r
+// 2. Register browser specific skin files\r
+// -----------------------------------------\r
+// (http://docs.cksource.com/CKEditor_4.x/Skin_SDK/Browser_Hacks)\r
+//\r
+// To help implementing browser specific "hacks" to the skin files and have it\r
+// easy to maintain, it is possible to have dedicated files for such browsers,\r
+// for both the main skin CSS files: editor.css and dialog.css.\r
+//\r
+// The browser files must be named after the main file names, appended by an\r
+// underscore and the browser name (e.g. editor_ie.css, dialog_ie8.css).\r
+//\r
+// The accepted browser names must match the CKEDITOR.env properties. The most\r
+// common names are: ie, webkit and gecko. Check the documentation for the complete\r
+// list:\r
+// http://docs.ckeditor.com/#!/api/CKEDITOR.env\r
+//\r
+// Internet explorer is an expection and the browser version is also accepted\r
+// (ie7, ie8, ie9, ie10), as well as a special name for IE in Quirks mode (iequirks).\r
+//\r
+// The available browser specific files must be set separately for editor.css\r
+// and dialog.css.\r
+CKEDITOR.skin.ua_editor = 'ie,iequirks,ie7,ie8,gecko';\r
+CKEDITOR.skin.ua_dialog = 'ie,iequirks,ie7,ie8';\r
+\r
+// 3. Define the "Chameleon" feature\r
+// -----------------------------------\r
+// (http://docs.cksource.com/CKEditor_4.x/Skin_SDK/Chameleon)\r
+//\r
+// "Chameleon" is a unique feature available in CKEditor. It makes it possible\r
+// to end users to specify which color to use as the basis for the editor UI.\r
+// It is enough to set config.uiColor to any color value and voila, the UI is\r
+// colored.\r
+//\r
+// The only detail here is that the skin itself must be compatible with the\r
+// Chameleon feature. That's because the skin CSS files are the responsible to\r
+// apply colors in the UI and each skin do that in different way and on\r
+// different places.\r
+//\r
+// Implementing the Chameleon feature requires a bit of JavaScript programming.\r
+// The CKEDITOR.skin.chameleon function must be defined. It must return the CSS\r
+// "template" to be used to change the color of a specific CKEditor instance\r
+// available in the page. When a color change is required, this template is\r
+// appended to the page holding the editor, overriding styles defined in the\r
+// skin files.\r
+//\r
+// The "$color" placeholder can be used in the returned string. It'll be\r
+// replaced with the desired color.\r
+CKEDITOR.skin.chameleon = ( function() {\r
+       // This method can be used to adjust colour brightness of various element.\r
+       // Colours are accepted in 7-byte hex format, for example: #00ff00.\r
+       // Brightness ratio must be a float number within [-1, 1],\r
+       // where -1 is black, 1 is white and 0 is the original colour.\r
+       var colorBrightness = ( function() {\r
+               function channelBrightness( channel, ratio ) {\r
+                       var brighten = ratio < 0 ? (\r
+                                       0 | channel * ( 1 + ratio )\r
+                               ) : (\r
+                                       0 | channel + ( 255 - channel ) * ratio\r
+                               );\r
+\r
+                       return ( '0' + brighten.toString( 16 ) ).slice( -2 );\r
+               }\r
+\r
+               return function( hexColor, ratio ) {\r
+                       var channels = hexColor.match( /[^#]./g );\r
+\r
+                       for ( var i = 0 ; i < 3 ; i++ )\r
+                               channels[ i ] = channelBrightness( parseInt( channels[ i ], 16 ), ratio );\r
+\r
+                       return '#' + channels.join( '' );\r
+               };\r
+       } )(),\r
+\r
+       // Use this function just to avoid having to repeat all these rules on\r
+       // several places of our template.\r
+       verticalGradient = ( function() {\r
+               var template = new CKEDITOR.template( 'background:#{to};' +\r
+                       'background-image:linear-gradient(to bottom,{from},{to});' +\r
+                       'filter:progid:DXImageTransform.Microsoft.gradient(gradientType=0,startColorstr=\'{from}\',endColorstr=\'{to}\');' );\r
+\r
+               return function( from, to ) {\r
+                       return template.output( { from: from, to: to } );\r
+               };\r
+       } )(),\r
+\r
+       // Style templates for various user interface parts:\r
+       //      * Default editor template.\r
+       //      * Default panel template.\r
+       templates = {\r
+               editor: new CKEDITOR.template(\r
+                       '{id}.cke_chrome [border-color:{defaultBorder};] ' +\r
+                       '{id} .cke_top [ ' +\r
+                                       '{defaultGradient}' +\r
+                                       'border-bottom-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_bottom [' +\r
+                                       '{defaultGradient}' +\r
+                                       'border-top-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_resizer [border-right-color:{ckeResizer}] ' +\r
+\r
+                       // Dialogs.\r
+                       '{id} .cke_dialog_title [' +\r
+                                       '{defaultGradient}' +\r
+                                       'border-bottom-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_dialog_footer [' +\r
+                                       '{defaultGradient}' +\r
+                                       'outline-color:{defaultBorder};' +\r
+                                       'border-top-color:{defaultBorder};' +   // IE7 doesn't use outline.\r
+                               '] ' +\r
+                       '{id} .cke_dialog_tab [' +\r
+                                       '{lightGradient}' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_dialog_tab:hover [' +\r
+                                       '{mediumGradient}' +\r
+                               '] ' +\r
+                       '{id} .cke_dialog_contents [' +\r
+                                       'border-top-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_dialog_tab_selected, {id} .cke_dialog_tab_selected:hover [' +\r
+                                       'background:{dialogTabSelected};' +\r
+                                       'border-bottom-color:{dialogTabSelectedBorder};' +\r
+                               '] ' +\r
+                       '{id} .cke_dialog_body [' +\r
+                                       'background:{dialogBody};' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] ' +\r
+\r
+                       // Toolbars, buttons.\r
+                       '{id} .cke_toolgroup [' +\r
+                                       '{lightGradient}' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       '{id} a.cke_button_off:hover, {id} a.cke_button_off:focus, {id} a.cke_button_off:active [' +\r
+                                       '{mediumGradient}' +\r
+                               '] ' +\r
+                       '{id} .cke_button_on [' +\r
+                                       '{ckeButtonOn}' +\r
+                               '] ' +\r
+                       '{id} .cke_toolbar_separator [' +\r
+                                       'background-color: {ckeToolbarSeparator};' +\r
+                               '] ' +\r
+\r
+                       // Combo buttons.\r
+                       '{id} .cke_combo_button [' +\r
+                                       'border-color:{defaultBorder};' +\r
+                                       '{lightGradient}' +\r
+                               '] ' +\r
+                       '{id} a.cke_combo_button:hover, {id} a.cke_combo_button:focus, {id} .cke_combo_on a.cke_combo_button [' +\r
+                                       'border-color:{defaultBorder};' +\r
+                                       '{mediumGradient}' +\r
+                               '] ' +\r
+\r
+                       // Elementspath.\r
+                       '{id} .cke_path_item [' +\r
+                                       'color:{elementsPathColor};' +\r
+                               '] ' +\r
+                       '{id} a.cke_path_item:hover, {id} a.cke_path_item:focus, {id} a.cke_path_item:active [' +\r
+                                       'background-color:{elementsPathBg};' +\r
+                               '] ' +\r
+\r
+                       '{id}.cke_panel [' +\r
+                               'border-color:{defaultBorder};' +\r
+                       '] '\r
+               ),\r
+               panel: new CKEDITOR.template(\r
+                       // Panel drop-downs.\r
+                       '.cke_panel_grouptitle [' +\r
+                                       '{lightGradient}' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] ' +\r
+\r
+                       // Context menus.\r
+                       '.cke_menubutton_icon [' +\r
+                                       'background-color:{menubuttonIcon};' +\r
+                               '] ' +\r
+                       '.cke_menubutton:hover .cke_menubutton_icon, .cke_menubutton:focus .cke_menubutton_icon, .cke_menubutton:active .cke_menubutton_icon [' +\r
+                                       'background-color:{menubuttonIconHover};' +\r
+                               '] ' +\r
+                       '.cke_menuseparator [' +\r
+                                       'background-color:{menubuttonIcon};' +\r
+                               '] ' +\r
+\r
+                       // Color boxes.\r
+                       'a:hover.cke_colorbox, a:focus.cke_colorbox, a:active.cke_colorbox [' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] ' +\r
+                       'a:hover.cke_colorauto, a:hover.cke_colormore, a:focus.cke_colorauto, a:focus.cke_colormore, a:active.cke_colorauto, a:active.cke_colormore [' +\r
+                                       'background-color:{ckeColorauto};' +\r
+                                       'border-color:{defaultBorder};' +\r
+                               '] '\r
+               )\r
+       };\r
+\r
+       return function( editor, part ) {\r
+               var uiColor = editor.uiColor,\r
+                       // The following are CSS styles used in templates.\r
+                       // Styles are generated according to current editor.uiColor.\r
+                       templateStyles = {\r
+                               // CKEditor instances have a unique ID, which is used as class name into\r
+                               // the outer container of the editor UI (e.g. ".cke_1").\r
+                               //\r
+                               // The Chameleon feature is available for each CKEditor instance,\r
+                               // independently. Because of this, we need to prefix all CSS selectors with\r
+                               // the unique class name of the instance.\r
+                               id: '.' + editor.id,\r
+\r
+                               // These styles are used by various UI elements.\r
+                               defaultBorder: colorBrightness( uiColor, -0.1 ),\r
+                               defaultGradient: verticalGradient( colorBrightness( uiColor, 0.9 ), uiColor ),\r
+                               lightGradient: verticalGradient( colorBrightness( uiColor, 1 ), colorBrightness( uiColor, 0.7 ) ),\r
+                               mediumGradient: verticalGradient( colorBrightness( uiColor, 0.8 ), colorBrightness( uiColor, 0.5 ) ),\r
+\r
+                               // These are for specific UI elements.\r
+                               ckeButtonOn: verticalGradient( colorBrightness( uiColor, 0.6 ), colorBrightness( uiColor, 0.7 ) ),\r
+                               ckeResizer: colorBrightness( uiColor, -0.4 ),\r
+                               ckeToolbarSeparator: colorBrightness( uiColor, 0.5 ),\r
+                               ckeColorauto: colorBrightness( uiColor, 0.8 ),\r
+                               dialogBody: colorBrightness( uiColor, 0.7 ),\r
+                               // Use gradient instead of simple hex to avoid further filter resetting in IE.\r
+                               dialogTabSelected: verticalGradient( '#FFFFFF', '#FFFFFF' ),\r
+                               dialogTabSelectedBorder: '#FFF',\r
+                               elementsPathColor: colorBrightness( uiColor, -0.6 ),\r
+                               elementsPathBg: uiColor,\r
+                               menubuttonIcon: colorBrightness( uiColor, 0.5 ),\r
+                               menubuttonIconHover: colorBrightness( uiColor, 0.3 )\r
+                       };\r
+\r
+               return templates[ part ]\r
+                       .output( templateStyles )\r
+                       .replace( /\[/g, '{' )                          // Replace brackets with braces.\r
+                       .replace( /\]/g, '}' );\r
+       };\r
+} )();\r
+\r
+// %REMOVE_START%\r
+\r
+// 4. Register the skin icons for development purposes only\r
+// ----------------------------------------------------------\r
+// (http://docs.cksource.com/CKEditor_4.x/Skin_SDK/Icons)\r
+//\r
+// This code is here just to make the skin work fully when using its "source"\r
+// version. Without this, the skin will still work, but its icons will not be\r
+// used (again, on source version only).\r
+//\r
+// This block of code is not necessary on the release version of the skin.\r
+// Because of this it is very important to include it inside the REMOVE_START\r
+// and REMOVE_END comment markers, so the skin builder will properly clean\r
+// things up.\r
+//\r
+// If a required icon is not available here, the plugin defined icon will be\r
+// used instead. This means that a skin is not required to provide all icons.\r
+// Actually, it is not required to provide icons at all.\r
+\r
+( function() {\r
+       // The available icons. This list must match the file names (without\r
+       // extension) available inside the "icons" folder.\r
+       var icons = ( 'about,anchor-rtl,anchor,bgcolor,bidiltr,bidirtl,blockquote,' +\r
+               'bold,bulletedlist-rtl,bulletedlist,button,checkbox,copy-rtl,copy,copyformatting,' +\r
+               'creatediv,cut-rtl,cut,docprops-rtl,docprops,find-rtl,find,flash,form,' +\r
+               'hiddenfield,horizontalrule,icons,iframe,image,imagebutton,indent-rtl,' +\r
+               'indent,italic,justifyblock,justifycenter,justifyleft,justifyright,' +\r
+               'link,maximize,newpage-rtl,newpage,numberedlist-rtl,numberedlist,' +\r
+               'outdent-rtl,outdent,pagebreak-rtl,pagebreak,paste-rtl,paste,' +\r
+               'pastefromword-rtl,pastefromword,pastetext-rtl,pastetext,preview-rtl,' +\r
+               'preview,print,radio,redo-rtl,redo,removeformat,replace,save,scayt,' +\r
+               'select-rtl,select,selectall,showblocks-rtl,showblocks,smiley,' +\r
+               'source-rtl,source,specialchar,spellchecker,strike,subscript,' +\r
+               'superscript,table,templates-rtl,templates,textarea-rtl,textarea,' +\r
+               'textcolor,textfield-rtl,textfield,uicolor,underline,undo-rtl,undo,unlink' ).split( ',' );\r
+\r
+       var iconsFolder = CKEDITOR.getUrl( CKEDITOR.skin.path() + 'icons/' + ( CKEDITOR.env.hidpi ? 'hidpi/' : '' ) );\r
+\r
+       for ( var i = 0; i < icons.length; i++ ) {\r
+               CKEDITOR.skin.addIcon( icons[ i ], iconsFolder + icons[ i ] + '.png' );\r
+       }\r
+} )();\r
+\r
+// %REMOVE_END%\r
diff --git a/sources/skins/moono/toolbar.css b/sources/skins/moono/toolbar.css
new file mode 100644 (file)
index 0000000..a5d32d4
--- /dev/null
@@ -0,0 +1,387 @@
+/*\r
+Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.\r
+For licensing, see LICENSE.md or http://ckeditor.com/license\r
+*/\r
+\r
+/*\r
+toolbar.css (part of editor.css)\r
+==================================\r
+\r
+This files styles the CKEditor toolbar and its buttons. For toolbar combo\r
+styles, check richcombo.css.\r
+\r
+The toolbar is rendered as a big container (called toolbox), which contains\r
+smaller "toolbars". Each toolbar represents a group of items that cannot be\r
+separated. The following is the visual representation of the toolbox.\r
+\r
++-- .cke_toolbox ----------------------------------------------------------+\r
+| +-- .cke_toolbar --+ +-- .cke_toolbar --+ ... +-- .cke_toolbar_break --+ |\r
+| |                  | |                  |     |                        | |\r
+| +------------------+ +------------------+     +------------------------+ |\r
+| +-- .cke_toolbar --+ +-- .cke_toolbar --+ ...                            |\r
+| |                  | |                  |                                |\r
+| +------------------+ +------------------+                                |\r
++--------------------------------------------------------------------------+\r
+\r
+The following instead is the visual representation of a single toolbar:\r
+\r
++-- .cke_toolbar ----------------------------------------------------------------+\r
+| +-- .cke_toolbar_start --+ +-- .cke_toolgroup (*) --+ +-- .cke_toolbar_end --+ |\r
+| |                        | |                        | |                      | |\r
+| +------------------------+ +------------------------+ +----------------------+ |\r
++--------------------------------------------------------------------------------+\r
+(*) .cke_toolgroup is available only when the toolbar items can be grouped\r
+    (buttons). If the items can't be group (combos), this box is not available\r
+       and the items are rendered straight in that place.\r
+\r
+This file also styles toolbar buttons, which are rendered inside the above\r
+.cke_toolgroup containers. This is the visual representation of a button:\r
+\r
++-- .cke_button -------------------------------------+\r
+| +-- .cke_button_icon --+ +-- .cke_button_label --+ |\r
+| |                      | |                       | |\r
+| +----------------------+ +-----------------------+ |\r
++----------------------------------------------------+\r
+\r
+Special outer level classes used in this file:\r
+\r
+       .cke_hc: Available when the editor is rendered on "High Contrast".\r
+       .cke_rtl: Available when the editor UI is on RTL.\r
+*/\r
+\r
+/* The box that holds each toolbar. */\r
+.cke_toolbar\r
+{\r
+       float: left;\r
+}\r
+\r
+.cke_rtl .cke_toolbar\r
+{\r
+       float: right;\r
+}\r
+\r
+/* The box that holds buttons. */\r
+.cke_toolgroup\r
+{\r
+       float: left;\r
+       margin: 0 6px 5px 0;\r
+       border: 1px solid #a6a6a6;\r
+       border-bottom-color: #979797;\r
+\r
+       border-radius: 3px;\r
+\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.5), 0 0 2px rgba(255,255,255,.15) inset, 0 1px 0 rgba(255,255,255,.15) inset;\r
+\r
+       background: #e4e4e4;\r
+       background-image: linear-gradient(to bottom, #ffffff, #e4e4e4);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ffffff', endColorstr='#e4e4e4');\r
+}\r
+\r
+.cke_hc .cke_toolgroup\r
+{\r
+       border: 0;\r
+       margin-right: 10px;\r
+       margin-bottom: 10px;\r
+}\r
+\r
+.cke_rtl .cke_toolgroup\r
+{\r
+       float: right;\r
+       margin-left: 6px;\r
+       margin-right: 0;\r
+}\r
+\r
+/* A toolbar button . */\r
+a.cke_button\r
+{\r
+       display: inline-block;\r
+       height: 18px;\r
+       padding: 4px 6px;\r
+       outline: none;\r
+       cursor: default;\r
+       float: left;\r
+       border: 0;\r
+}\r
+\r
+.cke_ltr .cke_button:last-child,\r
+.cke_rtl .cke_button:first-child\r
+{\r
+       /* Don't distort parent's rounded border. */\r
+       border-radius: 0 2px 2px 0;\r
+}\r
+\r
+.cke_ltr .cke_button:first-child,\r
+.cke_rtl .cke_button:last-child\r
+{\r
+       /* Don't distort parent's rounded border. */\r
+       border-radius: 2px 0 0 2px;\r
+}\r
+\r
+.cke_rtl .cke_button\r
+{\r
+       float: right;\r
+}\r
+\r
+.cke_hc .cke_button\r
+{\r
+       border: 1px solid black;\r
+\r
+       /* Compensate the added border */\r
+       padding: 3px 5px;\r
+       margin: -2px 4px 0 -2px;\r
+}\r
+\r
+/* This class is applied to the button when it is "active" (pushed).\r
+   This style indicates that the feature associated with the button is active\r
+   i.e. currently writing in bold or when spell checking is enabled. */\r
+a.cke_button_on\r
+{\r
+       box-shadow: 0 1px 5px rgba(0,0,0,.6) inset, 0 1px 0 rgba(0,0,0,.2);\r
+\r
+       background: #b5b5b5;\r
+       background-image: linear-gradient(to bottom, #aaa, #cacaca);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#aaaaaa', endColorstr='#cacaca');\r
+}\r
+\r
+.cke_hc .cke_button_on,\r
+.cke_hc a.cke_button_off:hover,\r
+.cke_hc a.cke_button_off:focus,\r
+.cke_hc a.cke_button_off:active,\r
+.cke_hc a.cke_button_disabled:hover,\r
+.cke_hc a.cke_button_disabled:focus,\r
+.cke_hc a.cke_button_disabled:active\r
+{\r
+       border-width: 3px;\r
+\r
+       /* Compensate the border change */\r
+       padding: 1px 3px;\r
+}\r
+\r
+/* This class is applied to the button when the feature associated with the\r
+   button cannot be used (grayed-out).\r
+   i.e. paste button remains disabled when there is nothing in the clipboard to\r
+   be pasted. */\r
+.cke_button_disabled .cke_button_icon\r
+{\r
+       opacity: 0.3;\r
+}\r
+\r
+.cke_hc .cke_button_disabled\r
+{\r
+       opacity: 0.5;\r
+}\r
+\r
+a.cke_button_on:hover,\r
+a.cke_button_on:focus,\r
+a.cke_button_on:active\r
+{\r
+       box-shadow: 0 1px 6px rgba(0,0,0,.7) inset, 0 1px 0 rgba(0,0,0,.2);\r
+}\r
+\r
+a.cke_button_off:hover,\r
+a.cke_button_off:focus,\r
+a.cke_button_off:active,\r
+a.cke_button_disabled:hover,\r
+a.cke_button_disabled:focus,\r
+a.cke_button_disabled:active\r
+{\r
+       box-shadow: 0 0 1px rgba(0,0,0,.3) inset;\r
+\r
+       background: #ccc;\r
+       background-image: linear-gradient(to bottom, #f2f2f2, #ccc);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f2f2f2', endColorstr='#cccccc');\r
+}\r
+\r
+/* The icon which is a visual representation of the button. */\r
+.cke_button_icon\r
+{\r
+       cursor: inherit;\r
+       background-repeat: no-repeat;\r
+       margin-top: 1px;\r
+       width: 16px;\r
+       height: 16px;\r
+       float: left;\r
+       display: inline-block;\r
+}\r
+\r
+.cke_rtl .cke_button_icon\r
+{\r
+       float: right;\r
+}\r
+\r
+.cke_hc .cke_button_icon\r
+{\r
+       display: none;\r
+}\r
+\r
+/* The label of the button that stores the name of the feature. By default,\r
+   labels are invisible. They can be revealed on demand though. */\r
+.cke_button_label\r
+{\r
+       display: none;\r
+       padding-left: 3px;\r
+       margin-top: 1px;\r
+       line-height: 17px;\r
+       vertical-align: middle;\r
+       float: left;\r
+       cursor: default;\r
+       color: #474747;\r
+       text-shadow: 0 1px 0 rgba(255,255,255,.5);\r
+}\r
+\r
+.cke_rtl .cke_button_label\r
+{\r
+       padding-right: 3px;\r
+       padding-left: 0;\r
+       float: right;\r
+}\r
+\r
+.cke_hc .cke_button_label\r
+{\r
+       padding: 0;\r
+       display: inline-block;\r
+       font-size: 12px;\r
+}\r
+\r
+/* The small arrow available on buttons that can be expanded\r
+   (e.g. the color buttons). */\r
+.cke_button_arrow\r
+{\r
+       /* Arrow in CSS */\r
+       display: inline-block;\r
+       margin: 8px 0 0 1px;\r
+       width: 0;\r
+       height: 0;\r
+       cursor: default;\r
+       vertical-align: top;\r
+       border-left: 3px solid transparent;\r
+       border-right: 3px solid transparent;\r
+       border-top: 3px solid #474747;\r
+}\r
+\r
+.cke_rtl .cke_button_arrow\r
+{\r
+       margin-right: 5px;\r
+       margin-left: 0;\r
+}\r
+\r
+.cke_hc .cke_button_arrow\r
+{\r
+       font-size: 10px;\r
+       margin: 3px -2px 0 3px;\r
+       width: auto;\r
+       border: 0;\r
+}\r
+\r
+/* The vertical separator which is used within a single toolbar to split\r
+   buttons into sub-groups. */\r
+.cke_toolbar_separator\r
+{\r
+       float: left;\r
+       background-color: #c0c0c0;\r
+       background-color: rgba(0,0,0,.2);\r
+       margin: 5px 2px 0;\r
+       height: 18px;\r
+       width: 1px;\r
+\r
+       box-shadow: 1px 0 1px rgba(255,255,255,.5);\r
+}\r
+\r
+.cke_rtl .cke_toolbar_separator\r
+{\r
+       float: right;\r
+\r
+       box-shadow: -1px 0 1px rgba(255,255,255,.1);\r
+}\r
+\r
+.cke_hc .cke_toolbar_separator\r
+{\r
+       width: 0;\r
+       border-left: 1px solid;\r
+       margin: 1px 5px 0 0px;\r
+}\r
+\r
+/* The dummy element that breaks toolbars.\r
+   Once it is placed, the very next toolbar is moved to the new row. */\r
+.cke_toolbar_break\r
+{\r
+       display: block;\r
+       clear: left;\r
+}\r
+\r
+.cke_rtl .cke_toolbar_break\r
+{\r
+       clear: right;\r
+}\r
+\r
+/* The button, which when clicked hides (collapses) all the toolbars. */\r
+a.cke_toolbox_collapser\r
+{\r
+       width: 12px;\r
+       height: 11px;\r
+       float: right;\r
+       margin: 11px 0 0;\r
+       font-size: 0;\r
+       cursor: default;\r
+       text-align: center;\r
+\r
+       border: 1px solid #a6a6a6;\r
+       border-bottom-color: #979797;\r
+\r
+       border-radius: 3px;\r
+\r
+       box-shadow: 0 1px 0 rgba(255,255,255,.5), 0 0 2px rgba(255,255,255,.15) inset, 0 1px 0 rgba(255,255,255,.15) inset;\r
+\r
+       background: #e4e4e4;\r
+       background-image: linear-gradient(to bottom, #ffffff, #e4e4e4);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#ffffff', endColorstr='#e4e4e4');\r
+}\r
+\r
+.cke_toolbox_collapser:hover\r
+{\r
+       background: #ccc;\r
+       background-image: linear-gradient(to bottom, #f2f2f2, #ccc);\r
+       filter: progid:DXImageTransform.Microsoft.gradient(gradientType=0, startColorstr='#f2f2f2', endColorstr='#cccccc');\r
+}\r
+\r
+.cke_toolbox_collapser.cke_toolbox_collapser_min\r
+{\r
+       margin: 0 2px 4px;\r
+}\r
+\r
+.cke_rtl .cke_toolbox_collapser\r
+{\r
+       float: left;\r
+}\r
+\r
+/* The CSS arrow, which belongs to the toolbar collapser. */\r
+.cke_toolbox_collapser .cke_arrow\r
+{\r
+       display: inline-block;\r
+\r
+       /* Pure CSS Arrow */\r
+       height: 0;\r
+       width: 0;\r
+       font-size: 0;\r
+       margin-top: 1px;\r
+       border-left: 3px solid transparent;\r
+       border-right: 3px solid transparent;\r
+       border-bottom: 3px solid #474747;\r
+       border-top: 3px solid transparent;\r
+}\r
+\r
+.cke_toolbox_collapser.cke_toolbox_collapser_min .cke_arrow\r
+{\r
+       margin-top: 4px;\r
+       border-bottom-color: transparent;\r
+       border-top-color: #474747;\r
+}\r
+\r
+.cke_hc .cke_toolbox_collapser .cke_arrow\r
+{\r
+       font-size: 8px;\r
+       width: auto;\r
+       border: 0;\r
+       margin-top: 0;\r
+       margin-right: 2px;\r
+}\r
diff --git a/sources/styles.js b/sources/styles.js
new file mode 100644 (file)
index 0000000..733bb4b
--- /dev/null
@@ -0,0 +1,138 @@
+/**
+ * @license Copyright (c) 2003-2017, CKSource - Frederico Knabben. All rights reserved.
+ * For licensing, see LICENSE.md or http://ckeditor.com/license
+ */
+
+// This file contains style definitions that can be used by CKEditor plugins.
+//
+// The most common use for it is the "stylescombo" plugin which shows the Styles drop-down
+// list containing all styles in the editor toolbar. Other plugins, like
+// the "div" plugin, use a subset of the styles for their features.
+//
+// If you do not have plugins that depend on this file in your editor build, you can simply
+// ignore it. Otherwise it is strongly recommended to customize this file to match your
+// website requirements and design properly.
+//
+// For more information refer to: http://docs.ckeditor.com/#!/guide/dev_styles-section-style-rules
+
+CKEDITOR.stylesSet.add( 'default', [
+       /* Block styles */
+
+       // These styles are already available in the "Format" drop-down list ("format" plugin),
+       // so they are not needed here by default. You may enable them to avoid
+       // placing the "Format" combo in the toolbar, maintaining the same features.
+       /*
+       { name: 'Paragraph',            element: 'p' },
+       { name: 'Heading 1',            element: 'h1' },
+       { name: 'Heading 2',            element: 'h2' },
+       { name: 'Heading 3',            element: 'h3' },
+       { name: 'Heading 4',            element: 'h4' },
+       { name: 'Heading 5',            element: 'h5' },
+       { name: 'Heading 6',            element: 'h6' },
+       { name: 'Preformatted Text',element: 'pre' },
+       { name: 'Address',                      element: 'address' },
+       */
+
+       { name: 'Italic Title',         element: 'h2', styles: { 'font-style': 'italic' } },
+       { name: 'Subtitle',                     element: 'h3', styles: { 'color': '#aaa', 'font-style': 'italic' } },
+       {
+               name: 'Special Container',
+               element: 'div',
+               styles: {
+                       padding: '5px 10px',
+                       background: '#eee',
+                       border: '1px solid #ccc'
+               }
+       },
+
+       /* Inline styles */
+
+       // These are core styles available as toolbar buttons. You may opt enabling
+       // some of them in the Styles drop-down list, removing them from the toolbar.
+       // (This requires the "stylescombo" plugin.)
+       /*
+       { name: 'Strong',                       element: 'strong', overrides: 'b' },
+       { name: 'Emphasis',                     element: 'em'   , overrides: 'i' },
+       { name: 'Underline',            element: 'u' },
+       { name: 'Strikethrough',        element: 'strike' },
+       { name: 'Subscript',            element: 'sub' },
+       { name: 'Superscript',          element: 'sup' },
+       */
+
+       { name: 'Marker',                       element: 'span', attributes: { 'class': 'marker' } },
+
+       { name: 'Big',                          element: 'big' },
+       { name: 'Small',                        element: 'small' },
+       { name: 'Typewriter',           element: 'tt' },
+
+       { name: 'Computer Code',        element: 'code' },
+       { name: 'Keyboard Phrase',      element: 'kbd' },
+       { name: 'Sample Text',          element: 'samp' },
+       { name: 'Variable',                     element: 'var' },
+
+       { name: 'Deleted Text',         element: 'del' },
+       { name: 'Inserted Text',        element: 'ins' },
+
+       { name: 'Cited Work',           element: 'cite' },
+       { name: 'Inline Quotation',     element: 'q' },
+
+       { name: 'Language: RTL',        element: 'span', attributes: { 'dir': 'rtl' } },
+       { name: 'Language: LTR',        element: 'span', attributes: { 'dir': 'ltr' } },
+
+       /* Object styles */
+
+       {
+               name: 'Styled Image (left)',
+               element: 'img',
+               attributes: { 'class': 'left' }
+       },
+
+       {
+               name: 'Styled Image (right)',
+               element: 'img',
+               attributes: { 'class': 'right' }
+       },
+
+       {
+               name: 'Compact Table',
+               element: 'table',
+               attributes: {
+                       cellpadding: '5',
+                       cellspacing: '0',
+                       border: '1',
+                       bordercolor: '#ccc'
+               },
+               styles: {
+                       'border-collapse': 'collapse'
+               }
+       },
+
+       { name: 'Borderless Table',             element: 'table',       styles: { 'border-style': 'hidden', 'background-color': '#E6E6FA' } },
+       { name: 'Square Bulleted List', element: 'ul',          styles: { 'list-style-type': 'square' } },
+
+       /* Widget styles */
+
+       { name: 'Clean Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-clean' } },
+       { name: 'Grayscale Image', type: 'widget', widget: 'image', attributes: { 'class': 'image-grayscale' } },
+
+       { name: 'Featured Snippet', type: 'widget', widget: 'codeSnippet', attributes: { 'class': 'code-featured' } },
+
+       { name: 'Featured Formula', type: 'widget', widget: 'mathjax', attributes: { 'class': 'math-featured' } },
+
+       { name: '240p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-240p' }, group: 'size' },
+       { name: '360p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-360p' }, group: 'size' },
+       { name: '480p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-480p' }, group: 'size' },
+       { name: '720p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-720p' }, group: 'size' },
+       { name: '1080p', type: 'widget', widget: 'embedSemantic', attributes: { 'class': 'embed-1080p' }, group: 'size' },
+
+       // Adding space after the style name is an intended workaround. For now, there
+       // is no option to create two styles with the same name for different widget types. See #16664.
+       { name: '240p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-240p' }, group: 'size' },
+       { name: '360p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-360p' }, group: 'size' },
+       { name: '480p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-480p' }, group: 'size' },
+       { name: '720p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-720p' }, group: 'size' },
+       { name: '1080p ', type: 'widget', widget: 'embed', attributes: { 'class': 'embed-1080p' }, group: 'size' }
+
+] );
+
+// %LEAVE_UNMINIFIED% %REMOVE_LINE%